diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/parser/simplify.rs | 80 | 
1 files changed, 78 insertions, 2 deletions
| diff --git a/src/parser/simplify.rs b/src/parser/simplify.rs index 2743a69..8f0dd31 100644 --- a/src/parser/simplify.rs +++ b/src/parser/simplify.rs @@ -1,3 +1,24 @@ +/* +http://docutils.sourceforge.net/docs/ref/rst/restructuredtext.html#hyperlink-targets + +Links can have internal or external targets. +In the source, targets look like: + +	.. targetname1: +	.. targetname2: + +	some paragraph or list item or so + +or: + +    .. targetname1: +	.. targetname2: https://link + +There’s also anonymous links and targets without names. + +TODO: continue documenting how it’s done via http://svn.code.sf.net/p/docutils/code/trunk/docutils/docutils/transforms/references.py +*/ +  use std::collections::HashMap;  use crate::target::Target; @@ -5,10 +26,16 @@ use crate::document_tree::{  	Document,  	HasChildren,  	attribute_types::ID, +	elements as e,  	element_categories as c,  }; +enum MaybeDirectTarget { +	IndirectTarget(ID), +	DirectTarget(Target), +} +  trait ResolvableRefs {  	fn populate_targets(&self, refs: &mut HashMap<&ID, Target>);  	fn resolve_refs(self, refs: &HashMap<&ID, Target>) -> Self; @@ -23,12 +50,61 @@ pub fn resolve_references(mut doc: Document) -> Document {  	Document::with_children(new)  } +fn sub_pop<P, C>(parent: &P, refs: &mut HashMap<&ID, Target>) where P: HasChildren<C>, C: ResolvableRefs { +	for c in parent.children() { +		c.populate_targets(&mut refs); +	} +} + +fn sub_res<P, C>(parent: P, refs: &HashMap<&ID, Target>) -> P where P: e::Element + HasChildren<C>, C: ResolvableRefs { +	 +	let new: Vec<_> = parent.children_mut().drain(..).map(|c| c.resolve_refs(&refs)).collect(); +	parent.children_mut().extend(new); +	parent +} +  impl ResolvableRefs for c::StructuralSubElement {  	fn populate_targets(&self, refs: &mut HashMap<&ID, Target>) { -		//TODO +		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: &HashMap<&ID, Target>) -> Self { -		self //TODO +		use c::StructuralSubElement::*; +		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) => e.resolve_refs(refs).into(), +		}  	}  } +impl ResolvableRefs for c::SubStructure { +	fn populate_targets(&self, refs: &mut HashMap<&ID, Target>) { +		use c::SubStructure::*; +		match *self { +			Topic(e) => sub_pop(&*e, refs), +			Sidebar(e) => sub_pop(&*e, refs), +			Transition(e) => sub_pop(&*e, refs), +			Section(e) => sub_pop(&*e, refs), +			BodyElement(e) => e.populate_targets(refs), +		} +	} +	fn resolve_refs(self, refs: &HashMap<&ID, Target>) -> Self { +		use c::SubStructure::*; +		match self { +			Topic(e) => sub_res(*e, refs).into(), +			Sidebar(e) => sub_res(*e, refs).into(), +			Transition(e) => sub_res(*e, refs).into(), +			Section(e) => sub_res(*e, refs).into(), +			BodyElement(e) => e.resolve_refs(refs).into(), +		} +	} +} | 
