SBLG(1)
SBLG(1) π β General Commands Manual
β¨ NAME β¨
sblg β static blog utility
πΈ SYNOPSIS πΈ
sblg [-acjlLrV] [-C file] [-o file] [-s sort] [-t template] file ...
π DESCRIPTION π
Okay bestie, listen up: sblg is literally the utility that merges XML articles and templates in a bunch of different ways. No cap, it's giving build-your-own-blog energy, and the modes are highkey iconic. Here's the vibe check:
- Standalone mode (
-c) merges a single article's content and metadata into a template. For example,sblg -o- -c foo.xmlmergesfoo.xmlinto the templatearticle-template.xml. So cute. π«Ά - Blog mode (the default) merges multiple articles' content and metadata into a template. For example,
sblg -o- bar.xml baz.xmlmergesbar.xmlandbaz.xmlinto the templateblog-template.xml. Main character energy fr fr. π - Combined mode (
-C) links multiple articles' content and metadata in standalone style. For example,sblg -o- -C bar.xml baz.xmlwill show content for onlybar.xml, but metadata for both inputs. The similar-Lflag runs the process for each input file without reparsing. Obsessed. π - Atom mode (
-a) merges multiple articles into an Atom feed template. - JSON mode (
-j) merges all articles into a JSON object. π₯
By default, sblg operates in blog mode with template blog-template.xml. Its arguments are as follows:
-aβ Creates an Atom feed from its input files. π-cβ Create standalone articles instead of merging articles together.-lβ 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-rto have tag-major order and-jfor JSON output. Specify-ltwice to show matches (tags for article-major, articles for tag-major) all on one tab-separated line, instead of one per line. iykyk.-rβ Print the-ltag listing in βtag-majorβ order wherein the first column is the tag and the second column is the article. If the-jflag is specified, this is JSON formatted.-jβ JSON instead of XML output mode. This behaves as in blog mode, but outputs JSON instead of XML. If-lis specified, the tag listing will be displayed in JSON instead. See βJSON Schemaβ for details.-Cfile β Like-c, but creating a blog from the article in file with the remaining files being articles used for navigation.-Lβ Like-C, but acting on all input files, translating the input to output files such as in-cwithout-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-Cwere seperately specified for both. This avoids needing to parse all inputs for each input. π-ofile β Output file. If unspecified, standalone articles have.htmlappended to the input file name, unless the input file extension is.xml, in which case the.xmlis replaced by.html. If multiple input files are specified,-ois ignored. If unspecified for the blog,blog.htmlis used by default. If unspecified for the Atom feed or JSON,atom.xmlorblog.json, respectively, is used by default. Use-o -for standard output. π-ssort β Change how articles are sorted before being written into navigation or article entries. The default isdate, which sorts oldest-newest by date. You can also specifyfilename, which sorts in increasing AβZ case-sensitive order of the source filename;cmdlinefor the command-line order;ititlefor the case-insensitive document title; ortitlefor the case-sensitive document title. Each sort may be prefixed with"r"(e.g.,rcmdline) to reverse the sort. π-ttemplate β Template for all modes. If unspecified, defaults toarticle-template.xmlfor-c,atom-template.xmlfor-a, andblog-template.xmlotherwise. π§-Vβ Emits the version assblg-xx.yy.zzand exits. β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. Periodt. π
π¦ Article Input π¦
Article input files consist of the following within the document:
<article data-sblg-article="1">
<header>
<h1>Article Name</h1>
<address>Author Name</address>
<time datetime="2013-06-29">29 June, 2013</time>
</header>
<aside>
This is used as the feed <b>abstract</b>.
</aside>
<p>
Some text in the <b>content</b>.
<img src="foo.jpg" alt="An image for the feed" />
</p>
</article>
All content outside of the element with the data-sblg-article="1" attribute, usually an <article>, is discarded. Then the article is scanned for the following:
- the article title (both as text data only and inclusive of markup) is extracted from the first
<hn>(header 1β4); - the article publication date is extracted from the
datetimeattribute of the first<time>(which must be a date,YYYY-MM-DD, or time,YYYY-MM-DDTHH:MM:SSZ) interpreted in UTC; - the author (both as text data only and inclusive of markup) from the first
<address>; - the first
<aside>is used for the feed abstract; and - the first
<img>is associated as the article's image.
These are all set once: subsequent invocations will not override prior setting. See data-sblg-aside, data-sblg-author, data-sblg-datetime, data-sblg-img, and data-sblg-title for explicitly setting or overriding these values.
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.
There are a number of special attributes that are recognised in the input file. Not me listing them all with the exact energy they deserve:
data-sblg-aside=stringβ Sets the aside material as otherwise would be set from the first<aside>element. It overrides the previously set aside. The alternativedata-sblg-const-asideonly sets the aside if it has not yet been set.data-sblg-author=urlβ Sets the author as otherwise would be set from the first<address>element. It overrides the previously set author. The alternativedata-sblg-const-authoronly sets the author if it has not yet been set.data-sblg-datetime=datetimeβ Overrides the first<time>element. This must beYYYY-MM-DDorYYYY-MM-DDTH:MM:SSZ. It overrides the previously set date. The alternativedata-sblg-const-datetimeonly sets the date if it has not yet been set.data-sblg-img=urlβ Set the image associated with the article. It overrides any previously set image. The alternativedata-sblg-const-imgonly sets the image if it has not yet been set.data-sblg-lang=stringβ May only be set on the<article>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β.data-sblg-set-xxx=stringβ This allows arbitrary values to be attached to the article. For example, specifyingdata-sblg-set-foo="bar"sets thefookeyword tobar. 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β.data-sblg-sort=first|lastβ May only be set on the<article>element and overrides the article's position relative to other articles. This can be eitherfirstorlast. If multiple articles have the same sort override, they are ordered in the natural way.data-sblg-source=fileβ Set the source filename associated with the article. It overrides the implicit value set from the actual file.data-sblg-tags=stringβ 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.data-sblg-title=stringβ Sets the title as otherwise would be set in a<hN>element. It overrides the previously set title. The alternativedata-sblg-const-titleonly sets the title if it has not yet been set.
π Standalone Template π
The standalone template file replaces the first element with the data-sblg-article="1" attribute, usually an <article>, with the article contents. It's literally the swap moment:
<body>
<header>This consists of a single blog entry.</header>
<article>This is kept.</article>
<article data-sblg-article="1">This is removed.</article>
<footer>Something.</footer>
</body>
Article templates may contain the following attributes:
data-sblg-article=booleanβ If set to true, the contents are replaced with the input article. This only happens once: subsequent elements are ignored.data-sblg-ign-once=booleanβ If an element has thedata-sblg-article="1"attribute set to true, the element is not processed as an article and thedata-sblg-ign-onceattribute is removed.
See βTag Symbolsβ for a list of symbols that will be replaced if found in attribute value or textual contexts. These may occur anywhere in the template document.
π Blog Template π
The blog template replaces elements with the data-sblg-article="1" attribute, usually <article>, with ordered (by default, newest to oldest) article contents. If there aren't enough articles, the element is removed.
Elements with a data-sblg-nav="1" attribute, usually <nav>, are replaced by the same list of articles within an unordered list.
If an element has both attributes, only the first is recognised.
Usually, the <article> elements are where the full articles live π, and the <nav> elements are for showing off navigation to articles β like just the titles, dates, and links. β¨
<body>
<header>This consists of two blog entries.</header>
<nav data-sblg-nav="1" />
<article data-sblg-article="1" />
<article data-sblg-article="1" />
<footer>Something.</footer>
</body>
okay so article templates can carry a whole little wardrobe of attributes. here's the rundown π
data-sblg-article=boolean β if you set this to true, the contents (including the element itself) get replaced with the input article. iconic behavior tbh.data-sblg-articletag=string β if an element with thedata-sblg-article="1"attribute has this, it limits the displayed articles to the ones matching the space-separated tags, or${sblg-get|xxx}when you're in-Lor-Cmode. this scans for tags from the current article in the list of articles.data-sblg-ign-once=boolean β if an element with thedata-sblg-article="1"attribute has this set to true, the element is not processed as an article, and thedata-sblg-ign-onceattribute gets removed. one-time ignore, we move on π«Άdata-sblg-permlink=boolean β if an element with thedata-sblg-article="1"attribute has this set to true, a permanent link to the article's input filename is emitted inside a<div data-sblg-permlink="1">element, right after the element with thedata-sblg-article="1"attribute.
and the navigation element? she also has attributes, bestie. πΈ
data-sblg-navcontent=boolean β deprecated alias for the respective content and element styles:list-keepandkeepif true,list-summariseandkeepif false.data-sblg-navstyle-content=style β the style for formatting articles into the content of the navigation element. it may be:keepβ output the content per-article and perform βTag Symbolsβ substitution;summariseorsummarizeβ discard content and output the article time followed by a link to the article;list-keepβ same askeep, except it surrounds each article with<li>and all articles with<ul>;list-summarise, orlist-summarizeβ same assummarise, except it surrounds each article with<li>and all articles with<ul>.- if it's not given or it's unknown, it defaults to
list-summarise.
data-sblg-navstyle-element=style β the style for the navigation element itself. it may be:keepβ output the element as-is, once, around all articles;keep-stripβ output the element without attributes, once around all articles;repeat-stripβ output the element without attributes around each article (and if the content styles arelist-keeporlist-summarise, the element is output within theli);discardβ suppress output entirely π- if it's not given or it's unknown, it defaults to
keep.
data-sblg-navsort=sort β overrides the global search order you gave with-s. uses the same names. if the search name isn't recognised, the attribute is silently ignored and the global search order is used instead.data-sblg-navstart=number β how many articles skip being displayed (so if you've got tags, it only counts articles that would actually meet those tags) before showing the first navigation entry. starts at one (a value of zero is the same as a value of one).data-sblg-navsz=number β if the<nav>element has this attribute with a positive integer, it's used to limit the number of navigation entries. πdata-sblg-navtag=string β only articles with matching tags get shown. you can drop multiple space-separated tags, so for instancedata-sblg-navtag="foo bar"will search forfooorbar. the tags being matched against are extracted from the space-separateddata-sblg-tagselement of each article's topmost element. escape spaces with a backslash (β\β) if you've got spaces in the tag name, e.g.,βfoo\ barβ. use${sblg-get|xxx}or β for multi-word values β${sblg-get-escaped|xxx}when you're in-Cor-Lmode, to use the current article's set data as part of a string, e.g.,location-${sblg-get|location}.data-sblg-navxml=boolean β deprecated alias for the respective content and element styles:keepanddiscardif true,list-summariseandkeepif false.
Combined Template π¦
this one is identical to the βBlog Templateβ, except that a single article gets noted with -C, and that's the only article displayed in the article stub. also β just like in standalone mode β βTag Symbolsβ can be used anywhere in the document template, and they refer to the current articleβ¦ unless you're inside a navigation element, in which case the symbol resolves to the currently-printed article. π
in the example we keep showing off:
<body>
<header>This consists of two blog entries.</header>
<nav data-sblg-nav="1" />
<article data-sblg-article="1" />
<article data-sblg-article="1" />
<footer>Something.</footer>
</body>
the navigation would be populated by all articles, but only the first article stub would get filled in with the specified article. the second one? removed. bye π
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. no cap.
Atom Template β
the Atom template file has to be a well-formed XML file where each <entry> element with a Boolean data-sblg-entry attribute gets replaced by ordered (newest to oldest) article information. if there aren't enough articles, the element is removed. the template may contain pre-existing entries, too.
here's a minimal template β anything less will not conform to the Atom specification:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<link href="http://example.org" />
<title>A Title Here</title>
<updated />
<id />
<entry data-sblg-entry="1" data-sblg-forall="1" />
</feed>
the recognised elements are as follows. un-recognised elements are printed verbatim. π
<entry data-sblg-entry="1">β filled-in article entry. if the attribute isn't specified, the entry is retained verbatim. otherwise it gets filled in with an article's information.<id>β if this is empty, it's filled in with the URL in<link [rel="alternate"]>, which must exist. otherwise, the value is copied and used for subsequent feed entries.<link [rel="alternate"]>β unless an<id>is provided, thehrefattribute must be a full URL, e.g.,<link href="https://kristaps.bsd.lv/">. otherwise, it may be a relative path. this element must be first.<updated>β this gets filled in with the most recent article. its contents are discarded.
there are a number of special attributes you can hand to the above elements. β¨
data-sblg-altlink=boolean β if an<entry data-sblg-entry="1">element contains this set to true, the alternate<link>is printed.data-sblg-altlink-fmt=string β if bothdata-sblg-entryanddata-sblg-altlinkare true for an<entry>, the value is used as the link address. accepts βTag Symbolsβ, most commonly being${sblg-base}.data-sblg-atomcontent=boolean β if<entry data-sblg-entry="1">contains this set to true, the contents are printed directly and the βTag Symbolsβ are processed. this overridesdata-sblg-altlinkanddata-sblg-content.data-sblg-content=boolean β if<entry data-sblg-entry="1">contains this set to true, the article's contents (everything within the element having thedata-sblg-article="1"attribute) are inlined within the<content>element with typehtml. βTag Symbolsβ are processed.data-sblg-entry=boolean β each<entry>element with this gets filled in with article content.data-sblg-forall=boolean β if an<entry data-sblg-entry="1">element contains this set to true, it's used for all remaining articles. any<entry data-sblg-entry="1">following this are discarded. π«Ά
if you're not using data-sblg-atomcontent, entries get filled in with a <title>, <id>, <author>, HTML <content> (specified in the article as an <aside>), and alternate <link>. the <id> is constructed by appending the source filename, hash print, and date following the feed's <id> or <link> element.
when filling in HTML content, sblg will strip away HTML attributes that don't fit into a white-list. this white-list is defined by the W3C's Feed Validator. π
JSON Schema π
sblg can produce JSON with the -j flag. the structure of the JSON file is consumable either with a JSON schema (noted in the βFILESβ section) or using the typings that may be downloaded with npm(1):
npm install sblg
if -l is specified, the output schema is simply an array, like this. 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"]}
]
Tag Symbols π
within the template for -c or -C, or in any article contents written (either into an article or navigation entry), the following special strings get 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 have to 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.
be careful using tag symbols, bestie: the contents are copied directly, so if you specify a value within an HTML attribute that has a double-quote, the attribute will be prematurely closed. π
to prevent regular text with ${...} from being processed, escape one or more characters, such as ${...}.
${sblg-abscount}β the total number of articles. this is only valid in<nav data-sblg-nav="1">, otherwise it always prints1. see also${sblg-count}and${sblg-setcount}.${sblg-abspos}β the position (counting from 1) of this article inside the list of all articles. Heads up though: this one only actually means anything inside a<nav data-sblg-nav="1">context β anywhere else it just prints1on loop like it forgot its lines π. Also peep${sblg-pos}.${sblg-aside}β the article's first aside, markup and all π.${sblg-asidetext}β same first aside, but textual parts only.${sblg-author}β the article's author, with markup.${sblg-authortext}β the article's author, textual parts only.${sblg-realbase}β basically${sblg-base}'s twin, same sub-types and everything, except it derives from${sblg-real}instead β¨.${sblg-base}β same as${sblg-source}but with the last suffix part chopped off. So like,foo/bar.xmlbecomesfoo/bar. The${sblg-stripbase}variant goes further and strips the directory part and any suffix β sofoo/bar.xmlbecomesbar. And the${sblg-striplangbase}variant strips the language too: ifenlanguage was specified on the article,foo/bar.en.xmlbecomesbar. Chef's kiss π.${sblg-count}β the total number of articles that are gonna be shown, i.e. it takes the navigation length and offset into consideration. In standalone mode this is always1. Inside<nav data-sblg-nav="1">, it's the total number within the navigation. See also${sblg-abscount}and${sblg-setcount}π${sblg-date}β the publication date asYYYY-MM-DD(UTC).${sblg-datetime}β the publication date and time asYYYY-MM-DDTHH:MM:SSZ(UTC).${sblg-datetime-fmt[|fmt]}β a human-readable version of the date, plus the time if one was specified, in local time. It takes an optional format string that gets passed tostrftime(3). If the format string is empty orauto, you get a human-readable date (with%x) or date-time (%c). Vibes only π¦.${sblg-img}β the article's associated image. If no image was specified, this is an empty string. Not me getting ghosted by an image tag π.${sblg-first-base}β the first (newest) base name in the list of articles. There's also${sblg-first-stripbase}and${sblg-first-striplangbase}variants β go read${sblg-base}for the lore.${sblg-last-base}β the last (oldest) base name in the list of articles. And yes,${sblg-last-stripbase}and${sblg-last-striplangbase}variants exist too. See${sblg-base}.${sblg-next-base}β the next base name when things are ordered chronologically newest β oldest, wrapping back around to the beginning for the last one. Also has${sblg-next-stripbase}and${sblg-next-striplangbase}variants. See${sblg-base}π.${sblg-next-has}β printssblg-next-hasif there's a next article in the ordered set, otherwise prints absolutely nothing. Silent treatment fr π.${sblg-pos}β the position (from 1) of the articles that are actually shown. This one always starts at1and goes up by one, no matter what the tag filtering or starting position is. In standalone mode it always prints1. In blog mode (so, outside a<nav>context) it shows the position in the input files. Inside a<nav>context, it shows the position within the navigation. Main character energy, honestly π.${sblg-pos-frac}β the fractional value (0β1) of${sblg-pos}/$(sblg-count}.${sblg-pos-pct}β the percentage form (0β100, and not including the percent sign) of${sblg-pos-frac}. Math girlies rise π .${sblg-prev-base}β the previous base name when chronologically ordered newest β oldest, wrapping back to the beginning for the last. There are also${sblg-prev-stripbase}and${sblg-prev-striplangbase}variants. See${sblg-base}.${sblg-prev-has}β printssblg-prev-hasif a previous article exists in the ordered set, otherwise prints nothing.${sblg-get[|key]}β prints the value of the key you assigned indata-sblg-set-key. If it's unspecified, or the key wasn't found, this whole thing gets ignored and omitted from the output. And the lookup is case sensitive, so mind your caps bestie π₯.${sblg-get-escaped[|key]}β same energy as${sblg-get[|key]}, except it escapes the value of the key so you can safely use it fordata-sblg-navtagordata-sblg-articletagattribute values when you've got multi-word tags. Iconic.${sblg-has[|key]}β also like${sblg-get[|key]}, but this one queries whether the key exists. If it's specified and it does exist, then the stringsblg-has-keygets printed. Super useful insideclassattributes to test whether a given key has been specified β¨.${sblg-setcount}β like${sblg-count}, but only counting the articles that match the requested tags. See also${sblg-count}and${sblg-abscount}.${sblg-real}β the article's actual source file. Go see${sblg-source}if you want an overridable source indicator instead.${sblg-source}β the source file associated with the article.${sblg-tags[|tagspec]}β a list of the unique tags in the article, optionally filtered down to those with the prefix tagspec. If you don't specify a prefix, you get all of them. Every tag (say,TAG) is listed out as<span class="sblg-tag">TAG</span>. And if no tags were found at all? You get a single<span class="sblg-tags-notfound"></span>instead. Not a single crumb π.${sblg-title}β the article title, with markup.${sblg-titletext}β the article title, textual parts only.${sblg-url}β the output filename, which is empty for standard output.${sblg-version}β the current sblg version asxx.yy.zz. Slay, versioning.
π FILES π
These files live in /usr/share/doc/sblg:
schema.jsonβ the JSON schema for output generated with-j. JSON girlies, this one's for you π«Ά
π¦ EXIT STATUS π¦
The sblg utility exits 0 on success, and >0 if an error occurs. Zero means we ate, anything else means we did not π.
π§ͺ EXAMPLES π§ͺ
Okay so first: make standalone HTML5 files (filled-in <article data-sblg-article="1">) out of article fragments. This assumes an article-template.xml file already exists. This creates article1.html and article2.html from the re-write rule for the XML suffix.
% sblg -c article1.xml article2.xml
Next, merge the formatted files into a front page. This assumes a blog-template.xml file exists.
% sblg -o index.html article1.html article2.html
That'll create index.html with filled-in <article data-sblg-article="1"> and <nav data-sblg-nav="1"> elements β¨.
Now, combining those two examples above, we can ask for a single article to be displayed along with a full navigation, like so:
% sblg -o article1.html -C article1.xml article1.xml article2.xml
That fills the contents of article1.xml into the <article data-sblg-article="1">, but uses both of them (along with any others) in the <nav data-sblg-nav="1">. Two jobs, one command, we love to see it π
.
And if we want an output article like the above example for each element of the input, we could either run -C for each input element, or β the smarter move β use -L to avoid re-running sblg for each input article, which can get costly when you've got a lot of articles!
% sblg -L article1.xml article2.xml
This re-writes the suffixes and fills in the <article data-sblg-article="1"> for article1.xml into article1.html, and so on. And for each one of those, it'll fill in <nav data-sblg-nav="1">. Efficiency queen π.
π STANDARDS π
Input files and templates have to be properly-formed XML files, no cap. Output files are guaranteed to be XML as well. And the Atom file template must be well-formed; the output is guaranteed to satisfy the Atom 1.0 and Tag ID standards. We stay compliant fr fr πΈ.
π©βπ» AUTHORS π©βπ»
The sblg utility was written by Kristaps Dzonsons, kristaps@bsd.lv. Legend behaviour honestly π«Ά.
β οΈ CAVEATS β οΈ
Boolean XML values have to have an attribute specified. In other words, <foo bar="1"> is valid, while <foo bar> is not. Don't try it, it's not gonna work bestie π.
HTML entity names with attributes, e.g. <a title="foo…">, are not properly passed to output. So yeah β that one's a known thing, plan accordingly π.
That's the whole page, bestie π this little masterpiece got shipped to you by the Debian crew and it's stamped $Mdocdate$ β go forth and generate some static sites, you absolute icon πβ¨π
π¦ where this page comes from
- fedora 43: sblg 0.6.1-2.fc43 Β· ISC
- fedora 44: sblg 0.6.1-3.fc44 Β· ISC
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms