Skip to content

fix(rtfcre): escape characters outside code page 1252 on export - #1857

Merged
mkrnr merged 3 commits into
opensteno:mainfrom
Sanjays2402:fix/rtf-export-unicode-1705
Aug 4, 2026
Merged

fix(rtfcre): escape characters outside code page 1252 on export#1857
mkrnr merged 3 commits into
opensteno:mainfrom
Sanjays2402:fix/rtf-export-unicode-1705

Conversation

@Sanjays2402

Copy link
Copy Markdown
Contributor

Summary of changes

Saving a dictionary as RTF encodes the file as code page 1252, so any translation containing a character outside that code page (e.g. in phở, or a combining acute accent) raised UnicodeEncodeError and the export failed.

Characters that cp1252 cannot represent are now escaped with the RTF \uN control word using UTF-16 code units, so characters outside the BMP are written as a surrogate pair — the approach @sammdot described on the issue (surrogate pairs, positive numbers, wrapped in \uc0 so no ANSI fallback is expected). The parser learned \uN/\ucN to match, so RTF dictionaries still round-trip.

Closes #1705

Pull Request Checklist

  • Changes have tests
  • News fragment added in news.d. See documentation for details

Saving a dictionary as RTF encodes the file as code page 1252, so any
translation containing a character outside that code page raised
UnicodeEncodeError and the export failed.

The RTF spec encodes such characters with the \uN control word, using
UTF-16 code units, so characters outside the BMP become a surrogate
pair. Escape them on save, wrapped in a group setting \uc0, and handle
\uN (and \ucN) when parsing so RTF dictionaries still round-trip.

Tests cover formatting, saving and loading of BMP characters, surrogate
pairs, and the negative \uN values the spec allows.
Comment thread plover/dictionary/rtfcre_parse.py Outdated
Sanjays2402 and others added 2 commits July 30, 2026 16:27
\ucN sets how many fallback characters follow each \uN escape, and 1 is
the RTF default, so files written by other programs emit `\u7903 ?` and
the `?` was ending up in the translation. Track the count per group,
restore it on group end, and drop that many following characters
(control-word substitutions and plain text alike).

@mkrnr mkrnr left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this contribution and for implementing the suggestion!

@mkrnr
mkrnr merged commit d08aac1 into opensteno:main Aug 4, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RTF dictionary export fails with encoding error

2 participants