summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortslil clingman <>2021-04-21 14:52:08 -0400
committertslil clingman <>2021-04-21 14:52:08 -0400
commitd450e3bfb8468c617f14ad12dd98fb697ff10580 (patch)
tree92269100e1a557a0a9e004950d10f9b6739617ea
parente9be29ac285876717076456a35f850e5184059c5 (diff)
compiling l-3.space for the web
-rw-r--r--atom.xml32
-rw-r--r--gmi2html.py131
-rw-r--r--index-log.gmi1
-rw-r--r--index.gmi1
-rw-r--r--log-210421-1.gmi55
5 files changed, 207 insertions, 13 deletions
diff --git a/atom.xml b/atom.xml
index 9c22db3..ddc536c 100644
--- a/atom.xml
+++ b/atom.xml
@@ -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
diff --git a/index.gmi b/index.gmi
index 76ff46f..1d19251 100644
--- a/index.gmi
+++ b/index.gmi
@@ -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