it works
This commit is contained in:
parent
69d524e79e
commit
e587d1a933
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,3 +1,4 @@
|
||||||
*.min.*
|
*.min.*
|
||||||
node_modules/
|
node_modules/
|
||||||
gmi-web.1
|
gmi-web.1
|
||||||
|
capsule/
|
||||||
|
|
14
README.md
14
README.md
|
@ -75,19 +75,17 @@ gmi.css will respect system dark mode preferences by inverting `--foreground` an
|
||||||
## gmi-web(1)
|
## gmi-web(1)
|
||||||
|
|
||||||
```
|
```
|
||||||
gmi-web [--out path] [--no-css] [files]
|
gmi-web [--no-css] [files..]
|
||||||
|
|
||||||
A bridge between Gemini and HTML. See gmi-web(1) for more details.
|
Convert .gmi to .html. See gmi-web(1) for more details.
|
||||||
|
|
||||||
Positionals:
|
Positionals:
|
||||||
files .gmi files to convert to .html
|
files .gmi files to convert to .html [required]
|
||||||
|
|
||||||
Options:
|
Options:
|
||||||
--version Show version number
|
--version Show version number [boolean]
|
||||||
--help Show help
|
--help Show help [boolean]
|
||||||
--out Write .html files to a seperate directory located at path.
|
--css Toggle inclusion of gmi.css. [boolean] [default: true]
|
||||||
--no-css Do not include gmi.css in the rendered HTML markup.
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
*You will need*:
|
*You will need*:
|
||||||
|
|
19
cli.js
19
cli.js
|
@ -3,28 +3,29 @@ const path = require("path");
|
||||||
const fs = require("vinyl-fs");
|
const fs = require("vinyl-fs");
|
||||||
const map = require("map-stream");
|
const map = require("map-stream");
|
||||||
const tokenize = require("./tokenize");
|
const tokenize = require("./tokenize");
|
||||||
|
const toHTML = require("./to-html");
|
||||||
|
|
||||||
require("yargs")
|
require("yargs")
|
||||||
.scriptName("gmi-web")
|
.scriptName("gmi-web")
|
||||||
.command(
|
.command(
|
||||||
"$0 [--no-css] [files..]",
|
"$0 [--no-css] [files..]",
|
||||||
"A bridge between Gemini and HTML. See gmi-web(1) for more details.",
|
"Convert .gmi to .html. See gmi-web(1) for more details.",
|
||||||
(yargs) =>
|
(yargs) =>
|
||||||
yargs
|
yargs
|
||||||
.positional("files", {
|
.positional("files", {
|
||||||
describe: ".gmi files to convert to .html",
|
describe: ".gmi files to convert to .html",
|
||||||
})
|
})
|
||||||
.required("files", true)
|
.required("files", true)
|
||||||
.option("no-css", {
|
.option("css", {
|
||||||
type: "boolean",
|
type: "boolean",
|
||||||
description: "Do not include gmi.css in the rendered HTML markup.",
|
default: true,
|
||||||
|
description: "Toggle inclusion of gmi.css.",
|
||||||
}),
|
}),
|
||||||
(argv) => {
|
(argv) => {
|
||||||
fs.src(argv.files).pipe(map(tokenize)).pipe(map(log));
|
fs.src(argv.files)
|
||||||
//.pipe(fs.dest((file) => {
|
.pipe(map(tokenize))
|
||||||
// const dest = path.dirname(file.path)
|
.pipe(map(toHTML({css: argv["css"]})))
|
||||||
// console.log(file.path, dest)
|
.pipe(fs.dest((file) => path.dirname(file.path)));
|
||||||
// return dest
|
|
||||||
//}));
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.help().argv;
|
.help().argv;
|
||||||
|
|
|
@ -6,7 +6,7 @@ gmi-web - A bridge between Gemini and HTML
|
||||||
|
|
||||||
# SYNOPSIS
|
# SYNOPSIS
|
||||||
|
|
||||||
*gmi-web* [--out _path_] [--no-css] _files_
|
*gmi-web* [--no-css] _files_
|
||||||
|
|
||||||
# DESCRIPTION
|
# DESCRIPTION
|
||||||
|
|
||||||
|
@ -15,9 +15,6 @@ and mobile-friendly fashion!
|
||||||
|
|
||||||
# OPTIONS
|
# OPTIONS
|
||||||
|
|
||||||
*--out* _path_
|
|
||||||
Write .html files to a seperate directory located at _path_.
|
|
||||||
|
|
||||||
*--no-css*
|
*--no-css*
|
||||||
Do not include gmi.css in the rendered HTML markup.
|
Do not include gmi.css in the rendered HTML markup.
|
||||||
|
|
||||||
|
@ -29,12 +26,6 @@ The following example will create .html converted files next to their .gmi count
|
||||||
$ gmi-web gmi/*.gmi
|
$ gmi-web gmi/*.gmi
|
||||||
```
|
```
|
||||||
|
|
||||||
If you would like to seperate the .html files out to their own folder use the *--out* flag.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ gmi-web --out html gmi/*.gmi
|
|
||||||
```
|
|
||||||
|
|
||||||
# AUTHORS
|
# AUTHORS
|
||||||
|
|
||||||
Maintained by Talon Poole <code@talon.computer>. Up-to-date sources can be
|
Maintained by Talon Poole <code@talon.computer>. Up-to-date sources can be
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
module.exports = /^((=>\s?(?<href>[^\s]+)\s(?<title>.+))|(?<pre>```\s?(?<alt>.+)?)|(###\s?(?<h3>.+))|(##\s?(?<h2>.+))|(#\s?(?<h1>.+))|(\*\s?(?<li>.+))|(>\s?(?<quote>.+))|(?<text>(.+)?))$/;
|
module.exports = /^((=>\s?(?<href>[^\s]+)(\s(?<title>.+))?)|(?<pre>```\s?(?<alt>.+)?)|(###\s?(?<h3>.+))|(##\s?(?<h2>.+))|(#\s?(?<h1>.+))|(\*\s?(?<li>.+))|(>\s?(?<quote>.+))|(?<text>(.+)?))$/;
|
||||||
|
|
54
to-html.js
Normal file
54
to-html.js
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
const TOKENS_EXT = /\.tokens\.json$/;
|
||||||
|
module.exports = ({css} = {css: true}) => (file, cb) => {
|
||||||
|
if (!TOKENS_EXT.test(file.path)) return cb(null, file);
|
||||||
|
file.path = file.path.replace(TOKENS_EXT, ".html");
|
||||||
|
file.contents = Buffer.from(`<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta name="viewport" content="width=device-width,initial-scale=1">${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")))}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
return cb(null, file);
|
||||||
|
};
|
||||||
|
|
||||||
|
function toHTML(tokens) {
|
||||||
|
let body = []
|
||||||
|
|
||||||
|
let cursor = tokens.shift()
|
||||||
|
while (tokens.length) {
|
||||||
|
if (cursor.pre) {
|
||||||
|
body.push(`<pre${cursor.alt ? `title="${cursor.alt}"` : ""}>`)
|
||||||
|
const closing = tokens.findIndex(token => token.pre)
|
||||||
|
body = body.concat(tokens.slice(0, closing).map(({text}) => text))
|
||||||
|
body.push("</pre>")
|
||||||
|
tokens = tokens.slice(closing + 1)
|
||||||
|
}
|
||||||
|
if (cursor.li) {
|
||||||
|
body.push(`<ul>`)
|
||||||
|
const closing = tokens.findIndex(token => !token.li)
|
||||||
|
body = body.concat(tokens.slice(0, closing).map(line))
|
||||||
|
body.push("</ul>")
|
||||||
|
tokens = tokens.slice(closing + 1)
|
||||||
|
}
|
||||||
|
body.push(line(cursor))
|
||||||
|
cursor = tokens.shift()
|
||||||
|
}
|
||||||
|
|
||||||
|
return body.join("\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
function line({ text, href, title, pre, alt, h1, h2, h3, li, quote }) {
|
||||||
|
if (text) return `<p>${text}</p>`;
|
||||||
|
if (href) 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>`;
|
||||||
|
if (li) return `<li>${li}</li>`;
|
||||||
|
if (quote) return `<blockquote>${quote}</blockquote>`;
|
||||||
|
return `<p><br></p>`;
|
||||||
|
}
|
|
@ -4,7 +4,6 @@ module.exports = (file, cb) => {
|
||||||
if (!GMI_EXT.test(file.path)) return cb(null, file);
|
if (!GMI_EXT.test(file.path)) return cb(null, file);
|
||||||
|
|
||||||
file.path = file.path.replace(GMI_EXT, ".tokens.json");
|
file.path = file.path.replace(GMI_EXT, ".tokens.json");
|
||||||
console.log(`tokenizing ${file.path}`);
|
|
||||||
file.contents = Buffer.from(
|
file.contents = Buffer.from(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
file.contents
|
file.contents
|
||||||
|
|
Loading…
Reference in a new issue