diff options
author | Titus Wormer <tituswormer@gmail.com> | 2022-10-28 18:28:12 +0200 |
---|---|---|
committer | Titus Wormer <tituswormer@gmail.com> | 2022-10-28 18:28:12 +0200 |
commit | e485745c6924e41f2896f579b5454cfb800e13f6 (patch) | |
tree | f4822d09d650f49e4776a43e5f1e6ec945762269 | |
parent | b910e37bb387a62509a7fda26617e9870ed6d56f (diff) | |
download | markdown-rs-e485745c6924e41f2896f579b5454cfb800e13f6.tar.gz markdown-rs-e485745c6924e41f2896f579b5454cfb800e13f6.tar.bz2 markdown-rs-e485745c6924e41f2896f579b5454cfb800e13f6.zip |
Fix GFM tables to require a non-pipe in header row
Related-to: GH-20.
-rw-r--r-- | src/construct/gfm_table.rs | 28 | ||||
-rw-r--r-- | tests/gfm_table.rs | 18 |
2 files changed, 39 insertions, 7 deletions
diff --git a/src/construct/gfm_table.rs b/src/construct/gfm_table.rs index e055e1d..3f88073 100644 --- a/src/construct/gfm_table.rs +++ b/src/construct/gfm_table.rs @@ -312,6 +312,8 @@ pub fn head_row_start(tokenizer: &mut Tokenizer) -> State { Some(b'|') => State::Retry(StateName::GfmTableHeadRowBreak), _ => { tokenizer.tokenize_state.seen = true; + // Count the first character, that isn’t a pipe, double. + tokenizer.tokenize_state.size_b += 1; State::Retry(StateName::GfmTableHeadRowBreak) } } @@ -332,22 +334,34 @@ pub fn head_row_break(tokenizer: &mut Tokenizer) -> State { None => { tokenizer.tokenize_state.seen = false; tokenizer.tokenize_state.size = 0; + tokenizer.tokenize_state.size_b = 0; State::Nok } Some(b'\n') => { - // Feel free to interrupt: - tokenizer.interrupt = true; - tokenizer.exit(Name::GfmTableRow); - tokenizer.enter(Name::LineEnding); - tokenizer.consume(); - tokenizer.exit(Name::LineEnding); - State::Next(StateName::GfmTableHeadDelimiterStart) + // If anything other than one pipe (ignoring whitespace) was used, it’s fine. + if tokenizer.tokenize_state.size_b > 1 { + tokenizer.tokenize_state.size_b = 0; + // Feel free to interrupt: + tokenizer.interrupt = true; + tokenizer.exit(Name::GfmTableRow); + tokenizer.enter(Name::LineEnding); + tokenizer.consume(); + tokenizer.exit(Name::LineEnding); + State::Next(StateName::GfmTableHeadDelimiterStart) + } else { + tokenizer.tokenize_state.seen = false; + tokenizer.tokenize_state.size = 0; + tokenizer.tokenize_state.size_b = 0; + State::Nok + } } Some(b'\t' | b' ') => { tokenizer.attempt(State::Next(StateName::GfmTableHeadRowBreak), State::Nok); State::Retry(space_or_tab(tokenizer)) } _ => { + tokenizer.tokenize_state.size_b += 1; + // Whether a delimiter was seen. if tokenizer.tokenize_state.seen { tokenizer.tokenize_state.seen = false; diff --git a/tests/gfm_table.rs b/tests/gfm_table.rs index db1c364..c8f20ef 100644 --- a/tests/gfm_table.rs +++ b/tests/gfm_table.rs @@ -130,6 +130,24 @@ fn gfm_table() -> Result<(), String> { ); assert_eq!( + to_html_with_options(":\n|-|\n|a|\n\nb\n|-|\n|c|\n\n|\n|-|\n|d|\n\n|\n|-|\n|e|\n\n|:\n|-|\n|f|\n\n||\n|-|\n|g|\n\n| |\n|-|\n|h|\n", &Options::gfm())?, + "<table>\n<thead>\n<tr>\n<th>:</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>a</td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th>b</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>c</td>\n</tr>\n</tbody>\n</table>\n<p>|\n|-|\n|d|</p>\n<p>|\n|-|\n|e|</p>\n<table>\n<thead>\n<tr>\n<th>:</th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>f</td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>g</td>\n</tr>\n</tbody>\n</table>\n<table>\n<thead>\n<tr>\n<th></th>\n</tr>\n</thead>\n<tbody>\n<tr>\n<td>h</td>\n</tr>\n</tbody>\n</table>\n", + "should need any character other than a single pipe in the header row" + ); + + assert_eq!( + to_html_with_options("a\n|-\n\nb\n||\n\nc\n|-|\n\nd\n|:|\n\ne\n| |\n\nf\n| -|\n\ng\n|- |\n", &Options::gfm())?, + "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<p>b\n||</p>\n<table>\n<thead>\n<tr>\n<th>c</th>\n</tr>\n</thead>\n</table>\n<p>d\n|:|</p>\n<p>e\n| |</p>\n<table>\n<thead>\n<tr>\n<th>f</th>\n</tr>\n</thead>\n</table>\n<table>\n<thead>\n<tr>\n<th>g</th>\n</tr>\n</thead>\n</table>\n", + "should need a dash in the delimimter row" + ); + + assert_eq!( + to_html_with_options("|\n|", &Options::gfm())?, + "<p>|\n|</p>", + "should need something" + ); + + assert_eq!( to_html_with_options("| a |\n| - |\n- b", &Options::gfm())?, "<table>\n<thead>\n<tr>\n<th>a</th>\n</tr>\n</thead>\n</table>\n<ul>\n<li>b</li>\n</ul>", "should support a list after a table" |