SBLG(1) General Commands Manual SBLG(1)

simple off-line blog utility

sblg [
] [
-C file
] [
-o file
] [
-s sort
] [
-t template
] file ...

The sblg utility knits together XML articles and templates in a number of ways.
By default, sblg operates in blog mode as if “sblg -o blog.html -t blog-template.xml ...” were specified. Its arguments are as follows:
Creates an Atom feed from its input files.
Create standalone articles instead of merging articles together.
Instead of emitting any output files, simply process the input and report a table of tags. This table consists of the input file name, a tab, then the tag. (Also known as article-major order.) The tag has escaped white-space printed as unescaped. You can also use -r to have tag-major order and -j for JSON output. Specify -l twice to show matches (tags for article-major, articles for tag-major) all on one tab-separated line, instead of one per line.
Print the -l tag listing in “tag-major” order wherein the first column is the tag and the second column is the article. If the -j flag is specified, this is JSON formatted.
JSON output mode. This behaves as in blog mode, but outputs JSON instead of XML. If -l is specified, the tag listing will be displayed in JSON instead. See JSON Schema for details.
Like -c, but creating a blog with a single <article data-sblg-article="1"> for the file while using the remaining arguments are other files used in <nav data-sblg-nav="1">.
Like -C, but acting on all input files, translating the input to output files such as in -c without -o. If there are multiple articles in an output file, the output is recreated for each (so only the last will remain). So running with “article0.xml article1.xml” will produce “article0.html article1.html” as if -C were seperately specified for both. This avoids needing to parse all inputs for each input.
Output file. If unspecified, standalone articles have .html appended to the input file name, unless the input file extension is .xml, in which case the .xml is replaced by .html. If multiple input files are specified, -o is ignored. If unspecified for the blog, blog.html is used by default. If unspecified for the Atom feed or JSON, atom.xml or blog.json, respectively, is used by default. Use -o - for standard output.
Change how articles are sorted before being written into navigation or article entries. The default is date, which sorts oldest-newest by date. You can also specify filename, which sorts in increasing A-Z alphabetical order of the source filename; cmdline, which uses the command-line order; or rdate, a reverse-date sort (newest-oldest).
Template for all modes. If unspecified, defaults to article-template.xml for -c, atom-template.xml for -a, and blog-template.xml otherwise.
file ...
Input files. In standalone mode with -c, input XML files are merged with a template into an output file. Otherwise, multiple input files are merged into a single blog.
All input must be well-formed XML. (Element names and attributes are case-sensitive.) HTML is assumed only with the default suffix re-write rule for -c without -o. Input articles may be XML fragments or full documents: only the <article data-sblg-article="1"> tree within the article is considered.

Article input files consist of XML fragments or whole documents. They usually consist of the following within the document:
<article data-sblg-article="1"> 
    <h1>Article Name</h1> 
    <address>Author Name</address> 
    <time datetime="2013-06-29">29 June, 2013</time> 
    This is used as the feed <b>abstract</b>. 
    Some text in the <b>content</b>. 
    <img src="foo.jpg" alt="An image for the feed" /> 
When processed with sblg, all data outside of the <article data-sblg-article="1"> element is discarded. Then the article is scanned for the following:
If unspecified, the default article title text (and mark-up) is “Untitled article”, the default author text (and mark-up) is the “Unknown author”, the publication time is set to the document's file-system creation time, the abstract is left empty, and the image is empty.
All content is recorded in case the data-sblg-content Boolean value is used in an Atom feed.
There are a number of special attributes that are recognised in the input file.
Overrides the first <img> link to be the image associated with the article. It doesn't matter where this appears: it will always override any images in the article.
This tag may only be specified on the article element and specifies one or more space-separated languages for the document. You can escape spaces with a backslash (“\”) if you have spaces in the tag name, e.g., “foo\ bar”. These languages are removed in the “stripping” operations for the Tag Symbols.
This allows arbitrary values to be attached to the article. For example, specifying data-sblg-set-foo="bar" sets the foo keyword to bar. If specified multiple times for the same key, only the last value is used. These may be retrieved with ${sblg-get} or queried with ${sblg-has} of the Tag Symbols.
Override the article's position relative to other articles. This can be either first or last. If multiple articles have the same sort override, they are ordered in the natural way.
This tag may be specified on any element within the article and consists of space-separated tag names. You can escape spaces with a backslash (“\”) if you have spaces in the tag name, e.g., “foo\ bar”. These tags are extracted for navigation tag operation. It may not contain any tabs.
There may be be multiple articles within a single document, for example,
  <article data-sblg-article="1"></article> 
  <article data-sblg-article="1"></article> 
  <article data-sblg-article="1"></article> 
