Assembling pages
This is the thirteenth post in the Mostly Oberon[1] series. Mostly Oberon documents my exploration of the Oberon Language, Oberon System and the various rabbit holes I will inevitably fall into.
Pandoc and JSON
I use Pandoc[2] to process Markdown documents. I like to keep my front matter in JSON rather than Pandoc's YAML. Fortunately Pandoc does support working with JSON as a metadata file include. Normally I would manually split the JSON front matter and the rest of the markup into two separate files, then process with Pandoc and other tooling like LunrJS[3]. AssemblePage[4] automates this process.
3: https://lunrjs.com (https://lunrjs.com)
4: AssemblePage.Mod
Example shell usage:
AssemblePage MyText.txt \
metadata=document.json \
document=document.md
pandoc --from markdown --to html \
--metadata-file document.json \
--standalone \
document.md >MyText.html
Source code for AssemblePage.Mod
MODULE AssemblePage;
IMPORT Out, Strings, Files, Args := extArgs;
VAR
srcName, metaName, docName : ARRAY 1024 OF CHAR;
(* FrontMatter takes a "read" Rider, r, and a "write" Rider "w".
If the first character read by r is an opening curly bracket
(the start of the front matter) it writes it out with w, until
it finds a matching closing curly bracket or the file ends. *)
PROCEDURE FrontMatter*(VAR r : Files.Rider; VAR w : Files.Rider);
VAR c : BYTE; cCnt : INTEGER;
BEGIN
(* Scan for opening JSON front matter *)
cCnt := 0;
REPEAT
Files.Read(r, c);
IF r.eof = FALSE THEN
IF c = ORD("{") THEN
cCnt := cCnt + 1;
ELSIF c = ORD("}") THEN
cCnt := cCnt - 1;
END;
Files.Write(w, c);
END;
UNTIL (r.eof = TRUE) OR (cCnt = 0);
IF cCnt # 0 THEN
Out.String("ERROR: mis matched '{' and '}' in front matter");
ASSERT(FALSE);
END;
END FrontMatter;
(* CopyIO copies the characters from a "read" Rider to a "write" Rider *)
PROCEDURE CopyIO*(VAR r : Files.Rider; VAR w: Files.Rider);
VAR c : BYTE;
BEGIN
REPEAT
Files.Read(r, c);
IF r.eof = FALSE THEN
Files.Write(w, c);
END;
UNTIL r.eof = TRUE;
END CopyIO;
PROCEDURE ProcessParameters(VAR sName, mName, dName : ARRAY OF CHAR);
VAR
arg : ARRAY 1024 OF CHAR;
i, res : INTEGER;
BEGIN
mName := "document.json";
dName := "document.txt";
arg := "";
FOR i := 0 TO (Args.count - 1) DO
Args.Get(i, arg, res);
IF Strings.Pos("metadata=", arg, 0) = 0 THEN
Strings.Extract(arg, 9, Strings.Length(arg), mName);
ELSIF Strings.Pos("document=", arg, 0) = 0 THEN
Strings.Extract(arg, 9, Strings.Length(arg), dName);
ELSE
Strings.Extract(arg, 0, Strings.Length(arg), sName);
END;
END;
END ProcessParameters;
PROCEDURE AssemblePage(srcName, metaName, docName : ARRAY OF CHAR);
VAR
src, meta, doc : Files.File;
reader, writer : Files.Rider;
BEGIN
src := Files.Old(srcName);
IF src # NIL THEN
Files.Set(reader, src, 0);
IF metaName # "" THEN
meta := Files.New(metaName);
Files.Register(meta);
Files.Set(writer, meta, 0);
FrontMatter(reader, writer);
Files.Close(meta);
END;
IF docName # "" THEN
doc := Files.New(docName);
Files.Register(doc);
Files.Set(writer, doc, 0);
CopyIO(reader, writer);
Files.Close(doc);
END;
ELSE
Out.String("ERROR: Could not read ");Out.String(srcName);Out.Ln();
ASSERT(FALSE);
END;
Files.Close(src);
END AssemblePage;
BEGIN
ProcessParameters(srcName, metaName, docName);
AssemblePage(srcName, metaName, docName);
END AssemblePage.
Next, Previous
- Next Dates & Clock[5]
- Previous Oberon To Markdown[6]
6: ../../10/03/Oberon-to-markdown.html
Response: text/gemini
| Original URL | gopher://sdf.org/0/users/rsdoiel/blog/2020/10/19/Assemble... |
|---|---|
| Content-Type | text/gemini; charset=utf-8 |