1use crate::Engine;
5use crate::cmd::Cmd;
6use crate::eqtb::{Loc, MU_GLUE_OFFSET, NUM_FAMILIES, Val};
7use crate::glue::Glue;
8use crate::nodes::NodeRef;
9
10impl Engine {
11 pub fn print_glue(&mut self, d: i32, order: u8, s: Option<&str>) {
14 self.printer.print_scaled(d);
15 if order > 4 {
16 self.printer.print_str("foul");
17 } else if order > 0 {
18 self.printer.print_str("fi");
19 for _ in 1..order {
20 self.printer.print_char('l' as u32);
21 }
22 } else if let Some(s) = s {
23 self.printer.print_str(s);
24 }
25 }
26
27 pub fn print_spec(&mut self, g: &Glue, s: Option<&str>) {
29 self.printer.print_scaled(g.width);
30 if let Some(s) = s {
31 self.printer.print_str(s);
32 }
33 if g.stretch != 0 {
34 self.printer.print_str(" plus ");
35 self.print_glue(g.stretch, g.stretch_order, s);
36 }
37 if g.shrink != 0 {
38 self.printer.print_str(" minus ");
39 self.print_glue(g.shrink, g.shrink_order, s);
40 }
41 }
42
43 pub fn show_eqtb(&mut self, loc: Loc) {
45 match loc {
46 Loc::Cs(cs) => {
47 self.sprint_cs(cs);
48 self.printer.print_char('=' as u32);
49 let m = self.eqtb.meaning(cs).clone();
50 if m.cmd.is_call() && m.mac.as_ref().is_some_and(|mac| mac.protected) {
51 self.print_esc_str("protected");
52 if m.cmd == Cmd::Call {
53 self.printer.print_char(' ' as u32);
54 }
55 }
56 self.print_cmd_chr(m.cmd, m.chr);
57 if m.cmd >= Cmd::Call
58 && let Some(mac) = m.mac
59 {
60 self.printer.print_char(':' as u32);
61 let t = mac.tokens.clone();
62 self.show_token_list(&t, 0, t.len(), 32);
63 }
64 }
65 Loc::IntPar(i) => {
66 self.print_cmd_chr(Cmd::AssignInt, i);
67 self.printer.print_char('=' as u32);
68 self.printer.print_int(self.eqtb.int(i).into());
69 }
70 Loc::Count(n) => {
71 self.print_esc_str("count");
72 self.printer.print_int(n.into());
73 self.printer.print_char('=' as u32);
74 self.printer
75 .print_int(self.eqtb.count[n as usize].val.into());
76 }
77 Loc::Attr(n) => {
78 self.print_esc_str("attribute");
79 self.printer.print_int(n.into());
80 self.printer.print_char('=' as u32);
81 self.printer
82 .print_int(self.eqtb.attr[n as usize].val.into());
83 }
84 Loc::DimenPar(i) => {
85 self.print_cmd_chr(Cmd::AssignDimen, i);
86 self.printer.print_char('=' as u32);
87 self.printer.print_scaled(self.eqtb.dimen(i));
88 self.printer.print_str("pt");
89 }
90 Loc::Dimen(n) => {
91 self.print_esc_str("dimen");
92 self.printer.print_int(n.into());
93 self.printer.print_char('=' as u32);
94 self.printer.print_scaled(self.eqtb.dimen[n as usize].val);
95 self.printer.print_str("pt");
96 }
97 Loc::GluePar(i) => {
98 let mu = i >= MU_GLUE_OFFSET;
99 if mu {
100 self.print_cmd_chr(Cmd::AssignMuGlue, i - MU_GLUE_OFFSET);
101 } else {
102 self.print_cmd_chr(Cmd::AssignGlue, i);
103 }
104 self.printer.print_char('=' as u32);
105 let g = self.eqtb.glue(i);
106 self.print_spec(&g, Some(if mu { "mu" } else { "pt" }));
107 }
108 Loc::Skip(n) | Loc::MuSkip(n) => {
109 let mu = matches!(loc, Loc::MuSkip(_));
110 self.print_esc_str(if mu { "muskip" } else { "skip" });
111 self.printer.print_int(n.into());
112 self.printer.print_char('=' as u32);
113 let g = if mu {
114 self.eqtb.muskip[n as usize].val
115 } else {
116 self.eqtb.skip[n as usize].val
117 };
118 self.print_spec(&g, Some(if mu { "mu" } else { "pt" }));
119 }
120 Loc::ToksPar(_) | Loc::Toks(_) => {
121 if let Loc::Toks(n) = loc {
122 self.print_esc_str("toks");
123 self.printer.print_int(n.into());
124 } else if let Loc::ToksPar(i) = loc {
125 self.print_cmd_chr(Cmd::AssignToks, i);
126 }
127 self.printer.print_char('=' as u32);
128 if let Val::Toks(t) = self.eqtb.get(loc) {
129 self.show_token_list(&t, 0, t.len(), 32);
130 }
131 }
132 Loc::Box(n) => {
133 self.print_esc_str("box");
134 self.printer.print_int(n.into());
135 self.printer.print_char('=' as u32);
136 let b = self.eqtb.boxes[n as usize].val;
137 if b.is_null() {
138 self.printer.print_str("void");
139 } else {
140 self.depth_threshold = 0;
141 self.breadth_max = 1;
142 self.show_box1(b);
143 }
144 }
145 Loc::CurFont => {
146 self.printer.print_str("current font");
147 self.printer.print_char('=' as u32);
148 let cs = self.font_id_cs(self.eqtb.cur_font.val);
149 let name = self.hash.name(cs).to_vec();
150 self.print_esc_bytes(&name);
151 }
152 Loc::MathFont(i) => {
153 let size = i / NUM_FAMILIES as u32;
154 let fam = i % NUM_FAMILIES as u32;
155 self.print_cmd_chr(Cmd::DefFamily, size);
156 self.printer.print_int(fam.into());
157 self.printer.print_char('=' as u32);
158 let cs = self.font_id_cs(self.eqtb.math_font[i as usize].val);
159 let name = self.hash.name(cs).to_vec();
160 self.print_esc_bytes(&name);
161 }
162 Loc::ParShape => {
163 self.print_esc_str("parshape");
164 self.printer.print_char('=' as u32);
165 let n = self.eqtb.par_shape.val.as_ref().map_or(0, |s| s.len() / 2);
166 self.printer.print_int(n as i64);
167 }
168 Loc::EtexShape(i) => {
169 self.print_cmd_chr(Cmd::SetEtexShape, i);
170 self.printer.print_char('=' as u32);
171 let n = self.eqtb.etex_shape[i as usize]
172 .val
173 .as_ref()
174 .map_or(0, |s| s.len());
175 self.printer.print_int(n as i64);
176 }
177 Loc::Cat { table, ch } => {
178 self.print_esc_str("catcode");
179 self.printer.print_int(ch.into());
180 self.printer.print_char('=' as u32);
181 self.printer
182 .print_int(self.eqtb.catcode_in(table, ch).into());
183 }
184 Loc::Code(kind, ch) => {
185 use crate::eqtb::CodeKind as K;
186 let name = match kind {
187 K::Lc => "lccode",
188 K::Uc => "uccode",
189 K::Sf => "sfcode",
190 K::Math => "mathcode",
191 K::Del => "delcode",
192 };
193 self.print_esc_str(name);
194 self.printer.print_int(ch.into());
195 self.printer.print_char('=' as u32);
196 self.printer.print_int(self.eqtb.code_table(kind).get(ch));
197 }
198 Loc::MathParam(i) => {
199 self.print_cmd_chr(Cmd::SetMathParam, i / 8);
200 self.printer.print_int((i % 8).into());
201 self.printer.print_char('=' as u32);
202 if let Val::Int(v) = self.eqtb.get(loc) {
203 self.printer.print_scaled(v as i32);
204 self.printer.print_str("pt");
205 }
206 }
207 Loc::LocalCount(i) => {
208 self.print_esc_str(if i == 0 {
209 "nolocalwhatsits"
210 } else {
211 "nolocaldirs"
212 });
213 self.printer.print_char('=' as u32);
214 self.printer
215 .print_int(self.eqtb.local_count[i as usize].val.into());
216 }
217 Loc::DirPar(i) => {
218 const NAMES: [&str; 6] = [
220 "pagedir", "bodydir", "pardir", "textdir", "mathdir", "linedir",
221 ];
222 self.print_esc_str(NAMES.get(i as usize).copied().unwrap_or("textdir"));
223 self.printer.print_char(' ' as u32);
224 let d = self.eqtb.dir_par[i as usize].val;
225 self.printer
226 .print_str(crate::showbox::DIR_NAMES[d.rem_euclid(4) as usize]);
227 }
228 Loc::LocalBox(i) => {
229 self.print_esc_str(if i == 0 {
230 "localleftbox"
231 } else {
232 "localrightbox"
233 });
234 self.printer.print_char('=' as u32);
235 let b = self.eqtb.local_box[i as usize].val;
236 if b.is_null() {
237 self.printer.print_str("void");
238 } else {
239 self.depth_threshold = 0;
240 self.breadth_max = 1;
241 self.show_box1(b);
242 }
243 }
244 }
245 }
246
247 pub fn show_box(&mut self, p: NodeRef) {
250 self.show_box_param_limits();
251 self.show_node_list(p);
252 self.printer.print_ln();
253 }
254
255 pub fn show_box1(&mut self, p: NodeRef) {
257 self.show_node_list(p);
258 }
259
260 pub fn show_save_groups(&mut self) {
262 self.printer.print_nl("");
263 self.printer.print_ln();
264 let lvl = self.save.cur_level;
265 let mut l = lvl;
266 let mut boundary = self.save.cur_boundary;
268 let mut group = self.save.cur_group;
269 while group != crate::save::GroupCode::BottomLevel {
270 l -= 1;
271 self.printer.print_nl("### ");
272 let saved_group = self.save.cur_group;
273 let saved_level = self.save.cur_level;
274 let saved_boundary = self.save.cur_boundary;
275 self.save.cur_group = group;
276 self.save.cur_level = l;
277 self.save.cur_boundary = boundary;
278 self.print_group(true);
279 self.save.cur_group = saved_group;
280 self.save.cur_level = saved_level;
281 self.save.cur_boundary = saved_boundary;
282 match self.save.stack.get(boundary) {
283 Some(crate::save::SaveEntry::Boundary {
284 group: g,
285 boundary: b,
286 ..
287 }) => {
288 group = *g;
289 boundary = *b;
290 }
291 _ => break,
292 }
293 }
294 }
295}