Syntax and Logic
Lis Novel includes a built-in prompt template language. Tags are wrapped in { and } and can be expressions, control blocks, or comments.
Template structure
| Tag type | Example | Purpose |
|---|---|---|
| Expression | {scene.fullTitle} | Insert a value or function result. |
| Control flow | {#if ...} / {#endif} | Show or hide sections based on logic. |
| Comment | {! ... !} | Notes for yourself; removed from output. |
Whitespace around tags is preserved unless removed by your own markup.
Comments
Comments are stripped from the output.
Enter the castle.{! Remind the model this is a stealth sequence. !}
Expressions
Expression tags output the value of an expression.
Identifiers
- Identifiers are case-sensitive and resolve to variables or functions.
- Use dot notation to reach nested data:
{scene.fullTitle}.
String literals
Strings can use single or double quotes. Newlines inside string literals are not supported.
{"Shadow"}
{'Shadow'}
Numeric literals
The prompt template language supports integers only.
{3}
Function calls
Call helpers with name(arg1, arg2, ...).
- Arguments can be literals, identifiers, member access, or other function calls.
- Any argument that evaluates to
nullorundefinedis omitted before the function is invoked, which can shift positions. - Functions used as a standalone expression are auto-invoked, so
{scene.fullText}is equivalent to{scene.fullText()}. - Objects and numbers are stringified using standard JavaScript string conversion. Many Lis Novel helpers override this to output XML.
{wordCount(scene.fullText)}
{chapter.title(chapter.next)}
Operators
The prompt template language supports a small set of infix operators inside expressions.
isperforms strict equality (===).+concatenates values after string conversion.nullandundefinedbecome empty strings.
{hero.role is "antagonist"}
{"Agent " + hero.codename + " reporting."}
Truthiness
Conditionals use JavaScript truthiness: empty strings, 0, null, undefined, and false are falsy; everything else is truthy.
Control flow blocks
{#if isGreaterThan(wordCount(scene.fullText), 1000)}
Flag as long-form scene.
{#elseif isGreaterThan(wordCount(scene.fullText), 200)}
Flag as medium scene.
{#else}
Keep as short scene.
{#endif}
{#if}requires a condition.{#elseif}can appear zero or more times.{#else}is optional and must be the final branch.- Blocks may nest; each
{#if}must be closed by{#endif}.
XML and markup
The prompt template language treats XML, HTML, and other markup as plain text. It does not parse or escape markup on its own. This makes it safe to emit <scene>, <novel>, and <lore> XML directly in prompts.
Syntax errors
Unterminated tags, malformed expressions, or unmatched control-flow blocks cause errors. Keep tags balanced and expressions valid.