///|
/// Metadata of Python's `SvgFormatter`.
pub let svg_info : FormatterInfo = {
class_name: "SvgFormatter",
name: "SVG",
aliases: ["svg"],
filenames: ["*.svg"],
description: "Format tokens as an SVG graphics file. This formatter is still experimental. Each line of code is a ```` element with explicit ``x`` and ``y`` coordinates containing ```` elements with the individual token styles.",
}
///|
/// Python's `SvgFormatter`. Options: `style`, `nowrap`, `fontfamily`,
/// `fontsize`, `xoffset`, `yoffset`, `ystep`, `spacehack`, `linenos`,
/// `linenostart`, `linenostep`, `linenowidth`.
pub fn svg_formatter(
options? : @lexer.Options = Map([]),
style? : @styles.Style,
) -> Formatter raise {
let base = BaseOptions::new(options, style?)
let st = base.style
let nowrap = @lexer.get_bool_opt(options, "nowrap", false)
let fontfamily = options.get("fontfamily").unwrap_or("monospace")
let fontsize = options.get("fontsize").unwrap_or("14px")
let xoffset = @lexer.get_int_opt(options, "xoffset", 0)
let mut fs = fontsize.trim(chars=" \t\n\r\u{0b}\u{0c}").to_owned()
if fs.has_suffix("px") {
fs = fs
.unsafe_substring(start=0, end=fs.length() - 2)
.trim(chars=" \t\n\r\u{0b}\u{0c}")
.to_owned()
}
let int_fs = py_int(fs).unwrap_or(20)
let yoffset = @lexer.get_int_opt(options, "yoffset", int_fs)
let ystep = @lexer.get_int_opt(options, "ystep", int_fs + 5)
let spacehack = @lexer.get_bool_opt(options, "spacehack", true)
let linenos = @lexer.get_bool_opt(options, "linenos", false)
let linenostart = @lexer.get_int_opt(options, "linenostart", 1)
let linenostep = @lexer.get_int_opt(options, "linenostep", 1)
let linenowidth = @lexer.get_int_opt(options, "linenowidth", 3 * ystep)
let stylecache : Map[@token.TokenType, String] = Map([])
// Python's `_get_style`
fn get_style(tokentype : @token.TokenType) -> String {
if stylecache.get(tokentype) is Some(s) {
return s
}
let mut t = tokentype
while !st.styles_token(t) {
t = t.parent().unwrap_or(@token.token)
}
let value = st.style_for_token(t) catch { _ => panic() }
let result = StringBuilder()
if value.color is Some(c) {
result.write_string(" fill=\"#" + c + "\"")
}
if value.bold {
result.write_string(" font-weight=\"bold\"")
}
if value.italic {
result.write_string(" font-style=\"italic\"")
}
let result = result.to_string()
stylecache[tokentype] = result
result
}
Formatter::new(svg_info, base, tokens => {
let buf = StringBuilder()
let x = xoffset
let mut y = yoffset
if !nowrap {
match base.encoding {
Some(enc) =>
buf.write_string("\n")
None => buf.write_string("\n")
}
buf.write_string(
"\n",
)
buf.write_string("\n")
}
buf.to_string()
})
}