use crate::Engine;
use crate::cmd::Cmd;
use crate::eqtb::{Loc, MU_GLUE_OFFSET, NUM_FAMILIES, Val};
use crate::glue::Glue;
use crate::nodes::NodeRef;
impl Engine {
pub fn print_glue(&mut self, d: i32, order: u8, s: Option<&str>) {
self.printer.print_scaled(d);
if order > 4 {
self.printer.print_str("foul");
} else if order > 0 {
self.printer.print_str("fi");
for _ in 1..order {
self.printer.print_char('l' as u32);
}
} else if let Some(s) = s {
self.printer.print_str(s);
}
}
pub fn print_spec(&mut self, g: &Glue, s: Option<&str>) {
self.printer.print_scaled(g.width);
if let Some(s) = s {
self.printer.print_str(s);
}
if g.stretch != 0 {
self.printer.print_str(" plus ");
self.print_glue(g.stretch, g.stretch_order, s);
}
if g.shrink != 0 {
self.printer.print_str(" minus ");
self.print_glue(g.shrink, g.shrink_order, s);
}
}
pub fn show_eqtb(&mut self, loc: Loc) {
match loc {
Loc::Cs(cs) => {
self.sprint_cs(cs);
self.printer.print_char('=' as u32);
let m = self.eqtb.meaning(cs).clone();
if m.cmd.is_call() && m.mac.as_ref().is_some_and(|mac| mac.protected) {
self.print_esc_str("protected");
if m.cmd == Cmd::Call {
self.printer.print_char(' ' as u32);
}
}
self.print_cmd_chr(m.cmd, m.chr);
if m.cmd >= Cmd::Call
&& let Some(mac) = m.mac
{
self.printer.print_char(':' as u32);
let t = mac.tokens.clone();
self.show_token_list(&t, 0, t.len(), 32);
}
}
Loc::IntPar(i) => {
self.print_cmd_chr(Cmd::AssignInt, i);
self.printer.print_char('=' as u32);
self.printer.print_int(self.eqtb.int(i).into());
}
Loc::Count(n) => {
self.print_esc_str("count");
self.printer.print_int(n.into());
self.printer.print_char('=' as u32);
self.printer
.print_int(self.eqtb.count[n as usize].val.into());
}
Loc::Attr(n) => {
self.print_esc_str("attribute");
self.printer.print_int(n.into());
self.printer.print_char('=' as u32);
self.printer
.print_int(self.eqtb.attr[n as usize].val.into());
}
Loc::DimenPar(i) => {
self.print_cmd_chr(Cmd::AssignDimen, i);
self.printer.print_char('=' as u32);
self.printer.print_scaled(self.eqtb.dimen(i));
self.printer.print_str("pt");
}
Loc::Dimen(n) => {
self.print_esc_str("dimen");
self.printer.print_int(n.into());
self.printer.print_char('=' as u32);
self.printer.print_scaled(self.eqtb.dimen[n as usize].val);
self.printer.print_str("pt");
}
Loc::GluePar(i) => {
let mu = i >= MU_GLUE_OFFSET;
if mu {
self.print_cmd_chr(Cmd::AssignMuGlue, i - MU_GLUE_OFFSET);
} else {
self.print_cmd_chr(Cmd::AssignGlue, i);
}
self.printer.print_char('=' as u32);
let g = self.eqtb.glue(i);
self.print_spec(&g, Some(if mu { "mu" } else { "pt" }));
}
Loc::Skip(n) | Loc::MuSkip(n) => {
let mu = matches!(loc, Loc::MuSkip(_));
self.print_esc_str(if mu { "muskip" } else { "skip" });
self.printer.print_int(n.into());
self.printer.print_char('=' as u32);
let g = if mu {
self.eqtb.muskip[n as usize].val
} else {
self.eqtb.skip[n as usize].val
};
self.print_spec(&g, Some(if mu { "mu" } else { "pt" }));
}
Loc::ToksPar(_) | Loc::Toks(_) => {
if let Loc::Toks(n) = loc {
self.print_esc_str("toks");
self.printer.print_int(n.into());
} else if let Loc::ToksPar(i) = loc {
self.print_cmd_chr(Cmd::AssignToks, i);
}
self.printer.print_char('=' as u32);
if let Val::Toks(t) = self.eqtb.get(loc) {
self.show_token_list(&t, 0, t.len(), 32);
}
}
Loc::Box(n) => {
self.print_esc_str("box");
self.printer.print_int(n.into());
self.printer.print_char('=' as u32);
let b = self.eqtb.boxes[n as usize].val;
if b.is_null() {
self.printer.print_str("void");
} else {
self.depth_threshold = 0;
self.breadth_max = 1;
self.show_box1(b);
}
}
Loc::CurFont => {
self.printer.print_str("current font");
self.printer.print_char('=' as u32);
let cs = self.font_id_cs(self.eqtb.cur_font.val);
let name = self.hash.name(cs).to_vec();
self.print_esc_bytes(&name);
}
Loc::MathFont(i) => {
let size = i / NUM_FAMILIES as u32;
let fam = i % NUM_FAMILIES as u32;
self.print_cmd_chr(Cmd::DefFamily, size);
self.printer.print_int(fam.into());
self.printer.print_char('=' as u32);
let cs = self.font_id_cs(self.eqtb.math_font[i as usize].val);
let name = self.hash.name(cs).to_vec();
self.print_esc_bytes(&name);
}
Loc::ParShape => {
self.print_esc_str("parshape");
self.printer.print_char('=' as u32);
let n = self.eqtb.par_shape.val.as_ref().map_or(0, |s| s.len() / 2);
self.printer.print_int(n as i64);
}
Loc::EtexShape(i) => {
self.print_cmd_chr(Cmd::SetEtexShape, i);
self.printer.print_char('=' as u32);
let n = self.eqtb.etex_shape[i as usize]
.val
.as_ref()
.map_or(0, |s| s.len());
self.printer.print_int(n as i64);
}
Loc::Cat { table, ch } => {
self.print_esc_str("catcode");
self.printer.print_int(ch.into());
self.printer.print_char('=' as u32);
self.printer
.print_int(self.eqtb.catcode_in(table, ch).into());
}
Loc::Code(kind, ch) => {
use crate::eqtb::CodeKind as K;
let name = match kind {
K::Lc => "lccode",
K::Uc => "uccode",
K::Sf => "sfcode",
K::Math => "mathcode",
K::Del => "delcode",
};
self.print_esc_str(name);
self.printer.print_int(ch.into());
self.printer.print_char('=' as u32);
self.printer.print_int(self.eqtb.code_table(kind).get(ch));
}
Loc::MathParam(i) => {
self.print_cmd_chr(Cmd::SetMathParam, i / 8);
self.printer.print_int((i % 8).into());
self.printer.print_char('=' as u32);
if let Val::Int(v) = self.eqtb.get(loc) {
self.printer.print_scaled(v as i32);
self.printer.print_str("pt");
}
}
Loc::LocalCount(i) => {
self.print_esc_str(if i == 0 {
"nolocalwhatsits"
} else {
"nolocaldirs"
});
self.printer.print_char('=' as u32);
self.printer
.print_int(self.eqtb.local_count[i as usize].val.into());
}
Loc::DirPar(i) => {
const NAMES: [&str; 6] = [
"pagedir", "bodydir", "pardir", "textdir", "mathdir", "linedir",
];
self.print_esc_str(NAMES.get(i as usize).copied().unwrap_or("textdir"));
self.printer.print_char(' ' as u32);
let d = self.eqtb.dir_par[i as usize].val;
self.printer
.print_str(crate::showbox::DIR_NAMES[d.rem_euclid(4) as usize]);
}
Loc::LocalBox(i) => {
self.print_esc_str(if i == 0 {
"localleftbox"
} else {
"localrightbox"
});
self.printer.print_char('=' as u32);
let b = self.eqtb.local_box[i as usize].val;
if b.is_null() {
self.printer.print_str("void");
} else {
self.depth_threshold = 0;
self.breadth_max = 1;
self.show_box1(b);
}
}
}
}
pub fn show_box(&mut self, p: NodeRef) {
self.show_box_param_limits();
self.show_node_list(p);
self.printer.print_ln();
}
pub fn show_box1(&mut self, p: NodeRef) {
self.show_node_list(p);
}
pub fn show_save_groups(&mut self) {
self.printer.print_nl("");
self.printer.print_ln();
let lvl = self.save.cur_level;
let mut l = lvl;
let mut boundary = self.save.cur_boundary;
let mut group = self.save.cur_group;
while group != crate::save::GroupCode::BottomLevel {
l -= 1;
self.printer.print_nl("### ");
let saved_group = self.save.cur_group;
let saved_level = self.save.cur_level;
let saved_boundary = self.save.cur_boundary;
self.save.cur_group = group;
self.save.cur_level = l;
self.save.cur_boundary = boundary;
self.print_group(true);
self.save.cur_group = saved_group;
self.save.cur_level = saved_level;
self.save.cur_boundary = saved_boundary;
match self.save.stack.get(boundary) {
Some(crate::save::SaveEntry::Boundary {
group: g,
boundary: b,
..
}) => {
group = *g;
boundary = *b;
}
_ => break,
}
}
}
}