refactor html.js

feature/server
Talon Poole 2 years ago
parent cae16d74db
commit 62d529a633
  1. 104
      html.js
  2. 2
      html.spec.js
  3. 17
      package.json

@ -11,6 +11,26 @@ export const tokenize = (gemtext) =>
)
);
export function toHTML(gemtext, options) {
options.inlineCSS = options.inlineCSS || CSS.inline(options);
options.styleTag = options.styleTag || CSS.style(options);
const tokens = tokenize(gemtext);
if (options.body) return body(tokens, options);
return `<!DOCTYPE html>
<html lang="${options.html}" dir="${
options.dir || "ltr"
}" style='${options.inlineCSS("html")}'>
<head>${head(tokens, options)}</head>
<body${options.inlineCSS("body")}>
${body(tokens, options)}
</body>
</html>
`;
}
export function block(
{ text, href, title, pre, alt, h1, h2, h3, li, quote },
options = {}
@ -21,6 +41,14 @@ export function block(
if (text) {
content = text;
}
if (li) {
type = "li";
content = li;
}
if (quote) {
type = "blockquote";
content = quote;
}
if (h1) {
type = "h1";
content = h1;
@ -33,17 +61,10 @@ export function block(
type = "h3";
content = h3;
}
if (li) {
type = "li";
content = li;
}
if (quote) {
type = "blockquote";
content = quote;
}
if (href) {
const matchesExt = (url, exts) =>
exts.some((ext) => new RegExp(`\.${ext}$`).test(url));
if (options.image && matchesExt(href, options.image)) {
type = "img";
props += ` src="${href}"`;
@ -62,10 +83,12 @@ export function block(
props += ` href="${href}"`;
}
}
if (options.body || options.inline)
if (options.body || options.inline) {
props += options.inlineCSS(
type === "p" && content === "" ? "p:empty" : type
);
}
return `<${type}${props}>${escape(content)}</${type}>`;
}
@ -102,65 +125,36 @@ export function body(tokens, options) {
return blocks.join("\n");
}
export function toHTML(gemtext, options) {
options.inlineCSS = options.inlineCSS || CSS.inline(options);
options.styleTag = options.styleTag || CSS.style(options);
const tokens = tokenize(gemtext);
if (options.body) return body(tokens, options);
export function head(tokens, options) {
const truncate = (text, limit) =>
text.length > limit ? `${text.substring(0, limit)}...` : text;
return `<!DOCTYPE html>
<html lang="${options.html}" dir="${
options.dir || "ltr"
}" style='${options.inlineCSS("html")}'>
<head>${head(
Object.assign(options, {
title: tokens[0].h1,
description: description(tokens, options),
})
)}</head>
<body${options.inlineCSS("body")}>
${body(tokens, options)}
</body>
</html>
`;
}
let description =
options.description > 0
? tokens.find((token) => {
return token.text && token.text !== "";
})
: false;
export function head(options) {
return `
<meta charset="${options.charset || "utf-8"}">
<meta name="viewport" content="width=device-width,initial-scale=1">${
options.styleTag
}
<title>${options.title}</title>${
!options.author ? "" : `\n<meta name="author" content="${options.author}">`
<title>${tokens.find(({h1}) => h1).h1 || ""}</title>${
options.author ? `\n<meta name="author" content="${options.author}">` : ""
}${
!options.description
? ""
: `\n<meta name="description" content="${escape(options.description)}">`
description
? `\n<meta name="description" content="${escape(truncate(description.text, options.description))}">`
: ""
}${
!options.canonical
? ""
: `\n<link rel="canonical" href="${options.canonical}">`
options.canonical
? `\n<link rel="canonical" href="${options.canonical}">`
: ""
}
`;
}
function description(tokens, options) {
const truncate = (text, limit) =>
text.length > limit ? `${text.substring(0, limit)}...` : text;
let description =
options.description > 0
? tokens.find((token) => {
return token.text && token.text !== "";
})
: false;
return description && truncate(description.text, options.description);
}
export const GMI_EXT = /\.gmi$/;
export function streamHTML(options) {

@ -178,7 +178,7 @@ test("--image, --audio, --video", () => {
});
test("tokenize", () => {
expect(tokenize(gemtext, { body: true })).toMatchInlineSnapshot(`
expect(tokenize(gemtext)).toMatchInlineSnapshot(`
Array [
Object {
"h1": "gmi-web",

@ -1,7 +1,7 @@
{
"name": "gmi-web-cli",
"version": "1.0.0-rc.4",
"description": "A bridge between HTML and Gemini",
"description": "A bridge between Gemini and HTML",
"main": "html.js",
"type": "module",
"bin": {
@ -11,17 +11,18 @@
"./gmi-web.1"
],
"files": [
"UNLICENSE",
"README.md",
"CONTRIBUTING.md",
"gmi-web.1",
"gmi-web.css",
"gmi.css",
"html.js",
"html.spec.js",
"css.js",
"css.spec.js",
"cli.js"
"gmi.css",
"gmi-web.css",
"cli.js",
"README.md",
"CONTRIBUTING.md",
"gmi-web.1",
"example.gmi",
"UNLICENSE"
],
"scripts": {
"test": "NODE_OPTIONS=--experimental-vm-modules jest",

Loading…
Cancel
Save