commit 37930cf6c6d2ef653d62015392c09534c8b264ef
Author: Simon Watson <spw01@protonmail.com>
Date: Fri Jan 21 15:45:35 2022 -0500
Some more posts from the past few days
diff --git a/2022-01-20-gopher-setup.html b/2022-01-20-gopher-setup.html
new file mode 100644
index 0000000..6602c47
--- /dev/null
+++ b/2022-01-20-gopher-setup.html
@@ -0,0 +1,434 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<!-- 2022-01-21 Fri 15:42 -->
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<title></title>
+<meta name="generator" content="Org mode" />
+<style type="text/css">
+ <!--/*--><![CDATA[/*><!--*/
+ .title { text-align: center;
+ margin-bottom: .2em; }
+ .subtitle { text-align: center;
+ font-size: medium;
+ font-weight: bold;
+ margin-top:0; }
+ .todo { font-family: monospace; color: red; }
+ .done { font-family: monospace; color: green; }
+ .priority { font-family: monospace; color: orange; }
+ .tag { background-color: #eee; font-family: monospace;
+ padding: 2px; font-size: 80%; font-weight: normal; }
+ .timestamp { color: #bebebe; }
+ .timestamp-kwd { color: #5f9ea0; }
+ .org-right { margin-left: auto; margin-right: 0px; text-align: right; }
+ .org-left { margin-left: 0px; margin-right: auto; text-align: left; }
+ .org-center { margin-left: auto; margin-right: auto; text-align: center; }
+ .underline { text-decoration: underline; }
+ #postamble p, #preamble p { font-size: 90%; margin: .2em; }
+ p.verse { margin-left: 3%; }
+ pre {
+ border: 1px solid #ccc;
+ box-shadow: 3px 3px 3px #eee;
+ padding: 8pt;
+ font-family: monospace;
+ overflow: auto;
+ margin: 1.2em;
+ }
+ pre.src {
+ position: relative;
+ overflow: auto;
+ padding-top: 1.2em;
+ }
+ pre.src:before {
+ display: none;
+ position: absolute;
+ background-color: white;
+ top: -10px;
+ right: 10px;
+ padding: 3px;
+ border: 1px solid black;
+ }
+ pre.src:hover:before { display: inline; margin-top: 14px;}
+ /* Languages per Org manual */
+ pre.src-asymptote:before { content: 'Asymptote'; }
+ pre.src-awk:before { content: 'Awk'; }
+ pre.src-C:before { content: 'C'; }
+ /* pre.src-C++ doesn't work in CSS */
+ pre.src-clojure:before { content: 'Clojure'; }
+ pre.src-css:before { content: 'CSS'; }
+ pre.src-D:before { content: 'D'; }
+ pre.src-ditaa:before { content: 'ditaa'; }
+ pre.src-dot:before { content: 'Graphviz'; }
+ pre.src-calc:before { content: 'Emacs Calc'; }
+ pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
+ pre.src-fortran:before { content: 'Fortran'; }
+ pre.src-gnuplot:before { content: 'gnuplot'; }
+ pre.src-haskell:before { content: 'Haskell'; }
+ pre.src-hledger:before { content: 'hledger'; }
+ pre.src-java:before { content: 'Java'; }
+ pre.src-js:before { content: 'Javascript'; }
+ pre.src-latex:before { content: 'LaTeX'; }
+ pre.src-ledger:before { content: 'Ledger'; }
+ pre.src-lisp:before { content: 'Lisp'; }
+ pre.src-lilypond:before { content: 'Lilypond'; }
+ pre.src-lua:before { content: 'Lua'; }
+ pre.src-matlab:before { content: 'MATLAB'; }
+ pre.src-mscgen:before { content: 'Mscgen'; }
+ pre.src-ocaml:before { content: 'Objective Caml'; }
+ pre.src-octave:before { content: 'Octave'; }
+ pre.src-org:before { content: 'Org mode'; }
+ pre.src-oz:before { content: 'OZ'; }
+ pre.src-plantuml:before { content: 'Plantuml'; }
+ pre.src-processing:before { content: 'Processing.js'; }
+ pre.src-python:before { content: 'Python'; }
+ pre.src-R:before { content: 'R'; }
+ pre.src-ruby:before { content: 'Ruby'; }
+ pre.src-sass:before { content: 'Sass'; }
+ pre.src-scheme:before { content: 'Scheme'; }
+ pre.src-screen:before { content: 'Gnu Screen'; }
+ pre.src-sed:before { content: 'Sed'; }
+ pre.src-sh:before { content: 'shell'; }
+ pre.src-sql:before { content: 'SQL'; }
+ pre.src-sqlite:before { content: 'SQLite'; }
+ /* additional languages in org.el's org-babel-load-languages alist */
+ pre.src-forth:before { content: 'Forth'; }
+ pre.src-io:before { content: 'IO'; }
+ pre.src-J:before { content: 'J'; }
+ pre.src-makefile:before { content: 'Makefile'; }
+ pre.src-maxima:before { content: 'Maxima'; }
+ pre.src-perl:before { content: 'Perl'; }
+ pre.src-picolisp:before { content: 'Pico Lisp'; }
+ pre.src-scala:before { content: 'Scala'; }
+ pre.src-shell:before { content: 'Shell Script'; }
+ pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
+ /* additional language identifiers per "defun org-babel-execute"
+ in ob-*.el */
+ pre.src-cpp:before { content: 'C++'; }
+ pre.src-abc:before { content: 'ABC'; }
+ pre.src-coq:before { content: 'Coq'; }
+ pre.src-groovy:before { content: 'Groovy'; }
+ /* additional language identifiers from org-babel-shell-names in
+ ob-shell.el: ob-shell is the only babel language using a lambda to put
+ the execution function name together. */
+ pre.src-bash:before { content: 'bash'; }
+ pre.src-csh:before { content: 'csh'; }
+ pre.src-ash:before { content: 'ash'; }
+ pre.src-dash:before { content: 'dash'; }
+ pre.src-ksh:before { content: 'ksh'; }
+ pre.src-mksh:before { content: 'mksh'; }
+ pre.src-posh:before { content: 'posh'; }
+ /* Additional Emacs modes also supported by the LaTeX listings package */
+ pre.src-ada:before { content: 'Ada'; }
+ pre.src-asm:before { content: 'Assembler'; }
+ pre.src-caml:before { content: 'Caml'; }
+ pre.src-delphi:before { content: 'Delphi'; }
+ pre.src-html:before { content: 'HTML'; }
+ pre.src-idl:before { content: 'IDL'; }
+ pre.src-mercury:before { content: 'Mercury'; }
+ pre.src-metapost:before { content: 'MetaPost'; }
+ pre.src-modula-2:before { content: 'Modula-2'; }
+ pre.src-pascal:before { content: 'Pascal'; }
+ pre.src-ps:before { content: 'PostScript'; }
+ pre.src-prolog:before { content: 'Prolog'; }
+ pre.src-simula:before { content: 'Simula'; }
+ pre.src-tcl:before { content: 'tcl'; }
+ pre.src-tex:before { content: 'TeX'; }
+ pre.src-plain-tex:before { content: 'Plain TeX'; }
+ pre.src-verilog:before { content: 'Verilog'; }
+ pre.src-vhdl:before { content: 'VHDL'; }
+ pre.src-xml:before { content: 'XML'; }
+ pre.src-nxml:before { content: 'XML'; }
+ /* add a generic configuration mode; LaTeX export needs an additional
+ (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
+ pre.src-conf:before { content: 'Configuration File'; }
+
+ table { border-collapse:collapse; }
+ caption.t-above { caption-side: top; }
+ caption.t-bottom { caption-side: bottom; }
+ td, th { vertical-align:top; }
+ th.org-right { text-align: center; }
+ th.org-left { text-align: center; }
+ th.org-center { text-align: center; }
+ td.org-right { text-align: right; }
+ td.org-left { text-align: left; }
+ td.org-center { text-align: center; }
+ dt { font-weight: bold; }
+ .footpara { display: inline; }
+ .footdef { margin-bottom: 1em; }
+ .figure { padding: 1em; }
+ .figure p { text-align: center; }
+ .equation-container {
+ display: table;
+ text-align: center;
+ width: 100%;
+ }
+ .equation {
+ vertical-align: middle;
+ }
+ .equation-label {
+ display: table-cell;
+ text-align: right;
+ vertical-align: middle;
+ }
+ .inlinetask {
+ padding: 10px;
+ border: 2px solid gray;
+ margin: 10px;
+ background: #ffffcc;
+ }
+ #org-div-home-and-up
+ { text-align: right; font-size: 70%; white-space: nowrap; }
+ textarea { overflow-x: auto; }
+ .linenr { font-size: smaller }
+ .code-highlighted { background-color: #ffff00; }
+ .org-info-js_info-navigation { border-style: none; }
+ #org-info-js_console-label
+ { font-size: 10px; font-weight: bold; white-space: nowrap; }
+ .org-info-js_search-highlight
+ { background-color: #ffff00; color: #000000; font-weight: bold; }
+ .org-svg { width: 90%; }
+ /*]]>*/-->
+</style>
+<script type="text/javascript">
+// @license magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt Public Domain
+<!--/*--><![CDATA[/*><!--*/
+ function CodeHighlightOn(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.add("code-highlighted");
+ target.classList.add("code-highlighted");
+ }
+ }
+ function CodeHighlightOff(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.remove("code-highlighted");
+ target.classList.remove("code-highlighted");
+ }
+ }
+ /*]]>*///-->
+// @license-end
+</script>
+<script type="text/x-mathjax-config">
+ MathJax.Hub.Config({
+ displayAlign: "center",
+ displayIndent: "0em",
+
+ "HTML-CSS": { scale: 100,
+ linebreaks: { automatic: "false" },
+ webFont: "TeX"
+ },
+ SVG: {scale: 100,
+ linebreaks: { automatic: "false" },
+ font: "TeX"},
+ NativeMML: {scale: 100},
+ TeX: { equationNumbers: {autoNumber: "AMS"},
+ MultLineWidth: "85%",
+ TagSide: "right",
+ TagIndent: ".8em"
+ }
+});
+</script>
+<script type="text/javascript"
+ src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
+</head>
+<body>
+<div id="content">
+<div id="table-of-contents">
+<h2>Table of Contents</h2>
+<div id="text-table-of-contents">
+<ul>
+<li><a href="#org38b106d">1. Setting up a Gopher Server</a></li>
+<li><a href="#org883f119">2. Basics</a></li>
+<li><a href="#org6abbb92">3. CGI</a>
+<ul>
+<li><a href="#org56a7a28">3.1. Footguns and Hangups</a></li>
+<li><a href="#org86dfa63">3.2. Helpful Patterns</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div id="outline-container-org38b106d" class="outline-2">
+<h2 id="org38b106d"><span class="section-number-2">1</span> Setting up a Gopher Server</h2>
+<div class="outline-text-2" id="text-1">
+<p>
+Hey folks! In this post I'm going to talk a bit about setting
+up my Gopher server and some of the choices I made in doing so.
+</p>
+
+<p>
+I hope this is helpful to anyone who stumbles onto this article!
+</p>
+
+<p>
+Disclaimer: I'm only a few weeks into learning about Gopher
+and the so-called "indie-net", so this article may not
+represent the better part of community knowledge, or
+"best practices".
+</p>
+</div>
+</div>
+
+<div id="outline-container-org883f119" class="outline-2">
+<h2 id="org883f119"><span class="section-number-2">2</span> Basics</h2>
+<div class="outline-text-2" id="text-2">
+<p>
+I'll just rattle these off quickly so that we don't need to spend
+too much time on them:
+</p>
+
+<ul class="org-ul">
+<li>Server: Ubuntu VPS</li>
+<li>Gopher Server: Motsognir</li>
+</ul>
+
+<p>
+I won't cover the basics of setting up Motsognir or a basic Gopher
+map, as others have already done a great job covering these topics.
+</p>
+
+<p>
+Checkout the following WWW links on the topic:
+<a href="https://gopher.zone/">https://gopher.zone/</a>
+<a href="https://usermanual.wiki/Document/manual.488145643/help">https://usermanual.wiki/Document/manual.488145643/help</a>
+</p>
+</div>
+</div>
+
+<div id="outline-container-org6abbb92" class="outline-2">
+<h2 id="org6abbb92"><span class="section-number-2">3</span> CGI</h2>
+<div class="outline-text-2" id="text-3">
+<p>
+Because Gopher is a pretty simple protocol spec, I wanted to
+not serve static gopher maps and instead implement everything
+as a CGI script. This allows me to be pretty flexible with
+the formatting and configuration of the site:
+</p>
+
+<ul class="org-ul">
+<li>Can provide a 'plain' non ANSI escape sequence cluttered
+version of the site for users who prefer the minimalism
+of uniform text/chars</li>
+<li>Can provide interesting tidbits like Last Modification
+date of the site and # of uniq visitors</li>
+<li>Silly stuff like intermediate http requests (server side)
+to my git server so that I can serve all of my git website
+natively in Gopher</li>
+</ul>
+
+<p>
+The CGI source is actually available to view live, see:
+<a href="gopher://chate.io/0/foobar.txt">gopher://chate.io/0/foobar.txt</a>
+</p>
+
+<p>
+Note: The Gopher server Gophernicus actually offers what I
+think is an even cooler way of doing this, with what it calls
+moles. Check it out: <a href="https://github.com/gophernicus/gophernicus">https://github.com/gophernicus/gophernicus</a>
+</p>
+
+<p>
+I may move over to gophernicus at some point, but for now
+I'm enjoying the ease of use of Motsognir.
+</p>
+
+<p>
+On that topic, to get all the CGI stuff working correctly
+I had to set the following values in the Motsognir config
+file. The config file is awesome, and well documented, but
+as a newcomer to the protocol it was somewhat confusing
+to get it configured right, so I've provided the following:
+</p>
+
+<p>
+GopherCgiSupport=1
+SubGophermaps=1
+DefaultGophermap=
+</p>
+
+<p>
+I'd encourage reading the comments for each of these settings
+for a clearer understanding of what they're doing, but I leave
+this exercise to the reader.
+</p>
+</div>
+
+<div id="outline-container-org56a7a28" class="outline-3">
+<h3 id="org56a7a28"><span class="section-number-3">3.1</span> Footguns and Hangups</h3>
+<div class="outline-text-3" id="text-3-1">
+<p>
+A few things I learned trying to always dynamically
+generate my gophermap:
+</p>
+
+<ul class="org-ul">
+<li>Clients can be finnicky and the protocl spec seems
+to be not super well agreed upon by client
+implimenters
+– Some clients will not correctly parse info
+ lines if there is a " " after the i
+– Some clients will seemingly ignore info lines
+– Some clients don't mind if you don't have a "."
+ char at the EOF, others seem to really care
+ — Apparently the "." at EOF is part of the spec,
+ so it really should be there
+– Some clients will automagically parse out any ANSI
+ escape sequnces, others will interpret them correctly,
+ and others will barf them to the screen literally
+ — To my knowledge there is nothing in the spec for
+ handling this, so client implementers can't be blamed
+– Some gopher servers will helpfully auto fill lines in a
+ map that don't contain <TAB>$host<$TAB>$port. I learned
+ that motsognir will do this on a statically served map,
+ but (in hindsight, obviously), not a dynamically
+ generated one, so make sure you're filling that out</li>
+</ul>
+</div>
+</div>
+
+<div id="outline-container-org86dfa63" class="outline-3">
+<h3 id="org86dfa63"><span class="section-number-3">3.2</span> Helpful Patterns</h3>
+<div class="outline-text-3" id="text-3-2">
+<p>
+A few helpful patterns I've employed while writing my CGI
+scripts:
+</p>
+
+<ul class="org-ul">
+<li><p>
+Establish an interface for printing your gopher map. I use
+a function that takes 3 args: $gopher<sub>menu</sub><sub>type</sub>, $string,
+$rest.
+</p>
+
+<p>
+The idea being that you call the function this way:
+g<sub>print</sub>("1","Some Dir","\t$path\t$hostname\t$port");
+</p>
+
+<p>
+This function will then, depending on what/if it gets
+a CGI query parameter, will either randomly colorize
+the output or not, allowing the site to be easily rendered
+one way or another.
+</p></li>
+
+<li>As with stuff on WWW, make sure your CGI scripts are
+executing quickly, otherwise the client will be left waiting</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+<div id="postamble" class="status">
+<p class="date">Created: 2022-01-21 Fri 15:42</p>
+<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
+</div>
+</body>
+</html>
diff --git a/2022-01-20-gopher-setup.org b/2022-01-20-gopher-setup.org
new file mode 100644
index 0000000..532ae59
--- /dev/null
+++ b/2022-01-20-gopher-setup.org
@@ -0,0 +1,112 @@
+* Setting up a Gopher Server
+
+Hey folks! In this post I'm going to talk a bit about setting
+up my Gopher server and some of the choices I made in doing so.
+
+I hope this is helpful to anyone who stumbles onto this article!
+
+Disclaimer: I'm only a few weeks into learning about Gopher
+and the so-called "indie-net", so this article may not
+represent the better part of community knowledge, or
+"best practices".
+
+* Basics
+
+I'll just rattle these off quickly so that we don't need to spend
+too much time on them:
+
+- Server: Ubuntu VPS
+- Gopher Server: Motsognir
+
+I won't cover the basics of setting up Motsognir or a basic Gopher
+map, as others have already done a great job covering these topics.
+
+Checkout the following WWW links on the topic:
+https://gopher.zone/
+https://usermanual.wiki/Document/manual.488145643/help
+
+* CGI
+
+Because Gopher is a pretty simple protocol spec, I wanted to
+not serve static gopher maps and instead implement everything
+as a CGI script. This allows me to be pretty flexible with
+the formatting and configuration of the site:
+
+- Can provide a 'plain' non ANSI escape sequence cluttered
+ version of the site for users who prefer the minimalism
+ of uniform text/chars
+- Can provide interesting tidbits like Last Modification
+ date of the site and # of uniq visitors
+- Silly stuff like intermediate http requests (server side)
+ to my git server so that I can serve all of my git website
+ natively in Gopher
+
+The CGI source is actually available to view live, see:
+gopher://chate.io/0/foobar.txt
+
+Note: The Gopher server Gophernicus actually offers what I
+think is an even cooler way of doing this, with what it calls
+moles. Check it out: https://github.com/gophernicus/gophernicus
+
+I may move over to gophernicus at some point, but for now
+I'm enjoying the ease of use of Motsognir.
+
+On that topic, to get all the CGI stuff working correctly
+I had to set the following values in the Motsognir config
+file. The config file is awesome, and well documented, but
+as a newcomer to the protocol it was somewhat confusing
+to get it configured right, so I've provided the following:
+
+GopherCgiSupport=1
+SubGophermaps=1
+DefaultGophermap=
+
+I'd encourage reading the comments for each of these settings
+for a clearer understanding of what they're doing, but I leave
+this exercise to the reader.
+
+** Footguns and Hangups
+
+A few things I learned trying to always dynamically
+generate my gophermap:
+
+- Clients can be finnicky and the protocl spec seems
+ to be not super well agreed upon by client
+ implimenters
+ -- Some clients will not correctly parse info
+ lines if there is a " " after the i
+ -- Some clients will seemingly ignore info lines
+ -- Some clients don't mind if you don't have a "."
+ char at the EOF, others seem to really care
+ --- Apparently the "." at EOF is part of the spec,
+ so it really should be there
+ -- Some clients will automagically parse out any ANSI
+ escape sequnces, others will interpret them correctly,
+ and others will barf them to the screen literally
+ --- To my knowledge there is nothing in the spec for
+ handling this, so client implementers can't be blamed
+ -- Some gopher servers will helpfully auto fill lines in a
+ map that don't contain <TAB>$host<$TAB>$port. I learned
+ that motsognir will do this on a statically served map,
+ but (in hindsight, obviously), not a dynamically
+ generated one, so make sure you're filling that out
+
+** Helpful Patterns
+
+A few helpful patterns I've employed while writing my CGI
+scripts:
+
+- Establish an interface for printing your gopher map. I use
+ a function that takes 3 args: $gopher_menu_type, $string,
+ $rest.
+
+ The idea being that you call the function this way:
+ g_print("1","Some Dir","\t$path\t$hostname\t$port");
+
+ This function will then, depending on what/if it gets
+ a CGI query parameter, will either randomly colorize
+ the output or not, allowing the site to be easily rendered
+ one way or another.
+
+- As with stuff on WWW, make sure your CGI scripts are
+ executing quickly, otherwise the client will be left waiting
diff --git a/2022-01-20-gopher-setup.pretty.html b/2022-01-20-gopher-setup.pretty.html
new file mode 100644
index 0000000..3d525ce
--- /dev/null
+++ b/2022-01-20-gopher-setup.pretty.html
@@ -0,0 +1,252 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<!-- 2022-01-21 Fri 15:42 -->
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<title></title>
+<meta name="generator" content="Org mode" />
+<style type="text/css">body{margin:40px
+auto;max-width:900px;line-height:1.6;font-size:18px;color:#444;padding:0
+10px}h1,h2,h3{line-height:1.2}</style>
+<script type="text/javascript">
+// @license magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt Public Domain
+<!--/*--><![CDATA[/*><!--*/
+ function CodeHighlightOn(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.add("code-highlighted");
+ target.classList.add("code-highlighted");
+ }
+ }
+ function CodeHighlightOff(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.remove("code-highlighted");
+ target.classList.remove("code-highlighted");
+ }
+ }
+ /*]]>*///-->
+// @license-end
+</script>
+<script type="text/x-mathjax-config">
+ MathJax.Hub.Config({
+ displayAlign: "center",
+ displayIndent: "0em",
+
+ "HTML-CSS": { scale: 100,
+ linebreaks: { automatic: "false" },
+ webFont: "TeX"
+ },
+ SVG: {scale: 100,
+ linebreaks: { automatic: "false" },
+ font: "TeX"},
+ NativeMML: {scale: 100},
+ TeX: { equationNumbers: {autoNumber: "AMS"},
+ MultLineWidth: "85%",
+ TagSide: "right",
+ TagIndent: ".8em"
+ }
+});
+</script>
+<script type="text/javascript"
+ src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS_HTML"></script>
+</head>
+<body>
+<div id="content">
+<div id="table-of-contents">
+<h2>Table of Contents</h2>
+<div id="text-table-of-contents">
+<ul>
+<li><a href="#org38b106d">1. Setting up a Gopher Server</a></li>
+<li><a href="#org883f119">2. Basics</a></li>
+<li><a href="#org6abbb92">3. CGI</a>
+<ul>
+<li><a href="#org56a7a28">3.1. Footguns and Hangups</a></li>
+<li><a href="#org86dfa63">3.2. Helpful Patterns</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div id="outline-container-org38b106d" class="outline-2">
+<h2 id="org38b106d"><span class="section-number-2">1</span> Setting up a Gopher Server</h2>
+<div class="outline-text-2" id="text-1">
+<p>
+Hey folks! In this post I'm going to talk a bit about setting
+up my Gopher server and some of the choices I made in doing so.
+</p>
+
+<p>
+I hope this is helpful to anyone who stumbles onto this article!
+</p>
+
+<p>
+Disclaimer: I'm only a few weeks into learning about Gopher
+and the so-called "indie-net", so this article may not
+represent the better part of community knowledge, or
+"best practices".
+</p>
+</div>
+</div>
+
+<div id="outline-container-org883f119" class="outline-2">
+<h2 id="org883f119"><span class="section-number-2">2</span> Basics</h2>
+<div class="outline-text-2" id="text-2">
+<p>
+I'll just rattle these off quickly so that we don't need to spend
+too much time on them:
+</p>
+
+<ul class="org-ul">
+<li>Server: Ubuntu VPS</li>
+<li>Gopher Server: Motsognir</li>
+</ul>
+
+<p>
+I won't cover the basics of setting up Motsognir or a basic Gopher
+map, as others have already done a great job covering these topics.
+</p>
+
+<p>
+Checkout the following WWW links on the topic:
+<a href="https://gopher.zone/">https://gopher.zone/</a>
+<a href="https://usermanual.wiki/Document/manual.488145643/help">https://usermanual.wiki/Document/manual.488145643/help</a>
+</p>
+</div>
+</div>
+
+<div id="outline-container-org6abbb92" class="outline-2">
+<h2 id="org6abbb92"><span class="section-number-2">3</span> CGI</h2>
+<div class="outline-text-2" id="text-3">
+<p>
+Because Gopher is a pretty simple protocol spec, I wanted to
+not serve static gopher maps and instead implement everything
+as a CGI script. This allows me to be pretty flexible with
+the formatting and configuration of the site:
+</p>
+
+<ul class="org-ul">
+<li>Can provide a 'plain' non ANSI escape sequence cluttered
+version of the site for users who prefer the minimalism
+of uniform text/chars</li>
+<li>Can provide interesting tidbits like Last Modification
+date of the site and # of uniq visitors</li>
+<li>Silly stuff like intermediate http requests (server side)
+to my git server so that I can serve all of my git website
+natively in Gopher</li>
+</ul>
+
+<p>
+The CGI source is actually available to view live, see:
+<a href="gopher://chate.io/0/foobar.txt">gopher://chate.io/0/foobar.txt</a>
+</p>
+
+<p>
+Note: The Gopher server Gophernicus actually offers what I
+think is an even cooler way of doing this, with what it calls
+moles. Check it out: <a href="https://github.com/gophernicus/gophernicus">https://github.com/gophernicus/gophernicus</a>
+</p>
+
+<p>
+I may move over to gophernicus at some point, but for now
+I'm enjoying the ease of use of Motsognir.
+</p>
+
+<p>
+On that topic, to get all the CGI stuff working correctly
+I had to set the following values in the Motsognir config
+file. The config file is awesome, and well documented, but
+as a newcomer to the protocol it was somewhat confusing
+to get it configured right, so I've provided the following:
+</p>
+
+<p>
+GopherCgiSupport=1
+SubGophermaps=1
+DefaultGophermap=
+</p>
+
+<p>
+I'd encourage reading the comments for each of these settings
+for a clearer understanding of what they're doing, but I leave
+this exercise to the reader.
+</p>
+</div>
+
+<div id="outline-container-org56a7a28" class="outline-3">
+<h3 id="org56a7a28"><span class="section-number-3">3.1</span> Footguns and Hangups</h3>
+<div class="outline-text-3" id="text-3-1">
+<p>
+A few things I learned trying to always dynamically
+generate my gophermap:
+</p>
+
+<ul class="org-ul">
+<li>Clients can be finnicky and the protocl spec seems
+to be not super well agreed upon by client
+implimenters
+– Some clients will not correctly parse info
+ lines if there is a " " after the i
+– Some clients will seemingly ignore info lines
+– Some clients don't mind if you don't have a "."
+ char at the EOF, others seem to really care
+ — Apparently the "." at EOF is part of the spec,
+ so it really should be there
+– Some clients will automagically parse out any ANSI
+ escape sequnces, others will interpret them correctly,
+ and others will barf them to the screen literally
+ — To my knowledge there is nothing in the spec for
+ handling this, so client implementers can't be blamed
+– Some gopher servers will helpfully auto fill lines in a
+ map that don't contain <TAB>$host<$TAB>$port. I learned
+ that motsognir will do this on a statically served map,
+ but (in hindsight, obviously), not a dynamically
+ generated one, so make sure you're filling that out</li>
+</ul>
+</div>
+</div>
+
+<div id="outline-container-org86dfa63" class="outline-3">
+<h3 id="org86dfa63"><span class="section-number-3">3.2</span> Helpful Patterns</h3>
+<div class="outline-text-3" id="text-3-2">
+<p>
+A few helpful patterns I've employed while writing my CGI
+scripts:
+</p>
+
+<ul class="org-ul">
+<li><p>
+Establish an interface for printing your gopher map. I use
+a function that takes 3 args: $gopher<sub>menu</sub><sub>type</sub>, $string,
+$rest.
+</p>
+
+<p>
+The idea being that you call the function this way:
+g<sub>print</sub>("1","Some Dir","\t$path\t$hostname\t$port");
+</p>
+
+<p>
+This function will then, depending on what/if it gets
+a CGI query parameter, will either randomly colorize
+the output or not, allowing the site to be easily rendered
+one way or another.
+</p></li>
+
+<li>As with stuff on WWW, make sure your CGI scripts are
+executing quickly, otherwise the client will be left waiting</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+<div id="postamble" class="status">
+<p class="date">Created: 2022-01-21 Fri 15:42</p>
+</div>
+</body>
+</html>
diff --git a/2022-01-20-keypro-fk-9000-docs.html b/2022-01-20-keypro-fk-9000-docs.html
new file mode 100644
index 0000000..b5977d8
--- /dev/null
+++ b/2022-01-20-keypro-fk-9000-docs.html
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<!-- 2022-01-20 Thu 13:06 -->
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<title></title>
+<meta name="generator" content="Org mode" />
+<style type="text/css">body{margin:40px
+auto;max-width:900px;line-height:1.6;font-size:18px;color:#444;padding:0
+10px}h1,h2,h3{line-height:1.2}</style>
+<script type="text/javascript">
+// @license magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt Public Domain
+<!--/*--><![CDATA[/*><!--*/
+ function CodeHighlightOn(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.add("code-highlighted");
+ target.classList.add("code-highlighted");
+ }
+ }
+ function CodeHighlightOff(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.remove("code-highlighted");
+ target.classList.remove("code-highlighted");
+ }
+ }
+ /*]]>*///-->
+// @license-end
+</script>
+</head>
+<body>
+<div id="content">
+<div id="table-of-contents">
+<h2>Table of Contents</h2>
+<div id="text-table-of-contents">
+<ul>
+<li><a href="#org348f716">1. Keypro FK-9000</a>
+<ul>
+<li><a href="#org42ef4d6">1.1. Backstory/Info</a></li>
+<li><a href="#org23dab99">1.2. Docs (Useful Info)</a></li>
+<li><a href="#orgb5939bc">1.3. Examples (Less Useful Info)</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div id="outline-container-org348f716" class="outline-2">
+<h2 id="org348f716"><span class="section-number-2">1</span> Keypro FK-9000</h2>
+<div class="outline-text-2" id="text-1">
+</div>
+<div id="outline-container-org42ef4d6" class="outline-3">
+<h3 id="org42ef4d6"><span class="section-number-3">1.1</span> Backstory/Info</h3>
+<div class="outline-text-3" id="text-1-1">
+<p>
+This is a pretty interesting keyboard. At the end of the post
+I'll render an UNICODE ascii picture of it for those interested.
+</p>
+
+<p>
+I wanted to write something quickly as a documentation exercise
+and as something perhaps useful to others.
+</p>
+
+<p>
+I've had this old Keypro FK-9000 and Soarer Converter lying
+around for a couple of years now and I had yet to play with it.
+</p>
+
+<p>
+So, last night, I finally decided to check it out.
+</p>
+
+<p>
+Basically it's an old 5 PIN keyboard that has a few cool tricks:
+</p>
+<ul class="org-ul">
+<li>built in calculator and lcd
+<ul class="org-ul">
+<li>You can hit a latching key on the keyboard and
+the numpad input will then be sent to the little
+on board LCD screen</li>
+</ul></li>
+<li>12 on board programmable macro keys</li>
+</ul>
+
+<p>
+The Soarer Converter cable I have, which as I understand is basically
+an atmega chip shoved into a cable, also allows me to remap keys as the
+scan codes come into the converter, before they get to the computer.
+</p>
+</div>
+</div>
+
+<div id="outline-container-org23dab99" class="outline-3">
+<h3 id="org23dab99"><span class="section-number-3">1.2</span> Docs (Useful Info)</h3>
+<div class="outline-text-3" id="text-1-2">
+<p>
+It took me a while to figure out how to program the keys
+so for any future readers hopefully this will help:
+</p>
+
+<ol class="org-ol">
+<li>Open a text editor</li>
+<li>Hold the `Prog` key and hit the key you want to
+program (PF1-12)</li>
+<li>Enter the key sequence you'd like to program</li>
+<li>Hit the key you want to program again</li>
+</ol>
+
+<p>
+Example:
+</p>
+
+<p>
+Prog->PF1sometringPF1
+</p>
+
+<p>
+This will also work with CTRL,RETURN,ALT,etc, however
+the macros all have a 14 char limit, with control chars
+taking up 2 chars.
+</p>
+</div>
+</div>
+
+<div id="outline-container-orgb5939bc" class="outline-3">
+<h3 id="orgb5939bc"><span class="section-number-3">1.3</span> Examples (Less Useful Info)</h3>
+<div class="outline-text-3" id="text-1-3">
+<p>
+Here I'm going to document my own macros:
+</p>
+
+<ul class="org-ul">
+<li>PF11: Ctrl-G – Emacs escape hatch/escape/stop</li>
+<li>PF1: Ctrl-x-b – Emacs switch buffer menu</li>
+<li>PF2: Ctrl-x-b-RETURN – Based on Ido menu ordering
+behaves as switch to last
+buffer</li>
+<li>PF3: Ctrl-x-Ctrl-f – Open file</li>
+<li>PF4: Ctrl-c-Ctrl-f – Open file at point</li>
+<li>PF5: M-xeshell-RETURN – Open eshell</li>
+<li>PF7: Ctrl-x-5-2 – Open new emacs frame (window for non emacsers)</li>
+<li>PF8: Ctrl-x-5-0 – Close emacs frame</li>
+<li>PF9: gT – literally gT, AKA previous tab in vim/evil mode</li>
+<li>PF10: gt – literally gt, next tab in vim/evil mode</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+<div id="postamble" class="status">
+<p class="date">Created: 2022-01-20 Thu 13:06</p>
+<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
+</div>
+</body>
+</html>
diff --git a/2022-01-20-keypro-fk-9000-docs.org b/2022-01-20-keypro-fk-9000-docs.org
new file mode 100644
index 0000000..22979f8
--- /dev/null
+++ b/2022-01-20-keypro-fk-9000-docs.org
@@ -0,0 +1,60 @@
+* Keypro FK-9000
+
+** Backstory/Info
+ This is a pretty interesting keyboard. At the end of the post
+ I'll render an UNICODE ascii picture of it for those interested.
+
+ I wanted to write something quickly as a documentation exercise
+ and as something perhaps useful to others.
+
+ I've had this old Keypro FK-9000 and Soarer Converter lying
+ around for a couple of years now and I had yet to play with it.
+
+ So, last night, I finally decided to check it out.
+
+ Basically it's an old 5 PIN keyboard that has a few cool tricks:
+ - built in calculator and lcd
+ - You can hit a latching key on the keyboard and
+ the numpad input will then be sent to the little
+ on board LCD screen
+ - 12 on board programmable macro keys
+
+ The Soarer Converter cable I have, which as I understand is basically
+ an atmega chip shoved into a cable, also allows me to remap keys as the
+ scan codes come into the converter, before they get to the computer.
+
+** Docs (Useful Info)
+
+ It took me a while to figure out how to program the keys
+ so for any future readers hopefully this will help:
+
+ 1. Open a text editor
+ 2. Hold the `Prog` key and hit the key you want to
+ program (PF1-12)
+ 3. Enter the key sequence you'd like to program
+ 4. Hit the key you want to program again
+
+ Example:
+
+ Prog->PF1sometringPF1
+
+ This will also work with CTRL,RETURN,ALT,etc, however
+ the macros all have a 14 char limit, with control chars
+ taking up 2 chars.
+
+** Examples (Less Useful Info)
+
+ Here I'm going to document my own macros:
+
+ - PF11: Ctrl-G -- Emacs escape hatch/escape/stop
+ - PF1: Ctrl-x-b -- Emacs switch buffer menu
+ - PF2: Ctrl-x-b-RETURN -- Based on Ido menu ordering
+ behaves as switch to last
+ buffer
+ - PF3: Ctrl-x-Ctrl-f -- Open file
+ - PF4: Ctrl-c-Ctrl-f -- Open file at point
+ - PF5: M-xeshell-RETURN -- Open eshell
+ - PF7: Ctrl-x-5-2 -- Open new emacs frame (window for non emacsers)
+ - PF8: Ctrl-x-5-0 -- Close emacs frame
+ - PF9: gT -- literally gT, AKA previous tab in vim/evil mode
+ - PF10: gt -- literally gt, next tab in vim/evil mode
diff --git a/2022-01-20-keypro-fk-9000.pretty.html b/2022-01-20-keypro-fk-9000.pretty.html
new file mode 100644
index 0000000..b5977d8
--- /dev/null
+++ b/2022-01-20-keypro-fk-9000.pretty.html
@@ -0,0 +1,162 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+<head>
+<!-- 2022-01-20 Thu 13:06 -->
+<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
+<meta name="viewport" content="width=device-width, initial-scale=1" />
+<title></title>
+<meta name="generator" content="Org mode" />
+<style type="text/css">body{margin:40px
+auto;max-width:900px;line-height:1.6;font-size:18px;color:#444;padding:0
+10px}h1,h2,h3{line-height:1.2}</style>
+<script type="text/javascript">
+// @license magnet:?xt=urn:btih:e95b018ef3580986a04669f1b5879592219e2a7a&dn=public-domain.txt Public Domain
+<!--/*--><![CDATA[/*><!--*/
+ function CodeHighlightOn(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.add("code-highlighted");
+ target.classList.add("code-highlighted");
+ }
+ }
+ function CodeHighlightOff(elem, id)
+ {
+ var target = document.getElementById(id);
+ if(null != target) {
+ elem.classList.remove("code-highlighted");
+ target.classList.remove("code-highlighted");
+ }
+ }
+ /*]]>*///-->
+// @license-end
+</script>
+</head>
+<body>
+<div id="content">
+<div id="table-of-contents">
+<h2>Table of Contents</h2>
+<div id="text-table-of-contents">
+<ul>
+<li><a href="#org348f716">1. Keypro FK-9000</a>
+<ul>
+<li><a href="#org42ef4d6">1.1. Backstory/Info</a></li>
+<li><a href="#org23dab99">1.2. Docs (Useful Info)</a></li>
+<li><a href="#orgb5939bc">1.3. Examples (Less Useful Info)</a></li>
+</ul>
+</li>
+</ul>
+</div>
+</div>
+<div id="outline-container-org348f716" class="outline-2">
+<h2 id="org348f716"><span class="section-number-2">1</span> Keypro FK-9000</h2>
+<div class="outline-text-2" id="text-1">
+</div>
+<div id="outline-container-org42ef4d6" class="outline-3">
+<h3 id="org42ef4d6"><span class="section-number-3">1.1</span> Backstory/Info</h3>
+<div class="outline-text-3" id="text-1-1">
+<p>
+This is a pretty interesting keyboard. At the end of the post
+I'll render an UNICODE ascii picture of it for those interested.
+</p>
+
+<p>
+I wanted to write something quickly as a documentation exercise
+and as something perhaps useful to others.
+</p>
+
+<p>
+I've had this old Keypro FK-9000 and Soarer Converter lying
+around for a couple of years now and I had yet to play with it.
+</p>
+
+<p>
+So, last night, I finally decided to check it out.
+</p>
+
+<p>
+Basically it's an old 5 PIN keyboard that has a few cool tricks:
+</p>
+<ul class="org-ul">
+<li>built in calculator and lcd
+<ul class="org-ul">
+<li>You can hit a latching key on the keyboard and
+the numpad input will then be sent to the little
+on board LCD screen</li>
+</ul></li>
+<li>12 on board programmable macro keys</li>
+</ul>
+
+<p>
+The Soarer Converter cable I have, which as I understand is basically
+an atmega chip shoved into a cable, also allows me to remap keys as the
+scan codes come into the converter, before they get to the computer.
+</p>
+</div>
+</div>
+
+<div id="outline-container-org23dab99" class="outline-3">
+<h3 id="org23dab99"><span class="section-number-3">1.2</span> Docs (Useful Info)</h3>
+<div class="outline-text-3" id="text-1-2">
+<p>
+It took me a while to figure out how to program the keys
+so for any future readers hopefully this will help:
+</p>
+
+<ol class="org-ol">
+<li>Open a text editor</li>
+<li>Hold the `Prog` key and hit the key you want to
+program (PF1-12)</li>
+<li>Enter the key sequence you'd like to program</li>
+<li>Hit the key you want to program again</li>
+</ol>
+
+<p>
+Example:
+</p>
+
+<p>
+Prog->PF1sometringPF1
+</p>
+
+<p>
+This will also work with CTRL,RETURN,ALT,etc, however
+the macros all have a 14 char limit, with control chars
+taking up 2 chars.
+</p>
+</div>
+</div>
+
+<div id="outline-container-orgb5939bc" class="outline-3">
+<h3 id="orgb5939bc"><span class="section-number-3">1.3</span> Examples (Less Useful Info)</h3>
+<div class="outline-text-3" id="text-1-3">
+<p>
+Here I'm going to document my own macros:
+</p>
+
+<ul class="org-ul">
+<li>PF11: Ctrl-G – Emacs escape hatch/escape/stop</li>
+<li>PF1: Ctrl-x-b – Emacs switch buffer menu</li>
+<li>PF2: Ctrl-x-b-RETURN – Based on Ido menu ordering
+behaves as switch to last
+buffer</li>
+<li>PF3: Ctrl-x-Ctrl-f – Open file</li>
+<li>PF4: Ctrl-c-Ctrl-f – Open file at point</li>
+<li>PF5: M-xeshell-RETURN – Open eshell</li>
+<li>PF7: Ctrl-x-5-2 – Open new emacs frame (window for non emacsers)</li>
+<li>PF8: Ctrl-x-5-0 – Close emacs frame</li>
+<li>PF9: gT – literally gT, AKA previous tab in vim/evil mode</li>
+<li>PF10: gt – literally gt, next tab in vim/evil mode</li>
+</ul>
+</div>
+</div>
+</div>
+</div>
+<div id="postamble" class="status">
+<p class="date">Created: 2022-01-20 Thu 13:06</p>
+<p class="validation"><a href="https://validator.w3.org/check?uri=referer">Validate</a></p>
+</div>
+</body>
+</html>