postext 1.59.1 → 1.60.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__/exercises/digital.test.js +19 -1
- package/dist/__tests__/exercises/digital.test.js.map +1 -1
- package/dist/__tests__/exercises/followups.test.d.ts +2 -0
- package/dist/__tests__/exercises/followups.test.d.ts.map +1 -0
- package/dist/__tests__/exercises/followups.test.js +235 -0
- package/dist/__tests__/exercises/followups.test.js.map +1 -0
- package/dist/__tests__/exercises/layout.test.js +31 -0
- package/dist/__tests__/exercises/layout.test.js.map +1 -1
- package/dist/__tests__/pipeline/spanHeadingMidPage.test.js +76 -0
- package/dist/__tests__/pipeline/spanHeadingMidPage.test.js.map +1 -1
- package/dist/canvas-backend/annotations.d.ts +4 -1
- package/dist/canvas-backend/annotations.d.ts.map +1 -1
- package/dist/canvas-backend/annotations.js +5 -0
- package/dist/canvas-backend/annotations.js.map +1 -1
- package/dist/canvas-backend/chip.d.ts.map +1 -1
- package/dist/canvas-backend/chip.js +4 -0
- package/dist/canvas-backend/chip.js.map +1 -1
- package/dist/canvas-backend/swatch.js +1 -1
- package/dist/canvas-backend/swatch.js.map +1 -1
- package/dist/defaults/exercises.d.ts.map +1 -1
- package/dist/defaults/exercises.js +15 -9
- package/dist/defaults/exercises.js.map +1 -1
- package/dist/exercises/build.d.ts.map +1 -1
- package/dist/exercises/build.js +1 -0
- package/dist/exercises/build.js.map +1 -1
- package/dist/exercises/configWarnings.d.ts.map +1 -1
- package/dist/exercises/configWarnings.js +6 -2
- package/dist/exercises/configWarnings.js.map +1 -1
- package/dist/exercises/designs.d.ts +5 -0
- package/dist/exercises/designs.d.ts.map +1 -1
- package/dist/exercises/designs.js +45 -16
- package/dist/exercises/designs.js.map +1 -1
- package/dist/exercises/expand.d.ts +2 -0
- package/dist/exercises/expand.d.ts.map +1 -1
- package/dist/exercises/expand.js +63 -19
- package/dist/exercises/expand.js.map +1 -1
- package/dist/exercises/grids.d.ts.map +1 -1
- package/dist/exercises/grids.js +76 -16
- package/dist/exercises/grids.js.map +1 -1
- package/dist/exercises/model.d.ts +4 -1
- package/dist/exercises/model.d.ts.map +1 -1
- package/dist/exercises/model.js +56 -15
- package/dist/exercises/model.js.map +1 -1
- package/dist/exercises/record.d.ts +5 -1
- package/dist/exercises/record.d.ts.map +1 -1
- package/dist/exercises/runtime.d.ts.map +1 -1
- package/dist/exercises/runtime.js +61 -13
- package/dist/exercises/runtime.js.map +1 -1
- package/dist/exercises/styles.d.ts +8 -0
- package/dist/exercises/styles.d.ts.map +1 -1
- package/dist/exercises/styles.js +16 -2
- package/dist/exercises/styles.js.map +1 -1
- package/dist/html-backend.d.ts.map +1 -1
- package/dist/html-backend.js +35 -23
- package/dist/html-backend.js.map +1 -1
- package/dist/htmlAnnotations.d.ts +5 -1
- package/dist/htmlAnnotations.d.ts.map +1 -1
- package/dist/htmlAnnotations.js +6 -0
- package/dist/htmlAnnotations.js.map +1 -1
- package/dist/measure/cache.js +3 -3
- package/dist/measure/cache.js.map +1 -1
- package/dist/measure/inlineIcon.d.ts +5 -2
- package/dist/measure/inlineIcon.d.ts.map +1 -1
- package/dist/measure/inlineIcon.js +8 -4
- package/dist/measure/inlineIcon.js.map +1 -1
- package/dist/measure/rich.d.ts.map +1 -1
- package/dist/measure/rich.js +72 -4
- package/dist/measure/rich.js.map +1 -1
- package/dist/parse/types.d.ts +7 -0
- package/dist/parse/types.d.ts.map +1 -1
- package/dist/pipeline/build.d.ts.map +1 -1
- package/dist/pipeline/build.js +38 -7
- package/dist/pipeline/build.js.map +1 -1
- package/dist/types.d.ts +18 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/vdt.d.ts +8 -0
- package/dist/vdt.d.ts.map +1 -1
- package/dist/vdt.js.map +1 -1
- package/package.json +1 -1
package/dist/html-backend.js
CHANGED
|
@@ -20,7 +20,7 @@ import { measureFontBox, measureSpacedWidth, measureTextWidth, measuresOwnFace,
|
|
|
20
20
|
import { trackedLigaturePieces } from './measure/trackedLigatures.js';
|
|
21
21
|
import { cellsOf, lineWordSegmentsInOrder, sameSetWidth } from './wordPieces.js';
|
|
22
22
|
import { fontFamilyOf } from './measure/vertical.js';
|
|
23
|
-
import { lineHighlightsHtml, lineMarksHtml, rubyHtml, verticalLineMarksHtml, warichuHtml, sideMarkerHtml, RT_OPEN, RUBY_OPEN, rubyGroupOf, kuntenHtml, verticalKuntenTateHtml } from './htmlAnnotations.js';
|
|
23
|
+
import { chipReadingsHtml, lineHighlightsHtml, lineMarksHtml, rubyHtml, verticalLineMarksHtml, warichuHtml, sideMarkerHtml, RT_OPEN, RUBY_OPEN, rubyGroupOf, kuntenHtml, verticalKuntenTateHtml } from './htmlAnnotations.js';
|
|
24
24
|
import { playMarkTriangle, qrModuleRuns } from './pipeline/videoOverlay.js';
|
|
25
25
|
import { isHlsMimeType, mediaFragment, videoElementAttributes, videoEmbedAllow } from './video/url.js';
|
|
26
26
|
import { hasSwatchShape, swatchGeometry } from './swatchShape.js';
|
|
@@ -1310,9 +1310,11 @@ function cjkAt(char) {
|
|
|
1310
1310
|
*/
|
|
1311
1311
|
function renderSegments(line, block, targets, rootDir = 'ltr', rootLang,
|
|
1312
1312
|
/** What a copy puts after the line (see {@link lineEndText}). */
|
|
1313
|
-
end = ''
|
|
1313
|
+
end = '',
|
|
1314
|
+
/** Where the line's inline pictures come from (#1249). */
|
|
1315
|
+
paint) {
|
|
1314
1316
|
if (line.cjkComposed)
|
|
1315
|
-
return renderComposedSegments(line, block, targets, rootDir, end);
|
|
1317
|
+
return renderComposedSegments(line, block, targets, rootDir, end, paint);
|
|
1316
1318
|
// The tracking after the last glyph is advance, not ink: centring and
|
|
1317
1319
|
// right alignment leave it out (EF-153), as the canvas does.
|
|
1318
1320
|
const tracking = (block.letterSpacing ?? 0) + (line.letterSpacing ?? 0);
|
|
@@ -1410,7 +1412,7 @@ end = '') {
|
|
|
1410
1412
|
continue;
|
|
1411
1413
|
}
|
|
1412
1414
|
if (seg.kind === 'swatch') {
|
|
1413
|
-
parts.push(renderSwatchSegment(seg.swatch, x, line.baseline - line.bbox.y, seg.width, block.color,
|
|
1415
|
+
parts.push(renderSwatchSegment(seg.swatch, x, line.baseline - line.bbox.y, seg.width, block.color, paint, seg.rtl === true));
|
|
1414
1416
|
x += seg.width;
|
|
1415
1417
|
continue;
|
|
1416
1418
|
}
|
|
@@ -1463,7 +1465,7 @@ function orderedOffsets(segs, order, start, spaceWidth) {
|
|
|
1463
1465
|
/** {@link renderSegments} for a line of the CJK composer: hung marks and
|
|
1464
1466
|
* Han–Latin spaces kept out of the justification, each segment with its
|
|
1465
1467
|
* own tracking, ink offset and scale, warichu notes and ruby readings. */
|
|
1466
|
-
function renderComposedSegments(line, block, targets, rootDir = 'ltr', end = '') {
|
|
1468
|
+
function renderComposedSegments(line, block, targets, rootDir = 'ltr', end = '', paint) {
|
|
1467
1469
|
// The tracking after the last glyph is advance, not ink: centring and
|
|
1468
1470
|
// right alignment leave it out (EF-153), as the canvas does.
|
|
1469
1471
|
const lineTracking = (block.letterSpacing ?? 0) + (line.letterSpacing ?? 0);
|
|
@@ -1564,7 +1566,7 @@ function renderComposedSegments(line, block, targets, rootDir = 'ltr', end = '')
|
|
|
1564
1566
|
continue;
|
|
1565
1567
|
}
|
|
1566
1568
|
if (seg.kind === 'swatch') {
|
|
1567
|
-
parts.push(renderSwatchSegment(seg.swatch, x, line.baseline - line.bbox.y, seg.width, block.color,
|
|
1569
|
+
parts.push(renderSwatchSegment(seg.swatch, x, line.baseline - line.bbox.y, seg.width, block.color, paint, seg.rtl === true));
|
|
1568
1570
|
x += seg.width;
|
|
1569
1571
|
continue;
|
|
1570
1572
|
}
|
|
@@ -1784,6 +1786,9 @@ rootDir = 'ltr') {
|
|
|
1784
1786
|
const label = chip.blank ? ` role="img" aria-label="${esc(chip.blankLabel ?? 'blank')}"` : '';
|
|
1785
1787
|
parts.push(`<span class="pt-ex-slot${chip.blank ? ' pt-ex-blank' : ''}"${data}${label} style="${boxGeometry}"></span>`);
|
|
1786
1788
|
}
|
|
1789
|
+
// The readings of its ruby words, over a blank too (#1244).
|
|
1790
|
+
if (chip.readings && chip.runs[0])
|
|
1791
|
+
parts.push(chipReadingsHtml(chip.readings, bx, inkFor(chip.runs[0]), quoteFontString));
|
|
1787
1792
|
if (chip.blank)
|
|
1788
1793
|
return parts.join('');
|
|
1789
1794
|
let tx = bx + chip.borderWidth + chip.paddingX;
|
|
@@ -1931,7 +1936,9 @@ function renderLine(line, block, targets, rootDir = 'ltr', rootLang,
|
|
|
1931
1936
|
next,
|
|
1932
1937
|
/** Markup set at the start of the line's box, before its text (a drop
|
|
1933
1938
|
* cap, #623). */
|
|
1934
|
-
lead = ''
|
|
1939
|
+
lead = '',
|
|
1940
|
+
/** Where the line's inline pictures come from (#1249). */
|
|
1941
|
+
paint) {
|
|
1935
1942
|
const font = quoteFontString(block.fontString);
|
|
1936
1943
|
const strikethroughDecl = block.strikethroughText ? 'text-decoration:line-through;' : '';
|
|
1937
1944
|
// Tracking — the block's (column balancing, a runt set short) and the
|
|
@@ -1951,7 +1958,7 @@ lead = '') {
|
|
|
1951
1958
|
strikethroughDecl +
|
|
1952
1959
|
trackingDecl +
|
|
1953
1960
|
(lineCjkDecl(line) ? cjkTextDecl(tracking !== 0) : '') +
|
|
1954
|
-
`">${lineHighlightsHtml(line)}${lead}${renderSegments(line, block, targets, rootDir, rootLang, lineEndText(line, next))}</div>`);
|
|
1961
|
+
`">${lineHighlightsHtml(line)}${lead}${renderSegments(line, block, targets, rootDir, rootLang, lineEndText(line, next), paint)}</div>`);
|
|
1955
1962
|
}
|
|
1956
1963
|
/**
|
|
1957
1964
|
* A paragraph's drop cap (#623), as the first runs of its first line's box:
|
|
@@ -2141,7 +2148,7 @@ function verticalWordSegments(line, block, v, tracking) {
|
|
|
2141
2148
|
/** A body line of a vertical page: its text segments down an upright box,
|
|
2142
2149
|
* its formulas, swatches and chips sideways where the canvas paints them
|
|
2143
2150
|
* (see the section comment). */
|
|
2144
|
-
function renderVerticalLine(line, block, v, targets, next) {
|
|
2151
|
+
function renderVerticalLine(line, block, v, targets, next, paint) {
|
|
2145
2152
|
const lineTracking = (block.letterSpacing ?? 0) + (line.letterSpacing ?? 0);
|
|
2146
2153
|
const trailing = lineTrailingTracking(line, lineTracking);
|
|
2147
2154
|
const lineIndent = line.bbox.x - block.bbox.x;
|
|
@@ -2190,7 +2197,7 @@ function renderVerticalLine(line, block, v, targets, next) {
|
|
|
2190
2197
|
continue;
|
|
2191
2198
|
}
|
|
2192
2199
|
if (seg.kind === 'swatch') {
|
|
2193
|
-
sideways.push(renderSwatchSegment(seg.swatch, x, line.baseline - line.bbox.y, seg.width, block.color,
|
|
2200
|
+
sideways.push(renderSwatchSegment(seg.swatch, x, line.baseline - line.bbox.y, seg.width, block.color, paint, seg.rtl === true));
|
|
2194
2201
|
x += seg.width;
|
|
2195
2202
|
continue;
|
|
2196
2203
|
}
|
|
@@ -2724,7 +2731,7 @@ function renderFigureLabelsHtml(rb, bx, by, options) {
|
|
|
2724
2731
|
const n2 = (v) => String(+v.toFixed(4));
|
|
2725
2732
|
// Their leaders first (#1057), under every label: vector lines hidden
|
|
2726
2733
|
// from assistive technology, as design paths are.
|
|
2727
|
-
const parts = figureLabelLeaderPaths(rb, bx, by).map(renderDesignPathBlock);
|
|
2734
|
+
const parts = figureLabelLeaderPaths(rb, bx, by).map((p) => renderDesignPathBlock(p));
|
|
2728
2735
|
for (const label of rb.labels ?? []) {
|
|
2729
2736
|
let layout = label.layout;
|
|
2730
2737
|
if (!layout)
|
|
@@ -2760,7 +2767,7 @@ function renderFigureLabelsHtml(rb, bx, by, options) {
|
|
|
2760
2767
|
id: label.id ?? '', fontString: layout.fontString, boldFontString: layout.boldFontString, italicFontString: layout.italicFontString,
|
|
2761
2768
|
boldItalicFontString: layout.boldItalicFontString, color: layout.color, textAlign: 'left', bbox: layout.box,
|
|
2762
2769
|
};
|
|
2763
|
-
layout.lines.forEach((line, i) => inner.push(renderVerticalLine(line, host, v, options.linkTargets, layout.lines[i + 1])));
|
|
2770
|
+
layout.lines.forEach((line, i) => inner.push(renderVerticalLine(line, host, v, options.linkTargets, layout.lines[i + 1], options)));
|
|
2764
2771
|
}
|
|
2765
2772
|
else {
|
|
2766
2773
|
layout.lines.forEach((line, i) => {
|
|
@@ -3095,7 +3102,7 @@ function renderDesignRuleBlock(block) {
|
|
|
3095
3102
|
* box like a rule, its outline and markers drawn in the box's own
|
|
3096
3103
|
* coordinates (ink past the box, a mitre, still shows). Decoration:
|
|
3097
3104
|
* hidden from assistive technology. */
|
|
3098
|
-
function renderDesignPathBlock(block) {
|
|
3105
|
+
function renderDesignPathBlock(block, mirrored = false) {
|
|
3099
3106
|
const { x, y, width, height } = block.bbox;
|
|
3100
3107
|
const parts = [];
|
|
3101
3108
|
const stroke = block.stroke && block.stroke.widthPx > 0 ? block.stroke : undefined;
|
|
@@ -3118,7 +3125,7 @@ function renderDesignPathBlock(block) {
|
|
|
3118
3125
|
parts.push(markerSvgElement(m, x, y, esc));
|
|
3119
3126
|
if (parts.length === 0)
|
|
3120
3127
|
return '';
|
|
3121
|
-
return (`<svg aria-hidden="true" focusable="false" width="${width}" height="${height}" ` +
|
|
3128
|
+
return (`<svg${mirrored ? ' class="pt-path"' : ''} aria-hidden="true" focusable="false" width="${width}" height="${height}" ` +
|
|
3122
3129
|
`style="position:absolute;left:${x}px;top:${y}px;width:${width}px;height:${height}px;overflow:visible;">` +
|
|
3123
3130
|
parts.join('') +
|
|
3124
3131
|
`</svg>`);
|
|
@@ -3177,7 +3184,7 @@ function renderDesignImageBlock(block, options) {
|
|
|
3177
3184
|
`background:rgba(160,160,160,0.12);border:1px solid rgba(160,160,160,0.5);box-sizing:border-box;` +
|
|
3178
3185
|
`"></div>`);
|
|
3179
3186
|
}
|
|
3180
|
-
function renderDesignBlock(block, options) {
|
|
3187
|
+
function renderDesignBlock(block, options, mirroredPaths = false) {
|
|
3181
3188
|
if (block.kind === 'text')
|
|
3182
3189
|
return renderDesignTextBlock(block, options);
|
|
3183
3190
|
if (block.kind === 'rule')
|
|
@@ -3185,20 +3192,23 @@ function renderDesignBlock(block, options) {
|
|
|
3185
3192
|
if (block.kind === 'image')
|
|
3186
3193
|
return renderDesignImageBlock(block, options);
|
|
3187
3194
|
if (block.kind === 'path')
|
|
3188
|
-
return renderDesignPathBlock(block);
|
|
3195
|
+
return renderDesignPathBlock(block, mirroredPaths);
|
|
3189
3196
|
return renderDesignBoxBlock(block);
|
|
3190
3197
|
}
|
|
3191
|
-
function renderDesignSlot(slot, options) {
|
|
3198
|
+
function renderDesignSlot(slot, options, mirroredPaths = false) {
|
|
3192
3199
|
const parts = [];
|
|
3193
3200
|
for (const block of slot.blocks)
|
|
3194
|
-
parts.push(renderDesignBlock(block, options));
|
|
3201
|
+
parts.push(renderDesignBlock(block, options, mirroredPaths));
|
|
3195
3202
|
return parts.join('');
|
|
3196
3203
|
}
|
|
3197
3204
|
function renderBlockInner(block, options) {
|
|
3198
3205
|
if (block.hidden)
|
|
3199
3206
|
return '';
|
|
3207
|
+
// An exercise's drawn box (a grid, an operation, a writing area) keeps
|
|
3208
|
+
// its paths mirrored with a mirrored flow, as the canvas and the PDF
|
|
3209
|
+
// paint it (#1244).
|
|
3200
3210
|
if (block.designOverlay)
|
|
3201
|
-
return renderDesignSlot(block.designOverlay, options);
|
|
3211
|
+
return renderDesignSlot(block.designOverlay, options, !!block.callout?.styleId?.startsWith('__postext-ex'));
|
|
3202
3212
|
// Resource embeds carry their own measured geometry (image/table + caption);
|
|
3203
3213
|
// the block's single placeholder line renders nothing useful.
|
|
3204
3214
|
if (block.resourceBlock)
|
|
@@ -3213,7 +3223,7 @@ function renderBlockInner(block, options) {
|
|
|
3213
3223
|
block.lines.forEach((line, i) => {
|
|
3214
3224
|
const next = block.lines[i + 1];
|
|
3215
3225
|
const lead = i === 0 && block.dropCap && !v ? dropCapHtml(block.dropCap, line, quoteFontString(block.fontString), (block.letterSpacing ?? 0) + (line.letterSpacing ?? 0)) : '';
|
|
3216
|
-
parts.push(v ? renderVerticalLine(line, block, v, options.linkTargets, next) : renderLine(line, block, options.linkTargets, options.dir, options.rootLang, next, lead));
|
|
3226
|
+
parts.push(v ? renderVerticalLine(line, block, v, options.linkTargets, next, options) : renderLine(line, block, options.linkTargets, options.dir, options.rootLang, next, lead, options));
|
|
3217
3227
|
});
|
|
3218
3228
|
return parts.join('');
|
|
3219
3229
|
}
|
|
@@ -3237,7 +3247,7 @@ function renderStripCaptionHtml(block, options) {
|
|
|
3237
3247
|
const lines = block.lines.slice(caption.firstLine, caption.firstLine + caption.lineCount);
|
|
3238
3248
|
lines.forEach((line, i) => {
|
|
3239
3249
|
const next = lines[i + 1];
|
|
3240
|
-
parts.push(v ? renderVerticalLine(line, block, v, options.linkTargets, next) : renderLine(line, block, options.linkTargets, options.dir, options.rootLang, next));
|
|
3250
|
+
parts.push(v ? renderVerticalLine(line, block, v, options.linkTargets, next, options) : renderLine(line, block, options.linkTargets, options.dir, options.rootLang, next, '', options));
|
|
3241
3251
|
});
|
|
3242
3252
|
return parts.join('');
|
|
3243
3253
|
}
|
|
@@ -3586,12 +3596,14 @@ function renderComicPageHtml(page, comic, k, options, overPanel) {
|
|
|
3586
3596
|
* mirrored layout put it. A box that sets a transform of its own (a
|
|
3587
3597
|
* stretched dash, a turned design picture) keeps it and stays mirrored. */
|
|
3588
3598
|
const MIRRORED_FLOW_STYLE = '<style>.pt-flow-mirrored [style*="white-space:pre"],.pt-flow-mirrored img,' +
|
|
3589
|
-
'
|
|
3599
|
+
// An exercise's drawing is geometry, mirrored with the flow as the canvas
|
|
3600
|
+
// and the PDF mirror it (#1244): a crossword's cells, an operation's rules.
|
|
3601
|
+
'.pt-flow-mirrored svg:not(.pt-char-grid):not(.pt-path),.pt-flow-mirrored .pt-video{transform:scaleX(-1);}' +
|
|
3590
3602
|
// A box reflected back about its body (a vertical label, #955) or a
|
|
3591
3603
|
// vertical frame of the page placed by a matrix that includes the mirror
|
|
3592
3604
|
// (#960): what is in it is not mirrored, so nothing is turned back.
|
|
3593
3605
|
'.pt-flow-mirrored .pt-unmirrored [style*="white-space:pre"],.pt-flow-mirrored .pt-unmirrored img,' +
|
|
3594
|
-
'.pt-flow-mirrored .pt-unmirrored svg:not(.pt-char-grid),.pt-flow-mirrored .pt-unmirrored .pt-video{transform:none;}</style>';
|
|
3606
|
+
'.pt-flow-mirrored .pt-unmirrored svg:not(.pt-char-grid):not(.pt-path),.pt-flow-mirrored .pt-unmirrored .pt-video{transform:none;}</style>';
|
|
3595
3607
|
/** The character grid (稿纸) as one SVG path over the page, under the
|
|
3596
3608
|
* text (see `cjkGridCells`). */
|
|
3597
3609
|
function renderCharacterGridSvg(cells, width, height) {
|