Changelog¶
2026.05.21.2¶
Add
:constructor-class:toliteralizer-callfor language-specific constructor targets.
2026.05.21.1¶
Bumped
literalizerto2026.5.21.Aligned the Pylint configuration more closely with
literalizer.
2026.05.21¶
Bumped
literalizerto2026.5.20.1.
2026.05.20¶
No significant changes.
Next¶
Bumped
literalizerto2026.5.20.
2026.05.18.1¶
Bumped
literalizerto2026.5.18.1.:modifiers: mutis now accepted for Rust. Following upstreamliteralizer2026.5.18.1, which adds aMUTmember toRust.Modifiers, combining:variable-name:with:modifiers: mutrenders a mutable Rust binding (let mut p1 = Playlist::new();) instead of the immutable default (let p1 = Playlist::new();). This unblocks migrating a construct-then-mutate ladder to Rust, where the constructed value is bound and then mutated through the binding.
2026.05.18¶
Bumped
literalizerto2026.5.18.:parameter-names:is now optional on theliteralizer-calldirective. An empty (or omitted) value means the call takes no arguments, rather than the previous behavior where an empty value parsed as a single empty-named argument. Combined with:per-element:over a single-element source and:variable-name:, this renders a no-argument constructor bound to a variable (p1 = Playlist()/let p1 = Playlist();/auto p1 = Playlist();), the construction line thatliteralizer-callcould not previously express – the original motivation of the:variable-name:feature.:variable-name:combined with:per-element:no longer always fails: following upstreamliteralizer2026.5.18it binds the call to the variable when the source produces exactly one call (a single-element list), and still surfaces a cleanExtensionErrorwhen the source produces zero or more than one call.
2026.05.17.1¶
The error raised for an unrecognized
:modifiers:value is now'<value>' is not a valid value. Choose from: ...(listing the modifiers the target language supports), replacing the previousLanguage '<name>' does not support modifier '<value>'.message. A single shared helper now converts these string options to their internal values and raises a cleanExtensionErrorinstead of relying on each option’s input validator to constrain the value.Bumped
literalizerto2026.5.17.1.:wrap-in-file:is now honored by theliteralizer-calldirective. It was previously parsed (and documented as a shared option) but silently ignored, soliteralizer-callalways emitted bare calls. It now passeswrap_in_filethrough toliteralize_call, which upstream2026.5.17.1extended to render a complete, self-contained file: an injected no-op stub for the target function (and any declared refs) precedes the generated calls, with a single reconciled preamble.C# array sequence-format output no longer carries a spurious
using System;/using System.Collections.Generic;line, and the empty array form is now the typed literalnew T[] {}rather thanArray.Empty<T>(), following upstreamliteralizer2026.5.17.1. No directive change was needed; rendered C# array examples update automatically.
2026.05.17¶
Bumped
literalizerto2026.5.17.:variable-name:(with:existing-variable:) onliteralizer-callnow produces a call-result binding forada,bash,c,d,elixir,erlang,forth,fortran,nim,objectivec,systemverilog,tcl, andzig. These languages previously failed the build because they could not bind a call result; they now emit an idiomatic binding (for exampleset my_data [make_widget ...]fortclandauto my_data = make_widget(...);ford), following upstreamliteralizerextendingvariable_formto those languages. No directive change was needed.:heterogeneous-strategy: record(including theautodefault’srecordfallback) and:record-struct-name-prefix:now work forc,csharp,cpp,crystal,d,nim,odin,swift,v, andzig. This follows upstreamliteralizeradding theRECORDstrategy to those languages; the directives expose it generically from the per-language capability flags, so no directive change was needed.:heterogeneous-strategy:now defaults toautoinstead of falling through to literalizer’s per-language default (e.g.errorfor Rust).autorenders the input with its natural representation first – so homogeneous and genuinely map-shaped data render identically to before – and genuinely unrepresentable input still raises, so this only ever turns a representable input that previously broke the build into a representable one. Projects that forcedautoglobally via a directive subclass inconf.pycan drop that override.automakes a representation choice implicitly (recordvstuplevstagged_enumchanges the generated API), so set:heterogeneous-strategy:explicitly – including:heterogeneous-strategy: errorto keep a mixed-scalar collection a hard build failure – when a specific behavior is wanted.The documentation examples now use
sphinx-toolbox’srest-exampledirective, which executes eachliteralizerandliteralizer-calldirective at build time, so the rendered output can no longer drift from the pinnedliteralizerbehavior.
2026.05.16.2¶
Two
:record-shape-names:entries for the same set of keys (in any order) now raise a cleanExtensionErrorinstead of silently keeping only the last name.:heterogeneous-strategy:now acceptsauto. It renders the input with its natural representation first – so homogeneous and genuinely map-shaped data keep their native form – and only if that fails because the data is heterogeneous does it retry with each strategy the target language supports, in the order given by the newliteralizer_heterogeneous_strategy_precedenceconfiguration value (default:record,tuple,tagged_enum,object_variant,variant,union_type,interface). This removes the need to pick a single per-project or per-input strategy.Both directives gain a
:skip-if-unrepresentable:flag. When the input cannot be represented in the target language (including afterautoexhausts its precedence), the directive emits no node instead of failing the build, so a per-language loop can skip the languages a given input does not fit without leaking data-shape concerns into prose.A
HeterogeneousCollectionErrorraised by a concrete (non-auto):heterogeneous-strategy:that cannot represent the input is now surfaced as a cleanExtensionErrorrather than an uncaught traceback.
2026.05.16.1¶
Bumped
literalizerto2026.5.16.1.Both directives gain a
:record-struct-name-prefix:option, which sets the name prefix for the structs/records/dataclasses generated by:heterogeneous-strategy: record(defaultRecord). Available forgo,java,kotlin,python,rust, andscala; using it with another language raises a cleanExtensionError.Both directives gain a
:record-shape-names:option, a semicolon-separated list ofkey1,key2=Nameentries that give specific record shapes a custom name instead of the auto-generated one, following upstreamliteralizeradding therecord_shape_namesconstructor argument. Available forgo,java,kotlin,rust, andscala.InvalidRecordNameErrorfromliteralizer(a:record-shape-names:name that is not a valid PascalCase identifier, or that collides with an auto-generated name or another entry) is now surfaced as a SphinxExtensionErrorrather than an uncaught traceback.The
:heterogeneous-strategy:option now acceptsrecordforpython(generating frozendataclasses.dataclassdeclarations and matching literals), matching upstreamliteralizeradditions.The
literalizer-calldirective gains a:comment-file:option: a text file with one line per generated call whose non-blank lines are emitted as trailing source comments after the matching call (using the target language’s comment syntax), with a blank line emitting no comment. This follows upstreamliteralizeradding thecomment_sourceargument toliteralize_call, which places the comment after the statement terminator – something a:call-transform:cannot do without commenting out the terminator.CommentSourceLengthMismatchError(the:comment-file:line count not matching the number of generated calls) andCommentSourceMultilineErrorfromliteralizerare now surfaced as a SphinxExtensionErrorrather than an uncaught traceback.The
:heterogeneous-strategy:option now acceptstupleforcpp,kotlin,scala, andtypescript, matching upstreamliteralizeradditions. See Heterogeneous strategies for the full strategy set, worked examples, and the per-language support matrix; future strategy changes are summarized here and detailed there.
2026.05.16¶
Bumped
literalizerto2026.5.15.2.The
literalizer-calldirective gains:zip-file:and:zip-input-format:options. The data file’s top-level elements pair positionally with the generated calls and are exposed to:call-transform:as$zipped, rendered as a native literal – useful for generating assertions from a parallel file of expected results (e.g.:call-transform: assert $call == $zipped). This follows upstreamliteralizerreplacingzip_valueswith thezip_source/zip_input_formatpair.The
:call-transform:template now also substitutes$call(an alias of the existing$0) for the rendered call expression and$indexfor the zero-based call position, following upstreamliteralizerpassing aCallContexttocall_transforminstead of a bare string.CallsNotSupportedByLanguageError,CallsNotSupportedByToolError,PerElementNotListError,ZipSourceWithoutInputFormatError, andZipValuesLengthMismatchErrorfromliteralizerare now surfaced as SphinxExtensionErrorrather than an uncaught traceback.The
:heterogeneous-strategy:option now acceptsrecordforjavaandkotlinandtupleforrust, and:language-version:acceptsjdk_16forjava, matching upstreamliteralizeradditions.
2026.05.15¶
Bumped
literalizerto2026.5.15.The
:heterogeneous-strategy:option now acceptsrecordforgo(previously onlyrust). Each record-shaped mapping becomes a generated struct declaration plus a matching struct literal, so a mapping whose values mix scalars and containers is representable instead of raising.The
:language-version:option acceptsv2003again forfortran(alongside the defaultv2008), matching upstreamliteralizerre-introducingFortran.VersionFormats.V2003.The
:language-version:values forpythonare nowpy38andpy39(previouslypy_3_12), following upstreamliteralizer’sPython.VersionFormatschange.pythonoutput now carries afrom __future__ import annotationspreamble (visible with:include-preamble:), following an upstreamliteralizerchange.
2026.05.14¶
Bumped
literalizerto2026.5.14.1.UnrepresentableInputErrorfromliteralizer(raised when a YAML input contains a non-string dict key that the target language cannot represent) is now surfaced as a SphinxExtensionErrorrather than an uncaught traceback.The
literalizer-calldirective now accepts:variable-name:,:existing-variable:, and:modifiers:options, wrapping the rendered call in an idiomatic per-language variable binding (e.g.let my_data = make_widget(42);).:both-variable-forms:is not supported forliteralizer-callbecause emitting both a declaration and an assignment would invoke the target function twice; upstreamliteralizerraisesUnsupportedCallShapeErrorfor languages whose call form is a statement rather than an expression, or whose declaration template is only valid for literal values.Removed the
:line-ending:directive option. Upstreamliteralizerremoved the correspondingLineEndingsenum; statement terminators now follow each language’s idiomatic default.Languages whose
wrap_in_fileintroduces a named scope (e.g. Java, C, C++, D, Erlang, Fortran, F#, Objective-C, Occam, SystemVerilog) now require:variable-name:when:wrap-in-file:is set. UpstreamliteralizerraisesWrapInFileWithoutVariableNotSupportedErrorfor languages that cannot represent a bare value at file-statement scope.The
:variable-type-hints:option exposes upstream’s newsafevalue, and the previousautovalue is now spellednever(the rendered output is unchanged for languages that did not previously distinguish the two).The
:call-style:option exposes the newcurriedvalue for F#, Haskell, OCaml, and SML. Elmliteralizer-calloutput now emits curried-application calls in place of the prior tuple form.The new upstream typed exceptions raised by directive option combinations a language cannot represent (
WrapInFileWithoutVariableNotSupportedError,WrapCombinedInFileNotSupportedError,VariableNameNotSupportedError,UnsupportedCallShapeError,UnsupportedIdentifierCaseError,DottedCallTargetNotSupportedError,DottedCallStubNotSupportedError,FreeFunctionCallNotSupportedError, andCallArgNotSupportedError) are now caught and re-raised asExtensionErrorso the offending directive is reported as a build error rather than a traceback.
2026.05.01.2¶
Bumped
literalizerto2026.5.1.1.Added
:collection-layout:to both directives, exposing literalizer’s nested collection layout control.Go output now follows literalizer’s idiomatic no-semicolon default line ending unless
:line-ending: semicolonis selected.
2026.05.01.1¶
Added
:omit-code:toliteralizer-callso callers can combine it with:include-preamble:to render imports or other preamble lines without also rendering generated calls.
2026.05.01¶
Bumped
literalizerto2026.5.1.Added
:ref-key:to both directives, exposing literalizer’s configurable reference marker key.Added
:language-version:to both directives, exposing each target language’sVersionFormatsenum.Rocis now selected with:language: rocwhile still usingtextsyntax highlighting.
2026.04.30.3¶
Bumped
literalizerto2026.4.30.3.New languages Tcl, Nix, SML, V, Wren, and Forth are now available via the
:language:option, provided by literalizer’s new backends.The
:module-name:value is now automatically converted to the case expected by the target language (e.g.my_modulebecomesMyModulefor Java, which requires PascalCase class names), using themodule_name_caseattribute introduced in literalizer2026.4.30.3.
2026.04.30.2¶
Bumped
literalizerto2026.4.30.2.Added
:consumable-refs:option to theliteralizer-calldirective. Accepts a comma-separated list of variable names that may be consumed (moved) when they appear as$refmarkers in exactly one call argument across all rendered calls. For languages such as C++ and Mojo, this causes the matchingstd::move/^transfer to be emitted.
2026.04.30.1¶
Added
:both-variable-forms:to theliteralizerdirective. When combined with:variable-name:and:wrap-in-file:, it uses literalizer’sBothVariableFormsto emit both a declaration and an assignment in a single output block.
2026.04.30¶
2026.04.30¶
Bumped
literalizerto2026.4.30.
2026.04.29¶
Bumped
literalizerto2026.4.29.Added
:wrap-in-file:to theliteralizerdirective, exposing literalizer’swrap_in_fileparameter so generated output can be emitted as a self-contained compilable file.Added
:module-name:to both directives. When the selected language has a named-scope wrapper (C,Cpp,D,Erlang,Fortran,FSharp,Java,ObjectiveC,Occam,SystemVerilog,Ada,Crystal,Scala,Haskell), the value is passed to the language constructor’smodule_nameargument. Languages that do not acceptmodule_nameraise a clearExtensionError.:ref-case:is now also accepted by theliteralizerdirective (previously onlyliteralizer-call), letting top-level or nested{"$ref": "name"}mappings render as case-converted bare identifiers in plain literal output.Roc is now available as a
:language: roctarget via literalizer’s new Roc backend.
2026.04.26¶
Bumped
literalizerto2026.4.24.1.literalizer-callnow accepts:ref-case:(snake,camel,pascal,upper_snake, orkebab) to convert{"$ref": "name"}identifiers to the chosen case before rendering.
2026.04.24¶
2026.04.24¶
Bumped
literalizerto2026.4.24.literalizer-callwith:per-element:for Rust now widens:heterogeneous-strategy: tagged_enumscalar wrapping across sibling calls at matching argument slots, so a homogeneous sibling no longer emits an unwrapped scalar that mismatches the parameter type implied by a heterogeneous sibling.
2026.04.23.1¶
Bumped
literalizerto2026.4.23.:heterogeneous-strategy: object_variantis now available for Nim, auto-generating a Nim object variant in the preamble for dicts, lists, or sibling-list pairs that hold scalars of more than one Nim type.:heterogeneous-strategy: union_typeis now available for Dhall, auto-generating a Dhall union type in the preamble for mixed-scalar containers.literalizer-callnow renders Clojure, Objective-C, and Perl calls: Clojure as(process :flag true :count 42), Objective-C asprocess(@YES, @(42));with boxed scalars, and Perl asprocess(1, 42);.literalizer-callnow recognizes{"$ref": "name"}markers at argument positions in the data file, emittingnameas a bare identifier (process(user=user_obj, count=42)) rather than formatting the marker dict as a literal. Refs and literal values can be mixed in the same call across JSON, JSON5, YAML, and TOML.
2026.04.23¶
Added a
:call-style:option to select a non-default call style for theliteralizer-calldirective (e.g.:call-style: positionalfor TypeScript to rendermyFunc({...})instead ofmyFunc({ obj: {...} })).
2026.04.22¶
2026.04.21.5¶
Bumped
literalizerto2026.4.21.5.:declaration-style: lazy_staticis now available for Rust, wrapping the value instd::sync::LazyLockso module-levelHashMap,BTreeMap,Vec, and similar collections can be declared with a runtime-initialized literal.literalizer-callnow renders Racket and Common Lisp calls as S-expressions with prefixed keyword arguments ((process #:flag #t #:count 42)and(process :flag t :count 42)respectively).literalizer-callwithout:per-element:now respects the language’s call style, so Swift gets calls with keyword labels (process(data: [1, 2, 3])) instead of an unlabeled positional argument.
2026.04.21.2¶
2026.04.21.4¶
Bumped
literalizerto2026.4.21.4.literalizer-callnow reports a parameter/value count mismatch as anExtensionErrornaming the:parameter-names:option, rather than surfacing literalizer’sParameterCountMismatchErroras a traceback.Picked up the upstream fix for
pre_indent_levelinteraction with:variable-name:: multi-line values are now uniformly indented under the declaration rather than inserting thepre_indent_levelwhitespace between=and the value.
2026.04.21.1¶
2026.04.21.3¶
Bumped
literalizerto2026.4.21.3.Added
:heterogeneous-strategy:directive option, exposing language-level heterogeneous-scalar strategies such as Rust’stagged_enum.
2026.04.21¶
Bumped
literalizerto2026.4.21.1.Added
:modifiers:directive option for declaring variables with language-specific keywords (e.g.public,static,finalfor Java).Removed the now-unused
error_on_coercionargument from theliteralizecall, matching the upstream API change.
2026.04.18¶
Bumped
literalizerto2026.4.18.
2026.04.15¶
Bumped
literalizerto2026.4.15.Adopted the new
variable_formparameter (NewVariable/ExistingVariable) replacingvariable_name/new_variable.Added
:numeric-style:directive option.
2026.04.14¶
Bumped
literalizerto2026.4.14.Added support for Nix output language.
Renamed
:call-function:directive option to:target-function:.Renamed
:call-params:directive option to:parameter-names:.
2026.04.06¶
Bumped
literalizerto2026.4.6.Added
:input-format:directive option for explicit input format selection.Added support for TOML (
.toml) and JSON5 (.json5) input files with auto-detection by extension.Added support for new output languages: Dhall, Odin, PureScript, Raku, Scheme, and SystemVerilog.
Fixed handling of languages with no Pygments lexer (
pygments_name=None).Added
:dict-entry-style:directive option.Added
:float-format:directive option.Added
:numeric-literal-suffix:directive option.Added
:default-ordered-map-value-type:directive option.
2026.03.26.2¶
Bumped
literalizerto2026.3.26.2.
2026.03.26.1¶
Bumped
literalizerto2026.3.26.1.Replaced
:variable-type-hints: inlinewith:variable-type-hints: alwaysand:variable-type-hints: auto, matching the upstream API change.Added
:empty-dict-key:directive option.
2026.03.26¶
Bumped
literalizerto2026.3.26.Replaced
:prefix:and:prefix-char:directive options with:pre-indent-level:and:indent-char:, matching the upstream API change fromline_prefixtopre_indent_level.Added
:line-ending:directive option.
2026.03.25¶
Bumped
literalizerto2026.3.25.Passed
:indent:to the language constructor instead ofliteralize_yaml, matching the upstream API change.
2026.03.23¶
Bumped
literalizerto2026.3.23.literalize_yamlnow returnsLiteralizeResult; use.codefor the rendered text.Added
:declaration-style:directive option.Added
:dict-format:directive option.Added
:integer-format:directive option.Added
:numeric-separator:directive option.Added
:string-format:directive option.Added
:trailing-comma:directive option.
2026.03.22.1¶
Bumped
literalizerto2026.3.22.1.Renamed
:wrap:directive option to:include-delimiters:.Added
:variable-type-hints:directive option.Derived language directive keys from
pygments_nameinstead of a hand-maintained mapping. Renamedvisual-basictovb.net.Used
pygments_namefrom language classes for syntax highlighting.Used
LanguageClsinstead ofHasFormatEnums.Added
ALL_LANGUAGESconsistency check.
2026.03.22¶
2026.03.20.1¶
Bumped
literalizerto2026.3.20.2.Added support for Objective-C language.
Added
arraysequence format option for Rust.Added
sequence_formatas a required field for all languages. New sequence format values:cell_array,initializer_list,sequence,slice,table,vector.
2026.03.20¶
Bumped
literalizerto2026.3.20.1.Added support for Fortran and Norg languages.
Added
vecandtuplesequence format options for Rust.
2026.03.19¶
Bumped
literalizerto2026.3.19.Added
:indent:directive option for controlling indentation inside wrapped delimiters independently of the line prefix.
2026.03.18¶
Bumped
literalizerto2026.3.18.Added support for Ada, Bash, C, Crystal, D, Elixir, Erlang, F#, Groovy, Haskell, Lua, MATLAB, Nim, OCaml, Occam, Perl, PowerShell, Rust, and Zig languages.
Added
rustdate format (NaiveDate::from_ymd_opt(...)/NaiveDateTime::new(...)).Added
typescriptdate format alias (same asjavascript).Removed
phpdate format (PHP uses ISO dates by default; the option had no effect).
2026.03.17.1¶
2026.03.17.2¶
Bumped
literalizerto2026.3.17.2.Added support for Clojure, Scala, and R languages.
Added
rdate format (as.Date(...)/as.POSIXct(...)).
2026.03.17¶
2026.03.16.2¶
2026.03.16.1¶
Bumped
literalizerto2026.3.16.1.
2026.03.16¶
Bumped
literalizerto2026.3.16.
2026.03.15.4¶
2026.03.15.3¶
Bumped
literalizerto2026.3.15.2.
2026.03.15.2¶
2026.03.15.1¶
2026.03.15¶
2026.03.14.1¶
2026.03.14¶
Initial release.