1use std::slice::Iter;
2
3use crate::{
4 HasSpan, Parser, Span,
5 attributes::Attrlist,
6 blocks::{
7 AdmonitionBlock, Break, CompoundDelimitedBlock, ContentModel, IsBlock, ListBlock, ListItem,
8 ListItemMarker, MediaBlock, Preamble, QuoteBlock, RawDelimitedBlock, SectionBlock,
9 SimpleBlock, TableBlock, media::TargetResolution, metadata::BlockMetadata,
10 starts_with_admonition_label,
11 },
12 content::{Content, SubstitutionGroup},
13 document::{Attribute, RefType},
14 parser::{InlineSubstitutionRenderer, ReferenceResolver, ReferenceWarning},
15 span::MatchedItem,
16 strings::CowStr,
17 warnings::{MatchAndWarnings, Warning, WarningType},
18};
19
20#[derive(Clone, Eq, PartialEq)]
33#[allow(clippy::large_enum_variant)] #[non_exhaustive]
35pub enum Block<'src> {
36 Simple(SimpleBlock<'src>),
39
40 Media(MediaBlock<'src>),
43
44 Section(SectionBlock<'src>),
47
48 List(ListBlock<'src>),
52
53 ListItem(ListItem<'src>),
56
57 RawDelimited(RawDelimitedBlock<'src>),
61
62 CompoundDelimited(CompoundDelimitedBlock<'src>),
64
65 Admonition(AdmonitionBlock<'src>),
69
70 Quote(QuoteBlock<'src>),
73
74 Table(TableBlock<'src>),
76
77 Preamble(Preamble<'src>),
80
81 Break(Break<'src>),
83
84 DocumentAttribute(Attribute<'src>),
87}
88
89impl<'src> std::fmt::Debug for Block<'src> {
90 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
91 match self {
92 Block::Simple(block) => f.debug_tuple("Block::Simple").field(block).finish(),
93 Block::Media(block) => f.debug_tuple("Block::Media").field(block).finish(),
94 Block::Section(block) => f.debug_tuple("Block::Section").field(block).finish(),
95 Block::List(block) => f.debug_tuple("Block::List").field(block).finish(),
96 Block::ListItem(block) => f.debug_tuple("Block::ListItem").field(block).finish(),
97
98 Block::RawDelimited(block) => {
99 f.debug_tuple("Block::RawDelimited").field(block).finish()
100 }
101
102 Block::CompoundDelimited(block) => f
103 .debug_tuple("Block::CompoundDelimited")
104 .field(block)
105 .finish(),
106
107 Block::Admonition(block) => f.debug_tuple("Block::Admonition").field(block).finish(),
108 Block::Quote(block) => f.debug_tuple("Block::Quote").field(block).finish(),
109 Block::Table(block) => f.debug_tuple("Block::Table").field(block).finish(),
110 Block::Preamble(block) => f.debug_tuple("Block::Preamble").field(block).finish(),
111 Block::Break(break_) => f.debug_tuple("Block::Break").field(break_).finish(),
112
113 Block::DocumentAttribute(block) => f
114 .debug_tuple("Block::DocumentAttribute")
115 .field(block)
116 .finish(),
117 }
118 }
119}
120
121#[allow(clippy::large_enum_variant)]
133pub(crate) enum BlockParseOutcome<'src> {
134 Parsed(MatchedItem<'src, Block<'src>>),
136
137 Dropped(Span<'src>),
142
143 NoMatch,
145}
146
147impl<'src> Block<'src> {
148 #[cfg(test)]
157 pub(crate) fn parse(
158 source: Span<'src>,
159 parser: &mut Parser,
160 ) -> MatchAndWarnings<'src, Option<MatchedItem<'src, Self>>> {
161 let MatchAndWarnings { item, warnings } = Self::parse_internal(source, parser, None, false);
162
163 MatchAndWarnings {
164 item: match item {
165 BlockParseOutcome::Parsed(mi) => Some(mi),
166 BlockParseOutcome::Dropped(_) | BlockParseOutcome::NoMatch => None,
167 },
168 warnings,
169 }
170 }
171
172 pub(crate) fn parse_with_outcome(
179 source: Span<'src>,
180 parser: &mut Parser,
181 ) -> MatchAndWarnings<'src, BlockParseOutcome<'src>> {
182 Self::parse_internal(source, parser, None, false)
183 }
184
185 pub(crate) fn parse_for_list_item(
196 source: Span<'src>,
197 parser: &mut Parser,
198 parent_list_markers: &[ListItemMarker<'src>],
199 is_continuation: bool,
200 ) -> MatchAndWarnings<'src, BlockParseOutcome<'src>> {
201 Self::parse_internal(source, parser, Some(parent_list_markers), is_continuation)
202 }
203
204 fn parse_internal(
207 source: Span<'src>,
208 parser: &mut Parser,
209 parent_list_markers: Option<&[ListItemMarker<'src>]>,
210 is_continuation: bool,
211 ) -> MatchAndWarnings<'src, BlockParseOutcome<'src>> {
212 let first_line = source.take_line().item.discard_whitespace();
216
217 if let Some(first_char) = first_line.chars().next()
220 && !matches!(
221 first_char,
222 '.' | '#'
223 | '='
224 | '/'
225 | '-'
226 | '+'
227 | '*'
228 | '_'
229 | '['
230 | ':'
231 | '\''
232 | '<'
233 | '>'
234 | '"'
235 | '•'
236 )
237 && !first_line.contains("::")
238 && !first_line.contains(";;")
239 && !TableBlock::is_table_delimiter(&first_line)
240 && !ListItemMarker::starts_with_marker(first_line)
241 && !starts_with_admonition_label(first_line)
242 && parent_list_markers.is_none()
243 && let Some(MatchedItem {
244 item: simple_block,
245 after,
246 }) = SimpleBlock::parse_fast(source, parser)
247 {
248 let mut warnings = vec![];
249 let block = Self::Simple(simple_block);
250
251 Self::register_block_id(
252 block.id(),
253 Self::block_reftext(&block),
254 block.span(),
255 parser,
256 &mut warnings,
257 );
258
259 return MatchAndWarnings {
260 item: BlockParseOutcome::Parsed(MatchedItem { item: block, after }),
261 warnings,
262 };
263 }
264
265 if first_line.starts_with(':')
267 && (first_line.ends_with(':') || first_line.contains(": "))
268 && let Some(attr) = Attribute::parse(source, parser)
269 {
270 let mut warnings: Vec<Warning<'src>> = vec![];
271 parser.set_attribute_from_body(&attr.item, &mut warnings);
272
273 return MatchAndWarnings {
274 item: BlockParseOutcome::Parsed(MatchedItem {
275 item: Self::DocumentAttribute(attr.item),
276 after: attr.after,
277 }),
278 warnings,
279 };
280 }
281
282 let MatchAndWarnings {
285 item: mut metadata,
286 mut warnings,
287 } = BlockMetadata::parse(source, parser);
288
289 let is_literal = metadata.attrlist.as_ref().and_then(|a| a.block_style())
295 == Some("literal")
296 && metadata.block_start.take_normalized_line().item.data() != "--";
297
298 let mut simple_block_mi = None;
305
306 if !is_literal {
307 if let Some(mut adm_maw) = AdmonitionBlock::parse(&metadata, parser)
308 && let Some(adm) = adm_maw.item
309 {
310 if !adm_maw.warnings.is_empty() {
311 warnings.append(&mut adm_maw.warnings);
312 }
313
314 let block = Self::Admonition(adm.item);
315
316 Self::register_block_id(
317 block.id(),
318 Self::block_reftext(&block),
319 block.span(),
320 parser,
321 &mut warnings,
322 );
323
324 return MatchAndWarnings {
325 item: BlockParseOutcome::Parsed(MatchedItem {
326 item: block,
327 after: adm.after,
328 }),
329 warnings,
330 };
331 }
332
333 if let Some(mut quote_maw) = QuoteBlock::parse(&metadata, parser)
334 && let Some(quote) = quote_maw.item
335 {
336 if !quote_maw.warnings.is_empty() {
337 warnings.append(&mut quote_maw.warnings);
338 }
339
340 let block = Self::Quote(quote.item);
341
342 Self::register_block_id(
343 block.id(),
344 Self::block_reftext(&block),
345 block.span(),
346 parser,
347 &mut warnings,
348 );
349
350 return MatchAndWarnings {
351 item: BlockParseOutcome::Parsed(MatchedItem {
352 item: block,
353 after: quote.after,
354 }),
355 warnings,
356 };
357 }
358
359 if let Some(mut rdb_maw) = RawDelimitedBlock::parse(&metadata, parser)
360 && let Some(rdb) = rdb_maw.item
361 {
362 if !rdb_maw.warnings.is_empty() {
363 warnings.append(&mut rdb_maw.warnings);
364 }
365
366 let block = Self::RawDelimited(rdb.item);
367
368 Self::register_block_id(
369 block.id(),
370 Self::block_reftext(&block),
371 block.span(),
372 parser,
373 &mut warnings,
374 );
375
376 return MatchAndWarnings {
377 item: BlockParseOutcome::Parsed(MatchedItem {
378 item: block,
379 after: rdb.after,
380 }),
381 warnings,
382 };
383 }
384
385 if let Some(mut cdb_maw) = CompoundDelimitedBlock::parse(&metadata, parser)
386 && let Some(cdb) = cdb_maw.item
387 {
388 if !cdb_maw.warnings.is_empty() {
389 warnings.append(&mut cdb_maw.warnings);
390 }
391
392 let block = Self::CompoundDelimited(cdb.item);
393
394 Self::register_block_id(
395 block.id(),
396 Self::block_reftext(&block),
397 block.span(),
398 parser,
399 &mut warnings,
400 );
401
402 return MatchAndWarnings {
403 item: BlockParseOutcome::Parsed(MatchedItem {
404 item: block,
405 after: cdb.after,
406 }),
407 warnings,
408 };
409 }
410
411 if let Some(mut table_maw) = TableBlock::parse(&metadata, parser)
412 && let Some(table) = table_maw.item
413 {
414 if !table_maw.warnings.is_empty() {
415 warnings.append(&mut table_maw.warnings);
416 }
417
418 let block = Self::Table(table.item);
419
420 Self::register_block_id(
421 block.id(),
422 Self::block_reftext(&block),
423 block.span(),
424 parser,
425 &mut warnings,
426 );
427
428 return MatchAndWarnings {
429 item: BlockParseOutcome::Parsed(MatchedItem {
430 item: block,
431 after: table.after,
432 }),
433 warnings,
434 };
435 }
436
437 let line = metadata.block_start.take_normalized_line();
439
440 if line.item.starts_with("image::")
441 || line.item.starts_with("video::")
442 || line.item.starts_with("audio::")
443 {
444 let mut media_block_maw = MediaBlock::parse(&metadata, parser);
445
446 if let Some(mut media_block) = media_block_maw.item {
447 if !media_block_maw.warnings.is_empty() {
451 warnings.append(&mut media_block_maw.warnings);
452 }
453
454 if media_block.item.resolve_target(parser) == TargetResolution::Drop {
458 return MatchAndWarnings {
459 item: BlockParseOutcome::Dropped(media_block.after),
460 warnings,
461 };
462 }
463
464 let block = Self::Media(media_block.item);
465
466 Self::register_block_id(
467 block.id(),
468 Self::block_reftext(&block),
469 block.span(),
470 parser,
471 &mut warnings,
472 );
473
474 return MatchAndWarnings {
475 item: BlockParseOutcome::Parsed(MatchedItem {
476 item: block,
477 after: media_block.after,
478 }),
479 warnings,
480 };
481 }
482
483 }
486
487 if (line.item.starts_with('=') || line.item.starts_with('#'))
488 && let Some(mi_section_block) =
489 SectionBlock::parse(&metadata, parser, &mut warnings)
490 {
491 return MatchAndWarnings {
495 item: BlockParseOutcome::Parsed(MatchedItem {
496 item: Self::Section(mi_section_block.item),
497 after: mi_section_block.after,
498 }),
499 warnings,
500 };
501 }
502
503 if (line.item.starts_with('\'')
504 || line.item.starts_with('-')
505 || line.item.starts_with('*')
506 || line.item.starts_with('<'))
507 && let Some(mi_break) = Break::parse(&metadata, parser)
508 {
509 return MatchAndWarnings {
512 item: BlockParseOutcome::Parsed(MatchedItem {
513 item: Self::Break(mi_break.item),
514 after: mi_break.after,
515 }),
516 warnings,
517 };
518 }
519
520 if parent_list_markers.is_none()
524 && let Some(mi_list) = ListBlock::parse(&metadata, parser, &mut warnings)
525 {
526 return MatchAndWarnings {
527 item: BlockParseOutcome::Parsed(MatchedItem {
528 item: Self::List(mi_list.item),
529 after: mi_list.after,
530 }),
531 warnings,
532 };
533 }
534
535 simple_block_mi = if let Some(plm) = parent_list_markers {
542 SimpleBlock::parse_for_list_item(&metadata, parser, is_continuation, plm)
543 } else {
544 SimpleBlock::parse(&metadata, parser)
545 };
546
547 if simple_block_mi.is_none() && !metadata.is_empty() {
548 warnings.push(Warning {
552 source: metadata.source,
553 warning: WarningType::MissingBlockAfterTitleOrAttributeList,
554 });
555
556 metadata.title_source = None;
560 metadata.title = None;
561 metadata.anchor = None;
562 metadata.attrlist = None;
563 metadata.block_start = metadata.source;
564 }
565 }
566
567 let simple_block_mi = match simple_block_mi {
571 Some(mi) => Some(mi),
572 None => {
573 if let Some(plm) = parent_list_markers {
574 SimpleBlock::parse_for_list_item(&metadata, parser, is_continuation, plm)
575 } else {
576 SimpleBlock::parse(&metadata, parser)
577 }
578 }
579 };
580
581 let mut result = MatchAndWarnings {
582 item: match simple_block_mi {
583 Some(mi) => BlockParseOutcome::Parsed(MatchedItem {
584 item: Self::Simple(mi.item),
585 after: mi.after,
586 }),
587 None => BlockParseOutcome::NoMatch,
588 },
589 warnings,
590 };
591
592 if let BlockParseOutcome::Parsed(ref matched_item) = result.item {
593 Self::register_block_id(
594 matched_item.item.id(),
595 Self::block_reftext(&matched_item.item),
596 matched_item.item.span(),
597 parser,
598 &mut result.warnings,
599 );
600 }
601
602 result
603 }
604
605 fn block_reftext<'a>(block: &'a Block<'a>) -> Option<&'a str> {
610 block
611 .attrlist()
612 .and_then(|attrlist| attrlist.named_attribute("reftext"))
613 .map(|attr| attr.value())
614 .or_else(|| block.anchor_reftext().map(|span| span.data()))
615 .or_else(|| block.title())
616 }
617
618 fn register_block_id(
623 id: Option<&str>,
624 reftext: Option<&str>,
625 span: Span<'src>,
626 parser: &mut Parser,
627 warnings: &mut Vec<Warning<'src>>,
628 ) {
629 if let Some(id) = id
630 && let Err(_duplicate_error) = parser.register_ref(id, reftext, RefType::Anchor)
631 {
632 warnings.push(Warning {
634 source: span,
635 warning: WarningType::DuplicateId(id.to_string()),
636 });
637 }
638 }
639
640 pub(crate) fn as_list_item(&self) -> Option<&ListItem<'src>> {
643 match self {
644 Self::ListItem(li) => Some(li),
645 _ => None,
646 }
647 }
648
649 pub(crate) fn resolve_references(
657 &mut self,
658 resolver: &dyn ReferenceResolver,
659 renderer: &dyn InlineSubstitutionRenderer,
660 warnings: &mut Vec<ReferenceWarning>,
661 ) {
662 if let Some(content) = self.content_mut() {
663 content.resolve_references(resolver, renderer, warnings);
664 }
665
666 if let Self::Table(table) = self {
669 table.resolve_references(resolver, renderer, warnings);
670 }
671
672 if let Self::Quote(quote) = self {
676 quote.resolve_references(resolver, renderer, warnings);
677 }
678
679 for child in self.nested_blocks_mut() {
680 child.resolve_references(resolver, renderer, warnings);
681 }
682 }
683}
684
685impl<'src> IsBlock<'src> for Block<'src> {
686 fn content_model(&self) -> ContentModel {
687 match self {
688 Self::Simple(_) => ContentModel::Simple,
689 Self::Media(b) => b.content_model(),
690 Self::Section(_) => ContentModel::Compound,
691 Self::List(b) => b.content_model(),
692 Self::ListItem(b) => b.content_model(),
693 Self::RawDelimited(b) => b.content_model(),
694 Self::CompoundDelimited(b) => b.content_model(),
695 Self::Admonition(b) => b.content_model(),
696 Self::Quote(b) => b.content_model(),
697 Self::Table(b) => b.content_model(),
698 Self::Preamble(b) => b.content_model(),
699 Self::Break(b) => b.content_model(),
700 Self::DocumentAttribute(b) => b.content_model(),
701 }
702 }
703
704 fn declared_style(&'src self) -> Option<&'src str> {
705 match self {
706 Self::Simple(b) => b.declared_style(),
707 Self::Media(b) => b.declared_style(),
708 Self::Section(b) => b.declared_style(),
709 Self::List(b) => b.declared_style(),
710 Self::ListItem(b) => b.declared_style(),
711 Self::RawDelimited(b) => b.declared_style(),
712 Self::CompoundDelimited(b) => b.declared_style(),
713 Self::Admonition(b) => b.declared_style(),
714 Self::Quote(b) => b.declared_style(),
715 Self::Table(b) => b.declared_style(),
716 Self::Preamble(b) => b.declared_style(),
717 Self::Break(b) => b.declared_style(),
718 Self::DocumentAttribute(b) => b.declared_style(),
719 }
720 }
721
722 fn rendered_content(&'src self) -> Option<&'src str> {
723 match self {
724 Self::Simple(b) => b.rendered_content(),
725 Self::Media(b) => b.rendered_content(),
726 Self::Section(b) => b.rendered_content(),
727 Self::List(b) => b.rendered_content(),
728 Self::ListItem(b) => b.rendered_content(),
729 Self::RawDelimited(b) => b.rendered_content(),
730 Self::CompoundDelimited(b) => b.rendered_content(),
731 Self::Admonition(b) => b.rendered_content(),
732 Self::Quote(b) => b.rendered_content(),
733 Self::Table(b) => b.rendered_content(),
734 Self::Preamble(b) => b.rendered_content(),
735 Self::Break(b) => b.rendered_content(),
736 Self::DocumentAttribute(b) => b.rendered_content(),
737 }
738 }
739
740 fn raw_context(&self) -> CowStr<'src> {
741 match self {
742 Self::Simple(b) => b.raw_context(),
743 Self::Media(b) => b.raw_context(),
744 Self::Section(b) => b.raw_context(),
745 Self::List(b) => b.raw_context(),
746 Self::ListItem(b) => b.raw_context(),
747 Self::RawDelimited(b) => b.raw_context(),
748 Self::CompoundDelimited(b) => b.raw_context(),
749 Self::Admonition(b) => b.raw_context(),
750 Self::Quote(b) => b.raw_context(),
751 Self::Table(b) => b.raw_context(),
752 Self::Preamble(b) => b.raw_context(),
753 Self::Break(b) => b.raw_context(),
754 Self::DocumentAttribute(b) => b.raw_context(),
755 }
756 }
757
758 fn nested_blocks(&'src self) -> Iter<'src, Block<'src>> {
759 match self {
760 Self::Simple(b) => b.nested_blocks(),
761 Self::Media(b) => b.nested_blocks(),
762 Self::Section(b) => b.nested_blocks(),
763 Self::List(b) => b.nested_blocks(),
764 Self::ListItem(b) => b.nested_blocks(),
765 Self::RawDelimited(b) => b.nested_blocks(),
766 Self::CompoundDelimited(b) => b.nested_blocks(),
767 Self::Admonition(b) => b.nested_blocks(),
768 Self::Quote(b) => b.nested_blocks(),
769 Self::Table(b) => b.nested_blocks(),
770 Self::Preamble(b) => b.nested_blocks(),
771 Self::Break(b) => b.nested_blocks(),
772 Self::DocumentAttribute(b) => b.nested_blocks(),
773 }
774 }
775
776 fn nested_blocks_mut(&mut self) -> &mut [Block<'src>] {
777 match self {
778 Self::Simple(b) => b.nested_blocks_mut(),
779 Self::Media(b) => b.nested_blocks_mut(),
780 Self::Section(b) => b.nested_blocks_mut(),
781 Self::List(b) => b.nested_blocks_mut(),
782 Self::ListItem(b) => b.nested_blocks_mut(),
783 Self::RawDelimited(b) => b.nested_blocks_mut(),
784 Self::CompoundDelimited(b) => b.nested_blocks_mut(),
785 Self::Admonition(b) => b.nested_blocks_mut(),
786 Self::Quote(b) => b.nested_blocks_mut(),
787 Self::Table(b) => b.nested_blocks_mut(),
788 Self::Preamble(b) => b.nested_blocks_mut(),
789 Self::Break(b) => b.nested_blocks_mut(),
790 Self::DocumentAttribute(b) => b.nested_blocks_mut(),
791 }
792 }
793
794 fn content_mut(&mut self) -> Option<&mut Content<'src>> {
795 match self {
796 Self::Simple(b) => b.content_mut(),
797 Self::Media(b) => b.content_mut(),
798 Self::Section(b) => b.content_mut(),
799 Self::List(b) => b.content_mut(),
800 Self::ListItem(b) => b.content_mut(),
801 Self::RawDelimited(b) => b.content_mut(),
802 Self::CompoundDelimited(b) => b.content_mut(),
803 Self::Admonition(b) => b.content_mut(),
804 Self::Quote(b) => b.content_mut(),
805 Self::Table(b) => b.content_mut(),
806 Self::Preamble(b) => b.content_mut(),
807 Self::Break(b) => b.content_mut(),
808 Self::DocumentAttribute(b) => b.content_mut(),
809 }
810 }
811
812 fn title_source(&'src self) -> Option<Span<'src>> {
813 match self {
814 Self::Simple(b) => b.title_source(),
815 Self::Media(b) => b.title_source(),
816 Self::Section(b) => b.title_source(),
817 Self::List(b) => b.title_source(),
818 Self::ListItem(b) => b.title_source(),
819 Self::RawDelimited(b) => b.title_source(),
820 Self::CompoundDelimited(b) => b.title_source(),
821 Self::Admonition(b) => b.title_source(),
822 Self::Quote(b) => b.title_source(),
823 Self::Table(b) => b.title_source(),
824 Self::Preamble(b) => b.title_source(),
825 Self::Break(b) => b.title_source(),
826 Self::DocumentAttribute(b) => b.title_source(),
827 }
828 }
829
830 fn title(&self) -> Option<&str> {
831 match self {
832 Self::Simple(b) => b.title(),
833 Self::Media(b) => b.title(),
834 Self::Section(b) => b.title(),
835 Self::List(b) => b.title(),
836 Self::ListItem(b) => b.title(),
837 Self::RawDelimited(b) => b.title(),
838 Self::CompoundDelimited(b) => b.title(),
839 Self::Admonition(b) => b.title(),
840 Self::Quote(b) => b.title(),
841 Self::Table(b) => b.title(),
842 Self::Preamble(b) => b.title(),
843 Self::Break(b) => b.title(),
844 Self::DocumentAttribute(b) => b.title(),
845 }
846 }
847
848 fn caption(&self) -> Option<&str> {
849 match self {
850 Self::Simple(b) => b.caption(),
851 Self::Media(b) => b.caption(),
852 Self::Section(b) => b.caption(),
853 Self::List(b) => b.caption(),
854 Self::ListItem(b) => b.caption(),
855 Self::RawDelimited(b) => b.caption(),
856 Self::CompoundDelimited(b) => b.caption(),
857 Self::Admonition(b) => b.caption(),
858 Self::Quote(b) => b.caption(),
859 Self::Table(b) => b.caption(),
860 Self::Preamble(b) => b.caption(),
861 Self::Break(b) => b.caption(),
862 Self::DocumentAttribute(b) => b.caption(),
863 }
864 }
865
866 fn number(&self) -> Option<usize> {
867 match self {
868 Self::Simple(b) => b.number(),
869 Self::Media(b) => b.number(),
870 Self::Section(b) => b.number(),
871 Self::List(b) => b.number(),
872 Self::ListItem(b) => b.number(),
873 Self::RawDelimited(b) => b.number(),
874 Self::CompoundDelimited(b) => b.number(),
875 Self::Admonition(b) => b.number(),
876 Self::Quote(b) => b.number(),
877 Self::Table(b) => b.number(),
878 Self::Preamble(b) => b.number(),
879 Self::Break(b) => b.number(),
880 Self::DocumentAttribute(b) => b.number(),
881 }
882 }
883
884 fn anchor(&'src self) -> Option<Span<'src>> {
885 match self {
886 Self::Simple(b) => b.anchor(),
887 Self::Media(b) => b.anchor(),
888 Self::Section(b) => b.anchor(),
889 Self::List(b) => b.anchor(),
890 Self::ListItem(b) => b.anchor(),
891 Self::RawDelimited(b) => b.anchor(),
892 Self::CompoundDelimited(b) => b.anchor(),
893 Self::Admonition(b) => b.anchor(),
894 Self::Quote(b) => b.anchor(),
895 Self::Table(b) => b.anchor(),
896 Self::Preamble(b) => b.anchor(),
897 Self::Break(b) => b.anchor(),
898 Self::DocumentAttribute(b) => b.anchor(),
899 }
900 }
901
902 fn anchor_reftext(&'src self) -> Option<Span<'src>> {
903 match self {
904 Self::Simple(b) => b.anchor_reftext(),
905 Self::Media(b) => b.anchor_reftext(),
906 Self::Section(b) => b.anchor_reftext(),
907 Self::List(b) => b.anchor_reftext(),
908 Self::ListItem(b) => b.anchor_reftext(),
909 Self::RawDelimited(b) => b.anchor_reftext(),
910 Self::CompoundDelimited(b) => b.anchor_reftext(),
911 Self::Admonition(b) => b.anchor_reftext(),
912 Self::Quote(b) => b.anchor_reftext(),
913 Self::Table(b) => b.anchor_reftext(),
914 Self::Preamble(b) => b.anchor_reftext(),
915 Self::Break(b) => b.anchor_reftext(),
916 Self::DocumentAttribute(b) => b.anchor_reftext(),
917 }
918 }
919
920 fn attrlist(&'src self) -> Option<&'src Attrlist<'src>> {
921 match self {
922 Self::Simple(b) => b.attrlist(),
923 Self::Media(b) => b.attrlist(),
924 Self::Section(b) => b.attrlist(),
925 Self::List(b) => b.attrlist(),
926 Self::ListItem(b) => b.attrlist(),
927 Self::RawDelimited(b) => b.attrlist(),
928 Self::CompoundDelimited(b) => b.attrlist(),
929 Self::Admonition(b) => b.attrlist(),
930 Self::Quote(b) => b.attrlist(),
931 Self::Table(b) => b.attrlist(),
932 Self::Preamble(b) => b.attrlist(),
933 Self::Break(b) => b.attrlist(),
934 Self::DocumentAttribute(b) => b.attrlist(),
935 }
936 }
937
938 fn substitution_group(&self) -> SubstitutionGroup {
939 match self {
940 Self::Simple(b) => b.substitution_group(),
941 Self::Media(b) => b.substitution_group(),
942 Self::Section(b) => b.substitution_group(),
943 Self::List(b) => b.substitution_group(),
944 Self::ListItem(b) => b.substitution_group(),
945 Self::RawDelimited(b) => b.substitution_group(),
946 Self::CompoundDelimited(b) => b.substitution_group(),
947 Self::Admonition(b) => b.substitution_group(),
948 Self::Quote(b) => b.substitution_group(),
949 Self::Table(b) => b.substitution_group(),
950 Self::Preamble(b) => b.substitution_group(),
951 Self::Break(b) => b.substitution_group(),
952 Self::DocumentAttribute(b) => b.substitution_group(),
953 }
954 }
955}
956
957impl<'src> HasSpan<'src> for Block<'src> {
958 fn span(&self) -> Span<'src> {
959 match self {
960 Self::Simple(b) => b.span(),
961 Self::Media(b) => b.span(),
962 Self::Section(b) => b.span(),
963 Self::List(b) => b.span(),
964 Self::ListItem(b) => b.span(),
965 Self::RawDelimited(b) => b.span(),
966 Self::CompoundDelimited(b) => b.span(),
967 Self::Admonition(b) => b.span(),
968 Self::Quote(b) => b.span(),
969 Self::Table(b) => b.span(),
970 Self::Preamble(b) => b.span(),
971 Self::Break(b) => b.span(),
972 Self::DocumentAttribute(b) => b.span(),
973 }
974 }
975}