The element(s) containing the articles is ignored. If you have multiple articles and are using -c, only the first article is compiled.

The standalone template file must be a well-formed XML file where the first <article data-sblg-article="1"> element is replaced by the article text. All of this element's children are removed.
  <header>This consists of a single blog entry.</header> 
  <article>This is kept.</article> 
  <article data-sblg-article="1">This is removed.</article> 
See Tag Symbols for a list of symbols that will be replaced if found in attribute value or textual contexts.

The blog template file must also be a well-formed XML file where each <article data-sblg-article="1"> element is replaced by ordered (by default, newest to oldest) article contents. If there aren't enough articles, the element is removed. Furthermore, <nav data-sblg-nav="1"> elements are replaced by the same list of articles within an unordered list.
Usually, the <article> tags are used for displaying full articles, while <nav> tags are used for displaying navigation to articles, such as just their titles, dates, and links.
  <header>This consists of two blog entries.</header> 
  <nav data-sblg-nav="1" /> 
  <article data-sblg-article="1" /> 
  <article data-sblg-article="1" /> 
Articles may contain several attributes.
If set to true, the contents are replaced with the input article.
If an <article data-sblg-article="1"> element contains this, limit displayed articles to those matching the space-separated tags or ${sblg-get|xxx} when in -L or -C mode.
If an <article data-sblg-article="1"> element contains this set to false, the permanent link is omitted.
Unless data-sblg-permlink is set to false, each <article data-sblg-article="1"> is followed by a (permanent link) anchor within a <div> with the custom class “data-sblg-permlink”. The permanent link is set to the article input file name, which may be an XML file. This confusing feature may be removed in future versions.
The navigation element may contain several attributes.
If true, reproduces the mark-up content of the <nav> within an unordered list item for each article shown, replacing Tag Symbols for the current article. If not true, sblg populates an unordered list with article title text in a link and the publication date.
Overrides the global search order given with -s. Uses the same names. If the search name is not recognised, the attribute is silently ignored and the global search order used.
How many articles will skip being displayed (so if you have tags, it will only account for articles that would meet those tags) before showing the first navigation entry. Starts at one (a value of zero is the same as a value of one).
If the <nav> element contains this attribute with a positive integer, it is used to limit the number of navigation entries.
Only articles with matching tags are shown. You can specify multiple space-separated tags, for instance, data-sblg-navtag="foo bar" will search for foo or bar. Tags to be matched against are extracted from the space-separated data-sblg-tags element of each article's topmost <article> element. Escape spaces with a backslash (“\”) if you have spaces in the tag name, e.g., “foo\ bar”. Use ${sblg-get|xxx} or (for multi-word values) ${sblg-get-escaped|xxx} when in -C or -L mode to use the current article's set data as part of a string, e.g., location-${sblg-get|location}.
Like data-sblg-navcontent, but without the surrounding list elements. The data-sbgl-navxml attribute does not print any additional <nav>, <ul>, or <li> HTML tags and can be used to generate custom XML files, such as sitemaps.

This is identical to the Blog Template except that a single article is noted with -C, and this is the only article displayed in the article stub. In the given example,
  <header>This consists of two blog entries.</header> 
  <nav data-sblg-nav="1" /> 
  <article data-sblg-article="1" /> 
  <article data-sblg-article="1" /> 
the navigation would be populated by all articles, but only the first article stub would be filled in with the specified article. The second would be removed.
Note: this follows the usual rules of data-sblg-articletag, so if the article you specify with -C doesn't have the correct tag, it won't inline the article.

