Midnight Pub

A little experiment

~starbreaker

I've decided to try a little experiment, since it occurred to me that most of what I put on my website is just text. I've decided to make my site a single HTML page linking to a bunch of TXT files.

But since I'm so used to Markdown, all of my posts are Markdown-formatted in case I change my mind—or figure out how to combine Markdown with HTML that uses M4 macros...

Here's a little more on the subject if anybody cares.

Writing HTML in TXT

m15o

I love that experiment of yours! I've found in your bookmarks that one on emacs and I thought to myself "hey, I never really tried emacs". So thanks to you, that's what I've spend most of my time on for a few days now!

reply

starbreaker

Thanks. I've been using Emacs for years, because it's actually a better text editor than the joke about it being an operating system suggests. At least for composition. Nothing beats vi for precise revisions. :)

However, I think I'm going to go back to HTML with m4 macros. But instead of writing posts in HTML, I'll write them in Markdown, run them through a converter and pipe them into the clipboard, and then paste text into my page.

reply

pink2ds

Markdown was designed to easily be able to convert to HTML so that's not going to be a problem going forward. (Just make sure to keep your old Markdown originals around, too.)

reply

starbreaker

I've got backups, so losing my originals shouldn't be a problem. Besides, I like using makefiles to rebuild my pages when I change the sources.

The problem I've been having is using m4 macros and includes with markdown. When I run m4 before the markdown converter, the resulting HTML comes out mangled.

reply

pink2ds

Whaddayamean mangled? I tried converting a few of them and they look fine.

I tried with pandoc, which just handled it straight up, and kramdown, where I needed to first strip out the YAML preamble. Like this:

sed -e '1,/^---$/d' /tmp/writing-html-in.txt|kramdown
reply

starbreaker

Those .txt files are pure markdown. There aren't any m4 macros.

This is one of the templates I used in the last version of my site. I've found that using pandoc or lowdown to process markdown in this template mangles the HTML that comes out of the includes. But if I write markdown and pipe the output of pandoc/lowdown to xclip, I can paste it into a template instead of doing HTML by hand, so I suppose that will do.

m4_include(website.m4)
m4_define([__title], [])
m4_define([__description], [])
m4_include(article-header.html)
<section>
  
</section>
m4_include(footer.html)

Here are the contents of "website.m4", if you're interested.

m4_divert(-1)
website.m4
© 2021 Matthew Graybosch <contact@matthewgraybosch.com>

Permission to use, copy, modify, and/or distribute this software for
any purpose with or without fee is hereby granted.

THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
m4_divert
m4_changequote(`[',`]')
m4_define([__site], [Matthew Graybosch])
m4_define([__url], [https://matthewgraybosch.com/])
m4_define([__tagline], [author by choice, techie by necessity])
m4_define([__lang], [en-us])
m4_define([__title], [Home])
m4_define([__description], [__tagline()])
m4_define([__copyright], [2021])
m4_define([__feed1], [__url()feed.xml])
m4_define([__feed1_desc], [__site() Atom Feed])
m4_define([__feed2], [__url()100days.xml])
m4_define([__feed2_desc], [__site(): #100DaysToOffload])
m4_define([__style], [__url()assets/css/main.css])
m4_define([__manifest], [__url()assets/text/site.webmanifest])
m4_define([__icon180], [__url()assets/images/apple-touch-icon.png])
m4_define([__icon32], [__url()assets/images/favicon-32x32.png])
m4_define([__icon16], [__url()assets/images/favicon-16x16.png])
m4_define([__og_url], [http://alwaysownyourplatform.com])
m4_define([__og_title], [Boycott Social Media])
m4_define([__og_description], [Please share my website on your own website.])
m4_define([__og_image], [__url()assets/images/no-social.jpg])
m4_define([__webmaster], [webmaster@matthewgraybosch.com])
m4_define([__400], [<q>What we've got here is failure to communicate.</q> ~<i>Cool Hand Luke</i>])
m4_define([__401], [<q>Speak, friend, and enter.</q> ~<i>The Lord of the Rings</i>])
m4_define([__402], [<q>Fuck you. Pay me.</q> ~<i>GoodFellas</i>])
m4_define([__403], [<q>None shall pass.</q> ~<i>Monty Python and the Holy Grail</i>])
m4_define([__404], [<q>Dave's not here, man.</q> ~Cheech & Chong])
m4_define([__410], [<q>He's dead, Jim.</q> ~<i>Star Trek</i>])
m4_define([__451], [<q>It was a pleasure to burn.</q> ~Ray Bradbury, <i>Fahrenheit 451</i>])
m4_define([__500], [<q>Even in the future nothing works.</q> ~<i>Spaceballs</i>])
m4_define([__policy], [default-src 'none'; base-uri 'none'; frame-ancestors 'none'; form-action 'none'; img-src 'self'; style-src __style(); manifest-src __manifest();])
m4_define([__permissions], [accelerometer=(); ambient-light-sensor=(); autoplay=(); battery=(); camera=(); display-capture=(); document-domain=(); encrypted-media=(); execution-while-not-rendered=(); execution-while-out-of-viewport=(); fullscreen=(); geolocation=(); gyroscope=(); layout-animations=(); legacy-image-formats=(); magnetometer=(); microphone=(); midi=(); navigation-override=(); oversized-images=(); payment=(); picture-in-picture=(); publickey-credentials-get=(); sync-xhr=(); vr=(); wake-lock=(); screen-wake-lock=(); web-share=(self); xr-spatial-tracking=();])
m4_define([__license], [rel="license noopener noreferrer"])
m4_define([__safe_rel], [rel="noopener noreferrer"])
m4_define([__nofollow], [rel="noopener noreferrer nofollow"])
m4_define([__newtab], [target="_blank"])
m4_define([__toplink],[<a href="#top" title="return to the top of the page">top</a>])
reply

pink2ds
#!/bin/sh
echo "m4_include(website.m4)
m4_define([__title], [])
m4_define([__description], [])
m4_include(article-header.html)
<section>"
pandoc "$1"
echo "</section>
m4_include(footer.html)"
reply

starbreaker

Thanks. I'm actually embarrassed right now because I think I should have thought of that myself. And if I use printf instead of echo I can pass in the title and description as arguments along with the filename. Then again echo would probably work fine, too, but I'm used to printf because of my feedgen script.

I use this to generate Atom feeds from a tab-delimited file. Though the usage function needs updating.

#!/bin/sh -e

main() {
	test -n "$1" || usage
	test -n "$2" || usage

	url="$1"
	head="$2"
	entries="$3"

	feed_start "$head"
	process_entries "$url" "$entries"
	feed_end ""
}

usage() {
	echo "usage:\n\t${0##*/} <header file> <entries file>" >&2
	echo "\tHeader file is tab-delimited: title, subtitle, link, name, email." >&2
	echo "\tEntries file is tab-delimited: title, link, id, updated, summary." >&2
	echo "\tPlease note that entries file will be read in reverse order." >&2
	exit 1
}

feed_start() {
	title=`cut -f 1 ${1}`
	subtitle=`cut -f 2 ${1}`
	link=`cut -f 3 ${1}`
	updated=`date "+%Y-%m-%dT%H:%M:%S.000-05:00"`
	name=`cut -f 4 ${1}`
	email=`cut -f 5 ${1}`

	printf '<?xml version="1.0" encoding="utf-8"?>\n'
	printf '<feed xmlns="http://www.w3.org/2005/Atom">\n'
	printf '\t<title>%s</title>\n' "$title"
	printf '\t<subtitle>%s</subtitle>\n' "$subtitle"
	printf '\t<link href="%s"/>\n' "$link"
	printf '\t<updated>%s</updated>\n' "$updated"
	printf '\t<author>\n'
	printf '\t\t<name>%s</name>\n' "$name"
	printf '\t\t<email>%s</email>\n' "$email"
	printf '\t</author>\n'
	printf '\t<id>%s</id>\n' "$link"
}

process_entries() {
	url=$1
	while IFS= read -r line
	do
		write_entry "$url" "$line"
	done < $2
}

write_entry() {
	url=$1
	title=`echo "$2" | cut -f 3`
	link=`echo "$2" | cut -f 2`
	updated=`echo "$2" | cut -f 1`
	summary=`echo "$2" | cut -f 4`
	
	printf '\t<entry>\n'
	printf '\t\t<title>%s</title>\n' "$title"
	printf '\t\t<link rel="alternate" href="%s%s"/>\n' "$url" "$link"
	printf '\t\t<id>%s%s</id>\n' "$url" "$link"
	printf '\t\t<updated>%sT23:58:00.000-0500</updated>\n' "$updated"
	printf '\t\t<summary>%s</summary>\n' "$summary"
	printf '\t</entry>\n'
}

feed_end() {
	printf '</feed>\n'
}

main "$@"
reply

pink2ds

Btw, pandoc has support for templates.

m4_include(website.m4)
m4_define([__title], [])
m4_define([__description], [])
m4_include(article-header.html)
<section>
$body$
</section>
m4_include(footer.html)

(Or you might not even need to use m4 if you used pandoc's templates.)

reply

starbreaker

Thanks, but I've tried pandoc templates for html. I find them better suited for converting novel drafts to Word using a publisher's house style. :) The problem is that if I want to use a different set of <header> and <footer> blocks for my home page vs other pages, or for posts vs pages, that ends up complicating my makefile unless I set variables in my YAML block to control which parts of the template get rendered (since pandoc's include_before and include_after affect what goes before and after <body>. If I stick with m4, I can just include the appropriate headers and footers in individual files and apply a single transform.

Also, I don't want to be too dependent on pandoc. It's a pain in the ass to build on OpenBSD since there isn't a port/package for it. I've just been using pandoc as an example of a markdown converter because I figure it's better-known than other tools. I've been using m4 because it comes with OpenBSD's default install.

reply

pink2ds

Right, so what you could do is make a pandoc template that writes an m4 template just like my last example there.

reply

starbreaker

Thanks for the suggestion, but after a month of monkeying around instead of writing I just gave up and went back to WordPress. :)

reply

pink2ds

YW♥

blog.webb.page is annoying but somewhat readable, since the text is hardwrapped.

Which is definitely a very bad idea to do on Gemini, with Gemini text, but good for Markdown.

reply

maya

Hmm! On the one hand, I like his blog and yours! On the other hand, it's unusual to have to do so much scrolling sideways? Obviously it doesn't normally matter when Markdown gets rendered out, but some mid-sentence line breaks wouldn't go amiss for this presentation style.

reply

starbreaker

I could manually break lines at 80 columns, but the fundamental problem with serving plain text on the web seems to be that most browsers don't wrap long lines in .txt files. Firefox does (and there's a toggle for it in about:config), but Chrome doesn't and 80-column text gets mangled in mobile unless you set your device to landscape mode.

Dammit.

reply