Free Software

Free Software Projects


Xerdi develops free software for different audiences. For high-end application users projects are colored purple. Projects aimed for LaTeX authors are colored blue. Technical projects aimed for developers are colored teal.


Xerdi selects licenses that embody the principles of free software and foster collaboration. For LaTeX projects, Xerdi adopts the LaTeX Project Public License (LPPL) version 1.3, ensuring clear guidelines for use, modification, and distribution within the LaTeX community. For other software projects, Xerdi chooses the GNU General Public License (GPL) version 3, promoting user freedom and a collaborative development model by requiring modifications to be released under the same license. These choices align with Xerdi's commitment to open collaboration and transparent, community-driven software development.

Support Xerdi

Xerdi welcomes your support to continue its commitment to developing free software and innovative projects. You can contribute by making a donation, either for a specific project or to support our overall mission of advancing open-source solutions.

To donate for a specific project, scroll to any project on this page and find the donation link. If you prefer to support Xerdi's general development of free software, you can make a donation here.

Your contributions play a crucial role in empowering individuals and organizations through technology. Thank you for being a part of the Xerdi community!

Lua [placeholders]

Take your LaTeX document creation to the next level with Lua Placeholders, a dynamic package tailored for LuaLaTeX. Bid farewell to tedious parameter setup and embrace a seamless, programmable approach using YAML recipe files.

Lua Placeholders empowers you to effortlessly create captivating documents by seamlessly incorporating both placeholders and real parameter values. Showcase your content dynamically with "example" documents and effortlessly transition to "final" documents enriched with authentic data.

Why Lua Placeholders?

  • Effortless Parameterization: Utilize YAML recipe files for streamlined and programmable parameter setup.
  • Dynamic Document Creation: Easily generate "example" and "final" documents for versatile content showcasing.
  • Seamless Integration: Integrate Lua Placeholders smoothly into your document workflow through standard LaTeX compilation.
  • Enhanced Flexibility: Support for multiple data types and formatting macros provides unparalleled design flexibility.

Ready to elevate your document game? Dive into Lua Placeholders' full potential by exploring our comprehensive manual.

Gitinfo Lua

Gitinfo Lua is a LaTeX package designed for LuaLaTeX, requiring shell escape functionality. It enhances LaTeX documents by providing macros like \gitversion and \gitdate for displaying version and date information retrieved from Git.

The package is available through the Comprehensive TeX Archive Network (CTAN).

The package supports multiple authors with \dogitauthors and \forgitauthors, allowing customizable formatting.

For commit information, \gitcommit and \forgitcommit offer versatile formatting options.

\forgittag introduces tag formatting with options for tag types, facilitating changelog generation.

For more information on Gitinfo Lua, read the package documentation.

Regulatory Documents

Every company qualifies to some degree with regulatory documents. Consider, for example, Terms and Conditions, Disclaimers or an Employment Agreement.

Xerdi develops all documentation using LaTeX. Functional-, technical designs, invoices et cetera. Xerdi sees it as the best solution due to the enormous potential for standardization, collaboration, technical compliance and even in some degree for automation purposes.

LaTeX proves remarkably user-friendly for certain applications; however, for specific tasks, its effective utilization becomes challenging without a thorough comprehension of the underlying TeX system.

On April 13, 2022, Xerdi started developing legal documents in LaTeX and as of April 18, 2023, all experience is intertwined in a LaTeX package — regulatory. This package was created to make it easy and concise for lawyers.

Read the user manual to get a better understanding of what the regulatory provides.


GinVoice logo

In 2017 I already made invoices with LaTeX. Not very user-friendly for normal users, but the perfect tool for me. It was in 2020 where I saw my formal girlfriend calculating invoice rows manually in Libre Office, so I decided to make a GTK app together with the power of LaTeX.

After more than 2 years of development of GinVoice, there is finally an installable product for Ubuntu Jammy Jellyfish. Currently it is available through my Personal Package Archives (PPA).

To install GinVoice via the PPA, you can do the following (root permissions required):

                    add-apt-repository ppa:maclotsen/ppa
                    apt update && apt install ginvoice

Alternatively, you can directly download the .deb file and run it with Ubuntu Software Center. Download the latest .deb file using this link.

Typed Lua Wrapping (TLW)

In 2019 Robin Koning and I started a game engine project, NGin. For using the NGin we have chosen not to burden the user with writing C++, but Lua. Lua is known for its simple embedding methods between C and Lua and vice versa, where other languages such as Python will only work optimally for one direction.

TLW was created to add concepts of C++ within the Lua context. For example, consider a C++ class, not a struct in C. In addition, TLW provides an elegant way to expose C++ classes to Lua.

Simple example:
struct entity {
    vec4 position;
    vec4 look_at;
    mat4 model;

    entity() : position(0, 0, 0, 1), look_at(0, 0, -1), model() {}

    explicit entity(vec4 position) : position(std::move(position)), look_at(0, 0, -1), model() {


    explicit entity(mat4 model) : position(0, 0, 0, 1), look_at(0, 0, -1), model(model) {


int luaopen_entitylib(lua_State *L) {
    tlw::state l(L);
    tlw::lua lua(l);
    auto lib_entity = tlw::define<entity>("entity")
            .prop("position", &entity::position)
            .prop("lookat", &entity::look_at)
            .prop("model", &entity::model)
    lua["entity"] = lib_entity(l);
    return 0;