Repository navigation
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-passbaseof/file/folderrendering.{{ 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 aTemplateLoader.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
globalcontext alongsidedata— 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 — nojava.nio.file.Paths. - Markdown integration:
markdownifyrenders a string through the markdown lib. - Emoji:
emojifysubstitutes: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,typefor 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.scalaroutes args throughcross_platform.processArgsso 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 —
findREno longer drops capture groups; recursive any-data renderer no longer flattens nested structures. - 0.2.2 — version refs in
Main.scalaand 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