Lavash.Template.Walker (Lavash v0.4.0-rc.5)

Copy Markdown View Source

Shared tree-walker for HEEx token transformers.

The LV 1.2 parser produces a tree of:

  • {:block, type, name, attrs, children, open_meta, close_meta} where type is :tag | :local_component | :remote_component | :slot
  • {:self_close, type, name, attrs, meta} — void/self-closing tags
  • {:body_expr, code, meta}{...} inline expression
  • {:eex, code, meta}<%= ... %> expression
  • {:eex_block, code, clauses, meta}<%= if x do %>...<% end %> where each clause is {children, end_code, meta}
  • {:text, content, meta}
  • {:eex_comment, content, meta}

Every sub-transformer that wants to walk this tree needs the same boilerplate: dispatch on the kind of node, recurse into children for blocks, recurse into each clause for eex_block, leave leaves alone. This module factors that out behind two callbacks.

Callbacks

walk(nodes, opts)

where opts is a keyword list:

  • :node_callback(node, parent, metadata) -> [node]. Receives the whole node, the parent context, and the threaded metadata. Returns a list (usually one element, sometimes more when a node expands). If omitted, defaults to [node].

  • :attrs_callback(name, attrs, meta, metadata) -> attrs. Receives the tag name + attrs list + opening-tag meta + threaded metadata. Returns the new attrs. The walker stitches the result back into the node. Use this when you want to inject attributes but don't need to rewrite node structure.

  • :metadata — opaque user data threaded through every callback. Sub-transformers stash their config here.

What the walker does for you

  • Recurse into children of :block nodes.
  • Recurse into each clause's children for :eex_block nodes.
  • Track the parent node ({:tag, name, attrs} for the nearest enclosing block) so node_callback can make context-dependent decisions.
  • Leave leaves (:text, :eex, :eex_comment, unknown) alone unless node_callback rewrites them.

Parent shape

The parent passed to node_callback is nil at the top level, or {:tag, name, attrs} describing the immediately enclosing block node. This is sparse on purpose — most callers only care about the parent's tag name + attrs (e.g. "am I inside a <textarea>?", "is my parent already a display-wrapper?").

Summary

Functions

Walks nodes applying the configured callbacks.

Functions

walk(nodes, opts)

Walks nodes applying the configured callbacks.

Returns the transformed node list.