diff options
| author | tslil clingman <> | 2021-04-21 14:52:08 -0400 |
|---|---|---|
| committer | tslil clingman <> | 2021-04-21 14:52:08 -0400 |
| commit | d450e3bfb8468c617f14ad12dd98fb697ff10580 (patch) | |
| tree | 92269100e1a557a0a9e004950d10f9b6739617ea | |
| parent | e9be29ac285876717076456a35f850e5184059c5 (diff) | |
compiling l-3.space for the web
| -rw-r--r-- | atom.xml | 32 | ||||
| -rw-r--r-- | gmi2html.py | 131 | ||||
| -rw-r--r-- | index-log.gmi | 1 | ||||
| -rw-r--r-- | index.gmi | 1 | ||||
| -rw-r--r-- | log-210421-1.gmi | 55 |
5 files changed, 207 insertions, 13 deletions
@@ -2,7 +2,7 @@ <feed xmlns="http://www.w3.org/2005/Atom"> <id>gemini://l-3.space/</id> <title>l-3.space</title> - <updated>2021-04-15T17:06:04.403000+00:00</updated> + <updated>2021-04-21T18:50:32.944000+00:00</updated> <author> <name>tslil</name> <email>hello@l-3.space</email> @@ -10,18 +10,6 @@ <link href="gemini://l-3.space/atom.xml" rel="self"/> <link href="gemini://l-3.space/" rel="alternate"/> <entry> - <id>gemini://l-3.space/split-keys.gmi</id> - <title>Qubes split-SSH</title> - <updated>2020-09-04T18:43:09.049000+00:00</updated> - <link href="gemini://l-3.space/split-keys.gmi" rel="alternate"/> - </entry> - <entry> - <id>gemini://l-3.space/dwm.gmi</id> - <title>Why tiling</title> - <updated>2020-09-07T17:48:25.575000+00:00</updated> - <link href="gemini://l-3.space/dwm.gmi" rel="alternate"/> - </entry> - <entry> <id>gemini://l-3.space/log-201116-1.gmi</id> <title>Plausible authorship deniability</title> <updated>2020-11-16T15:55:26.889000+00:00</updated> @@ -57,4 +45,22 @@ <updated>2021-04-15T17:06:04.403000+00:00</updated> <link href="gemini://l-3.space/log-210415-1.gmi" rel="alternate"/> </entry> + <entry> + <id>gemini://l-3.space/dwm.gmi</id> + <title>Why tiling</title> + <updated>2021-04-20T18:22:32.170000+00:00</updated> + <link href="gemini://l-3.space/dwm.gmi" rel="alternate"/> + </entry> + <entry> + <id>gemini://l-3.space/split-keys.gmi</id> + <title>Qubes split-SSH</title> + <updated>2021-04-20T18:23:16.337000+00:00</updated> + <link href="gemini://l-3.space/split-keys.gmi" rel="alternate"/> + </entry> + <entry> + <id>gemini://l-3.space/log-210421-1.gmi</id> + <title>l-3.space is now automatically compiled to the web</title> + <updated>2021-04-21T18:50:32.944000+00:00</updated> + <link href="gemini://l-3.space/log-210421-1.gmi" rel="alternate"/> + </entry> </feed> diff --git a/gmi2html.py b/gmi2html.py new file mode 100644 index 0000000..e102380 --- /dev/null +++ b/gmi2html.py @@ -0,0 +1,131 @@ +#!/usr/bin/env python3 + +# Convert gemtext to HTML, accepting HTML header and footer files + +# Copyright 2021 huntingb +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see https://www.gnu.org/licenses/. + +# Original code found at: +# https://github.com/huntingb/gemtext-html-converter + +# Modified by tslil clingman, April 2021 in the following ways +# - added HTML escaping of all non-pre lines +# - added header and footer file input +# - added generation of <ul> ... </ul> for list items +# - fixed stripping of lines, no longer occurs in pre blocks, and +# otherwise is rstrip only +# - replace := syntax with something my version of python3 accepts +# - modified description below + +""" +HUNTER'S SIMPLE GEMTEXT TO HTML CONVERTER +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +A simple script that converts gemtext to HTML. + +Takes four arguments from stdin. The first two arguments are the names +of files which will be used as a header and footer for the generated +output, in that order. + +The next argument is the name of of a gemtext file, and the last +argument is the name of the desired output file. + +The output file consists of, in order: the header; the lines of +gemtext in the input file converted to their HTML equivalents: <h1>, +<h2>, <h3>, <p>, <a>, <blockquote>, <li>, and <pre> tags; the footer. +""" + +# importing required libraries +import sys +import re +import html + +# A dictionary that maps regex to match at the beginning of gmi lines +# to their corresponding HTML tag names. Used by +# convert_single_line(). +tags_dict = { + r"^# (.*)": "h1", + r"^## (.*)": "h2", + r"^### (.*)": "h3", + r"^\* (.*)": "li", + r"^> (.*)": "blockquote", + r"^=>\s*(\S+)(\s+.*)?": "a" +} + + +# This function takes a string of gemtext as input and returns a +# string of HTML +def convert_single_line(gmi_line): + for pattern in tags_dict.keys(): + match = re.match(pattern, gmi_line) + if match: + tag = tags_dict[pattern] + groups = match.groups() + if tag == "a": + href = re.sub("^gemini://", "https://", groups[0]) + href = re.sub(r"\.gmi$", ".html", href) + if len(groups) > 1 and groups[1] is not None: + inner_text = groups[1].strip() + else: + inner_text = href + return f"<p><{tag} href='{href}'>{inner_text}</{tag}></p>" + else: + inner_text = html.escape(groups[0].strip()) + return f"<{tag}>{inner_text}</{tag}>" + gmi_line = html.escape(gmi_line) + return f"<p>{gmi_line}</p>" + + +# Reads the contents of the input file line by line and outputs HTML. +# Renders text in preformat blocks (toggled by ```) as multiline <pre> +# tags. +def main(args): + with open(args[3]) as gmi, open(args[4], "w") as output: + # Write header + header = open(args[1]) + output.write(header.read()) + header.close() + # Parse gmitext + pre = False + listing = False + for line in gmi: + if line.startswith("```"): + pre = not pre + if pre: + line = line.rstrip() + if len(line) > 3: + line = html.escape(line[3:]) + output.write(f"<pre title=\"{line}\">\n") + else: + output.write("<pre>\n") + else: + output.write("</pre>\n") + elif pre: + output.write(html.escape(line)) + else: + line = line.rstrip() + if line.startswith("*") and not listing: + listing = True + output.write("<ul>\n") + if not line.startswith("*") and listing: + listing = False + output.write("</ul>\n") + output_line = convert_single_line(line) + output.write(output_line+"\n") + # Write footer + footer = open(args[2]) + output.write(footer.read()) + footer.close() + +# Main guard +if __name__ == "__main__": + main(sys.argv) diff --git a/index-log.gmi b/index-log.gmi index 4da0a0c..28b88a5 100644 --- a/index-log.gmi +++ b/index-log.gmi @@ -2,6 +2,7 @@ Shorter thoughts and articles. +=> gemini://l-3.space/log-210421-1.gmi 2021-04-21 - l-3.space is now automatically compiled to the web => gemini://l-3.space/log-210415-1.gmi 2021-04-15 - Modding my Thinkpad x230 => gemini://l-3.space/log-210317-1.gmi 2021-03-17 - Hindsight is always 20-20 => gemini://l-3.space/log-210226-1.gmi 2021-02-26 - Burnout @@ -22,6 +22,7 @@ Contact: hello@l-3.space ## Recent posts +=> gemini://l-3.space/log-210421-1.gmi 2021-04-21 - l-3.space is now automatically compiled to the web => gemini://l-3.space/log-210415-1.gmi 2021-04-15 - Modding my Thinkpad x230 => gemini://l-3.space/log-210317-1.gmi 2021-03-17 - Hindsight is always 20-20 => gemini://l-3.space/log-210226-1.gmi 2021-02-26 - Burnout diff --git a/log-210421-1.gmi b/log-210421-1.gmi new file mode 100644 index 0000000..7685471 --- /dev/null +++ b/log-210421-1.gmi @@ -0,0 +1,55 @@ +Time-stamp: <2021-04-21 18h50 UTC> + +# l-3.space is now automatically compiled to the web + +Using a combination of git hooks, a python script, and some shell glue it is now possible to view an HTML version of l-3.space over the web⁰. + +=> https://l-3.space + +This is a short post to detail how i implemented it, and lament the things that didn't work. + +## I'm not in the best time-line (yet) + +I would have liked to have been able to set up a gemini-to-http server and proxied it in. The first thing i found was ddevault's Kineto. + +=> https://git.sr.ht/~sircmpwn/kineto kineto + +It's written in Go, about which i have some reservations, but one of it's modules has a hard version requirement *on Go itself*! Debian does not package a ``new enough'' version, so i can't use this code. To me this is frankly unbelievable, and i'm still not sure i even understand what a version of a ``programming language'' could mean. If this is a question of libraries or something, then perhaps call it such, but the compiler gleefully reports ``Go version 1.15 required'' ... + +There's also tslocum's Xenia. + +=> https://code.rocketnine.space/tslocum/xenia tslocum's Xenia + +Unfortunately i couldn't quite work out what this is supposed to be, or how it works, so i ended up doing this the wrong way. + +## The wrong way + +I came across a gemtext-to-html converter and decided that i could reasonably modify it to generate usable HTML output directly. As l-3.space exists as a repository on the hosting machine, i opted to add the following snippet to `.git/hooks/post-update' to (re)generate the HTML every time i pushed a change to the capsule. + +``` +echo Generating HTML site +for g in /var/gemini/l-3.space/content/*.gmi; do + html_out="/var/www/l-3.space/$(basename $g .gmi).html" + gmi2html.py /home/$USER/gemini-capsules/l-3.space/html_header.html \ + /home/$USER/gemini-capsules/l-3.space/html_footer.html \ + "$g" "$html_out"; + chmod 644 "$html_out" +done +``` + +Here gmi2html.py is the name of the script. You can find the original version and my modified version using the below links. + +=> https://github.com/huntingb/gemtext-html-converter hunterb's original version, convert_gemtext_file.py +=> gemini://l-3.space/gmi2html.py my modified version, gmi2htmly.py + +## A fun story about licensing + +Originally hunterb had made the code available, but had forgotten to include a license. Fortunately, there was a listed contact email address. I wrote to hunterb, explaining that i want to make use of the script, change it, share my changes, and allow others to do the same. I asked whether they would be willing to release the code under a license which afforded me these freedoms ... + +they said yes! + +The code is now available under the terms of the GNU GPL v3! + +--- + +⁰ though of course, why would you |
