sutter
A static HTML blog / Gemini capsule generator
Features
- Lightweight (written in C, no dependencies on libraries nor programs)
- Multithreaded
- Simple as hell
Description
sutter (as in "Do you read Sutter Cane...?") is a standalone program which duty is to explore a directory of files (with as many subdirectory levels as desired) and generate an HTML-based blog and a Gemini capsule with the same directory hierarchy as possible.
Files with the extensions .html, .gmi, .md, .raw_html and .raw_gmi are considered by sutter to be special "source" files. These files can have a set of metadata appended to the end, like the post entry title, the publishing date and the author information. These metadata is looked up after a line containing the string __META__ on its own. If sutter finds a "source" file that does not contain this metadata, it adds it with some default values. Source file links and references are added to the indexes (more below).
The processor does the following to each type of file found:
- HTML (
.html) files: adds a common header and footer and writes the result to thewwwoutput directory. - Gemini (
.gmi) files: does two things: adds a common header and footer and writes the result to thegmioutput directory; also, it converts the entry to HTML with a common header and footer and writes the result to thewwwdirectory. - Markdown (
.md) file: converts the entry to HTML with a common header and footer and writes the result to thewwwdirectory. This is a special subset of Markdown (see below) and no external tools are called nor needed. - Raw HTML (
.raw_html) files: copies the file as is (renamed with an.htmlextension) to thewwwdirectory. - Raw Gemini (
.raw_gmi) files: copies the file as is (renamed with a.gmiextension) to thegmioutput directory. - The rest of the files are hard-linked from the
srcdirectory to both output directories.
The following indexes are updated for each processed file:
- For HTML and converted Gemini files:
www/rss.xml,www/archive.htmlandwww/sitemap.xml. - For Gemini files:
gmi/archive.gmi.
Files that have not changed are not rewritten to be gentle to rsync and similar tools that may transfer the blog/capsule to another host.
Building and installation
Run make and then make install as root.
Usage
sutter has the following commands:
sutter init [{storage directory}]
Prompts for some basic information and creates an empty directory storage (see below).
sutter run {storage directory}
Does its thing and builds the content of the output directories.
sutter check {storage directory}
Checks that all entries in the storage directory have metadata and, for those that don't, adds it. The run command implies this.
sutter 2html {Markdown or Gemini file}
Converts a Markdown (.md) or Gemini (.gmi) file to HTML to STDOUT. Take note that you don't need a sutter storage for this operation to work.
Storage directory file hierarchy
The following files and directories are inside a sutter storage directory:
src/: The source directory. This is where you will create your source files.www/: The directory where the Weblog is generated. This is what you will transfer to a directory in your HTTP server.gmi/: The directory where the Gemini capsule is generated. This is what you will transfer to a directory in your Gemini server.sutter.json: The configuration file (see below).sutter.css: A tiny CSS file that will be inserted into all you HTML files.
Configuration directives
The sutter.json file is a JSON file with the following fields:
title: The blog/capsule title. Will be inserted in all titles and as the main 'back to top' link.baseurl: The base URL for your blog.suttertries to build all links as relative, but some things like the RSS file needs a complete base URL.author_name: You (the default author).author_email: Your email.author_avatar: The URL to an image to be used as an avatar for your posts. If it's not defined, a Gravatar created using yourauthor_emailwill be used instead.srcdir,wwwdirandgmidir: The subdirectory names inside thesutterdirectory. You can change them, but don't need to.dbglevel: The debug level. The higher the number, the loudersutterwill chat about what it's doing. You can override this by setting theDEBUGenvironment variable to a matching value.minimum_date: If an entry has a date metadata (inyyyy-mm-ddTHH:MM:SSZformat) older than this one, it will NOT be added to any index (but generated as well).cssurls: An array of URLs to CSS files that will be added to all HTML headers.num_rss_entries: The number of post entries in the RSS file (default: 10).
File metadata
File metadata fields appear after the META line in the source files as a keyword, a colon, a space and a content. They can be:
title: The entry title. If not defined,sutterwill try to create one. Of course, you can always re-edit the file to change it.date: The publishing date inyyyy-mm-ddTHH:MM:SSZformat. If this field is not defined,sutterwill create one from the file date. If a file has a date that is in the future or older than the one defined in theminimum_datefield of the configuration file, it's generated but NOT added to any index.lang: A two-letter identifier of the language the entry is written in.keywords: A comma-separated list of keywords that tag the entry.author_name,author_emailandauthor_avatar: If these fields exist, they are used instead of the values defined in the configuration file. Useful for guest contributions (you have those, don't you?).
Special URIs
Special markup that look like URIs (i.e. a keyword followed by a colon and two slashes) can be used as shortcuts for some HTML tagsets that are somewhat cumbersome to write. They can be used in .html and .md files. They can be:
img ://image.jpg An img tag for image files
img ://image.jpg/css_class An img tag wrapped in a css_class
story ://path/to_entry A link to an entry
story ://path/to_entry (link label) A link to an entry with a label
link ://example.host/path/path An http link to an URL
link ://example.host/path/path (label) An http link to an URL with a label
links ://example.host/path/path An https link to an URL
links ://example.host/path/path (label) An https link to an URL with a label
Markdown
The subset of Markdown implemented by sutter allows:
- Italic, bold and monospaced text using one asterisk, two asterisks and backticks;
- Strikethought text surrounded by two tildes;
- Preformatted text surrounded by lines starting with three backticks;
- Headers for lines prefixed with one, two or three hash symbols;
- Bullet lists for lines prefixed by hyphens;
- Blockquotes for paragraphs prefixed with the greater-than symbol.
Since version 1.02, Markdown links in the URL label format are supported.
Since version 1.04, Markdown images (like links, but prefixed by a !, and with the label used as the caption and alt text) are supported.
Also since version 1.04, simple Markdown tables are supported, like the following:
| Header 1 | Header 2 | Header 3 |
|---|---|---|
| Cell 1.1 | Cell 1.2 | Cell 1.3 |
| Cell 2.1 | 2.3 (previous one is empty) | |
| Cell 3.1 | Cell 3.2 | A somewhat longer cell content |
Gemini
Gemini files are converted to HTML in a straightforward way. Also, square-bracketed references in paragraph texts are converted to links if there is a link below that starts with the same reference. For example:
Magpies [1] are very intelligent birds.
=> https://en.wikipedia.org/wiki/Magpie [1] Magpie page in Wikipedia
More information
Sutter Cane is the horror writer from John Carpenter's movie In The Mouth Of Madness.
I CAN SEE
License
See the LICENSE file for details.
Author
grunfink @grunfink@comam.es with the help of others.
Buy grunfink a coffee: https://ko-fi.com/grunfink