gmi-web(1) inline media
This commit is contained in:
parent
06a8bab54a
commit
541c6345e4
|
@ -75,17 +75,20 @@ gmi.css will respect system dark mode preferences by inverting `--foreground` an
|
|||
## gmi-web(1)
|
||||
|
||||
```
|
||||
gmi-web [--no-css] [files..]
|
||||
gmi-web [--css] [files..]
|
||||
|
||||
Convert .gmi to .html. See gmi-web(1) for more details.
|
||||
|
||||
Positionals:
|
||||
files .gmi files to convert to .html [required]
|
||||
files The *.gmi files to convert [required]
|
||||
|
||||
Options:
|
||||
--version Show version number [boolean]
|
||||
--help Show help [boolean]
|
||||
--css Toggle inclusion of gmi.css. [boolean] [default: true]
|
||||
--images Include images [boolean] [default: false]
|
||||
--audio Include audio [boolean] [default: false]
|
||||
--video Include video [boolean] [default: false]
|
||||
--css Include gmi.css [boolean] [default: true]
|
||||
```
|
||||
|
||||
*You will need*:
|
||||
|
|
34
cli.js
34
cli.js
|
@ -8,23 +8,49 @@ const toHTML = require("./to-html");
|
|||
require("yargs")
|
||||
.scriptName("gmi-web")
|
||||
.command(
|
||||
"$0 [--no-css] [files..]",
|
||||
"$0 [--css] [files..]",
|
||||
"Convert .gmi to .html. See gmi-web(1) for more details.",
|
||||
(yargs) =>
|
||||
yargs
|
||||
.positional("files", {
|
||||
describe: ".gmi files to convert to .html",
|
||||
describe: "The *.gmi files to convert",
|
||||
})
|
||||
.required("files", true)
|
||||
.option("images", {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "Include images",
|
||||
})
|
||||
.option("audio", {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "Include audio",
|
||||
})
|
||||
.option("video", {
|
||||
type: "boolean",
|
||||
default: false,
|
||||
description: "Include video",
|
||||
})
|
||||
.option("css", {
|
||||
type: "boolean",
|
||||
default: true,
|
||||
description: "Toggle inclusion of gmi.css.",
|
||||
description: "Include gmi.css",
|
||||
}),
|
||||
(argv) => {
|
||||
fs.src(argv.files)
|
||||
.pipe(map(tokenize))
|
||||
.pipe(map(toHTML({ css: argv["css"] })))
|
||||
.pipe(
|
||||
map(
|
||||
toHTML({
|
||||
css: argv.css,
|
||||
inline: {
|
||||
images: argv.images,
|
||||
audio: argv.audio,
|
||||
video: argv.video,
|
||||
},
|
||||
})
|
||||
)
|
||||
)
|
||||
.pipe(fs.dest((file) => path.dirname(file.path)));
|
||||
}
|
||||
)
|
||||
|
|
|
@ -6,7 +6,7 @@ gmi-web - A bridge between Gemini and HTML
|
|||
|
||||
# SYNOPSIS
|
||||
|
||||
*gmi-web* [--no-css] _files_
|
||||
*gmi-web* [--images] [--audio] [--video] [--no-css] _files_
|
||||
|
||||
# DESCRIPTION
|
||||
|
||||
|
@ -15,6 +15,9 @@ and mobile-friendly fashion!
|
|||
|
||||
# OPTIONS
|
||||
|
||||
*--images* *--audio* *--video*
|
||||
Include the respective media inline.
|
||||
|
||||
*--no-css*
|
||||
Do not include gmi.css in the rendered HTML markup.
|
||||
|
||||
|
|
37
to-html.js
37
to-html.js
|
@ -1,24 +1,32 @@
|
|||
const TOKENS_EXT = /\.tokens\.json$/;
|
||||
module.exports = ({ css } = { css: true }) => (file, cb) => {
|
||||
// https://developer.mozilla.org/en-US/docs/Web/Media/Formats
|
||||
const IMG_EXT = /\.(apng|avif|gif|jpg|jpeg|jfif|pjpeg|pjp|png|svg|webp)$/;
|
||||
const AUDIO_EXT = /\.(mp3|wav|aac|aacp|mpeg|off|flac)$/;
|
||||
const VIDEO_EXT = /\.(mp4|webm)$/;
|
||||
|
||||
module.exports = (options) => (file, cb) => {
|
||||
if (!TOKENS_EXT.test(file.path)) return cb(null, file);
|
||||
file.path = file.path.replace(TOKENS_EXT, ".html");
|
||||
|
||||
// TODO: meta: author, copyright, keywords, content-type, language, description, canonical
|
||||
file.contents = Buffer.from(`<!DOCTYPE html>
|
||||
<html>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1">${
|
||||
css
|
||||
options.css
|
||||
? '\n<meta name="color-scheme" content="dark light">\n<link rel="stylesheet" href="/gmi.min.css">'
|
||||
: ""
|
||||
}
|
||||
<body>
|
||||
${toHTML(JSON.parse(file.contents.toString("utf8")))}
|
||||
${toHTML(JSON.parse(file.contents.toString("utf8")), options)}
|
||||
</body>
|
||||
</html>
|
||||
`);
|
||||
|
||||
file.path = file.path.replace(TOKENS_EXT, ".html");
|
||||
return cb(null, file);
|
||||
};
|
||||
|
||||
function toHTML(tokens) {
|
||||
function toHTML(tokens, options) {
|
||||
let body = [];
|
||||
|
||||
let cursor = tokens.shift();
|
||||
|
@ -37,16 +45,29 @@ function toHTML(tokens) {
|
|||
body.push("</ul>");
|
||||
tokens = tokens.slice(closing + 1);
|
||||
}
|
||||
body.push(line(cursor));
|
||||
body.push(line(cursor, options));
|
||||
cursor = tokens.shift();
|
||||
}
|
||||
|
||||
return body.join("\n");
|
||||
}
|
||||
|
||||
function line({ text, href, title, pre, alt, h1, h2, h3, li, quote }) {
|
||||
function line(
|
||||
{ text, href, title, pre, alt, h1, h2, h3, li, quote },
|
||||
{ inline }
|
||||
) {
|
||||
console.log(inline)
|
||||
if (text) return `<p>${text}</p>`;
|
||||
if (href) return `<a href="${href}">${title || href}</a>`;
|
||||
if (href) {
|
||||
if (inline.images && IMG_EXT.test(href))
|
||||
return `<img src="${href}" title="${title}"/>`;
|
||||
if (inline.audio && AUDIO_EXT.test(href))
|
||||
return `<audio controls src="${href}" title="${title}"></audio>`;
|
||||
if (inline.video && VIDEO_EXT.test(href))
|
||||
return `<video controls src="${href}" title="${title}"/></video>`;
|
||||
|
||||
return `<a href="${href}">${title || href}</a>`;
|
||||
}
|
||||
if (h1) return `<h1>${h1}</h1>`;
|
||||
if (h2) return `<h2>${h2}</h2>`;
|
||||
if (h3) return `<h3>${h3}</h3>`;
|
||||
|
|
Loading…
Reference in a new issue