///|
priv struct FontCommandSpec {
name : String
font : String
}
///|
let font_commands : Array[FontCommandSpec] = [
{ name: "\\mathrm", font: "mathrm" },
{ name: "\\mathit", font: "mathit" },
{ name: "\\mathbf", font: "mathbf" },
{ name: "\\mathnormal", font: "mathnormal" },
{ name: "\\mathsfit", font: "mathsfit" },
{ name: "\\mathbb", font: "mathbb" },
{ name: "\\mathcal", font: "mathcal" },
{ name: "\\mathfrak", font: "mathfrak" },
{ name: "\\mathscr", font: "mathscr" },
{ name: "\\mathsf", font: "mathsf" },
{ name: "\\mathtt", font: "mathtt" },
{ name: "\\Bbb", font: "mathbb" },
{ name: "\\bold", font: "mathbf" },
{ name: "\\frak", font: "mathfrak" },
]
///|
let old_font_commands : Array[FontCommandSpec] = [
{ name: "\\rm", font: "mathrm" },
{ name: "\\sf", font: "mathsf" },
{ name: "\\tt", font: "mathtt" },
{ name: "\\bf", font: "mathbf" },
{ name: "\\it", font: "mathit" },
{ name: "\\cal", font: "mathcal" },
]
///|
fn command_font(
commands : Array[FontCommandSpec],
func_name : String,
) -> String raise ParseFailure {
for command in commands {
guard command.name == func_name else { continue }
return command.font
}
raise InternalInvariant(message="Unknown font command: " + func_name)
}
///|
fn font_spec() -> FunctionSpec {
FunctionSpec::make(
font_commands.map(command => command.name),
1,
allowed_in_argument=true,
handler=font_handler,
)
}
///|
fn font_handler(
context : FunctionContext,
args : Array[ParseNode],
_opt_args : Array[ParseNode?],
) -> ParseNode raise ParseFailure {
Font(
mode=context.mode,
font=command_font(font_commands, context.func_name),
body=normalize_argument(require_function_arg(args, 0, context.func_name)),
)
}
///|
fn boldsymbol_spec() -> FunctionSpec {
FunctionSpec::make(["\\boldsymbol", "\\bm"], 1, handler=boldsymbol_handler)
}
///|
fn boldsymbol_handler(
context : FunctionContext,
args : Array[ParseNode],
_opt_args : Array[ParseNode?],
) -> ParseNode raise ParseFailure {
let body = require_function_arg(args, 0, context.func_name)
MClass(
mode=context.mode,
mclass=binrel_class(body),
body=[Font(mode=context.mode, font="boldsymbol", body~)],
is_character_box=is_character_box(body),
)
}
///|
fn old_font_spec() -> FunctionSpec {
FunctionSpec::make(
old_font_commands.map(command => command.name),
0,
allowed_in_text=true,
handler=old_font_handler,
)
}
///|
fn old_font_handler(
context : FunctionContext,
_args : Array[ParseNode],
_opt_args : Array[ParseNode?],
) -> ParseNode raise ParseFailure {
let body = (context.parse_expression)(true, context.break_on_token_text)
Font(
mode=context.mode,
font=command_font(old_font_commands, context.func_name),
body=OrdGroup(mode=context.mode, loc=None, body~, semisimple=false),
)
}