bUwUma is a build system that uses GNU make and a preprocessor written in python to build static, multilingual websites. https:/quintern.xyz/en/software/buwuma.html
Go to file
2024-11-24 22:55:15 +01:00
example add optimized image support 2023-11-28 00:37:38 +01:00
html-preprocessor use mdtex2html for md conversion 2024-10-26 01:49:24 +02:00
LICENSE added license 2022-12-16 05:25:18 +01:00
Makefile convert -> magick 2024-11-24 22:55:15 +01:00
nginx.conf cleanup 2023-11-27 11:48:50 +01:00
README.md use mdtex2html for md conversion 2024-10-26 01:55:39 +02:00

bUwUma

Build Websites Using Make

Overview

bUwUma is a build system that uses GNU make and a preprocessor written in python to build static, multilingual websites.

This readme only documents the preprocessor. For more information and a quickstart guide on how to use bUwUma, please refer to the article on my website.

HTML Preprocessor Documentation

Markdown support

Using the #include command (see below) you can include markdown files, which will be automatically converted to html using mdtex2html, which also supports converting LaTeX to MathML. If mdtex2html is not installed python-markdown will be used instead. Preprocessor commands in included markdown files will be handled as well.

Syntax

Commands

  • All commands must be located within a html comment that starts with <!-- and ends with -->.
  • Commands start with a # character, the command must follow the # immediately.
  • Everything after the command until the end of the comment or a newline character are considered the argument of the command.
<!-- #command everything here is an argument -->
<!--
    #command everything here is an argument
    #anothercommand more arguments
    #comment This will be a single line html comment after the preprocessor finishes.
-->
  • All commands return a string, which can be empty.
  • If a comment contains a command, the entire comment will replaced with the return value of the command.
  • If there are multiple commands in a comment, it will be replaced by all the return values added together.

Variables

  • Variable names must only consist of these characters: a-zA-Z0-9_
  • A variable with name varname can be used like this: #$(varname)
  • A variable usage will be replaced by the value of the variable
  • Any variable that has is not defined has empty string as value

General

  • Whitespaces around a token are ignored, so <!--#include dir/file--> is the same as <!-- #include dir/file -->
  • If a command-comment takes up a whole line, the whole line including the newline character is replaced.

Commands

include

Include the content of a file (or only a specific section in that file) at the position of the command.

Synopsis: <!-- #include path/to-a-text-file.html --> <!-- #include path/to-a-text-file.html section_name -->

Argument: A absolute or relative path to a text file [ + section name ]

Return Value: The content of the file or <!-- Could not include '{args}' --> empty string if the file can not be opened.


section

Start a section in a file. The section is only used by the include command to determine the start and end of a section

Synopsis: <!-- #section section_name -->

Argument: Name of the section

Return Value: Empty String


set

Set the value of a variable

Synopsis: Set the value of varname to this is the value: <!-- #set varname this is the value -->

Set the value of varname depending on the value of othervar: <!-- #set varname othervar?{*:fallback,key1:val1,key2:val2...}>

Argument: The first word is the name of the variable, the rest is the value or a dictionary.

Return Value: Empty string

You can make the value of varname dependant on the value of another variable othervar by using a dictionary-like syntax described above. In this case, varname will take the first value from the dictionary that matches tha value of othervar. * always everything and can be used as fallback. General wildcards like a* to match everything that starts with a are not supported. Instead of commas , you can also use semicolons ; as separators, but this must be consistend within the map.

return

Same as set, but it returns the value of the variable that is being set. This is meant to use with maps, when you need a variable from a map you can 'inline' it with return

default

Same as set, but it sets the variable's value only if it has no value yet.

unset

Unset a variable

Synopsis: Unset varname, it will no longer be defined and can therefor be set with default again. <!-- #unset varname -->

Argument: Name of the variable

Return Value: Empty string


comment

Comment the arguemnts.

Synopsis: <!-- #comment This will stay as comment in the html -->

Argument: Any string

Return Value: The argument in comment tags

uncomment

Uncomment the comment.

Synopsis: <!-- #uncomment This will not be commented -->

Argument: Any string

Return Value: The argument

This can be useful when you want to look at the unprocessed html without variables or when your syntax highlighting gets confused by a variable.


conditionals

To turn on or off entire blocks, if, elif can else be used. These commands can not be nested. Logical and && and logical or || can be used to chain conditions. If a condition is true, the corresponding block is included while all other blocks are deleted.

Synopsis

<!-- #if #$(var) == value && #$(other_var) == other_value -->
...
<!-- #elif #$(var) == value || #$(other_var) != other_value -->
...
<!-- #else -->
...
<!-- #endif -->

Argument Condition for if and elif, ignored for else and endif

Return Value Empty String


sidenav

Manage the generation of a content menu which contains links to all headings in your html that have an id. The menu is called sidenav here. An entry is a html heading with a id: <h1 id=myheading>This heading will be linked in the sidenav</h1>

Synopsis: <!-- #sidenav sidenav-command arguments --> sidenav-command must be one of the following:

include

Include the generated sidenav at this position. This command will always be executed last, after the whole file has been parsed.

Argument: Ignored

Return Value: The generated sidenav

section

Group all following entries in named section. section may not appear in conditional blocks.

Argument: The name of the section

Return Value Empty string

name

Use a custom name instead of the heading itself for the link to the next heading.

Argument: The link-name of the next heading

Return Value: Empty string

custom

Include a custom link in the sidenav.

Synopsis: <!-- #sidenav custom href="my-link" name="Go to my link!" -->

Argument: Must be href="..." name="...". Either single ' or double " quotes are required.

Return Value: Empty string


sitemap

Used for automatically generating a sitemap.xml for the website.

include

Include the current page in the sitemap

Synopsis: <!-- #sitemap include --> <!-- #sitemap include https://use.custom.link/for-this/site -->

Argument: Optional: Use a different link for this page

Return Value: Empty string

priority

Set the priority field

Synopsis: <!-- #sitemap priority 0.8 -->

Argument: Float between 0.0 and 1.0

Return Value: Empty string

changefreq

Set the changefreq field

Synopsis: <!-- #sitemap changefreq never -->

Argument: One of always, hourly, daily, weekly, monthly, yearly, never

Return Value: Empty string

lastmod

Set the lastmod field

Synopsis: <!-- #sitemap lastmod 2023-12-29T14:00:05+01:00 -->

Argument: The lastmod date in w3c date format

Return Value: Empty string


Pitfalls

  • The include command must not be in the last line of the file
  • The maps in set must have at least 2 options
  • The section commands must not be in a conditional block
  • The conditionals must not be neseted
  • If you want to use variables in markdown, you have to escape the # with a backslash, so #$(var) becomes \#$(var)
  • You can not use the return command from within the arguments of other commands. Commands are executed in order, so return will end up as argument of the first command and thus never be executed