substr/html.ts
2024-10-20 21:10:58 +02:00

146 lines
3.2 KiB
TypeScript

import { render as renderMarkdown } from "@deno/gfm";
import { log } from "./log.ts";
export function htmlLayout(title: string, body: string) {
return `
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>${title}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Merriweather:ital,wght@0,400;0,700;0,900;1,400;1,700&display=swap" rel="stylesheet">
<style>
body {
background-color: #f5f2eb;
color: #3b3a38;
font-size: 18px;
font-family: "Merriweather", serif;
}
img {
max-width: 100%;
}
img.avatar {
height: 48px;
width: 48px;
border-radius: 50%;
}
a.anchor {
display: none;
}
h1 {
margin: 2em 0 0 0;
}
h2, h3, h4 {
margin-top: 2em;
margin-bottom: 2rem;
}
h1, h2, h3, h4 {
color: #191818;
}
p, pre, ul, ol, blockquote {
line-height: 1.6em;
margin-bottom: 1.6em;
}
a {
color: #023b77
}
a:visited {
color: #3b0277
}
code {
font-size: 1rem;
background-color: #e8e3da;
color: #027739;
padding: 0.1em 0.3em;
}
pre code {
display: block;
padding: 0.6rem 1rem;
background-color: #333;
color: #ccc;
}
main {
display: block;
max-width: 728px;
margin: 12rem auto;
}
main header {
display: block;
margin-bottom: 3rem;
}
main header h1 {
margin-bottom: 1.6rem;
}
p.meta {
display: flex;
column-gap: 1rem;
}
p.meta .content {
display: flex;
flex-direction: column;
font-size: 0.875rem;
line-height: 1.6rem;
}
p.meta .date {
color: #888;
}
</style>
</head>
<body>
${body}
</body>
</html>
`;
}
export function articleHtml(articleEvent: object, profile: object) {
const titleTag = articleEvent.tags.find(t => t[0] === "title");
const title = titleTag ? titleTag[1] : "Untitled";
const content = renderMarkdown(articleEvent.content);
const date = new Date(articleEvent.created_at * 1000);
const formattedDate = date.toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
});
const body = `
<main>
<header>
<h1>${title}</h1>
<p class="meta">
<img class="avatar" src="${profile.picture}" alt="User Avatar" />
<span class="content">
<span class="name">${profile.name}</span>
<span class="date">${formattedDate}</span>
</span>
</p>
</header>
${content}
</main>
`;
return htmlLayout(title, body);
}