texlang_stdlib/
tracingmacros.rs1use colored::*;
4use texlang::{command, texmacro, token::write_tokens, traits::*, variable, vm};
5
6#[derive(Default)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
9pub struct Component {
10 tracing_macros: i32,
11}
12
13pub fn get_tracingmacros<S: HasComponent<Component>>() -> command::BuiltIn<S> {
15 variable::Command::new_singleton(
16 |state: &S, _: variable::Index| -> &i32 { &state.component().tracing_macros },
17 |state: &mut S, _: variable::Index| -> &mut i32 {
18 &mut state.component_mut().tracing_macros
19 },
20 )
21 .into()
22}
23
24pub fn hook<S: HasComponent<Component>>(
25 token: texlang::token::Token,
26 input: &vm::ExpansionInput<S>,
27 tex_macro: &texlang::texmacro::Macro,
28 arguments: &[&[texlang::token::Token]],
29 reversed_expansion: &[texlang::token::Token],
30) {
31 if input.state().component().tracing_macros <= 0 {
32 return;
33 }
34 let trace = input.trace(token);
35 println!(
36 "{}{}",
37 "Macro expansion trace of ".bold(),
38 trace.value.bold()
39 );
40 let interner = input.vm().cs_name_interner();
43 println![" ┌──",];
44 print![" arguments "];
45 if arguments.is_empty() {
46 print!["│ (none)\n "];
47 }
48 for (i, argument) in arguments.iter().enumerate() {
49 print![
50 "│ {}{}={} \n ",
51 "#".bright_yellow(),
52 (i + 1).to_string().bright_yellow(),
53 write_tokens(*argument, interner).bright_yellow()
54 ]
55 }
56
57 print!["├──\n replacement definition │ ",];
58 for replacement in tex_macro.replacements() {
59 match replacement {
60 texmacro::Replacement::Tokens(tokens) => {
61 print!("{}", write_tokens(tokens.iter().rev(), interner))
62 }
63 texmacro::Replacement::Parameter(i) => {
64 print!(
65 "{}{}",
66 "#".bright_yellow(),
67 (i + 1).to_string().bright_yellow(),
68 )
69 }
70 }
71 }
72
73 println![
74 "\n ├──\n expansion │ {}",
75 write_tokens(reversed_expansion.iter().rev(), interner)
76 ];
77 println![" └──"];
78}