feat(rtff-pdb): RTF and PalmDOC plain-text support (v0.5.0)

rtf.js: a minimal single-pass RTF tokenizer extracting document text
with paragraph structure — groups, control words with signed params,
\\'hh Windows-1252 escapes, \\uN unicode with \\ucN fallback skipping,
known text destinations skipped whole (fonttbl/colortbl/stylesheet/
info/headers/pict/field/...), spec-required ignoring of unknown words.
Format runs are intentionally not converted; RTF is read as styled
text like .txt.

pdb.js: the TEXt/REAd PalmDOC container (PalmDOC, TealDoc) — the PDB
record reader and LZ77 decompressor are shared from mobi.js (both
exported; upstream already carried the TODO for this path). Records
decode as Windows-1252 and feed the plain-text pipeline (paragraph
split, line join, ~150KB sectioning, Part N TOC).

makeBook dispatch: content-based (TEXtREAd magic at offset 60;
'{\\rtf' magic), after MOBI and before the text branch.

Tests: node harness covering store + compressed PalmDOC, RTF paragraphs
/escapes/unicode/hex/destination-skipping, makeBook routing; txt/docx
regression suites pass.
This commit is contained in:
John O'Keefe committed 2026-10-03 14:49:22 -04:00
1 parent 50f56ee67f
commit ac699e71ee
5 files changed
+218 -4

No files matched your search

+3 -3
View File
@@ -180,7 +180,7 @@ const concatTypedArray3 = (a, b, c) => {
}
const decoder = new TextDecoder()
const getString = buffer => decoder.decode(buffer)
export const getString = buffer => decoder.decode(buffer)
const getUint = buffer => {
if (!buffer) return
const l = buffer.byteLength
@@ -226,7 +226,7 @@ const countUnsetEnd = x => {
return count
}
const decompressPalmDOC = array => {
export const decompressPalmDOC = array => {
let output = []
for (let i = 0; i < array.length; i++) {
const byte = array[i]
@@ -483,7 +483,7 @@ export const isMOBI = async file => {
return magic === 'BOOKMOBI'// || magic === 'TEXtREAd'
}
class PDB {
export class PDB {
#file
#offsets
pdb