eureka is a simple static site generator based on the generator for 100r.co.

eureka simply reads .htm files in ./inc/ and applies a template around them, giving them a <header>, <nav>, and <footer>. The <nav> content is also located in inc/meta.nav.htm, and, contrary to 100r.co’s engine, special rules are applied when templating around it to render the landing page (index.html).

In addition, there is a thumbnailer that uses ImageMagick to create low-bandwidth thumbnails at 500px wide and 16 colors, and store them in a subdirectory alongside the full size images. eureka has a function to automatically replace the inline images within pages with the thumbnails, but leave the links they point to untouched.

Eureka also parses a twtxt file at SITEROOT/twtxt.txt and displays the latest three entrires on the front page. It expects the file to be in descending order.


  1. Run ./build.sh to copy the default config header to config.h and create the inc directory (and meta.nav.htm) if it doesn’t exist.
  2. Edit your config; see below for details.
  3. Create your CSS and other assets if necessary and put them in your SITEROOT.
  4. Edit your inc/meta.nav.htm to create your nav structure (see the markup section below).
  5. Create a new page, eg inc/my_first_page.htm (see the markup section below).
  6. Edit your inc/meta.nav.htm again to reference your new page.
  7. Run ./build.sh again! You will be warned of any orphaned files.

build options

Currently these build options are supported, and they must be supplied in this order if used together: - -r: Regenerate all thumbnails - -d: Delete the latest twtxt entry; if used together with -t, the new entry replaces the old one - -t: Add the next arg (quoted string) as a twtxt entry

Combined argument format like ./build.sh -rdt "twt stuff" is not supported. Use this format instead: ./build.sh -r -d -t "twt stuff"


If you run into issues with your markup crashing eureka, edit the build.sh file to uncomment the linux debug build line and comment the fast build; this will show you a stack trace of where you are running into buffer overflows, and give you a hint of where your markup is messed up. To see the individual file that has the error, also uncomment the line in fpinject() that prints the file names.


There is a markup language which makes writing long blog posts, memex entries, etc easier by reducing the need for typing out HTML tags:

// shorthand for crosslinking (assuming the file is inc/page_name.htm)
{page name}

// shorthand for transclusion (assuming the file is inc/page_name.htm)
{/page name}

// shorthand for arbitary link
{*destination url|text}

// shorthand for an image you can click to see the full sized version
{:anchor-id|image url|alt text}

// shorthand for an image with arbitrary link destination
{?anchor-id|destination url|image url|alt text}

// shorthand for an audio player

// shorthand for a video player
{]id|/path/to/video|/path/to/thumbnail|fallback alt text for thumbnail image if HTML5 video is not supported}

// shorthand for paragraphs, can embed other markup inside it
{&paragraph text {with a link} {@and some bold text}}

// shorthand for ordered lists, can embed other markup inside it
  {-item one}
  {-item two}
  {-item three}

// shorthand for unordered lists, can embed other markup inside it
  {-item one}
  {-item two}
  {-item three}

// shorthand for bold
{@bold text}

// shorthand for italic
{~italic text}

// shorthand for code
{`short code}

// shorthand for pre
{$longer code}

// shorthand for quote
{'short quote}

// shorthand for blockquote
{>longer quote}

// shorthand for strikethrough
{\crossed-out text}

// shorthand for level 3 heading 
{!heading text}

// shorthand for level 4 heading
{.heading text}

// shorthand for tables
{[column 1 header|column 2 header|column 3 header}
{|simple data|{@bold data}|{*https://nilfm.cc|link data}}
{|more|and more|and more data!}

// shorthand for publish date (renders as <time class='publish-date'>)


The following macros are available in config.h to customize to your liking.

  • LEXICON_SIZE: max size of the Lexicon, corresponds to the number of pages eureka can keep track of
  • TAG_BODY_SIZE: max size for an individual markup body (ie, a markup token as above, minus the curly brackets and the rune), in bytes
  • NAME: the title of the site
  • DOMAIN: currently unused
  • LOGO: HTML to put in the header h1 verbatim
  • ABOUT: HTML content for the front page, placed between <header> and <nav>
  • CONTACT: the contact info line at the bottom of every page (except the front page, where it would typically already be in @ABOUT
  • FOOTER: arbitrary footer HTML
  • LICENSE: the license link at the bottom of every page
  • SITEROOT: the path where the rendered HTML is placed
  • MAINCSS and FRONTCSS: to differentiate styles used for the landing page and the rest of the site