From 5a98a4626d4e87c4681f7f2434bbc56c90bad322 Mon Sep 17 00:00:00 2001 From: Titus Wormer Date: Thu, 14 Jul 2022 19:28:36 +0200 Subject: Fix interrupting sibling list items --- src/construct/list.rs | 4 +-- src/content/document.rs | 29 ++++++++++++++---- tests/list.rs | 79 ++++++++++++++++++++++--------------------------- 3 files changed, 61 insertions(+), 51 deletions(-) diff --git a/src/construct/list.rs b/src/construct/list.rs index bab821c..6614122 100644 --- a/src/construct/list.rs +++ b/src/construct/list.rs @@ -112,10 +112,9 @@ fn before(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { Box::new(if ok { nok } else { before_unordered }) })(tokenizer, code), // Ordered. - Code::Char(char) if char.is_ascii_digit() => { + Code::Char(char) if char.is_ascii_digit() && (!tokenizer.interrupt || char == '1') => { tokenizer.enter(Token::ListItemPrefix); tokenizer.enter(Token::ListItemValue); - // To do: `interrupt || !1`? inside(tokenizer, code, 0) } _ => (State::Nok, None), @@ -271,7 +270,6 @@ pub fn blank_cont(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { // We have a blank line. // Still, try to consume at most the items size. - // To do: eat at most `size` whitespace. tokenizer.go(space_or_tab_min_max(0, size), cont_after)(tokenizer, code) } diff --git a/src/content/document.rs b/src/content/document.rs index bec0039..cd66909 100644 --- a/src/content/document.rs +++ b/src/content/document.rs @@ -37,6 +37,7 @@ struct DocumentInfo { continued: usize, index: usize, paragraph_before: bool, + interrupt_before: bool, inject: Vec<(Vec, Vec)>, stack: Vec, states: Vec, @@ -88,6 +89,7 @@ fn start(tokenizer: &mut Tokenizer, code: Code) -> StateFnResult { inject: vec![], next: Box::new(flow), paragraph_before: false, + interrupt_before: false, stack: vec![], states: vec![], stack_close: vec![], @@ -101,6 +103,8 @@ fn line_start(tokenizer: &mut Tokenizer, code: Code, mut info: DocumentInfo) -> info.index = tokenizer.events.len(); info.inject.push((vec![], vec![])); info.continued = 0; + // Containers would only be interrupting if we’ve continued. + tokenizer.interrupt = false; container_existing_before(tokenizer, code, info) } @@ -189,9 +193,11 @@ fn container_new_before( } println!( - " to do: set interrupt? (before: {:?})", - tokenizer.interrupt + " set interrupt to {:?} because we have continued (was: {:?})", + info.interrupt_before, tokenizer.interrupt ); + tokenizer.interrupt = info.interrupt_before; + // // If we do have flow, it could still be a blank line, // // but we’d be interrupting it w/ a new container if there’s a current // // construct. @@ -267,6 +273,13 @@ fn container_new_after( info.states.push(container); info.stack.push(kind); info.continued = info.stack.len(); // To do: `+= 1`? + println!( + " set `interrupt`, `info.interrupt_before: false` because we have new containers (before: {:?}, {:?})", + info.interrupt_before, + tokenizer.interrupt + ); + info.interrupt_before = false; + tokenizer.interrupt = info.interrupt_before; container_new_before(tokenizer, code, info) } @@ -282,6 +295,11 @@ fn containers_after( info.inject.last_mut().unwrap().0.append(&mut containers); tokenizer.lazy = info.continued != info.stack.len(); + println!( + " restoring interrupt: {:?} (was: {:?})", + info.interrupt_before, tokenizer.interrupt + ); + tokenizer.interrupt = info.interrupt_before; // Define start. let point = tokenizer.point.clone(); @@ -358,6 +376,7 @@ fn flow_end( tokenizer.expect(code, true); info.paragraph_before = paragraph; + info.interrupt_before = tokenizer.interrupt; match result { State::Ok => { @@ -521,10 +540,10 @@ fn line_end( info.inject[index].1.append(&mut exits); println!( - " setting `interrupt: false` (before: {:?})", - tokenizer.interrupt + " setting `info.interrupt_before: false` (before: {:?})", + info.interrupt_before ); - tokenizer.interrupt = false; + info.interrupt_before = false; info } diff --git a/tests/list.rs b/tests/list.rs index d3fcb98..e773a84 100644 --- a/tests/list.rs +++ b/tests/list.rs @@ -155,12 +155,11 @@ fn list() { "should support indented code in list items (8)" ); - // To do: list (empty item is allowed to follow another item). - // assert_eq!( - // micromark("-\n foo\n-\n ```\n bar\n ```\n-\n baz"), - // "
    \n
  • foo
  • \n
  • \n
    bar\n
    \n
  • \n
  • \n
    baz\n
    \n
  • \n
