diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-06-28 14:18:17 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-06-28 14:18:17 +0200 |
commit | dfd11b1bc155ae1fba9975a90c2dc83dc07697b4 (patch) | |
tree | 0dd150365a6ae1df4c4845518efafe02ab61cb77 /src/construct/partial_title.rs | |
parent | a3dd207e3b1ebcbcb6cec0f703a695e51ae4ece0 (diff) | |
download | markdown-rs-dfd11b1bc155ae1fba9975a90c2dc83dc07697b4.tar.gz markdown-rs-dfd11b1bc155ae1fba9975a90c2dc83dc07697b4.tar.bz2 markdown-rs-dfd11b1bc155ae1fba9975a90c2dc83dc07697b4.zip |
Fix jumps in `edit_map`
* Use resolve more often (e.g., heading (atx, setext))
* Fix to link whole phrasing (e.g., one big chunk of text in heading (atx,
setext), titles, labels)
* Replace `ChunkText`, `ChunkString`, with
`event.content_type: Option<ContentType>`
* Refactor to externalize `edit_map` from `label`
Diffstat (limited to 'src/construct/partial_title.rs')
-rw-r--r-- | src/construct/partial_title.rs | 67 |
1 files changed, 25 insertions, 42 deletions
diff --git a/src/construct/partial_title.rs b/src/construct/partial_title.rs index 78ae311..b102f7e 100644 --- a/src/construct/partial_title.rs +++ b/src/construct/partial_title.rs @@ -31,9 +31,11 @@ //! //! <!-- To do: link label end. --> -use crate::construct::partial_space_or_tab::space_or_tab; -use crate::subtokenize::link_to; -use crate::tokenizer::{Code, State, StateFnResult, TokenType, Tokenizer}; +use super::partial_space_or_tab::{ + space_or_tab_one_line_ending_with_options, OneLineEndingOptions, +}; +use crate::subtokenize::link; +use crate::tokenizer::{Code, ContentType, State, StateFnResult, TokenType, Tokenizer}; /// Configuration. /// @@ -108,8 +110,8 @@ impl Kind { /// State needed to parse titles. #[derive(Debug)] struct Info { - /// Whether we’ve seen our first `ChunkString`. - connect_index: Option<usize>, + /// Whether we’ve seen data. + connect: bool, /// Kind of title. kind: Kind, /// Configuration. @@ -127,7 +129,7 @@ pub fn start(tokenizer: &mut Tokenizer, code: Code, options: Options) -> StateFn match code { Code::Char(char) if char == '"' || char == '\'' || char == '(' => { let info = Info { - connect_index: None, + connect: false, kind: Kind::from_char(char), options, }; @@ -181,14 +183,24 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes begin(tokenizer, code, info) } Code::None => (State::Nok, None), + Code::CarriageReturnLineFeed | Code::Char('\r' | '\n') => tokenizer.go( + space_or_tab_one_line_ending_with_options(OneLineEndingOptions { + content_type: Some(ContentType::String), + connect: info.connect, + }), + |t, c| { + info.connect = true; + at_break(t, c, info) + }, + )(tokenizer, code), _ => { - tokenizer.enter(TokenType::ChunkString); + tokenizer.enter_with_content(TokenType::Data, Some(ContentType::String)); - if let Some(connect_index) = info.connect_index { + if info.connect { let index = tokenizer.events.len() - 1; - link_to(&mut tokenizer.events, connect_index, index); + link(&mut tokenizer.events, index); } else { - info.connect_index = Some(tokenizer.events.len() - 1); + info.connect = true; } title(tokenizer, code, info) @@ -196,30 +208,6 @@ fn at_break(tokenizer: &mut Tokenizer, code: Code, mut info: Info) -> StateFnRes } } -/// After a line ending. -/// -/// ```markdown -/// "a -/// |b" -/// ``` -fn line_start(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { - tokenizer.attempt_opt(space_or_tab(), |t, c| line_begin(t, c, info))(tokenizer, code) -} - -/// After a line ending, after optional whitespace. -/// -/// ```markdown -/// "a -/// |b" -/// ``` -fn line_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { - match code { - // Blank line not allowed. - Code::CarriageReturnLineFeed | Code::Char('\r' | '\n') => (State::Nok, None), - _ => at_break(tokenizer, code, info), - } -} - /// In title text. /// /// ```markdown @@ -228,18 +216,13 @@ fn line_begin(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResul fn title(tokenizer: &mut Tokenizer, code: Code, info: Info) -> StateFnResult { match code { Code::Char(char) if char == info.kind.as_char() => { - tokenizer.exit(TokenType::ChunkString); + tokenizer.exit(TokenType::Data); at_break(tokenizer, code, info) } - Code::None => { - tokenizer.exit(TokenType::ChunkString); + Code::None | Code::CarriageReturnLineFeed | Code::Char('\r' | '\n') => { + tokenizer.exit(TokenType::Data); at_break(tokenizer, code, info) } - Code::CarriageReturnLineFeed | Code::Char('\r' | '\n') => { - tokenizer.consume(code); - tokenizer.exit(TokenType::ChunkString); - (State::Fn(Box::new(|t, c| line_start(t, c, info))), None) - } Code::Char('\\') => { tokenizer.consume(code); (State::Fn(Box::new(|t, c| escape(t, c, info))), None) |