From 86834a02b301bba48c2bd568beb156e604470167 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Tue, 12 Jul 2022 19:04:31 +0200 Subject: Fix some issues around empty lists --- src/construct/list.rs | 69 ++++++++++++++++++++++++++++++++++++++++--------- src/content/document.rs | 3 +++ src/util/skip.rs | 5 +++- 3 files changed, 64 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/construct/list.rs b/src/construct/list.rs index b81a5cc..27180a8 100644 --- a/src/construct/list.rs +++ b/src/construct/list.rs @@ -123,11 +123,6 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { } } -/// To do. -fn nok(_tokenizer: &mut Tokenizer, _code: Code) -> StateFnResult { - (State::Nok, None) -} - /// To do. fn before_unordered(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { // To do: check if this is a thematic break? @@ -160,13 +155,42 @@ fn marker(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { tokenizer.enter(Token::ListItemMarker); tokenizer.consume(code); tokenizer.exit(Token::ListItemMarker); - // To do: check blank line, if true `State::Nok` else `on_blank`. + println!("check:blank_line:before"); (State::Fn(Box::new(marker_after)), None) } /// To do. fn marker_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { - tokenizer.attempt(list_item_prefix_whitespace, |ok| { + let interrupt = tokenizer.interrupt; + + tokenizer.check(blank_line, move |ok| { + println!("check:blank_line:after {:?} {:?}", ok, interrupt); + let func = if ok { + if interrupt { + nok + } else { + on_blank + } + } else { + marker_after_after + }; + Box::new(func) + })(tokenizer, code) +} + +/// To do. +fn on_blank(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { + // self.containerState.initialBlankLine = true + // initialSize++ + prefix_end(tokenizer, code) +} + +/// To do. +fn marker_after_after(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { + println!("marker:after:before"); + let interrupt = tokenizer.interrupt; + tokenizer.attempt(list_item_prefix_whitespace, move |ok| { + println!("marker:after:after: {:?} {:?}", ok, interrupt); let func = if ok { prefix_end } else { prefix_other }; Box::new(func) })(tokenizer, code) @@ -209,16 +233,22 @@ fn list_item_prefix_whitespace_after(_tokenizer: &mut Tokenizer, code: Code) -> (State::Ok, Some(vec![code])) } +/// To do. +fn nok(_tokenizer: &mut Tokenizer, _code: Code) -> StateFnResult { + (State::Nok, None) +} + /// To do. pub fn cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { + println!("cont:check:blank:before"); tokenizer.check(blank_line, |ok| { + println!("cont:check:blank:after: {:?}", ok); let func = if ok { blank_cont } else { not_blank_cont }; Box::new(func) })(tokenizer, code) } pub fn blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { - println!("cont: blank"); // self.containerState.furtherBlankLines = // self.containerState.furtherBlankLines || // self.containerState.initialBlankLine @@ -235,10 +265,25 @@ pub fn blank_cont_after(_tokenizer: &mut Tokenizer, code: Code) -> StateFnResult } pub fn not_blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { - println!("cont: not blank"); - // if (self.containerState.furtherBlankLines || !markdownSpace(code)) nok - // To do: eat exactly `size` whitespace. - tokenizer.go(space_or_tab_min_max(TAB_SIZE, TAB_SIZE), blank_cont_after)(tokenizer, code) + let index = tokenizer.events.len(); + let currently_blank = + index > 0 && tokenizer.events[index - 1].token_type == Token::BlankLineEnding; + let mut further_blank = false; + + if currently_blank { + let before = skip::opt_back(&tokenizer.events, index - 3, &[Token::SpaceOrTab]); + further_blank = tokenizer.events[before].token_type == Token::BlankLineEnding; + } + + if further_blank || !matches!(code, Code::VirtualSpace | Code::Char('\t' | ' ')) { + println!("cont: not blank after further blank, or not blank w/o whitespace"); + println!("cont:nok:1"); + (State::Nok, None) + } else { + println!("cont: not blank"); + // To do: eat exactly `size` whitespace. + tokenizer.go(space_or_tab_min_max(TAB_SIZE, TAB_SIZE), blank_cont_after)(tokenizer, code) + } } /// To do. diff --git a/src/content/document.rs b/src/content/document.rs index c5bf5c8..27fb73d 100644 --- a/src/content/document.rs +++ b/src/content/document.rs @@ -156,6 +156,8 @@ fn check_new_containers( // self.interrupt = Boolean( // childFlow.currentConstruct && !childFlow._gfmTableDynamicInterruptHack // ) + } else { + tokenizer.interrupt = false; } // Check if there is a new container. @@ -299,6 +301,7 @@ fn exit_containers( println!("inject:0: {:?}", index); index = 0; } else { + index -= before; println!("set: {:?}", index); } info.inject[index].1.append(&mut exits); diff --git a/src/util/skip.rs b/src/util/skip.rs index 3307734..d7b3896 100644 --- a/src/util/skip.rs +++ b/src/util/skip.rs @@ -59,7 +59,10 @@ fn skip_opt_with_direction( }; if events[index].token_type == *current && balance == 0 { - println!("close:it! {:?} {:?}", events[index].token_type, balance); + println!( + "close:it! {:?} {:?} {:?}", + events[index].token_type, balance, index + ); index = if forward { index + 1 } else { index - 1 }; println!("index:break: {:?}", index); break; -- cgit