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 | |
| parent | 5387291c1a2d4cfd0e5acdad26dcc7e33329d39a (diff) | |
| download | rust-rst-df6b7645d845a022ca7eeba08b1ecb761a020195.tar.bz2 | |
Handling relative URLs in the conversion code.
Closes #10.
Diffstat (limited to 'src/parser')
| -rw-r--r-- | src/parser/conversion/inline.rs | 32 | ||||
| -rw-r--r-- | src/parser/simplify.rs | 4 |
2 files changed, 23 insertions, 13 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()); diff --git a/src/parser/simplify.rs b/src/parser/simplify.rs index bb47760..f6f0e8a 100644 --- a/src/parser/simplify.rs +++ b/src/parser/simplify.rs @@ -21,7 +21,7 @@ TODO: continue documenting how it’s done via http://svn.code.sf.net/p/docutils use std::collections::HashMap; -use crate::target::Target; +use crate::url::Url; use crate::document_tree::{ Document, HasChildren, @@ -37,7 +37,7 @@ enum NamedTargetType { LabeledFootnote(usize), Citation, InternalLink, - ExternalLink(Target), + ExternalLink(Url), IndirectLink(NameToken), SectionTitle } |
