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.
92 lines
2.1 KiB
92 lines
2.1 KiB
2 years ago
|
import { TokenStream } from './token_stream.mjs';
|
||
2 years ago
|
|
||
|
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;
|
||
2 years ago
|
|
||
|
if (isLastLine && !line.length) break;
|
||
|
|
||
2 years ago
|
const formatString = isLastLine ? '%s' : '%s\\n';
|
||
|
|
||
|
buffer += `printf '${formatString}' '${line.replace("'", "'\\''")}';\n`;
|
||
|
}
|
||
|
|
||
|
return buffer;
|
||
|
}
|
||
|
}
|
||
2 years ago
|
|
||
|
/* Convenience function for quickly rendering a file */
|
||
|
export function renderFile(fileName) {
|
||
|
const tp = new TemplateEngine();
|
||
|
return tp.render(fileName);
|
||
|
}
|