diff options
author | Lars Wirzenius <liw@liw.fi> | 2021-10-17 09:35:42 +0300 |
---|---|---|
committer | Lars Wirzenius <liw@liw.fi> | 2021-10-17 09:35:42 +0300 |
commit | d6946c3b0c8de9b0f836d2afff1274a616822c68 (patch) | |
tree | 1a5ef67a5a16ac269fdb428f494774ca5b6dd0d6 | |
parent | 951ea27cc9263c004c2ae171435affdc68ff7d9f (diff) | |
download | subplot-d6946c3b0c8de9b0f836d2afff1274a616822c68.tar.gz |
fix: regex for extracting YAML from Markdown
The old regex had a wrong, and weird, pattern for lines of YAML. The
new one is simpler and seems more correct: it matches lines not
staring with a dot.
Sponsored-by: author
-rw-r--r-- | src/ast.rs | 24 |
1 files changed, 15 insertions, 9 deletions
@@ -8,11 +8,11 @@ use tracing::{event, span, Level}; lazy_static! { // Pattern that recognises a YAML block at the beginning of a file. - static ref LEADING_YAML_PATTERN: Regex = Regex::new(r"^(?:\S*\n)*-{3,}\n(?P<yaml>([^.]+.*?\n)*)\.{3,}\n(?P<text>(.*\n)*)$").unwrap(); + static ref LEADING_YAML_PATTERN: Regex = Regex::new(r"^(?:\S*\n)*(?P<yaml>-{3,}\n([^.].*\n)*\.{3,}\n)(?P<text>(.*\n)*)$").unwrap(); - // Pattern that recognises a YAML block at the beginning of a file. - static ref TRAILING_YAML_PATTERN: Regex = Regex::new(r"(?P<text>(.*\n)*)\n*-{3,}\n(?P<yaml>(.*?\n)*)\.{3,}\n(?:\S*\n)*$").unwrap(); + // Pattern that recognises a YAML block at the end of a file. + static ref TRAILING_YAML_PATTERN: Regex = Regex::new(r"(?P<text>(.*\n)*)\n*(?P<yaml>-{3,}\n([^.].*\n)*\.{3,}\n)(?:\S*\n)*$").unwrap(); } /// An abstract syntax tree representation of a Markdown file. @@ -75,18 +75,24 @@ impl std::str::FromStr for AbstractSyntaxTree { // Extract a YAML metadata block using a given regex. fn get_yaml<'a>(pat: &Regex, markdown: &'a str) -> Option<(&'a str, &'a str)> { + event!(Level::TRACE, ?markdown, "Markdown"); if let Some(c) = pat.captures(markdown) { - event!(Level::TRACE, "YAML regex matches"); + event!(Level::TRACE, ?c, "YAML regex matches"); let yaml = c.name("yaml"); let text = c.name("text"); + event!(Level::TRACE, ?yaml, "YAML metadata"); + event!(Level::TRACE, ?text, "markdown"); if yaml.is_some() && text.is_some() { event!(Level::TRACE, "YAML regex captures YAML and text"); - let yaml = &markdown[yaml?.start()..yaml?.end()]; - - let text = &markdown[text?.start()..text?.end()]; + let yaml = yaml?; + let text = text?; + let yaml = &markdown[yaml.start()..yaml.end()]; + let text = &markdown[text.start()..text.end()]; + assert!(yaml.starts_with("---")); + assert!(yaml.ends_with("...\n")); return Some((yaml, text)); } else { - event!(Level::TRACE, ?c, "YAML regex fails to capture YAML"); + event!(Level::TRACE, "YAML regex fails to capture YAML"); } } else { event!(Level::TRACE, ?pat, "YAML regex does not match"); @@ -286,7 +292,7 @@ struct Metadata { impl Metadata { fn new(yaml_text: &str) -> Result<Self, Error> { - event!(Level::TRACE, "Parsing YAML"); + event!(Level::TRACE, ?yaml_text, "Parsing YAML"); let meta: Self = serde_yaml::from_str(yaml_text)?; Ok(meta) } |