Emanote is a Haskell program that, at its essense, transforms a bunch of “source files” (Markdown, static files, etc.) into a “target website”. It does that in a reactive manner such that as the source files change the resultant website updates in real-time (thanks to Ema’s hot-reload via websocket).
Emanote’s high-level architecture is as follows,
-
Emanote.Source
: manages source files and communicates them toEmanote.Model
.-
The key concept here is the notion of “union mount”, implemented by
Emanote.Source.Mount
, which will eventually be made its own Haskell library.
-
The key concept here is the notion of “union mount”, implemented by
-
Emanote.Model
: Haskell types & machinary to represent the source files in memory, as well as a way to efficiently index and query into them.-
The individual modules in this package should be
import
ed separately to use the specific model types.
-
The individual modules in this package should be
-
Emanote.Route
: Route types-
Emanote.Route.ModelRoute
: Haskell route types to point to somewhere inEmanote.Model
(eg: route to a .md file, or a route to a .jpeg file) -
Emanote.Route.SiteRoute
: Haskell route types pointing to somewhere in the generated site.
-
-
Emanote.View
: Rendering code (HTML, templates, site routes) -
Emanote.Pandoc
: Everything to do with light-weight markup processing-
Emanote.Pandoc.Markdown
: Markdown-specific parsers and syntax. -
Emanote.Pandoc.Renderer
: Emanote-specific transformation of Pandoc AST, via Heist custom splicing.
-
Ema acts as the framework orchestrating two things at the same time:
-
Emanote.Source.emanate
which is responsible for keeping the in-memoryModel
in sync with what’s on disk -
Emanote.View.render
which, whilst querying theModel
, is responsible for producing the final HTML for everySiteRoute
in the target website.
In addition, we have the following non-source files in the Git repository that are vital to Emanote’s functionality:
-
./default
: The primary and first “layer” used, which provides the default HTML templates (we use Heist),index.md
and a favicon. Users can override these by creating an equivalent file (same path) in their own layer.