The Atom template file must be a well-formed XML file where each <entry> element with a Boolean data-sblg-entry attribute is replaced by ordered (newest to oldest) article information. If there aren't enough articles, the element is removed.
<?xml version="1.0" encoding="utf-8"?> 
<feed xmlns=""> 
  <title>Example Feed</title> 
  <link href="" rel="self" /> 
  <link href="" /> 
  <updated data-sblg-updated="1" /> 
  <id data-sblg-id="1" /> 
  <entry data-sblg-entry="1" data-sblg-forall="1" /> 
There are a number of special attributes that are recognised in the input file.
If an <entry data-sblg-entry="1"> element contains this set to true, the alternate <link> is printed.
If both data-sblg-entry and data-sblg-altlink are true for an <entry>, the value is used as the link address. Accepts Tag Symbols, most commonly being ${sblg-base}. Deprecates data-sblg-striplink.
If <entry data-sblg-entry="1"> contains this set to true, the article's contents (everything within the <article data-sblg-article="1">) are inlined within the <content> element with type html. Tag Symbols are processed.
Each <entry> element with this set to true is filled in with a <title>, <id> (in tag format), <author>, HTML <content> (specified in the article as an <aside>), and alternate <link>.
If an <entry data-sblg-entry="1"> element contains this set to true, it is used for all remaining articles. Any <entry data-sblg-entry="1"> following this are discarded.
The <id> element with this set to true is replaced with an identifier in the form of tag:domain,year:path, where the domain is initialised to the current domain or extracted from the <link> to the self and the path is also extracted from the self <link>, initialised to the root path ‘/’, with the name of the output file. The year is set to the current year. If an input file is not specified (standard input), no filename is used.
If data-sblg-entry="1"> for an <entry>, element contains this set to true, the alternate link (if requested) has its directory part stripped and is assumed to be in the root directory. This is deprecated in favour of data-sblg-altlink-fmt.
The <updated> element with this set to true is replaced with the newest article date (or the current date, if no articles are listed). Tag Symbols are processed.
When filling in HTML content, sblg will strip away HTML attributes that do not fit into a white-list. This white-list is defined by the W3C's Feed Validator.

sblg can produce JSON with the -j flag. The schema is documented in /usr/local/share/sblg/schema.json. If -l is specified, the output schema is simply an array as follows. Let source1.xml and source2.xml be input files with a variety of tags.
 {"src": "source1.xml", 
  "tags": ["tag1","tag2"]}, 
 {"src": "source2.xml", 
  "tags": ["tag1"]} 
If, however, -r is also specified, the reverse format is used:
 {"tag": "tag1", 
  "srcs": ["source1.xml","source2.xml"]}, 
 {"tag": "tag2", 
  "srcs": ["source1.xml"]} 

