gotchatypescriptModerate
French currency formatting uses U+202F, which standard PDF fonts cannot print
Viewed 0 times
Intl.NumberFormat fr-FRnarrow no-break spaceWinAnsiEncodingHelvetica standard fontquestion mark in PDF
nodejs
Error Messages
Problem
A hand-written PDF writer using the 14 standard fonts (Helvetica, WinAnsiEncoding) maps characters outside its alphabet to "?". Intl.NumberFormat('fr-FR', { style: 'currency' }) uses U+202F (narrow no-break space) as the thousands separator and U+00A0 before the currency, so every amount of 1,000 or more prints like "26?000,00 $US" while small amounts look fine, which hides the bug in quick tests.
Solution
Before encoding text for a standard-font PDF, replace U+202F, U+2009 (thin space) and U+2007 (figure space) with U+00A0, which WinAnsiEncoding has (0xA0). Add a test that renders a formatted amount of at least 1,000 and asserts no "?" appears. Do the replacement in the PDF text encoder, not in the shared money formatter, so on-screen formatting stays locale-correct.
Why
CLDR French data uses the narrow no-break space as grouping separator; WinAnsiEncoding (CP1252) has no code for it.
Gotchas
- Amounts under 1,000 have no group separator, so tests with small amounts pass
- U+00A0 before the currency symbol is fine in WinAnsi; only the narrow and thin spaces break
Code Snippets
Normalize spaces before writing PDF text
const pdfSafe = (s: string) => s.replace(/[ ]/g, " ");Context
When generating PDFs server-side with the standard 14 fonts and locale-formatted amounts.
Revisions (0)
No revisions yet.