Getting Started

This guide walks through building a static site from an Obsidian vault using ssglib and Pandoc.

Prerequisites

Minimal main.lua

Here is a minimal site builder:

local pandoc = require "pandoc"
local elements = require "ssglib.elements"
local paths = require "ssglib.paths"
local vault = require "ssglib.vault"
local site = require "ssglib.site"
local filters = require "ssglib.filters"

local function render(vars)
  local html = elements.html
  return elements.concat {
    elements.raw "<!DOCTYPE html>\n",
    html.html { lang = "en",
      html.head {
        html.meta { charset = "utf-8" },
        html.title { vars.title },
      },
      html.body {
        html.main {
          html.h1 { vars.title },
          elements.raw(vars.body),
        },
      },
    },
  }
end

local s = site.Site.new(arg[2])
local v = vault.Vault.new(arg[1])

for note in v.notes:iter() do
  local doc = v:doc(note)
  doc = doc:walk {
    BlockQuote = filters.callout_filter,
    Link = filters.make_link_filter(v, note),
  }
  local vars = {
    title = paths.stem(note),
    body = pandoc.write(doc, "html5"),
  }
  s:write_data(v:url(note), pandoc.layout.render(render(vars), 72))
end

s:cleanup()

Build Pipeline

The build process follows these steps:

  1. Load the vault -- Vault.new() scans the vault directory, indexes all files, and reads permalink front matter from each note.

  2. Iterate notes -- vault.notes is a pandoc.List of vault-relative POSIX paths for all .md files.

  3. Parse and filter -- vault:doc(path) parses a note into a Pandoc document. Calling doc:walk(filter) applies filters that resolve wikilinks and process callouts.

  4. Render HTML -- pandoc.write(doc, "html5") converts the filtered document to HTML. A render function wraps the content in a full page template using the Elements module.

  5. Write output -- Site:write_data() writes the rendered HTML to the output directory. Unchanged files are skipped for fast incremental builds.

  6. Clean up -- Site:cleanup() removes any files in the output directory that were not written during this build.

Running the Build