Assembling pages
This is the thirteenth post in the Mostly Oberon 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 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. AssemblePage automates this process.
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
- Previous Oberon To Markdown