eugen

A minimalist living documentation tool for Design Systems

Examples used here:

Eugen is a Design System documentation tool based on CSS comments.

Writing a Design System is a complicated task and documenting it is tedious. As a big fan of Living Documentation, I have decided to develop this tiny tool to make the process easier.

Fun fact, this site is entirely built using eugen itself, check it yourself!

How does it work?

That's damn simple. Just add comments on top of your declarations with a @tagname, for example in my_styles.css:

/**
 * @block: Represents a button
 * /
.button { }

/**
 * @block
 * Represents the sidebar
 *
 * @added_in: 1.2.0
 * /
.sidebar { }

Tag names can be anything that makes sense to you and not in the list of reserved tags: declarations, properties, url.

Create a template file for the @block tag called templates/block.html with the content:

<!-- 
    Here you must use valid html but for this sample,
    no html, no head just body.

    Here, the title will be the element CSS declarations
    joined by a colon.
-->
<h1>{{ page.declarations | join(', ') }}</h1>
<!--
    Next, the content of the `@block` tag will be rendered
    using the markdown builtin filter.
-->
{{ page.block | markdown }}
<!--
    page properties are extracted from existing tags
    and are represented as a list of lines hence the 
    `first` filter here to retrieve the value `1.2.0`
    for the sidebar example.
-->
{% if page.added_in %}
<small>Component added in version {{ page.added_in | first }}</small>
{% endif %}

eugen will group pages based on their tags and will try to render templates matching those tags (here block). By the way, the :root element will be your index page so it will be rendered with the index.html template file if present.

And finally, launch the eugen CLI:

$ eugen my_styles.css -t templates -o _build -v

And voilĂ , your documentation is ready!

Writing templates

Writing templates is just as easy as the syntax itself and use Jinja2 as its template engine.

Create a directory containing your template files (in html or pugjs like syntax) and eugen will use them to render your site.

Available variables

Here is the list of available variables inside a template:

Available filters

In order to make writing template easier, a bunch of filters has been included:

Page data

Page data represents what eugen has parsed from your source CSS files. It's a dictionary with the following structure:

page = {
 '_': ['Contains every comments not tied to any eugen tag', 'and may span multiple lines'],
 'url': lambda group='': 'lambda which returns the url relative to a group',
 'declarations': ['.text', 'p', '.and-every-other-declaration],
 'properties': [
   {
     '_': ['Structure is the same as for the page data', 'except the name property.', 'properties here refers to CSS Custom Properties'],
     'name': 'name-of-the-property',
   },
   ],
 'block': ['Contains all lines for the @block tag', 'here is another example with a @version tag'],
 'version': ['1.0.0'],
}