README ¶
silvera
A minimal, markdown based static-site-generator. Extensible in python and bash with readable source-code.
Motivation
None of the available static-site-generators (ssg) fit my needs. They either offer too many features (see Hugo), or are unmaintained (see zs), or lack the extensibility.
I wanted an ssg that met the following requirements:
- Modifiable:
Everyone that wants to usesilvera
should be able to easily modify its source code. Because of that, the code is written relatively verbose, and includes a lot comments, to allow even users new togolang
to make changes. - Quickly/easily extensible:
silvera
already comes with some builtin features that can be enabled through a config file. Further extensions is easily possible in whatever language the user wishes. (Calledaddons
here, to differentiate between builtin options.) - Minimal:
The program should be easily understood, easily installed (contained in a singly binary) and not clutter the users system. Providing the user a base for building a very specialized tool is the only goal. - Well Documented:
A user should be able to find an explanation for every question regardingsilvera
, be it in this document, or in the source-code. No feature should be left unexplained or without example.
Installation
Depending on your preferences, build a binary, and put that somewhere in your PATH
:
go build -o silvera main.go
mv silvera /usr/local/bin
Then you can just do silvera init
wherever you want.
Or you could just go run
like:
go run /path/to/silvera/main.go init
Basic Usage
First, initialize a chosen directory as a workspace
.
Here you will put all the website-source- and configuration-files.
mkdir my_new_site
cd my_new_site
silvera init
A file called silvera.conf
will be created, containing a default configuration setup.
And create some content:
cd src
echo "# Hello World" > index.md
mkdir subdirectory
echo "# Hello Subdirectory" > subdirectory/index.md
echo "# Other File" > subdirectory/other.md
cd ..
Now go ahead and create the build directory according to the outdir
defined in silvera.conf
,
and then finally, build the files:
mkdir build
silvera build
Done! The outdir
should now look like this:
build
|- subdirectory
| |- index.html
| |- other.html
|- index.html
Configuration
Basic configuration is done in two files: silvera.conf
and template.html
.
silvera.conf
- outdir: The location at which to output the final product to.
- template: The path where the template is located.
- extensions
- tables: GitHub Flavored Markdown: Tables
- strikethrough: GitHub Flavored Markdown: Strikethrough
- autolinks: GitHub Flavored Markdown: Autolinks
- task_list: GitHub Flavored Markdown: Task list items
- definition_list: PHP Markdown Extra: Definition lists
- footnotes: PHP Markdown Extra: Footnotes
- typographer: This extension substitutes punctuations with typographic entities like smartypants.
- wikilink: Adds support for
[[wiki]]
-style links: goldmark-wikilink - mathjax: Mathjax support for the goldmark markdown parser: goldmark-mathjax
- table_of_contents: Adds support for generating tables-of-contents for goldmark documents: goldmark-toc
- parser_options
- custom_heading_attrs: Allows for custom attributes on headers like
## heading {#id .className attrName=attrValue class="class1 class2"}
. - auto_heading_id: Automatically generates ids for each heading. This is required for the
table_of_contents
extension to generate links to the listed headings.
- custom_heading_attrs: Allows for custom attributes on headers like
- renderer_options
- hard_wraps: Renders newlines as
<br>
. - xhtml: Renders as
XHTML
(just leave this enabled if you've never heard of XHTML). - unsafe_rendering: Allow for the rendering of potentially dangerous links or raw HTML. So if you want to use raw HTML mixed with Markdown, turn this on.
- hard_wraps: Renders newlines as
- addons: A list of active addon names (as strings).
template.html
This file specifies the HTML environment, in which the converted Markdown content is put it.
The file does not have to be named template.html
; you can specify the path to this file in silvera.conf
, including its name.
The template format follows golangs text/template format;
In short, this means you can write normal html
(or whatever text you'd like), and use markers like {{.Title}}
to embed generated content.
There are a number of markers available:
- {{.Title}}: An auto detected title of the page (the contents of the first h1 element).
- {{.Body}}: The actual contents that were generated from Markdown.
- {{.Path}}: The respective files relative path.
Take the following as a basic example:
<!DOCTYPE html>
<html>
<head>
<title>{{.Title}}</title>
</head>
<body>
<p>You are currently at {{.Path}}</p>
{{.Body}}
</body>
</html>
Local Cascading Configuration
Within your src
directory, every path may contain a .slv
directory with a silvera.conf
file inside it.
You can use this directory to specify local silvera.conf
files,
and to store files that should not be copied to the build directory, such as template.html
files.
This local configuration is cascaded through the nested directories like this:
Imagine the following structure
src
|- subdirectory
| |- .slv
| |- silvera.conf <-- LOCAL CONF
| |- file2.md
| |- file3.md
| |- sub_subdirectory
| |- file4.md
|- file1.md
This local configuration file will affect file2
, file3
and file4
, but not file1
.
file1
will instead be processed using the global configuration found in the workspace.
sub_subdirectory
could also contain its own .slv/silvera.conf
that would only affect file4
.
Addons
Addons are (mostly user written) pieces of code/script, that extend the functionality of silvera
from the outside.
They act on their own, without the context of the silvera
process, using their own data.
The name addon
is chosen in favor of extension
to make them easier to differentiate from the builtin extension options (see silvera.conf).
addon
would also not be fitting, as addons
mostly work "on-top" or "around" silvera
, and are not part of the programs main process.
Note: Addons
may come with their own dependencies, such as a .py
script requiring a python installation.
Using addons
You first have to install an addon to be able to use it.
To do this, simply move an addons directory to your workspaces' addon
directory.
Lets take silvera-html-format as an example.
Clone the addon into your addon
directory like this:
cd addons
git clone https://github.com/wintermute-cell/silvera-html-format
Done! Running ls
should reveal a single silvera-html-format
directory inside your addons
directory.
Now you can go ahead and enable the addon.
This is done through silvera.conf.
In the addons
field, add the directory name of your newly installed addon (silvera-html-format
) to the list:
addons:
- silvera-html-format
(also valid:)
addons: ['silvera-html-format']
Done! The addons will now work as expected. Note that you can also utilize the local config sytem to manage directory specific addons.
Existing addons
A managed (probably incomplete) list of addons can be found here: addon list.
Writing your own addon
Should you be willing to share you addon, you are invited to open a pull request to add an entry in the addon list.
To begin writing an addon, create a directory for your files to live in. Inside that directory, you can place any number of executable files, which have to obey the following naming guidelines:
prh__FILENAME.ext
forpre-hook
files.prf__FILENAME.ext
forpre-file-hook
files.pof__FILENAME.ext
forpost-file-hook
files.poh__FILENAME.ext
forpost-hook
files.
addon files use the hook
-system to know when they have to be called, and with what arguments.
There are 4 available hooks in silvera
:
- pre-hook: Called right at the beginning, before any processing happens.
- pre-file-hook: Called right before a Markdown file is read for processing. As a first argument, addons for this hook are given the path of the respective file. This makes it useful for modifying the source (.md) file ahead of processing.
- post-file-hook: Called right before a Markdown file is read for processing. As a first argument, addons for this hook are given the path of the respective file. This makes it useful for modifying the build (.html) file after of processing.
- post-hook: Called right at the end, after all the processing has finished.
All addon files in one directory compose a single addon.
This way, you could use ...-file-hook
executables to gather data, about all the files, save that data in a temporary file,
and then use the data in a post-hook
executable. For example gathering titles and building a nav-menu out of these titles at the end.
For a single hook, executables are called in alphabetical order.
You should prefix the filenames with numbers, so indicate a clear order, like prf__0FILENAME.ext
and prf__1FILENAME.ext
.
HINT: You can set the
PRINT_HOOK
constant inmain.go
to true, to get verbose output about addon activity, and also output your addons stdout.
Contributing
All contributions are generally welcome, within the above declared spirit of the program. If you're having problems and don't know how to fix them yourself, please report the issue at the issues page.
Testing
To run the test, use go test
from inside the project directory. The test will create a mock-workspace using silvera init
, run silvera build
,
and compare the results with the pregenerated results in testdata/correct_results
.
The test-generated files will be put in testdata/test_env
for the workspace and testdata/test_results
for the built files;
there you can manually observe them after the test.
License
This project uses GPLv3.
Documentation ¶
There is no documentation for this package.