Skip to content

Releases: PataphysicalSociety/soupault

5.1.0 release

17 Jun 13:31
Compare
Choose a tag to compare

5.1.0 (2025-06-17)

Release blog post: https://soupault.app/blog/soupault-5.1.0-release/

New features

  • Target directories for page files are now guaranteed to exist when soupault starts processing widgets,
    so that widgets can create new asset files in page directories.
  • Global data for Lua plugins is now reintroduced: the startup hook can add values to the global_data table
    and all Lua plugins and hooks can retrieve them using the new Plugin.get_global_data(name) function.
    Plugins and hooks cannot modify the global data, so it doesn't create a consistency problem.
  • site_index and index_entry variables are now available in the template environment of the element_template widget.
  • New index field option strip_tags for people who want to strip HTML tags from particular index fields.

New Lua API functions

There are now functions for case conversion. They only affect the case of ASCII characters,
Unicode characters are ignored because handling their case requires knowing their language.

  • String.lowercase_ascii(string)
  • String.uppercase_ascii(string)
  • String.capitalize_ascii(string)
  • String.uncapitalize_ascii(string)

Behavior changes

  • Index extraction is now always enabled in generator mode. index.index option no longer has any effect.

5.0.0 release

24 Apr 00:56
Compare
Choose a tag to compare

Release post: https://soupault.app/blog/soupault-5.0.0-release/

Removed features

  • index.index_first is no longer a valid configuration option.
    If you use it, simply remove it from the config — index data is now always available to all pages
    (more on that later).
  • settings.process_pages_first is no longer a valid option — there is no sequential page processing anymore
    so the concept of "processing specific pages first" no longer applies.
    It should have no effect on any websites.
  • There is no separate post-save hook anymore. If you used it, move the code to the save hook instead.
  • There is no way to make the post-index hook tell soupault to ignore a page
    (previously that was possble to do by setting the undocumented ingore_page variable).
  • persistent_data and global_data variables are no longer available in the plugin environment.
    If you want to share data, place it in the page or in the index entry.

New features

Built-in Markdown support

Soupault now includes a built-in Markdown processor (compatible with CommonMark and popular extensions,
based on CMarkit).

Support for built-in Markdown needs to be explicitly enabled in the config:

[settings]
  markdown_extensions = ["md"]

If enabled, it takes priority over page preprocessors — if "md" (or another extension)
is in settings.markdown_extensions, soupault does not try to look up a preprocessor
and processed it using the built-in implementation right away.

element_template widget

The new element_template widget replaces an element with an HTML snippet produced by rendering
a template using attributed and content of the source element.

Its goal is to allow users to easily create "shortcodes" without writing Lua code.

os_family option for exec and preprocess_element widgets

Those widgets now support a new os_family option to limit them to only one OS family
and use different commands for those OSes. At the moment, it can be "unix" (any UNIX-like OS)
or "windows" (Microsoft Windows or compatibles, such as ReactOS).

New plugin functions

  • Table.sort(func, table) — sorts a table with numeric indices using func for value comparison.
  • String.to_integer — converts a string to an integer (returns nil if conversion fails).
  • String.to_float — a clearer-named alias for String.to_number.

Deprecated options

  • settings.strict and --strict <true|false> options are not deprecated
    and will be removed in future releases.
    All built-in errors are now treated as fatal and cannot be ignored.

