docx: w:sym glyphs beyond checkboxes (Wingdings bullets, Symbol-font operators) are silently dropped #193
Description
w:sym — a character drawn from a symbol font rather than the run's text — is dropped entirely by the DOCX run walker, so the character vanishes and adjacent runs glue together with a stray space. #177 addresses exactly the checked/unchecked box glyphs of Wingdings and Wingdings 2 (its own description scopes unknown symbols to "existing behavior"); the rest of the symbol repertoire still disappears.
Where
src/formats/docx/content.rs:482-541 — walk_run_content has arms for t, tab, ptab, br, cr, footnoteReference, endnoteReference, drawing, pict, object, fldChar, instrText; w:sym falls into _ => {} at line 541. grep -rn '"sym"' src/ finds nothing.
Repro (0.2.4, commit 261fc25)
<w:r><w:t>Check </w:t><w:sym w:font="Wingdings" w:char="F0B7"/><w:t> item</w:t></w:r>expected: Check • item (F0B7 is the round bullet Word's legacy bullet lists use)
actual: Check item
(The double space is the two text runs meeting where the symbol used to be.)
Why it matters
Two common cases lose real content:
- Legacy bullets: Word documents from the 97-2003 era (and text boxes/older generators still) use
w:symwith WingdingsF0B7(round bullet) /F0A7(small square) as the bullet marker in front of list items. The marker vanishes and the item reads as plain text. - Symbol font characters:
w:symwithw:font="Symbol"carries operators and math glyphs (2264≤,2265≥,2261≡,2248≈) — dropping one fromp ≤ qleavesp q, silently corrupting the statement.
The RTF and binary-DOC readers do not have this gap for the same characters: the .doc reader maps the control characters and code-page bytes through (src/formats/doc/mod.rs:781), and RTF symbol runs arrive as font-encoded \'xx bytes that decode through the font table.
Direction
A small Wingdings/Wingdings 2/Symbol codepage→Unicode table would cover the frequently used glyphs (F0B7 → •, F0A7 → ▪, F0D8 → ➢, F0A8 → ☐, and the Symbol operators ≤ ≥ ≡ ≈). #177's checkbox mapping is a start on the same table; folding the general case in would fix bullets and operators too. Unknown font/code pairs could at least log at debug level the way other skipped content does, instead of vanishing silently.
Activity