Skip to content

Commit 4191458

Browse files
committed
fix: remove structural line breaks from tables
1 parent 5524225 commit 4191458

2 files changed

Lines changed: 65 additions & 1 deletion

File tree

native/src/document.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::Diagnostic;
1212
use crate::config::{
1313
NativeCollectionConfig, NativeMdxConfig, NativeMediaConfig, apply_schema_defaults_and_validate,
1414
};
15-
use crate::hast::rewrite_media;
15+
use crate::hast::{remove_table_line_breaks, rewrite_media};
1616

1717
#[derive(Debug, serde::Serialize)]
1818
#[serde(rename_all = "camelCase")]
@@ -104,6 +104,7 @@ pub fn prepare_mdx(
104104
apply_hard_breaks(&mut mdast);
105105
}
106106
let mut tree = mdxjs::mdast_util_to_hast(&mdast);
107+
remove_table_line_breaks(&mut tree);
107108
let media = rewrite_media(&mut tree, root, Path::new(file), media)?;
108109

109110
Ok(PreparedMdx {
@@ -369,6 +370,7 @@ fn split_frontmatter<'a>(
369370
mod tests {
370371
use std::fs;
371372

373+
use mdxjs::hast::Node;
372374
use serde_json::json;
373375

374376
use crate::config::{MediaMissing, NativeCollectionConfig, NativeMdxConfig, NativeMediaConfig};
@@ -457,6 +459,29 @@ mod tests {
457459
assert!(!module.contains("secret"));
458460
}
459461

462+
#[test]
463+
fn gfm_tables_do_not_keep_structure_line_breaks() {
464+
let source = "| a | b |\n| - | - |\n| 1 | 2 |\n";
465+
let options = NativeMdxConfig {
466+
gfm: true,
467+
hard_breaks: true,
468+
jsx_import_source: "react".into(),
469+
provider_import_source: String::new(),
470+
};
471+
let prepared = prepare_mdx(
472+
"posts/table",
473+
"/project/table.mdx",
474+
source,
475+
&options,
476+
false,
477+
std::path::Path::new("/project"),
478+
&NativeMediaConfig::default(),
479+
)
480+
.unwrap();
481+
482+
assert!(!has_table_structure_line_break(&prepared.tree));
483+
}
484+
460485
#[test]
461486
fn hard_breaks_only_replace_newlines_inside_text_nodes() {
462487
let source = "first\nsecond\n\n# Heading\n\n| a | b |\n| - | - |\n| 1 | 2 |\n";
@@ -560,4 +585,24 @@ mod tests {
560585

561586
assert_eq!(diagnostics[0].code, "AMAMO_MEDIA_OUTSIDE_ROOT");
562587
}
588+
589+
fn has_table_structure_line_break(node: &Node) -> bool {
590+
let is_table_structure = matches!(
591+
node,
592+
Node::Element(element)
593+
if matches!(
594+
element.tag_name.as_str(),
595+
"table" | "thead" | "tbody" | "tfoot" | "tr" | "th" | "td"
596+
)
597+
);
598+
let Some(children) = node.children() else {
599+
return false;
600+
};
601+
602+
(is_table_structure
603+
&& children
604+
.iter()
605+
.any(|child| matches!(child, Node::Text(text) if text.value == "\n")))
606+
|| children.iter().any(has_table_structure_line_break)
607+
}
563608
}

native/src/hast.rs

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,25 @@ pub fn inject_highlights(tree: &mut Node, replacements: &HashMap<usize, Node>) -
105105
replace_code_blocks(tree, replacements, &mut block_id)
106106
}
107107

108+
pub fn remove_table_line_breaks(node: &mut Node) {
109+
let remove_line_breaks = matches!(
110+
node,
111+
Node::Element(element)
112+
if matches!(
113+
element.tag_name.as_str(),
114+
"table" | "thead" | "tbody" | "tfoot" | "tr" | "th" | "td"
115+
)
116+
);
117+
let Some(children) = node.children_mut() else {
118+
return;
119+
};
120+
121+
if remove_line_breaks {
122+
children.retain(|child| !matches!(child, Node::Text(text) if text.value == "\n"));
123+
}
124+
children.iter_mut().for_each(remove_table_line_breaks);
125+
}
126+
108127
fn wire_node(wire: HastWire) -> Result<Node, Vec<Diagnostic>> {
109128
match wire {
110129
HastWire::Root { .. } => Err(vec![Diagnostic::error(

0 commit comments

Comments
 (0)