Almost working implementation for brackets, stuck on last test
This commit is contained in:
parent
50bf00c167
commit
8ff39850a9
|
@ -19,7 +19,7 @@ clap = "2.2.1"
|
||||||
handlebars = "0.20.0"
|
handlebars = "0.20.0"
|
||||||
rustc-serialize = "0.3.18"
|
rustc-serialize = "0.3.18"
|
||||||
pulldown-cmark = "0.0.8"
|
pulldown-cmark = "0.0.8"
|
||||||
nom = "1.2.3"
|
nom = "1.2.4"
|
||||||
|
|
||||||
# Watch feature
|
# Watch feature
|
||||||
notify = { version = "2.5.5", optional = true }
|
notify = { version = "2.5.5", optional = true }
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use nom::{self, IResult, alphanumeric};
|
use nom::{self, IResult};
|
||||||
|
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -15,6 +15,7 @@ fn link(i: &[u8]) -> IResult<&[u8], Link> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parser for parsing the title part of the link: [title](destination)
|
/// Parser for parsing the title part of the link: [title](destination)
|
||||||
|
/// ^^^^^^^
|
||||||
///
|
///
|
||||||
/// From the Common Mark spec (http://spec.commonmark.org/0.26/#links):
|
/// From the Common Mark spec (http://spec.commonmark.org/0.26/#links):
|
||||||
///
|
///
|
||||||
|
@ -22,9 +23,42 @@ fn link(i: &[u8]) -> IResult<&[u8], Link> {
|
||||||
/// (a) they are backslash-escaped or
|
/// (a) they are backslash-escaped or
|
||||||
/// (b) they appear as a matched pair of brackets,
|
/// (b) they appear as a matched pair of brackets,
|
||||||
/// with an open bracket [, a sequence of zero or more inlines, and a close bracket ].
|
/// with an open bracket [, a sequence of zero or more inlines, and a close bracket ].
|
||||||
/// ^^^^^^^
|
///
|
||||||
fn link_text(i: &[u8]) -> IResult<&[u8], String> {
|
fn link_text(i: &[u8]) -> IResult<&[u8], String> {
|
||||||
map_res!(i, map_res!(delimited!(char!('['), is_not!("[]"), char!(']')), str::from_utf8), FromStr::from_str)
|
map_res!(i,
|
||||||
|
map_res!(
|
||||||
|
delimited!(
|
||||||
|
// Begin with '['
|
||||||
|
char!('['),
|
||||||
|
// Followed by anything that is not '[' or ']'
|
||||||
|
// Make sure to allow escaped brackets and balanced brackets
|
||||||
|
recognize!(many1!(alt!(not_unescaped_bracket | balanced_brackets))),
|
||||||
|
// End with ']'
|
||||||
|
char!(']')
|
||||||
|
),
|
||||||
|
str::from_utf8
|
||||||
|
),
|
||||||
|
FromStr::from_str
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg_attr(rustfmt, rustfmt_skip)]
|
||||||
|
fn balanced_brackets(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||||
|
recognize!(i,
|
||||||
|
delimited!(
|
||||||
|
// Begin with '['
|
||||||
|
char!('['),
|
||||||
|
// Followed by anything that is not '[' or ']'
|
||||||
|
// Make sure to allow escaped brackets and balanced brackets
|
||||||
|
many0!(alt!(not_unescaped_bracket | balanced_brackets)),
|
||||||
|
// End with ']'
|
||||||
|
char!(']')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn not_unescaped_bracket(i: &[u8]) -> IResult<&[u8], &[u8]> {
|
||||||
|
escaped!(i, is_not!("\\[]"), '\\', is_a_bytes!(&b"[]"[..]))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parser for parsing the destination part of the link: [title](destination)
|
/// Parser for parsing the destination part of the link: [title](destination)
|
||||||
|
@ -37,6 +71,33 @@ fn link_destination(i: &[u8]) -> IResult<&[u8], String> {
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use nom::{self, IResult};
|
use nom::{self, IResult};
|
||||||
|
use nom::Err::{NodePosition, Position};
|
||||||
|
use nom::ErrorKind::Escaped;
|
||||||
|
|
||||||
|
// Tests not_unescaped_bracket
|
||||||
|
#[test]
|
||||||
|
fn not_unescaped_bracket() {
|
||||||
|
assert_eq!(super::not_unescaped_bracket(b"a"), IResult::Done(&b""[..], &b"a"[..]));
|
||||||
|
assert_eq!(super::not_unescaped_bracket(b"-"), IResult::Done(&b""[..], &b"-"[..]));
|
||||||
|
assert_eq!(super::not_unescaped_bracket(b"\\["), IResult::Done(&b""[..], &b"\\["[..]));
|
||||||
|
assert_eq!(super::not_unescaped_bracket(b"]"), IResult::Error(NodePosition(Escaped, &[93][..], Box::new(Position(Escaped, &[93][..])))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tests for balanced brackets
|
||||||
|
#[test]
|
||||||
|
fn balanced_brackets() {
|
||||||
|
assert_eq!(super::balanced_brackets(b"[a]"), nom::IResult::Done(&b""[..], &b"[a]"[..]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn balanced_brackets_empty() {
|
||||||
|
assert_eq!(super::balanced_brackets(b"[]"), nom::IResult::Done(&b""[..], &b"[]"[..]));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn balanced_brackets_nested() {
|
||||||
|
assert_eq!(super::balanced_brackets(b"[abc[a]]"), nom::IResult::Done(&b""[..], &b"[abc[a]]"[..]));
|
||||||
|
}
|
||||||
|
|
||||||
// Tests for link_text
|
// Tests for link_text
|
||||||
|
|
||||||
|
@ -66,6 +127,6 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn link_text_brackets() {
|
fn link_text_brackets() {
|
||||||
assert_eq!(super::link_text(b"[Intro[]]"), nom::IResult::Done(&b""[..], String::from("Intro[]")));
|
assert_eq!(super::link_text(b"[Intro[]]"), nom::IResult::Done(&b""[..], String::from("Intro[]")));
|
||||||
assert_eq!(super::link_text(br"[Intro\[]"), nom::IResult::Done(&b""[..], String::from("Intro[")));
|
assert_eq!(super::link_text(br"[Intro\]]"), nom::IResult::Done(&b""[..], String::from("Intro[")));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue