Skip to main content

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 typeExamplePurpose
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 null or undefined is 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.

  • is performs strict equality (===).
  • + concatenates values after string conversion. null and undefined become 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.