feat(preview): render RTF and Word documents - #1086
spandan11106 wants to merge 4 commits into
Conversation
RTF converts in-process to the bounded HTML subset the rendered document view already parses, keeping its Source view. DOCX is read with docx-rs inside the preview sandbox, which returns the same HTML as validated JSON for the application to reparse. Closes lgse#730
screenrecording-2026-09-17_14-36-48.mp4 |
|
request-changes on DOCX sandboxing, HTML reparse, the underline subset, and Blocker:
Minimal shape: Related: the walker sees
|
A \binN payload advanced the walk by that many source bytes. The preview source is a lossy decode, so the count could land inside a multi-byte character and slicing the next run of text panicked the in-process parser. Skip whole characters instead, and decode emitted text from the byte slice so no stored length can panic the walk.
|
Confirmed and fixed in 3335744. Thanks — the reproduction was exact.
Both halves of the diagnosis hold. Two changes:
Regression test You are right that a picture payload can still desync grouping — a decoded length is an approximation of a binary one, so a stray |
Description
Quick preview renders RTF and Word (DOCX) documents instead of showing raw source or nothing at all. Both feed the paragraph/block document model and virtualized rich-text view already used for Markdown, HTML, CSV/TSV and workbooks, so they inherit its theming, selection, copy, sorting and bounded-parsing behaviour.
\'hhescapes and\uNescapes with their\ucNfallback characters. Font tables, stylesheets, pictures, headers, footers and other non-body destination groups are discarded. It keeps its Source view like Markdown and HTML.docx-rsinside the existing preview sandbox, under the same 20 MiB input limit as workbooks, and returns bounded JSON that the application reparses with the existing HTML parser. Headings,Title/Subtitle, quote styles, inline formatting, tabs, breaks, bulleted and numbered lists with nesting, and tables all render; the first table row becomes the sortable column titles. Being a ZIP container, it has no Source view — the same as XLSX/ODS.u,ins) is now part of the supported HTML subset. The Pango layer already had the span style but the parser dropped it, so underlined text lost its formatting and raised a misleading "unsupported or active HTML content was omitted" notice.PreviewContent::Workbookis renamed toRendered, since spreadsheets and Word documents now share it.The RTF converter is hand written rather than using
rtf-parseras the issue proposed. That crate (0.4.3) drops\parentirely, so every paragraph runs together; decodes\'93to U+0093 instead of a curly quote; and turns舒?into an unrelated CJK character while leaving the?fallback in place. DOCX usesdocx-rsas planned.Known limits, documented in
docs/document-previews.md: DOCX drops images, hyperlink targets, headers, footers, footnotes and comments, joins each cell's paragraphs into one value, and flattens nested tables into their containing cell; RTF renders paragraphs and inline formatting only, so list markers and table cells become plain text, code pages other than Windows-1252 can mis-decode\'hh, and files over the 1 MiB preview limit fall back to Source.Visual evidence
Pending — a short video of both previews will be attached in a follow-up comment below.
How to test
.docxcontaining headings, bold/italic/underlined text, a bulleted list, a numbered list and a table, plus a.rtfwith several paragraphs, styled runs, curly quotes and an em dash. Any Word or WordPad/LibreOffice export works..docxand press Space..rtfand press Space, then use View source in the preview header and switch back to the rendered view.Expected result: the DOCX preview shows a styled document — headings, inline formatting, nested bullets, numbered items and a sortable table whose first row is the column titles — with no View source control and no omission notice; the copied cells arrive tab separated. The RTF preview shows one block per paragraph with its bold, italic, underlined and struck runs, curly quotes and dashes intact, and toggles between Rendered and Source. Both follow the active theme live. Files that cannot be parsed fall back to the source view or "Preview unavailable" rather than failing the pane.
Related issue
Closes #730