---- -- A string with substitutions, partially implements the `AST` interface. -- -- Is automatically "splatted" into multiple expressions when the containing -- `Cell` is evaluated: the original string (str=), but with with substitution -- markers like `#{1}`, `#{2}` and so on and one expression for each substitution. -- -- `#` symbols in the original string are escaped to `##`. -- -- @classmod TemplateString import Constant from require 'alv.result' -- @type TemplateString class TemplateString --- AST interface -- -- `TemplateString` partially implements the `AST` interface. -- @section ast --- create a clone with its own identity. -- -- creates a clone of this TemplateString by cloning all child expressions -- recursively. -- -- @tparam Tag parent -- @treturn TemplateString clone: (parent) => children = [child\clone parent for child in *@children] @@ @string, children --- stringify this TemplateString. -- -- if `depth` is passed, does not faithfully recreate the original string but -- rather create useful debug output. -- -- @tparam[opt] int depth the maximum depth, defaults to infinite -- @treturn string the exact string this TemplateString was parsed from stringify: (depth=-1) => children = ['#' .. child\stringify depth for child in *@children] str = @@.subst @.string!, (i) -> '#' .. @children[i]\stringify depth '#"' .. str .. '"' --- static functions -- @section static new: (@string, @children) => --- apply substitutions to a template string. -- -- This also reverses the escaping that the parser applied. -- -- @classmethod -- @tparam string str the evaluated `TemplateString.string` -- @tparam function fn function called with index i to obtain string to substitute -- @treturn string @subst: (str, fn) -> str = str\gsub '##', '#' str\gsub '#{(%d+)}', (i) -> fn tonumber i --- parse a TemplateString (for parsing with Lpeg). -- -- @classmethod -- @tparam {string|AST,...} pieces -- @treturn TemplateString @parse: (...) => string = '' children = {} i = 1 for elem in *{...} if 'string' == type elem string ..= elem\gsub '#', '##' else table.insert children, elem string ..= '#{' .. #children .. '}' string = Constant.str string @@ string, children { :TemplateString }