postext 1.22.3 → 1.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/__tests__/bundle.test.js +1 -1
- package/dist/__tests__/codeBlocks.test.d.ts +2 -0
- package/dist/__tests__/codeBlocks.test.d.ts.map +1 -0
- package/dist/__tests__/codeBlocks.test.js +550 -0
- package/dist/__tests__/codeBlocks.test.js.map +1 -0
- package/dist/__tests__/exports.test.js +19 -0
- package/dist/__tests__/exports.test.js.map +1 -1
- package/dist/__tests__/hardBreaks.test.d.ts +2 -0
- package/dist/__tests__/hardBreaks.test.d.ts.map +1 -0
- package/dist/__tests__/hardBreaks.test.js +226 -0
- package/dist/__tests__/hardBreaks.test.js.map +1 -0
- package/dist/__tests__/headingInlineMarks.test.js +1 -1
- package/dist/__tests__/headingLetterSpacing.test.js +1 -1
- package/dist/__tests__/headingLetterSpacing.test.js.map +1 -1
- package/dist/__tests__/lineNumbers.test.d.ts +2 -0
- package/dist/__tests__/lineNumbers.test.d.ts.map +1 -0
- package/dist/__tests__/lineNumbers.test.js +304 -0
- package/dist/__tests__/lineNumbers.test.js.map +1 -0
- package/dist/__tests__/mathSizeMigration.test.js +2 -2
- package/dist/__tests__/paragraphDropCap.test.d.ts +2 -0
- package/dist/__tests__/paragraphDropCap.test.d.ts.map +1 -0
- package/dist/__tests__/paragraphDropCap.test.js +442 -0
- package/dist/__tests__/paragraphDropCap.test.js.map +1 -0
- package/dist/__tests__/paragraphStyleIndent.test.js +26 -2
- package/dist/__tests__/paragraphStyleIndent.test.js.map +1 -1
- package/dist/__tests__/pipeline/calloutInlineResourceGap.test.js +1 -1
- package/dist/__tests__/pipeline/calloutSplitMinLinesChild.test.js +1 -1
- package/dist/__tests__/pipeline/colonListRoom.test.js +1 -1
- package/dist/__tests__/pipeline/compoundBreaks.test.js +1 -1
- package/dist/__tests__/pipeline/dashBreaks.test.js +1 -1
- package/dist/__tests__/pipeline/headingSplitOrphans.test.js +1 -1
- package/dist/__tests__/pipeline/inlineFigureSpace.test.js +1 -1
- package/dist/__tests__/pipeline/paragraphContainerTail.test.js +1 -1
- package/dist/__tests__/pipeline/paragraphStyleFaces.test.js +7 -1
- package/dist/__tests__/pipeline/paragraphStyleFaces.test.js.map +1 -1
- package/dist/__tests__/pipeline/raggedOptimal.test.js +1 -1
- package/dist/__tests__/tabStops.test.d.ts +2 -0
- package/dist/__tests__/tabStops.test.d.ts.map +1 -0
- package/dist/__tests__/tabStops.test.js +394 -0
- package/dist/__tests__/tabStops.test.js.map +1 -0
- package/dist/__tests__/verseLines.test.d.ts +2 -0
- package/dist/__tests__/verseLines.test.d.ts.map +1 -0
- package/dist/__tests__/verseLines.test.js +375 -0
- package/dist/__tests__/verseLines.test.js.map +1 -0
- package/dist/bundle/configVersion.d.ts +77 -7
- package/dist/bundle/configVersion.d.ts.map +1 -1
- package/dist/bundle/configVersion.js +239 -5
- package/dist/bundle/configVersion.js.map +1 -1
- package/dist/bundle/index.d.ts +1 -1
- package/dist/bundle/index.d.ts.map +1 -1
- package/dist/bundle/index.js +1 -1
- package/dist/bundle/index.js.map +1 -1
- package/dist/canvas-backend/blockRender.d.ts.map +1 -1
- package/dist/canvas-backend/blockRender.js +39 -5
- package/dist/canvas-backend/blockRender.js.map +1 -1
- package/dist/canvas-backend/index.d.ts.map +1 -1
- package/dist/canvas-backend/index.js +3 -0
- package/dist/canvas-backend/index.js.map +1 -1
- package/dist/cjkMarks.js +1 -1
- package/dist/cjkMarks.js.map +1 -1
- package/dist/code/highlight.d.ts +34 -0
- package/dist/code/highlight.d.ts.map +1 -0
- package/dist/code/highlight.js +406 -0
- package/dist/code/highlight.js.map +1 -0
- package/dist/configWarnings.d.ts.map +1 -1
- package/dist/configWarnings.js +192 -3
- package/dist/configWarnings.js.map +1 -1
- package/dist/defaults/bodyText.d.ts.map +1 -1
- package/dist/defaults/bodyText.js +25 -0
- package/dist/defaults/bodyText.js.map +1 -1
- package/dist/defaults/calloutStyles.d.ts.map +1 -1
- package/dist/defaults/calloutStyles.js +7 -0
- package/dist/defaults/calloutStyles.js.map +1 -1
- package/dist/defaults/codeStyle.d.ts +29 -0
- package/dist/defaults/codeStyle.d.ts.map +1 -0
- package/dist/defaults/codeStyle.js +284 -0
- package/dist/defaults/codeStyle.js.map +1 -0
- package/dist/defaults/dropCap.d.ts +49 -0
- package/dist/defaults/dropCap.d.ts.map +1 -0
- package/dist/defaults/dropCap.js +66 -0
- package/dist/defaults/dropCap.js.map +1 -0
- package/dist/defaults/headings.d.ts +1 -1
- package/dist/defaults/headings.d.ts.map +1 -1
- package/dist/defaults/headings.js +11 -0
- package/dist/defaults/headings.js.map +1 -1
- package/dist/defaults/index.d.ts +3 -0
- package/dist/defaults/index.d.ts.map +1 -1
- package/dist/defaults/index.js +19 -0
- package/dist/defaults/index.js.map +1 -1
- package/dist/defaults/lineNumbers.d.ts +19 -0
- package/dist/defaults/lineNumbers.d.ts.map +1 -0
- package/dist/defaults/lineNumbers.js +101 -0
- package/dist/defaults/lineNumbers.js.map +1 -0
- package/dist/defaults/paragraphStyles.d.ts.map +1 -1
- package/dist/defaults/paragraphStyles.js +20 -0
- package/dist/defaults/paragraphStyles.js.map +1 -1
- package/dist/defaults/tabStops.d.ts +29 -0
- package/dist/defaults/tabStops.d.ts.map +1 -0
- package/dist/defaults/tabStops.js +94 -0
- package/dist/defaults/tabStops.js.map +1 -0
- package/dist/defaults/verse.d.ts +10 -0
- package/dist/defaults/verse.d.ts.map +1 -0
- package/dist/defaults/verse.js +52 -0
- package/dist/defaults/verse.js.map +1 -0
- package/dist/fonts/usage.d.ts +7 -0
- package/dist/fonts/usage.d.ts.map +1 -1
- package/dist/fonts/usage.js +71 -0
- package/dist/fonts/usage.js.map +1 -1
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +85 -11
- package/dist/html-backend.js.map +1 -1
- package/dist/index.d.ts +8 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -2
- package/dist/index.js.map +1 -1
- package/dist/measure/bidiLines.js +2 -2
- package/dist/measure/bidiLines.js.map +1 -1
- package/dist/measure/cache.js +2 -2
- package/dist/measure/cache.js.map +1 -1
- package/dist/measure/cjkCompose.d.ts.map +1 -1
- package/dist/measure/cjkCompose.js +5 -5
- package/dist/measure/cjkCompose.js.map +1 -1
- package/dist/measure/hardBreaks.d.ts +46 -0
- package/dist/measure/hardBreaks.d.ts.map +1 -0
- package/dist/measure/hardBreaks.js +216 -0
- package/dist/measure/hardBreaks.js.map +1 -0
- package/dist/measure/index.d.ts +1 -0
- package/dist/measure/index.d.ts.map +1 -1
- package/dist/measure/index.js +1 -0
- package/dist/measure/index.js.map +1 -1
- package/dist/measure/leader.d.ts +20 -0
- package/dist/measure/leader.d.ts.map +1 -0
- package/dist/measure/leader.js +46 -0
- package/dist/measure/leader.js.map +1 -0
- package/dist/measure/links.js +1 -1
- package/dist/measure/links.js.map +1 -1
- package/dist/measure/plain.d.ts.map +1 -1
- package/dist/measure/plain.js +18 -25
- package/dist/measure/plain.js.map +1 -1
- package/dist/measure/rich.d.ts +19 -0
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +211 -38
- package/dist/measure/rich.js.map +1 -1
- package/dist/measure/tabs.d.ts +103 -0
- package/dist/measure/tabs.d.ts.map +1 -0
- package/dist/measure/tabs.js +123 -0
- package/dist/measure/tabs.js.map +1 -0
- package/dist/measure/types.d.ts +26 -2
- package/dist/measure/types.d.ts.map +1 -1
- package/dist/measure/types.js +23 -3
- package/dist/measure/types.js.map +1 -1
- package/dist/parse/blockParser.d.ts +13 -6
- package/dist/parse/blockParser.d.ts.map +1 -1
- package/dist/parse/blockParser.js +457 -87
- package/dist/parse/blockParser.js.map +1 -1
- package/dist/parse/codeFence.d.ts +18 -0
- package/dist/parse/codeFence.d.ts.map +1 -0
- package/dist/parse/codeFence.js +52 -0
- package/dist/parse/codeFence.js.map +1 -0
- package/dist/parse/index.d.ts +1 -1
- package/dist/parse/index.d.ts.map +1 -1
- package/dist/parse/index.js.map +1 -1
- package/dist/parse/indexMarks.d.ts +3 -1
- package/dist/parse/indexMarks.d.ts.map +1 -1
- package/dist/parse/indexMarks.js +22 -2
- package/dist/parse/indexMarks.js.map +1 -1
- package/dist/parse/inlineFormatting.d.ts +50 -0
- package/dist/parse/inlineFormatting.d.ts.map +1 -1
- package/dist/parse/inlineFormatting.js +94 -0
- package/dist/parse/inlineFormatting.js.map +1 -1
- package/dist/parse/sourceMapping.d.ts.map +1 -1
- package/dist/parse/sourceMapping.js +65 -1
- package/dist/parse/sourceMapping.js.map +1 -1
- package/dist/parse/types.d.ts +144 -9
- package/dist/parse/types.d.ts.map +1 -1
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +143 -18
- package/dist/pipeline/build.js.map +1 -1
- package/dist/pipeline/buildBlockKind.d.ts.map +1 -1
- package/dist/pipeline/buildBlockKind.js +60 -1
- package/dist/pipeline/buildBlockKind.js.map +1 -1
- package/dist/pipeline/buildHelpers.d.ts +3 -0
- package/dist/pipeline/buildHelpers.d.ts.map +1 -1
- package/dist/pipeline/buildHelpers.js +7 -2
- package/dist/pipeline/buildHelpers.js.map +1 -1
- package/dist/pipeline/calloutLayout.d.ts.map +1 -1
- package/dist/pipeline/calloutLayout.js +33 -2
- package/dist/pipeline/calloutLayout.js.map +1 -1
- package/dist/pipeline/chips.d.ts.map +1 -1
- package/dist/pipeline/chips.js +4 -0
- package/dist/pipeline/chips.js.map +1 -1
- package/dist/pipeline/codeBlocks.d.ts +38 -0
- package/dist/pipeline/codeBlocks.d.ts.map +1 -0
- package/dist/pipeline/codeBlocks.js +146 -0
- package/dist/pipeline/codeBlocks.js.map +1 -0
- package/dist/pipeline/codeInline.d.ts +22 -0
- package/dist/pipeline/codeInline.d.ts.map +1 -0
- package/dist/pipeline/codeInline.js +93 -0
- package/dist/pipeline/codeInline.js.map +1 -0
- package/dist/pipeline/codeLines.d.ts +91 -0
- package/dist/pipeline/codeLines.d.ts.map +1 -0
- package/dist/pipeline/codeLines.js +399 -0
- package/dist/pipeline/codeLines.js.map +1 -0
- package/dist/pipeline/config.d.ts.map +1 -1
- package/dist/pipeline/config.js +8 -1
- package/dist/pipeline/config.js.map +1 -1
- package/dist/pipeline/contentWarnings.d.ts +9 -0
- package/dist/pipeline/contentWarnings.d.ts.map +1 -1
- package/dist/pipeline/contentWarnings.js +60 -2
- package/dist/pipeline/contentWarnings.js.map +1 -1
- package/dist/pipeline/continuation.d.ts.map +1 -1
- package/dist/pipeline/continuation.js +9 -2
- package/dist/pipeline/continuation.js.map +1 -1
- package/dist/pipeline/dropCap.d.ts +128 -0
- package/dist/pipeline/dropCap.d.ts.map +1 -0
- package/dist/pipeline/dropCap.js +412 -0
- package/dist/pipeline/dropCap.js.map +1 -0
- package/dist/pipeline/hardBreaks.d.ts +19 -0
- package/dist/pipeline/hardBreaks.d.ts.map +1 -0
- package/dist/pipeline/hardBreaks.js +36 -0
- package/dist/pipeline/hardBreaks.js.map +1 -0
- package/dist/pipeline/headerFooter.d.ts.map +1 -1
- package/dist/pipeline/headerFooter.js +4 -1
- package/dist/pipeline/headerFooter.js.map +1 -1
- package/dist/pipeline/lineNumbers.d.ts +37 -0
- package/dist/pipeline/lineNumbers.d.ts.map +1 -0
- package/dist/pipeline/lineNumbers.js +441 -0
- package/dist/pipeline/lineNumbers.js.map +1 -0
- package/dist/pipeline/measureContentBlock.d.ts +31 -5
- package/dist/pipeline/measureContentBlock.d.ts.map +1 -1
- package/dist/pipeline/measureContentBlock.js +274 -68
- package/dist/pipeline/measureContentBlock.js.map +1 -1
- package/dist/pipeline/partPalette.d.ts +1 -1
- package/dist/pipeline/partPalette.d.ts.map +1 -1
- package/dist/pipeline/partPalette.js +24 -2
- package/dist/pipeline/partPalette.js.map +1 -1
- package/dist/pipeline/styles.d.ts +18 -2
- package/dist/pipeline/styles.d.ts.map +1 -1
- package/dist/pipeline/styles.js +15 -3
- package/dist/pipeline/styles.js.map +1 -1
- package/dist/pipeline/tabs.d.ts +35 -0
- package/dist/pipeline/tabs.d.ts.map +1 -0
- package/dist/pipeline/tabs.js +99 -0
- package/dist/pipeline/tabs.js.map +1 -0
- package/dist/pipeline/toc.d.ts.map +1 -1
- package/dist/pipeline/toc.js +3 -38
- package/dist/pipeline/toc.js.map +1 -1
- package/dist/pipeline/verseLines.d.ts +78 -0
- package/dist/pipeline/verseLines.d.ts.map +1 -0
- package/dist/pipeline/verseLines.js +245 -0
- package/dist/pipeline/verseLines.js.map +1 -0
- package/dist/preflight.d.ts.map +1 -1
- package/dist/preflight.js +1 -0
- package/dist/preflight.js.map +1 -1
- package/dist/types.d.ts +560 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/vdt.d.ts +240 -7
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js +6 -0
- package/dist/vdt.js.map +1 -1
- package/dist/word/docxRead.d.ts.map +1 -1
- package/dist/word/docxRead.js +15 -0
- package/dist/word/docxRead.js.map +1 -1
- package/dist/word/inline.d.ts +6 -1
- package/dist/word/inline.d.ts.map +1 -1
- package/dist/word/inline.js +35 -1
- package/dist/word/inline.js.map +1 -1
- package/dist/word/model.d.ts +14 -0
- package/dist/word/model.d.ts.map +1 -1
- package/dist/word/model.js.map +1 -1
- package/dist/word/template.d.ts +12 -3
- package/dist/word/template.d.ts.map +1 -1
- package/dist/word/template.js +13 -3
- package/dist/word/template.js.map +1 -1
- package/dist/word/toDocx.d.ts.map +1 -1
- package/dist/word/toDocx.js +52 -8
- package/dist/word/toDocx.js.map +1 -1
- package/dist/word/toMarkdown.d.ts +5 -1
- package/dist/word/toMarkdown.d.ts.map +1 -1
- package/dist/word/toMarkdown.js +117 -6
- package/dist/word/toMarkdown.js.map +1 -1
- package/dist/word/word.test.js +124 -2
- package/dist/word/word.test.js.map +1 -1
- package/dist/worker/fonts.d.ts +2 -1
- package/dist/worker/fonts.d.ts.map +1 -1
- package/dist/worker/fonts.js +6 -2
- package/dist/worker/fonts.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rich.d.ts","sourceRoot":"","sources":["../../src/measure/rich.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rich.d.ts","sourceRoot":"","sources":["../../src/measure/rich.ts"],"names":[],"mappings":"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"}
|
package/dist/measure/rich.js
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
import { FORCED_BREAK, measureForcedBreaks } from './hardBreaks';
|
|
2
|
+
import { placeTab } from './tabs';
|
|
1
3
|
import { uprightArabicSpans, uprightFace } from '../uprightArabic';
|
|
2
4
|
import { createBoundingBox } from '../vdt';
|
|
3
5
|
import { hyphenateText, withoutSlashJoints } from '../hyphenate';
|
|
4
6
|
import { richTokensToItems, computeBreakpoints, reconstructRichLines, } from '../knuthPlass';
|
|
5
7
|
import { SOFT_HYPHEN } from './types';
|
|
6
|
-
import { lineMeasure, uniformMeasureFrom } from './types';
|
|
8
|
+
import { lineIndentAt, lineMeasure, uniformMeasureFrom } from './types';
|
|
7
9
|
import { cleanSoftHyphens, measureTextWidth, normalSpaceWidthFor } from './canvas';
|
|
8
10
|
import { isRuntLastLine } from './runts';
|
|
9
11
|
import { computeJustifiedSpaceRatio, hasOverfullLine } from './plain';
|
|
@@ -188,7 +190,9 @@ export function expandSmallCaps(lines, normalFont, boldFont, italicFont, boldIta
|
|
|
188
190
|
const segs = line.segments;
|
|
189
191
|
if (!segs || !segs.some((s) => s.smallCaps))
|
|
190
192
|
continue;
|
|
191
|
-
|
|
193
|
+
// A leader (#622) is no text of the line.
|
|
194
|
+
const spelled = (list) => list.filter((s) => !s.leader).map((s) => s.text).join('');
|
|
195
|
+
const before = spelled(segs);
|
|
192
196
|
const out = [];
|
|
193
197
|
for (const seg of segs) {
|
|
194
198
|
if (!seg.smallCaps) {
|
|
@@ -225,7 +229,7 @@ export function expandSmallCaps(lines, normalFont, boldFont, italicFont, boldIta
|
|
|
225
229
|
}
|
|
226
230
|
line.segments = out;
|
|
227
231
|
if (line.text === before)
|
|
228
|
-
line.text = out
|
|
232
|
+
line.text = spelled(out);
|
|
229
233
|
}
|
|
230
234
|
}
|
|
231
235
|
/** The text band of a chip box around the baseline, as fractions of the
|
|
@@ -353,7 +357,8 @@ const TRAILING_NO_BREAK_RE = new RegExp(`[${NO_BREAK_SPACES}]+$`);
|
|
|
353
357
|
function applyChipGaps(tokens, noBreakWidth) {
|
|
354
358
|
for (let i = 0; i < tokens.length; i++) {
|
|
355
359
|
const space = tokens[i];
|
|
356
|
-
|
|
360
|
+
// A tab makes its own room (#622).
|
|
361
|
+
if (space.kind !== 'space' || space.tab)
|
|
357
362
|
continue;
|
|
358
363
|
const left = tokens[i - 1]?.chip ? tokens[i - 1] : undefined;
|
|
359
364
|
const right = tokens[i + 1]?.chip ? tokens[i + 1] : undefined;
|
|
@@ -894,7 +899,7 @@ export function tokenSegment(t) {
|
|
|
894
899
|
...(t.refResourceId !== undefined ? { refResourceId: t.refResourceId, ...(t.refAnchor ? { refAnchor: true } : {}), ...(t.refPageIndex !== undefined ? { refPageIndex: t.refPageIndex } : {}) } : {}),
|
|
895
900
|
...(t.footnoteId !== undefined ? { footnoteId: t.footnoteId } : {}),
|
|
896
901
|
...(t.captionLabel ? { captionLabel: true } : {}),
|
|
897
|
-
...(t.labelTab ? { labelTab: true } : {}),
|
|
902
|
+
...(t.labelTab || t.tab ? { labelTab: true } : {}),
|
|
898
903
|
...(t.script ? { script: t.script, fontString: t.scriptFont, baselineShift: t.baselineShift } : {}),
|
|
899
904
|
...(t.markerFont && !t.script ? { fontString: t.markerFont } : {}),
|
|
900
905
|
...(t.sideRuns ? { sideMarker: { runs: t.sideRuns } } : {}),
|
|
@@ -979,6 +984,16 @@ bidi) {
|
|
|
979
984
|
for (const span of spans) {
|
|
980
985
|
const spanBase = spanStart;
|
|
981
986
|
spanStart += span.text.length;
|
|
987
|
+
// A tab (#622): its width is set where its line gets to it.
|
|
988
|
+
// Tab characters in a row are one character of the text that goes on
|
|
989
|
+
// that many stops: the later ones have no text.
|
|
990
|
+
if (span.tab) {
|
|
991
|
+
const tab = span.tab.px ? { stop: span.tab.px } : {};
|
|
992
|
+
for (let k = 0; k < Math.max(1, span.tab.count ?? 1); k++) {
|
|
993
|
+
tokens.push({ text: k === 0 ? span.text : '', bold: span.bold, italic: span.italic, kind: 'space', width: 0, tab });
|
|
994
|
+
}
|
|
995
|
+
continue;
|
|
996
|
+
}
|
|
982
997
|
const atomic = atomicSpanToken(span, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx);
|
|
983
998
|
if (atomic) {
|
|
984
999
|
tokens.push(atomic);
|
|
@@ -1387,6 +1402,15 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1387
1402
|
const opts = options;
|
|
1388
1403
|
return withMeasureWritingMode(opts.writingMode, () => measureRichText(spans, plainText, normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, opts));
|
|
1389
1404
|
}
|
|
1405
|
+
// Forced line breaks (#620): the text between two of them is broken on
|
|
1406
|
+
// its own, by whichever breaker sets it, and the pieces stacked
|
|
1407
|
+
// (`measure/hardBreaks.ts`).
|
|
1408
|
+
if (plainText.includes(FORCED_BREAK)) {
|
|
1409
|
+
return measureForcedBreaks(spans, maxWidthPx, lineHeightPx, options, (piece, opts) => measureRichText(piece, piece.map((s) => s.text).join(''), normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, opts));
|
|
1410
|
+
}
|
|
1411
|
+
// Tabs (#622) are word spaces in vertical text.
|
|
1412
|
+
if (measuringVertically() && spans.some((sp) => sp.tab))
|
|
1413
|
+
spans = tabsAsSpaces(spans);
|
|
1390
1414
|
// Vertical text: a short number inside a Latin sentence runs sideways
|
|
1391
1415
|
// with it, read against the whole paragraph (#222).
|
|
1392
1416
|
if (measuringVertically())
|
|
@@ -1402,13 +1426,18 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1402
1426
|
// #195, #430), which the composer alone lays out.
|
|
1403
1427
|
// The paragraph is looked at for CJK text once (`cjkText`); a Latin one
|
|
1404
1428
|
// then never looks into its words.
|
|
1429
|
+
// A paragraph with a tab (#622) is set by the line breaker below, which
|
|
1430
|
+
// breaks Chinese and Japanese words between their characters under the
|
|
1431
|
+
// document's rules; one with ruby, a warichu note or kanbun marks keeps
|
|
1432
|
+
// the composer, its tabs set as word spaces.
|
|
1405
1433
|
const cjkText = hasCJK(plainText);
|
|
1406
|
-
|
|
1407
|
-
|
|
1434
|
+
const annotated = spans.some((s) => s.ruby || s.warichu || s.kunten);
|
|
1435
|
+
const hasTabs = spans.some((s) => s.tab);
|
|
1436
|
+
if ((cjkText && composesAsCjk(plainText) && !hasTabs) || annotated) {
|
|
1437
|
+
return composeCjkParagraph(hasTabs ? tabsAsSpaces(spans) : spans, normalFont, boldFont, italicFont, boldItalicFont, maxWidthPx, lineHeightPx, options);
|
|
1408
1438
|
}
|
|
1409
1439
|
const shouldHyphenate = options?.hyphenate ?? false;
|
|
1410
|
-
const
|
|
1411
|
-
const hanging = options?.hangingIndent ?? false;
|
|
1440
|
+
const indentOf = (li) => lineIndentAt(options, li);
|
|
1412
1441
|
const textAlign = options?.textAlign ?? 'left';
|
|
1413
1442
|
const letterSpacingPx = options?.letterSpacingPx ?? 0;
|
|
1414
1443
|
const hyphenationZonePx = shouldHyphenate ? options?.hyphenationZonePx : undefined;
|
|
@@ -1436,8 +1465,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1436
1465
|
if (!kashida)
|
|
1437
1466
|
return;
|
|
1438
1467
|
justifyLinesWithKashida(lines, (li) => {
|
|
1439
|
-
|
|
1440
|
-
return lineMeasure(maxWidthPx, options?.restWidths, li) - indent;
|
|
1468
|
+
return lineMeasure(maxWidthPx, options?.restWidths, li) - indentOf(li);
|
|
1441
1469
|
}, normalSpaceWidth, kashida, (seg, text) => textWidth(text, fontOf(seg), false));
|
|
1442
1470
|
};
|
|
1443
1471
|
// Knuth-Plass optimal line breaking path. A Latin paragraph quoting CJK
|
|
@@ -1446,25 +1474,16 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1446
1474
|
// it too with `optimalRagged`: its word spaces keep their width and each
|
|
1447
1475
|
// line gets the ragged stretch instead.
|
|
1448
1476
|
const ragged = textAlign !== 'justify';
|
|
1449
|
-
|
|
1477
|
+
// A paragraph that holds a tab is set line by line (#622): a tab's width
|
|
1478
|
+
// depends on where its line starts.
|
|
1479
|
+
if (options?.optimal && (!ragged || options.optimalRagged) && !hasTabs) {
|
|
1450
1480
|
const maxStretchRatio = ragged ? 1 : options.maxStretchRatio ?? 1.5;
|
|
1451
1481
|
const minShrinkRatio = ragged ? 1 : options.minShrinkRatio ?? 0.8;
|
|
1452
1482
|
// The runt threshold counts word spaces on ragged text too.
|
|
1453
1483
|
const spaceWidth = ragged ? normalSpaceWidthFor(normalFont) + letterSpacingPx : normalSpaceWidth;
|
|
1454
1484
|
const items = richTokensToItems(tokens, spaceWidth, maxStretchRatio, minShrinkRatio, repeatHyphen);
|
|
1455
|
-
const lineWidthFn = (li) =>
|
|
1456
|
-
|
|
1457
|
-
const indent = indentPx > 0
|
|
1458
|
-
? (hanging ? (isFirst ? 0 : indentPx) : (isFirst ? indentPx : 0))
|
|
1459
|
-
: 0;
|
|
1460
|
-
return lineMeasure(maxWidthPx, options.restWidths, li) - indent;
|
|
1461
|
-
};
|
|
1462
|
-
const lineIndentFn = (li) => {
|
|
1463
|
-
const isFirst = li === 0;
|
|
1464
|
-
return indentPx > 0
|
|
1465
|
-
? (hanging ? (isFirst ? 0 : indentPx) : (isFirst ? indentPx : 0))
|
|
1466
|
-
: 0;
|
|
1467
|
-
};
|
|
1485
|
+
const lineWidthFn = (li) => lineMeasure(maxWidthPx, options.restWidths, li) - indentOf(li);
|
|
1486
|
+
const lineIndentFn = indentOf;
|
|
1468
1487
|
const runtPenalty = options.runtPenalty ?? 0;
|
|
1469
1488
|
const runtMinWidth = runtPenalty > 0
|
|
1470
1489
|
? (options.runtMinCharacters ?? 0) * spaceWidth
|
|
@@ -1481,7 +1500,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1481
1500
|
...(options.avoidHyphenAtLines ? { avoidHyphenAtLines: options.avoidHyphenAtLines } : {}),
|
|
1482
1501
|
...(options.keepBreaks?.path === 'rich' ? { fixedBreaks: options.keepBreaks.at } : {}),
|
|
1483
1502
|
looseness: options.looseness ?? 0,
|
|
1484
|
-
lineWidthUniformFrom: uniformMeasureFrom(options.restWidths),
|
|
1503
|
+
lineWidthUniformFrom: uniformMeasureFrom(options.restWidths, options.lineIndentsPx),
|
|
1485
1504
|
trackingPerChar,
|
|
1486
1505
|
...(ragged ? { raggedStretch: raggedStretchPx(normalFont) } : {}),
|
|
1487
1506
|
...(ragged && hyphenationZonePx !== undefined ? { hyphenationZone: hyphenationZonePx } : {}),
|
|
@@ -1517,11 +1536,14 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1517
1536
|
// The line before broke after a compound's hyphen, which this one repeats
|
|
1518
1537
|
// (`repeatHyphen`).
|
|
1519
1538
|
let repeatPending = false;
|
|
1539
|
+
// Tabs (#622): a leader is measured in the paragraph's face, tracked as
|
|
1540
|
+
// its words are; a tab past the last stop is a word space.
|
|
1541
|
+
const leaderWidth = (text) => measureTextWidth(text, normalFont) + (letterSpacingPx === 0 ? 0 : letterSpacingPx * graphemeCount(text));
|
|
1542
|
+
const tabSpaceWidth = hasTabs ? normalSpaceWidthFor(normalFont) + letterSpacingPx : 0;
|
|
1543
|
+
// A word space a line may start or end at (a tab is none).
|
|
1544
|
+
const isBreakSpace = (t) => t.kind === 'space' && !t.tab;
|
|
1520
1545
|
while (tokenIdx < tokens.length) {
|
|
1521
|
-
const
|
|
1522
|
-
const lineIndent = indentPx > 0
|
|
1523
|
-
? (hanging ? (isFirstLine ? 0 : indentPx) : (isFirstLine ? indentPx : 0))
|
|
1524
|
-
: 0;
|
|
1546
|
+
const lineIndent = indentOf(lineIndex);
|
|
1525
1547
|
const lineMaxWidth = lineMeasure(maxWidthPx, options?.restWidths, lineIndex) - lineIndent;
|
|
1526
1548
|
const lineTokens = [];
|
|
1527
1549
|
let lineWidth = 0;
|
|
@@ -1531,8 +1553,10 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1531
1553
|
let lineHardHyphen = false;
|
|
1532
1554
|
// A word of a joining script wider than the line runs past it.
|
|
1533
1555
|
let lineWordOverflow = false;
|
|
1556
|
+
// The line holds a tab placed at a stop (#622).
|
|
1557
|
+
let lineTabbed = false;
|
|
1534
1558
|
// Consume leading spaces at line start (skip them)
|
|
1535
|
-
while (tokenIdx < tokens.length && tokens[tokenIdx]
|
|
1559
|
+
while (tokenIdx < tokens.length && isBreakSpace(tokens[tokenIdx])) {
|
|
1536
1560
|
tokenIdx++;
|
|
1537
1561
|
}
|
|
1538
1562
|
// The compound's hyphen, repeated: the tail it broke from opens the
|
|
@@ -1545,10 +1569,63 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1545
1569
|
repeatPending = false;
|
|
1546
1570
|
// This line ends after a compound's hyphen the next one repeats.
|
|
1547
1571
|
let lineRepeatNext = false;
|
|
1572
|
+
// Tabs (#622): the stop the line's last tab took, and that tab's place
|
|
1573
|
+
// among the line's tokens.
|
|
1574
|
+
let tabUsedPos = -Infinity;
|
|
1575
|
+
let lastTabAt = -1;
|
|
1548
1576
|
// Greedy: add tokens until we overflow
|
|
1549
1577
|
while (tokenIdx < tokens.length) {
|
|
1550
|
-
|
|
1551
|
-
if (
|
|
1578
|
+
let token = tokens[tokenIdx];
|
|
1579
|
+
if (token.tab) {
|
|
1580
|
+
const x = lineIndent + lineWidth;
|
|
1581
|
+
const placement = placeTab(x, tabRun(tokens, tokenIdx, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx), { start: lineIndent, end: lineIndent + lineMaxWidth, measure: maxWidthPx, usedPos: tabUsedPos }, options?.tabs, token.tab.stop, leaderWidth);
|
|
1582
|
+
if (placement.kind === 'stop' || (placement.kind === 'overrun' && !lineTokens.some((t) => t.kind !== 'space'))) {
|
|
1583
|
+
// At its stop; or opening its line with no stop the text after
|
|
1584
|
+
// it fits: it takes no room.
|
|
1585
|
+
const width = placement.kind === 'stop' ? placement.width : 0;
|
|
1586
|
+
lineTokens.push({
|
|
1587
|
+
...token,
|
|
1588
|
+
width,
|
|
1589
|
+
tabPlaced: placement.kind === 'stop' ? { align: placement.align, at: placement.pos } : { align: 'start', at: x },
|
|
1590
|
+
...(placement.kind === 'stop' && placement.leader ? { tabLeader: placement.leader } : {}),
|
|
1591
|
+
});
|
|
1592
|
+
lineWidth += width;
|
|
1593
|
+
tokenIdx++;
|
|
1594
|
+
if (placement.kind === 'stop')
|
|
1595
|
+
tabUsedPos = placement.pos;
|
|
1596
|
+
lastTabAt = lineTokens.length - 1;
|
|
1597
|
+
lineTabbed = true;
|
|
1598
|
+
continue;
|
|
1599
|
+
}
|
|
1600
|
+
if (placement.kind === 'overrun') {
|
|
1601
|
+
// An end, centre or decimal stop the text before it has passed
|
|
1602
|
+
// takes that text's last word down with it; a start stop breaks
|
|
1603
|
+
// the line before the tab.
|
|
1604
|
+
if (placement.align !== 'start') {
|
|
1605
|
+
let k = lineTokens.length - 1;
|
|
1606
|
+
while (k > lastTabAt + 1 && !(lineTokens[k].kind === 'space' && !lineTokens[k].tab))
|
|
1607
|
+
k--;
|
|
1608
|
+
if (k > lastTabAt + 1 && lineTokens.slice(lastTabAt + 1, k).some((t) => t.kind !== 'space')) {
|
|
1609
|
+
tokenIdx -= lineTokens.length - k;
|
|
1610
|
+
while (lineTokens.length > k)
|
|
1611
|
+
lineWidth -= lineTokens.pop().width;
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
break;
|
|
1615
|
+
}
|
|
1616
|
+
// Past the last stop with no default stops: a word space, none at
|
|
1617
|
+
// the line's start.
|
|
1618
|
+
if (!lineTokens.some((t) => t.kind !== 'space')) {
|
|
1619
|
+
tokenIdx++;
|
|
1620
|
+
continue;
|
|
1621
|
+
}
|
|
1622
|
+
const { tab: _tab, ...space } = token;
|
|
1623
|
+
void _tab;
|
|
1624
|
+
token = { ...space, width: tabSpaceWidth, labelTab: 'gap' };
|
|
1625
|
+
}
|
|
1626
|
+
// The text a tab sent to its stop fits as measured: rounding in the
|
|
1627
|
+
// sums is no overflow (#622).
|
|
1628
|
+
if (lineWidth + token.width <= lineMaxWidth + (lineTabbed ? 0.01 : 0)) {
|
|
1552
1629
|
lineTokens.push(token);
|
|
1553
1630
|
lineWidth += token.width;
|
|
1554
1631
|
tokenIdx++;
|
|
@@ -1715,23 +1792,27 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1715
1792
|
break;
|
|
1716
1793
|
syllableRun = lineSyllable ? syllableRun + 1 : 0;
|
|
1717
1794
|
repeatPending = lineRepeatNext;
|
|
1718
|
-
// Trim trailing spaces from line tokens
|
|
1719
|
-
|
|
1795
|
+
// Trim trailing spaces from line tokens (a tab stays: a rule to the
|
|
1796
|
+
// line's end is a form's blank)
|
|
1797
|
+
while (lineTokens.length > 0 && isBreakSpace(lineTokens[lineTokens.length - 1])) {
|
|
1720
1798
|
lineWidth -= lineTokens[lineTokens.length - 1].width;
|
|
1721
1799
|
lineTokens.pop();
|
|
1722
1800
|
}
|
|
1723
1801
|
// Check if this is the last line
|
|
1724
1802
|
// Skip remaining leading spaces to check if there's more content
|
|
1725
1803
|
let peekIdx = tokenIdx;
|
|
1726
|
-
while (peekIdx < tokens.length && tokens[peekIdx]
|
|
1804
|
+
while (peekIdx < tokens.length && isBreakSpace(tokens[peekIdx])) {
|
|
1727
1805
|
peekIdx++;
|
|
1728
1806
|
}
|
|
1729
1807
|
const isLastLine = peekIdx >= tokens.length;
|
|
1730
1808
|
// Build segments for justified rendering
|
|
1731
|
-
|
|
1809
|
+
let segments = trimChipLineEdges(lineTokens.map(tokenSegment));
|
|
1810
|
+
if (lineTabbed)
|
|
1811
|
+
segments = setTabbedLine(segments, lineTokens, lineMaxWidth, textAlign, isLastLine);
|
|
1732
1812
|
const lineText = lineTokens.map((t) => cleanSoftHyphens(t.text)).join('');
|
|
1733
1813
|
const contentWidth = segments.reduce((sum, t) => sum + t.width, 0);
|
|
1734
|
-
|
|
1814
|
+
// A tabbed line is set as measured: its widths are final.
|
|
1815
|
+
const justifiedSpaceRatio = lineTabbed ? undefined : computeJustifiedSpaceRatio(segments, lineMaxWidth, normalSpaceWidth, textAlign, isLastLine);
|
|
1735
1816
|
lines.push({
|
|
1736
1817
|
text: lineText,
|
|
1737
1818
|
bbox: createBoundingBox(lineIndent, y, contentWidth, lineHeightPx),
|
|
@@ -1743,6 +1824,7 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1743
1824
|
isLastLine,
|
|
1744
1825
|
...(justifiedSpaceRatio !== undefined ? { justifiedSpaceRatio } : {}),
|
|
1745
1826
|
...(lineWordOverflow ? { wordOverflow: true } : {}),
|
|
1827
|
+
...(lineTabbed ? { tabbed: true, ...(textAlign === 'justify' ? { ragged: true } : {}) } : {}),
|
|
1746
1828
|
});
|
|
1747
1829
|
y += lineHeightPx;
|
|
1748
1830
|
lineIndex++;
|
|
@@ -1756,6 +1838,97 @@ function measureRichText(spans, plainText, normalFont, boldFont, italicFont, bol
|
|
|
1756
1838
|
withKashida(lines);
|
|
1757
1839
|
return { lines, totalHeight: y };
|
|
1758
1840
|
}
|
|
1841
|
+
/** The text a tab at `at` sends to its stop (#622): the tokens after it up
|
|
1842
|
+
* to the next tab or the paragraph's end, spaces at either end left out. */
|
|
1843
|
+
function tabRun(tokens, at, normalFont, boldFont, italicFont, boldItalicFont, letterSpacingPx) {
|
|
1844
|
+
let from = at + 1;
|
|
1845
|
+
while (from < tokens.length && tokens[from].kind === 'space' && !tokens[from].tab)
|
|
1846
|
+
from++;
|
|
1847
|
+
let to = from;
|
|
1848
|
+
while (to < tokens.length && !tokens[to].tab)
|
|
1849
|
+
to++;
|
|
1850
|
+
while (to > from && tokens[to - 1].kind === 'space')
|
|
1851
|
+
to--;
|
|
1852
|
+
let width = 0;
|
|
1853
|
+
for (let k = from; k < to; k++)
|
|
1854
|
+
width += tokens[k].width;
|
|
1855
|
+
return {
|
|
1856
|
+
width,
|
|
1857
|
+
decimalWidth: (char) => {
|
|
1858
|
+
if (char.length === 0)
|
|
1859
|
+
return undefined;
|
|
1860
|
+
let before = 0;
|
|
1861
|
+
for (let k = from; k < to; k++) {
|
|
1862
|
+
const t = tokens[k];
|
|
1863
|
+
const idx = t.kind === 'text' && !t.mathRender && !t.chip && !t.swatch ? t.text.indexOf(char) : -1;
|
|
1864
|
+
if (idx >= 0) {
|
|
1865
|
+
const head = cleanSoftHyphens(t.text.slice(0, idx));
|
|
1866
|
+
const font = tokenFont(t, normalFont, boldFont, italicFont, boldItalicFont);
|
|
1867
|
+
return before + textWidth(head, font, t.smallCaps) + (letterSpacingPx === 0 ? 0 : wordLetterSpacing(head, letterSpacingPx) * graphemeCount(head));
|
|
1868
|
+
}
|
|
1869
|
+
before += t.width;
|
|
1870
|
+
}
|
|
1871
|
+
return undefined;
|
|
1872
|
+
},
|
|
1873
|
+
};
|
|
1874
|
+
}
|
|
1875
|
+
/**
|
|
1876
|
+
* The segments of a line holding a tab at its stop (#622): each tab with a
|
|
1877
|
+
* leader becomes the tab's space up to the leader, the leader (`leader`,
|
|
1878
|
+
* no character of the text) and the gap after it (an empty space). In a
|
|
1879
|
+
* justified paragraph the word spaces after the line's last tab take the
|
|
1880
|
+
* slack, the line not being the paragraph's last (the renderers set the
|
|
1881
|
+
* line as it is: it is `ragged`); in a centred or right-aligned one an empty
|
|
1882
|
+
* space fills the line to its measure, so it is set from its start side as
|
|
1883
|
+
* its stops are.
|
|
1884
|
+
*/
|
|
1885
|
+
function setTabbedLine(segments, lineTokens, lineMaxWidth, textAlign, isLastLine) {
|
|
1886
|
+
const out = [];
|
|
1887
|
+
let lastTab = -1;
|
|
1888
|
+
segments.forEach((seg, i) => {
|
|
1889
|
+
const token = lineTokens[i];
|
|
1890
|
+
if (token?.tab)
|
|
1891
|
+
lastTab = out.length;
|
|
1892
|
+
const placed = token?.tabPlaced;
|
|
1893
|
+
const leader = token?.tabLeader;
|
|
1894
|
+
const tabSeg = placed ? { ...seg, tab: { align: placed.align, at: placed.at } } : seg;
|
|
1895
|
+
if (!token?.tab || !leader) {
|
|
1896
|
+
out.push(tabSeg);
|
|
1897
|
+
return;
|
|
1898
|
+
}
|
|
1899
|
+
out.push({ ...tabSeg, width: Math.max(0, leader.end - leader.width) });
|
|
1900
|
+
out.push({ kind: 'text', text: leader.text, width: leader.width, leader: leader.rule ? 'rule' : 'text' });
|
|
1901
|
+
const after = seg.width - leader.end;
|
|
1902
|
+
if (after > 0)
|
|
1903
|
+
out.push({ kind: 'space', text: '', width: after, labelTab: true });
|
|
1904
|
+
lastTab = out.length - 1;
|
|
1905
|
+
});
|
|
1906
|
+
const natural = out.reduce((sum, seg) => sum + seg.width, 0);
|
|
1907
|
+
const slack = lineMaxWidth - natural;
|
|
1908
|
+
if (slack > 0.01 && textAlign === 'justify' && !isLastLine) {
|
|
1909
|
+
const spaces = out.map((seg, k) => (k > lastTab && seg.kind === 'space' && !seg.labelTab ? k : -1)).filter((k) => k >= 0);
|
|
1910
|
+
if (spaces.length > 0) {
|
|
1911
|
+
const share = slack / spaces.length;
|
|
1912
|
+
for (const k of spaces)
|
|
1913
|
+
out[k] = { ...out[k], width: out[k].width + share };
|
|
1914
|
+
}
|
|
1915
|
+
}
|
|
1916
|
+
else if (slack > 0.01 && (textAlign === 'center' || textAlign === 'right')) {
|
|
1917
|
+
out.push({ kind: 'space', text: '', width: slack, labelTab: true });
|
|
1918
|
+
}
|
|
1919
|
+
return out;
|
|
1920
|
+
}
|
|
1921
|
+
/** `spans` with their tabs (#622) set as word spaces: vertical text, and a
|
|
1922
|
+
* paragraph the CJK composer sets for its ruby, warichu or kanbun marks. */
|
|
1923
|
+
export function tabsAsSpaces(spans) {
|
|
1924
|
+
return spans.map((s) => {
|
|
1925
|
+
if (!s.tab)
|
|
1926
|
+
return s;
|
|
1927
|
+
const { tab: _tab, ...rest } = s;
|
|
1928
|
+
void _tab;
|
|
1929
|
+
return { ...rest, text: ' ' };
|
|
1930
|
+
});
|
|
1931
|
+
}
|
|
1759
1932
|
/** Give each Arabic word of a justified paragraph its kashida capacity
|
|
1760
1933
|
* (`RichToken.kashida`), which Knuth–Plass counts as the stretch of its
|
|
1761
1934
|
* box. A word in pieces (styled runs of a Latin word, a reference label, a
|