diff --git a/src/export/traverse.rs b/src/export/traverse.rs index a44398c..bb25a7a 100644 --- a/src/export/traverse.rs +++ b/src/export/traverse.rs @@ -143,7 +143,7 @@ pub trait Traverser { BLOCK_CONTENT | LIST_ITEM_CONTENT => traverse_children!(node), - _ => {} + kind => debug_assert!(!kind.is_element() && !kind.is_object()), } } diff --git a/src/syntax/block.rs b/src/syntax/block.rs index cabc90b..6e142ec 100644 --- a/src/syntax/block.rs +++ b/src/syntax/block.rs @@ -20,16 +20,15 @@ fn block_node_base(input: Input) -> IResult { let (input, (block_begin, name)) = block_begin_node(input)?; let (input, pre_blank) = blank_lines(input)?; - let (kind, is_greater_block) = match name { - s if s.eq_ignore_ascii_case("COMMENT") => (COMMENT_BLOCK, false), - s if s.eq_ignore_ascii_case("EXAMPLE") => (EXAMPLE_BLOCK, false), - s if s.eq_ignore_ascii_case("EXPORT") => (EXPORT_BLOCK, false), - s if s.eq_ignore_ascii_case("SRC") => (SOURCE_BLOCK, false), - - s if s.eq_ignore_ascii_case("CENTER") => (CENTER_BLOCK, true), - s if s.eq_ignore_ascii_case("QUOTE") => (QUOTE_BLOCK, true), - s if s.eq_ignore_ascii_case("VERSE") => (VERSE_BLOCK, true), - _ => (SPECIAL_BLOCK, true), + let kind = match name { + s if s.eq_ignore_ascii_case("COMMENT") => COMMENT_BLOCK, + s if s.eq_ignore_ascii_case("EXAMPLE") => EXAMPLE_BLOCK, + s if s.eq_ignore_ascii_case("EXPORT") => EXPORT_BLOCK, + s if s.eq_ignore_ascii_case("SRC") => SOURCE_BLOCK, + s if s.eq_ignore_ascii_case("CENTER") => CENTER_BLOCK, + s if s.eq_ignore_ascii_case("QUOTE") => QUOTE_BLOCK, + s if s.eq_ignore_ascii_case("VERSE") => VERSE_BLOCK, + _ => SPECIAL_BLOCK, }; for (input, contents) in line_starts_iter(input.as_str()).map(|i| input.take_split(i)) { @@ -38,7 +37,7 @@ fn block_node_base(input: Input) -> IResult { let mut children = vec![block_begin]; children.extend(pre_blank); - if is_greater_block { + if kind.is_greater_element() { children.push(node(BLOCK_CONTENT, element_nodes(contents)?)); } else { children.push(node(BLOCK_CONTENT, comma_quoted_text_nodes(contents))); diff --git a/src/syntax/mod.rs b/src/syntax/mod.rs index b16bb75..a77423f 100644 --- a/src/syntax/mod.rs +++ b/src/syntax/mod.rs @@ -222,3 +222,81 @@ impl From for rowan::SyntaxKind { OrgLanguage::kind_to_raw(value) } } + +impl SyntaxKind { + /// whether this node is [object](https://orgmode.org/worg/org-syntax.html#Objects) + pub fn is_object(&self) -> bool { + matches!( + self, + SyntaxKind::ENTITY + | SyntaxKind::LATEX_FRAGMENT + | SyntaxKind::SNIPPET + | SyntaxKind::FN_REF + | SyntaxKind::INLINE_CALL + | SyntaxKind::INLINE_SRC + | SyntaxKind::LINK + | SyntaxKind::MACROS + | SyntaxKind::RADIO_TARGET + | SyntaxKind::COOKIE + | SyntaxKind::ORG_TABLE_CELL + | SyntaxKind::TIMESTAMP_ACTIVE + | SyntaxKind::TIMESTAMP_INACTIVE + | SyntaxKind::TIMESTAMP_DIARY + | SyntaxKind::BOLD + | SyntaxKind::ITALIC + | SyntaxKind::UNDERLINE + | SyntaxKind::VERBATIM + | SyntaxKind::CODE + | SyntaxKind::STRIKE + ) + } + + /// whether this node is [element](https://orgmode.org/worg/org-syntax.html#Elements) + pub fn is_element(&self) -> bool { + matches!(self, SyntaxKind::HEADLINE | SyntaxKind::SECTION) + || self.is_lesser_element() + || self.is_greater_element() + } + + /// whether this node is [lesser element](https://orgmode.org/worg/org-syntax.html#Lesser_Elements) + pub fn is_lesser_element(&self) -> bool { + matches!( + self, + SyntaxKind::COMMENT_BLOCK + | SyntaxKind::EXAMPLE_BLOCK + | SyntaxKind::EXPORT_BLOCK + | SyntaxKind::SOURCE_BLOCK + | SyntaxKind::VERSE_BLOCK + | SyntaxKind::CLOCK + | SyntaxKind::PLANNING + | SyntaxKind::COMMENT + | SyntaxKind::FIXED_WIDTH + | SyntaxKind::RULE + | SyntaxKind::KEYWORD + | SyntaxKind::AFFILIATED_KEYWORD + | SyntaxKind::BABEL_CALL + | SyntaxKind::LATEX_ENVIRONMENT + | SyntaxKind::NODE_PROPERTY + | SyntaxKind::PARAGRAPH + | SyntaxKind::ORG_TABLE_RULE_ROW + | SyntaxKind::ORG_TABLE_STANDARD_ROW + ) + } + + /// whether this node is [greater element](https://orgmode.org/worg/org-syntax.html#Greater_Elements) + pub fn is_greater_element(&self) -> bool { + matches!( + self, + SyntaxKind::CENTER_BLOCK + | SyntaxKind::QUOTE_BLOCK + | SyntaxKind::SPECIAL_BLOCK + | SyntaxKind::DRAWER + | SyntaxKind::DYN_BLOCK + | SyntaxKind::FN_DEF + | SyntaxKind::LIST_ITEM + | SyntaxKind::LIST + | SyntaxKind::PROPERTY_DRAWER + | SyntaxKind::ORG_TABLE + ) + } +}