~charles/gemdown

Tool for working with text/gemini files
several small improvements
fix missing spaces in feed titles
fix bug where DontEscapeHTML was not respected for text elements

refs

master
browse  log 

clone

read-only
https://git.sr.ht/~charles/gemdown
read/write
git@git.sr.ht:~charles/gemdown

You can also use your local clone with git send-email.

#gemdown - Tools for Working With text/gemini

builds.sr.ht status go.dev reference

Warning: early development. Probably has bugs. Things may change without warnings.

gemdown includes a set of tools which aim to be useful for writing a site in the text/gemini format (gemtext) which will be published using both Gemini and HTTP. It may also be useful for some gemini-only workflows. gemdown includes multiple subcommands which are discussed below.

gemdown also includes a parser and AST for the text/gemini format, which may be useful as a library for other Go projects which would like to process Gemini files.

#Demo

#Convert Gemtext to HTML

$ cat simple.gmi
# Top-level heading

Rerum nam necessitatibus commodi facilis est eos officiis et. Ea non tenetur hic autem. Repellendus veniam qui omnis.
In sed voluptates non ea adipisci natus. Vitae corporis neque quae quaerat maxime. Eligendi consequuntur magni voluptatem rerum rerum quos est. Reiciendis non consequuntur error fuga expedita ipsa ut. Quod soluta sequi quidem.

* item 1
* item 2
* item 3

```
int main(void) {
        return -1;
}
```

=> https://example.org An example link
$ gemdown html < simple.gmi
<h1 class="gemdown-heading">Top-level heading</h1>
<p class="gemdown-text">Rerum nam necessitatibus commodi facilis est eos officiis et. Ea non tenetur hic autem. Repellendus veniam qui omnis.</p>
<p class="gemdown-text">In sed voluptates non ea adipisci natus. Vitae corporis neque quae quaerat maxime. Eligendi consequuntur magni voluptatem rerum rerum quos est. Reiciendis non consequuntur error fuga expedita ipsa ut. Quod soluta sequi quidem.</p>
<ul class="gemdown-list">
        <li class="gemdown-list">item 1</li>
        <li class="gemdown-list">item 2</li>
        <li class="gemdown-list">item 3</li>
</ul>
<pre class="gemdown-preformatted" title="">int main(void) {
        return -1;
}
</pre>
<a class="gemdown-link" href="https://example.org">An example link</a>

#Generate RSS Feeds from Gemlogs

RSS and Atom feeds can be generated from Gemlogs, where any links which have a link label that starts with a YYYY-MM-DD date are assumed to be feed entries. RSS is generated by default, but Atom can be generated using the -T flag.

$ cat feed.gmi
# this is a feed

=> https://example.com 2021-03-05 a link title

=> gemini://example.com/foo.gmi 2021-03-07 some other link
$ gemdown feed -T atom < feed.gmi
<?xml version="1.0" encoding="UTF-8"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>Generated by Gemdown</title>
  <id></id>
  <updated>2021-03-29T20:16:57-04:00</updated>
  <subtitle>Feed generated by Gemdown - https://git.sr.ht/~charles/gemdown</subtitle>
  <link href=""></link>
  <author>
    <name>Gemdown User</name>
  </author>
  <entry>
    <title>alinktitle</title>
    <updated>2021-03-05T00:00:00Z</updated>
    <id>tag:example.com,2021-03-05:</id>
    <link href="https://example.com" rel="alternate"></link>
    <summary type="html">alinktitle</summary>
    <author>
      <name>Gemdown User</name>
    </author>
  </entry>
  <entry>
    <title>someotherlink</title>
    <updated>2021-03-07T00:00:00Z</updated>
    <id>tag:example.com,2021-03-07:/foo.gmi</id>
    <link href="gemini://example.com/foo.gmi" rel="alternate"></link>
    <summary type="html">someotherlink</summary>
    <author>
      <name>Gemdown User</name>
    </author>
  </entry>
</feed>

Links that would appear in generated HTML or feeds can be rewritten using a "rewrite spec" file. In this case, we rewrite all gemini links to HTTP links. By writing different regular expressions in the Pattern field, different link rewriting behavior can be configured for different domains, schemes, or extensions as needed.

$ cat feed.gmi
# this is a feed

=> https://example.com 2021-03-05 a link title

=> gemini://example.com/foo.gmi 2021-03-07 some other link
$ cat spec.json
[
        {
                "Pattern": "^gemini[:].*[.]gmi$",
                "Scheme": "http",
                "Extension": "html",
                "Proxy": "",
                "Encode": false
        }
]

$ gemdown -p spec.json html < feed.gmi
<h1 class="gemdown-heading">this is a feed</h1>
<a class="gemdown-link" href="https://example.com">2021-03-05 a link title</a>
<a class="gemdown-link" href="http://example.com/foo.html">2021-03-07 some other link</a>

#Features

  • Validate text/gemini documents (gemdown validate)
  • Generate HTML from text/gemini documents (gemdown html)
  • Generate RSS and Atom feeds based on Gemlog files
  • Rewrite links in a configurable way.

#Installation

make install or go install ./cmd/gemdown

#Usage

See gemdown --help. Each sub-command has it's own --help too.

#Rewrite Specifications

A rewrite specification is a JSON file which contains a single top-level list element. Each object in the list should have the following fields:

  • Pattern - string - a regular expression.
  • Scheme - string - a URI scheme, such as http or https.
  • Extension - string - a file extension, such as .html or .txt.
  • Proxy - string - a format string containing exactly one %s, for example https://proxy.vulpes.one/gemini/%s.
  • Encode - bool - either true or `false.

When -p/--rewrite-spec is used to specify a rewrite spec file, this causes any gemdown subcommand which converts Gemtext to another format to apply the list of rewrite rules to all links encountered. Each rewrite rule is applied in order, one after the other. If the link fails to match the regular expression specified by Pattern, the rule is skipped and the next rule runs.

Scheme specifies the scheme that the link should be changed to, not including the ://. If scheme is blank, then the scheme is not changed. If the scheme is exactly -, then the scheme will be replaced with an empty string.

Extension specifies the file extension that the link should be changed to have. If omitted, the extension is unchanged. Links without extensions are also not affected by the value of the Extension field.

Proxy is a format string into which the link is formatted. This is useful for allowing Gemini or Gopher content that isn't part of your site to be linked from the HTTP/HTML version. The value of this field should have exactly one instance of %s which is replaced with the link. This substitution is performed after the scheme and extension have been changed, if applicable. If the Proxy field is empty, this step is skipped.

Encode, if true, will cause the link to be URL-encoded before substitution into the Proxy string.

#Discuss & Contributions

Feel free to discuss or send patches via my public inbox.

#License

Copyright 2021 Charles Daniels, released under BSD 3-clause. See ./LICENSE.