[][src]Crate extended_pulldown

This crate extends pulldown_cmark to do the following:

  • smarten quotes according to a more complex but substantially slower algorithm than that used in pulldown_cmark versions greater than 8.0

  • substitute unicode en-dashes, em-dashes and ellipsis for --, --- and ....

  • allow multiple-paragraph footnotes by interpreting an indented and unlabelled code block within a footnote as text to be parsed again.

  • allow several new tags:

    • Sans
    • Centred
    • Right-aligned
    • Small caps
    • Subscript
    • Superscript

It also provides a function, flatten_footnotes, which replaces footnote references and definitions with a single group of tagged text; this allows rendering to targets like LaTeX which need a footnote to be defined at the point to which it refers. It inserts empty footnotes where a definition is missing.

In general, this crate mimics the structs and methods of pulldown_cmark. However its more complex conception of markdown comes at the cost of much slower parsing. It is therefore not recommended to use instead of pulldown_cmark except where this complexity is required.

The markdown syntax to use is otherwise essentially that of CommonMark togther with pulldown_cmark's extensions.

Examples

Inline Spans

These are parsed preferentially from html spans:

use extended_pulldown::Parser;
use extended_pulldown::Event::*;
use extended_pulldown::Tag::*;

let text = concat!(r#"<span class="sans">Sans text</span>"#,
r#"<span class="centred">Centred text</span>"#,
r#"<span class="right-aligned">Right-aligned text</span>"#,
r#"<span class="smallcaps">Small caps text</span>"#,
r#"<span class="subscript">Subscript text</span>"#,
r#"<span class="superscript">Superscript text</span>"#);
   
let parsed = Parser::new(text)
    .collect::<Vec<_>>();
let expected = vec![
    Start(Paragraph),
    Start(Sans),
    Text("Sans text".into()),
    End(Sans),
    Start(Centred),
    Text("Centred text".into()),
    End(Centred),
    Start(RightAligned),
    Text("Right-aligned text".into()),
    End(RightAligned),
    Start(SmallCaps),
    Text("Small caps text".into()),
    End(SmallCaps),
    Start(Subscript),
    Text("Subscript text".into()),
    End(Subscript),
    Start(Superscript),
    Text("Superscript text".into()),
    End(Superscript),
    End(Paragraph)
];
 assert_eq!(parsed, expected);

However, markdown syntax is also extended slightly, to allow wrapping a span of alphanumeric text in ^ to indicate superscript and in ~ to indicate subscript: 25^th^ July, H~2~O.

Multipara footnotes

use extended_pulldown::Parser;
use extended_pulldown::Event::*;
use extended_pulldown::Tag::*;
use pulldown_cmark::CodeBlockKind::Indented;
let text = "Hello World[^footnote]\n\n[^footnote]:\n\tA footnote\n\n\tIn *multiple* pieces";
let output = Parser::new(text)
    .collect::<Vec<_>>();
let pulldown_output = vec![
    Start(Paragraph),
    Text("Hello World".into()),
    FootnoteReference("footnote".into()),
    End(Paragraph),
    Start(FootnoteDefinition("footnote".into())),
    Start(CodeBlock(Indented)),
    Text("A footnote\n\n".into()),
    Text("In *multiple* pieces".into()),
    End(CodeBlock(Indented)),
    End(FootnoteDefinition("footnote".into()))
];
let extended_pulldown_output = vec![
    Start(Paragraph),
    Text("Hello World".into()),
    FootnoteReference("footnote".into()),
    End(Paragraph),
    Start(FootnoteDefinition("footnote".into())),
    Start(Paragraph),
    Text("A footnote".into()),
    End(Paragraph),
    Start(Paragraph),
    Text("In ".into()),
    Start(Emphasis),
    Text("multiple".into()),
    End(Emphasis),
    Text(" pieces".into()),
    End(Paragraph),
    End(FootnoteDefinition("footnote".into()))
];
assert!(output != pulldown_output);
assert_eq!(output, extended_pulldown_output);

Flattening footnotes

use extended_pulldown::Event::*;
use extended_pulldown::Tag;

let events = vec![
  Start(Tag::Paragraph),
  Text("Hello".into()),
  FootnoteReference("1".into()),
 End(Tag::Paragraph),
  Start(Tag::FootnoteDefinition("1".into())),
  Start(Tag::Paragraph),
  Text("World".into()),
 End(Tag::Paragraph),
  End(Tag::FootnoteDefinition("1".into())),
];

let flattened = extended_pulldown::flatten_footnotes(events);
let expected = vec![
  Start(Tag::Paragraph),
  Text("Hello".into()),
  Start(Tag::FlattenedFootnote),
  Text("World".into()),
  End(Tag::FlattenedFootnote),
  End(Tag::Paragraph)
];

assert_eq!(flattened, expected);

Structs

InlineParser

Markdown event iterator which drops non-inline elements, keeping only plain text, links, and superscript, subscript, emphasised, smallcaps and strong text

InlineStr

An inline string that can contain almost three words of utf-8 text.

Options

Options for rendering

Parser

Markdown event iterator

Enums

CodeBlockKind

Codeblock kind.

CowStr

A copy-on-write string that can be owned, borrowed or inlined.

Event

A markdown event

Tag

A tag containing other events

Traits

MakeStatic

Make a markdown event static; i.e. no longer pinned to the lifetime of the str used to produce it

Functions

flatten_footnotes

Replace Event::FootnoteReference(f) and a seperate definition Event::Start(Tag::FootnoteDefinition(f))...Event::End(Tag::FootnoteDefinition(f)) with (at the point where Event::FootnoteReference(f) was) Event::Start(Tag::FlattenedFootnote)...Event::End(Tag::FlattenedFootnote)