diff --git a/src/error.rs b/src/error.rs index acb676c..ca107be 100644 --- a/src/error.rs +++ b/src/error.rs @@ -26,6 +26,20 @@ pub enum OrgizeError { }, } +impl OrgizeError { + pub fn element<'a, 'b>(&self, org: &'a Org<'b>) -> &'a Element<'b> { + match &self { + OrgizeError::Children { at } + | OrgizeError::NoChildren { at } + | OrgizeError::HeadlineOrSection { at } + | OrgizeError::Title { at } + | OrgizeError::Headline { at } + | OrgizeError::Detached { at } + | OrgizeError::HeadlineLevel { at, .. } => org.arena[*at].get(), + } + } +} + impl Org<'_> { /// Validate an `Org` struct. pub fn validate(&self) -> Result<(), OrgizeError> { @@ -107,7 +121,6 @@ impl Org<'_> { | Element::Section | Element::Table(Table::Org { .. }) | Element::TableRow(TableRow::Standard) - | Element::TableCell | Element::Bold | Element::Italic | Element::Underline @@ -119,6 +132,9 @@ impl Org<'_> { return Err(OrgizeError::Children { at: node_id }); } } + // TableCell is a container but it might + // not contains anything, e.g. `||||||` + Element::TableCell => () } } Ok(()) diff --git a/src/parsers.rs b/src/parsers.rs index e42d9de..4afdbd4 100644 --- a/src/parsers.rs +++ b/src/parsers.rs @@ -1,6 +1,7 @@ // parser related functions use std::borrow::Cow; +use std::iter::once; use std::marker::PhantomData; use indextree::{Arena, NodeId}; @@ -168,7 +169,7 @@ pub fn parse_section_and_headlines<'a, T: ElementArena<'a>>( } let mut last_end = 0; - for i in memchr_iter(b'\n', content.as_bytes()) { + for i in memchr_iter(b'\n', content.as_bytes()).chain(once(content.len())) { if let Ok((mut tail, (headline_content, level))) = parse_headline(&content[last_end..]) { if last_end != 0 { let node = arena.push_element(Element::Section, parent); @@ -668,7 +669,7 @@ pub fn parse_table<'a, T: ElementArena<'a>>( let table_node = arena.push_element(Table::Org { tblfm: None }, parent); let mut last_end = 0; - for start in memchr_iter(b'\n', contents.as_bytes()) { + for start in memchr_iter(b'\n', contents.as_bytes()).chain(once(contents.len())) { let line = contents[last_end..start].trim(); match TableRow::parse(line) { Some(TableRow::Standard) => { @@ -727,10 +728,8 @@ pub fn take_lines_while(predicate: impl Fn(&str) -> bool) -> impl Fn(&str) -> IR if !predicate(&input[last_end..i - 1]) { return Ok((&input[last_end..], &input[0..last_end])); } - } else { - if !predicate(&input[last_end..i]) { - return Ok((&input[last_end..], &input[0..last_end])); - } + } else if !predicate(&input[last_end..i]) { + return Ok((&input[last_end..], &input[0..last_end])); } last_end = i + 1; }