Skip to content

v0.2.3

Latest

Choose a tag to compare

@edadma edadma released this 08 May 02:23
· 36 commits to stable since this release

Highlights

First proper release in three years. The parser is rewritten on top of Scala parser-combinators, the language has a real Scala 3.8.3 cross-build, and the renderer covers the any-data shape (Map / List / scalar) end-to-end. 316 / 316 tests green across JVM, Scala.js, and Scala Native.

What changed since v0.1.14

Parser

  • Tag parser rewritten on parser-combinators. Cleaner precedence, better error reporting, and the original recursive-descent quirks are gone. Long history of intermediate "rewrite tag parser" commits collapsed into a stable result.
  • Comment syntax: {{ // a comment }} (one-line, swallows to the closing }}).

Language features

  • {{ define name }} … {{ end }} / {{ block name expr }} — define/use named blocks. Used by juicer's two-pass baseof / file / folder rendering.
  • {{ for x <- xs }} … {{ end }} — list iteration; {{ for k, v <- m }} … {{ end }} for maps.
  • {{ if cond }} … {{ elif … }} … {{ else }} … {{ end }} — full conditional.
  • {{ with expr }} … {{ end }} — bind a sub-context.
  • {{ match expr }} {{ case a }} … {{ case b }} … {{ end }} — pattern match.
  • {{ x := expr }} — local variable assignment.
  • {{ partial 'name' . }} — pluggable partials via a TemplateLoader.
  • and, or, not — logical operators.
  • {{ x | filter … }} — pipe syntax for any 1+ arity function.

Renderer

  • Recursive any-data render path. Lists nest, maps print as field-value pairs, scalars do the right thing. The earlier renderer flattened in places it shouldn't.
  • Per-page global context alongside data — partials and sub-contexts can read top-level page data without explicit threading.
  • Hardcoded HTML-escaping in a few places where it was wrong; configurable via the renderer's data callbacks where it makes sense.

Builtins

  • URL helpers: relURL, absURL, urlEscape. Cross-platform — no java.nio.file.Paths.
  • Markdown integration: markdownify renders a string through the markdown lib.
  • Emoji: emojify substitutes :smile: → 😄 via the emoji lib.
  • Strings: upper, lower, trim, replace, split, join, startsWith, endsWith, contains, indexOf, substring, reverse, length, isEmpty, nonEmpty.
  • Lists: head, tail, first, last, append, prepend, compact, distinct, reverse, sort, length, isEmpty, nonEmpty.
  • Maths: abs, plus the usual arithmetic via operators in expressions.
  • Date/time: built on java.time.
  • Regex: matchRE, findRE (with capture groups in 0.2.3), findAllRE, replaceRE, splitRE.
  • Files: fileExists.
  • Debug: context, type for inspecting the data shape inline.

Build / cross-platform

  • Scala 3.8.3 cross-build (was 2.13).
  • Cross-published on JVM, Scala.js, Scala Native. Test data migrated from YAML literals to JSON so the JS / Native builds don't pull in scala-yaml.
  • All compiler warnings eliminated (3.4 migration sweep).
  • Main.scala routes args through cross_platform.processArgs so the CLI works the same on every backend.
  • Dependency baseline: char_reader 0.1.27, cross_platform 0.1.6.

Bug fixes (since 0.2.x began)

  • 0.2.3 — findRE no longer drops capture groups; recursive any-data renderer no longer flattens nested structures.
  • 0.2.2 — version refs in Main.scala and the README synced.
  • Two bugs surfaced by an end-to-end coverage pass landed in 0.2.1.

Compatibility

  • Scala 3.8.3, sbt 1.12.x.
  • Cross-built on JVM, Scala.js, and Scala Native.
  • 316 / 316 tests green across all three platforms.

Used by

  • juicer (the static site generator powering juicer.run) — squiggly is its template engine.

Full changelog: v0.1.14...v0.2.3