diff options
| author | Andreu Botella Botella | 2019-11-06 03:09:22 +0100 | 
|---|---|---|
| committer | Philipp A | 2019-11-07 09:27:38 +0100 | 
| commit | df6b7645d845a022ca7eeba08b1ecb761a020195 (patch) | |
| tree | b6809aefdafcf9aec6e833e53a8d2304fea17362 /src/parser/conversion/inline.rs | |
| parent | 5387291c1a2d4cfd0e5acdad26dcc7e33329d39a (diff) | |
| download | rust-rst-df6b7645d845a022ca7eeba08b1ecb761a020195.tar.bz2 | |
Handling relative URLs in the conversion code.
Closes #10.
Diffstat (limited to 'src/parser/conversion/inline.rs')
| -rw-r--r-- | src/parser/conversion/inline.rs | 32 | 
1 files changed, 21 insertions, 11 deletions
| diff --git a/src/parser/conversion/inline.rs b/src/parser/conversion/inline.rs index c51b2d9..c942732 100644 --- a/src/parser/conversion/inline.rs +++ b/src/parser/conversion/inline.rs @@ -1,6 +1,5 @@  use failure::Error;  use pest::iterators::Pair; -use url::Url;  use crate::document_tree::{  	ExtraAttributes, @@ -15,6 +14,7 @@ use crate::parser::{  //    pair_ext_parse::PairExt,  }; +use crate::url::Url;  use super::whitespace_normalize_name; @@ -73,16 +73,26 @@ fn convert_reference(pair: Pair<Rule>) -> Result<c::TextOrInlineElement, Error>  					refuri = if let Some(reference) = reference {  						let inner = reference.into_inner().next().unwrap();  						match inner.as_rule() { -							Rule::url => if let Ok(url) = Url::parse(inner.as_str()) { -								Some(url.into()) +							// The URL rules in our parser accept a narrow superset of +							// valid URLs, so we need to handle false positives. +							Rule::url => if let Ok(target) = Url::parse_absolute(inner.as_str()) { +								Some(target) +							} else if inner.as_str().ends_with('_') { +								// like target_name_qu (minus the final underscore) +								let full_str = inner.as_str(); +								refname.push(full_str[0..full_str.len() - 1].into()); +								None  							} else { -								unimplemented!("reference to a relative URL") +								// like relative_reference +								Some(Url::parse_relative(inner.as_str())?)  							},  							Rule::target_name_qu => {  								refname.push(inner.as_str().into());  								None  							}, -							Rule::relative_reference => unimplemented!("reference to a relative URL"), +							Rule::relative_reference => { +								Some(Url::parse_relative(inner.as_str())?) +							},  							_ => unreachable!()  						}  					} else { @@ -98,9 +108,9 @@ fn convert_reference(pair: Pair<Rule>) -> Result<c::TextOrInlineElement, Error>  		Rule::reference_auto => {  			let rt_inner = concrete.into_inner().next().unwrap();  			match rt_inner.as_rule() { -				Rule::url_auto => match Url::parse(rt_inner.as_str()) { -					Ok(url) => { -						refuri = Some(url.into()); +				Rule::url_auto => match Url::parse_absolute(rt_inner.as_str()) { +					Ok(target) => { +						refuri = Some(target);  						name   = None;  						refid  = None;  						children.push(rt_inner.as_str().into()); @@ -110,9 +120,9 @@ fn convert_reference(pair: Pair<Rule>) -> Result<c::TextOrInlineElement, Error>  				},  				Rule::email => {  					let mailto_url = String::from("mailto:") + rt_inner.as_str(); -					match Url::parse(&mailto_url) { -						Ok(url) => { -							refuri = Some(url.into()); +					match Url::parse_absolute(&mailto_url) { +						Ok(target) => { +							refuri = Some(target);  							name   = None;  							refid  = None;  							children.push(rt_inner.as_str().into()); | 
