Add initial user's guide

This commit is contained in:
Mikko Ahlroth 2024-04-21 21:27:56 +03:00
parent cb93a8bad4
commit dca0bde579
3 changed files with 281 additions and 7 deletions

View file

@ -1,5 +1,153 @@
Scriptorium User's Guide
This user's guide is a work-in-progress. Please check back later. If you have any questions, don't
hesitate to ask me [on the fediverse](https://social.ahlcode.fi/@nicd) or on the Gleam Discord (user
Nicd).
_This user's guide is a work-in-progress. Please keep checking back for more information. If you have
any questions or feedback, don't hesitate to ask me [on the fediverse](https://social.ahlcode.fi/@nicd)
or on the Gleam Discord (user Nicd)._
### Table of Contents
1. [Prerequisites & Installation](#installation)
1. [Default Filesystem Layout](#filesystem)
1. [Writing a Post](#writing)
### <a name="installation"></a>Prerequisites & Installation
Scriptorium requires the following software:
- Gleam 1.1+
- Node.js (tested on version 20)
In addition, you will need at least a preliminary understanding of the Gleam language. The default blog
setup does not require any special knowledge, but customizing the generation process will require
writing Gleam code.
Typically creating a blog with Scriptorium requires creating a new Gleam project. When you have a Gleam
project, you can add the library as a dependency by using <kbd>gleam add scriptorium</kbd>.
To set up a basic blog, replace the project's main file with the following:
```gleam
import gleam/result
import gleam/option
import gleam/io
import scriptorium/builder
import scriptorium/config.{type Configuration}
import scriptorium/defaults
pub fn main() {
let config =
defaults.default_config(
"My Blog",
"https://my.blog.example/",
"en",
config.Author(
"Person McPerson",
option.Some("person@example.com"),
option.Some("https://fedi.instance.example/@person"),
),
"© Person McPerson",
)
io.debug(build(config))
}
pub fn build(config: Configuration) {
// Parse the files
use db <- result.try(builder.parse(config))
// Compile Markdown into HTML
let compiled = builder.compile(db, config)
// Render content into Lustre elements
let rendered = builder.render(db, compiled, config)
// Write rendered content into the filesystem
builder.write(rendered, config)
}
```
This is the minimum setup for building a blog. Now the blog can be generated with <kbd>gleam run</kbd>.
### <a name="filesystem"></a>Default Filesystem Layout
By default the blog generator expects the following folders to exist:
- `data` Master folder for input data, inside the root of the project folder.
- `posts` Folder for posts.
- `pages` Folder for pages.
As an illustrative example of the contents, the filesystem contents of this blog at the time of writing
were:
```
data
├── menu
├── pages
│   ├── 404.md
│   └── guide.md
└── posts
├── 2024-04-14-hello-world.md
└── 2024-04-21-scriptorium-published.md
```
<!-- TODO: Screen reader alternative for the above? -->
### <a name="writing"></a>Writing a Post
#### Post Filename
To write a post, create a new file in the `./data/posts` folder. The filename must consist of the
following:
- an [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) formatted date, i.e. `YYYY-MM-DD`,
- a dash
- an _optional_ zero-padded 2-digit order number used for ordering when two posts were written on the
same day and don't have time information, followed by a dash,
- a _slug_ that is a free-form name for the post used in the post filename and thus the final URL, and
- the file extension `.md`.
Note that because the slug is used in the filename and in the URL, it should only contain filename and
URL safe text. The recommendation is to stick to regular characters, dashes, and underscores, without
any spaces. "Regular characters" here does not exclude non-latin characters, as they are safely
percent-encoded in a URL.
#### Post Contents
Scriptorium posts are written in [Markdown](https://en.wikipedia.org/wiki/Markdown).
[Marked.js](https://marked.js.org) is used for compiling Markdown, so its documentation should be
consulted when there is a question about how something is rendered.
##### Header
There are, however, some special parts at the start of a post. Let's look at an example:
```markdown
Post Title
tag1, tag2, tag3
time: 21:15 Europe/Helsinki
description: Example post
image: https://example.com/example.jpg
Hello, and welcome to this example post!
```
The first line in a file is the post title. After that, optionally, come post tags on their own line,
separated by a comma. Post tags are used as-is, so they also should contain only filename and URL safe
content, and no spaces.
After the tags are _headers_. Headers are a collection of key-value pairs, separated by a colon. They
can contain various metadata about the post, and the user can implement their own headers by
customizing the post view. There are some predefined headers:
- `time` Defines the time when the post was written. The format is <kbd>hh:mm TZ</kbd>, where the
first part is the local time using a 24 hour clock, and the second is the
[local timezone identifier](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
- `description` A description of the post that is used for link embeds on external services.
- `image` An image that is used for link embeds on external services. Should be on the smaller side
and must be an absolute URL.
##### Splitting
Often it is not sensible to show the whole post in list views with many posts. In this case the post
can be divided into two pieces. In the list view, only the first part is shown, and in the individual
post page, both parts are shown.
To do this, insert <kbd>&lt;!-- SPLIT --&gt;</kbd> in the post. It's recommended to put this on its
own line and not inside any HTML or Markdown content that would get broken when split apart.

View file

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="html">Scriptorium Blog</title><updated>2024-04-21T08:15:36.178Z</updated><link href="https://nicd.gitlab.io/scriptorium_blog"/><id>https://nicd.gitlab.io/scriptorium_blog</id><author><name>Mikko Ahlroth</name><email>mikko@ahlroth.fi</email><uri>https://social.ahlcode.fi/@nicd</uri></author><generator uri="https://gitlab.com/Nicd/scriptorium" version="1.0.0">Scriptorium</generator><rights>© Mikko Ahlroth</rights><entry><title type="html">Scriptorium 1.0 Published</title><id>https://nicd.gitlab.io/scriptorium_blog/2024/04/21/scriptorium-published.html</id><updated>2024-04-21T11:00:00.000+03:00</updated><content type="html">&lt;figure&gt;
<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom"><title type="html">Scriptorium Blog</title><updated>2024-04-21T18:27:24.515Z</updated><link href="https://nicd.gitlab.io/scriptorium_blog"/><id>https://nicd.gitlab.io/scriptorium_blog</id><author><name>Mikko Ahlroth</name><email>mikko@ahlroth.fi</email><uri>https://social.ahlcode.fi/@nicd</uri></author><generator uri="https://gitlab.com/Nicd/scriptorium" version="1.0.0">Scriptorium</generator><rights>© Mikko Ahlroth</rights><entry><title type="html">Scriptorium 1.0 Published</title><id>https://nicd.gitlab.io/scriptorium_blog/2024/04/21/scriptorium-published.html</id><updated>2024-04-21T11:00:00.000+03:00</updated><content type="html">&lt;figure&gt;
&lt;blockquote&gt;
&lt;p&gt;
scriptorium /skrĭp-tôrē-əm/&lt;br&gt;

View file

@ -1,5 +1,131 @@
<!doctype html>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Scriptorium User&#39;s Guide · Scriptorium Blog</title><link href="/scriptorium_blog/css/normalize.css" rel="stylesheet"><link href="/scriptorium_blog/css/magick.css" rel="stylesheet"><link href="/scriptorium_blog/css/custom.css" rel="stylesheet"><link href="/scriptorium_blog/feed.xml" rel="alternate" type="application/atom+xml"><link rel="me" href="https://social.ahlcode.fi/@nicd"><meta name="author" content="Mikko Ahlroth"><meta name="description" content><meta itemprop="name" content="Scriptorium User's Guide"><meta itemprop="author" content="Mikko Ahlroth"><meta itemprop="headline" content="Scriptorium User's Guide"><meta itemprop="description" content><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content><meta name="twitter:title" content="Scriptorium User's Guide"><meta name="twitter:description" content><meta name="twitter:creator" content><meta property="og:title" content="Scriptorium User's Guide"><meta property="og:type" content="article"><meta property="og:description" content><meta property="og:site_name" content="Scriptorium Blog"><meta property="og:url" content="https://nicd.gitlab.io/scriptorium_blog/guide"></head><body><header id="title" role="banner"><h1><a href="/scriptorium_blog/index.html">Scriptorium Blog</a></h1><nav><ul><li><a href="https://hex.pm/packages/scriptorium">Hex</a></li><li><a href="https://hexdocs.pm/scriptorium">HexDocs</a></li><li><a href="https://gitlab.com/Nicd/scriptorium">GitLab</a></li><li><a href="/scriptorium_blog/guide.html">User&#39;s Guide</a></li><li><a href="https://gitlab.com/Nicd/scriptorium_blog">This blog&#39;s source</a></li></ul></nav></header><main><article class="page"><header><h2>Scriptorium User&#39;s Guide</h2></header><div><p>This user&#39;s guide is a work-in-progress. Please check back later. If you have any questions, don&#39;t
hesitate to ask me <a href="https://social.ahlcode.fi/@nicd">on the fediverse</a> or on the Gleam Discord (user
Nicd).</p>
<html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Scriptorium User&#39;s Guide · Scriptorium Blog</title><link href="/scriptorium_blog/css/normalize.css" rel="stylesheet"><link href="/scriptorium_blog/css/magick.css" rel="stylesheet"><link href="/scriptorium_blog/css/custom.css" rel="stylesheet"><link href="/scriptorium_blog/feed.xml" rel="alternate" type="application/atom+xml"><link rel="me" href="https://social.ahlcode.fi/@nicd"><meta name="author" content="Mikko Ahlroth"><meta name="description" content><meta itemprop="name" content="Scriptorium User's Guide"><meta itemprop="author" content="Mikko Ahlroth"><meta itemprop="headline" content="Scriptorium User's Guide"><meta itemprop="description" content><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content><meta name="twitter:title" content="Scriptorium User's Guide"><meta name="twitter:description" content><meta name="twitter:creator" content><meta property="og:title" content="Scriptorium User's Guide"><meta property="og:type" content="article"><meta property="og:description" content><meta property="og:site_name" content="Scriptorium Blog"><meta property="og:url" content="https://nicd.gitlab.io/scriptorium_blog/guide"></head><body><header id="title" role="banner"><h1><a href="/scriptorium_blog/index.html">Scriptorium Blog</a></h1><nav><ul><li><a href="https://hex.pm/packages/scriptorium">Hex</a></li><li><a href="https://hexdocs.pm/scriptorium">HexDocs</a></li><li><a href="https://gitlab.com/Nicd/scriptorium">GitLab</a></li><li><a href="/scriptorium_blog/guide.html">User&#39;s Guide</a></li><li><a href="https://gitlab.com/Nicd/scriptorium_blog">This blog&#39;s source</a></li></ul></nav></header><main><article class="page"><header><h2>Scriptorium User&#39;s Guide</h2></header><div><p><em>This user&#39;s guide is a work-in-progress. Please keep checking back for more information. If you have
any questions or feedback, don&#39;t hesitate to ask me <a href="https://social.ahlcode.fi/@nicd">on the fediverse</a>
or on the Gleam Discord (user Nicd).</em></p>
<h3>Table of Contents</h3>
<ol>
<li><a href="#installation">Prerequisites &amp; Installation</a></li>
<li><a href="#filesystem">Default Filesystem Layout</a></li>
<li><a href="#writing">Writing a Post</a></li>
</ol>
<h3><a name="installation"></a>Prerequisites &amp; Installation</h3>
<p>Scriptorium requires the following software:</p>
<ul>
<li>Gleam 1.1+</li>
<li>Node.js (tested on version 20)</li>
</ul>
<p>In addition, you will need at least a preliminary understanding of the Gleam language. The default blog
setup does not require any special knowledge, but customizing the generation process will require
writing Gleam code.</p>
<p>Typically creating a blog with Scriptorium requires creating a new Gleam project. When you have a Gleam
project, you can add the library as a dependency by using <kbd>gleam add scriptorium</kbd>.</p>
<p>To set up a basic blog, replace the project&#39;s main file with the following:</p>
<pre><code class="language-gleam">import gleam/result
import gleam/option
import gleam/io
import scriptorium/builder
import scriptorium/config.{type Configuration}
import scriptorium/defaults
pub fn main() {
let config =
defaults.default_config(
&quot;My Blog&quot;,
&quot;https://my.blog.example/&quot;,
&quot;en&quot;,
config.Author(
&quot;Person McPerson&quot;,
option.Some(&quot;person@example.com&quot;),
option.Some(&quot;https://fedi.instance.example/@person&quot;),
),
&quot;© Person McPerson&quot;,
)
io.debug(build(config))
}
pub fn build(config: Configuration) {
// Parse the files
use db &lt;- result.try(builder.parse(config))
// Compile Markdown into HTML
let compiled = builder.compile(db, config)
// Render content into Lustre elements
let rendered = builder.render(db, compiled, config)
// Write rendered content into the filesystem
builder.write(rendered, config)
}
</code></pre>
<p>This is the minimum setup for building a blog. Now the blog can be generated with <kbd>gleam run</kbd>.</p>
<h3><a name="filesystem"></a>Default Filesystem Layout</h3>
<p>By default the blog generator expects the following folders to exist:</p>
<ul>
<li><code>data</code> Master folder for input data, inside the root of the project folder.<ul>
<li><code>posts</code> Folder for posts.</li>
<li><code>pages</code> Folder for pages.</li>
</ul>
</li>
</ul>
<p>As an illustrative example of the contents, the filesystem contents of this blog at the time of writing
were:</p>
<pre><code>data
├── menu
├── pages
│   ├── 404.md
│   └── guide.md
└── posts
├── 2024-04-14-hello-world.md
└── 2024-04-21-scriptorium-published.md
</code></pre>
<!-- TODO: Screen reader alternative for the above? -->
<h3><a name="writing"></a>Writing a Post</h3>
<h4>Post Filename</h4>
<p>To write a post, create a new file in the <code>./data/posts</code> folder. The filename must consist of the
following:</p>
<ul>
<li>an <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> formatted date, i.e. <code>YYYY-MM-DD</code>,</li>
<li>a dash</li>
<li>an <em>optional</em> zero-padded 2-digit order number used for ordering when two posts were written on the
same day and don&#39;t have time information, followed by a dash,</li>
<li>a <em>slug</em> that is a free-form name for the post used in the post filename and thus the final URL, and</li>
<li>the file extension <code>.md</code>.</li>
</ul>
<p>Note that because the slug is used in the filename and in the URL, it should only contain filename and
URL safe text. The recommendation is to stick to regular characters, dashes, and underscores, without
any spaces. &quot;Regular characters&quot; here does not exclude non-latin characters, as they are safely
percent-encoded in a URL.</p>
<h4>Post Contents</h4>
<p>Scriptorium posts are written in <a href="https://en.wikipedia.org/wiki/Markdown">Markdown</a>.
<a href="https://marked.js.org">Marked.js</a> is used for compiling Markdown, so its documentation should be
consulted when there is a question about how something is rendered.</p>
<h5>Header</h5>
<p>There are, however, some special parts at the start of a post. Let&#39;s look at an example:</p>
<pre><code class="language-markdown">Post Title
tag1, tag2, tag3
time: 21:15 Europe/Helsinki
description: Example post
image: https://example.com/example.jpg
Hello, and welcome to this example post!
</code></pre>
<p>The first line in a file is the post title. After that, optionally, come post tags on their own line,
separated by a comma. Post tags are used as-is, so they also should contain only filename and URL safe
content, and no spaces.</p>
<p>After the tags are <em>headers</em>. Headers are a collection of key-value pairs, separated by a colon. They
can contain various metadata about the post, and the user can implement their own headers by
customizing the post view. There are some predefined headers:</p>
<ul>
<li><code>time</code> Defines the time when the post was written. The format is <kbd>hh:mm TZ</kbd>, where the
first part is the local time using a 24 hour clock, and the second is the
<a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">local timezone identifier</a>.</li>
<li><code>description</code> A description of the post that is used for link embeds on external services.</li>
<li><code>image</code> An image that is used for link embeds on external services. Should be on the smaller side
and must be an absolute URL.</li>
</ul>
<h5>Splitting</h5>
<p>Often it is not sensible to show the whole post in list views with many posts. In this case the post
can be divided into two pieces. In the list view, only the first part is shown, and in the individual
post page, both parts are shown.</p>
<p>To do this, insert <kbd>&lt;!-- SPLIT --&gt;</kbd> in the post. It&#39;s recommended to put this on its
own line and not inside any HTML or Markdown content that would get broken when split apart.</p>
</div></article></main><section id="sidebar"><nav id="tags" aria-label="Tags"><ul><li><a href="/scriptorium_blog/tag/hex.html" style="font-size:100%;">hex</a></li></ul></nav><nav id="archives" aria-label="Archives"><ul><li><a href="/scriptorium_blog/archive/2024.html">2024</a><ul><li><a href="/scriptorium_blog/archive/2024/04.html">April (2)</a></li></ul></li></ul></nav></section><footer><p>© Mikko Ahlroth · Powered by: <a href="https://gleam.run/">Gleam</a>, <a href="https://hexdocs.pm/lustre">Lustre</a>, <a href="https://gitlab.com/Nicd/scriptorium">Scriptorium</a></p></footer></body></html>