(DIR) Josip Tišljar Mataušić (9A3SFZ)
       Published on: 2026-05-30
       
       Gopher is an old protocol for sure, but being old, it's also very
       minimal, making it perfect for browsing on low-bandwidth connections.
       However, it doesn't use HTML, instead, it uses its own, also very
       minimal, format called Gophermap.
       
       
       Gophermap structure
       
       !This is a title
       
       sA link to an Audio file TAB /audio.mp3 TAB gopher.radioz.org TAB 70
       ||---------------------|     |--------|     |---------------|    |--|
       |     Visible text        Destination path  Destination host     Port
       |
       Tells the client what file type to expect - a sound file
       
       iOrdinarry text (not a link) TAB /this TAB can.be.anything TAB 9258
       ||-------------------------| |------------------------------------|
       |       Visible text             Ignored, but still required
       |
       Denotes plain text, as oppose to a link
       
       As you can see, this is quite different from HTML. Even if I
       converted all of my markdown posts to Gophermaps there was no way I
       was going to maintain two versions of every article!
       
       Therefore, I decided to make a program that will read existing posts,
       automatically convert them to Gophermaps, generate the Latest and
       Related sections, add the date of publication and everything else.
       
       My goal was to have the same level of automation for Gopher as I have
       for the Web, so that publishing to Gopher doesn't become a chore.
       Furthermore, I wanted to be able to substitute <script> tags, which I
       often use to integrate various calculators to posts, with server-side
       PHP scripts that will provide the same kind of functionality on
       Gopher.
       
       This all led me to create a complex stack of scripts to achieve
       exactly what I wanted. Some of them are written by me, some of them
       are not.
       
       
       Markdown --> Gophermap
       
       I only found one program[1] that can convert markdown directly to a
       gophermap in a reliable way, however, I wasn't satisfied with how it
       handled converting inline links to footnote links. After many more
       searches that yielded nothing, an idea struck: Okay, there are no
       good markdown to gophermap converters, but what about markdown to
       gemtext converters?
       
 (HTM) 1: https://github.com/theobori/lueur
       
       For those unfamiliar, Gemtext is another "hypertext" format. It's
       similar to gophermaps in terms of features. (the main difference
       being that Gemtext also supports subtitles and code blocks).
       
       I found exactly what I wanted, md2gemini[2] nicely converted inline
       links to footnotes. Now I just had to write a simple script that can
       convert gemtext to gophermap. This is a lot simpler than writing a
       script that deals with markdown directly. I completed the task in a
       couple of hours.
       
 (HTM) 2: https://github.com/makew0rld/md2gemini
       
       If you want to use the script yourself here it is[3]. It's built so
       that you can pipe output from md2gemini directly to it:
       
 (HTM) 3: https://git.radioz.org/pisoj/gemtext2gophermap
       
       md2gemini -l paragraph -f -a -p my-post.md | ./gemtext2gophermap -
       gophermap
       
       As per the readme, this script also handles injecting gopher specific
       content into the final gophermap.
       
       
       Generating Latest and Related sections
       
       Now that I figured out how to convert markdown posts to gophermaps,
       it was time for making another script that would put all of that
       together. This was hard because there is no static-site generator for
       Gopher. It also didn't help that I chose to write the script in Bash
       for some, yet undiscovered, reason.
       
       A list of all the things the script had to do:
       - Extract metadata from the header of a markdown file
       - Put the title, author, date of publication, date of last update and
       - a list of other languages at the beginning of every post
       - Convert paths that Astro normally handles (like ../../assets) to
       - the ones Gopher can handle
       - Figure out which posts should have a link in the main menu
       - Generate Latest, Related and Featured sections at the end of every
       - post
       
       If you want to take a look at the strange regexes I used to parse
       markdown and yaml, as well as everything else mentioned in the list
       the script is here[4].
       
 (TXT) 4: /process-file.sh
       
       At the end, I used a Makefile to streamline the process of installing
       md2gemini and gemtext2gophermap, as well as to run the aforementioned
       script on every post.
       
       
       Supporting multiple domains
       
       I still do not have the ability to BGP peer on Hamnet so I'm stuck
       with addresses they give me through vpn.hamnet.network. This means
       that I need two separate domains, one pointing to Internet addresses
       and another one pointing to Hamnet addresses of the server.
       
       Doing this on the Web is easy, you just have a link like /about and
       the browser will preserve the domain. On Gopher, however, every link
       needs to specify a domain and a port, even if those do not change.
       Luckily, my server of choice[5] automatically adds the domain and
       port at the end of every line. This means that I can leave it up to
       the server to decide which domain a link will point to.
       
 (HTM) 5: https://github.com/gophernicus/gophernicus
       
       But how can the server know which domain a client uses? There is no
       Host header in Gopher. - Simple, not only are the domains different,
       but IP addresses are as well, so I can have one  server instance
       configured for the Internet domain and bound to the Internet IPs and
       another instance configured for the Hamnet domain and bound to Hamnet
       IPs.
       
       Of course, this is only possible if your server has multiple IP
       addresses, if it doesn't, well, you're out of luck. (Yet another
       reason to push for IPv6)
       
       
       
       Accessing RadioZ via Gopher
       
       To access Gopher, you need a Gopher client. Common ones include:
       - Lagrange[6] (Win/Mac/Linux/Android/iOS)
       - Kristall[7] (Win/Mac/Linux/BSD)
       - Gopher Browser[8] (Windows)
       - Gophie[9] (Win/Mac/Linux)
       - Bombadillo[10] (Linux/BSD) (no-GUI)
       
 (HTM) 6: https://gmi.skyjake.fi/lagrange/
 (HTM) 7: https://kristall.random-projects.net/
 (HTM) 8: https://www.jaruzel.com/gopher/gopher-client-browser-for-windows/
 (HTM) 9: https://gophie.org/
 (HTM) 10: https://bombadillo.colorfield.space/
       
       You can also use a Gopher to Web proxy[11].
       
 (HTM) 11: https://portal.mozz.us/
       
       --------------------------------------------------------------------------------
       
       In any case, these are the URLs:
       
 (DIR) gopher://gopher.radioz.org
 (DIR) gopher://hamnet.gopher.radioz.org
       
       
       
       
       Related
       
 (DIR) 2026-04-27 Test your HAMNET IPv6 setup
       
       
       
       Latest
       
 (DIR) 2026-05-06 Easy IPv4 to IPv6 proxy
 (DIR) 2026-04-27 Test your HAMNET IPv6 setup
 (DIR) 2026-03-29 IPv6 on HAMNET with 6to4
 (DIR) 2026-03-22 AMPRNet IPIP with systemd-networkd
       
       --------------------------------------------------------------------------------
       
 (DIR) Home
 (DIR) Logbook