File size: 1,706 Bytes
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43f8c77
 
 
94753b6
 
 
 
 
 
 
 
43f8c77
 
 
 
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
43f8c77
94753b6
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
 * @file Jinja templating engine
 *
 * A minimalistic JavaScript reimplementation of the [Jinja](https://github.com/pallets/jinja) templating engine,
 * to support the chat templates. Special thanks to [Tyler Laceby](https://github.com/tlaceby) for his amazing
 * ["Guide to Interpreters"](https://github.com/tlaceby/guide-to-interpreters-series) tutorial series,
 * which provided the basis for this implementation.
 *
 * See the [Transformers documentation](https://huggingface.co/docs/transformers/main/en/chat_templating) for more information.
 *
 * @module index
 */
import { tokenize } from "./lexer";
import { parse } from "./parser";
import { Environment, Interpreter } from "./runtime";
import type { Program } from "./ast";
import type { StringValue } from "./runtime";
import { range } from "./utils";

export class Template {
	parsed: Program;

	/**
	 * @param {string} template The template string
	 */
	constructor(template: string) {
		const tokens = tokenize(template, {
			lstrip_blocks: true,
			trim_blocks: true,
		});
		this.parsed = parse(tokens);
	}

	render(items: Record<string, unknown>): string {
		// Create a new environment for this template
		const env = new Environment();

		// Declare global variables
		env.set("false", false);
		env.set("true", true);
		env.set("raise_exception", (args: string) => {
			throw new Error(args);
		});
		env.set("range", range);

		// Add user-defined variables
		for (const [key, value] of Object.entries(items)) {
			env.set(key, value);
		}

		const interpreter = new Interpreter(env);

		const result = interpreter.run(this.parsed) as StringValue;
		return result.value;
	}
}

export { Environment, Interpreter, tokenize, parse };