🐫 In a startup pitch style, it's a website generator for Markdown haters.


Daniil Baturin 41399e1452 Update the ocaml version requirement to 4.13 1 week ago
.github 478e46ca7a Use macOS 12 for CI builds since 10.5 is no longer available 3 months ago
examples 8ee3839857 Improve the example plugin a bit. 2 years ago
sample-site f1208df7eb Fix default_template_option in the sample site config 7 months ago
scripts a5a38962eb Add a release automation script 6 months ago
src 8470d828d5 Update the version string inside soupault to 4.3.1 1 week ago
.gitignore 17af1e0eb4 Clean up the .gitignore a bit 11 months ago
CHANGELOG.md 1ed82cd56a Add release dates to the changelog 1 week ago
LICENSE 85dfa51b9a Update copyright year 10 months ago
README.md 82c1035924 README improvements (mainly links) 6 months ago
dune f17e457c3f First prototype. 3 years ago
dune-project 31205f9837 Update the version for new dependencies. 3 years ago
link_widgets.ml 73807e8d93 Add labels to the arguments of regex functions 7 months ago
soupault.opam 41399e1452 Update the ocaml version requirement to 4.13 1 week ago



Build GitHub all releases

Soupault is an HTML manipulation tool. It can be any of:

  • static site generator,
  • HTML processor,
  • metadata extractor,

or all of them at the same time.

Soupault works with the HTML element tree of the page, so it can do many things that traditionally could be done with client-side JS: inject new HTML into existing complete pages, create a table of contents that preserves the id elements of HTML headings and more.

It also doesn't use front matter and extracts metadata from HTML instead, using a CSS3 selector to metadata field mapping, so even hand-written static pages can be indexed rather than treated as assets. For example:

  # Try to find <h1 id="post-title"> if it exists,
  # else use the first <h1> 
  selector = ["h1#post-title", "h1"]

  selector = ["p#post-excerpt", "p"]

  selector = ["time#post-date", "time"]
  extract_attribute = "datetime"
  fallback_to_content = true

Extracted metadata can then be rendered and injected into pages:

  # Insert rendered data into the element that matches "#blog-index" CSS selector.
  index_selector = "#blog-index"
  index_item_template = """
    <h2><a href="{{url}}">{{title}}</a></h2>
    <p><strong>Last update:</strong> {{date}}.</p>
    <a href="{{url}}">Read more</a>

Soupault is...

  • Eternal: it comes as a statically-linked binary with no dependencies.
  • Extensible: you can bring your own page preprocessors (e.g. Markdown to HTML convertors), pipe HTML elements through external programs, and load Lua plugins.
  • Flexible: most options are configurable, most built-in features can be reimplemented as Lua plugins, and there are page processing hooks.

Soupault is named after the French dadaist and surrealist writer Philippe Soupault because it's based on the lambdasoup library.

Visit soupault.app for details.

For support and discussion, write a message to the mailing list.


Pre-built binaries are available for Linux, Windows, and macOS. You can download them from https://files.baturin.org/software/soupault and from Github releases (https://github.com/dmbaturin/soupault/releases).

You can verify release archive integrity using this signify/minisign key: RWRfW+gkhk/+iA7dOUtTio6G6KeJCiAEp4Zfozw7eqv2shN90+5z20Cy.

You can also install stable release versions from OPAM:

opam install soupault

Finally, you can build the latest development version with:

opam pin add git+https://github.com/PataphysicalSociety/soupault


Bug reports and patches are always welcome. Feature requests and new features are also welcome, but please consider discussing them with the maintainer first.

You can contribute either through GitHub or through Codeberg.