diff options
Diffstat (limited to 'src/parser')
| -rw-r--r-- | src/parser/conversion/block.rs | 33 | ||||
| -rw-r--r-- | src/parser/simplify.rs | 139 | ||||
| -rw-r--r-- | src/parser/tests.rs | 26 | 
3 files changed, 108 insertions, 90 deletions
| diff --git a/src/parser/conversion/block.rs b/src/parser/conversion/block.rs index 8659dcd..0c313f6 100644 --- a/src/parser/conversion/block.rs +++ b/src/parser/conversion/block.rs @@ -111,25 +111,22 @@ fn convert_replace(pair: Pair<Rule>) -> Result<Vec<c::TextOrInlineElement>, Erro  fn convert_image<I>(pair: Pair<Rule>) -> Result<I, Error> where I: Element + ExtraAttributes<a::Image> {  	let mut pairs = pair.into_inner();  	let mut image = I::with_extra(a::Image::new( -		pairs.next().unwrap().parse()?,  // line +		pairs.next().unwrap().as_str().trim().parse()?,  // line  	)); -	if let Some(opt_block) = pairs.next() {  // image_opt_block -		let options = opt_block.into_inner(); -		for opt in options { -			let mut opt_iter = opt.into_inner(); -			let opt_name = opt_iter.next().unwrap(); -			let opt_val = opt_iter.next().unwrap(); -			match opt_name.as_str() { -				"class"  => image.classes_mut().push(opt_val.as_str().to_owned()), -				"name"   => image.names_mut().push(opt_val.as_str().into()), -				"alt"    => image.extra_mut().alt    = Some(opt_val.as_str().to_owned()), -				"height" => image.extra_mut().height = Some(opt_val.parse()?), -				"width"  => image.extra_mut().width  = Some(opt_val.parse()?), -				"scale"  => image.extra_mut().scale  = Some(parse_scale(&opt_val)?), -				"align"  => image.extra_mut().align  = Some(opt_val.parse()?), -				"target" => image.extra_mut().target = Some(opt_val.parse()?), -				name => bail!("Unknown Image option {}", name), -			} +	for opt in pairs { +		let mut opt_iter = opt.into_inner(); +		let opt_name = opt_iter.next().unwrap(); +		let opt_val = opt_iter.next().unwrap(); +		match opt_name.as_str() { +			"class"  => image.classes_mut().push(opt_val.as_str().to_owned()), +			"name"   => image.names_mut().push(opt_val.as_str().into()), +			"alt"    => image.extra_mut().alt    = Some(opt_val.as_str().to_owned()), +			"height" => image.extra_mut().height = Some(opt_val.parse()?), +			"width"  => image.extra_mut().width  = Some(opt_val.parse()?), +			"scale"  => image.extra_mut().scale  = Some(parse_scale(&opt_val)?), +			"align"  => image.extra_mut().align  = Some(opt_val.parse()?), +			"target" => image.extra_mut().target = Some(opt_val.parse()?), +			name => bail!("Unknown Image option {}", name),  		}  	}  	Ok(image) diff --git a/src/parser/simplify.rs b/src/parser/simplify.rs index ab79343..cc169ee 100644 --- a/src/parser/simplify.rs +++ b/src/parser/simplify.rs @@ -53,7 +53,7 @@ impl NamedTargetType {  #[derive(Clone, Debug)]  struct Substitution { -	content: e::ImageInline, +	content: Vec<c::TextOrInlineElement>,  	/// If true and the sibling before the reference is a text node,  	/// the text node gets right-trimmed.   	ltrim: bool, @@ -94,7 +94,7 @@ impl TargetsCollected {  trait ResolvableRefs {  	fn populate_targets(&self, refs: &mut TargetsCollected); -	fn resolve_refs(self, refs: &TargetsCollected) -> Self; +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> where Self: Sized;  }  pub fn resolve_references(mut doc: Document) -> Document { @@ -102,7 +102,7 @@ pub fn resolve_references(mut doc: Document) -> Document {  	for c in doc.children() {  		c.populate_targets(&mut references);  	} -	let new: Vec<_> = doc.children_mut().drain(..).map(|c| c.resolve_refs(&references)).collect(); +	let new: Vec<_> = doc.children_mut().drain(..).flat_map(|c| c.resolve_refs(&references)).collect();  	Document::with_children(new)  } @@ -113,7 +113,7 @@ fn sub_pop<P, C>(parent: &P, refs: &mut TargetsCollected) where P: HasChildren<C  }  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(..).map(|c| c.resolve_refs(refs)).collect(); +	let new: Vec<_> = parent.children_mut().drain(..).flat_map(|c| c.resolve_refs(refs)).collect();  	parent.children_mut().extend(new);  	parent  } @@ -141,15 +141,15 @@ impl ResolvableRefs for c::StructuralSubElement {  			SubStructure(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::StructuralSubElement::*; -		match self { +		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) => e.resolve_refs(refs).into(), -		} +			SubStructure(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), +		}]  	}  } @@ -164,15 +164,15 @@ impl ResolvableRefs for c::SubStructure {  			BodyElement(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubStructure::*; -		match self { +		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) => e.resolve_refs(refs).into(), -		} +			BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), +		}]  	}  } @@ -186,13 +186,8 @@ impl ResolvableRefs for c::BodyElement {  			MathBlock(_) => {},  			Rubric(e) => sub_pop(&**e, refs),  			SubstitutionDefinition(e) => { -				let subst_content = if let [c::TextOrInlineElement::ImageInline(content)] = &e.children()[..] { -					content.as_ref() -				} else { -					panic!("Unexpected substitution contents.") -				};  				let subst = Substitution { -					content: subst_content.clone(), +					content: e.children().clone(),  					ltrim: e.extra().ltrim,  					rtrim: e.extra().rtrim  				}; @@ -246,15 +241,15 @@ impl ResolvableRefs for c::BodyElement {  			Table(e) => sub_pop(&**e, refs)  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::BodyElement::*; -		match self { +		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(e) => SubstitutionDefinition(e), +			SubstitutionDefinition(_) => return vec![],  			Comment(e) => Comment(e),  			Pending(e) => Pending(e),  			Target(e) => Target(e), @@ -284,7 +279,7 @@ impl ResolvableRefs for c::BodyElement {  			SystemMessage(e) => sub_res(*e, refs).into(),  			Figure(e) => sub_res(*e, refs).into(),  			Table(e) => sub_res(*e, refs).into() -		} +		}]  	}  } @@ -305,9 +300,9 @@ impl ResolvableRefs for c::BibliographicElement {  			Field(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::BibliographicElement::*; -		match self { +		vec![match self {  			Author(e) => sub_res(*e, refs).into(),  			Authors(e) => sub_res(*e, refs).into(),  			Organization(e) => sub_res(*e, refs).into(), @@ -319,7 +314,7 @@ impl ResolvableRefs for c::BibliographicElement {  			Date(e) => sub_res(*e, refs).into(),  			Copyright(e) => sub_res(*e, refs).into(),  			Field(e) => sub_res(*e, refs).into(), -		} +		}]  	}  } @@ -351,10 +346,10 @@ impl ResolvableRefs for c::TextOrInlineElement {  			ImageInline(_) => {}  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::TextOrInlineElement::*; -		match self { -			c::TextOrInlineElement::String(e) => c::TextOrInlineElement::String(e), +		vec![match self { +			String(e) => String(e),  			Emphasis(e) => sub_res(*e, refs).into(),  			Strong(e) => sub_res(*e, refs).into(),  			Literal(e) => sub_res(*e, refs).into(), @@ -375,7 +370,7 @@ impl ResolvableRefs for c::TextOrInlineElement {  					if *ltrim || *rtrim {  						dbg!(content, ltrim, rtrim);  					} -					ImageInline(Box::new(content.clone())) +					return content.clone()  				},  				None => {  					// Undefined substitution name (level 3 system message). @@ -404,7 +399,7 @@ impl ResolvableRefs for c::TextOrInlineElement {  			TargetInline(e) => TargetInline(e),  			RawInline(e) => RawInline(e),  			ImageInline(e) => ImageInline(e) -		} +		}]  	}  } @@ -418,14 +413,14 @@ impl ResolvableRefs for c::AuthorInfo {  			Contact(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::AuthorInfo::*; -		match self { +		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(), -		} +		}]  	}  } @@ -437,12 +432,12 @@ impl ResolvableRefs for c::DecorationElement {  			Footer(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::DecorationElement::*; -		match self { +		vec![match self {  			Header(e) => sub_res(*e, refs).into(),  			Footer(e) => sub_res(*e, refs).into(), -		} +		}]  	}  } @@ -454,11 +449,11 @@ impl ResolvableRefs for c::SubTopic {  			BodyElement(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubTopic::*;  		match self { -			Title(e) => sub_res(*e, refs).into(), -			BodyElement(e) => e.resolve_refs(refs).into(), +			Title(e) => vec![sub_res(*e, refs).into()], +			BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(),  		}  	}  } @@ -473,14 +468,14 @@ impl ResolvableRefs for c::SubSidebar {  			BodyElement(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubSidebar::*; -		match self { +		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) => e.resolve_refs(refs).into(), -		} +			BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), +		}]  	}  } @@ -493,13 +488,13 @@ impl ResolvableRefs for c::SubDLItem {  			Definition(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubDLItem::*; -		match self { +		vec![match self {  			Term(e) => sub_res(*e, refs).into(),  			Classifier(e) => sub_res(*e, refs).into(),  			Definition(e) => sub_res(*e, refs).into(), -		} +		}]  	}  } @@ -511,12 +506,12 @@ impl ResolvableRefs for c::SubField {  			FieldBody(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubField::*; -		match self { +		vec![match self {  			FieldName(e) => sub_res(*e, refs).into(),  			FieldBody(e) => sub_res(*e, refs).into(), -		} +		}]  	}  } @@ -528,18 +523,18 @@ impl ResolvableRefs for c::SubOptionListItem {  			Description(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubOptionListItem::*; -		match self { +		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) -> Self { self } +	fn resolve_refs(self, _: &TargetsCollected) -> Vec<Self> { vec![self] }  }  impl ResolvableRefs for c::SubLineBlock { @@ -550,12 +545,12 @@ impl ResolvableRefs for c::SubLineBlock {  			Line(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubLineBlock::*; -		match self { +		vec![match self {  			LineBlock(e) => sub_res(*e, refs).into(),  			Line(e) => sub_res(*e, refs).into(), -		} +		}]  	}  } @@ -567,11 +562,11 @@ impl ResolvableRefs for c::SubBlockQuote {  			BodyElement(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubBlockQuote::*;  		match self { -			Attribution(e) => sub_res(*e, refs).into(), -			BodyElement(e) => e.resolve_refs(refs).into(), +			Attribution(e) => vec![sub_res(*e, refs).into()], +			BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(),  		}  	}  } @@ -584,11 +579,11 @@ impl ResolvableRefs for c::SubFootnote {  			BodyElement(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubFootnote::*;  		match self { -			Label(e) => sub_res(*e, refs).into(), -			BodyElement(e) => e.resolve_refs(refs).into(), +			Label(e) => vec![sub_res(*e, refs).into()], +			BodyElement(e) => e.resolve_refs(refs).drain(..).map(Into::into).collect(),  		}  	}  } @@ -602,13 +597,13 @@ impl ResolvableRefs for c::SubFigure {  			BodyElement(e) => e.populate_targets(refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubFigure::*; -		match self { +		vec![match self {  			Caption(e) => sub_res(*e, refs).into(),  			Legend(e) => sub_res(*e, refs).into(), -			BodyElement(e) => e.resolve_refs(refs).into(), -		} +			BodyElement(e) => return e.resolve_refs(refs).drain(..).map(Into::into).collect(), +		}]  	}  } @@ -620,12 +615,12 @@ impl ResolvableRefs for c::SubTable {  			TableGroup(e) => sub_pop(&**e, refs),  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubTable::*; -		match self { +		vec![match self {  			Title(e) => sub_res(*e, refs).into(),  			TableGroup(e) => sub_res(*e, refs).into(), -		} +		}]  	}  } @@ -648,9 +643,9 @@ impl ResolvableRefs for c::SubTableGroup {  			},  		}  	} -	fn resolve_refs(self, refs: &TargetsCollected) -> Self { +	fn resolve_refs(self, refs: &TargetsCollected) -> Vec<Self> {  		use c::SubTableGroup::*; -		match self { +		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(); @@ -662,6 +657,6 @@ impl ResolvableRefs for c::SubTableGroup {  				e.children_mut().extend(new);  				TableBody(e)  			}, -		} +		}]  	}  } diff --git a/src/parser/tests.rs b/src/parser/tests.rs index ee33c8a..075b750 100644 --- a/src/parser/tests.rs +++ b/src/parser/tests.rs @@ -134,6 +134,32 @@ A |subst| in-line  	};  } + +#[allow(clippy::cognitive_complexity)] +#[test] +fn substitution_image() { +	parses_to! { +		parser: RstParser, +		input: "\ +.. |subst| image:: thing.png +   :target: foo.html +", +		rule: Rule::document, +		tokens: [ +			substitution_def(0, 50, [ +				substitution_name(4, 9), +				image(11, 50, [ +					line(18, 29, [ str(18, 28) ]), +					image_option(32, 50, [ +						image_opt_name(33, 39), +						line(40, 50, [ str(40, 49) ]), +					]), +				]), +			]), +		] +	}; +} +  // TODO: test images  #[allow(clippy::cognitive_complexity)] | 
