1use crate::engine::filesystem::SourceRef;
3use crate::engine::EngineTypes;
4use crate::tex::nodes::boxes::{TeXBox, ToOrSpread, VBoxInfo};
5use crate::tex::nodes::{display_do_indent, BoxTarget, Leaders, NodeTrait, NodeType, WhatsitNode};
6use crate::tex::numerics::Skip;
7use crate::tex::numerics::TeXDimen;
8use crate::tex::tokens::token_lists::TokenList;
9
10#[derive(Clone, Debug)]
12pub enum VNode<ET: EngineTypes> {
13 Penalty(i32),
15 Mark(usize, TokenList<ET::Token>),
17 Whatsit(WhatsitNode<ET>),
19 VSkip(Skip<ET::Dim>),
21 VFil,
23 VFill,
25 VFilneg,
27 Vss,
29 VKern(ET::Dim),
31 Leaders(Leaders<ET>),
33 Box(TeXBox<ET>),
35 HRule {
37 width: Option<ET::Dim>,
39 height: Option<ET::Dim>,
41 depth: Option<ET::Dim>,
43 start: SourceRef<ET>,
45 end: SourceRef<ET>,
47 },
48 Insert(usize, Box<[VNode<ET>]>),
50 Custom(ET::CustomNode),
52}
53
54impl<ET: EngineTypes> VNode<ET> {
55 pub fn discardable(&self) -> bool {
57 use VNode::*;
58 matches!(
59 self,
60 Penalty(_) | VSkip(_) | VKern(_) | VFil | VFill | VFilneg | Vss
61 )
62 }
63}
64
65impl<ET: EngineTypes> NodeTrait<ET> for VNode<ET> {
66 fn display_fmt(&self, indent: usize, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
67 match self {
68 VNode::Penalty(p) => {
69 display_do_indent(indent, f)?;
70 write!(f, "<penalty:{}>", p)
71 }
72 VNode::Leaders(l) => l.display_fmt(indent, f),
73 VNode::VSkip(s) => write!(f, "<vskip:{}>", s),
74 VNode::VFil => write!(f, "<vfil>"),
75 VNode::VFill => write!(f, "<vfill>"),
76 VNode::VFilneg => write!(f, "<vfilneg>"),
77 VNode::Vss => write!(f, "<vss>"),
78 VNode::VKern(d) => write!(f, "<vkern:{}>", d),
79 VNode::HRule {
80 width,
81 height,
82 depth,
83 ..
84 } => {
85 write!(f, "<hrule")?;
86 if let Some(w) = width {
87 write!(f, " width={}", w)?;
88 }
89 if let Some(h) = height {
90 write!(f, " height={}", h)?;
91 }
92 if let Some(d) = depth {
93 write!(f, " depth={}", d)?;
94 }
95 write!(f, ">")
96 }
97 VNode::Box(b) => b.display_fmt(indent, f),
98 VNode::Mark(i, _) => {
99 display_do_indent(indent, f)?;
100 write!(f, "<mark:{}>", i)
101 }
102 VNode::Insert(n, ch) => {
103 display_do_indent(indent, f)?;
104 write!(f, "<insert {}>", n)?;
105 for c in ch.iter() {
106 c.display_fmt(indent + 2, f)?;
107 }
108 display_do_indent(indent, f)?;
109 write!(f, "</insert>")
110 }
111 VNode::Whatsit(w) => {
112 display_do_indent(indent, f)?;
113 write!(f, "{:?}", w)
114 }
115 VNode::Custom(n) => n.display_fmt(indent, f),
116 }
117 }
118 fn height(&self) -> ET::Dim {
119 match self {
120 VNode::VKern(d) => *d,
121 VNode::Box(b) => b.height(),
122 VNode::Leaders(l) => l.height(),
123 VNode::HRule { height, .. } => height.unwrap_or(ET::Dim::from_sp(26214)),
124 VNode::Custom(n) => n.height(),
125 VNode::VSkip(s) => s.base,
126 _ => ET::Dim::default(),
127 }
128 }
129 fn width(&self) -> ET::Dim {
130 match self {
131 VNode::Box(b) => b.width(),
132 VNode::HRule { width, .. } => width.unwrap_or_default(),
133 VNode::Custom(n) => n.width(),
134 VNode::Leaders(l) => l.width(),
135 _ => ET::Dim::default(),
136 }
137 }
138 fn depth(&self) -> ET::Dim {
139 match self {
140 VNode::Box(b) => b.depth(),
141 VNode::HRule { depth, .. } => depth.unwrap_or_default(),
142 VNode::Custom(n) => n.depth(),
143 VNode::Leaders(l) => l.depth(),
144 _ => ET::Dim::default(),
145 }
146 }
147 fn nodetype(&self) -> NodeType {
148 match self {
149 VNode::Penalty(_) => NodeType::Penalty,
150 VNode::HRule { .. } => NodeType::Rule,
151 VNode::Leaders(_) => NodeType::Glue,
152 VNode::Box(b) => b.nodetype(),
153 VNode::VKern(_) => NodeType::Kern,
154 VNode::Insert(..) => NodeType::Insertion,
155 VNode::Mark(_, _) => NodeType::Mark,
156 VNode::Whatsit(_) => NodeType::WhatsIt,
157 VNode::Custom(n) => n.nodetype(),
158 VNode::VSkip(_) | VNode::VFil | VNode::VFill | VNode::VFilneg | VNode::Vss => {
159 NodeType::Glue
160 }
161 }
162 }
163 fn opaque(&self) -> bool {
164 match self {
165 VNode::Mark(_, _) => true,
166 VNode::Custom(n) => n.opaque(),
167 _ => false,
168 }
169 }
170 fn sourceref(&self) -> Option<(&SourceRef<ET>, &SourceRef<ET>)> {
171 match self {
172 VNode::HRule { start, end, .. } => Some((start, end)),
173 VNode::Box(b) => b.sourceref(),
174 _ => None,
175 }
176 }
177}
178
179#[derive(Clone, Debug)]
181pub enum VerticalNodeListType<ET: EngineTypes> {
182 Box(VBoxInfo<ET>, SourceRef<ET>, BoxTarget<ET>),
184 Insert(usize),
186 VCenter(SourceRef<ET>, ToOrSpread<ET::Dim>),
188 VAdjust,
190 VAlignColumn(SourceRef<ET>),
192 VAlignCell(SourceRef<ET>, u8),
196 HAlign,
198 Page,
200}