From 8cfbdf985e2c6544a5ebb6edfc4f5fe9cc1a9a0b Mon Sep 17 00:00:00 2001 From: Ben Lubas Date: Sat, 1 Feb 2025 23:04:23 -0500 Subject: [PATCH] feat: parse_tree groups list items into Lists --- ...rust_norg__tests__carryover_tags_tree.snap | 19 +- ...ust_norg__tests__delimiting_mods_tree.snap | 19 +- .../rust_norg__tests__lists_tree.snap | 173 ++++++++++-------- src/stage_3.rs | 2 +- src/stage_4.rs | 37 +++- 5 files changed, 147 insertions(+), 103 deletions(-) diff --git a/src/snapshots/rust_norg__tests__carryover_tags_tree.snap b/src/snapshots/rust_norg__tests__carryover_tags_tree.snap index ba62533..eb74d03 100644 --- a/src/snapshots/rust_norg__tests__carryover_tags_tree.snap +++ b/src/snapshots/rust_norg__tests__carryover_tags_tree.snap @@ -69,15 +69,18 @@ expression: examples - Token: Text: two content: - - NestableDetachedModifier: + - List: modifier_type: UnorderedList - level: 4 - extensions: [] - text: - Paragraph: - - Token: - Text: four - content: [] + items: + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 4 + extensions: [] + text: + Paragraph: + - Token: + Text: four + content: [] - CarryoverTag: tag_type: Macro name: diff --git a/src/snapshots/rust_norg__tests__delimiting_mods_tree.snap b/src/snapshots/rust_norg__tests__delimiting_mods_tree.snap index ae6b99f..39bf66f 100644 --- a/src/snapshots/rust_norg__tests__delimiting_mods_tree.snap +++ b/src/snapshots/rust_norg__tests__delimiting_mods_tree.snap @@ -46,15 +46,18 @@ expression: examples - Paragraph: - Token: Text: two -- - NestableDetachedModifier: +- - List: modifier_type: UnorderedList - level: 1 - extensions: [] - text: - Paragraph: - - Token: - Text: list - content: [] + items: + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 1 + extensions: [] + text: + Paragraph: + - Token: + Text: list + content: [] - DelimitingModifier: HorizontalRule - Paragraph: - Token: diff --git a/src/snapshots/rust_norg__tests__lists_tree.snap b/src/snapshots/rust_norg__tests__lists_tree.snap index f21a3ad..140218d 100644 --- a/src/snapshots/rust_norg__tests__lists_tree.snap +++ b/src/snapshots/rust_norg__tests__lists_tree.snap @@ -2,57 +2,112 @@ source: src/lib.rs expression: examples --- -- - NestableDetachedModifier: +- - List: modifier_type: UnorderedList - level: 1 - extensions: [] - text: - Paragraph: - - Token: - Text: base - content: [] -- - NestableDetachedModifier: - modifier_type: UnorderedList - level: 1 - extensions: [] - text: - Paragraph: - - Token: - Text: one - content: + items: - NestableDetachedModifier: modifier_type: UnorderedList - level: 2 + level: 1 extensions: [] text: Paragraph: - Token: - Text: two + Text: base content: [] -- - NestableDetachedModifier: +- - List: modifier_type: UnorderedList - level: 1 - extensions: [] - text: - Paragraph: - - Token: - Text: one - content: + items: - NestableDetachedModifier: modifier_type: UnorderedList - level: 2 + level: 1 extensions: [] text: Paragraph: - Token: - Text: two - - Token: Whitespace + Text: one + content: + - List: + modifier_type: UnorderedList + items: + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 2 + extensions: [] + text: + Paragraph: + - Token: + Text: two + content: [] +- - List: + modifier_type: UnorderedList + items: + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 1 + extensions: [] + text: + Paragraph: - Token: - Text: with - - Token: Whitespace + Text: one + content: + - List: + modifier_type: UnorderedList + items: + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 2 + extensions: [] + text: + Paragraph: + - Token: + Text: two + - Token: Whitespace + - Token: + Text: with + - Token: Whitespace + - Token: + Text: content + content: [] + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 2 + extensions: [] + text: + Paragraph: + - Token: + Text: two + - Token: Whitespace + - Token: + Special: ( + - Token: + Text: "2" + - Token: + Special: ) + content: + - List: + modifier_type: UnorderedList + items: + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 3 + extensions: [] + text: + Paragraph: + - Token: + Text: three + content: [] + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 1 + extensions: [] + text: + Paragraph: - Token: - Text: content + Text: one content: [] +- - List: + modifier_type: UnorderedList + items: - NestableDetachedModifier: modifier_type: UnorderedList level: 2 @@ -61,47 +116,13 @@ expression: examples Paragraph: - Token: Text: two - - Token: Whitespace - - Token: - Special: ( - - Token: - Text: "2" + content: [] + - NestableDetachedModifier: + modifier_type: UnorderedList + level: 1 + extensions: [] + text: + Paragraph: - Token: - Special: ) - content: - - NestableDetachedModifier: - modifier_type: UnorderedList - level: 3 - extensions: [] - text: - Paragraph: - - Token: - Text: three - content: [] - - NestableDetachedModifier: - modifier_type: UnorderedList - level: 1 - extensions: [] - text: - Paragraph: - - Token: - Text: one - content: [] -- - NestableDetachedModifier: - modifier_type: UnorderedList - level: 2 - extensions: [] - text: - Paragraph: - - Token: - Text: two - content: [] - - NestableDetachedModifier: - modifier_type: UnorderedList - level: 1 - extensions: [] - text: - Paragraph: - - Token: - Text: one - content: [] + Text: one + content: [] diff --git a/src/stage_3.rs b/src/stage_3.rs index 6e56490..0c066bf 100644 --- a/src/stage_3.rs +++ b/src/stage_3.rs @@ -7,7 +7,7 @@ use textwrap::dedent; use crate::stage_2::{NorgBlock, ParagraphSegmentToken, ParagraphTokenList}; -#[derive(Clone, Hash, Debug, PartialEq, Eq, Serialize)] +#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq, Serialize)] pub enum NestableDetachedModifier { Quote, UnorderedList, diff --git a/src/stage_4.rs b/src/stage_4.rs index ed08eea..1a8868a 100644 --- a/src/stage_4.rs +++ b/src/stage_4.rs @@ -15,6 +15,12 @@ pub enum NorgAST { text: Box, content: Vec, }, + List { + modifier_type: NestableDetachedModifier, + // These will only ever be NestableDetachedModifiers, we should really pull them out into + // their own struct + items: Vec, + }, RangeableDetachedModifier { modifier_type: RangeableDetachedModifier, title: Vec, @@ -190,12 +196,13 @@ fn consume_nestable_detached_mod_content( start_level: &u16, flat: &[NorgASTFlat], i: &mut usize, + list_type: NestableDetachedModifier, ) -> Vec { let mut content = vec![]; for j in (*i + 1)..flat.len() { match &flat[j] { - NorgASTFlat::NestableDetachedModifier { level, .. } => { - if level <= start_level { + NorgASTFlat::NestableDetachedModifier { level, modifier_type, .. } => { + if *modifier_type != list_type || level <= start_level { content = stage_4(flat[(*i + 1)..j].to_vec()); *i = j - 1; break; @@ -208,8 +215,8 @@ fn consume_nestable_detached_mod_content( NorgASTFlat::CarryoverTag { next_object, .. } if matches!(**next_object, NorgASTFlat::NestableDetachedModifier { .. }) => { - if let NorgASTFlat::NestableDetachedModifier { level, .. } = **next_object { - if level <= *start_level { + if let NorgASTFlat::NestableDetachedModifier { level, modifier_type, .. } = **next_object { + if modifier_type != list_type || level <= *start_level { content = stage_4(flat[(*i + 1)..j].to_vec()); *i = j - 1; break; @@ -287,7 +294,7 @@ pub fn stage_4(flat: Vec) -> Vec { content, } => { let new_content = - consume_nestable_detached_mod_content(&level, &flat, &mut i); + consume_nestable_detached_mod_content(&level, &flat, &mut i, modifier_type); ast.push(NorgAST::CarryoverTag { tag_type: tag_type.clone(), name: name.to_vec(), @@ -312,15 +319,25 @@ pub fn stage_4(flat: Vec) -> Vec { extensions, content: text, } => { - let content = consume_nestable_detached_mod_content(start_level, &flat, &mut i); - - ast.push(NorgAST::NestableDetachedModifier { - modifier_type: modifier_type.clone(), + let content = consume_nestable_detached_mod_content(start_level, &flat, &mut i, *modifier_type); + let parsed = NorgAST::NestableDetachedModifier { + modifier_type: *modifier_type, level: *start_level, extensions: extensions.to_vec(), text: text.clone(), content, - }); + }; + if !ast.is_empty() { + let len = ast.len(); + if let NorgAST::List { modifier_type: list_modifier, ref mut items } = ast[len - 1] { + if *modifier_type == list_modifier { + items.push(parsed); + i += 1; + continue + } + } + } + ast.push(NorgAST::List { modifier_type: *modifier_type, items: vec![parsed] }); } _ => { ast.push(convert(item.clone()));