AB-PDF: Zeichen ohne Glyph werden ersetzt statt als Kästchen gedruckt
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ae6d84b2a4
commit
b097fedf5a
2 files changed
+76
No files matched your search
@@ -36,3 +36,43 @@ export function hatGlyph(codePoint) {
|
||||
const { regularFont, semiboldFont } = ladeSchriften()
|
||||
return regularFont.hasGlyphForCodePoint(codePoint) && semiboldFont.hasGlyphForCodePoint(codePoint)
|
||||
}
|
||||
|
||||
const ERSATZ = new Map([
|
||||
[0x2010, '-'], [0x2011, '-'], [0x2012, '-'], [0x2013, '-'], [0x2014, '-'], [0x2015, '-'], [0x2212, '-'],
|
||||
[0x2018, "'"], [0x2019, "'"], [0x201a, "'"], [0x2032, "'"],
|
||||
[0x201c, '"'], [0x201d, '"'], [0x201e, '"'], [0x201f, '"'], [0x2033, '"'],
|
||||
[0x2026, '...'], [0x20ac, 'EUR'], [0x2022, '-'], [0x00b7, '-'], [0x00d7, 'x'], [0x2192, '->'],
|
||||
])
|
||||
// Steuerzeichen (außer \n), weiche Trennung, Zero-Width-Zeichen, Variantenselektoren, BOM
|
||||
const ENTFERNEN = /[\u{0}-\u{8}\u{B}-\u{1F}\u{7F}-\u{9F}\u{AD}\u{200B}-\u{200D}\u{2060}\u{FE00}-\u{FE0F}\u{FEFF}]/gu
|
||||
|
||||
/** Ersetzt Zeichen ohne Glyph, damit nie ein leeres Kästchen im PDF steht. */
|
||||
export function bereinigeText(text, hatGlyphFn = hatGlyph) {
|
||||
const roh = String(text ?? '')
|
||||
.normalize('NFC')
|
||||
.replace(/\r\n?|[\u{2028}\u{2029}]/gu, '\n')
|
||||
.replace(/\t/g, ' ')
|
||||
.replace(ENTFERNEN, '')
|
||||
let aus = ''
|
||||
for (const zeichen of roh) {
|
||||
const cp = zeichen.codePointAt(0)
|
||||
if (zeichen === '\n' || hatGlyphFn(cp)) aus += zeichen
|
||||
else if (ERSATZ.has(cp)) aus += ERSATZ.get(cp)
|
||||
else if (/\p{Zs}/u.test(zeichen)) aus += ' '
|
||||
else if (/\p{M}/u.test(zeichen)) continue
|
||||
else {
|
||||
const basis = zeichen.normalize('NFD').codePointAt(0)
|
||||
aus += basis !== cp && hatGlyphFn(basis) ? String.fromCodePoint(basis) : '?'
|
||||
}
|
||||
}
|
||||
return aus
|
||||
}
|
||||
|
||||
/** bereinigeText für jede Zeichenkette in beliebig verschachtelten Objekten und Listen. */
|
||||
export function bereinigeTexte(wert, hatGlyphFn = hatGlyph) {
|
||||
if (typeof wert === 'string') return bereinigeText(wert, hatGlyphFn)
|
||||
if (Array.isArray(wert)) return wert.map((e) => bereinigeTexte(e, hatGlyphFn))
|
||||
if (wert && typeof wert === 'object') return Object.fromEntries(Object.entries(wert).map(([k, v]) => [k, bereinigeTexte(v, hatGlyphFn)]))
|
||||
return wert
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user