This package processes KumaScript macros in a source string.
It includes modified versions of the KumaScript macros and KumaScript engine code in https://github.com/mdn/yari. This mdn/yari code is used under the MPL 2.0 license.
import { render } from "mdn-kumascript";
const source = `<p>The {{cssxref("margin")}} property and the {{experimental_inline}} note and also the {{cssref}} sidebar, and also the {{cssxref("border", "border syntax", "#syntax")}} property, and also the {{embedinteractiveexample("the-link")}}</p>`;
const environment = { frontMatter: {} };
const output = await render(source, environment);
console.log(output);
/*
{
markup: '<p>The <a href="/Web/CSS/margin"><code>margin</code></a> property and the <abbr class="icon icon-experimental" title="Experimental. Expect behavior to change in the future."><span class="visually-hidden">Experimental</span></abbr> note and also the sidebar, and also the <a href="/Web/CSS/border#syntax"><code>border syntax</code></a> property, and also the </p>',
frontMatter: {
'interactive-example': 'https://interactive-examples.mdn.mozilla.net/the-link'
},
errors: []
}
*/
This package exports a single asynchronous function render()
, which takes two arguments:
source
: a string that may contain KumaScript macrosenvironment
: an object with a single propertyfrontMatter
, which is an object containing the page front matter. At the moment, in fact, the front matter is not used as an input parameter, but some macros may need it later.
The function returns a Promise
that resolves to an object with three properties:
markup
: a string representing the originalsource
, but with macros expanded into HTML.frontMatter
: the same front matter object that was passed in, with any modifications made by macroserrors
: an array of nonfatal errors encountered during macro processing.
This package is really in two parts:
- the engine, that finds macro calls, arranges for the right macro to be called with the right arguments, and assembles the result.
- the individual macros
The engine is ported from https://github.com/mdn/yari. In particular:
- parser.js, which parses the source to find macro calls and their arguments, is unchanged
- errors.ts, which implements error messages, is slightly modified to remove errors that seem to depend on the website
- render.ts, which orchestrates the invocation of macros for a given source, is modified top remove some features we don't need. This module implements the top-level
render()
function, so is the entry point to the module. - templates.ts is mostly rewritten, as it forms the interface between the engine and individual macros, so the Yari version is highly dependent on the EJS implementation used in Yari.
In this package, individual macros are implements as separate modules under the /macros directory. Each module must export an async function executeMacro()
, which takes two arguments:
args
: an array containing the arguments that were passed to the macro in the source invocationenv
: an object containing a single propertyfrontMatter
, which is an object containing the page front matter (It's quite likely that some macros will eventually need more environment than this, so we will probably extend thisenv
object).
The executeMacro()
function returns a Promise
that resolves to the expansion of the macro in the source. Macros may also modify the frontMatter
argument: if they do, these modifications will appear in the object returned by the top level render()
function.
After implementing a macro module, you make it available to the engine by adding its executeMacro()
function to the renderers
map in the renderers.js
module.
Tests are provided for both the framework and for individual macros. To run tests:
npm run test