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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
content focus. Custom processors constructing this public input must populate
the new fields.

### Fixed

- Bound DOCX table dimensions and padded cell work before local conversion,
including the default markkit backend. The deprecated Office renderer admits
Markdown bytes before escaping or padding into one capped buffer.

## [0.5.0] - 2026-07-14

### Highlights
Expand Down
2 changes: 1 addition & 1 deletion crates/fetchkit/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ default = ["docs-pdf", "docs-markkit"]
# Document conversion backends (see knowledge/foundations/fetchers.md)
docs-pdf = ["dep:pdf-inspector"]
# Office documents (DOCX, XLSX/XLSM, XLS, ODS) via markkit.
docs-markkit = ["dep:markkit"]
docs-markkit = ["dep:markkit", "dep:zip", "dep:quick-xml"]
# Deprecated in-crate Office converter (DOCX, PPTX, spreadsheets); use docs-markkit.
docs-office = ["dep:calamine", "dep:zip", "dep:quick-xml"]
docs-cloudflare = []
Expand Down
45 changes: 36 additions & 9 deletions crates/fetchkit/src/documents/markkit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
//! fetchkit adds the blocking-pool two-document concurrency cap and caps the final
//! Markdown at `max_body_size`. Callers tune markkit limits through
//! [`MarkkitConverter::with_markkit`].
//! - DOCX tables pass Fetchkit's archive preflight before markkit parses them:
//! sheet limits in markkit do not apply to DOCX padding (TM-DOS-008).
//! - The confirmed fetchkit format's canonical media type is passed as the hint, so
//! markkit parses the same format fetchkit detected and magic-checked.
//! - markkit warnings are `code: detail`; only the stable code is surfaced as a
Expand Down Expand Up @@ -107,20 +109,25 @@ impl DocumentConverter for MarkkitConverter {
}
let markkit = Arc::clone(&self.markkit);
let media_type = input.format.media_type();
let is_docx = input.format == DocumentFormat::Docx;
let DocumentInput {
body, file_name, ..
} = input;
let extraction = run_document_task(move || {
markkit.extract_document_sync(
&body,
DocumentHint {
content_type: Some(media_type),
file_name: Some(&file_name),
},
)
if is_docx {
super::tables::check_archive(&body, markkit.config())?;
}
markkit
.extract_document_sync(
&body,
DocumentHint {
content_type: Some(media_type),
file_name: Some(&file_name),
},
)
.map_err(map_error)
})
.await?
.map_err(map_error)?;
.await??;

let mut warnings: Vec<String> = Vec::new();
for warning in &extraction.warnings {
Expand Down Expand Up @@ -279,6 +286,26 @@ mod tests {
assert!(converted.warnings.is_empty());
}

#[tokio::test]
async fn converts_docx_with_relationship_selected_main_part() {
let body = zip(&[
(
"_rels/.rels",
r#"<Relationships><Relationship Id="r1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="./parts/custom.data"/></Relationships>"#,
),
(
"parts/custom.data",
r#"<w:document xmlns:w="w"><w:body><w:tbl><w:tr><w:tc><w:p><w:r><w:t>Owner</w:t></w:r></w:p></w:tc></w:tr><w:tr><w:tc><w:p><w:r><w:t>Ann</w:t></w:r></w:p></w:tc></w:tr></w:tbl></w:body></w:document>"#,
),
("word/media/image.png", "ordinary binary fixture"),
]);
let converted = MarkkitConverter::new()
.convert(input(DocumentFormat::Docx, body))
.await
.unwrap();
assert!(converted.markdown.contains("| Owner |\n| --- |\n| Ann |"));
}

#[tokio::test]
async fn converts_xlsx_and_reports_warning_codes() {
let converted = MarkkitConverter::new()
Expand Down
2 changes: 2 additions & 0 deletions crates/fetchkit/src/documents/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ mod pdf_inspector;
#[cfg(any(feature = "docs-cloudflare", feature = "docs-http"))]
mod remote;
mod settings;
#[cfg(any(feature = "docs-markkit", feature = "docs-office"))]
mod tables;

use std::collections::BTreeMap;
use std::fmt;
Expand Down
Loading
Loading