Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
245 changes: 173 additions & 72 deletions Cargo.lock

Large diffs are not rendered by default.

7 changes: 5 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,10 @@ clap = { version = "4", features = ["derive"] }
regex = "1"
once_cell = "1"
rayon = "1.11"
html5ever = "0.27"
markup5ever_rcdom = "0.3"
html5ever = "0.39.0"
# `markup5ever_rcdom` must stay on the same parser stack as `html5ever`
# because `RcDom` implements `TreeSink` from that shared `markup5ever` line.
markup5ever_rcdom = "0.39.0"
textwrap = "0.16.2"
unicode-width = "0.2"

Expand All @@ -35,6 +37,7 @@ insta = "1.47"
tempfile = "3"
libc = "0.2.174"
predicates = "3"
trybuild = "1"

[lints.clippy]
pedantic = "warn"
5 changes: 4 additions & 1 deletion docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -257,7 +257,10 @@ immediately follows an H2 heading when these conditions are met.

`mdtablefix` can format simple HTML `<table>` elements embedded in Markdown.
These HTML tables are transformed into Markdown before the main table reflow
logic runs. That preprocessing is handled by the `convert_html_tables` function.
logic runs. That preprocessing is handled by the `convert_html_tables`
function. The parser path uses `html5ever` to build a temporary `RcDom` tree
through `markup5ever_rcdom`, then walks that tree to extract table rows and
cells.

Only straightforward tables with `<tr>`, `<th>` and `<td>` tags are detected.
Attributes and tag casing are ignored, and complex nested or styled tables are
Expand Down
12 changes: 12 additions & 0 deletions docs/developers-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,18 @@ restores the separator row with widths derived from the final table body.
- `format_separator_cells`: Expands separator cells to the target widths while
preserving Markdown alignment markers.

## HTML parser dependency coupling

HTML table conversion uses `html5ever` for parsing and `markup5ever_rcdom` for
the temporary DOM sink. These crates must stay on the same `markup5ever` parser
stack because `RcDom` implements the `TreeSink` trait from that shared
dependency line. If `html5ever` is upgraded, update `markup5ever_rcdom` in the
same change and run the compile-time parser integration test before merging.

The manifest uses caret requirements rather than exact pins, so compatible
patch updates remain available. The lockfile records the concrete crate release
selected for the branch.

## Fence normalization module

`src/fences.rs` exposes the preprocessing helpers used by the `--fences` option.
Expand Down
5 changes: 3 additions & 2 deletions tests/breaks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@

use std::borrow::Cow;

use assert_cmd::Command;
use mdtablefix::{THEMATIC_BREAK_LEN, format_breaks};

#[macro_use]
mod prelude;
use prelude::*;
#[path = "common/mod.rs"]
mod common;

