Value converters to apply before values are rendered.
A value converter is a function that converts a value to another value
immediately before the value is rendered (and after the value has been type-checked).
The converted value is then rendered by the renderer's hardwired rendering logic.
When a converter returns a value of type Object, Collection, Map, or Pair,
converters are recursively applied to the returned value's components (object properties,
list elements, etc.).
At most one converter is applied per value.
If multiple converters are applicable, a winner is chosen as follows:
A converter with String key wins over a converter with Class key.
Between multiple String key converters, the converter defined earlier
(according to the mapping's definition order) wins.
Between multiple Class key converters, the most specific class (according to class
hierarchy) wins.
A converter's key specifies which values the converter should be applied to.
A converter with Class key is applied to values of that class, including values of its
subclasses.
A converter with String key is applied to values whose path matches the path spec
described by the string.
Path specs can have the following components:
^ matches the top-level value passed to renderDocument() or renderValue() (often the
module object)
pigeon matches property pigeon at any hierarchy level
[pigeon] matches map(ping) entry with String key "pigeon" at any hierarchy level
* matches any property
[*] matches any list(ing) element or map(ping) entry
Here are some examples of valid property paths:
"server"
"server.timeout"
"^server.timeout" (matches server.timeout, but not racks[12345].server.timeout)
"racks[12345].server"
"racks[*].server
Paths are matched against path specs component-wise in reverse order.
For example, paths server.timeout and racks[*].server.timeout
both match path spec server.timeout, whereas path server.timeout.millis does not.
pkl.ValueRenderer
subclass used to render pretty-printed tables