diff options
Diffstat (limited to 'parser/src/simplify.rs')
| -rw-r--r-- | parser/src/simplify.rs | 1159 |
1 files changed, 605 insertions, 554 deletions
diff --git a/parser/src/simplify.rs b/parser/src/simplify.rs index 4c254af..17e9ee3 100644 --- a/parser/src/simplify.rs +++ b/parser/src/simplify.rs @@ -4,15 +4,15 @@ http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#hyperlink-tar Links can have internal or external targets. In the source, targets look like: - .. targetname1: - .. targetname2: + .. targetname1: + .. targetname2: - some paragraph or list item or so + some paragraph or list item or so or: .. targetname1: - .. targetname2: https://link + .. targetname2: https://link There’s also anonymous links and targets without names. @@ -22,641 +22,692 @@ TODO: continue documenting how it’s done via https://repo.or.cz/docutils.git/b use std::collections::HashMap; use document_tree::{ - url::Url, - Document, - HasChildren, - attribute_types::NameToken, - elements::{self as e, Element}, - element_categories as c, - extra_attributes::ExtraAttributes, + attribute_types::NameToken, + element_categories as c, + elements::{self as e, Element}, + extra_attributes::ExtraAttributes, + url::Url, + Document, HasChildren, }; - #[derive(Debug)] +#[allow(dead_code)] enum NamedTargetType { - NumberedFootnote(usize), - LabeledFootnote(usize), - Citation, - InternalLink, - ExternalLink(Url), - IndirectLink(NameToken), - SectionTitle, + NumberedFootnote(usize), + LabeledFootnote(usize), + Citation, + InternalLink, + ExternalLink(Url), + IndirectLink(NameToken), + SectionTitle, } impl NamedTargetType { - fn is_implicit_target(&self) -> bool { - match self { - NamedTargetType::SectionTitle => true, - _ => false, - } - } + #[allow(dead_code)] + fn is_implicit_target(&self) -> bool { + matches!(self, NamedTargetType::SectionTitle) + } } #[derive(Clone, Debug)] struct Substitution { - content: Vec<c::TextOrInlineElement>, - /// If true and the sibling before the reference is a text node, - /// the text node gets right-trimmed. - ltrim: bool, - /// Same as `ltrim` with the sibling after the reference. - rtrim: bool, + content: Vec<c::TextOrInlineElement>, + /// If true and the sibling before the reference is a text node, + /// the text node gets right-trimmed. + ltrim: bool, + /// Same as `ltrim` with the sibling after the reference. + rtrim: bool, } #[derive(Default, Debug)] struct TargetsCollected { - named_targets: HashMap<NameToken, NamedTargetType>, - substitutions: HashMap<NameToken, Substitution>, - normalized_substitutions: HashMap<String, Substitution>, + named_targets: HashMap<NameToken, NamedTargetType>, + substitutions: HashMap<NameToken, Substitution>, + normalized_substitutions: HashMap<String, Substitution>, } impl TargetsCollected { - fn target_url<'t>(self: &'t TargetsCollected, refname: &[NameToken]) -> Option<&'t Url> { - // TODO: Check if the target would expand circularly - if refname.len() != 1 { - panic!("Expected exactly one name in a reference."); - } - let name = refname[0].clone(); - match self.named_targets.get(&name)? { - NamedTargetType::ExternalLink(url) => Some(url), - _ => unimplemented!(), - } - } - - fn substitution<'t>(self: &'t TargetsCollected, refname: &[NameToken]) -> Option<&'t Substitution> { - // TODO: Check if the substitution would expand circularly - if refname.len() != 1 { - panic!("Expected exactly one name in a substitution reference."); - } - let name = refname[0].clone(); - self.substitutions.get(&name).or_else(|| { - self.normalized_substitutions.get(&name.0.to_lowercase()) - }) - } + fn target_url<'t>(self: &'t TargetsCollected, refname: &[NameToken]) -> Option<&'t Url> { + // TODO: Check if the target would expand circularly + if refname.len() != 1 { + panic!("Expected exactly one name in a reference."); + } + let name = refname[0].clone(); + match self.named_targets.get(&name)? { + NamedTargetType::ExternalLink(url) => Some(url), + _ => unimplemented!(), + } + } + + fn substitution<'t>( + self: &'t TargetsCollected, + refname: &[NameToken], + ) -> Option<&'t Substitution> { + // TODO: Check if the substitution would expand circularly + if refname.len() != 1 { + panic!("Expected exactly one name in a substitution reference."); + } + let name = refname[0].clone(); + self.substitutions + .get(&name) + .or_else(|| self.normalized_substitutions.get(&name.0.to_lowercase())) + } } trait ResolvableRefs { - fn populate_targets(&self, refs: &mut TargetsCollected); - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> where Self: Sized; + fn populate_targets(&self, refs: &mut TargetsCollected); + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> + where + Self: Sized; } pub fn resolve_references(mut doc: Document) -> Document { - let mut references: TargetsCollected = Default::default(); - for c in doc.children() { - c.populate_targets(&mut references); - } - let new: Vec<_> = doc.children_mut().drain(..).flat_map(|c| c.resolve_refs(&references)).collect(); - Document::with_children(new) + let mut references: TargetsCollected = Default::default(); + for c in doc.children() { + c.populate_targets(&mut references); + } + let new: Vec<_> = doc + .children_mut() + .drain(..) + .flat_map(|c| c.resolve_refs(&references)) + .collect(); + Document::with_children(new) } -fn sub_pop<P, C>(parent: &P, refs: &mut TargetsCollected) where P: HasChildren<C>, C: ResolvableRefs { - for c in parent.children() { - c.populate_targets(refs); - } +fn sub_pop<P, C>(parent: &P, refs: &mut TargetsCollected) +where + P: HasChildren<C>, + C: ResolvableRefs, +{ + for c in parent.children() { + c.populate_targets(refs); + } } -fn sub_res<P, C>(mut parent: P, refs: &TargetsCollected) -> P where P: e::Element + HasChildren<C>, C: ResolvableRefs { - let new: Vec<_> = parent.children_mut().drain(..).flat_map(|c| c.resolve_refs(refs)).collect(); - parent.children_mut().extend(new); - parent +fn sub_res<P, C>(mut parent: P, refs: &TargetsCollected) -> P +where + P: e::Element + HasChildren<C>, + C: ResolvableRefs, +{ + let new: Vec<_> = parent + .children_mut() + .drain(..) + .flat_map(|c| c.resolve_refs(refs)) + .collect(); + parent.children_mut().extend(new); + parent } -fn sub_sub_pop<P, C1, C2>(parent: &P, refs: &mut TargetsCollected) where P: HasChildren<C1>, C1: HasChildren<C2>, C2: ResolvableRefs { - for c in parent.children() { - sub_pop(c, refs); - } +fn sub_sub_pop<P, C1, C2>(parent: &P, refs: &mut TargetsCollected) +where + P: HasChildren<C1>, + C1: HasChildren<C2>, + C2: ResolvableRefs, +{ + for c in parent.children() { + sub_pop(c, refs); + } } -fn sub_sub_res<P, C1, C2>(mut parent: P, refs: &TargetsCollected) -> P where P: e::Element + HasChildren<C1>, C1: e::Element + HasChildren<C2>, C2: ResolvableRefs { - let new: Vec<_> = parent.children_mut().drain(..).map(|c| sub_res(c, refs)).collect(); - parent.children_mut().extend(new); - parent +fn sub_sub_res<P, C1, C2>(mut parent: P, refs: &TargetsCollected) -> P +where + P: e::Element + HasChildren<C1>, + C1: e::Element + HasChildren<C2>, + C2: ResolvableRefs, +{ + let new: Vec<_> = parent + .children_mut() + .drain(..) + .map(|c| sub_res(c, refs)) + .collect(); + parent.children_mut().extend(new); + parent } impl ResolvableRefs for c::StructuralSubElement { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::StructuralSubElement::*; - match self { - Title(e) => sub_pop(&**e, refs), - Subtitle(e) => sub_pop(&**e, refs), - Decoration(e) => sub_pop(&**e, refs), - Docinfo(e) => sub_pop(&**e, refs), - SubStructure(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::StructuralSubElement::*; - vec![match self { - Title(e) => sub_res(*e, refs).into(), - Subtitle(e) => sub_res(*e, refs).into(), - Decoration(e) => sub_res(*e, refs).into(), - Docinfo(e) => sub_res(*e, refs).into(), - SubStructure(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::StructuralSubElement::*; + match self { + Title(e) => sub_pop(&**e, refs), + Subtitle(e) => sub_pop(&**e, refs), + Decoration(e) => sub_pop(&**e, refs), + Docinfo(e) => sub_pop(&**e, refs), + SubStructure(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::StructuralSubElement::*; + vec![match self { + Title(e) => sub_res(*e, refs).into(), + Subtitle(e) => sub_res(*e, refs).into(), + Decoration(e) => sub_res(*e, refs).into(), + Docinfo(e) => sub_res(*e, refs).into(), + SubStructure(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), + }] + } } impl ResolvableRefs for c::SubStructure { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubStructure::*; - match self { - Topic(e) => sub_pop(&**e, refs), - Sidebar(e) => sub_pop(&**e, refs), - Transition(_) => {}, - Section(e) => sub_pop(&**e, refs), - BodyElement(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubStructure::*; - vec![match self { - Topic(e) => sub_res(*e, refs).into(), - Sidebar(e) => sub_res(*e, refs).into(), - Transition(e) => Transition(e), - Section(e) => sub_res(*e, refs).into(), - BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubStructure::*; + match self { + Topic(e) => sub_pop(&**e, refs), + Sidebar(e) => sub_pop(&**e, refs), + Transition(_) => {} + Section(e) => sub_pop(&**e, refs), + BodyElement(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubStructure::*; + vec![match self { + Topic(e) => sub_res(*e, refs).into(), + Sidebar(e) => sub_res(*e, refs).into(), + Transition(e) => Transition(e), + Section(e) => sub_res(*e, refs).into(), + BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), + }] + } } impl ResolvableRefs for c::BodyElement { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::BodyElement::*; - match self { - Paragraph(e) => sub_pop(&**e, refs), - LiteralBlock(e) => sub_pop(&**e, refs), - DoctestBlock(e) => sub_pop(&**e, refs), - MathBlock(_) => {}, - Rubric(e) => sub_pop(&**e, refs), - SubstitutionDefinition(e) => { - let subst = Substitution { - content: e.children().clone(), - ltrim: e.extra().ltrim, - rtrim: e.extra().rtrim - }; - for name in e.names() { - if refs.substitutions.contains_key(name) { - // TODO: Duplicate substitution name (level 3 system message). - } - // Intentionally overriding any previous values. - refs.substitutions.insert(name.clone(), subst.clone()); - refs.normalized_substitutions.insert(name.0.to_lowercase(), subst.clone()); - } - }, - Comment(_) => {}, - Pending(_) => { - unimplemented!(); - }, - Target(e) => { - if let Some(uri) = &e.extra().refuri { - for name in e.names() { - refs.named_targets.insert(name.clone(), NamedTargetType::ExternalLink(uri.clone())); - } - } - // TODO: as is, people can only refer to the target directly containing the URL. - // add refid and refnames to some HashMap and follow those later. - }, - Raw(_) => {}, - Image(_) => {}, - Compound(e) => sub_pop(&**e, refs), - Container(e) => sub_pop(&**e, refs), - BulletList(e) => sub_sub_pop(&**e, refs), - EnumeratedList(e) => sub_sub_pop(&**e, refs), - DefinitionList(e) => sub_sub_pop(&**e, refs), - FieldList(e) => sub_sub_pop(&**e, refs), - OptionList(e) => sub_sub_pop(&**e, refs), - LineBlock(e) => sub_pop(&**e, refs), - BlockQuote(e) => sub_pop(&**e, refs), - Admonition(e) => sub_pop(&**e, refs), - Attention(e) => sub_pop(&**e, refs), - Hint(e) => sub_pop(&**e, refs), - Note(e) => sub_pop(&**e, refs), - Caution(e) => sub_pop(&**e, refs), - Danger(e) => sub_pop(&**e, refs), - Error(e) => sub_pop(&**e, refs), - Important(e) => sub_pop(&**e, refs), - Tip(e) => sub_pop(&**e, refs), - Warning(e) => sub_pop(&**e, refs), - Footnote(e) => sub_pop(&**e, refs), - Citation(e) => sub_pop(&**e, refs), - SystemMessage(e) => sub_pop(&**e, refs), - Figure(e) => sub_pop(&**e, refs), - Table(e) => sub_pop(&**e, refs) - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::BodyElement::*; - vec![match self { - Paragraph(e) => sub_res(*e, refs).into(), - LiteralBlock(e) => sub_res(*e, refs).into(), - DoctestBlock(e) => sub_res(*e, refs).into(), - MathBlock(e) => MathBlock(e), - Rubric(e) => sub_res(*e, refs).into(), - SubstitutionDefinition(_) => return vec![], - Comment(e) => Comment(e), - Pending(e) => Pending(e), - Target(e) => Target(e), - Raw(e) => Raw(e), - Image(e) => Image(e), - Compound(e) => sub_res(*e, refs).into(), - Container(e) => sub_res(*e, refs).into(), - BulletList(e) => sub_sub_res(*e, refs).into(), - EnumeratedList(e) => sub_sub_res(*e, refs).into(), - DefinitionList(e) => sub_sub_res(*e, refs).into(), - FieldList(e) => sub_sub_res(*e, refs).into(), - OptionList(e) => sub_sub_res(*e, refs).into(), - LineBlock(e) => sub_res(*e, refs).into(), - BlockQuote(e) => sub_res(*e, refs).into(), - Admonition(e) => sub_res(*e, refs).into(), - Attention(e) => sub_res(*e, refs).into(), - Hint(e) => sub_res(*e, refs).into(), - Note(e) => sub_res(*e, refs).into(), - Caution(e) => sub_res(*e, refs).into(), - Danger(e) => sub_res(*e, refs).into(), - Error(e) => sub_res(*e, refs).into(), - Important(e) => sub_res(*e, refs).into(), - Tip(e) => sub_res(*e, refs).into(), - Warning(e) => sub_res(*e, refs).into(), - Footnote(e) => sub_res(*e, refs).into(), - Citation(e) => sub_res(*e, refs).into(), - SystemMessage(e) => sub_res(*e, refs).into(), - Figure(e) => sub_res(*e, refs).into(), - Table(e) => sub_res(*e, refs).into() - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::BodyElement::*; + match self { + Paragraph(e) => sub_pop(&**e, refs), + LiteralBlock(e) => sub_pop(&**e, refs), + DoctestBlock(e) => sub_pop(&**e, refs), + MathBlock(_) => {} + Rubric(e) => sub_pop(&**e, refs), + SubstitutionDefinition(e) => { + let subst = Substitution { + content: e.children().clone(), + ltrim: e.extra().ltrim, + rtrim: e.extra().rtrim, + }; + for name in e.names() { + if refs.substitutions.contains_key(name) { + // TODO: Duplicate substitution name (level 3 system message). + } + // Intentionally overriding any previous values. + refs.substitutions.insert(name.clone(), subst.clone()); + refs.normalized_substitutions + .insert(name.0.to_lowercase(), subst.clone()); + } + } + Comment(_) => {} + Pending(_) => { + unimplemented!(); + } + Target(e) => { + if let Some(uri) = &e.extra().refuri { + for name in e.names() { + refs.named_targets + .insert(name.clone(), NamedTargetType::ExternalLink(uri.clone())); + } + } + // TODO: as is, people can only refer to the target directly containing the URL. + // add refid and refnames to some HashMap and follow those later. + } + Raw(_) => {} + Image(_) => {} + Compound(e) => sub_pop(&**e, refs), + Container(e) => sub_pop(&**e, refs), + BulletList(e) => sub_sub_pop(&**e, refs), + EnumeratedList(e) => sub_sub_pop(&**e, refs), + DefinitionList(e) => sub_sub_pop(&**e, refs), + FieldList(e) => sub_sub_pop(&**e, refs), + OptionList(e) => sub_sub_pop(&**e, refs), + LineBlock(e) => sub_pop(&**e, refs), + BlockQuote(e) => sub_pop(&**e, refs), + Admonition(e) => sub_pop(&**e, refs), + Attention(e) => sub_pop(&**e, refs), + Hint(e) => sub_pop(&**e, refs), + Note(e) => sub_pop(&**e, refs), + Caution(e) => sub_pop(&**e, refs), + Danger(e) => sub_pop(&**e, refs), + Error(e) => sub_pop(&**e, refs), + Important(e) => sub_pop(&**e, refs), + Tip(e) => sub_pop(&**e, refs), + Warning(e) => sub_pop(&**e, refs), + Footnote(e) => sub_pop(&**e, refs), + Citation(e) => sub_pop(&**e, refs), + SystemMessage(e) => sub_pop(&**e, refs), + Figure(e) => sub_pop(&**e, refs), + Table(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::BodyElement::*; + vec![match self { + Paragraph(e) => sub_res(*e, refs).into(), + LiteralBlock(e) => sub_res(*e, refs).into(), + DoctestBlock(e) => sub_res(*e, refs).into(), + MathBlock(e) => MathBlock(e), + Rubric(e) => sub_res(*e, refs).into(), + SubstitutionDefinition(_) => return vec![], + Comment(e) => Comment(e), + Pending(e) => Pending(e), + Target(e) => Target(e), + Raw(e) => Raw(e), + Image(e) => Image(e), + Compound(e) => sub_res(*e, refs).into(), + Container(e) => sub_res(*e, refs).into(), + BulletList(e) => sub_sub_res(*e, refs).into(), + EnumeratedList(e) => sub_sub_res(*e, refs).into(), + DefinitionList(e) => sub_sub_res(*e, refs).into(), + FieldList(e) => sub_sub_res(*e, refs).into(), + OptionList(e) => sub_sub_res(*e, refs).into(), + LineBlock(e) => sub_res(*e, refs).into(), + BlockQuote(e) => sub_res(*e, refs).into(), + Admonition(e) => sub_res(*e, refs).into(), + Attention(e) => sub_res(*e, refs).into(), + Hint(e) => sub_res(*e, refs).into(), + Note(e) => sub_res(*e, refs).into(), + Caution(e) => sub_res(*e, refs).into(), + Danger(e) => sub_res(*e, refs).into(), + Error(e) => sub_res(*e, refs).into(), + Important(e) => sub_res(*e, refs).into(), + Tip(e) => sub_res(*e, refs).into(), + Warning(e) => sub_res(*e, refs).into(), + Footnote(e) => sub_res(*e, refs).into(), + Citation(e) => sub_res(*e, refs).into(), + SystemMessage(e) => sub_res(*e, refs).into(), + Figure(e) => sub_res(*e, refs).into(), + Table(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::BibliographicElement { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::BibliographicElement::*; - match self { - Author(e) => sub_pop(&**e, refs), - Authors(e) => sub_pop(&**e, refs), - Organization(e) => sub_pop(&**e, refs), - Address(e) => sub_pop(&**e, refs), - Contact(e) => sub_pop(&**e, refs), - Version(e) => sub_pop(&**e, refs), - Revision(e) => sub_pop(&**e, refs), - Status(e) => sub_pop(&**e, refs), - Date(e) => sub_pop(&**e, refs), - Copyright(e) => sub_pop(&**e, refs), - Field(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::BibliographicElement::*; - vec![match self { - Author(e) => sub_res(*e, refs).into(), - Authors(e) => sub_res(*e, refs).into(), - Organization(e) => sub_res(*e, refs).into(), - Address(e) => sub_res(*e, refs).into(), - Contact(e) => sub_res(*e, refs).into(), - Version(e) => sub_res(*e, refs).into(), - Revision(e) => sub_res(*e, refs).into(), - Status(e) => sub_res(*e, refs).into(), - Date(e) => sub_res(*e, refs).into(), - Copyright(e) => sub_res(*e, refs).into(), - Field(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::BibliographicElement::*; + match self { + Author(e) => sub_pop(&**e, refs), + Authors(e) => sub_pop(&**e, refs), + Organization(e) => sub_pop(&**e, refs), + Address(e) => sub_pop(&**e, refs), + Contact(e) => sub_pop(&**e, refs), + Version(e) => sub_pop(&**e, refs), + Revision(e) => sub_pop(&**e, refs), + Status(e) => sub_pop(&**e, refs), + Date(e) => sub_pop(&**e, refs), + Copyright(e) => sub_pop(&**e, refs), + Field(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::BibliographicElement::*; + vec![match self { + Author(e) => sub_res(*e, refs).into(), + Authors(e) => sub_res(*e, refs).into(), + Organization(e) => sub_res(*e, refs).into(), + Address(e) => sub_res(*e, refs).into(), + Contact(e) => sub_res(*e, refs).into(), + Version(e) => sub_res(*e, refs).into(), + Revision(e) => sub_res(*e, refs).into(), + Status(e) => sub_res(*e, refs).into(), + Date(e) => sub_res(*e, refs).into(), + Copyright(e) => sub_res(*e, refs).into(), + Field(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::TextOrInlineElement { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::TextOrInlineElement::*; - match self { - String(_) => {}, - Emphasis(e) => sub_pop(&**e, refs), - Strong(e) => sub_pop(&**e, refs), - Literal(_) => {}, - Reference(e) => sub_pop(&**e, refs), - FootnoteReference(e) => sub_pop(&**e, refs), - CitationReference(e) => sub_pop(&**e, refs), - SubstitutionReference(e) => sub_pop(&**e, refs), - TitleReference(e) => sub_pop(&**e, refs), - Abbreviation(e) => sub_pop(&**e, refs), - Acronym(e) => sub_pop(&**e, refs), - Superscript(e) => sub_pop(&**e, refs), - Subscript(e) => sub_pop(&**e, refs), - Inline(e) => sub_pop(&**e, refs), - Problematic(e) => sub_pop(&**e, refs), - Generated(e) => sub_pop(&**e, refs), - Math(_) => {}, - TargetInline(_) => { - unimplemented!(); - }, - RawInline(_) => {}, - ImageInline(_) => {} - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::TextOrInlineElement::*; - vec![match self { - String(e) => String(e), - Emphasis(e) => sub_res(*e, refs).into(), - Strong(e) => sub_res(*e, refs).into(), - Literal(e) => Literal(e), - Reference(mut e) => { - if e.extra().refuri.is_none() { - if let Some(uri) = refs.target_url(&e.extra().refname) { - e.extra_mut().refuri = Some(uri.clone()); - } - } - (*e).into() - }, - FootnoteReference(e) => sub_res(*e, refs).into(), - CitationReference(e) => sub_res(*e, refs).into(), - SubstitutionReference(e) => match refs.substitution(&e.extra().refname) { - Some(Substitution {content, ltrim, rtrim}) => { - // (level 3 system message). - // TODO: ltrim and rtrim. - if *ltrim || *rtrim { - dbg!(content, ltrim, rtrim); - } - return content.clone() - }, - None => { - // Undefined substitution name (level 3 system message). - // TODO: This replaces the reference by a Problematic node. - // The corresponding SystemMessage node should go in a generated - // section with class "system-messages" at the end of the document. - use document_tree::Problematic; - let mut replacement: Box<Problematic> = Box::new(Default::default()); - replacement.children_mut().push( - c::TextOrInlineElement::String(Box::new(format!("|{}|", e.extra().refname[0].0))) - ); - // TODO: Create an ID for replacement for the system_message to reference. - // TODO: replacement.refid pointing to the system_message. - Problematic(replacement) - } - }, - TitleReference(e) => sub_res(*e, refs).into(), - Abbreviation(e) => sub_res(*e, refs).into(), - Acronym(e) => sub_res(*e, refs).into(), - Superscript(e) => sub_res(*e, refs).into(), - Subscript(e) => sub_res(*e, refs).into(), - Inline(e) => sub_res(*e, refs).into(), - Problematic(e) => sub_res(*e, refs).into(), - Generated(e) => sub_res(*e, refs).into(), - Math(e) => Math(e), - TargetInline(e) => TargetInline(e), - RawInline(e) => RawInline(e), - ImageInline(e) => ImageInline(e) - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::TextOrInlineElement::*; + match self { + String(_) => {} + Emphasis(e) => sub_pop(&**e, refs), + Strong(e) => sub_pop(&**e, refs), + Literal(_) => {} + Reference(e) => sub_pop(&**e, refs), + FootnoteReference(e) => sub_pop(&**e, refs), + CitationReference(e) => sub_pop(&**e, refs), + SubstitutionReference(e) => sub_pop(&**e, refs), + TitleReference(e) => sub_pop(&**e, refs), + Abbreviation(e) => sub_pop(&**e, refs), + Acronym(e) => sub_pop(&**e, refs), + Superscript(e) => sub_pop(&**e, refs), + Subscript(e) => sub_pop(&**e, refs), + Inline(e) => sub_pop(&**e, refs), + Problematic(e) => sub_pop(&**e, refs), + Generated(e) => sub_pop(&**e, refs), + Math(_) => {} + TargetInline(_) => { + unimplemented!(); + } + RawInline(_) => {} + ImageInline(_) => {} + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::TextOrInlineElement::*; + vec![match self { + String(e) => String(e), + Emphasis(e) => sub_res(*e, refs).into(), + Strong(e) => sub_res(*e, refs).into(), + Literal(e) => Literal(e), + Reference(mut e) => { + if e.extra().refuri.is_none() { + if let Some(uri) = refs.target_url(&e.extra().refname) { + e.extra_mut().refuri = Some(uri.clone()); + } + } + (*e).into() + } + FootnoteReference(e) => sub_res(*e, refs).into(), + CitationReference(e) => sub_res(*e, refs).into(), + SubstitutionReference(e) => match refs.substitution(&e.extra().refname) { + Some(Substitution { + content, + ltrim, + rtrim, + }) => { + // (level 3 system message). + // TODO: ltrim and rtrim. + if *ltrim || *rtrim { + dbg!(content, ltrim, rtrim); + } + return content.clone(); + } + None => { + // Undefined substitution name (level 3 system message). + // TODO: This replaces the reference by a Problematic node. + // The corresponding SystemMessage node should go in a generated + // section with class "system-messages" at the end of the document. + use document_tree::Problematic; + let mut replacement: Box<Problematic> = Box::default(); + replacement + .children_mut() + .push(c::TextOrInlineElement::String(Box::new(format!( + "|{}|", + e.extra().refname[0].0 + )))); + // TODO: Create an ID for replacement for the system_message to reference. + // TODO: replacement.refid pointing to the system_message. + Problematic(replacement) + } + }, + TitleReference(e) => sub_res(*e, refs).into(), + Abbreviation(e) => sub_res(*e, refs).into(), + Acronym(e) => sub_res(*e, refs).into(), + Superscript(e) => sub_res(*e, refs).into(), + Subscript(e) => sub_res(*e, refs).into(), + Inline(e) => sub_res(*e, refs).into(), + Problematic(e) => sub_res(*e, refs).into(), + Generated(e) => sub_res(*e, refs).into(), + Math(e) => Math(e), + TargetInline(e) => TargetInline(e), + RawInline(e) => RawInline(e), + ImageInline(e) => ImageInline(e), + }] + } } impl ResolvableRefs for c::AuthorInfo { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::AuthorInfo::*; - match self { - Author(e) => sub_pop(&**e, refs), - Organization(e) => sub_pop(&**e, refs), - Address(e) => sub_pop(&**e, refs), - Contact(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::AuthorInfo::*; - vec![match self { - Author(e) => sub_res(*e, refs).into(), - Organization(e) => sub_res(*e, refs).into(), - Address(e) => sub_res(*e, refs).into(), - Contact(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::AuthorInfo::*; + match self { + Author(e) => sub_pop(&**e, refs), + Organization(e) => sub_pop(&**e, refs), + Address(e) => sub_pop(&**e, refs), + Contact(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::AuthorInfo::*; + vec![match self { + Author(e) => sub_res(*e, refs).into(), + Organization(e) => sub_res(*e, refs).into(), + Address(e) => sub_res(*e, refs).into(), + Contact(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::DecorationElement { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::DecorationElement::*; - match self { - Header(e) => sub_pop(&**e, refs), - Footer(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::DecorationElement::*; - vec![match self { - Header(e) => sub_res(*e, refs).into(), - Footer(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::DecorationElement::*; + match self { + Header(e) => sub_pop(&**e, refs), + Footer(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::DecorationElement::*; + vec![match self { + Header(e) => sub_res(*e, refs).into(), + Footer(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::SubTopic { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubTopic::*; - match self { - Title(e) => sub_pop(&**e, refs), - BodyElement(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubTopic::*; - match self { - Title(e) => vec![sub_res(*e, refs).into()], - BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(), - } - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubTopic::*; + match self { + Title(e) => sub_pop(&**e, refs), + BodyElement(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubTopic::*; + match self { + Title(e) => vec![sub_res(*e, refs).into()], + BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(), + } + } } impl ResolvableRefs for c::SubSidebar { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubSidebar::*; - match self { - Topic(e) => sub_pop(&**e, refs), - Title(e) => sub_pop(&**e, refs), - Subtitle(e) => sub_pop(&**e, refs), - BodyElement(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubSidebar::*; - vec![match self { - Topic(e) => sub_res(*e, refs).into(), - Title(e) => sub_res(*e, refs).into(), - Subtitle(e) => sub_res(*e, refs).into(), - BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubSidebar::*; + match self { + Topic(e) => sub_pop(&**e, refs), + Title(e) => sub_pop(&**e, refs), + Subtitle(e) => sub_pop(&**e, refs), + BodyElement(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubSidebar::*; + vec![match self { + Topic(e) => sub_res(*e, refs).into(), + Title(e) => sub_res(*e, refs).into(), + Subtitle(e) => sub_res(*e, refs).into(), + BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), + }] + } } impl ResolvableRefs for c::SubDLItem { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubDLItem::*; - match self { - Term(e) => sub_pop(&**e, refs), - Classifier(e) => sub_pop(&**e, refs), - Definition(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubDLItem::*; - vec![match self { - Term(e) => sub_res(*e, refs).into(), - Classifier(e) => sub_res(*e, refs).into(), - Definition(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubDLItem::*; + match self { + Term(e) => sub_pop(&**e, refs), + Classifier(e) => sub_pop(&**e, refs), + Definition(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubDLItem::*; + vec![match self { + Term(e) => sub_res(*e, refs).into(), + Classifier(e) => sub_res(*e, refs).into(), + Definition(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::SubField { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubField::*; - match self { - FieldName(e) => sub_pop(&**e, refs), - FieldBody(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubField::*; - vec![match self { - FieldName(e) => sub_res(*e, refs).into(), - FieldBody(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubField::*; + match self { + FieldName(e) => sub_pop(&**e, refs), + FieldBody(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubField::*; + vec![match self { + FieldName(e) => sub_res(*e, refs).into(), + FieldBody(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::SubOptionListItem { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubOptionListItem::*; - match self { - OptionGroup(e) => sub_sub_pop(&**e, refs), - Description(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubOptionListItem::*; - vec![match self { - OptionGroup(e) => sub_sub_res(*e, refs).into(), - Description(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubOptionListItem::*; + match self { + OptionGroup(e) => sub_sub_pop(&**e, refs), + Description(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubOptionListItem::*; + vec![match self { + OptionGroup(e) => sub_sub_res(*e, refs).into(), + Description(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::SubOption { - fn populate_targets(&self, _: &mut TargetsCollected) {} - fn resolve_refs(self, _: &TargetsCollected) -> Vec<Self> { vec![self] } + fn populate_targets(&self, _: &mut TargetsCollected) {} + fn resolve_refs(self, _: &TargetsCollected) -> Vec<Self> { + vec![self] + } } impl ResolvableRefs for c::SubLineBlock { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubLineBlock::*; - match self { - LineBlock(e) => sub_pop(&**e, refs), - Line(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubLineBlock::*; - vec![match self { - LineBlock(e) => sub_res(*e, refs).into(), - Line(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubLineBlock::*; + match self { + LineBlock(e) => sub_pop(&**e, refs), + Line(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubLineBlock::*; + vec![match self { + LineBlock(e) => sub_res(*e, refs).into(), + Line(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::SubBlockQuote { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubBlockQuote::*; - match self { - Attribution(e) => sub_pop(&**e, refs), - BodyElement(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubBlockQuote::*; - match self { - Attribution(e) => vec![sub_res(*e, refs).into()], - BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(), - } - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubBlockQuote::*; + match self { + Attribution(e) => sub_pop(&**e, refs), + BodyElement(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubBlockQuote::*; + match self { + Attribution(e) => vec![sub_res(*e, refs).into()], + BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(), + } + } } impl ResolvableRefs for c::SubFootnote { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubFootnote::*; - match self { - Label(e) => sub_pop(&**e, refs), - BodyElement(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubFootnote::*; - match self { - Label(e) => vec![sub_res(*e, refs).into()], - BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(), - } - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubFootnote::*; + match self { + Label(e) => sub_pop(&**e, refs), + BodyElement(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubFootnote::*; + match self { + Label(e) => vec![sub_res(*e, refs).into()], + BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(), + } + } } impl ResolvableRefs for c::SubFigure { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubFigure::*; - match self { - Caption(e) => sub_pop(&**e, refs), - Legend(e) => sub_pop(&**e, refs), - BodyElement(e) => e.populate_targets(refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubFigure::*; - vec![match self { - Caption(e) => sub_res(*e, refs).into(), - Legend(e) => sub_res(*e, refs).into(), - BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubFigure::*; + match self { + Caption(e) => sub_pop(&**e, refs), + Legend(e) => sub_pop(&**e, refs), + BodyElement(e) => e.populate_targets(refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubFigure::*; + vec![match self { + Caption(e) => sub_res(*e, refs).into(), + Legend(e) => sub_res(*e, refs).into(), + BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), + }] + } } impl ResolvableRefs for c::SubTable { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubTable::*; - match self { - Title(e) => sub_pop(&**e, refs), - TableGroup(e) => sub_pop(&**e, refs), - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubTable::*; - vec![match self { - Title(e) => sub_res(*e, refs).into(), - TableGroup(e) => sub_res(*e, refs).into(), - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubTable::*; + match self { + Title(e) => sub_pop(&**e, refs), + TableGroup(e) => sub_pop(&**e, refs), + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubTable::*; + vec![match self { + Title(e) => sub_res(*e, refs).into(), + TableGroup(e) => sub_res(*e, refs).into(), + }] + } } impl ResolvableRefs for c::SubTableGroup { - fn populate_targets(&self, refs: &mut TargetsCollected) { - use c::SubTableGroup::*; - match self { - TableColspec(_) => { - unimplemented!(); - }, - TableHead(e) => { - for c in e.children() { - sub_sub_pop(c, refs); - } - }, - TableBody(e) => { - for c in e.children() { - sub_sub_pop(c, refs); - } - }, - } - } - fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { - use c::SubTableGroup::*; - vec![match self { - TableColspec(e) => TableColspec(e), - TableHead(mut e) => { - let new: Vec<_> = e.children_mut().drain(..).map(|c| sub_sub_res(c, refs)).collect(); - e.children_mut().extend(new); - TableHead(e) - }, - TableBody(mut e) => { - let new: Vec<_> = e.children_mut().drain(..).map(|c| sub_sub_res(c, refs)).collect(); - e.children_mut().extend(new); - TableBody(e) - }, - }] - } + fn populate_targets(&self, refs: &mut TargetsCollected) { + use c::SubTableGroup::*; + match self { + TableColspec(_) => { + unimplemented!(); + } + TableHead(e) => { + for c in e.children() { + sub_sub_pop(c, refs); + } + } + TableBody(e) => { + for c in e.children() { + sub_sub_pop(c, refs); + } + } + } + } + fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> { + use c::SubTableGroup::*; + vec![match self { + TableColspec(e) => TableColspec(e), + TableHead(mut e) => { + let new: Vec<_> = e + .children_mut() + .drain(..) + .map(|c| sub_sub_res(c, refs)) + .collect(); + e.children_mut().extend(new); + TableHead(e) + } + TableBody(mut e) => { + let new: Vec<_> = e + .children_mut() + .drain(..) + .map(|c| sub_sub_res(c, refs)) + .collect(); + e.children_mut().extend(new); + TableBody(e) + } + }] + } } |
