zena:template-strings-array

zena
import {…} from 'zena:template-strings-array';

Classes

TemplateStringsArray

zena
final class TemplateStringsArray

Represents the string literals in a tagged template expression.

When you write tag\Hello ${name}!`` the tag function receives:

  • strings: TemplateStringsArray containing ["Hello ", "!"]
  • values: array containing [name]

Key properties:

  • Immutable: The strings array cannot be modified.
  • Cached: The same TemplateStringsArray instance is reused across invocations of the same tagged template expression.
  • Interleaved: Strings and values alternate, with strings on both ends. For \a${x}b${y}c`: strings = ["a", "b", "c"], values = [x, y]. This means there is always strings.length == values.length + 1`.

The raw property provides access to the raw (unescaped) string literals, where escape sequences like \\n appear as two characters (\ and n) rather than being interpreted as a newline.

Example:

text
let tag = (strings: TemplateStringsArray, values: FixedArray<anyref>): String => {
  // strings[0] = "Line 1\nLine 2" (newline interpreted)
  // strings.raw[0] = "Line 1\\nLine 2" (backslash-n literal)
  return strings[0];
};
tag\`Line 1\\nLine 2\`;
Constructors
zena
new(strings: ImmutableArray<String>, raw: ImmutableArray<String>)
#
Properties
zena
raw: ImmutableArray<String> { get; }
#

The raw string literals with escape sequences preserved.

zena
length: i32 { get; }
#

The number of string literals. This is always one more than the number of interpolated values.

Operators
zena
operator [](index: i32): String
#

Access a cooked string literal by index.

Type aliases

TemplateTag

zena
type TemplateTag<T> = (strings: TemplateStringsArray, values: FixedArray<anyref>) => T

Type alias for template tag functions.

Example usage:

text
const html: TemplateTag<String> = (strings, values) => {
  // strings[0], strings[1], etc. are the literal parts
  // values[0], values[1], etc. are the interpolated expressions
  // strings.raw gives access to raw (unescaped) strings
  return '...';
};

const result = html`<div>${name}</div>`;

Functions

dedent

zena
function dedent(strings: TemplateStringsArray, values: FixedArray<String>): String

A template tag that strips the source indentation from a multi-line template literal, so a block of text can be written at the indentation of the code around it and still come out flush left:

text
let usage = dedent`
  zena build <entry>
    -o <path>   where to write the module
`;
// "zena build <entry>\n  -o <path>   where to write the module"

The rules:

  • The opening line is dropped, along with its line break, when it is blank — which it is in the form above, where the content starts on the line after the backtick. The closing line is dropped the same way. Neither is dropped when it has content on it: a line with content is a line, and it takes part in the rule below like any other.
  • The indentation removed from every remaining line is the longest common prefix of the indentation of the lines that have content on them. It is compared byte for byte, so a file that mixes tabs and spaces dedents by what its lines actually share rather than by a count that assumes a tab width.
  • Blank lines are ignored when computing that prefix and come out empty, so a line of leftover trailing spaces is not what decides the result.
  • Interpolated values are inserted verbatim. A value containing newlines is not re-indented, and its newlines do not start lines that participate in the computation: only indentation written in the literal counts. A line that starts with a value is a content line, and the whitespace before the value is its indentation.

Interpolations must be Strings — a tag receives its values without the conversion ${} performs in an untagged template literal, so write dedent`count: ${`${n}`}` (or i32ToString(n)) for a number.

The text dedented is the cooked strings, so an escape is processed before the indentation is measured: a \n written as an escape breaks a line here exactly as a real newline does. Today that is theory rather than practice — a tagged template whose literal contains any escape sequence fails to compile, whatever the tag (see elematic/zena#84).