Behavior changes

  • Site index is now available to all pages by default.
  • If a website requires more RAM to process than the machine has available,
    soupault now can run out or memory, like most other static site generators
    (that's the compromise required to make index data available to all pages).
  • Metadata extraction now occurs as early as possible — just after all widgets listed in index.extract_after_widgets.
  • Caching is now enabled by default.

Bug fixes

  • Clean URL in rendered index views now include trailing slashes,
    which reduces the number of unncessessary redirects (GitHub issue #81).
    The old behavior can be restored with settings.clean_url_trailing_slash = false.
  • Lists of selectors are now consistently supported in all built-in widgets (GitHub issue #77).
  • If the pre-process hook modifies the path of a leaf bundle,
    its child asset paths are adjusted accordingly (GitHub issue #63).
  • soupault --show-effective-config now correctly updates values
    that are overridden by commmand line options or internal processes.

4.11.0 release

07 Sep 18:46
Compare
Choose a tag to compare

Release post: https://soupault.app/blog/soupault-4.11.0-release/

New features

  • It's now possible to use :has() selector in options that accept CSS selectors (implemented in lambdasoup 1.1.0)

New plugin API functions

  • HTML.is_text(e) — checks if an HTML element tree node is a text node. Thanks to @jbhoot!

Bug fixes

  • HTML.is_document(e) now correctly returns true for values created with HTML.parse() and HTML.create_document().
  • Namespaces are now correctly preserved in HTML element attribute names (implemented in lambdasoup 1.1.1).

4.10.0 release

22 Apr 09:12
Compare
Choose a tag to compare

Release blog post: https://soupault.app/blog/soupault-4.10.0-release/

New features

Deleting only elements that do not have certain children

The delete_element widget has a new option: when_no_child.

For example, suppose you have footnotes container in your template that looks like this:
<div id="footnotes"> <hr class="footnotes-separator"> </div>. If a page has footnotes,
it would contain something like <p class="footnote">.... If not, it would only have the <hr> element in it.

Deleting it from pages that don't have any footnotes cannot be done with only_if_empty
because the container has that auxilliary element in it.

However, with the new option you can make the widget delete the container
only if nothing inside it matches the selector of actual footnotes.

[widgets.clean-up-footnote-containers]
  after = "footnotes"
  widget = "delete_element"
  selector = "div#footnotes"
  when_no_child = "p.footnote"

Bug fixes

  • Complete HTML pages work correctly in generator mode again (report by Auguste Baum)
  • Config files with multiline strings and Windows newlines (CRLF) no longer cause parse errors
    (report by Bohdan Kolesnikov)
  • Configs that consist of a single comment line followed by EOF no longer cause parse errors
    (found thanks to the TOML test suite v1.4.0)

4.9.0

20 Mar 12:06
Compare
Choose a tag to compare

Release blog post: https://soupault.app/blog/soupault-4.9.0-release

New features and improvements

  • New startup hook that runs before soupault processes any pages and can modify the global_data variable.

New plugin API functions

New Digest module offers functions for calculating cryptographic hash sums of strings.
All those functions return hex digests.

  • Digest.md5(str)
  • Digest.sha1(str)
  • Digest.sha256(str)
  • Digest.sha512(str)
  • Digest.blake2s(str)
  • Digest.blake2b(str)

Other new functions:

  • Sys.basename_url(str) and Sys.dirname_url(str) — aliases for Sys.basename_unix and Sys.dirname_unix, respectively.

4.8.0 release

01 Feb 11:26
Compare
Choose a tag to compare

Full announcement: https://soupault.app/blog/soupault-4.8.0-release (includes important information about future plans)

4.8.0 (2024-01-12)

New features and improvements

  • site_index variable is now available to the post-build hook.
  • index_entry variable (the complete site index entry for the current page) is now available to post-index, save and post-save hooks and to Lua index processors.
  • New options for ignoring certain paths in the sire dir: settings.ignore_path_regexes and settings.ignore_directories.

New plugin API functions

  • HTML.inner_text() — returns the text nodes from inside a node, stripped of all HTML tags.

Bug fixes

  • In generator mode, page files are parsed as HTML fragments so <style> tags and similar no longer call issues
    with duplicate <body> tag inserted in the page (#58, report by Delan Azabani).

4.7.0 release

19 Sep 16:54
Compare
Choose a tag to compare

Release blog post: https://soupault.app/blog/soupault-4.7.0-release

New features and improvements

  • New max_items option in index views allows limiting the number of displayed items.
  • New settings.page_character_encoding option for correctly loading pages in encodings other than ASCII and UTF-8.
  • New post-build hook that runs when all pages are processed and soupault is about to terminate.
  • Info logs to indicate the first and second passes in the index_first = true mode.
  • Debug logs now tell why a page is included or excluded from an index view: "page_included checks for %s: regex=%b, page=%b, section=%b"

New plugin API functions

  • CSV.from_string(str) — parses CSV data and returns it as a list (i.e., an int-indexed table) of lists.
  • CSV.unsafe_from_string(str) — like CSV.from_string but returns nil on errors instead or raising an exception.
  • CSV.to_list_of_tables(csv_data) — converts CSV data with a header returned by CSV.from_string into a list of string-indexed tables for easy rendering.
  • HTML.swap(l, r) — swaps two elements in an element tree.
  • HTML.wrap(node, elem) — wraps node in elem.
  • New global_data hash table for sharing data between plugins.
  • New soupault_pass plugin environment variable (0 when index_first = false, 1 and 2 for the first and the second pass respectively when it's true).

Bug fixes

  • Fixed an unhandled exception on index entry sorting failures when sort_strict = true and sort_by is unspecified.
  • Fixed a typo in the comments of the config generated by soupault --init (s/ULRs/URLs/).

Misc

New state record now holds both the settings record and the TOML config datastructure,
plus the new global_data and soupault_pass variables, and can be easily extended to support global state new variables.

Official binaries are now available for Linux on ARM64.

4.6.0 release

17 Jun 13:26
Compare
Choose a tag to compare

Release post: https://soupault.app/blog/soupault-4.6.0-release/

New features and improvements

New plugin API functions

  • Sys.getenv(name, default_value) function (default_value is optional).
  • String.ends_with(string, suffix).
  • String.is_valid_utf8(string) and String.is_valid_ascii(string) functions.
  • Table.length(table) — returns the number of items in a table.
  • Table.for_all(func, table) — checks if boolean function func is true for all items in a table.
  • Table.for_any(func, table) — checks if boolean function func is true for at least one item in a table.
  • Table.is_empty(t) — returns true if t has no items in it.
  • Table.copy(t) — returns a copy of the table t.
  • HTML.is_empty(e) — returns true if e has zero child nodes.
  • HTML.is_root(e) — returns true if e has no parent node.
  • HTML.is_document(e) — returns true if e is a soup (document) node rather than an element or a text.
  • Value.is_html(v) — returns true is v is an HTML document or node.

Bug fixes

  • Fixed an unhandled OTOML exception when loading configs with duplicate key names (such issues generate proper parse errors now).

4.5.0 release

18 Apr 22:30
Compare
Choose a tag to compare

Full announcement: https://soupault.app/blog/soupault-4.5.0-release

New features and improvements

  • --no-caching option allows the user to disable caching even if settings.caching is true in the config.
  • [Plugin API] New HTML.prepend_root(node, child) function for inserting new nodes in HTML documents before all existing nodes.
  • The name of the Lua index processor file and the index view that calls it are displayed in the logs now.
  • Clearer breadcrumb template parse error message (mentions Jingoo now).

Bug fixes

  • soupault --version correctly prints a trailing newline again.

4.4.0 release

04 Feb 10:21
Compare
Choose a tag to compare

New features

Support for caching the output of page preprocessors and commands used by preprocess_element widgets.

[settings]
  # Caching is off by default so you need to enable it
  caching = true

  # Change the cache directory name if you wish
  cache_dir = ".soupault-cache"

You can force soupault to clear the cache and rebuild everything by running soupault --force.