", - // "should support blank first lines (1)" - // ); + assert_eq!( + micromark("-\n foo\n-\n ```\n bar\n ```\n-\n baz"), + "
    \n
  • foo
  • \n
  • \n
    bar\n
    \n
  • \n
  • \n
    baz\n
    \n
  • \n
", + "should support blank first lines (1)" + ); assert_eq!( micromark("- \n foo"), @@ -174,26 +173,23 @@ fn list() { "should support empty only items" ); - // To do: list (empty item is allowed to follow another item). - // assert_eq!( - // micromark("- foo\n-\n- bar"), - // "
    \n
  • foo
  • \n
  • \n
  • bar
  • \n
", - // "should support empty continued items" - // ); + assert_eq!( + micromark("- foo\n-\n- bar"), + "
    \n
  • foo
  • \n
  • \n
  • bar
  • \n
", + "should support empty continued items" + ); - // To do: list (empty item is allowed to follow another item). - // assert_eq!( - // micromark("- foo\n- \n- bar"), - // "
    \n
  • foo
  • \n
  • \n
  • bar
  • \n
", - // "should support blank continued items" - // ); + assert_eq!( + micromark("- foo\n- \n- bar"), + "
    \n
  • foo
  • \n
  • \n
  • bar
  • \n
", + "should support blank continued items" + ); - // To do: list (empty item is allowed to follow another item). - // assert_eq!( - // micromark("1. foo\n2.\n3. bar"), - // "
    \n
  1. foo
  2. \n
  3. \n
  4. bar
  5. \n
", - // "should support empty continued items (ordered)" - // ); + assert_eq!( + micromark("1. foo\n2.\n3. bar"), + "
    \n
  1. foo
  2. \n
  3. \n
  4. bar
  5. \n
", + "should support empty continued items (ordered)" + ); assert_eq!( micromark("*"), @@ -325,12 +321,11 @@ fn list() { "should support interrupting a paragraph" ); - // To do: list (interrupt paragraph). - // assert_eq!( - // micromark("a\n2. b"), - // "

a\n2. b

", - // "should not support interrupting a paragraph with a non-1 numbered item" - // ); + assert_eq!( + micromark("a\n2. b"), + "

a\n2. b

", + "should not support interrupting a paragraph with a non-1 numbered item" + ); assert_eq!( micromark("\n2. a"), @@ -404,12 +399,11 @@ fn list() { "should support loose lists w/ a blank line between (1)" ); - // To do: list (empty item is allowed to follow another item). - // assert_eq!( - // micromark("* a\n*\n\n* c"), - // "
    \n
  • \n

    a

    \n
  • \n
  • \n
  • \n

    c

    \n
  • \n
", - // "should support loose lists w/ a blank line between (2)" - // ); + assert_eq!( + micromark("* a\n*\n\n* c"), + "
    \n
  • \n

    a

    \n
  • \n
  • \n
  • \n

    c

    \n
  • \n
", + "should support loose lists w/ a blank line between (2)" + ); assert_eq!( micromark("- a\n- b\n\n c\n- d"), @@ -480,12 +474,11 @@ fn list() { ); // Extra. - // To do: list (empty item is allowed to follow another item). - // assert_eq!( - // micromark("* a\n*\n\n \n\t\n* b"), - // "
    \n
  • \n

    a

    \n
  • \n
  • \n
  • \n

    b

    \n
  • \n
", - // "should support continued list items after an empty list item w/ many blank lines" - // ); + assert_eq!( + micromark("* a\n*\n\n \n\t\n* b"), + "
    \n
  • \n

    a

    \n
  • \n
  • \n
  • \n

    b

    \n
  • \n
", + "should support continued list items after an empty list item w/ many blank lines" + ); assert_eq!( micromark("*\n ~~~p\n\n ~~~"), @@ -537,7 +530,7 @@ fn list() { "should remove indent of code (fenced) in list (4 spaces)" ); - // To do: list (some off by one bug with tabs). + // To do: list (something ugly with tabs and counts and skips?). // assert_eq!( // micromark("- ```\n\t\n ```"), // "
    \n
  • \n
      \n
    \n
  • \n
", -- cgit