PR #27 Expose tag for unresolved links
Merge branch 'unresolved_links' closes #27
This commit is contained in:
		
				commit
				
					
						5e2d567a54
					
				
			
		
					 4 changed files with 51 additions and 17 deletions
				
			
		| 
						 | 
					@ -25,9 +25,11 @@
 | 
				
			||||||
use crate::Alignment;
 | 
					use crate::Alignment;
 | 
				
			||||||
use crate::Container;
 | 
					use crate::Container;
 | 
				
			||||||
use crate::Event;
 | 
					use crate::Event;
 | 
				
			||||||
 | 
					use crate::LinkType;
 | 
				
			||||||
use crate::ListKind;
 | 
					use crate::ListKind;
 | 
				
			||||||
use crate::OrderedListNumbering::*;
 | 
					use crate::OrderedListNumbering::*;
 | 
				
			||||||
use crate::Render;
 | 
					use crate::Render;
 | 
				
			||||||
 | 
					use crate::SpanLinkType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct Renderer;
 | 
					pub struct Renderer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,11 +163,14 @@ impl<'s, I: Iterator<Item = Event<'s>>, W: std::fmt::Write> Writer<'s, I, W> {
 | 
				
			||||||
                        Container::DescriptionTerm => self.out.write_str("<dt")?,
 | 
					                        Container::DescriptionTerm => self.out.write_str("<dt")?,
 | 
				
			||||||
                        Container::CodeBlock { .. } => self.out.write_str("<pre")?,
 | 
					                        Container::CodeBlock { .. } => self.out.write_str("<pre")?,
 | 
				
			||||||
                        Container::Span | Container::Math { .. } => self.out.write_str("<span")?,
 | 
					                        Container::Span | Container::Math { .. } => self.out.write_str("<span")?,
 | 
				
			||||||
                        Container::Link(dst, ..) => {
 | 
					                        Container::Link(dst, ty) => {
 | 
				
			||||||
                            if dst.is_empty() {
 | 
					                            if matches!(ty, LinkType::Span(SpanLinkType::Unresolved)) {
 | 
				
			||||||
                                self.out.write_str("<a")?;
 | 
					                                self.out.write_str("<a")?;
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                self.out.write_str(r#"<a href=""#)?;
 | 
					                                self.out.write_str(r#"<a href=""#)?;
 | 
				
			||||||
 | 
					                                if matches!(ty, LinkType::Email) {
 | 
				
			||||||
 | 
					                                    self.out.write_str("mailto:")?;
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
                                self.write_attr(dst)?;
 | 
					                                self.write_attr(dst)?;
 | 
				
			||||||
                                self.out.write_char('"')?;
 | 
					                                self.out.write_char('"')?;
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										56
									
								
								src/lib.rs
									
										
									
									
									
								
							
							
						
						
									
										56
									
								
								src/lib.rs
									
										
									
									
									
								
							| 
						 | 
					@ -213,9 +213,10 @@ pub enum Container<'s> {
 | 
				
			||||||
    CodeBlock { lang: Option<&'s str> },
 | 
					    CodeBlock { lang: Option<&'s str> },
 | 
				
			||||||
    /// An inline divider element.
 | 
					    /// An inline divider element.
 | 
				
			||||||
    Span,
 | 
					    Span,
 | 
				
			||||||
    /// An inline link with a destination URL.
 | 
					    /// An inline link, the first field is either a destination URL or an unresolved tag.
 | 
				
			||||||
    Link(CowStr<'s>, LinkType),
 | 
					    Link(CowStr<'s>, LinkType),
 | 
				
			||||||
    /// An inline image with a source URL. Inner Str objects compose the alternative text.
 | 
					    /// An inline image, the first field is either a destination URL or an unresolved tag. Inner
 | 
				
			||||||
 | 
					    /// Str objects compose the alternative text.
 | 
				
			||||||
    Image(CowStr<'s>, SpanLinkType),
 | 
					    Image(CowStr<'s>, SpanLinkType),
 | 
				
			||||||
    /// An inline verbatim string.
 | 
					    /// An inline verbatim string.
 | 
				
			||||||
    Verbatim,
 | 
					    Verbatim,
 | 
				
			||||||
| 
						 | 
					@ -333,6 +334,8 @@ pub enum SpanLinkType {
 | 
				
			||||||
    Inline,
 | 
					    Inline,
 | 
				
			||||||
    /// In the form `[text][tag]` or `[tag][]`.
 | 
					    /// In the form `[text][tag]` or `[tag][]`.
 | 
				
			||||||
    Reference,
 | 
					    Reference,
 | 
				
			||||||
 | 
					    /// Like reference, but the tag is unresolved.
 | 
				
			||||||
 | 
					    Unresolved,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// The type of an inline link.
 | 
					/// The type of an inline link.
 | 
				
			||||||
| 
						 | 
					@ -729,29 +732,30 @@ impl<'s> Parser<'s> {
 | 
				
			||||||
                            let link_def =
 | 
					                            let link_def =
 | 
				
			||||||
                                self.pre_pass.link_definitions.get(tag.as_ref()).cloned();
 | 
					                                self.pre_pass.link_definitions.get(tag.as_ref()).cloned();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            let url = if let Some((url, attrs_def)) = link_def {
 | 
					                            let (url_or_tag, ty) = if let Some((url, attrs_def)) = link_def {
 | 
				
			||||||
                                attributes.union(attrs_def);
 | 
					                                attributes.union(attrs_def);
 | 
				
			||||||
                                url
 | 
					                                (url, SpanLinkType::Reference)
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                self.pre_pass
 | 
					                                self.pre_pass.heading_id_by_tag(tag.as_ref()).map_or_else(
 | 
				
			||||||
                                    .heading_id_by_tag(tag.as_ref())
 | 
					                                    || (tag, SpanLinkType::Unresolved),
 | 
				
			||||||
                                    .map_or_else(|| "".into(), |id| format!("#{}", id).into())
 | 
					                                    |id| (format!("#{}", id).into(), SpanLinkType::Reference),
 | 
				
			||||||
 | 
					                                )
 | 
				
			||||||
                            };
 | 
					                            };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                            if matches!(c, inline::Container::ReferenceLink) {
 | 
					                            if matches!(c, inline::Container::ReferenceLink) {
 | 
				
			||||||
                                Container::Link(url, LinkType::Span(SpanLinkType::Reference))
 | 
					                                Container::Link(url_or_tag, LinkType::Span(ty))
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                Container::Image(url, SpanLinkType::Reference)
 | 
					                                Container::Image(url_or_tag, ty)
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        inline::Container::Autolink => {
 | 
					                        inline::Container::Autolink => {
 | 
				
			||||||
                            let url = self.inlines.src(inline.span);
 | 
					                            let url = self.inlines.src(inline.span);
 | 
				
			||||||
                            let url = if url.contains('@') {
 | 
					                            let ty = if url.contains('@') {
 | 
				
			||||||
                                format!("mailto:{}", url).into()
 | 
					                                LinkType::Email
 | 
				
			||||||
                            } else {
 | 
					                            } else {
 | 
				
			||||||
                                url
 | 
					                                LinkType::AutoLink
 | 
				
			||||||
                            };
 | 
					                            };
 | 
				
			||||||
                            Container::Link(url, LinkType::AutoLink)
 | 
					                            Container::Link(url, ty)
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    };
 | 
					                    };
 | 
				
			||||||
                    if matches!(inline.kind, inline::EventKind::Enter(_)) {
 | 
					                    if matches!(inline.kind, inline::EventKind::Enter(_)) {
 | 
				
			||||||
| 
						 | 
					@ -1298,6 +1302,32 @@ mod test {
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn link_reference_unresolved() {
 | 
				
			||||||
 | 
					        test_parse!(
 | 
				
			||||||
 | 
					            "[text][tag]",
 | 
				
			||||||
 | 
					            Start(Paragraph, Attributes::new()),
 | 
				
			||||||
 | 
					            Start(
 | 
				
			||||||
 | 
					                Link("tag".into(), LinkType::Span(SpanLinkType::Unresolved)),
 | 
				
			||||||
 | 
					                Attributes::new()
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Str("text".into()),
 | 
				
			||||||
 | 
					            End(Link("tag".into(), LinkType::Span(SpanLinkType::Unresolved))),
 | 
				
			||||||
 | 
					            End(Paragraph),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        test_parse!(
 | 
				
			||||||
 | 
					            "![text][tag]",
 | 
				
			||||||
 | 
					            Start(Paragraph, Attributes::new()),
 | 
				
			||||||
 | 
					            Start(
 | 
				
			||||||
 | 
					                Image("tag".into(), SpanLinkType::Unresolved),
 | 
				
			||||||
 | 
					                Attributes::new()
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					            Str("text".into()),
 | 
				
			||||||
 | 
					            End(Image("tag".into(), SpanLinkType::Unresolved)),
 | 
				
			||||||
 | 
					            End(Paragraph),
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    #[test]
 | 
				
			||||||
    fn link_reference_multiline() {
 | 
					    fn link_reference_multiline() {
 | 
				
			||||||
        test_parse!(
 | 
					        test_parse!(
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,3 @@
 | 
				
			||||||
block_list_flat:large list marker number
 | 
					block_list_flat:large list marker number
 | 
				
			||||||
inline_links_flat:escaped attributes, empty hrefs
 | 
					inline_links_flat:space before img, img attrs order
 | 
				
			||||||
inline_links_nested:empty link text
 | 
					inline_links_nested:empty link text
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,6 @@ e1f5b5e:untrimmed whitespace before linebreak
 | 
				
			||||||
07888f3:div close within raw block
 | 
					07888f3:div close within raw block
 | 
				
			||||||
8423412:heading id conflict with existing id
 | 
					8423412:heading id conflict with existing id
 | 
				
			||||||
00a46ed:clear inline formatting from link tags
 | 
					00a46ed:clear inline formatting from link tags
 | 
				
			||||||
a8e17c3:empty href
 | 
					 | 
				
			||||||
c0a3dec:escape in url
 | 
					c0a3dec:escape in url
 | 
				
			||||||
e66af00:url container precedence
 | 
					e66af00:url container precedence
 | 
				
			||||||
61876cf:roman alpha ambiguity
 | 
					61876cf:roman alpha ambiguity
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue