template inclusion

pull/249/head
xwashere 6 months ago
parent 3660b6cc8b
commit 8a5684c4ec
No known key found for this signature in database
GPG Key ID: 042F8BFA1B0EF93B

@ -13,8 +13,56 @@ export class TemplateError extends Error {
let format = '';
if (this.range) {
format += this.range.file.code + '\n';
format += ' '.repeat(this.range.from) + '^' + '~'.repeat(Math.max(this.range.to - this.range.from, 0)) + '\n';
let fcol = 0;
let fline = 1;
let pstart = 0;
for (let i = 0; i < this.range.from; i++) {
fcol++;
if (this.range.file.code[i] == '\n') {
fline++;
fcol = 0;
pstart = i + 1;
}
}
let tcol = fcol;
let tline = fline;
let pend = pstart;
for (let i = this.range.from; i < this.range.to; i++) {
tcol++;
if (this.range.file.code[i] == '\n') {
tline++;
tcol = 0;
pend = i + 1;
}
}
pend = Math.max(this.range.file.code.indexOf('\n', pend), pend);
if (fline == tline) {
format += `${fline.toString().padStart(5, ' ')} | ${this.range.file.code.substring(pstart, pend)}\n`;
format += `${fline.toString().padStart(5, ' ')} | ${' '.repeat(fcol)}^${'~'.repeat(Math.max(tcol - fcol, 0))}\n`;
} else {
let lines = this.range.file.code.substring(pstart, pend).split('\n');
format += ` | /${'~'.repeat(lines[0].length)}v\n`;
for (let i = fline; i < fline + 5 && i <= tline; i++) {
format += `${i.toString().padStart(5, ' ')} | | ${lines[i - fline]}\n`;
}
if (fline + 5 < tline) {
format += ` | | ...\n`;
for (let i = tline - 4; i <= tline; i++) {
format += `${i.toString().padStart(5, ' ')} | | ${lines[i - fline]}\n`;
}
}
format += ` | \\${'~'.repeat(tcol + 1)}^\n`;
}
}
format += `${this.name}: ${this.message}`;

@ -1,4 +1,7 @@
import { TemplateOp, TemplateSource } from 'ass';
import fs from 'fs';
import { TemplateSyntaxError } from './error';
enum TokenType {
@ -97,6 +100,10 @@ function getTemplateTokens(src: string): TemplateToken[] {
pos++;
buf += findReplacement();
pos--; continue;
} else if (src[pos] == '\n') {
pos++;
for (; pos < src.length && (src[pos] == ' ' || src[pos] == '\t'); pos++);
pos--; continue;
} else {
buf += src[pos];
continue;
@ -203,7 +210,7 @@ export function prepareTemplate(src: string): TemplateOp {
} else if (pos < tokens.length) {
if (tokens[pos].type == TokenType.T_CLOSE) {
throw new TemplateSyntaxError('Template name missing', { file: file, from: tokens[pos - 1].from, to: tokens[pos].to });
} else throw new TemplateSyntaxError('Expected template name', { file: file, from: tokens[pos].from, to: tokens[pos].to });
} else throw new TemplateSyntaxError('Expected template name', { file: file, from: tokens[pos].from, to: tokens[pos].to });
} else throw new TemplateSyntaxError('Unexpected end of file');
if (pos < tokens.length && tokens[pos].type == TokenType.PIPE) {
@ -253,6 +260,26 @@ export function prepareTemplate(src: string): TemplateOp {
stackDrop();
// include is executed early
if (name.toLowerCase() == 'include') {
if (nargs['file'] != null) {
// TODO: this NEEDS to be restricted before ass 0.15.0 is released
// its extremely insecure and should be restricted to things
// set by operators, users can have their own template inclusion
// thing that doesnt depend on reading files
if (typeof nargs['file'] == 'string') {
if (fs.existsSync(nargs['file'])) {
let template = fs.readFileSync(nargs['file'], { encoding: 'utf-8' });
let tl = prepareTemplate(template);
return tl;
} else throw new TemplateSyntaxError('File does not exist', { file: file, from: tokens[start].from, to: tokens[pos - 1].to});
} else throw new TemplateSyntaxError('Include directive can not contain templates', { file: file, from: tokens[start].from, to: tokens[pos - 1].to});
} else throw new TemplateSyntaxError(`Bad include directive`, { file: file, from: tokens[start].from, to: tokens[pos - 1].to});
}
return {
op: name.toLocaleLowerCase(),
named: nargs,

Loading…
Cancel
Save