1use input_context::InputContext;
5use peg::Parse;
6#[cfg(feature = "serde")]
7use serde::Serialize;
8use std::{borrow::Cow, fmt, str::FromStr};
9
10pub mod input_context;
11
12#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
13pub struct Pos {
14 pub byte_index: usize,
15}
16
17pub trait GetPos {
18 fn pos(&self) -> Pos;
19}
20
21impl<T: ?Sized + GetPos> GetPos for &'_ T {
22 fn pos(&self) -> Pos {
23 (**self).pos()
24 }
25}
26
27impl<T: ?Sized + GetPos> GetPos for &'_ mut T {
28 fn pos(&self) -> Pos {
29 (**self).pos()
30 }
31}
32
33impl GetPos for Pos {
34 fn pos(&self) -> Pos {
35 *self
36 }
37}
38
39macro_rules! impl_get_pos_simple {
40 ($name:ident) => {
41 impl GetPos for $name {
42 fn pos(&self) -> Pos {
43 self.pos
44 }
45 }
46 };
47}
48
49#[cfg(feature = "serde")]
50impl Serialize for Pos {
51 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
52 where
53 S: serde::Serializer,
54 {
55 format!("{:?}", self).serialize(serializer)
56 }
57}
58
59impl fmt::Debug for Pos {
60 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61 Self::get_input_context(|input: Option<InputContext<'_>>| match input {
62 Some(input) if input.input.get(..self.byte_index).is_some() => {
63 write!(f, "@{}", input.input.position_repr(self.byte_index))
64 }
65 _ => write!(f, "@{}", self.byte_index),
66 })
67 }
68}
69
70impl Pos {
71 pub fn new(byte_index: usize) -> Self {
72 Self { byte_index }
73 }
74}
75
76#[cfg_attr(feature = "serde", derive(Serialize))]
77#[derive(Debug, Clone)]
78pub struct Escape {
79 pub pos: Pos,
80}
81
82impl_get_pos_simple!(Escape);
83
84#[cfg_attr(feature = "serde", derive(Serialize))]
85#[derive(Debug, Clone)]
86pub struct BeginGroup {
87 pub pos: Pos,
88}
89
90impl_get_pos_simple!(BeginGroup);
91
92#[cfg_attr(feature = "serde", derive(Serialize))]
93#[derive(Debug, Clone)]
94pub struct EndGroup {
95 pub pos: Pos,
96}
97
98impl_get_pos_simple!(EndGroup);
99
100#[cfg_attr(feature = "serde", derive(Serialize))]
101#[derive(Debug, Clone)]
102pub struct AlignmentTab {
103 pub pos: Pos,
104}
105
106impl_get_pos_simple!(AlignmentTab);
107
108#[cfg_attr(feature = "serde", derive(Serialize))]
109#[derive(Debug, Clone)]
110pub struct MacroParameter {
111 pub pos: Pos,
112}
113
114impl_get_pos_simple!(MacroParameter);
115
116#[cfg_attr(feature = "serde", derive(Serialize))]
117#[derive(Debug, Clone)]
118pub struct CommentStart {
119 pub pos: Pos,
120}
121
122impl_get_pos_simple!(CommentStart);
123
124#[cfg_attr(feature = "serde", derive(Serialize))]
125#[derive(Debug, Clone)]
126pub struct MathShift {
127 pub pos: Pos,
128}
129
130impl_get_pos_simple!(MathShift);
131
132#[cfg_attr(feature = "serde", derive(Serialize))]
133#[derive(Debug, Clone)]
134pub struct Superscript {
135 pub pos: Pos,
136}
137
138impl_get_pos_simple!(Superscript);
139
140#[cfg_attr(feature = "serde", derive(Serialize))]
141#[derive(Debug, Clone)]
142pub struct Subscript {
143 pub pos: Pos,
144}
145
146impl_get_pos_simple!(Subscript);
147
148#[cfg_attr(feature = "serde", derive(Serialize))]
149#[derive(Debug, Clone)]
150pub struct Ignore {
151 pub pos: Pos,
152}
153
154impl_get_pos_simple!(Ignore);
155
156#[cfg_attr(feature = "serde", derive(Serialize))]
157#[derive(Debug, Clone)]
158pub struct AnyChar {
159 pub pos: Pos,
160 pub ch: char,
161}
162
163impl_get_pos_simple!(AnyChar);
164
165#[cfg_attr(feature = "serde", derive(Serialize))]
166#[derive(Debug, Clone)]
167pub struct Punctuation {
168 pub pos: Pos,
169 pub ch: char,
170}
171
172impl_get_pos_simple!(Punctuation);
173
174#[cfg_attr(feature = "serde", derive(Serialize))]
175#[derive(Debug, Clone)]
176pub struct Space {
177 pub pos: Pos,
178}
179
180impl_get_pos_simple!(Space);
181
182#[cfg_attr(feature = "serde", derive(Serialize))]
183#[derive(Debug, Clone)]
184pub struct AsciiAlphabetic {
185 pub pos: Pos,
186}
187
188impl_get_pos_simple!(AsciiAlphabetic);
189
190#[cfg_attr(feature = "serde", derive(Serialize))]
191#[derive(Debug, Clone)]
192pub struct AsciiDigit {
193 pub pos: Pos,
194}
195
196impl_get_pos_simple!(AsciiDigit);
197
198#[cfg_attr(feature = "serde", derive(Serialize))]
199#[derive(Debug, Clone)]
200pub struct NewLine {
201 pub pos: Pos,
202}
203
204impl_get_pos_simple!(NewLine);
205
206#[cfg_attr(feature = "serde", derive(Serialize))]
207#[derive(Debug, Clone)]
208pub struct CharToken {
209 pub pos: Pos,
210}
211
212impl_get_pos_simple!(CharToken);
213
214#[cfg_attr(feature = "serde", derive(Serialize))]
215#[derive(Debug, Clone)]
216pub struct CharTokens {
217 pub pos: Pos,
218 pub content: String,
219}
220
221impl CharTokens {
222 pub fn split_off(&mut self, index: usize) -> Self {
223 let content = self.content.split_off(index);
224 Self {
225 pos: Pos {
226 byte_index: self.pos.byte_index + index,
227 },
228 content,
229 }
230 }
231 pub fn split_at(mut self, index: usize) -> (Self, Self) {
232 let tail = self.split_off(index);
233 (self, tail)
234 }
235}
236
237impl_get_pos_simple!(CharTokens);
238
239#[cfg_attr(feature = "serde", derive(Serialize))]
240#[derive(Debug, Clone)]
241pub struct Document {
242 pub content: Vec<Token>,
243}
244
245impl GetPos for Document {
246 fn pos(&self) -> Pos {
247 self.content
248 .first()
249 .map_or(Pos { byte_index: 0 }, GetPos::pos)
250 }
251}
252
253macro_rules! declare_nested_access_fns {
254 ($alternative:ident($alternative_fn:ident, $alternative_mut_fn:ident, $into_alternative_fn:ident), ($outer_alternative_fn:ident, $outer_alternative_mut_fn:ident, $outer_into_alternative_fn:ident)) => {
255 pub fn $alternative_fn(&self) -> Option<&$alternative> {
256 self.$outer_alternative_fn()?.$alternative_fn()
257 }
258 pub fn $alternative_mut_fn(&mut self) -> Option<&mut $alternative> {
259 self.$outer_alternative_mut_fn()?.$alternative_mut_fn()
260 }
261 pub fn $into_alternative_fn(self) -> Option<$alternative> {
262 self.$outer_into_alternative_fn()?.$into_alternative_fn()
263 }
264 };
265}
266
267macro_rules! declare_transparent_enum {
268 (
269 #[serde(tag = $tag:literal)]
270 #[access_fns_macro = $access_fns_macro:ident]
271 enum $name:ident {
272 $(
273 $(#[nested_access_fns = $nested_access_fns:ident])?
274 $alternative:ident($alternative_fn:ident, $alternative_mut_fn:ident, $into_alternative_fn:ident),
275 )+
276 }
277 ) => {
278 #[cfg_attr(feature = "serde", derive(Serialize))]
279 #[derive(Clone)]
280 #[cfg_attr(feature = "serde", serde(tag = $tag))]
281 pub enum $name {
282 $($alternative($alternative),)+
283 }
284
285 #[allow(unused_macros)]
286 macro_rules! $access_fns_macro {
287 ($m:ident!($tt:tt)) => {
288 $($m!($alternative($alternative_fn, $alternative_mut_fn, $into_alternative_fn), $tt);)+
289 };
290 }
291
292 impl $name {
293 $(
294 pub fn $alternative_fn(&self) -> Option<&$alternative> {
295 if let Self::$alternative(v) = self {
296 Some(v)
297 } else {
298 None
299 }
300 }
301 pub fn $alternative_mut_fn(&mut self) -> Option<&mut $alternative> {
302 if let Self::$alternative(v) = self {
303 Some(v)
304 } else {
305 None
306 }
307 }
308 pub fn $into_alternative_fn(self) -> Option<$alternative> {
309 if let Self::$alternative(v) = self {
310 Some(v)
311 } else {
312 None
313 }
314 }
315 $(
316 $nested_access_fns!(declare_nested_access_fns!(($alternative_fn, $alternative_mut_fn, $into_alternative_fn)));
317 )?
318 )+
319 }
320
321 impl GetPos for $name {
322 fn pos(&self) -> Pos {
323 match self {
324 $(Self::$alternative(v) => v.pos(),)+
325 }
326 }
327 }
328
329 impl fmt::Debug for $name {
330 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
331 match self {
332 $(Self::$alternative(v) => fmt::Debug::fmt(v, f),)+
333 }
334 }
335 }
336 };
337}
338
339declare_transparent_enum! {
340 #[serde(tag = "special_macro_type")]
341 #[access_fns_macro = special_macro_access_fns]
342 enum SpecialMacro {
343 Verb(verb, verb_mut, into_verb),
344 VerbatimEnvironment(verbatim_environment, verbatim_environment_mut, into_verbatim_environment),
345 DisplayMath(display_math, display_math_mut, into_display_math),
346 ParenthesizedInlineMath(parenthesized_inline_math, parenthesized_inline_math_mut, into_parenthesized_inline_math),
347 MathEnvironment(math_environment, math_environment_mut, into_math_environment),
348 Environment(environment, environment_mut, into_environment),
349 }
350}
351
352declare_transparent_enum! {
353 #[serde(tag = "token_type")]
354 #[access_fns_macro = token_access_fns]
355 enum Token {
356 #[nested_access_fns = special_macro_access_fns]
357 SpecialMacro(special_macro, special_macro_mut, into_special_macro),
358 Macro(macro_, macro_mut, into_macro),
359 FullComment(full_comment, full_comment_mut, into_full_comment),
360 Group(group, group_mut, into_group),
361 DollarInlineMath(dollar_inline_math, dollar_inline_math_mut, into_dollar_inline_math),
362 AlignmentTab(alignment_tab, alignment_tab_mut, into_alignment_tab),
363 ParBreak(par_break, par_break_mut, into_par_break),
364 MacroParameter(macro_parameter, macro_parameter_mut, into_macro_parameter),
365 Ignore(ignore, ignore_mut, into_ignore),
366 Number(number, number_mut, into_number),
367 Whitespace(whitespace, whitespace_mut, into_whitespace),
368 Punctuation(punctuation, punctuation_mut, into_punctuation),
369 CharTokens(char_tokens, char_tokens_mut, into_char_tokens),
370 BeginGroup(begin_group, begin_group_mut, into_begin_group),
371 EndGroup(end_group, end_group_mut, into_end_group),
372 MathShift(math_shift, math_shift_mut, into_math_shift),
373 }
374}
375
376pub struct SplitCharTokensIter<Iter> {
377 next_chars: Option<CharTokens>,
378 iter: Iter,
379}
380
381impl<Iter: Iterator> SplitCharTokensIter<Iter> {
382 pub fn new<T: IntoIterator<IntoIter = Iter>>(iter: T) -> Self {
383 Self {
384 next_chars: None,
385 iter: iter.into_iter(),
386 }
387 }
388 pub fn into(self) -> (Option<CharTokens>, Iter) {
389 (self.next_chars, self.iter)
390 }
391 fn take_first_char(&mut self, next_chars: Option<CharTokens>) -> Option<CharTokens> {
392 let next_chars = next_chars?;
393 let ch = next_chars.content.chars().next()?;
394 let (retval, rest) = next_chars.split_at(ch.len_utf8());
395 if !rest.content.is_empty() {
396 self.next_chars = Some(rest);
397 }
398 Some(retval)
399 }
400}
401
402mod sealed {
403 pub trait Sealed {}
404 impl Sealed for super::Token {}
405 impl Sealed for &'_ super::Token {}
406}
407
408pub trait SplitCharTokensIterHelper: Sized + sealed::Sealed {
409 type Item;
410 fn next<I: Iterator<Item = Self>>(this: &mut SplitCharTokensIter<I>) -> Option<Self::Item>;
411}
412
413impl SplitCharTokensIterHelper for Token {
414 type Item = Token;
415
416 fn next<I: Iterator<Item = Self>>(this: &mut SplitCharTokensIter<I>) -> Option<Self::Item> {
417 let next_chars = this.next_chars.take();
418 if let Some(retval) = this.take_first_char(next_chars) {
419 return Some(Token::CharTokens(retval));
420 }
421 loop {
422 match this.iter.next()? {
423 Token::CharTokens(next_chars) => {
424 if let Some(retval) = this.take_first_char(Some(next_chars)) {
425 return Some(Token::CharTokens(retval));
426 }
427 }
428 retval => return Some(retval),
429 }
430 }
431 }
432}
433
434impl<'a> SplitCharTokensIterHelper for &'a Token {
435 type Item = Cow<'a, Token>;
436
437 fn next<I: Iterator<Item = Self>>(this: &mut SplitCharTokensIter<I>) -> Option<Self::Item> {
438 let next_chars = this.next_chars.take();
439 if let Some(retval) = this.take_first_char(next_chars) {
440 return Some(Cow::Owned(Token::CharTokens(retval)));
441 }
442 loop {
443 match this.iter.next()? {
444 Token::CharTokens(next_chars) => {
445 if let Some(retval) = this.take_first_char(Some(next_chars.clone())) {
446 return Some(Cow::Owned(Token::CharTokens(retval)));
447 }
448 }
449 retval => return Some(Cow::Borrowed(retval)),
450 }
451 }
452 }
453}
454
455impl<I, Item> Iterator for SplitCharTokensIter<I>
456where
457 I: Iterator<Item = Item>,
458 Item: SplitCharTokensIterHelper,
459{
460 type Item = Item::Item;
461
462 fn next(&mut self) -> Option<Self::Item> {
463 Item::next(self)
464 }
465}
466
467declare_transparent_enum! {
468 #[serde(tag = "math_token_type")]
469 #[access_fns_macro = math_token_access_fns]
470 enum MathToken {
471 #[nested_access_fns = special_macro_access_fns]
472 SpecialMacro(special_macro, special_macro_mut, into_special_macro),
473 Macro(macro_, macro_mut, into_macro),
474 FullComment(full_comment, full_comment_mut, into_full_comment),
475 MathGroup(math_group, math_group_mut, into_math_group),
476 AlignmentTab(alignment_tab, alignment_tab_mut, into_alignment_tab),
477 MacroParameter(macro_parameter, macro_parameter_mut, into_macro_parameter),
478 Superscript(superscript, superscript_mut, into_superscript),
479 Subscript(subscript, subscript_mut, into_subscript),
480 Ignore(ignore, ignore_mut, into_ignore),
481 Whitespace(whitespace, whitespace_mut, into_whitespace),
482 Number(number, number_mut, number_char),
483 AnyChar(any_char, any_char_mut, into_any_char),
484 }
485}
486
487#[cfg_attr(feature = "serde", derive(Serialize))]
488#[derive(Debug, Clone)]
489pub struct Verb {
490 pub escape: Escape,
491 pub env: String,
492 pub delimiter: char,
493 pub content: String,
494}
495
496impl GetPos for Verb {
497 fn pos(&self) -> Pos {
498 self.escape.pos()
499 }
500}
501
502#[cfg_attr(feature = "serde", derive(Serialize))]
503#[derive(Debug, Clone)]
504pub struct ParenthesizedInlineMath {
505 pub begin: BeginInlineMath,
506 pub content: Vec<MathToken>,
507 pub end: EndInlineMath,
508}
509
510impl ParenthesizedInlineMath {
511 pub fn content_pos(&self) -> Pos {
512 self.content.first().map_or(self.end.pos(), GetPos::pos)
513 }
514}
515
516impl GetPos for ParenthesizedInlineMath {
517 fn pos(&self) -> Pos {
518 self.begin.pos()
519 }
520}
521
522#[cfg_attr(feature = "serde", derive(Serialize))]
523#[derive(Debug, Clone)]
524pub struct DollarInlineMath {
525 pub begin: MathShift,
526 pub content: Vec<MathToken>,
527 pub end: MathShift,
528}
529
530impl DollarInlineMath {
531 pub fn content_pos(&self) -> Pos {
532 self.content.first().map_or(self.end.pos(), GetPos::pos)
533 }
534}
535
536impl GetPos for DollarInlineMath {
537 fn pos(&self) -> Pos {
538 self.begin.pos()
539 }
540}
541
542#[cfg_attr(feature = "serde", derive(Serialize))]
543#[derive(Debug, Clone)]
544pub struct VerbatimEnvironment {
545 pub begin: BeginEnvironment,
546 pub name: VerbatimEnvironmentName,
547 pub body: String,
548 pub end: EndEnvironment,
549}
550
551impl GetPos for VerbatimEnvironment {
552 fn pos(&self) -> Pos {
553 self.begin.pos()
554 }
555}
556
557#[cfg_attr(feature = "serde", derive(Serialize))]
558#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
559pub enum VerbatimEnvironmentNameKind {
560 VerbatimStar,
561 Verbatim,
562 FileContentsStar,
563 FileContents,
564 Comment,
565 ListListing,
566}
567
568#[cfg_attr(feature = "serde", derive(Serialize))]
569#[derive(Debug, Clone)]
570pub struct VerbatimEnvironmentName {
571 pub pos: Pos,
572 pub kind: VerbatimEnvironmentNameKind,
573}
574
575impl_get_pos_simple!(VerbatimEnvironmentName);
576
577#[cfg_attr(feature = "serde", derive(Serialize))]
578#[derive(Debug, Clone)]
579pub struct DisplayMath {
580 pub pos: Pos,
581 pub content: Vec<MathToken>,
582}
583
584impl_get_pos_simple!(DisplayMath);
585
586#[cfg_attr(feature = "serde", derive(Serialize))]
587#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
588pub enum MathEnvironmentNameKind {
589 EquationStar,
590 Equation,
591 AlignStar,
592 Align,
593 AlignAtStar,
594 AlignAt,
595 GatherStar,
596 Gather,
597 MultiLineStar,
598 MultiLine,
599 FlAlignStar,
600 FlAlign,
601 Split,
602 Math,
603 DisplayMath,
604}
605
606#[cfg_attr(feature = "serde", derive(Serialize))]
607#[derive(Debug, Clone)]
608pub struct MathEnvironmentName {
609 pub pos: Pos,
610 pub kind: MathEnvironmentNameKind,
611}
612
613impl_get_pos_simple!(MathEnvironmentName);
614
615#[cfg_attr(feature = "serde", derive(Serialize))]
616#[derive(Debug, Clone)]
617pub struct MathEnvironment {
618 pub begin: BeginEnvironment,
619 pub name: MathEnvironmentName,
620 pub environment_comment: Option<SameLineComment>,
621 pub body: Vec<MathToken>,
622 pub end: EndEnvironment,
623}
624
625impl MathEnvironment {
626 pub fn environment_comment_pos(&self) -> Pos {
627 self.environment_comment
628 .as_ref()
629 .map_or_else(|| self.body_pos(), GetPos::pos)
630 }
631 pub fn body_pos(&self) -> Pos {
632 self.body.first().map_or(self.end.pos(), GetPos::pos)
633 }
634}
635
636impl GetPos for MathEnvironment {
637 fn pos(&self) -> Pos {
638 self.begin.pos()
639 }
640}
641
642#[cfg_attr(feature = "serde", derive(Serialize))]
643#[derive(Debug, Clone)]
644pub struct Environment {
645 pub begin: BeginEnvironment,
646 pub name: CharTokens,
647 pub body: Vec<Token>,
648 pub end: EndEnvironment,
649}
650
651impl Environment {
652 pub fn body_pos(&self) -> Pos {
653 self.body.first().map_or(self.end.pos(), GetPos::pos)
654 }
655}
656
657impl GetPos for Environment {
658 fn pos(&self) -> Pos {
659 self.begin.pos()
660 }
661}
662
663#[cfg_attr(feature = "serde", derive(Serialize))]
664#[derive(Debug, Clone)]
665pub struct Number {
666 pub pos: Pos,
667 pub content: String,
668}
669
670impl Number {
671 pub fn parse<T: FromStr>(&self) -> Result<T, T::Err> {
672 self.content.parse()
673 }
674 pub fn parse_with_err_arg<T: FromStr, E, A, ErrFn: FnOnce(A, Pos, String) -> E>(
675 &self,
676 err_fn_arg: A,
677 err_fn: ErrFn,
678 ) -> Result<T, E>
679 where
680 T::Err: fmt::Display,
681 {
682 self.parse()
683 .map_err(|e: T::Err| err_fn(err_fn_arg, self.pos, e.to_string()))
684 }
685}
686
687impl_get_pos_simple!(Number);
688
689#[cfg_attr(feature = "serde", derive(Serialize))]
690#[derive(Debug, Clone)]
691pub struct Group {
692 pub begin: BeginGroup,
693 pub tokens: Vec<Token>,
694 pub end: EndGroup,
695}
696
697impl Group {
698 pub fn tokens_pos(&self) -> Pos {
699 self.tokens.first().map_or(self.end.pos(), GetPos::pos)
700 }
701}
702
703impl GetPos for Group {
704 fn pos(&self) -> Pos {
705 self.begin.pos()
706 }
707}
708
709#[cfg_attr(feature = "serde", derive(Serialize))]
710#[derive(Debug, Clone)]
711pub struct MathGroup {
712 pub begin: BeginGroup,
713 pub tokens: Vec<MathToken>,
714 pub end: EndGroup,
715}
716
717impl MathGroup {
718 pub fn tokens_pos(&self) -> Pos {
719 self.tokens.first().map_or(self.end.pos(), GetPos::pos)
720 }
721}
722
723impl GetPos for MathGroup {
724 fn pos(&self) -> Pos {
725 self.begin.pos()
726 }
727}
728
729#[cfg_attr(feature = "serde", derive(Serialize))]
730#[derive(Debug, Clone)]
731pub struct Whitespace {
732 pub pos: Pos,
733}
734
735impl_get_pos_simple!(Whitespace);
736
737declare_transparent_enum! {
738 #[serde(tag = "comment_type")]
739 #[access_fns_macro = full_comment_access_fns]
740 enum FullComment {
741 OwnLineComment(own_line_comment, own_line_comment_mut, into_own_line_comment),
742 SameLineComment(same_line_comment, same_line_comment_mut, into_same_line_comment),
743 }
744}
745
746#[cfg_attr(feature = "serde", derive(Serialize))]
747#[derive(Debug, Clone)]
748pub struct OwnLineComment {
749 pub pos: Pos,
750 pub leading_space: LeadingSpace,
751 pub comment: Comment,
752}
753
754impl_get_pos_simple!(OwnLineComment);
755
756#[cfg_attr(feature = "serde", derive(Serialize))]
757#[derive(Debug, Clone)]
758pub struct SameLineComment {
759 pub pos: Pos,
760 pub leading_spaces: bool,
761 pub comment: Comment,
762}
763
764impl_get_pos_simple!(SameLineComment);
765
766#[cfg_attr(feature = "serde", derive(Serialize))]
767#[derive(Debug, Clone)]
768pub struct LeadingSpace {
769 pub pos: Pos,
770 pub empty: bool,
771}
772
773impl_get_pos_simple!(LeadingSpace);
774
775#[cfg_attr(feature = "serde", derive(Serialize))]
776#[derive(Debug, Clone)]
777pub struct Comment {
778 pub comment_start: CommentStart,
779 pub content: String,
780}
781
782#[cfg_attr(feature = "serde", derive(Serialize))]
783#[derive(Debug, Clone)]
784pub struct ParBreak {
785 pub pos: Pos,
786}
787
788impl_get_pos_simple!(ParBreak);
789
790#[cfg_attr(feature = "serde", derive(Serialize))]
791#[derive(Debug, Clone)]
792pub struct MacroName {
793 pub pos: Pos,
794 pub content: String,
795}
796
797impl_get_pos_simple!(MacroName);
798
799#[cfg_attr(feature = "serde", derive(Serialize))]
800#[derive(Debug, Clone)]
801pub struct Macro {
802 pub escape: Escape,
803 pub name: MacroName,
804}
805
806impl GetPos for Macro {
807 fn pos(&self) -> Pos {
808 self.escape.pos()
809 }
810}
811
812#[cfg_attr(feature = "serde", derive(Serialize))]
813#[derive(Debug, Clone)]
814pub struct BeginDisplayMath {
815 pub escape: Escape,
816}
817
818impl GetPos for BeginDisplayMath {
819 fn pos(&self) -> Pos {
820 self.escape.pos()
821 }
822}
823
824#[cfg_attr(feature = "serde", derive(Serialize))]
825#[derive(Debug, Clone)]
826pub struct EndDisplayMath {
827 pub escape: Escape,
828}
829
830impl GetPos for EndDisplayMath {
831 fn pos(&self) -> Pos {
832 self.escape.pos()
833 }
834}
835
836#[cfg_attr(feature = "serde", derive(Serialize))]
837#[derive(Debug, Clone)]
838pub struct BeginInlineMath {
839 pub escape: Escape,
840}
841
842impl GetPos for BeginInlineMath {
843 fn pos(&self) -> Pos {
844 self.escape.pos()
845 }
846}
847
848#[cfg_attr(feature = "serde", derive(Serialize))]
849#[derive(Debug, Clone)]
850pub struct EndInlineMath {
851 pub escape: Escape,
852}
853
854impl GetPos for EndInlineMath {
855 fn pos(&self) -> Pos {
856 self.escape.pos()
857 }
858}
859
860#[cfg_attr(feature = "serde", derive(Serialize))]
861#[derive(Debug, Clone)]
862pub struct BeginEnvironment {
863 pub escape: Escape,
864}
865
866impl GetPos for BeginEnvironment {
867 fn pos(&self) -> Pos {
868 self.escape.pos()
869 }
870}
871
872#[cfg_attr(feature = "serde", derive(Serialize))]
873#[derive(Debug, Clone)]
874pub struct EndEnvironment {
875 pub escape: Escape,
876}
877
878impl GetPos for EndEnvironment {
879 fn pos(&self) -> Pos {
880 self.escape.pos()
881 }
882}