A shell script template engine for generating HTML markup
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

91 lines
2.1 KiB

import { TokenStream } from './token_stream.mjs';
export class TemplateEngine {
async render(fileName) {
const ts = new TokenStream();
await ts.loadFile(fileName);
let buffer = '';
while (!ts.eof()) {
const token = ts.next();
switch (token.type) {
case 'raw':
buffer += this._renderRaw(token.value);
break;
case 'inline':
buffer += this._renderInline(token.value);
break;
case 'inline_unescaped':
buffer += this._renderInlineUnescaped(token.value);
break;
case 'inline_statement':
buffer += this._renderInlineStatement(token.value);
break;
case 'inline_statement_unescaped':
buffer += this._renderInlineStatementUnescaped(token.value);
break;
case 'statement':
buffer += this._renderStatement(token.value);
break;
case 'comment':
buffer += this._renderComment(token.value);
break;
default:
throw new Error(`Unrecognized token: ${token.type}`);
}
}
return buffer;
}
_renderComment(value) {
return `# ${value}\n`;
}
_renderStatement(value) {
return `${value}\n`;
}
_renderInline(value) {
return `printf '%s' "${value}" | jq -Rrj @html;\n`;
}
_renderInlineUnescaped(value) {
return `printf '%s' "${value}";\n`;
}
_renderInlineStatement(value) {
return `printf '%s' "$(${value})" | jq -Rrj @html;\n`;
}
_renderInlineStatementUnescaped(value) {
return `printf '%s' "$(${value})";\n`;
}
_renderRaw(value) {
const lines = value.split('\n');
let buffer = '';
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const isLastLine = i === lines.length - 1;
if (isLastLine && !line.length) break;
const formatString = isLastLine ? '%s' : '%s\\n';
buffer += `printf '${formatString}' '${line.replace("'", "'\\''")}';\n`;
}
return buffer;
}
}
/* Convenience function for quickly rendering a file */
export function renderFile(fileName) {
const tp = new TemplateEngine();
return tp.render(fileName);
}