This file was last updated for SBWG version 0.10.14. SBWG and its README file are works in progress. The list of features and other details may have changed by now.

SBWG (sweet bash website generator) is a bash script that generates a static HTML website from raw text files. The main focus of SBWG is flexibility and
customisability. Its large and still growing set of optionally ignorable features can be individually used, changed and even complemented with own code for each
web site.

SBWG is free. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar.
See http://www.wtfpl.net/txt/copying/ for more details.


# Features

* Generates static HTML structure from a source file structure
* Content is file based (no separate database) …
    * … allowing for unixy tricks, like linking blog entries to multiple blogs,
    * … making SBWG web sites text editor agnostic
    * … allowing for custom automatic or manual pre-processing of web site content with any text based tool
* Adds menu(s), header and footer to each page/HTML file, without relying on frames
* Simple image galleries
* Weblog/Blog generation
    * Categorised/tagged posts
    * Blog entries can be additionally categorised as topics for an index view
    * Classical blog view, filterable by category, topic, author, language or author AND one of the others
    * Support for multi-author weblogs with the option to split off entries from single authors into separate weblog sites
* File attachments to blog entries
    * Image attachments for embedding images in blog entries
    * Image gallery attachment
    * Audio attachments can be used for potcast support
    * File enclosures in RSS feed
    * Displays file descriptions (incl. image title attributes) for attached images
* Style sets/templates for stylesheets, JavaScript files, images, etc.
    * Supports preferred and alternate stylesheets for those browsers that offer a selection
* Written in Bash
    * Extensive code comments plus references
    * Everything is open and modular
    * Modifications/Additions to the generation process on a per-web-site basis with hooks and a sourced settings file
* Can create persistent file caches to speed up future generation processes
* Easy staging
* Simple RSS feed for the weblog


## Feature Ideas And Requested Features

I will work on these when I'm satisfied with the state of the current feature set and have some time.

* Video attachment support with embedded player
* Video support in galleries
* Support for more image file formats
* ATOM feeds, JSON feeds and multiple RSS feeds for individual tags, categories and topics
* Parallel processing in the generation process
* Easier management of custom menu items
* Generating of web books


The following feature ideas and requests have been decided against. They will not be implemented by me any time soon or any time soon after soon.

* Generate gopher hole and/or gemini capsule at the same time as a web site.
    - They are too different and deserve a different, much simpler generator script if one is needed at all.

* SBWG specific tags in content, e.g. for embedding image files, linking to entries on the same site.
    - This would require parsing the content of entry files, which is a line in complexity of the script that I'm not willing to cross. Everything that could be
      done with custom tags like in web bulletin boards would also be possible with regular HTML. I choose to keep it simple in that case.

* Content Revisioning System (Entry Revisions)
    -  This is not what SBWG is meant for. For archival purposes the files can be saved regularly/whenever they differ from already archived files, independently of
       SBWG (e.g. using git). For public revisions of individual entries, the 'updateof:' tag can be used. For a more elaborate system, custom tags could be used.

* Shorten/Cut off the content of entries when they are displayed on a tagpage. Click "Read More" or the title to view the whole entry on a separate page.
    - This would leave HTML tags that are opened before the cutoff point but closed after it, opened on tagpages. Fixing this problem would go against the decision
      of not parsing the content of entry files.

* Templates for the HTML structure or an option/setting for different levels of HTML granularity.
    - This would add a huge amount of flexibility and eliminate the problem that either the script itself has to be edited or relatively complicated hooks and
      overwrite functions have to be used to make some customisations to the generated HTML structure. But it would also add a great amount of complexity. It is not
      worth it for a script that is still mainly for generating my own web site. You can do a great deal with hooks in a site's settings file. And you actually can
      edit the script to customise HTML output or replace a function with your own version by overwriting it in the site's settings file if you want.

* The generated RSS feed is not valid and issue-free.
    - Well, it's RSS. I don't try to make it 100% valid. I rather offer more than one file attachment/enclosure and displaying an author name without publishing
      their e-mail address than to eliminate warnings from a validator. It is in a OK state and should be accepted by and working with most feed readers.

* Interactive use of the script, interactive setup/install script
    - This is not a priority or much called for feature. Because of this and the amount of work that it would probably take to properly implement a whole second
      way of using the script, is was removed from the todo list of feature ideas.


## Known Issues And Bugs

* Prviews of SVG files attached to entries are not displayed. Other image files that can not be displayed by web browsers are embbedded as <img> tags regardless.
* Message output in parallel mode is usually garbled.
* Headings of file attachments below engries show the number of attached files including hidden and otherwise excluded attachments.
* The log file can not be set using option -S/settings. Workouround: If you really need to set it dynamically on the command line, include the deciding code in the
    settings file or read the path from a file or environment variable.
* Messages (e.g. debug output) about some command line options are not printed to stdout. Workaround: Place the verbosity option (-v/-vv/-vvv/-d) first in the
    command line, before other options.
* Arguments to command line options can not start with a dash ('-'), space (' ') or tab ('	') or end with a space (' ') or tab ('      '). Workaround: Don't
    use (entry/page/style/gallery) names that start with a dash, a space or a tab or end with a space or tab for content files.
* The script is written in bash, which is not a good choice for such a project. This will probably not be fixed.


# Installation

You can get the latest published version from https://log.steeph.de/SBWG.html

There is correctly no setup script. Installation is straightforward though if you understand how SBWG works. **There are short instructions in the INSTALL file** if
not. **Those install instructions are sufficient to get started.** The README file (yes, this one here) contains complete descriptions of SBWGs functionality. So,
if you just want to quickly set up a web site using the example web site as a starting point, head over to the INSTALL file now. If you want to know more than you
need to know to get started, read on.

After installation of SBWG and during setting up/editing of a web site you might find useful tips in the HOWTO file.


## Requirements:

* bash 4.x (bash >=4.3 for parallel mode. The script has not been tested with other shells. bash 4.4 will become a requirement in future versions.)
* coreutils
* imagemagick (or compatible `convert`; only needed for image gallery and image attachment generation)
* Optionally: perl (source file filtering will not be as good if perl is not available. But SBWG does work without it.)
* For serving the generated HTML files: a HTTP server (This file does not go into installing a web server. SBWG only generates web sites. It does not make them
    accessible over a network. Please refer to instructions on how to install a web server for your operating system.)+
* The style sheets included in the example website make use of CSS 3. This is not an issue. I just thought I better mention it.
* The same goes for the generated HTML, which assumes HTML 5 support.
* A terminal with VT-100 style escape codes (only needed for the very much optional and purposeless waiting animation)


## Setting Up The Script

* Extract the package to a location outside of your web root
* Move the files to a directory in the PATH or add the SBWG directory path to the PATH.
* Check if the file 'sbwg' (and optionally the other files starting with 'sbwg-') is(/are) executable, make it(/them) executable if it is not already.


## Setting Up A New Web Site

The steps necessary to create a new web site depend very much on what you wish your web site to be. SBWG is sort of flexible. You can change variables and add your
own code on a per-website basis in the 'settings' file of a web site. But you don't have to get into the details of what SBWG can do and how it works, exactly, to
set up a basic web site. If you have never created a web site with SBWG before, I recommend to copy the 'example' directory and make changes to the copied example
according to your requirements/wishes. The next chapter explains how to do that. The chapters after that explain how SBWG and all its pieces work and can be used to
set up a web site from scratch or as a reference.


### Setting Up A New Web Site From The Example Template

The 'example' directory included in this package contains the complete source for a web site with a couple of pages, blog, a gallery and some other files. All of
the following steps are technically optional. Omitting one will simply mean that whatever you didn't set/change will stay as it was set for the example web site.
 
* Copy the 'example' directory to a suitable location, e.g. ~/my_website
* Edit the 'settings' file to change your website's title, url/domain name, style template choice, default output directory, etc. The relevant lines are at the top
    and clearly commented.
* If you have not changed the default output directory, create a symlink called 'html' inside the web site's source directory to point to your web root.
* Remove or edit the 'footer' file to include any HTML code that you want to be included at the bottom of every generated HTML page.
* Create or edit CSS files in the 'styles' directory according to your wishes. Which files are used is determined by the 'style=' setting in the settings file.
* Create and/or edit files in the 'pages' directory for "static" web pages not related to a weblog.
* Create blog entries in the 'entries' directory. You can use the 'sbwg-genentry' script, write files from scratch or use a template file that you have filled with
    header lines that you regularly use.
* Add galleries in the 'galleries' directory, one directory per gallery. Simply place JPEG and PNG files in these directories.
* Place any other miscellaneous files needed to be publicly accessible on your web site in the 'files' directory.
* Run 'sbwg --complete' or 'sbwg -c' to create the HTML website in the default output directory with its default settings. Use the '-o'/'--output' option to
    specify a different output directory, e.g. for testing/a non-public preview.


### Setting Up A New Web Site From Scratch

If you've copied the example directory, you're fine and you don't need all these details described below. You may skip reading any or all of them.

Setting up a new web site source directory from scratch is something that is not currently explained in a complete step by step guide in any of the help files. I
suggest you just copy the example or parts from it or look at how the example does things. Below I'll explain what a SBWG web site source directory consists of and
what settings and features exist, though. That should help if you really want to do it from scratch. It isn't complicated. It's just a matter of knowing what's what.


# (Files And Directories Of) A Web Site Source Directory

The following files and directories can be used to build a web site with SBWG. All except the `settings` file are optional. That means if there are no pages, no
galleries and no entries the script will just prepare for generating an empty web site and may (depending on the contents of the settings file) actually produce
output in the output directory. Files and directories that are not listed below will simply be ignored by the script.


## settings

The `settings` file must exist in order for SBWG to recognise the directory as a SBWG web site source directory. SBWG will refuse to generate the website if this
file isn't there and it will assume that there is a valid SBWG web site source structure in the same directory if the file exists and starts with a SBWG version
string. This means that the first line of the settings file has to start with '#SBWG VERSION', where VERSION is the oldest version of SBWG that this settings file
(and the web site it represents) is compatible with.

Example 1: #SBWG 0.9.11 - This means that the web site may not be compatible with SBWG versions older than 0.9.11. 
Example 2: #SBWG 0.10.2 - This means that the web site may make use of features introduced in SBWG version 0.10.2. It expects to be generated only with SBWG 0.10.2
  or a newer version. If an older version of SBWG tries to generate this web site, it will stop with an error message before anything is written to the output
  directory.
Example 3: #SBWG 0 - This means that the web site can be generated with any version of SBWG. SBWG has changed and chages over time. Although SBWG will not refuse to
  generate a web site with a settings file with #SBWG 0 as its first line, it might fail completely or in parts. It is recommended to put an actual version number
  here to give a hint to somebody who does not know with which version a web site is compatiple and to prevent a bad result if a too early version is used.

If you use the settings file of the example web site included in the SBWG package, a suitable first line is already present. If you want to create a new settings
file and you're in doubt about the version, you can see the version of your copy of SVWG by executing it with the option `-V` or `--version`: `sbwg --version`
You then can use the output after `#SBWG ` in the first line of your settings file. Alternatively you can try to generate a web site with no settings file. SBWG
then will print a command that you can use to create a settings file for the version of your copy of SBWG.

You can use the file to inject any Bash commands that should be executed before the web site is generated. Commonly it is only used to set a few global variables and
declare hooks (see the "Hooks" section below). You can copy the settings file from the example directory or peek at it for explanations of the settings that should
be set for any new web site. I suggest that you include at least the 'sitename' and 'url' settings. There are more settings worth knowing about. Have a look at the
settings file in the example directory or see the short descriptions of all settings further down in this file under "Settings".


## files

The `files` directory can be used to store random and miscellaneous files that you would like to be publicly available. These can be JavaScript files used by the
web site, image files that you use somewhere in the site's content, files that you want to link to to be downloaded, or anything else really.

The directory just gets copied to the output directory when generating the web site. This means that, unless prevented by web server settings, anything in this
directory will become publicly available on the resulting web site.


## header

The 'header' file does not exist in this version of SBWG. If it exists, it is ignored. The head section of the generated HTML pages can be influenced by using a
hook. (see the "Hooks" section below)


## footer

The contents of this file gets appended to every generated HTML file. You can put anything that should appear at the end of every HTML page in it. For example a
`<footer>` tag with a copyright notice. The contents of the file will be inserted in every generated HTML page right before the closing </body> tag.

The hook 'hook_footer' can serve the same purpose as the footer file and can be used as an alternative or in conjunction with the footer file.


## styles

There can be several files in this directory that can belong to one or more style sets. Depending on the settings and command line options one or more of these
files may be copied to the output directory and, in the case of stylesheets and script files, linked in every HTML file's head when the web site is generated.
See the "Styles" section below for more information on style sets and custom style changes.


## pages

This directory contains the web site's page source files, meaning content that will be turned into HTML and is not part of the weblog or galleries. See chapter
`Pages` below.


## entries

This directory contains the source files for the entries that make up the web site's weblog as well as file attachments to those entries. If there will be no weblog
on the site, the directory should be empty or not present. Each text file in the entries directory represents one blog entry. Entry source files can optionally be
placed in subdirectories for better overview of the file structure. This directory structure has no effect on the generated web site though. On the web site entries
are categorised according to their tags, not the directories their source files are in.

An entry source file is basically just a text file with the contents of the blog entry in HTML. A simple text file with one or multiple lines is a valid entry source
file. But usually an entry source file consists of a source file header and the entry's content. The header can consist of one or many tags of different types,
specifying e.g. the entry's title, author, creation date and the categories and topics it's filed in. Please see the sections "Blog Entries" and "Tags" below for a
description of how the source file header and tags work. The important tag types are used in the blog entries that are contained in the example web site. Looking at
the headers of those entries is probably enough to get started.

If a filename occurs more than once in the directory structure of the entries directory (if there is a/are duplicate filename(s)) the first file that is found or
both/all may be used. There is no check for or warning about duplicate filenames in most situations. Duplicate filenames should not be used in the entries directory.

It is recommended to not use dashes ('-') in file names of files in the entries directory unless the file is intended to be used as a file attachment to some entry.
Depending on the volume of a blog and the file naming convention used it might otherwise happen that a file is used unintentionally as an attachment to some entry
whose name equals the part before the dash of another file. If you trust yourself to be able to keep track of your entry file names even with a growing blog, feel
free to use dashes or any other characters you like.

A file attachment is any file in the entries directory (or a sub-directory thereof) that can be identified as belonging to an entry according to its filename and do
not look like they are intended to be used as an entry file. (See Attachments section below.)


## tagicons

In this directory you can place icons that should be displayed in place of tags in entries' headers. The file name has to be `tagtype:tagname.EXT`, whereby EXT can
be any string, usually JPEG, PNG, SVG, ... Only files that are recognised as image files by `file` are used. If there is no suitable tagicon file for a tag, the tag
will be included as text as usual. No messages are printed to the terminal either way. Note that the image files are not resized by SBWG. They are intended to be
small icons that will be displayed inline instead of the names of commonly used tags. By placing an image file for an author tag in this directory, author portraits
or other "profile pictures" can be implemented.


## html