Within the template for -c or -C, or in any article contents written (either into an article or navigation entry), the following special strings are replaced. These symbols concern the current article being processed: in a navigation entry, or as article contents. In the event of the positional “next” and “prev” symbols, these refer to the article's position within the input articles. Obviously, -c has only a single article.
In general, these must be considered strict values, e.g., ${sblg-aside} and not ${ sblg-aside }. Some symbols accept optional arguments, which have the format ${sblg-tags[|argument]}. Here, |argument may be omitted.
The total number of articles. This is only valid in a <nav data-sblg-nav="1"> context, otherwise it always prints 1. See also ${sblg-count}.
The position (from 1) of the article's position in the list of all articles. This is only valid in a <nav data-sblg-nav="1"> context, otherwise it always prints 1. See also ${sblg-pos}.
The article's first aside with markup.
The article's first aside, textual parts only.
The article's author with markup.
The article's author, textual parts only
The full filename (including directory) with the last suffix part chopped off. For example, foo/bar.xml becomes foo/bar. The ${sblg-stripbase} variant will strip off the directory part and any sufix. For example, foo/bar.xml becomes bar. The ${sblg-striplangbase} variant will also strip the language. For example, if “en” language was specified on the article, foo/bar.en.xml becomes bar.
The total number of articles that will be shown. In standalone mode, this is always 1. In a blog <nav> mode, it's the total number within the navigation.
The publication date as YYYY-MM-DD (UTC).
The publication date and time as YYYY-MM-DDTHH:MM:SSZ (UTC).
A human-readable representation of the date and, if specified, time in local time. This accepts an optional format string passed to strftime(3). If the format string is empty or “auto”, a human-readable date (with %x) or date-time (%c) is printed.
The article's associated image. This will be an empty string if no image was specified.
The first (newest) base name in the list of articles. There are also ${sblg-first-stripbase} and ${sblg-first-striplangbase} variants. (See ${sblg-base}).
The last (oldest) base name in the list of articles. There are also ${sblg-last-stripbase} and ${sblg-last-striplangbase} variants. (See ${sblg-base}).
The next base name when chronologically ordered from newest to oldest, wrapping back to the beginning for the last. There are also ${sblg-next-stripbase} and ${sblg-next-striplangbase} variants. (See ${sblg-base}).
The position (from 1) of the articles actually shown. This always starts at 1 and increments by one, regardless the tag filtering or starting position. In standalone mode, it always prints 1. In blog mode (outside of a <nav> context), it shows the position in the input files. Within a <nav> context, it shows the position within the navigation.
The fractional (0–1) value of ${sblg-pos}/$(sblg-count}.
The percentage (0–100, not including the percent sign) form of ${sblg-pos-frac}.
The previous base name when chronologically ordered from newest to oldest, wrapping back to the beginning for the last. There are also ${sblg-prev-stripbase} and ${sblg-prev-striplangbase} variants. (See ${sblg-base}).
Print the value of key assigned in data-sblg-set-key. If unspecified or the key was not found, this is ignored and omitted from output. The lookup is case sensitive.
Like ${sblg-get[|key]}, but escapes the value of the key so that it may be used for data-sblg-navtag or data-sblg-articletag attribute values for multi-word tags.
Like ${sblg-get[|key]}, but queries with the key exists. If it is specified and it does exist, then the string sblg-has-key is printed. This is useful in class attributes to test whether a given key has been specified.
The source file when passed for parsing.
List of unique tags in the article, optionally filtered by those having the prefix tagspec. If the prefix is not specified, all tags. Each tag (e.g., TAG) is listed as <span class="sblg-tag">TAG</span>. If no tags were found, a single <span class="sblg-tags-notfound"></span> is emitted.
The article title with markup.
The article title, textual parts only.
The output filename, which is empty for standard output.
Be careful in using these: the contents are copied directly, so if specifying a value within an HTML attribute that has a double-quote, the attribute will be prematurely closed.

Default template for creating articles with -c.
Default template for creating atom feeds with -a.
Default template for creating a front page.

The sblg utility exits 0 on success, and >0 if an error occurs.

First, create standalone HTML5 files (filled-in <article data-sblg-article="1">) from article fragments. An article-template.xml file is assumed to exist. This will create article1.html and article2.html from the re-write rule for the XML suffix.
% sblg -c article1.xml article2.xml
Next, merge formatted files into a front page. A blog-template.xml file is assumed to exist.
% sblg -o index.html article1.html article2.html
This will create index.html with filled-in <article data-sblg-article="1"> and <nav data-sblg-nav="1"> elements.
Combining the above two examples, we can specify a single article to be displayed along with a full navigation as follows:
% sblg -o article1.html -C article1.xml article1.xml article2.xml
This will fill the contents of article1.xml into the <article data-sblg-article="1"> but use both (along with any others) in the <nav data-sblg-nav="1">.
If we want to make an output article as in the above example for each element of the input, we could either run -C for each input element, or use -L to avoid re-running sblg for each input article, which can be costly for many articles!
% sblg -L article1.xml article2.xml
This re-writes the suffixes and fills in the <article data-sblg-article="1"> for article1.xml in article1.html, and so on. For each of these, it will fill in <nav data-sblg-nav="1">.

Input files and templates must be properly-formed XML files. Output files are guranteed to be XML as well. The Atom file template must be well-formed; output is guaranteed to satisfy the Atom 1.0 and Tag ID standards.

The sblg utility was written by Kristaps Dzonsons,

Boolean XML values must have an attribute specified. In other words, <foo bar="1"> is valid, while <foo bar> is not.
Since input is recognised as XML and not HTML5, special characters must be specified as unicode code-point numbers and not HTML element names. For example, you must use &#8230; instead of &hellip;.
April 21, 2019 OpenBSD 6.4