Skip to content

Commit 37e8dcb

Browse files
committed
Escape special characters in inline code in tables
1 parent edcac27 commit 37e8dcb

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

src/lib.rs

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ pub struct State<'a> {
7979
pub image_stack: Vec<ImageLink<'a>>,
8080
/// Keeps track of the last seen heading's id, classes, and attributes
8181
pub current_heading: Option<Heading<'a>>,
82+
/// True whenever between `Start(TableCell)` and `End(TableCell)`
83+
pub in_table_cell: bool,
8284

8385
/// Keeps track of the last seen shortcut/link
8486
pub current_shortcut_text: Option<String>,
@@ -305,10 +307,26 @@ where
305307
text_for_header.push_str(text);
306308
text_for_header.push('`');
307309
}
310+
311+
// (re)-escape `|` when it appears as part of inline code in the
312+
// body of a table. NOTES:
313+
// - This is always *safe*, but may not be *necessary*: more recent
314+
// versions of `pulldown-cmark` do not require this because they
315+
// correctly handle unescaped pipes in this position.
316+
// - This does not do *general* escaped-character handling because
317+
// the only character which *requires* this handling in this spot
318+
// in earlier versions of `pulldown-cmark` is a pipe character in
319+
// inline code in a table. Other escaping is handled when `Text`
320+
// events are emitted.
321+
let text = if state.in_table_cell {
322+
text.replace('|', "\\|")
323+
} else {
324+
text.to_string()
325+
};
308326
if text.chars().all(|ch| ch == ' ') {
309327
write!(formatter, "`{text}`")
310328
} else {
311-
let backticks = "`".repeat(count_consecutive(text, '`') + 1);
329+
let backticks = "`".repeat(count_consecutive(&text, '`') + 1);
312330
let space = match text.as_bytes() {
313331
&[b'`', ..] | &[.., b'`'] => " ", // Space needed to separate backtick.
314332
&[b' ', .., b' '] => " ", // Space needed to escape inner space.
@@ -355,6 +373,7 @@ where
355373
TableRow => Ok(()),
356374
TableCell => {
357375
state.text_for_header = Some(String::new());
376+
state.in_table_cell = true;
358377
formatter.write_char('|')
359378
}
360379
Link {
@@ -689,6 +708,7 @@ where
689708
state
690709
.table_headers
691710
.push(state.text_for_header.take().unwrap_or_default());
711+
state.in_table_cell = false;
692712
Ok(())
693713
}
694714
t @ (TagEnd::TableRow | TagEnd::TableHead) => {

0 commit comments

Comments
 (0)