Convert text/gemini to text/html
Go to file
Talon Poole 18b8c73ce3 heh
2021-02-19 00:01:02 +00:00
.editorconfig clean 2021-02-16 20:32:27 +00:00
.gitignore clean 2021-02-16 20:32:27 +00:00
cli.js refactor css 2021-02-18 23:16:05 +00:00
core.css refactor css 2021-02-18 23:16:05 +00:00
css.js refactor css 2021-02-18 23:16:05 +00:00
gmi-web.1.scd narrowing in... 2021-02-18 19:11:03 +00:00
gmi.css refactor css 2021-02-18 23:16:05 +00:00
html.js inline media refine 2021-02-18 23:57:56 +00:00
package-lock.json add --inline 2021-02-18 16:43:25 +00:00
package.json narrowing in... 2021-02-18 19:11:03 +00:00
README.md heh 2021-02-19 00:01:02 +00:00
UNLICENSE documentation 2021-01-28 17:56:02 +00:00

This project is home to a gmi-to-html reference, the gmi-web(1) command-line tool and a gmi.css stylesheet.

gmi-to-html

The converted Gemini document should exist inside the <body>. Consider if sharing the page with other HTML to put the core document inside <main>. Each available line-type may be translated using the following guide:

<p>           ↔
<a>           ↔  =>
<pre>         ↔  ```
<h[1-3]>      ↔  #[##]
<li>          ↔  *
<blockquote>  ↔  >

<li> must be wrapped with a <ul> tag. Take care to render <pre> blocks with their original formatting, DO NOT indent the generated HTML for these tags.

<a> tags are categorized as inline which CSS 2.1's Normal Flow presents vertically—Gemini only deals with horizontally flowing content, this can be addressed by using display: block; at the CSS level.

optional: inline media

If a link is consumable by <img>, <audio> or <video> you may insert the respective tag inline, instead of an <a>. It's a good idea to also include the controls, currentTime and duration attributes.

These are categorized as inline just like <a> and will need display: block; styling. Images and video should also have max-width: 100%; so they don't overflow the body.

<html> and <head>

When producing a complete and valid HTML5 document the first declaration is the required <!DOCTYPE html>. At the root of a document is the <html> tag which should have a lang attribute which declares the overall language of the page and if necessary should also include dir="rtl".

Additionally a <head> tag with at least the following must also be included:

<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title></title>

These may also be nice to have:

<meta name="author" content="" />
<meta name="description" content="" />
<link rel="canonical" href="gemini://" />
<meta name="color-scheme" content="dark light" />

gmi-web(1)

npm install --global gmi-web-cli && gmi-web --help
gmi-web [files..]

Convert text/gemini to text/html.

CSS:
  --inline                                                             [boolean]
  --foreground                                                [default: "black"]
  --background                                                [default: "white"]
  --body-width                                                [default: "48rem"]
  --hyphens                                                  [default: "manual"]
  --serif                                     [default: "georgia, times, serif"]
  --sans-serif                 [default: "avenir, helvetica, arial, sans-serif"]
  --mono                                [default: "consolas, monaco, monospace"]
  --p-family                                           [default: "var(--serif)"]
  --p-size                                                  [default: "1.25rem"]
  --p-height                                                    [default: "1.5"]
  --p-indent                                                   [default: "0rem"]
  --a-family                                           [default: "var(--serif)"]
  --a-size                                            [default: "var(--p-size)"]
  --a-height                                                    [default: "1.5"]
  --a-decoration                                          [default: "underline"]
  --a-style                                                  [default: "normal"]
  --pre-family                                          [default: "var(--mono)"]
  --pre-size                                                   [default: "1rem"]
  --pre-height                                                    [default: "1"]
  --h1-family                                     [default: "var(--sans-serif)"]
  --h1-size                                                    [default: "3rem"]
  --h1-height                                                  [default: "1.25"]
  --h2-family                                     [default: "var(--sans-serif)"]
  --h2-size                                                 [default: "2.25rem"]
  --h2-height                                                  [default: "1.25"]
  --h3-family                                     [default: "var(--sans-serif)"]
  --h3-size                                                  [default: "1.5rem"]
  --h3-height                                                  [default: "1.25"]
  --ul-family                                          [default: "var(--serif)"]
  --ul-size                                           [default: "var(--p-size)"]
  --ul-height                                                  [default: "1.25"]
  --quote-family                                       [default: "var(--serif)"]
  --quote-size                                        [default: "var(--p-size)"]
  --quote-height                                               [default: "1.25"]
  --quote-style                                              [default: "italic"]

Core:
  --html, --language, --lang                                            [string]
  --body                                                               [boolean]

HTML:
  --author                                                              [string]
  --descriptions                                           [number] [default: 0]
  --css                                                        [default: "full"]
  --dir                        [string] [choices: "rtl", "ltr"] [default: "ltr"]

Inline Media:
  --image                                                                [array]
  --audio                                                                [array]
  --video                                                                [array]

Options:
  --version  Show version number                                       [boolean]
  --config   Path to JSON config file
  --help     Show help                                                 [boolean]

Examples:
  gmi-web --body < ~/my-capsule/index.gmi
  gmi-web --html en $(find ~/my-capsule -name '*.gmi')
  gmi-web --foreground '#000000' --background '#EEEEEE' --html en < doc.gmi
  gmi-web --image jpg --audio mp3 --image png --body < doc.gmi

See the gmi-web(1) man page for more information.

config

A JSON file can be passed to --config for conveniently applying any option without using the command-line flag. For example a web.json file with the following contents...

{
  "html": "en",
  "descriptions": 200,
  "foreground": "#137752",
  "background": "#F4F4F4"
}

...can be used like so:

gmi-web --config web.json $(find ~/gmi/dst -name '*.gmi')

gmi.css

core.css is a maximally miniminal stylesheet that overrides the default CSS Normal Flow to render content horizontally in a Gemini way. gmi.css extends upon that slightly with font and color options. The default values are optimized for readability and mobile-friendliness and may be customized by adding a style property to <html>.

<head>
  <!-- assuming you wanna host a copy and link to it... -->
  <link rel="stylesheet" type="text/css" href="gmi.css" />
  <meta name="color-scheme" content="dark light" />
  <!-- ... -->
</head>
<html style="--foreground:#555555; --background:#9EEBCF;">
  <!-- ... -->
</html>

The --foreground and --background variables will be inverted when prefers-color-scheme is "dark".

license

gmi-web is free and unencumbered public domain software. For more information, see http://unlicense.org/ or the accompanying UNLICENSE file.