#api/space-lua #maturity/experimental

Enables defining simple custom syntax extensions to Markdown. Custom syntax lets you define new delimiter-based regions (both inline and block) that are recognized by the parser and can be styled or rendered as Space Lua/Widget|Widgets.

API

syntax.define(spec)

Registers a custom syntax extension. The extension will be active after the next editor state rebuild (e.g. on page reload or config change).

spec is a table that can contain: * name (required): AST node name (e.g. "LatexInline") * startMarker (required): Regex string for start delimiter (e.g. "\\$") * endMarker (required): Regex string for end delimiter * mode (required): "block" or "inline" * CSS styling used when not Live Preview|Live Previewing: * startMarkerClass: CSS class for the start marker * bodyClass: CSS class for the body content between markers * endMarkerClass: CSS class for the end marker * CSS styling applied when Live Previewing: * renderClass: CSS class applied to the rendered widget * render (required): Callback function(body, pageName) returning API/widget|widget content for live preview.

Escaping

Within the body of an inline syntax extension, backslash (\) acts as an escape character. Use \ before the end marker to include it literally in the body. The render callback receives the raw body text with escape sequences intact; the renderer is responsible for unescaping if needed.

Example

Define an inline LaTeX syntax using $ delimiters:

syntax.define {
  name = "LatexInline",
  startMarker = "\\$(?!\\{)",
  endMarker = "\\$(?!\\{)",
  mode = "inline",
  --startMarkerClass = "sb-latex-mark",
  --bodyClass = "sb-latex-body",
  --endMarkerClass = "sb-latex-mark",
  renderClass = "sb-latex-inline-preview",
  render = function(body, pageName)
    return widget.html(dom.i { body })
  end
}

This will recognize $E=mc^2$ in your text and render the body using the provided callback (in this case it just makes it italic): \(E=mc^2\).

note Note The (?!\{) negative lookahead prevents $ from clashing with the ${expr} Lua expression syntax. Without it, $math ${expr} more$ would prematurely close at the $ in ${expr}.

A block-level variant using $$ fences:

syntax.define {
  name = "LatexBlock",
  startMarker = "^\\|\\|$",
  endMarker = "^\\|\\|$",
  mode = "block",
  startMarkerClass = "sb-latex-mark",
  bodyClass = "sb-latex-body",
  endMarkerClass = "sb-latex-mark",
  render = function(body, pageName)
    return widget.htmlBlock(dom.marquee { body })
  end
}

This recognizes fenced blocks:

|| E = mc^2 ||

You can style these with Space Style:

.sb-latex-mark {
  color: cyan;
}
.sb-latex-body {
  color: gray;
}