///|
// Canonical dumps of theme values and themes, to compare this loader with
// Ruby's (scripts/pdf_theme/harvest.rb writes the same form).
///|
/// A string in double quotes, `"` and `\` escaped, control characters as
/// `\uXXXX`.
fn dump_quote(s : String) -> String {
let sb = StringBuilder()
sb.write_char('"')
for c in s {
match c {
'"' | '\\' => {
sb.write_char('\\')
sb.write_char(c)
}
c if c.to_int() < 0x20 => {
let hex = c.to_int().to_string(radix=16)
sb.write_string("\\u")
for _ in 0..<(4 - hex.length()) {
sb.write_char('0')
}
sb.write_string(hex)
}
c => sb.write_char(c)
}
}
sb.write_char('"')
sb.to_string()
}
///|
/// A canonical, typed form of the value: `nil`, `true`, `12`, `f12.0` (a
/// Float, as Ruby prints it), `"text"`, `hex"FFFFFF"`, `transparent`,
/// `cmyk[0, 50, 100, 100]`, `[...]`, `{"key" => ...}` (`{:key => ...}`
/// for symbol keys).
pub fn Value::dump(self : Value) -> String {
match self {
Null => "nil"
Bool(b) => b.to_string()
Int(i) => i.to_string()
Float(f) => "f" + ruby_float_to_s(f)
Str(s) => dump_quote(s)
Hex(s) => "hex" + dump_quote(s)
Transparent => "transparent"
Cmyk(items) => "cmyk[" + items.map(v => v.dump()).join(", ") + "]"
Array(items) => "[" + items.map(v => v.dump()).join(", ") + "]"
Hash(map, symbols~) => {
let parts = []
for k, v in map {
let key = if symbols { ":" + k } else { dump_quote(k) }
parts.push(key + " => " + v.dump())
}
"{" + parts.join(", ") + "}"
}
}
}
///|
/// The theme as `key: value` lines (see `Value::dump`) in the order the
/// keys were set.
pub fn Theme::dump(self : Theme) -> String {
let lines = []
for k, v in self.table {
lines.push("\{k}: \{v.dump()}")
}
lines.join("\n")
}