///|
/// Lexer, formatter and filter options. As on the pygmentize command line,
/// every value is a string; typed accessors mirror `pygments.util`.
pub type Options = Map[String, String]
///|
/// Errors raised for invalid option values.
pub suberror OptionError {
OptionError(String)
} derive(Debug)
///|
/// Python's `get_bool_opt`.
pub fn get_bool_opt(
options : Options,
name : String,
default : Bool,
) -> Bool raise OptionError {
match options.get(name) {
None => default
Some(v) =>
match v.to_lower() {
"1" | "yes" | "true" | "on" => true
"0" | "no" | "false" | "off" => false
_ =>
raise OptionError(
"Invalid value \{v.escape()} for option \{name}; use 1/0, yes/no, true/false, on/off",
)
}
}
}
///|
/// Python's `get_int_opt`.
pub fn get_int_opt(
options : Options,
name : String,
default : Int,
) -> Int raise OptionError {
match options.get(name) {
None => default
Some(v) =>
@string.parse_int(v.trim()) catch {
_ =>
raise OptionError(
"Invalid value \{v.escape()} for option \{name}; you must give an integer value",
)
}
}
}
///|
/// Python's `get_list_opt`: the value split at whitespace.
pub fn get_list_opt(
options : Options,
name : String,
default : Array[String],
) -> Array[String] {
match options.get(name) {
None => default
Some(v) => split_whitespace(v)
}
}
///|
/// Python's `get_choice_opt`.
pub fn get_choice_opt(
options : Options,
name : String,
allowed : Array[String],
default : String,
normcase? : Bool = false,
) -> String raise OptionError {
let v = options.get(name).unwrap_or(default)
let v = if normcase { v.to_lower() } else { v }
if !allowed.contains(v) {
raise OptionError(
"Value for option \{name} must be one of \{allowed.join(", ")}",
)
}
v
}
///|
/// Python's `str.split()` without arguments.
pub fn split_whitespace(s : String) -> Array[String] {
let out = []
let buf = StringBuilder()
let mut pending = false
for c in s {
if is_space(c) {
if pending {
out.push(buf.to_string())
buf.reset()
pending = false
}
} else {
buf.write_char(c)
pending = true
}
}
if pending {
out.push(buf.to_string())
}
out
}
///|
/// Python's `str.isspace` for one character.
pub fn is_space(c : Char) -> Bool {
match c {
' ' | '\t' | '\n' | '\r' | '\u{0b}' | '\u{0c}' => true
'\u{1c}'..='\u{1f}' | '\u{85}' | '\u{a0}' | '\u{1680}' => true
'\u{2000}'..='\u{200a}' | '\u{2028}' | '\u{2029}' | '\u{202f}' => true
'\u{205f}' | '\u{3000}' => true
_ => false
}
}