#[test]
fn test_format_breaks_basic() {
Expand Down
6 changes: 4 additions & 2 deletions tests/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ use std::{
io::Write,
};

use assert_cmd::Command;
use rstest::rstest;
use tempfile::tempdir;

#[macro_use]
mod prelude;
use prelude::*;
#[path = "common/mod.rs"]
mod common;
use common::broken_table;

/// Verifies that the CLI fails when the `--in-place` flag is used without specifying a file.
///
Expand Down
5 changes: 3 additions & 2 deletions tests/cli_fences.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
//! CLI regression tests for fence normalization edge cases.

#[macro_use]
mod prelude;
use prelude::*;
#[path = "common/mod.rs"]
mod common;
use common::run_cli_with_stdin;

#[test]
fn test_cli_fences_preserves_nested_backtick_block() {
Expand Down
5 changes: 3 additions & 2 deletions tests/code_emphasis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@
//!
//! Verifies that emphasis markers adjacent to inline code are normalised.

mod prelude;
use std::fs;

use prelude::{run_cli_with_args, run_cli_with_stdin};
#[path = "common/mod.rs"]
mod common;
use common::{run_cli_with_args, run_cli_with_stdin};
use tempfile::tempdir;

#[test]
Expand Down
7 changes: 7 additions & 0 deletions tests/compile.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
//! Compile-time regression tests for dependency integration.

#[test]
fn html5ever_rcdom_parser_stack_compiles() {
let cases = trybuild::TestCases::new();
cases.pass("tests/ui/html5ever_rcdom_pass.rs");
}
3 changes: 2 additions & 1 deletion tests/fences.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
//! Tests for fence normalisation functionality.

#[macro_use]
mod prelude;
#[path = "common/mod.rs"]
mod common;
use mdtablefix::{attach_orphan_specifiers, compress_fences};
use rstest::rstest;

Expand Down
8 changes: 4 additions & 4 deletions tests/footnotes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,20 @@
//!
//! Each test processes a complete Markdown document using
//! `convert_footnotes`. Inputs are loaded from fixture files through the
//! `include_lines!` and `lines_vec!` macros re-exported by `tests::prelude`.
//! `include_lines!` and `lines_vec!` macros from the shared test utilities.
//! The cases mix headings, code blocks and ordinary text to confirm that
//! inline references become footnote links; eligible trailing numeric lists are
//! rewritten as definition-style footnotes when at least one footnote reference exists;
//! footnotes are renumbered sequentially with definitions reordered to match.
//!
//! A simple check ensures these macros are available so the prelude exports
//! are correctly wired for all integration tests.
//! A simple check ensures these macros are available for integration tests.

use mdtablefix::{convert_footnotes, process_stream};
use rstest::rstest;

#[macro_use]
mod prelude;
#[path = "common/mod.rs"]
mod common;

#[test]
fn macros_available() {
Expand Down
5 changes: 3 additions & 2 deletions tests/lists.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
//! Integration tests for list renumbering.

use assert_cmd::Command;
use mdtablefix::renumber_lists;
use rstest::rstest;

#[macro_use]
mod prelude;
use prelude::*;
#[path = "common/mod.rs"]
mod common;

#[test]
fn restart_after_equal_indent_paragraph() {
Expand Down
3 changes: 2 additions & 1 deletion tests/markdownlint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
//! after processing. Regular comments should still be wrapped normally.

#[macro_use]
mod prelude;
#[path = "common/mod.rs"]
mod common;
use mdtablefix::process_stream;
use rstest::rstest;

Expand Down
6 changes: 4 additions & 2 deletions tests/parallel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@

use std::{fs::File, io::Write};

use assert_cmd::Command;
use rstest::rstest;
use tempfile::tempdir;

#[macro_use]
mod prelude;
use prelude::*;
#[path = "common/mod.rs"]
mod common;
use common::{broken_table, run_cli_with_args};

#[rstest]
fn test_cli_parallel_empty_file_list() { run_cli_with_args(&[]).success().stdout("\n"); }
Expand Down
15 changes: 0 additions & 15 deletions tests/prelude/mod.rs

This file was deleted.

5 changes: 3 additions & 2 deletions tests/table/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@
//! across different scenarios whilst avoiding duplication.

use mdtablefix::{convert_html_tables, process_stream, reflow_table};
use rstest::fixture;

#[macro_use]
mod prelude;
use prelude::*;
#[path = "../common/mod.rs"]
mod common;

#[fixture]
fn malformed_table() -> Vec<String> {
Expand Down
12 changes: 12 additions & 0 deletions tests/ui/html5ever_rcdom_pass.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
//! Ensures `markup5ever_rcdom::RcDom` implements the `TreeSink` expected by
//! the active `html5ever` parser stack.

use html5ever::{driver::ParseOpts, parse_document, tendril::TendrilSink};
use markup5ever_rcdom::RcDom;

fn main() {
let opts = ParseOpts::default();
let dom: RcDom = parse_document(RcDom::default(), opts).one("<table></table>");

let _document = dom.document;
}
5 changes: 3 additions & 2 deletions tests/wrap/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@
use mdtablefix::process_stream;

#[macro_use]
mod prelude;
use prelude::*;
#[path = "../common/mod.rs"]
mod common;
use common::{assert_wrapped_blockquote, assert_wrapped_list_item, run_cli_with_stdin};

mod paragraphs;
mod lists;
Expand Down
3 changes: 2 additions & 1 deletion tests/wrap_renumber.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
use mdtablefix::{process_stream, renumber_lists};

#[macro_use]
mod prelude;
#[path = "common/mod.rs"]
mod common;

#[test]
fn wrap_then_renumber_preserves_order() {
Expand Down
Loading