By default this is the output directory if no other output directory was specified either in the web site's settings file or through the command line option
`--output` (`-o`). It is recommended to replace this directory with a symbolic link to your webserver's webroot. But this depends entirely on your preferences. By
default the generated website is placed in this directory. If it is not accessible by the webserver at the same time then you'll have to copy it over manually in
order to publish the web site.

If a different directory is used as the output directory (see the sections "Settings" and "Generating a web site" below) then this directory is not needed.


# Settings

A setting in a web sites `settings` file is just a global variable that's set for the script before generating the web site. Therefore a setting can be set by
writing the setting name followed by a `=` followed by the value in an otherwise empty line. There may be no blank before or after the `=`. Values with some special
characters (e.g. spaces) have to be quoted (enclosed in `"`s).

Examples:

`sitename="ExSite (The Example Web Site)"`
The Name of the web site needs to have a `"` before and one after in this case, because it contains spaces. Otherwise, an error will occur.

`thumbsize=200`
The value `200` does not contain any special characters. Therefore no `"` is needed. It doesn't matter whether the value is enclosed in them or not.

All settings are optional. If a setting is not set in the settings file, a default value is used. The following variables/settings are meant to be set in the
settings file. Additional settings can be declared in the same way if they don't have the same name as an existing global variable. Those additional variables can
then be used in hooks. (See the "Hooks" section below.)

`sitename` - The name/title of the website as displayed in the header and used in the browser window title bar/browser tabs.

`url` - The url is used when external documents that link to the web site are generated, e.g. the RSS feed.

`style` - The name of the style set that should be used if none is specified by command line option. See the "Styles" section below to learn which files this will include.

`odir` - The path of the output directory.
 
`thumbsize` - The maximum width and height of gallery image thumbnails when attached to blog entries.

`thumbsizemini` - The maximum width and height of gallery image thumbnails on gallery pages.

`previewsize` - The maximum width and height of gallery image previews as displayed on gallery pages. This should be large enough to view the image in full but doesn't need to be too large as the original image file will be linked for the case that somebody wants to download the full resolution.

`perpage` - The maximum number of entries that will be included in one HTML page when generating tagpages. When there are more entries that belong on the tagpage, it is divided into several HTML pages and a pager is added at the bottom.

`emails` - Associative array of email addresses for authors. See the 'Comments' section below to learn how to use it.

`tagiconsize` - This setting is currently ignored. You may do the same with this line.

`duals` - This setting is currently ignored. You may do the same with this line.

`details` - This setting is obsolete and will be ignored by the script. You may do the same with this line.

`exclude` - This setting is currently ignored. You may do the same with this line.


## Hooks

A hook is a function that is declared in the settings file of a web site. It does not exist in the SBWG script and therefore is not executed if it is not included
in the settings file. No hook is required. There are many hooks that get executed at different points in the generation of a web site. Therefore they can be used to
inject code at certain points of the script for only the web site who's settings file contains the hook. This way the script does not need to be edited for
customisation and different web sites can be customised differently.

Inside a hook all variables that exist at the point at which the hook is executed can be read and changed. Output can be added to the file that is being generated at
that point, additional commands can be executed, and so on. This makes the settings file a very flexible tool for the customisation of a web site and SBWG itself,
and a possible source of errors when not used carefully.

When writing an elaborate new hook (as opposed to copying an example hook or hook from an existing settings file) you will probably not be able to avoid reading at
least some of the SBWG script to see how your goal can be accomplished. There are a couple of helper functions in the script that of course can also be used in
hooks, too. I will not explain here every part of the code that could possibly be of relevance when writing a new hook. I don't know what you want to do with you
hook, so I wouldn't know what to limit myself to.

The below table lists all hooks that currently exist in SBWG and the local variables that are accessible inside these hooks. Additionally there are a couple of
global variables that are accessible from inside every hook:

* `$shellbase` - The path of the input directory - The directory of the web site that is being generated
* `$tmpdir` - The path of the temporary directory - This directory will be deleted after the script is done or when it fails.
* `$version` - The version of SBWG that is processing the website
* `$options` - A string of option letters that are set through command line options
* `$entrylist` - An array that contains all entry names that exist on the web site. Only available after the navigation bar has started to be generated.
* `$entrylists` - An associative array with all existing tag names as keys and lists of entry names as values. Only available after tagpage preparation.
* `$tagslist` - An array that contains all existing tags. Only available after the navigation bar has started to be generated.
* `$gallerylist` - An array that contains the names of all galleries on this web site that contain any supported image files. Only available after navbar generation.
* `$desired_entry` - The entry name, if one was passed to option -e (or --entry).
* `$desired_page` - The page name, if one was passed to option -p (or --page).
* `$desired_tagpage` - The name of the tagpage, if one was passed to option -t (or --tagpage).
* `$desired_gallery` - The name of the gallery, if one was passed to option -g (or --gallery).
* All variables that are declared in the settings file as well as the default values for settings that are not set in the settings file

   ┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┯━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
   ┃ Function Name                      │ Called                                             │ Available Local Variables            │ Usage Examples                ┃
   ┣━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┫
   ┃ hook_error                         │ When a fatal error has occurred                    │ $@   The error message (usually just │ Clean-up before exit          ┃
   ┃                                    │ After the error message has been printed           │        one string, so $1)            │ Send out a notification       ┃
   ┃                                    │ Before the temporary directory gets cleared        │ $str The error message in one string │ Send message to stderr and    ┃
   ┃                                    │                                                    │                                      │   exit cleanly                ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_warning                       │ When an important but non-fatal error has been     │ $@   The warning message (usually    │ Send out warning message      ┃
   ┃                                    │   detected.                                        │        just one string, so $1)       │ Send out a notification       ┃
   ┃                                    │ After the warning message has been printed         │ $str The error message in one string │ Send message to stderr        ┃
   ┃                                    │                                                    │                                      │   without exiting             ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pathreducer                   │ Whenever the pathreducer function is called        │ $1      The path or part of the path │ Manipulate the path before it ┃
   ┃                                    │                                                    │           that should be reduced if  │   is processed                ┃
   ┃                                    │                                                    │           pathreducer mode is in. A  │ Replace the function always   ┃
   ┃                                    │                                                    │           string of path elements    │   in specific cases           ┃
   ┃                                    │                                                    │           separated by '/', the last │                               ┃
   ┃                                    │                                                    │           one being a filename, all  │                               ┃
   ┃                                    │                                                    │           others being a directory   │                               ┃
   ┃                                    │                                                    │           name.                      │                               ┃
   ┃                                    │                                                    │ $maxfnl The maximum allowed filename │                               ┃
   ┃                                    │                                                    │           length. Either an integer  │                               ┃
   ┃                                    │                                                    │           or two integers separated  │                               ┃
   ┃                                    │                                                    │           by a dot.                  │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pathreducer_part_start        │ For each path element (directory name and          │ Same as above. Additionally:         │ Manipulate certain path       ┃
   ┃                                    │   filename)                                        │ $part The currently processed path   │   elements before they are    ┃
   ┃                                    │ Before anything is done to the path element or     │         element                      │   processed                   ┃
   ┃                                    │   anything is outputted                            │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pathreducer_part_before       │ For each path element (directory name and          │ Same as above. Additionally:         │ Further change the reduced    ┃
   ┃                                    │   filename)                                        │ $newbase  If $part is not the last   │   basename and/or suffix      ┃
   ┃                                    │ After all unwanted characters have been removed    │             path element (meaning it │   before the path element     ┃
   ┃                                    │ Before the part is shortened and the hash is added │             is a directory name):    │   gets shortened, the hash    ┃
   ┃                                    │ Before the reduced path element is outputted       │             the reduced directory    │   gets appended and the       ┃
   ┃                                    │                                                    │             name. If it is the last  │   result gets printed         ┃
   ┃                                    │                                                    │             path element (meaning it │                               ┃
   ┃                                    │                                                    │             is a filename): The      │ Override the standard way of  ┃
   ┃                                    │                                                    │             reduced filename's       │   how the path element gets   ┃
   ┃                                    │                                                    │             basename without a       │   reduced, e.g. allow more    ┃
   ┃                                    │                                                    │             suffix/filename          │   special characters or       ┃
   ┃                                    │                                                    │             extension. (The complete │   convert all letters to      ┃
   ┃                                    │                                                    │             reduced filename if      │   upper case                  ┃
   ┃                                    │                                                    │             there is no suffix.)     │                               ┃
   ┃                                    │                                                    │ $newsuff  The reduced suffix of the  │                               ┃
   ┃                                    │                                                    │             filename. Empty if $part │                               ┃
   ┃                                    │                                                    │             is not the last path     │                               ┃
   ┃                                    │                                                    │             element (meaning it is   │                               ┃
   ┃                                    │                                                    │             a directory name) or the │                               ┃
   ┃                                    │                                                    │             filename has no suffix.  │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pathreducer_part_between      │ For each path element (directory name and          │ Same as above, with one change:      │ Custom changes to the path    ┃
   ┃                                    │   filename) if the element needs to be reduced     │ $newbase  The reduced and shortened  │   element after it has been   ┃
   ┃                                    │ After the path element has been reduced/processed  │             basename/directory name/ │   completely processed before ┃
   ┃                                    │ Before the reduced path element is printed         │             filename with a 6-       │   it is outputted             ┃
   ┃                                    │                                                    │             character hash appended. │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pathreducer_part_after        │ For each path element (directory name and          │ Same as above.                       │ Append custom string to the   ┃
   ┃                                    │   filename)                                        │                                      │   path element                ┃
   ┃                                    │ After the path element has been processed and the  │                                      │                               ┃
   ┃                                    │   reduced/processed path element has been outputted│                                      │                               ┃
   ┃                                    │ Before the separating '/' gets outputted           │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_redirect                      │ When an redirection is created (may be link or     │ $1 Path of created HTML file/link    │ Additional file operations    ┃
   ┃                                    │ HTML file that refreshes, redirecting to a URL     │ $2 Path of target, relative to odir  │   related to the redirection  ┃
   ┃                                    │ Before the file is written/the link is created     │                                      │   (e.g. file system links)    ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_prepare                       │ After all preparations have been made              │ -                                    │ Create or copy files indepen- ┃
   ┃                                    │ Before anything gets generated                     │                                      │   dantly of what SBWG will do ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_grab_tags                     │ Whenever tags are extracted from a source file     │ $t  Newline separated list of tags   │ Convert all tags to           ┃
   ┃                                    │ After the tags have been fetched and filtered      │                                      │   uppercase for case-         ┃
   ┃                                    │ Before the tags are used for website generation    │                                      │   insensitive processing      ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_grab_tag                      │ Whenever single tag is extracted from list of tags │ $ret  The requested tag if it was    │ Conceal some tags by checking ┃
   ┃                                    │ After the tag has been fetched                     │       found, a default value, if one │   the about to be returned    ┃
   ┃                                    │ Before the tag is returned to the requesting       │       was supplied, otherwise        │   value and aborting          ┃
   ┃                                    │   function                                         │                                      │   conditionally with return 1 ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_files                         │ When and after the web site's files directory gets │ -                                    │ Copy additional files when-   ┃
   ┃                                    │ copied from the source directory to the output dir │                                      │   ever SBWG copies files dir  ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_head                          │ When the head portion of an HTML file is generated │ $outfile  The HTML file that is cur- │ Inject tags into the HTML     ┃
   ┃                                    │ After the hardcoded tags in the <head> tag         │             rently being generated   │   <head> tag (e.g. link JS)   ┃
   ┃                                    │ Before the <head> tag is closed                    │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_sitename_before               │ When the beginning of the body of an HTML file is  │ $outfile  The HTML file that is cur- │ Inject HTML into the header   ┃
   ┃                                    │   is generated.                                    │             rently being generated   │   section of every generated  ┃
   ┃                                    │ Before the title of the web site is printed        │                                      │   HTML file                   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_sitename_after                │ When the beginning of the body of an HTML file is  │ $outfile  The HTML file that is cur- │ Inject HTML into the header   ┃
   ┃                                    │   is generated.                                    │             rently being generated   │   section of every generated  ┃
   ┃                                    │ After the title of the web site is printed         │                                      │   HTML file                   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_header_before                 │ When the beginning of the body of an HTML file is  │ $outfile  The HTML file that is cur- │ Inject HTML before the header ┃
   ┃                                    │   is generated.                                    │             rently being generated   │   section of every generated  ┃
   ┃                                    │ Before the header section of the page is printed   │                                      │   HTML file                   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_header_after                  │ When the beginning of the body of an HTML file is  │ $outfile  The HTML file that is cur- │ Inject HTML between the header┃
   ┃                                    │   is generated.                                    │             rently being generated   │   section and the navigation  ┃
   ┃                                    │ After the header section of the page is printed    │                                      │   bar of every HTML file      ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_start                   │ When an entry page gets generated                  │ $outfile  The HTML file that is cur- │ Additional preparations of an ┃
   ┃                                    │ After the entry file has been checked              │             rently being generated   │   entry before any HTML is    ┃
   ┃                                    │ After tags have been extracted from the entry file │ $entry    Name of the current entry  │   generated                   ┃
   ┃                                    │ Before any tags are processed                      │ $tags     List of the entry's tags   │                               ┃
   ┃                                    │ Before anything gets written to the HTML file      │ $author   Name of the entry's author │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_above_entry_content           │ When an entry is generated (either entry page or   │ $outfile                             │ Execute something every time  ┃
   ┃                                    │   tag page)                                        │ $entrybasename                       │   an entry is generated,      ┃
   ┃                                    │ Before any HTML above the entry content below the  │ $cachefile                           │   before the content is added ┃
   ┃                                    │   title-wrapper is generated or cache is used.     │ (( $entryname and $entry )           │   but after the title and tags┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_above_entry_content_before    │ When an entry is generated (either entry page or   │ $outfile          $entrybasename     │ Add additional HTML at the    ┃
   ┃                                    │   tag page)                                        │ $cachefile        ( $entryname )     │   beginning of the notes      ┃
   ┃                                    │ If the HTML below the title-wrapper and above the  │ ( $entry )                           │   above the entry content     ┃
   ┃                                    │   content is not cached/if it is generated newly.  │                                      │                               ┃
   ┃                                    │ Before any HTML above the entry content below the  │                                      │                               ┃
   ┃                                    │   title-wrapper is generated.                      │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_above_entry_content_after     │ When an entry is generated (either entry page or   │ $outfile          $entrybasename     │ Add a note to an entry depen- ┃
   ┃                                    │   tag page)                                        │ $author           $atts              │   ding on its tags            ┃
   ┃                                    │ If the HTML below the title-wrapper and above the  │ $images           $title             │                               ┃
   ┃                                    │   content is not cached/if it is generated newly.  │ $cachefile        $attslist          │                               ┃
   ┃                                    │ After the last HTML above the entry content below  │ ( $entryname )    ( $entry )         │                               ┃
   ┃                                    │   the title-wrapper has been generated.            │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_below_entry_content           │ When an entry is generated (either entry page or   │ $outfile                             │                               ┃
   ┃                                    │   tag page)                                        │ $entrybasename                       │                               ┃
   ┃                                    │ Before any HTML below the entry content or the     │ $cachefile                           │                               ┃
   ┃                                    │   cache for this part is used                      │ (( $entryname and $entry )           │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_below_entry_content_before    │ When an entry is generated (either entry page or   │ $outfile          $entrybasename     │                               ┃
   ┃                                    │   tag page)                                        │ $cachefile        ( $entryname )     │                               ┃
   ┃                                    │ If the HTML below the entry content is not cached  │ ( $entry )                           │                               ┃
   ┃                                    │ Before any HTML below the entry content is         │                                      │                               ┃
   ┃                                    │   generated                                        │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_below_entry_content_after     │ When an entry is generated (either entry page or   │ $outfile          $entrybasename     │                               ┃
   ┃                                    │   tag page)                                        │ $author           $atts              │                               ┃
   ┃                                    │ If the HTML below the entry content is not cached  │ $images           $title             │                               ┃
   ┃                                    │ After the last HTML below the entry content is     │ $cachefile        $attslist          │                               ┃
   ┃                                    │   generated                                        │ ( $entryname )    ( $entry )         │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_title_start             │ When an entry chunk gets generated                 │ See hook 'hook_entry_start' above.   │ Inject HTML at the beginning  ┃
   ┃                                    │ Inside (at the beginning of) the title wrapper     │                                      │   of the title-wrapper of an  ┃
   ┃                                    │ After the title wrapper tag has been opened        │                                      │   entry                       ┃
   ┃                                    │ Before the title and meta-information are printed  │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_title_tags_before       │ When an entry chunk gets generated                 │ See hook above.                      │ Inject HTML at the beginning  ┃
   ┃                                    │ Inside the title wrapper                           │ Additionally:                        │   of the tags in the title-   ┃
   ┃                                    │ After the created (and edited) date(s) are printed │ $created  The entry's created date v.│   wrapper of an entry         ┃
   ┃                                    │ Before the tags are printed                        │ $edited   It's edited date value     │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_title_tag_before        │ When a tag gets printed inside the title wrapper   │ See hook above.                      │ Inject HTML before certain or ┃
   ┃                                    │   of an entry                                      │ Additionally:                        │   all tags in the title-      ┃
   ┃                                    │ Before it was checked whether it is a tag that     │ $tag    The currently processed tag  │   wrapper of an entry         ┃
   ┃                                    │   will be printed or not                           │                                      │                               ┃
   ┃                                    │ Before the its surrounding HTML tags are printed   │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_title_tag_after         │ When a tag gets printed inside the title wrapper   │ See hook above.                      │ Inject HTML after certain or  ┃
   ┃                                    │   of an entry                                      │ Additionally:                        │   all tags in the title-      ┃
   ┃                                    │ After the tag has been printed                     │ $tag    The currently processed tag  │   wrapper of an entry         ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_title_tags_after        │ When an entry chunk gets generated                 │ Same as three hooks above.           │ Inject HTML at the end of the ┃
   ┃                                    │ After the tags have been printed                   │   (hook_entry_title_tags_before)     │   tags in the title-wrapper   ┃
   ┃                                    │ Before the title wrapper is closed                 │                                      │   of an entry                 ┃
   ┃                                    │ Before the content is printed                      │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_above_entry_content           │ When the section for notes above content is gene-  │ Same as six hooks above.             │ Same as next hook, actually.  ┃
   ┃                                    │   rated, whether there are any notes or not.       │   (hook_entry_start)                 │                               ┃
   ┃                                    │ After all notes have been printed (if any exist).  │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_before                  │ When an entry page gets generated                  │ Same as seven hooks above.           │ Inject HTML at the beginning  ┃
   ┃                                    │ After the title wrapper is printed and closed      │   (hook_entry_start)                 │   of the content of the       ┃
   ┃                                    │ After the content div is opened                    │                                      │   content of an entry on the  ┃
   ┃                                    │ After the reference lines (if any) have been been  │                                      │   entry page                  ┃
   ┃                                    │   printed                                          │                                      │                               ┃
   ┃                                    │ Before the entry content is printed                │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_after                   │ When an entry page gets generate                   │ See hook above.                      │ Inject HTML at the end of the ┃
   ┃                                    │ After the entry content is printed                 │                                      │   content of an entry on the  ┃
   ┃                                    │ Before the content div is closed                   │                                      │   entry page                  ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entry_end                     │ When an entry page gets generated                  │ See hook above.                      │ Additional file operations    ┃
   ┃                                    │ After everything concerning this entry is done and │                                      │   after an entry page has     ┃
   ┃                                    │   the HTML file is completed and closed            │                                      │   been generated that don't   ┃
   ┃                                    │                                                    │                                      │   affect generation           ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entries_start                 │ When generating entries                            │ -                                    │ Additional operations per-    ┃
   ┃                                    │ Before any entry has been generated or prepared    │                                      │   formed if and before any    ┃
   ┃                                    │                                                    │                                      │   entry pages are generated   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_entries_end                   │ When generating entries                            │ -                                    │ Additional operations per-    ┃
   ┃                                    │ After all entries have been generated/completed    │                                      │   formed if and after all     ┃
   ┃                                    │                                                    │                                      │   entry pages are generated   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_gallery_start                 │ When a gallery page gets generated                 │ $outfile  The HTML file that is cur- │ Additional changes or other   ┃
   ┃                                    │ After gallery generation has been prepared         │             rently being generated   │   preparations of the gallery ┃
   ┃                                    │ After the gallery has been checked                 │ $gallery  Name of the gallery that is│   before it is processed      ┃
   ┃                                    │ Before anything gets written to the HTML file      │             currently being generated│                               ┃
   ┃                                    │                                                    │ $images   List of file names of all  │ Exclude certain images con-   ┃
   ┃                                    │                                                    │             images in this gallery   │   ditionally, e.g. based on   ┃
   ┃                                    │                                                    │ $tags     If there is a corrospon-   │   file names                  ┃
   ┃                                    │                                                    │             ding entry: list of all  │                               ┃
   ┃                                    │                                                    │             tags of that entry       │ Add something to the gal-     ┃
   ┃                                    │                                                    │ $title    If there is a corrospon-   │   lery's title if its corros- ┃
   ┃                                    │                                                    │             ding entry: Entry's title│   ponding entry source file   ┃
   ┃                                    │                                                    │                                   l  │   contains a certain tag      ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_gallery_before                │ When a gallery page gets generated                 │ See hook above.                      │ Add text to the header of the ┃
   ┃                                    │ After the navigation bar and page header have been │                                      │   gallery above its thumb-    ┃
   ┃                                    │   generated                                        │                                      │   nails                       ┃
   ┃                                    │ Before the image thumbnails are written to the     │                                      │                               ┃
   ┃                                    │   HTML file                                        │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_gallery_image_before          │ When an image is placed in a gallery page          │ See hook above.                      │ Change from where the the     ┃
   ┃                                    │ After the image file has been checked              │ Additionally:                        │   file/which image file is    ┃
   ┃                                    │ Before the image preview is placed in the HTML file│ $image   Path and file name of the   │   embedded in the gallery     ┃
   ┃                                    │                                                    │            currently processed image │   (e.g. change the default    ┃
   ┃                                    │                                                    │ $img     Its file name without path  │   preview to a CDN source)    ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_gallery_image_after           │ When an image is placed in a gallery page          │ See hook above.                      │ Inject additional text or a   ┃
   ┃                                    │ After the image preview has been placed in the     │                                      │   link below all images or    ┃
   ┃                                    │   HTML file                                        │                                      │   certain images e.g. based   ┃
   ┃                                    │ Before the "Go to top" link is placed in the file  │                                      │   on the gallery title/name   ┃
   ┃                                    │                                                    │                                      │   or image file name          ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_gallery_after                 │ When a gallery page gets generated                 │ Same as three hooks above.           │ Add a footer to all or to     ┃
   ┃                                    │ After the last image has been placed in the        │   (hook_gallery_before)              │   certain galleries           ┃
   ┃                                    │   generated HTML output file                       │                                      │                               ┃
   ┃                                    │ Before the main section is closed and the footer   │                                      │                               ┃
   ┃                                    │   printed to the generated HTML output file        │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_gallery_end                   │ When a gallery page gets generated                 │ See hook above.                      │ Additional image modifi-      ┃
   ┃                                    │ After the gallery page HTML file has been finished │                                      │   cations after the fact      ┃
   ┃                                    │ After everything concerning this gallery is done   │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_galleries_start               │ When image galleries are generated                 │ -                                    │ Additional operations before  ┃
   ┃                                    │ Before it gets decided which galleries will be     │                                      │   any gallery is generated    ┃
   ┃                                    │   generated                                        │                                      │                               ┃
   ┃                                    │ Before any of the galleries have been checked,     │                                      │ Modify the list of list of    ┃
   ┃                                    │   prepared or generated                            │                                      │   galleries before processing ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_galleries_end                 │ When image galleries are generated                 │ -                                    │ Additional operations to be   ┃
   ┃                                    │ After every gallery has been generated             │                                      │   performed if any galleries  ┃
   ┃                                    │                                                    │                                      │   are/have been generated     ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_page_start                    │ When a SBWG page gets generated                    │ $outfile  The HTML file that is cur- │ Modify the tags or content of ┃
   ┃                                    │ After the page file has been checked               │             rently being generated   │   the page that is about to   ┃
   ┃                                    │ After tags have been extracted from the page file  │ $tags     List of the page's tags    │   be generated                ┃
   ┃                                    │ Before any tags are processed                      │ $title    The page's title if tag set│                               ┃
   ┃                                    │ Before anything gets written to the HTML file      │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_page_title_before             │ When a SBWG page gets generated                    │ See hook above.                      │ Inject HTML right before the  ┃
   ┃                                    │ If the page has a title tag                        │                                      │   title of a page if it was   ┃
   ┃                                    │ After the header and navigation bar have been      │                                      │   defined by a tagline        ┃
   ┃                                    │   added to the generated output file               │                                      │                               ┃
   ┃                                    │ Right before the title gets printed on the page    │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_page_title_after              │ When a SBWG page gets generated                    │ See hook above.                      │ Append text to the title of a ┃
   ┃                                    │ If the page has a title tag                        │                                      │   page if its title was de-   ┃
   ┃                                    │ Right after the title gets printed on the page     │                                      │   fined by a tagline          ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_page_content_before           │ When a SBWG page gets generated                    │ See hook above.                      │ Add text right before the     ┃
   ┃                                    │ Right before the content gets printed on the page  │                                      │   content of a page           ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_page_content_after            │ When a SBWG page gets generated                    │ See hook above.                      │ Add text right after the      ┃
   ┃                                    │ Right after the content gets printed on the page   │                                      │   content of a page           ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_page_end                      │ When a SBWG page gets generated                    │ See hook above.                      │ Additional operations after   ┃
   ┃                                    │ After everything concerning this page has been     │                                      │   a page's HTML file has been ┃
   ┃                                    │   done                                             │                                      │   generated                   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pages_start                   │ When SBWG pages are generated                      │ -                                    │ Modify the list of pages that ┃
   ┃                                    │ Before any pages are prepared or generated         │                                      │   are about to be generated   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_pages_end                     │ When SBWG pages are generated                      │ -                                    │ Additional operations after   ┃
   ┃                                    │ After all pages have been generated                │                                      │   pages have been generated   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_start                  │ Before any HTML pages are generated                │ $entrylist  Array of entries that    │ Modify $entrylist or          ┃
   ┃                                    │ If any HTML pages will be generated in this run    │               exist in the web site  │   $tagslist_unsorted before   ┃
   ┃                                    │ When the navigation bar is generated               │ $tagslist_unsorted  Array of tags    │   they are used / Inject      ┃
   ┃                                    │ Before any preparations for the navigation bar     │                       that exist in  │   possibly fake entries or    ┃
   ┃                                    │   generation have been done                        │                       the web site   │   tags                        ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_before                 │ When the navigation bar is generated (once per     │ $outfile  Path of the navbar file in │ Add links to the beginning of ┃
   ┃                                    │   run of the script)                               │             the temporary directory  │   the navigation bar          ┃
   ┃                                    │ After the <nav> tag has been opened                │             during the generation of │ Add HTML before the first     ┃
   ┃                                    │ Before anything gets printed to the navigation bar │             the navigation bar       │   navigation/menu item/link   ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_item_before            │ When the navigation bar is generated (once per     │ See hook above.                      │ Inject HTML at the beginning  ┃
   ┃                                    │   run of the script)                               │ Additionally:                        │   of every link in the menu/  ┃
   ┃                                    │ For each tag that occurs at least once in an entry │ $item   Tag that is currently being  │   navigation bar              ┃
   ┃                                    │ Before the tag type has been checked               │           processed (e.g. "cat:foo") │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_item_after             │ When the navigation bar is generated (once per     │ See hook above.                      │ Inject HTML after every menu  ┃
   ┃                                    │   run of the script)                               │                                      │   item/link in the navigation ┃
   ┃                                    │ For each tag that occurs at least once in an entry │                                      │   bar.                        ┃
   ┃                                    │ After the tag type has been checked and the tag    │                                      │                               ┃
   ┃                                    │   been processed if of a tag type that is included │                                      │                               ┃
   ┃                                    │   in the navigation bar by default                 │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_item_change            │ When the navigation bar is generated (once per     │ See hook above.                      │ Add a link at the end of a    ┃
   ┃                                    │   run of the script)                               │                                      │   list of items in the navi-  ┃
   ┃                                    │ For the last tag of each tag type that occurs at   │                                      │   gation bar (e.g. add custom ┃
   ┃                                    │   least once in an entry                           │                                      │   item/link in the link list  ┃
   ┃                                    │   least once in an entry                           │                                      │   category items              ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_galleries_before       │ When the navigation bar is generated (once per     │ Same as four hooks above.            │ Modify the list of galleries  ┃
   ┃                                    │   run of the script)                               │   (hook_navbar_before)               │   before it's used for the    ┃
   ┃                                    │ After all tags have been processed                 │                                      │   first time (e.g. add/remove ┃
   ┃                                    │ Right before the list of galleries is generated    │                                      │   galleries conditionally)    ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_gallery_before         │ When the navigation bar is generated (once per     │ See hook above. Additionally:        │ Add HTML right before all or  ┃
   ┃                                    │   run of the script)                               │ $gallery  Name of the currently      │   certain gallery links in    ┃
   ┃                                    │ Before a gallery gets printed to the output file   │             being added to the list  │   the gallery link list in    ┃
   ┃                                    │                                                    │             in the navigation bar    │   the navigation bar          ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_gallery_after          │ When the navigation bar is generated (once per     │ See hook above.                      │ Add HTML right after all or   ┃
   ┃                                    │   run of the script)                               │                                      │   certain gallery links in    ┃
   ┃                                    │ After a gallery gets printed to the output file    │                                      │   the gallery link list in    ┃
   ┃                                    │                                                    │                                      │   the navigation bar          ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_galleries_after        │ When the navigation bar is generated (once per     │ Same as six hooks above.             │ Inject an additional link at  ┃
   ┃                                    │   run of the script)                               │   (hook_navbar_before)               │   the end of the list of gal- ┃
   ┃                                    │ After the list of galleries has been printed to    │                                      │   lery links in the navi-     ┃
   ┃                                    │   the generated HTML output file                   │                                      │   gation bar                  ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_after                  │ When the navigation bar is generated (once per     │ See hook above.                      │ Inject HTMl at the end of the ┃
   ┃                                    │   run of the script)                               │                                      │   navigation bar              ┃
   ┃                                    │ After all content that is included in the          │                                      │                               ┃
   ┃                                    │   navigation bar by default has been added to it   │                                      │ Add custom links after all    ┃
   ┃                                    │ Before the <nav> tag is closed                     │                                      │   others in the navigation bar┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_navbar_end                    │ When the navigation bar is generated (once per     │ See hook above.                      │ Execute additional commands   ┃
   ┃                                    │   run of the script)                               │                                      │   once per run if HTML output ┃
   ┃                                    │ After everything concerning the navigation bar     │                                      │   is generated                ┃
   ┃                                    │   generation has been processed                    │                                      │ Parse/alter navigation bar    ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_start                 │ When a tagpage is generated                        │ $outfile    Path of the tagpage HTML │                               ┃
   ┃                                    │ After the output file has been checked             │               file that is currently │                               ┃
   ┃                                    │ Before anything gets written to the generated      │               being generated        │                               ┃
   ┃                                    │  tagpage HTML output file                          │ $tag        Name of the tag for which│                               ┃
   ┃                                    │                                                    │               the tagpage is cur-    │                               ┃
   ┃                                    │                                                    │               rently being generated │                               ┃
   ┃                                    │                                                    │ $lastentry  Number of entries that   │                               ┃
   ┃                                    │                                                    │               are included on this   │                               ┃
   ┃                                    │                                                    │               tagpage                │                               ┃
   ┃                                    │                                                    │ $lastpage   Number of additional     │                               ┃
   ┃                                    │                                                    │               pages if this tagpage  │                               ┃
   ┃                                    │                                                    │               will have a pager/more │                               ┃
   ┃                                    │                                                    │               than one HTML page     │                               ┃
   ┃                                    │                                                    │ $pagecount  Number of the page that  │                               ┃
   ┃                                    │                                                    │               is currently being     │                               ┃
   ┃                                    │                                                    │               processed (out of      │                               ┃
   ┃                                    │                                                    │               $lastpage pages)       │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_before                │ When a tagpage is generated                        │ See hook above. Additionally:        │                               ┃
   ┃                                    │ After the header and navigation bar of the         │ $secs    List of tags for which      │                               ┃
   ┃                                    │   generated HTML page have been generated          │            combined tagpages will    │                               ┃
   ┃                                    │ Right after the content <div> tag is opened        │            be generated (if any)     │                               ┃
   ┃                                    │ Before the content of the tagpage is written       │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_top_before      │ When a topic tagpage is generated                  │ See hook above. Additionally:        │                               ┃
   ┃                                    │ Inside the title-wrapper div                       │ $entrycount   Number of the entry    │                               ┃
   ┃                                    │ Before the title of an entry is printed to HTML    │                 is currently being   │                               ┃
   ┃                                    │                                                    │                 processed (out of    │                               ┃
   ┃                                    │                                                    │                 $lastentry pages)    │                               ┃
   ┃                                    │                                                    │ $tags         List of all tag lines  │                               ┃
   ┃                                    │                                                    │                 of the currently     │                               ┃
   ┃                                    │                                                    │                 processed entry      │                               ┃
   ┃                                    │                                                    │ $author       Name of the author     │                               ┃
   ┃                                    │                                                    │                 of the current entry │                               ┃
   ┃                                    │                                                    │ $target       Name of an entry the   │                               ┃
   ┃                                    │                                                    │                 current entry will   │                               ┃
   ┃                                    │                                                    │                 redirect to (if any) │                               ┃
   ┃                                    │                                                    │ $entryname    Name of the currently  │                               ┃
   ┃                                    │                                                    │                 processed entry      │                               ┃
   ┃                                    │                                                    │ $created      Created date value of  │                               ┃
   ┃                                    │                                                    │                 the current entry    │                               ┃
   ┃                                    │                                                    │ $edited       Edited date value of   │                               ┃
   ┃                                    │                                                    │                 the current entry    │                               ┃
   ┃                                    │                                                    │ $title        Title of the current-  │                               ┃
   ┃                                    │                                                    │                 ly processed entry   │                               ┃
   ┃                                    │                                                    │ $sortby       Sort value of the      │                               ┃
   ┃                                    │                                                    │                 current entry        │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_top_after       │ When a topic tagpage is generated                  │ See hook above.                      │                               ┃
   ┃                                    │ Inside the title-wrapper div                       │                                      │                               ┃
   ┃                                    │ After the created and edited dates have been       │                                      │                               ┃
   ┃                                    │   printed to the generated HTML file               │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_title_before    │ When a tagpage (not topic tagpage) is generated    │ See hook above.                      │                               ┃
   ┃                                    │ For each entry that on this tagpage except for     │                                      │                               ┃
   ┃                                    │   stickied entries                                 │                                      │                               ┃
   ┃                                    │ Inside the title-wrapper div                       │                                      │                               ┃
   ┃                                    │ Before the entry's title is written to the HTML    │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_title_after     │ When a tagpage (not topic tagpage) is generated    │ See hook above.                      │                               ┃
   ┃                                    │ For each entry that on this tagpage except for     │                                      │                               ┃
   ┃                                    │   stickied entries                                 │                                      │                               ┃
   ┃                                    │ Inside the title-wrapper div                       │                                      │                               ┃
   ┃                                    │ After the entry's title is written to the HTML     │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_stickied        │ When a tagpage (not topic tagpage) is generated    │ See hook above.                      │                               ┃
   ┃                                    │ For each stickied entry on this tagpage            │                                      │                               ┃
   ┃                                    │ Before the entry's content is printed to the HTML  │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_content_before  │ When a tagpage (not topic tagpage) is generated    │ See hook above.                      │                               ┃
   ┃                                    │ Inside the entry-content-wrapper div               │                                      │                               ┃
   ┃                                    │ Before the entry's content is printed to the HTML  │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_entry_content_after   │ When a tagpage (not topic tagpage) is generated    │ See hook above.                      │                               ┃
   ┃                                    │ Inside the entry-content-wrapper div               │                                      │                               ┃
   ┃                                    │ After the entry's content is printed to the HTML   │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_after                 │ When a tagpage is generated                        │ Same as eight hooks above.           │                               ┃
   ┃                                    │ After all entries have been added to the generated │   (hook_tagpage_before)              │                               ┃
   ┃                                    │   HTML file in the output directory                │                                      │                               ┃
   ┃                                    │ Before content <div> tag has been closed           │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpage_end                   │ When a tagpage is generated                        │ See hook above.                      │                               ┃
   ┃                                    │ After all entries concerning this tagpage have     │                                      │                               ┃
   ┃                                    │   been processed                                   │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpages_entry                │ When tagpage generation is prepared                │ $entry    Name of entry currently    │ Influence tagpage sorting by  ┃
   ┃                                    │ For each entry that exists on the web site         │             being examined           │   changing $sortby of entries ┃
   ┃                                    │ After the entry source file has been checked       │ $tags     List of all tags of the    │                               ┃
   ┃                                    │ After some meta information has been retrieved     │             currently examined entry │                               ┃
   ┃                                    │   from the entry's tags                            │ $created  Created date value of the  │                               ┃
   ┃                                    │ After the entry's sorting value has been determined│             currently examined entry │                               ┃
   ┃                                    │ Before all tags have been checked                  │ $edited   Edited date value of the   │                               ┃
   ┃                                    │ Before the entry is assigned to any tagpage        │             currently examined value │                               ┃
   ┃                                    │ Before any tagpages get generated                  │ $author   Name of the author of the  │                               ┃
   ┃                                    │                                                    │             currently examined entry │                               ┃
   ┃                                    │                                                    │ $sortby    Sort value of the         │                               ┃
   ┃                                    │                                                    │             currently examined entry │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpages_start                │ When tagpages get generated                        │ -                                    │                               ┃
   ┃                                    │ After tagpage generation has been prepared         │                                      │                               ┃
   ┃                                    │ Before it is determined which tagpages to generate │                                      │                               ┃
   ┃                                    │ Before any tagpages get generated                  │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_tagpages_end                  │ When tagpages get generated                        │ -                                    │                               ┃
   ┃                                    │ After all tagpages that are generated in this run  │                                      │                               ┃
   ┃                                    │   of the script have been completely generated     │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_footer                        │ Whenever the footer that goes at the end of every  │ -                                    │                               ┃
   ┃                                    │   HTML document is added.                          │                                      │                               ┃
   ┃                                    │ Right before the body tag is closed.               │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_rss_start                     │ When an RSS file gets generated                    │ $outfile    Path of the RSS file     │                               ┃
   ┃                                    │ Before anything is concerning the RSS feed         │               being generated        │                               ┃
   ┃                                    │ Before the RSS file is generated                   │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_rss_channel                   │ When an RSS file gets generated                    │ See hook above.                      │ Restrict which entries will   ┃
   ┃                                    │ After the blog's meta information have been added  │                                      │   be included (e.g. number    ┃
   ┃                                    │ Before any entries are added to the feed           │                                      │   of entries in the feed)     ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_rss_entry                     │ When an RSS file gets generated                    │ See hook above. Additionally:        │ Change the entry's name for   ┃
   ┃                                    │ For each entry that is added to the feed           │ $entry      URL of the entry file    │   the RSS feed.               ┃
   ┃                                    │ Before any data concerning this entry is added     │ $entryname  Name of the entry (file) │                               ┃
   ┃                                    │                                                    │ $tags       Newline separated list   │ Change how entries with no    ┃
   ┃                                    │                                                    │               of tags of the cur-    │   content are displayed in    ┃
   ┃                                    │                                                    │               rently processed entry │   RSS feeds.                  ┃
   ┃                                    │                                                    │ $author     Name of the author of    │                               ┃
   ┃                                    │                                                    │               the currently pro-     │ Determine how entries with no ┃
   ┃                                    │                                                    │               cessed entry           │   specified author (no author ┃
   ┃                                    │                                                    │ $title      Title of the currently   │   tag line) are displayed in  ┃
   ┃                                    │                                                    │               processed entry        │   the RSS feed.               ┃
   ┃                                    │                                                    │ $pubdate    Created date of the cur- │                               ┃
   ┃                                    │                                                    │               rently processed en-   │ Exclude certain entries from  ┃
   ┃                                    │                                                    │               try, Edited date if no │   the RSS feed e.g. based on  ┃
   ┃                                    │                                                    │               create date exists for │   tags or content.            ┃
   ┃                                    │                                                    │               the currently pro-     │                               ┃
   ┃                                    │                                                    │               cessed entry, $pubdate │                               ┃
   ┃                                    │                                                    │               is in RFC 2822 format; │                               ┃
   ┃                                    │                                                    │               The entry is omitted   │                               ┃
   ┃                                    │                                                    │               if pubdate does not    │                               ┃
   ┃                                    │                                                    │               start with a number    │                               ┃
   ┃                                    │                                                    │ $content    Content of the currently │                               ┃
   ┃                                    │                                                    │               processed entry        │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_rss_end                       │ When an RSS file gets generated                    │ See hook above.                      │ Add additional content        ┃
   ┃                                    │ After the last entry has been added to the feed    │                                      │   (channels, items/entries)   ┃
   ┃                                    │ Before the <rss> tag is closed                     │                                      │                               ┃
   ┠────────────────────────────────────┼────────────────────────────────────────────────────┼──────────────────────────────────────┼───────────────────────────────┨
   ┃ hook_end                           │ After everything that is generated in this run of  │ -                                    │ Perform additional operations ┃
   ┃                                    │   of the script has been done                      │                                      │   on the final product        ┃
   ┃                                    │ Before cleanup (removal of temporary files)        │                                      │ Send out a notification       ┃
   ┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┷━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Because the settings file is sourced in the script after all functions have been declared, you could also overwrite a function to replace it with a custom version
of yours without editing the script file itself.


## Comments To Blog Entries

A comment link can be added below every entry from an author for whom an email address has been defined in the settings file. To define an email address, assign it
to an array item of the `emails` variable. The item name has to be corresponding to the author name. Examples:

`emails[Fooberg]=fooberg@example.com` - Sets the email address for the author 'Fooberg'. A comment link will be added to entries that are tagged 'author:Fooberg'.

`emails['James Barrie']=james-blog-comments@example.com` - Sets the email address for comments on entries tagged 'author:James Barrie'.

The email addresses will be publicly visible to visitors of web pages that contain the comment link. The addresses will also be included in the author tag of RSS
feeds in order to comply with the RSS standard. This means the addresses will also be accessible to spam bot feeding crawlers and everybody else with an internet
connection. If you see a problem with that, I recommend to only use throw-away addresses as comment addresses.


# Styles

A style, or style set, is a group of CSS, JavaScript, image or other files that together create the look and behaviour of the web site. The styles directory can
contain several style sets that are independent of each other. When generating a web site one of these sets is used as the preferred style. Zero or more style sets
can be defined optionally as alternate styles. If several style sets are defined in the web site's settings file, the first one is used as the preferred style an
all others are added as alternate styles. That means that visitors of the web site can select one of the alternate styles if they choose to and their browser
supports alternate stylesheets. All files belonging to the preferred style set are copied to the `styles` directory inside the output directory. Only CSS files
belonging to the alternate style set are copied.

If no style set is defined on the command line (See "Options" below, specifically option `--style`/`-s`) or in the web site's settings file (see "Settings" section
below) the style "elth" is used as a fallbck. That means that by default all CSS files with a name starting with `elth-` and ending in `.css` or `.js` as well as
the files `elth.css` and `elth.js` will be linked in the header of every generated HTML file. Capitalisation of the file name suffix does not matter. For example
the following files will all be used if they exist:
elth.css
elth-colours.css
elth-mobile.css
elth-anything-that-you-want.CSS

Additionally, files whose names start with `elth-` or `elth.` and don't end in .css or .js are copied to the output directory's styles directory. So the following
files will be copied if they exist when option`--style`/`-s` is used:
if the style set "elth" is used:
elth.png
elth-background-tile.GiF
elth-logo.svg
elth-something.jpeg
elth-anything that you want

The default style `elth` consists of several CSS files and comes with the SBWG package. If you want to make custom changes to the default elth style, you can either
edit one of the existing CSS files (e.g. elth.css) or add a file named elth-custom.css or similar (elth-something.css). The latter is highly preferred because it
prevents your changes from being overwritten if you decide to update the style with a newer version of the SBWG package.

If you want to create your own style set, you can specify its name in your web site's setting file or pass it with the --style/-s option upon generation.
Specifically, for the following example, you can use the command line option `--style=my_style` or `-s my_style` or, to make it more permanent, edit/add
`style=my_style` to the web site's settings file.

Example file names: If your style is set as "my_style" then the files
my_style.css
my_style-sidebar.css
my_style-awesomeness.js
my_style-something.css
my_style-effects.JS

and so on, will be linked in the head section of every generated HTML file.

If you would like to link a CSS or JS file in some but not all HTML file's headers or insert an internal CSS or script into the header, you can use the hook
`hook_head` to add custom code that decides what to add in which cases. (See the "Hooks" section above.)


## Preferred Style And Alternate Styles

Some web browsers support alternate styles if a web page offers them, letting the visitor of a web page choose from several different styles. Multiple styles can
be defined in the web site's settings file by using the style variable as an array. That simply means that instead of

`style=my_style`

you write

`style=( my_style another_style 'Extra Fancy' )

resulting in `my_style` being used as the preferred style and the styles `another_style` and `Extra Fancy` being offered as alternate styles if the web browser
supports this. A web site with this setting of course will only be generated if those styles exist. There are example lines in the example web site's settings file
for setting one or multiple style sets. The names will be displayed in the browser's menu as specified. So if you want to offer an alternate style named 'Extra
Fancy', for example, then the files belonging to that style set have to be named accordingly (including capitalisation and the space): 'Extra Fancy.css',
'Extra Fancy-mobile.css', etc.

Users will have to be made aware of the fact that there is a choice. Browsers don't usually make this visible unless the user looks for the available styles.

Note that the style `base` is handled specially. If a style of this name is defined as an alternate style, its stylesheets will be applied to the page regardless of
which style is selected by the visitor. If `base` is defined as the default style (the first style, the preferred style), it will be used like any other style that's
defined as default/preferred/first style. To be used regardless of which style is selected in the web browser, `base` has to be defined at an alternate style,
meaning it has to be other than in the first place of defined styles.

Additionally, the file `reset.css` resembles a special case of stylesheet. If at least one alternate style is offered and the file `reset.css` exists in the input
directory's styles directory, then it will be applied regardless of which stylesheet is selected by the page visitor. If the file exists in the `styles/` directory
and at least a second style set is defined, it will be copied and linked even if a style of the name `reset` is not defined among the chosen style sets.


# Pages

A page in SBWG terminology is a file consisting of a title and content, that will be turned into an HTML file but not automatically linked to from other generated
files. Typical uses for pages are the index page, a contact page, about page or any other HTML page that has to contain the header, sidebar, menu and footer but is
not part of the weblog. The page source files are placed in the `pages` directory in the web site's source directory. Each file represents one page. Their filenames
may not contain any characters that can not be used in URLs (reserved characters or otherwise problematic characters) or non-printable characters (newline, NULL
bytes, ...). Spaces are fine, though. Please note that if you use different file systems for the source directory, output directory, temporary directory or the
web server, no filename may be longer than the longest allowed filename on the file system with the shortest allowed filename minus five characters (for '.html'
extension).

It is recommended to at least have a file named `index` in this directory. It will be turned into an HTML page and placed as "index.html" in the root of the output
directory so that it will be the default index page if not specified otherwise by webserver settings. Respectively, all other text files that are directly in the
`pages` directory are turned into HTML files and placed directly in the output directory. Subdirectory below the pages/ directory that contain at least one page
source file that is going to be generated will be also created in the root of the output directory, meaning the directory tree from the pages/ directory will be
recreated in the output directory.

A page does not have to contain a source file header as it is recommended for entries (see the "entries" section below). But if a page source file starts with a line
that starts with `title:`, that title will be used as the heading. For example if the first line of a file in the `pages` directory is

`title:This Is The Tilte But It Has A Typo`

then the generated HTML page will turn that line into an `<h2>` heading. In the future, more tag types for page files will be added. But right now `title:` is the
only one.

## Example Of A Page Source File

    title:Interesting Title
    
    <p>This is just an example.</p>


# Blog/Weblog

The blog is the most complex part of a SBWG website. Having a blog is optional, as is pretty much any feature of the blog. The blog content is made up of entries,
which are combined into HTML pages for every author, topic, category and language tag an entry contains. An individual HTML file for each entry is also generated.


## Blog Entries

Blog entries are stored in the `entries` directory of the web site. Each file represents one blog entry. Their filenames may not contain any characters that can not
be used in URLs (reserved characters or otherwise problematic characters) or non-printable characters (newline, NULL bytes, ...). Spaces are fine, though. Please
note that if you use different file systems for the source directory, output directory, temporary directory or the web server, no filename may be longer than the
longest allowed filename on the file system with the shortest allowed filename minus five characters (for '.html' extension). The option `--reduce-paths` or `-R`
can be used to shorten file names of the generated files.

An entry source file consists of a header and content. Both are technically optional. That means that any text file can be an entry file, too. The header of an entry
source file is made up of various tags that provide metadata to the entry, like the name of the author, the date when the entry was created, the categories it is
filed under, and so on. Line breaks in the header have to be in the unix form (LF) unless the Bash environment SBWG in run in treats other characters as line breaks
by default. An entry file without a header will be included in the weblog view of the generated web site. But since there are no information about where the entry
should be placed, linked and sorted in the weblog, it is recommended to provide some basic information in each entry source file header.

The header ends where the content (lines of text that are not tags) starts. Everything below the header will be used as the content of the entry. The content part
will be copied to the generated HTML page un-parsed. You can use HTML tags in the content.


## Example Of An Entry Source File

    note:This tag can be used to make a note for readers of the source file.
    title:Interesting Blog Entry
    created:2021-05-05
    author:foobär
    cat:Example Entries
    top:Interesting Things
    cat:Another Category
    
    <p>This is the example entry's content. The paragraph tags are not necessary. Any HTML that belongs in an HTML body can be used here. All the above tags are
    optional. Their order does not matter. Multiple category (cat:) and topic (top:) tags can be used. The "Tags" section in the README file for more information
    about tags.</p>


## Tags

Tags assign meta information to an entry or page, such as their title, creation date, categories or the name of the author of an entry. They are written one per
line at the beginning of an entry or page source file. (See the sections "Blog Entries" and "Pages" above.)

All tags are optional. Some tag types are useful to use multiple times in a single entry header, others should only occur once. Some tag types you will rarely use
and some probably never. The section "Tags Types" below lists and explains all tag types that SBWG knows. If you use a tag that is not listed below, it will be
ignored by SBWG. But too many lines of non-existent tag types will make it look to the script like they are not part of the header anymore. In that case they and
every following line will be considered part of the page's/entry's content.

A tag line starts with the tag type, followed by a colon (":"), followed by the value of the tag. The value of tags may not contain colons, except when it is used
to delimit sub-tags. See below for more forbidden characters and considerations or unwise character usage in SBWG tags.

### Tag Value Limitations

The following paragraphs are still true, but since they have been written, many changes have been made to handle every possibility automatically by filtering and
encoding characters where needed. In short: Avoid colons (':'), avoid slashes ('/') in tags of the type top, cat, lang and author. Avoid tab characters in tags of
all types. Avoid non-existing unicode characters. If you do use any of those, expect them to be replaced or removed in the output that is generated by the script.
Avoid any characters that can't be part of a filename on your filesystem(s) in tags of the type top, cat, lang and author. Alternatively use option
-R/--reduce-paths to convert file names into a format that is supported by your filesystem(s).

Some characters are not allowed in tag values, due to different reasons, founded in both the way the script processes and saves the content and by the way the result
will be handled (web browsers). The maximum allowed length of file names and paths differs on different file systems. If you don't know the limitations of the file
system(s) that you are/will be using or if you can't be sure which file systems will be used for generating or serving a web site in the future, use the general rule
of keeping tag values short and without special characters. If the web site you want to generate contains tag values or file names with characters that are not
supported by at least one of the file systems you use, you can use the option --reduce-paths (-R) to reduce the length of and remove special characters from all
generated directory names, file names and HTML links/anchors. See 'sbwg --help options' for more information.

Not allowed in any tag type are: `:` (colon), the NULL byte and the newline character (line break, Unicode U+000A). Even though colons do work in many use cases,
they can also break things in certain cases.

In the tag types `cat:`, `top:`, `lang:` and `author:` the following characters are not allowed: `+` (plus sign), `#` (hash sign), `?` (question mark),
`%` (percent sign), `/` (slash). Additionally, any characters that can not be part of a URL or a file name on any file system that will be used by the script (that
includes the input directory, the output directory and the temporary directory) or the web server must be avoided.

For Windows file systems several common special characters are forbidden. Additionally some words are forbidden as file names in Windows. For a list of
allowed/forbidden characters and words please refer to the relevant documentation or specifications depending on the system you are using. SBWG will add `.html` at
the end of generated file names of tagpages and the name of a second tag for combined tagpages. That means that, for example, for ext file systems with a maximum
file name length of 255 bytes, the longest allowed value of `author` tags is 118 bytes and for `top` tags 119 bytes if combined tag pages are generated. If the
longest tag value of one of those tag types is shorter, the other one can use longer values.

Several characters are to be avoided because they can or will cause problems when used in a URI/URL. Those problems can occur in different use cases of the URI and
the rules for problematic characters are deeper than I'm willing to explain here. For more information, see the Internet Engineering Task Force's memo "Uniform
Resource Identifier (URI): Generic Syntax" (RFC3986) at https://datatracker.ietf.org/doc/html/rfc3986 (additionally older version RFC2396 at
https://datatracker.ietf.org/doc/html/rfc2396 if you want to serve old and obsolete client software). Please note that some web browsers may not be able to access
pages with URLs with non-printable characters and old browsers have trouble with characters that do not belong to the original set of accepted characters (unicode
emoticons and umlauts for examples).

If you want to be sure for all sorts of systems both of the server and client side, only use alphanumeric characters for `top:`, `cat:`, `author:` and `lang:` tags
and keep them short, or use the pathreducer (option `--reduce-paths`/`-r`).


### Tag Types

The following tag types can be used in header of page source files as well as entry source files.

`note:`
This tag has no function. It is a valid tag but it is ignored by SBWG. It can be used to include a note/comment in an entry or page source file header.
Multiple note tags can be used in a single file.
Example: `note:This is just a note.`

`title:`
The title of the entry or page
If more than one title tag is present, the first one will be used.
Example: `title:An Interesting Title`

`menu:`
This tag type does not exist, yet. It will be used in future versions of SBWG to place an entry (or page) at a certain point in a menu.
Example: `menu:Main:About:History` (not yet implemented)

The following tag types can only be used in entry source file headers.

`created:`
The date at which the entry was first created. Any string is accepted, but only dates in formats that are recognised by your system's `date` programme will be used
as publication dates in feed (RSS, ATOM). Any alphanumerical format in descending order works for sorting of entries as long as every entry uses the same format.
It is recommended to use the ISO style date format YYYY-MM-DD for simplicity. If more than one created tag is present, only the first one will be used.
Example: `created:2020-12-29`

`edited:`
The date at which the entry has been edited last. This is not updated automatically unless you use an editor or script that edits or adds the line automatically,
like sbwg-editentry. Any string is accepted, but only dates in formats that are recognised by your system's `date` programme will be used as publication dates in
feed (RSS, ATOM). Any numerical date format in descending order works for sorting of entries as long as every entry uses the same format. The value overwrites the
created date in sorting entries. It is recommended to use the ISO style date format YYYY-MM-DD for simplicity. If more than one edited tag is present, only the first
one will be used.
Example: `edited:2021-05-05`

`sort:`
A value that overwrites both the edited and the created date in sorting entries. The value is not displayed on the generated web site. Values from `edited:` and
`created:` will be ignored when a `sort:` tag is present. It is recommended to use the ISO style date format YYYY-MM-DD when the sort tag is used to place an entry
in between other entries that use the same format for created/edited dates. If your web site uses a different date format, that format is recommended for the sort
tag as well. The same restrictions on the date format apply as for the edited and created date. If numerical values are used for created and edited dates, then a
sort value that starts with a letter will sort an entry on top of the blog view. If the value of a `sort:` tag starts with "about" or "stick" then the entry's
title-wrapper is not included in the output file. This can be used to create stickied entries (paragraphs that are displayed above all entries on certain tagpages).
See the "Sorting" section below for more details. If more than one sort tag is present, only the first one will be used.
Example: `sort:stickied` will place the entry content (without meta information) above all other, non-stickied, content on the tagpages of every `cat:` tag that is
included in the header.

`cat:`
A category the entry will be filed under. An entry can have any number of category tags.
Multiple cat tags can be used in a single file
Example: `cat:Dogs` marks an entry that contains something relating to dogs. A tagpage that lists all entries with this tag will be generated.

`top:`
A topic that is addressed by this entry. An entry can have multiple topics and/or sub-topics. A sub-topic is assigned by adding another colon after a topic name, 
followed by the sub-topic name. Topic tagpages are indexes of entries with a specific topic tag or a sub-topic tag of that topic tag.
Multiple top tags can be used in a single file
Example: `top:Science:Mathematics` will include the entry's title in the topic tagpages/indexes "Science" and "Science:Mathematics".

`lang:`
The language the entry is written in. Any string is accepted. You can use `lang:en` or `lang:English` or `lang:ENG` or whatever you like, as long as entries of the
same language use the same tag. Only one language tag per entry is allowed.
Multiple lang tags can be used in a single file
Example: `lang:gr` tags an entry as being written in Greek.

`author:`
The name of the author of the entry. If only one person is adding entries to the web site then it is best to ignore this tag type and not include it in any entry
header. Every author name that is used in at least one entry will be listed in the navigation bar to offer to display only entries written by this author.
Multiple author tags can be used in a single file
Example: `author:Nickname7000`

`re:`
The name of an entry this entry is connected to. Includes a note at the top of the entry, linking to the entry named in the re: tag.
If more than one re tag is present, only the first one will be used.
Example: `re:some entry` links the entry that has this tag to the entry with the filename "some_entry".

`ref:`
The name of an entry this entry is referring to. Includes a note at the top of the entry, linking to the entry named in the ref: tag.
If more than one ref tag is present, only the first one will be used.
Example: `ref:entry0815` links the entry that has this tag to the entry with the filename "entry0815".

`reply:`
The name of an entry this entry is a reply to. Includes a note at the top of the entry, linking to the entry named in the reply: tag.
If more than one reply tag is present, only the first one will be used.
Example: `reply:Some Questions` links the entry that has this tag to the entry with the filename "Some Questions".

`redirect:`
The name of an entry this entry will redirect to. The content below the entry header will not be displayed on the web site (but will still be included in the RSS
feed). Visiting this entry's page will redirect the browser to the entry with the file name in the redirect: tag. On tagpages the entry will be substituted with the
entry it is redirecting to. This can for example be used to link multiple galleries to the same entry by creating dummy entries with the names of the galleries.
If more than one redirect tag is present, only the first one will be used.
Example: `redirect:some entry`

`updateof:`
The name of an entry of which the entry to which the tag was assigned is an update of. This cross-links those two entries.
Example: `updateof:some entry`
If this line is added to the tags of the entry 'newer entry', a note with a link to 'some entry' gets included above the content of 'newer entry' and a note with a
link to the entry 'newer entry' gets included above the entry content of 'some entry'.

`flags:`
A string of flags or a single flag to influence how this entry is displayed or treated when generating tagpages. See the `Flags` section below for more information.


### Redirections

The `redirect:` tag can be used to tell SBWG to substitute the content of an entry with the content of another entry. For entry pages, this creates a link to the
target entry on the filesystem layer if possible, or an HTML file that redirects to the target otherwise.

On tagpages, entries that have this tag set to an existing entry are excluded by default because the target entry already is present on the relevant tagpage(s). If
option `>` is enabled though, entries with a redirect tag will be included on tagpages according to their tags, not the tags of their target. That way, a duplicate
of an entry can be placed in other spots of other tagpages as the original.

Example: Option `>` is enabled. Entry1 has the tags `title:Entry 1` and `cat:Dogs`. It will therefore appear as "Entry 1" on the "Category: Dogs" tagpage, of course.
Entry2 has the tags `title:Entry2`, `cat:Fish` and `redirect:Entry1`. Because of the redirect, it will appear as "Entry 1" with the tags and content of Entry1 on the
tagpage "Category: Fish". This can also be used to make an entry appear more than once on the same tagpage, sorted into different places, by giving the redirecting
and the target entry the same category tag but different created, edited or sort tags.

The content portion of the redirect entry is never used in the previous example with or without option `>`. If option `<` is enabled, redirect tags are ignored when
generating tagpages. That way the content and tags of entries that have a redirect tag are used just as normal, just as if there would be no redirect tag. Therefore
it is recommended to include a comment in the content body of redirecting entries in case their site is ever generated with the `<` option enabled.

A redirection on a tagpage …
… displays: The title of the target, the tags of the target, the notes of the target, the attachments of the target, its own gallery's thumbnails and
… uses: The link to the target entry page, its own tags for placement, its own tags for sorting, the tags of the target as CSS classes, the link to its own gallery

The options `>` and `<` don't have a correlating command line option. They can be enabled in the settings file like any option though, e.g. in the hook `hook_start`:

    hook_start() { set_option '>'; }	# Enable inclusion of redirects on tagpages.



### Flags

Flags can be optionally set in entries to influence how individual entries are displayed or treated during tagpage and entry page generation. For example, a flag
can be set in an entry's tag header that makes SBWG generate this entry without the title wrapper on tagpages, meaning the entry's title and other meta information
will not be included in the generated HTML of tagpages.

To set a flag, include a `flags:` tag in the tag header of an entry. Only one flags tag may be present per entry tag header. Multiple flags can be set with a single
flags tag by stringing them together. If multiple flags are set in a single flags tag, they may be separated by any character or string of characters, including
none.

Examples:
* `flags:nocomment`
* `flags:noheader:nocomment`
* `flags:noheader, nocomment`
* `flags:nocomment - noheader`
* `flags:nocommentnoheader`
    - The first example sets the 'nocomment' flag. No other flags are set, no additional flags tags may be included in the tag header.
    - The other four examples are identical to each other. Either variant or any other separators may be used.

The following flags are available:

* `nocomment`
    - Will exclude the comment/email link from the entry regardless of whether an email address is set for the author of the entry.

* `hideatts`
    - Do not include links or embeddings of file attachments below entry content. The files will still be copied/created but not included in the generated HTML. This
      can be used e.g. to embed thumbnails of attached images at arbitrary places inside the entry content or to link to attached files inline and not have the
      attached file(s) listed again at the end of the entry's content.

* `hideimageatts`
    - Like `hideatts` but only affecting files of the mime type image. Hides all image file attachments of the entry. The image files are still copies over and
      their small versions are created. So the images can still be embedded or linked to inline in the content of the entry.

* `hideaudioatts`
    - Like `hideatts` but only affecting files of the mime type audio. Hides all audio file attachments of the entry. Please note that old OGG/Vorbis files may be
      identified as 'application' instead of 'audio'.

* `hidevideoatts`
    - Like `hideatts` but only affecting files of the mime type video. Hides all video file attachments of the entry. Please note that old OGG/Vorbis files may be
      identified as 'application' instead of 'video'.

* `hideotheratts`
    - Like `hideatts` but only affecting files that are not of the mime types image, audio, video or text. Please note that text files are not supported as files
      attachments in the first place. Therefore this flag hides only file attachments of the type application and files of rare/custom mime types.

* Custom flags:
    - Additionally, any other string of characters may be included in the flags string without having an effect on the entry of its own. Custom flags can be
      processed in hooks, though. Adding a flag that is not listed above does not make the flags sting invalid. The custom flag will simply be ignored but may be
      tested for and potentially acted upon in custom code added to the settings file of a web site.

The following flags are not available, yet, but planned for future versions:

* `noheader`
    - Will exclude the header/title wrapper (the title and other tag information) of the entry when it is generated into tagpages.

* `noshow`
    - Will exclude the entire entry when tagpages are generated. Its entry page will still be generated, just not linked to from tagpages.

* `nouse`
    - Will ignore the entry entirely, as if the file wasn't there.

* `sticky`
    - Will sort the entry at the beginning of tagpages regardless of any 'created', 'edited' or 'sort' tags.

#### Example for a custom flag

Tag line for the custom flag: `flags: incomplete`
That flag ('incomplete') is not known by SBWG. Therefor it is ignored by default.

Goal: If the part after `flags:` contains `incomplete`, the entry should be marked as work in progress on the web site. Specifically, the entry should appear in
fainted colors and a note should be placed above the entry content.

The fainted colors can be achieved with CSS:

    div.entry-wrapper[class*="incomplete"], div.entry-wrapper[class*="incomplete"] a {
        filter: grayscale(0.5) contrast(0.90) brightness(1.2);
        color: #555;
    }

The note can be added in a hook in the settings file (see section 'Hooks' above):

    hook_above_entry_content_before() {
        has_flag incomplete && c printf '<p><span class="note">This entry is work in progress, incomplete, not done and totally unfinished.</span><p>'
    }


## Tagpages

A tagpage is an HTML page generated by SBWG that lists all entries that contain a certain tag. Tagpages are created for every `cat:`, `top:`, `lang:` and `author:`
tag that occurres in at least one entry. If there is at least one entry that contains an author tag then combined tagpages for author+category are created, too.
Combined tagpages list all entries that contain two specific tags. For example the tagpage for `author:foobär+cat:wildlife` lists all entries authored by foobär that
are also tagged with cat:wildlife. If there are more entries with a certain tag than what is set for the `perpage` value in the settigns file then the generated HTML is split into multiple files and a pager is placed at the bottom of the list. A link for every generated tagpage is placed in the Topic list in the
navigation bar.

Tagpages for `cat:`, `top:` and `lang:` tags include the whole entries including its meta information above the content. The entries' `created:`, `edited:` and
`sort:` tags determine how the entries are sorted on the tagpage. Newer entries are places higher than entries with an older created or edited date. A `sort:`
tag can overwrite those values. (See the "Tag Types" section above and the "Sorting" section below.)

Tagpages for `top:` tags don't include
the content of the entries. They only list their titles and dates, serving as an automatically generated index for the topic. Topic tagpages include entries that
are tagged with that topic tag and entries that are tagged with sub-topic tags to the topic tag. For example the tagpage for `top:Projects` will list all entries
that are tagged with `top:Projects`, `top:Projects:Electronics`, `top:Projects:Art`, `top:Projects:DIY`, `top:Projects:Art:Wood Sculptures`,
`top:Projects:Art:Wood Sculptures:Wood Sculptures of Tony`, and so on, sorted alphabetically by sub-topic and title.


## RSS Feed

The only feed that is available for subscribing to blog entries is `all.rss`, a very simple RSS feed that contains all entries of the blog at once (except for
stickied entries). The feed is updated with option `-r`/`--rss` (only the feed), `-b`/`--blog` (together with the rest of the blog) or `-c`/`--complete` (with a
complete site generation). Please be aware that this is a very basic feed with a fixed language (en-uk), no rotation/paging and at least sub-par validity. (It will
only validate if all entries have an author tag that contains an e-mail address. Additionally, the complete content of entries is used unparsed and unfiltered as
the description of feed items.

Only slight improvements on the RSS feed are planned. Future versions if SBWG will probably generate better Atom feeds for individual authors, categories and topics.
But right now `all.rss` is the only option.


### Sorting

Entries are sorted differently on the two different kinds of tagpages (Topic tagpages being one, all other tagpages the other kind). Since topic tagpages are meant
to represent an index of the entries on a given topic, entries are sorted by topic and sub-topic first, then alphabetically. Entries with the same
sub-(sub-...-)topic are listed together alphabetically.

All other tagpages (category, language, author and combined tagpages) are sorted by created date. If an entry does not have a `created:` tag, it is sorted at the
bottom of a list, at the end of a tag page (or at the end of the last page of a paged tagpage). If an entry has an `edited:` tag, this edited date overwrites the
created date, meaning entries that have been edited will be placed higher than they would be otherwise. The `edited:` tag has to be placed in the header of an entry
source file manually when it is edited. This means for example that typos can simply be corrected in an old entry without affecting where the entry is placed on
tagpages. But if substantial changes are made or a paragraph with an update is added to an entry, you have the choice of adding an edited tag with the current date
to bump the entry to the top of tagpages without faking its creation date.

A third tag that influences how entries are sorted is the `sort:` tag. It is meant for special cases where you would like created and/or edited dates present and
displayed but the entry sorted to a different place independently of those two tags. The `sort:` tag overwrites both the `created:` and `edited:` tags when it
comes to sorting on tagpages. This can be used to place an entry between others by using a fake date for the `sort:` tag or at the end of tagpages by setting `sort:`
to 0, all independently from what created or edited date is displayed for the entry. `sort:` can also be used to place an entry at the top of tagpages, making it
"stickied" so to speak.

The value of the `sort:` tag is treated the same as the values for `edited:` and `created:`. It's just a way to overwrite both for a single entry. There are two
special values though that influence how an entry is displayed: Every value for the `sort:` tag that starts with either `stick` or `about` will remove the
title-wrapper of the entry on tagpages. You may, for example, want something to appear above all entries on a specific tagpage, say the tagpage for the category
"Miscellaneous" to explain what type of content you put in this category. In that case you can create an entry that has the tags `cat:Miscellaneous` and
`sort:stickied` (or `sort:about`) and the explanation below. This will make the explanation appear on the top of the cat:Miscellaneous tagpage without a title,
link or other meta information.

Only one occurrence of each of the three tag types that influence sorting is expected per entry. If more than one of the same tag are present, all but the first
occurrence is ignored.

Sort criteria summary:

* Sort order for each of the tags is ABCDEFGHIJKLMNOPQRSTUVWXYZ9876543210

* `sort:stick…` or `sort:about…` transform the entry into a stickied entry and place the entry at the top of tagpages (except "all.html")
    regardless of other entries' `sort:` values.

* `sort:` overwrites `edited:` and `created:`, is not displayed on the web site.

* `edited:` overwrites `created:`, is displayed in parentheses, if it is defined, after the created value.

* `created:` is used if no `edited:` or `sort:` tags are present.


## Tagicons

By default In this directory you can place icons that should be displayed in place of tags in entries' headers. The file name has to be `tagtype:tagname.png`.

Examples:

If you place a file called `lang:en.png` in this directory, the image is inserted in the header of every entry that's tagged with `lang:en`. The text `lang:en` will
not be displayed in the header, only the image.

If you place a file called `author:foobär.png` in this directory, the author foobär has an avatar that will be displayed instead of their name in the header of
posts tagged with `author:foobär`.

Make sure to resize all images placed in this folder to be of small, sensible dimensions. The image size is only restricted by CSS which means the original image
file is loaded regardless of its dimensions and size.

If you would like to add icons in addition to the tag name in text, it is suggested to use CSS. Every tag displayed in entry headers has its name as a class
selector.


# Attachments

Files that are not SBWG source files can be attached to an entry. This will include a (download) link below the entry content to which the file is attached without
the need to create the necessary HTML manually. A file is used as an attachment if it is not an entry file, it is in the `entries/` directory and named after an
existing entry. Attachment filenames can be either the name of the entry followed by a '.' (dot) followed by at least one character or the name of the entry followed
by a '-' (dash) followed by at least one character.

Examples:
An entry with the name `foo` will get the following attachments if those files exist somewhere in the `entries/` directory and are not entry files: `foo.mp3`,
`foo-1.jpeg`, `foo-2.jpeg`, `foo-archive`. The file `borbi-shlumb-grarg.pdf` will be used as an attachment to both the entries `borbi` and `borbi-shlumb` if those
entries exist or to just one if just one of them exists.

Files that are not entry files but don't belong to any entry according to their filename are ignored. Attachment files do not have to be in the same directory as
the entry source file they belong to. They can be at any depth in the `entries/` directory, just as entries themselves. This means you can have a `downloads/`
subdirectory in which your attachment files are kept separately from the entry source files, or you could have a directory in which you store both the entry source
file(s) and attachment(s) belonging to these entries. The directory structure is not copied to the output directory/the generated web site.

Attachments that are identified as audio files will be displayed in the form of an audio player instead of a download link, if the browser supports this. Image
file will be resized to pre-defined dimensions (determined by the $smallsize variable that can be set in the settings file) and embedded below the entry's content
as well as linked to the original image file. If a text file's name would make it an attachment to an existing entry, the first three lines of the text file are
checked to determine whether the file is an entry itself or not. If it looks like it's a SBWG source file/entry file, it is not included as an attachment.

If an attached file has the XMP tag 'SBWG_Description' then this string is displayed as a file description and in the case of image attachments also as their alt
attribute.

Single attachments are also included in the RSS feed. If an entry has more than one file attached, only the first one (depending on the filename) may be displayed
in feed readers depending on whether the feed reader supports multiple enclosure tags for a single feed item.


# Galleries

Creating a gallery is very simple, but there also isn't much control over how a gallery looks. Galleries can not have any metadata or a description on their own.
But they can be linked to a corresponding entry that contains more information. If you are missing functionalities related to galleries, adding a hook may be a
solution. (See the "Hooks" section above.)

A gallery in SBWG simply consists of a directory that contains image files. The name of the directory is the name/title of the gallery. If an entry of the same name
exists on the same web site, a link to the entry will be placed on the gallery page and vice versa and thumbnails of the gallery's images will be included below the
entry. Currently only JPEG and PNG files are supported and the image file names need to have those extensions.

Upon generation of the web site, the images will be resized into three sizes:

The originals of the images will be copied to the output directory as well. The original image files will be linked to from their previews on the gallery page. This
way large original files are not loaded every time a gallery page is opened, but they are available to every visitor if they want to display or download it. If you
don't want to have the original images included on the published web site, you need to resize them manually beforehand or include a function that does this in the
settings file. `convert` or `mogrify` can be used for this.


# Generating A Web Site (Command Line Options)

The file name of the main script is `sbwg`. Calling it without any options will not do anything. When everything goes well (there are no errors) and you didn't set
a verbose mode, there is no output from the script.

There are options to tell the script what to do, how to do it and which website to do it to. There is a short and long version for most options. Short option letters
can be grouped together. The last option letter of a group can still take an argument, meaning that, for example, `sbwg -v -v -e foo -s` is the same as
`sbwg -vvse foo`. To have the script do anything, you need to add at least one option from the "actions" list below.


## Actions (Options For Generating (Parts Of) The Web Site)

The following options tell the script which parts of the web site should be generated/updated in this run.


`--page` or `-p` [PAGENAME]
Generates/updates all SBWG pages from the pages/ directory. If PAGE is specified: Generates/updates only that page.


`--pagefile` PAGEFILE or `-P` PAGEFILE
Path/filename to a page source file inside or outside of the web site's pages directory. The page will be generated as if PAGEFILE was located in the web site's
pages directory. If a page source file of the same name as the supplied PAGEFILE exists in the pages directory, the file under the path supplied to option
-P/--pagefile overwrites the file that exists in the input directory's pages directory.


`--entry` or `-e` [ENTRYNAME]
Generates/updates all entries from the entries/ directory but not the corresponding tagpages. If ENTRY is specified: Generates/updates only that entry.


`--entryfile` ENTRYFILE or `-E` ENTRYFILE
Path/filename to an entry source file inside or outside of the web site's entries directory. An entry page will be generated as if ENTRYFILE would be in the web
site's entries directory. Potential file attachments in the web site's entries directory will be attached. But the generated entry page will not be linked to from
the navbar automatically. Nor will it be included in tagpages. Only the entrypage itself is generated by this option. If an entry source with the same name as
ENTRYFILE exists in the entries directory or a subdirectory thereof, the entry supplied to option -E/--entryfile overwrites the one in the input directory's entries
directory. Note that any category, topic, language or author tags that are declared in the ENTRYFILE will be linked whether they would otherwise exists in the
web site or not.


`--tagpage` or `-t` [TAGNAME]
Generates/updates tagpages (topic, category, language and author tagpages as well as combined tagpages) for all entries, but not the entries themselves. If TAGNAME
is specified: Generates/updates only the tagpage for that tag.


`--blog` or `-b`
Alias for -e -t -r. Generates/Updates entries, tagpages and the RSS feed.


`--gallery` or `-g` [GALLERYNAME]
Generates/Updates the gallery pages. If GALLERYNAME is specified: Generates only that gallery.


`--gallerydir` or `-G` GALLERYPATH
Generates/Updates the external gallery that is located in GALLERYDIR. A gallery page will be generated as if it belonged to the web site. But the page will not be
linked to in the navbar/web site menu automatically. If a gallery of the same name already exists, it will be overwritten.


`--rss` or `-r`
Generates/Updates the RSS feed all.rss. Other feed formats might be added in future versions.


`--files` or `-f`
Copies the files from the files/directory to the root of the output directory.


`--style` or `-s` [STYLESETNAME]
Copy/update the CSS files for the style set specified in the settings file to the output directory. If STYLESETNAME is specified: Copy/update the files belonging to
that style set to the output directory and use that style in the header of HTML files if any HTML files are generated in this run of the script.


`--complete` or `-c`
Alias for -p -e -t -r -g -f -s. Generates/updates the entire site.


If none of the above options is specified, nothing is generated.


## Other Options

The following options mainly specify how and from/to where the web site should be generated.


`--input` or `-i` INPUTDIR
Specifies the input directory - the directory that contains the source file structure of the web site. INPUTDIR can be a relative or absolute path to the directory.
If the option is omitted, SBWG will attempt to generate a web site from the file structure in the current working directory.


`--output` or `-o` OUTPUTDIR
Specifies the output directory - the directory where the generated HTML site will be placed. OUTPUTDIR can be a relative or absolute path to the directory. If the
option is omitted, the output directory specified in the settings file will be used. If not output directory is specified there, either, `html/` relative to the
input directory will be used.


`--author` or `-a` AUTHORNAME
Specifies the name of an author who's entries should be generated exclusively. If this option is specified, all entries that do not have that author name specified
in their source file headers will be ignored. The web site will be generated as if it contained only the entries by that author (containing an 'author:AUTHORNAME'
tag in their header).


`--reduce-paths` or `-R` [NUM]
Turn on pathreducer mode. If this option is supplied, the names of files that are generated by the script and of directories the script writes to are constructed in
a way that minimises the risk that they will not meet the requirements of any target filesystem. They are converted to not contain any characters other than a-z,
0-9, underscore (_), dash (-) and a single dot (.) and are shortened if they would otherwise be longer than the specified maximum file name length. If NUM is given,
that value is used as the maximum file name length in bytes. If the option is given without an argument, the value assigned to the variable `$maxfnl` in the web
site's settings file will be used. If both aren't specified, the maximum file name length is set to 255 bytes. Files that are stored in the web site's `files/`
directory will currently be copied into the output directory without change of filenames. The minimum value for the maximum file name length is 6 bytes. If the
maximum filename length is specified as two numbers separated by a dot (.) (e.g. '8.3') the first number is used as the maximum basename length (maximum filename
length without filename extension) and maximum directory name length and the second number is used as the maximum suffix length (length of the filename extension
without the dot).
Note that the paths generated with this option may differ from those of a web site that was generated without this option. Therefore using this option on a web site
that previously was generated without this option, or changing the NUM value, may result in incompatible/dead links. Note also that this option slows down th
generation process significantly.


`--settings` or `-S` COMMANDS
Commands supplied as an argument to this option are sourced by the script after the settings file has been sourced. COMMANDS can be one or more Bash commands
(separated by semicolons but in a single word/string), e.g. variable assignments, declarations of functions/hooks and so on. These settings complement or overwrite
the settings contained in the settings file. This option can be used to temporarily add or change settings without editing the settings file, or to create different
variants of a web site (e.g. with aliases for different commands for different settings).

A simple example would be to change the number of entries included per page in the weblog:

    sbwg --input ~/my_website --output /var/www --settings 'perpage=5' --blog

Another example would be to add or overwrite a hook:

    sbwg --input ~/my_website --output /var/www --settings 'hook_head() { o printf "<style>p { color: #b05; }<style>"; }' --complete

An advanced example would be to generate different parts of the web site using different web site names:

    sbwg --input ~/my_website --output /var/www --settings 'sitename="My Homepage"' --pages
    sbwg --input ~/my_website --output /var/www --settings 'sitename="My Logbook"' --blog

More than one `-S` option can be used. They will be executed in order.

The `--settings` or `-S` option uses `eval` which can lead to problems with variable assignments in some rare cases. It is generally recommended to favour using the
settings file over using this option. But it is an option for a quick hack or non-persistant changes to the settigns. For permanent variations of a web site, using
separate input directories and softlinking the directories/files that are shared between the web sites is the better choice.


`--force` or `-F`
Forces SBWG to continue when an error occurs or a fault is suspected. This can be used to get around yet undiscovered bugs that prevent the script from generating a
web site or parts of a web site despite everything being okay. It is not advised to use this option unless you know specifically why you are using it and how it
might affect the web site generation is that case. If SBWG detects an error, aborts the generation process or omits source files, it is always a good idea to check
the related files first and correct any mistakes. If you think that SBWG should not have aborted when it did or should have used a file it cautiously omitted, feel
free to use force mode as much as you want, but please let me know so I can improve the script in future versions. (See 'Other Remarks' at the end of this file for
contact information.)


`--cachegroups` or `-C` [CACHEGROUP(S)]
This option enables permanent caching mode. That means that SBWG will generate cache files and store them in non-temporary directory (by default the `cache/`
directory inside the web site's source directory; see option `--cachedir`/`-D` below). Once this cache is generated, future generation processes can finish faster
if this option is used again. But they also won't update any parts of the web site for which a cache file exists. Cache files that have been generated with this
option will also only be used if this option is set. If a string is supplied for CACHEGROUPS, SBWG will only generate persistant cache files for the group(s)
included in the string. More than one cache group can be specified. (No separation is necessary, but separating them with a colon is preferred, for readability.)
If no string is supplied for the option, all available cache groups will be enabled. Those groups are currently: navbar, tags, content, entries, head
More than one `-C` option can be used. Their values will be concatenated. Passing a non-existing cache group as an argument does not produce an error. Thus a custom
cachegroup could be created using the settings file of a web site.

`--cache`  [CACHEGROUP(S)]
This option is depricated. It has the same usage and properties as `--cachegroups` has. But it may be removed or re-purposed in a future version of SBWG.


`--cachedir` or `-D` CACHEDIR
This option also enables permanent caching mode if it isn't already enabled (see option `--cachegroups`/`-C` above). CACHEDIR needs to be supplied and defines the
path (directory) where the permanent caches are/will be stored. The same rules as for option `--cachegroups`/`-C` apply. Caches are created in CACHEDIR (those that
don't already exist there) and will only be used in future generation processes if the same CACHEDIR is defined (and the cahce files are still there). If no
cachegroups are set, all available cachegroups are enabled.


`--update-only` or `--update` or `-U`
(Not implemented, yet)


`--parallel` or `-Q`
Enables parallelisation mode for processing multiple items in parallel. The types of items (entries, tagpages, ...) will still be processed linearly. But entries,
pages, galleries, RSS entries and tagpages will each be processed in parallel if this option is enabled. The variable `$maxprocs' may be set in a web site's
setting file to define the maximum number of processes that the script may produce at a time. If you include custom code in a web site's settings file that runs
background processes, these processes also count towards the maximum number of allowed processes. `$maxprocs` defaults to 50. A number higher than the number of
available CPU threads can result in a performance increase for certain tasks, like generating HTML files.


`--verbose` or `-v`
Adds one to the verbosity. If option `--verbose`/`-v` is supplied once, verbose mode is enabled. If it is supplied twice, very verbose mode is enabled. If it is
supplied more than once, very very verbose mode is enabled.
When verbose mode is enabled the script will report progress at certain stages during the generation. Higher verbosity means more detailed informational messages
on stdout. See also option `--debug`/`-d`


`--debug` or `-d`
Enables debug output mode. Debug mode includes messages that are meant to help with debugging the script itself. This is mainly used during development versions.
In released version the debug mode just adds some additional information in the output that will likely not be of any use to you. Debug mode includes very verbose
mode (see above). If this option is set more than once, the last few commands that were called in the script will be printed to stdout. The variable
$max_debug_commands decides how many commands will be remembered for this.


`--waiting-animation` or `-w`
If any verbosity is enabled (meaning messages that are neither warning nor error messages may appear on stdout), this option displays a waiting animation whenever
no new output is printed to stdout for several seconds. The following details about the animation can be modified via a web site's settings file: The animation
frames are stored as array elements in $waiting_ani_frames`. The speed in Hertz is stored in `$waiting_ani_speed`. The delay in seconds is stored in
`$waiting_ani_delay`. If you decide to create your own animation, note that no newline characters, ASCII control characters or cursor moving escape sequences
should be used in animation frames. Usage of these characters is not tested and would likely break the animation. See the example web site's settings file for
animation examples to copy and change.


`--log` or `-l` [LOGFILE]
Enables logging to a file with highest verbosity (debugging). If LOGFILE is not provided or the supplied path can't be used for any reason, 'SBWG.log' in the
current working directory is used. Existing files are overwritten without warning. Every log message generated by SBWG starts with a symbol correlating with the
type of message (informational, warning, error or debug message). After that symbol the message includes a timestamp, then the actual message string.
Option --log/-l may only be set once in a command line. If option --log/-l is not used, logging can still be enabled in a web site's settings file. If that is the
case, option --log/-l overwrites that setting. If a log file is set manually in a web site's settings file and it is not set at the highest level of its structure
(i.e. it is set in a hook) then the log will not include messages that occured before the log file was set.


`--help` or `-h` [HELPPAGE]
Without an argument, this option prints short usage instructions and exits the script, ignoring all other options. Help on specific topics is available by adding
the name of an existing help page after the option. A list of available topics is printed when no argument is provided. Those topics currently are: attachments,
blog, comments, entries, feeds, files, galleries, hooks, input, options, output, pages, pathreducer, settings, styles, tagpages, tagtypes


## Example Commands

`sbwg -c`
Generates/updates the complete web site from the sources in the current working directory into its default output directory.


`sbwg -b -o /srv/stage`
Updates the parts of the web site from the current working directory that make up the weblog of the web site into the directory `/srv/stage`


`sbwg -vv --input "/home/user/my web site" --pages`
Updates only the static pages from the web site who's sources can be found in the directory `/home/user/my web site/` while displaying the progress of the generation
process.


`sbwg -p index --output ~`
Generate only the index page from the web site who's source is residing in the current working directory, into the current working directory, resulting in the file
`~/index.html`.


## Caches / Persistant Caching

During the generation process, SBWG creates several files (by default in its temporary directory) of pieces of a web site that may be reused in multiple places in
the generated web site, such as the navbar that is placed on every generated HTML page, or the title-wrapper part of an entry (with its title, tags, etc.), that
occurs on the entry's own page but also on every tagpage on which the entry is on. By enabling permanent caching with option `--cachegroups`/`-C` or
`--cachedir`/`-D` those files are placed in a non-temorary directory and can be reused in futures runs of SBWG.

That way cached parts of the web site don't get generated again every time the web site is updated. That also means though that changed/edited/updated parts of the
web site will not get updated as long as the relevant cache files are there and used. Different kinds of cache files can be created and used independently in order
to create a default SBWG command that can be used to update a web site quickly without re-generating every single piece again every time.

Media files will not be cached in the caching directory. Various image sizes that are generated for thumbnails and previews are directly placed in the output
directory. Those files will not be re-generated if a file of the same name already exists and original image files will not be copies again if the target file
already exists in the output directory, meaning image files are cached indefinitely in the outoput directory. If the contents of an image file in the input directory
changes, all image sizes that have been generated in the output direcry have to be removed manually in order for the changes to take effekt the next time the web
site is generated.


### Cache Lifetime

Cache files, regardless of their location, expire after a certain amount of time. That time can be set in the settings file as `$cachelife` in seconds. If that
setting is not set, the default of 7776000 seconds (90 days) is used. If `$cachelife` is set to 0, cache lifetime is indefinite.

Cache lifetime takes effect the next time a cache file would be used by SBWG. When SBWG tries to use an existing cache file and discovers that it's expired, it
empties the file and re-creates its contents.

Examples:

* `cachelife=604800` - Cache lifetime is 7 days.

* `cachelife=0` - Cache files never expire.


### Caching Options and Settings

Persistant caching can be enabled by using either of the following options.

Option `--cachegroups`/`-C`: argument determines which cachegroups will be enabled, no argument means all cachegroups will be used

Option `--cachedir`/`-D`: argument determines the path of the directory that will be used as caching directory

The option `--cachegroups`/`-C` optionally takes one argument: a string containing the names of all cachegroups that should be enabled in this run of SBWG. The
names of those cachegroups (see chapter Cachegroups below for a list of available cachegroups) can be concatenated in any way. A separation by commas (',') is
suggested (see examples below). If more than one options `--cachegroups`/`-C` are supplied, their values will be combined, enabling all cachegroups specified in
either argument. If persistand caching is not enabled (neither of the two options is used), the cache files will be located in the temporary directory. If persistant
caching is enabled, cache files belongig to one of the enabled cachegroups will be placed in a non-temporary directory. By default this directory will be `cache/`
in the web site's input directory. Using option `-D`/`--cachedir` a different path can be specified. In future runs of the script on the same web site, the cache
files that have been placed in the non-temporary directory will be used only if persistant caching is again enabled. Only those previously generated persistant
caches are used that belong to one of the cachegroups that are enabled.

Examples:

* `./sbwg --input=/home/example/weblog --output=/var/www/html --complete --cachegroups=:default`

  Instead of `--cachegroups=default` either `--cachegroups` or `-C` can be used with the same effect. This command generates all components of the web site with the
  default (recommended) cachegroups enabled. Cache files located in `/home/example/weblog/cache/` will be used. Not already existing cache files will be generated
  into that directory. When SBWG is run with the same options and arguments the next time, the newly created cache files will be used.

* `./sbwg --input=/home/example/weblog --output=/var/www/html --complete --cachedir=/home/example/weblog_cache/`

  The same web site as in the sample above will be generated, but cache files will be placed in `/home/example/weblog_cache/`. SBWG will not be aware of any cache
  files that were previously placed in `/home/example/weblog/cache/` nor will anything be written to that directory. If `weblog_cache/` is empty or doesn't exist,
  this command will have the same result in the output directory as generating the web site with persistant caches disabled. But the cache files that are generated
  into `weblog_cache/` can be used the next time the web site is generated with the option --cachedir=/home/example/weblog_cache/`

* `./sbwg --input=/home/example/weblog --output=/var/www/html --entries --cachegroups=title,above,below`

  Generating the web site with these options will update only the entry pages (option `--entries`), meaning new entry pages will be generated and existing entry
  pages will be updated. The directory used for persistant caches is `/home/example/weblog/cache/`. Because the cachegroups `title`, `above` and `below` are
  enabled, the title-wrappers, notes above entries, file attachments and gallery thumbnails below entries will not be generated again if cache files exist for them
  already. Because the cachegroup `content` is not enabled, the actual content part of the entries will be taken from the entry files, ignoring any possibly
  existing cache files in the persistand caching directory and not writing generating those cache files into the persistant caching directory.

* `./sbwg --input=/home/example/weblog --output=/var/www/html --complete --cachegroups=:all --cachegroups=footertables`

  These options will lead to the following cachegroups to be enabled: head, navbar, tags, title, above, content, below, galleries, entrylist, tagslist, entrylists,
  gallerylist, updateslists and footertables. So all cachegroups that exist in SBWG out of the box and the custom cacehgroup 'footertables'. Enabling the latter
  does not actually do anything on its one. A cachegroup of that name is not known by SBWG. But if there are cache files generated in the web site's settings file
  that use this cachegroup, then enabling it will cause those cache files to be generated into the persistant caching directory. Note that using 'all' is not
  recommended because is keeps entrylist, tagslists, etc. persistantly cached.


### Cachegroups

When persistant caches are enabled, it can be enabled only for certain cachegroups. If no cachegroups are specified, the ':default' set of cachegroups is enabled.
Whenever a cache file is created or being looked for, a path either in the temporary directory or in the cachedir is used, depending on whether the cachegroup to
which the cache file belongs is enabled or not.

The following groups of cachefiles exist out of the box:

* tags - Directory that contains one file per entry and page in subdirectories according to their respective paths, containing lists of tags of that entry/page.

* title - Directory that contains one file per entry and page in subdirectories according to their respective paths, containing HTML of their title wrapper.

* above - Directory that contains one file per entry and page in subdirectories according to their respective paths, containing HTML of their notes.

* content - above - Directory that contains one file per entry and page in subdirectories according to their respective paths, containing HTML of their content.

* below - Directory that contains one file per entry and page in subdirectories according to their respective paths, containing HTML of their attachments.

* navbar - File in the directory 'misc', containing the HTML of the navbar.

* head - File in the directory 'misc', containing the HTML head section.

The following groups are planned for futures versions of SBWG:

* galleries - Directory that contains one file per gallery, containing the gallery's HTML chunk (<img> tags of thumbails and previews).

* entrylist - File in the directory 'lists', containing a list of all entries of the web site.

* tagslist - File in the directory 'lists', containing a list of all tags found in the web site.

* entrylists - Sub-directory in the directory 'lists', containing a file for each tag, containing lists of all entries that carry that tag.

* gallerylist - File in the directory 'lists', containing a list of all galleries on the web site.

* updateslists - Sub-directory in the directory 'lists', containing a file for each entry for which a newer version exists in the website, containing the names of
                 those newer versions.

If one of the following cachegroup aliases is used, it is replaced by a set of cachegroups it stand for.

* :default - head,navbar,tags,title,above,content,below,galleries
  The default set of cachegroups. Recommended for the most usual use cases. This set of cachegroups will also be used if the argument to the option
  `--cachegroups`/`-C` is empty or there is no argument.

* :all - head,navbar,tags,title,above,content,below,galleries,entrylist,tagslist,entrylists,gallerylist,updateslists
  Specifying ':all' as an argument to the option `--cachegroups`/`-C` will enable all cachegroups that are known by SBWG out of the box. This is not recommended for
  most use cases because not much is actually generated with all cachegroups enabled.

Custom cachegroups can be defined in a web site's settings file when using the function set_cachefile() for custom code. Those cachegroups will have to be enabled
manually e.g. by adding their name to the argument of `--cachegroups`/`-C`.

Enabling persistant caching for any of the lists (entrylist, tagslist, entrylists, gallerylist, updateslists) is not recommended for most use cases. Those lists
are meant to be generated anew each time the web site is generated. Enabling them may speed up the process, but can lead to problems and even new content to be
omitted.


### Practical Examples For Using Persistant Caches

There are simple example command lines above that show how the options are used. What followes are practical examples of how to use persistant caching to speed up
the web site generation process without getting in the way of keeping a web site automatically reasonably up-to-date. All following examples assume that the web
site is generated automatically, e.g. by a daily cron job.

A simple way to use caching would be for example to always generate a web site with option `--cachegroups=:default`/`-C` and a cache lifetime of at least a few days
(depending on how frequently the web site is usually updated and how important it is to timely reflect all changes on the generated HTML). That way, new blog entries
will be generated immedietely and existing pages/entries will be updated after the cache lifetime. Only every other day (depending on the cache lifetime) the
re-generation process takes longer after cache files have expired.

Another example of using the caching option is to always generate a web site with the option `--cachegroups=:head,tags,title,above,content,below,lists,galleries`.
That way all parts of the website except the navbar will be cached. The menu/navbar, tagpages and new entries will be generated when running SBWG with this option
every time (e.g. using an alias) but if existing content changes, it will not be updated unless the respective cache files are deleted or expired.

One way that requires more manual action whenever any changes are made to any part of the web site but also brings the fastest generation times pissible, is to
always generate the web site with the option `--cachegroups=:all`/`-C :all`. All cachegroups are enabled. Every possible cache file is generated/used. Every time
anything should actually get updated, the cache files that belong to those parts have to be removed beforehand. Otherwise the parts will only update once the
relevant cache files are dismissed for having expired.

The last approach of course can be adapted in a less radical form by using a custom set of cachegroups instead of the alias `:all`. If persistant caches should be
used for a web site, it makes sense to think about how frequently it will be updated and what sort of changes are expected when it is updated. Each web site can
benefit from its individual cache settings, depending also on the users preferences. Not to use persistant caches at all can also be a good option. There are other
ways to prevent the entire site from having to be re-generated every time something is changed in its source files. (See the Actions heading above and the option
`--update-only`/`-U` for examples.)


## Message Types

### Error Messages

Error messages are produced when there is output to stderr from a sub-process of the script and when the script ends unexpectedly because an error is detected. In
both cases an error message gets printed to stderr. If option `--force` (`-F`) is enabled there can be more than one error messages from errors that would have
otherwise ended the script. Error messages from subprocesses are printed again when the script ends.


### Warning messages

Warning messages are printed (to stdout by default) when a problem is detected or suspected that may cause the generated web site to differ from what was
expected/intended by the user. These messages are printed to stdout by default but can be redirected independently of the rest of stdout by redirecting file
descriptor 6.


### Informational messages

Informtional messages report progress and the names of the components the script is currently working on. These messages are printed to stdout by default but can
be redirected intependently of the rest of stdout by redirecting file descriptor 6.

With only one `--verbose`/`-v` option (verbose mode) only few informational messages get printed to inform about the general progress of the script (which parts of
the web site generation are finished).

With two `--verbose`/`-v` or one `--very-verbose` option, messages about which individual item (entry/page/gallery/tagpage) is currently being generated are printed.

With three or more `--verbose`/`-v` options or one `--very-very-verbose` option, messages about parts of generated items, like file attachments to entries or
individual images in image galleries are printed additionally.


### Debug messages

Debug messages are not intended for the user nor do they contain any useful information for regular use of the script. You can just ignore the option that enables
those messages. These messages are printed to stdout by default but can be redirected independently of the rest of stdout by redirecting file descriptor 8.

Debig messages may contain additional information about the configuratin of the generated web site as well as confusing output containing any amount of internal
data in any or no format. In versions of SBWG that end in "-wip" it is not recommended to enable the debug option because informational messages may be drowned in
debug output.


### Verbosity Level

The verbosity level defines which types of messages are printed and thus determines in how much detail progress and events are reported to the user.

The existing verbosity levels are:

* no verbosity: Only error messages and warning messages are printed. No informational messages or progress messages are printed. No output if everything goes fine.

* verbose: A few messages on the general progress are printed when major parts of the generation are finished.

* very verbose: Progress is reported in much more details, including which items the script is currently working on.

* very very verbose: The script prints messages for almost every step it takes, including e.g. individual file attachments.

* debug: Additional messaged are printed for the purpose of debugging work-in-progress versions. Not much debug messages are included in released version of SBWG.

* double debug: Additional debug output is generated, e.g. the call stack when the script ends.

Log files that are created by using the `--log` (`-l`) option contain all message types, including error and warning messages as well as informational messages up
to verbosity level "debug".


### Redirecting Output

By default error messages are printed to stderr and all other message types to stdout. Those can be redirected as usual by redirecting file descriptors 2 resp. 1.

Example: `sbwg -v 2>ERR 1>STD` (Error messages are redirected to the file ERR, standard output to the file STD)

If file descriptor 5 (informational messages), file descriptor 6 (warning messages) or file descriptor 8 (debug messages) are redirected, those messages are dverted
from stdout. The redirection of FD 5, 6 or 8 can be before or after the redirection of FD 1.

Example: `sbwg -v 1>STD 6>WARN` (Warning messages are redirected to the file WARN, info and debug messages remain in stdout, which is redirected to the file STD.)

Of course parts of stdout can be redirected without redirecting the remaining messages types of stdout.

Example: `sbwg -d 8>DEBUG` (Debug messages get redirected to the file DEBUG. All other messages stay untouched.)

To recreate the behaviour of SBWG version 0.10.12 and older (wqarning messages on stderr), you can just duplucate file descriptor 6 to file descriptor 2 uing
`6>&2`. If error messages including warning messages should be redirected further, that rediretion has to be placed before the duplication in the command line.


## Directory Locks

During the Generation of a web site, both the input directory (the web site's source directory) and the output directory (the directory in which the generated HTML
is generated into) are locked. The lock consists of a file named `lock` in each of the two directories. The file gets removed when the script ends its doings,
whether it finished without an error or it was interrupted by a fatal error. They are not removed if SBWG is killed. But as long as the file(s) exist, SBWG will
refuse to generate the locked web site into any directory or any web site into the locked output directory. Option `--force` (`-F`) overrides the caution. This is
a simple measure that can protect against accidental web site generations interfering with each other, e.g. when a cron job is executed while another instance of
the web site generation is still running. Both false positive and false negative results of the lock file checks can occur in various special cases. With nothing
but (a) working SBWG command(s) in the crontab and occasionally executing SBWG manually it works reliably.


## File Permissions

Files that are newly created by SBWG (HTML files, image thumbnails, anything) derive their permission as usual from the mode mask (as set by umask). The same is
true though for files that are copied without changing their content. That means that the file permissions of gallery images, entry attachments, tagicons, files
belonging to a style set and the files in a web site's files directory are not preserved. The owner of all files in web site's output directories is the user that
executed SBWG and their permissions are set according to umask.


# File Descriptors

Some of the single-digit file descriptors are used internally for reading lists as loop input or other operations. Those file descriptors should not be used in
custom code without checking for the possibility of conflicts first. Other file descriptors are used for different kinds of message output (see chaptor Message
Types). Those file descriptors can be redirected when calling the script (like stdout/FD1 and stderr/FD2, see chapter Redirecting Output under Message Types).

0 (stdin): Ignored.

1 (stdout): Output meant for the terminal. Verbosity depending on options. Includes output to file descriptors 5, 6 and 8 by default.

2 (stderr): Error output from external processes/sub-processes and from fatal error messages from the script itself.

3 (perl): Used by filter_tag() to read in the perl script.

4: Unused.

5 (info): Used for informational messages (v, vv and vvv). Can be redirected externally when calling the script.

6 (warn): Used for warning messages.  Can be redirected externally when calling the script.

7: Unused.

8 (debug): Used for debug messages. Can be redirected externally when calling the script.

9 (loops): Is used for processing loops here and there (to avoid using stdin which could come into conflict with another 'read' from stdin).


# Exit Status

Warnings that are generated during the script run do not influence the exit status of the script. Neither does output to stderr if it is not from an error that
the script determined to be fatal. The script returns 0 if no fatal error was encountered. 2 is returned if the script encountered at least one error in force
mode (option `-F`/`--force` enabled). An exit status of 5 means that a fatal error occured before the script started to write anything to the output directory.
That means that a failed run of SBWG that returned 5 can not have resultet in a corrupted or incomplete output directory/web site. Error 7 means that either the
input directory or the output directory are locked (the lock file was found in at least one of them). All other fatal errors cause an exit status of 1. More error
codes/exit statuses might be introduced in future versions, meaning an error that in this version produces an exit status of 1 might in a future version of SBWG
produce an exit status that is not yet determined.


# Other Remarks

SBWG is work in progress and I don't always publish new versions immediately. I may also not test old features or combination of features in new versions unless I
use them myself on some web site or suspect a reason to test them again thorowly. Or I may not notice that I broke something until after I published a new version
and then not bother to publish the fix right away. Feel free to contact me via e-mail at a-sbwg@steeph.de for any requests, bug reports, criticism, suggestions,
wishes, complaints or declarations of love.

There is a HOWTO file included in this package where you can read more about how you can use SBWG and how you can accomplish specific things that have not been
mentioned in this README file. The HOWTO file didn't receive as much attention from me as this README file has. But it's there and will probably grow a lot in
future versions.

There is no version control in use for SBWG. Feel free to create a Git repositpry or whatever. Maybe I'll start to use it, too, some day.

On security: Please keep in mind that all input from the command line, from a web site's source directory including its settings file and from the temporary
directory is expected to be trustworthy. There are almost no measures in place that try to prevent exploitation of unintended possibilities deriving from the open
design of this script. Tag values do get filtered to prevent them from breaking the generated HTML code. But even this can be circumvented by manipulating the cache
files during the generation process. Code injection through the settings file is literally an intended feature and part of the concept that makes this script
flexible, extendable and customisable for individual web sites.

SBWG is free. You can redistribute it and/or modify it under the terms of the Do What The Fuck You Want To Public License, Version 2, as published by Sam Hocevar.
See http://www.wtfpl.net/txt/copying/ for more details.
