💾 Archived View for sdf.org › rsdoiel › blog › 2020 › 10 › 19 › Assemble-pages.html captured on 2023-06-14 at 14:28:48.
⬅️ Previous capture (2023-03-20)
-=-=-=-=-=-=-
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <meta name="language" content="EN"> <title>Assemble-pages</title> <link rel="stylesheet" type="text/css" href="/printfonts/print.css" media="print" /> <link rel="stylesheet" type="text/css" href="/webfonts/fonts.css" media="screen" /> <link rel="stylesheet" type="text/css" href="/css/site.css" media="screen" /> <link rel="stylesheet" type="text/css" href="/css/tables.css" media="screen" /> <link title="RSS feed for rsdoiel's blog" rel="alternate" type="application/rss+xml" href="https://rsdoiel.github.io/rss.xml" /> <meta name="keywords" content="Oberon-07, portable, markdown, pandoc, frontmatter"> <link rel="alternative" type="application/markdown" href="/blog/2020/10/19/Assemble-pages.md"> <link rel="search" type="application/opensearchdescription+xml" title="Robert's Rambling Search Engine" href="search.osdx"> </head> <body> <nav> <ul> <li><a href="/">R. S. Doiel</a></li> <li><a href="/about.html">About</a></li> <li><a href="/blog/">Blog</a></li> <li><a href="/cv.html">CV</a></li> <li><a href="https://github.com/rsdoiel">GitHub</a></li> <li><a href="/library-terminology.html">Library Jargon</a></li> <li><a href="/presentations.html">Presentations</a></li> <li><a href="/projects.html">Projects</a></li> <li><a href="/resume.html">Resume</a></li> <li><a href="/search.html">Search</a></li> <li><a href="/series/">Series</a></li> </ul> </nav> <section> <article> <a data-pocket-label="pocket" data-pocket-count="none" class="pocket-btn" data-lang="en"></a> <script type="text/javascript">!function(d,i){if(!d.getElementById(i)){var j=d.createElement("script");j.id=i;j.src="https://widgets.getpocket.com/v1/j/btn.js?v=1";var w=d.getElementById(i);d.body.appendChild(j);}}(document,"pocket-btn-js");</script> <h1 id="assembling-pages">Assembling pages</h1> <p>This is the thirteenth post in the <a href="https://rsdoiel.github.io/blog/2020/04/11/Mostly-Oberon.html">Mostly Oberon</a> series. Mostly Oberon documents my exploration of the Oberon Language, Oberon System and the various rabbit holes I will inevitably fall into.</p> <h2 id="pandoc-and-json">Pandoc and JSON</h2> <p>I use <a href="https://pandoc.org">Pandoc</a> 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 <a href="https://lunrjs.com">LunrJS</a>. <a href="AssemblePage.Mod">AssemblePage</a> automates this process.</p> <p>Example shell usage:</p> <pre><code> AssemblePage MyText.txt \ metadata=document.json \ document=document.md pandoc --from markdown --to html \ --metadata-file document.json \ --standalone \ document.md >MyText.html </code></pre> <h2 id="source-code-for-assemblepage.mod">Source code for <strong>AssemblePage.Mod</strong></h2> <pre><code> 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. </code></pre> <h3 id="next-previous">Next, Previous</h3> <ul> <li>Next <a href="../../11/27/Dates-and-Clock.html">Dates & Clock</a></li> <li>Previous <a href="../../10/03/Oberon-to-markdown.html">Oberon To Markdown</a></li> </ul> </article> </section> <footer> <p>copyright © 2016 - 2023 R. S. Doiel<br /> <a href="/rssfeed.html">RSS</a> feeds and website built with <a href="https://rsdoiel.github.io/pttk">pttk</a>, Bash, Make and <a href="https://pandoc.org">Pandoc</a>.</p> </footer> <!-- START: PrettyFi from https://github.com/google/code-prettify --> <script> /* We want to add the class "prettyprint" to all the pre elements */ var pre_list = document.querySelectorAll("pre"); pre_list.forEach(function(elem) { elem.classList.add("prettyprint"); elem.classList.add("linenums");/**/ elem.classList.add("json"); /**/ }); </script> <style> li.L0, li.L1, li.L2, li.L3, li.L4, li.L5, li.L6, li.L7, li.L8, li.L9 { color: #555; list-style-type: decimal; } </style> <link rel="stylesheet" type="text/css" href="/css/prettify.css"> <script src="https://cdn.jsdelivr.net/gh/google/code-prettify@master/loader/run_ prettify.js"></script> <!-- END: PrettyFi from https://github.com/google/code-prettify --> </body> </html>