fix: keep the highlighter pen a docx run carries
Word's highlighter is w:highlight, a palette name; only w:shd's hex fill was read, so 121 yellow runs of a fixture imported unmarked. 'none' maps to the same 'auto' sentinel an empty w:shd gives, so it still cancels a style's pen.
This commit is contained in:
1 parent
361b14dc17
commit
993e64e933
2 files changed
+33
-1
No files matched your search
@@ -27,7 +27,7 @@ export type RunProps = {
|
||||
spacingTwip?: number; // w:spacing (character spacing, twentieths of a point)
|
||||
font?: string; // explicit w:rFonts w:ascii/hAnsi
|
||||
fontTheme?: 'minor' | 'major'; // w:rFonts w:asciiTheme/hAnsiTheme → theme1.xml font
|
||||
highlightFill?: string; // run-level w:shd w:fill (text highlight)
|
||||
highlightFill?: string; // text highlight: w:shd w:fill, or w:highlight's palette colour
|
||||
};
|
||||
|
||||
// A numbering level definition (numbering.xml w:lvl). bulletFont is the level's
|
||||
@@ -65,6 +65,15 @@ export function toggle(el: Element): boolean {
|
||||
return v == null || !(v === 'false' || v === '0' || v === 'off');
|
||||
}
|
||||
|
||||
// The highlighter pen's fixed palette (w:highlight names a colour where w:shd gives a
|
||||
// hex). 'none' maps to the same sentinel as an empty w:shd, so it cancels an inherited pen.
|
||||
const HIGHLIGHT_HEX: Record<string, string> = {
|
||||
black: '000000', blue: '0000FF', cyan: '00FFFF', darkBlue: '000080', darkCyan: '008080',
|
||||
darkGray: '808080', darkGreen: '008000', darkMagenta: '800080', darkRed: '800000',
|
||||
darkYellow: '808000', green: '00FF00', lightGray: 'C0C0C0', magenta: 'FF00FF',
|
||||
red: 'FF0000', white: 'FFFFFF', yellow: 'FFFF00', none: 'auto',
|
||||
};
|
||||
|
||||
// w:rPr element → RunProps (later layers override earlier; absent keys inherit).
|
||||
export function parseRunProps(rPr: Element | null | undefined): RunProps {
|
||||
const p: RunProps = {};
|
||||
@@ -93,6 +102,7 @@ export function parseRunProps(rPr: Element | null | undefined): RunProps {
|
||||
break;
|
||||
}
|
||||
case 'shd': { const f = child.getAttributeNS(W, 'fill'); if (f && f !== 'auto') p.highlightFill = f; break; }
|
||||
case 'highlight': { const c = HIGHLIGHT_HEX[wVal(child) ?? '']; if (c) p.highlightFill = c; break; }
|
||||
}
|
||||
}
|
||||
return p;
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
// Word's highlighter pen is w:highlight (a palette name), not the w:shd hex fill.
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import { parseRunProps, mergeRunProps, W } from '../../src/lib/import/docxStyles';
|
||||
|
||||
const rPr = (inner: string) =>
|
||||
new DOMParser().parseFromString(`<w:rPr xmlns:w="${W}">${inner}</w:rPr>`, 'application/xml').documentElement;
|
||||
|
||||
describe('parseRunProps highlight', () => {
|
||||
it('resolves a palette name to its hex', () => {
|
||||
expect(parseRunProps(rPr('<w:highlight w:val="yellow"/>')).highlightFill).toBe('FFFF00');
|
||||
});
|
||||
|
||||
it("lets a run's w:highlight none cancel the character style's pen", () => {
|
||||
const base = parseRunProps(rPr('<w:highlight w:val="green"/>'));
|
||||
const merged = mergeRunProps(base, parseRunProps(rPr('<w:highlight w:val="none"/>')));
|
||||
expect(merged.highlightFill).toBe('auto');
|
||||
});
|
||||
|
||||
it('ignores an unknown name rather than inventing a colour', () => {
|
||||
expect(parseRunProps(rPr('<w:highlight w:val="chartreuse"/>')).highlightFill).toBeUndefined();
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user