aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLibravatar Titus Wormer <tituswormer@gmail.com>2022-10-28 18:28:12 +0200
committerLibravatar Titus Wormer <tituswormer@gmail.com>2022-10-28 18:28:12 +0200
commite485745c6924e41f2896f579b5454cfb800e13f6 (patch)
treef4822d09d650f49e4776a43e5f1e6ec945762269
parentb910e37bb387a62509a7fda26617e9870ed6d56f (diff)
downloadmarkdown-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.rs28
-rw-r--r--tests/gfm_table.rs18
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"