postext 1.53.0 → 1.54.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.
Files changed (157) hide show
  1. package/dist/__tests__/bundle/balloonPlacementPin.test.js +6 -5
  2. package/dist/__tests__/bundle/balloonPlacementPin.test.js.map +1 -1
  3. package/dist/__tests__/bundle/designOverflowPin.test.js +1 -1
  4. package/dist/__tests__/bundle/gridBalancingPin.test.js +6 -5
  5. package/dist/__tests__/bundle/gridBalancingPin.test.js.map +1 -1
  6. package/dist/__tests__/bundle/gridBreakRulesPin.test.js +8 -7
  7. package/dist/__tests__/bundle/gridBreakRulesPin.test.js.map +1 -1
  8. package/dist/__tests__/bundle/looseOrderPin.test.js +6 -5
  9. package/dist/__tests__/bundle/looseOrderPin.test.js.map +1 -1
  10. package/dist/__tests__/bundle/markRadiusPin.test.js +1 -1
  11. package/dist/__tests__/bundle/refLabelBreaksPin.test.js +6 -5
  12. package/dist/__tests__/bundle/refLabelBreaksPin.test.js.map +1 -1
  13. package/dist/__tests__/bundle/scriptContextPin.test.js +6 -5
  14. package/dist/__tests__/bundle/scriptContextPin.test.js.map +1 -1
  15. package/dist/__tests__/bundle/shapingLanguagePin.test.js +3 -3
  16. package/dist/__tests__/bundle/taskBoxPin.test.js +1 -1
  17. package/dist/__tests__/bundle.test.js +1 -1
  18. package/dist/__tests__/codeBlocks.test.js +1 -1
  19. package/dist/__tests__/composedTemplates.test.js +1 -1
  20. package/dist/__tests__/exports.test.js +17 -0
  21. package/dist/__tests__/exports.test.js.map +1 -1
  22. package/dist/__tests__/hardBreaks.test.js +1 -1
  23. package/dist/__tests__/headingInlineMarks.test.js +1 -1
  24. package/dist/__tests__/mathSizeMigration.test.js +2 -2
  25. package/dist/__tests__/musicEngine.test.d.ts +2 -0
  26. package/dist/__tests__/musicEngine.test.d.ts.map +1 -0
  27. package/dist/__tests__/musicEngine.test.js +102 -0
  28. package/dist/__tests__/musicEngine.test.js.map +1 -0
  29. package/dist/__tests__/musicLayout.test.d.ts +2 -0
  30. package/dist/__tests__/musicLayout.test.d.ts.map +1 -0
  31. package/dist/__tests__/musicLayout.test.js +146 -0
  32. package/dist/__tests__/musicLayout.test.js.map +1 -0
  33. package/dist/__tests__/pipeline/boxParagraphStyles.test.js +2 -2
  34. package/dist/__tests__/pipeline/calloutInlineResourceGap.test.js +1 -1
  35. package/dist/__tests__/pipeline/calloutSplitMinLinesChild.test.js +1 -1
  36. package/dist/__tests__/pipeline/colonListRoom.test.js +1 -1
  37. package/dist/__tests__/pipeline/compoundBreaks.test.js +1 -1
  38. package/dist/__tests__/pipeline/dashBreaks.test.js +1 -1
  39. package/dist/__tests__/pipeline/headingSplitOrphans.test.js +1 -1
  40. package/dist/__tests__/pipeline/inlineFigureSpace.test.js +1 -1
  41. package/dist/__tests__/pipeline/paragraphContainerTail.test.js +1 -1
  42. package/dist/__tests__/pipeline/raggedOptimal.test.js +1 -1
  43. package/dist/__tests__/slashBreaks.test.js +1 -1
  44. package/dist/__tests__/verseLines.test.js +1 -1
  45. package/dist/bundle/codec.d.ts.map +1 -1
  46. package/dist/bundle/codec.js +10 -0
  47. package/dist/bundle/codec.js.map +1 -1
  48. package/dist/bundle/configVersion.d.ts +12 -2
  49. package/dist/bundle/configVersion.d.ts.map +1 -1
  50. package/dist/bundle/configVersion.js +32 -2
  51. package/dist/bundle/configVersion.js.map +1 -1
  52. package/dist/bundle/manifest.d.ts.map +1 -1
  53. package/dist/bundle/manifest.js +9 -2
  54. package/dist/bundle/manifest.js.map +1 -1
  55. package/dist/bundle/types.d.ts +6 -1
  56. package/dist/bundle/types.d.ts.map +1 -1
  57. package/dist/canvas-backend/blockRender.d.ts.map +1 -1
  58. package/dist/canvas-backend/blockRender.js +17 -2
  59. package/dist/canvas-backend/blockRender.js.map +1 -1
  60. package/dist/canvas-backend/renderResourceBlock.d.ts.map +1 -1
  61. package/dist/canvas-backend/renderResourceBlock.js +7 -0
  62. package/dist/canvas-backend/renderResourceBlock.js.map +1 -1
  63. package/dist/canvas-backend/scoreRender.d.ts +10 -0
  64. package/dist/canvas-backend/scoreRender.d.ts.map +1 -0
  65. package/dist/canvas-backend/scoreRender.js +74 -0
  66. package/dist/canvas-backend/scoreRender.js.map +1 -0
  67. package/dist/composed/sourceMap.js +1 -1
  68. package/dist/composed/sourceMap.js.map +1 -1
  69. package/dist/defaults/index.d.ts +2 -1
  70. package/dist/defaults/index.d.ts.map +1 -1
  71. package/dist/defaults/index.js +17 -1
  72. package/dist/defaults/index.js.map +1 -1
  73. package/dist/defaults/resourceTypes.d.ts +5 -0
  74. package/dist/defaults/resourceTypes.d.ts.map +1 -1
  75. package/dist/defaults/resourceTypes.js +34 -4
  76. package/dist/defaults/resourceTypes.js.map +1 -1
  77. package/dist/defaults/scoreStyle.d.ts +15 -0
  78. package/dist/defaults/scoreStyle.d.ts.map +1 -0
  79. package/dist/defaults/scoreStyle.js +91 -0
  80. package/dist/defaults/scoreStyle.js.map +1 -0
  81. package/dist/design/elementKeys.d.ts +2 -0
  82. package/dist/design/elementKeys.d.ts.map +1 -1
  83. package/dist/design/elementKeys.js +1 -1
  84. package/dist/design/elementKeys.js.map +1 -1
  85. package/dist/html-backend.d.ts.map +1 -1
  86. package/dist/html-backend.js +47 -0
  87. package/dist/html-backend.js.map +1 -1
  88. package/dist/index.d.ts +4 -2
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +2 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/music/engine.d.ts +21 -0
  93. package/dist/music/engine.d.ts.map +1 -0
  94. package/dist/music/engine.js +309 -0
  95. package/dist/music/engine.js.map +1 -0
  96. package/dist/music/flatten.d.ts +21 -0
  97. package/dist/music/flatten.d.ts.map +1 -0
  98. package/dist/music/flatten.js +302 -0
  99. package/dist/music/flatten.js.map +1 -0
  100. package/dist/music/index.d.ts +4 -0
  101. package/dist/music/index.d.ts.map +1 -0
  102. package/dist/music/index.js +3 -0
  103. package/dist/music/index.js.map +1 -0
  104. package/dist/music/types.d.ts +88 -0
  105. package/dist/music/types.d.ts.map +1 -0
  106. package/dist/music/types.js +35 -0
  107. package/dist/music/types.js.map +1 -0
  108. package/dist/parse/blockParser.d.ts.map +1 -1
  109. package/dist/parse/blockParser.js +21 -1
  110. package/dist/parse/blockParser.js.map +1 -1
  111. package/dist/parse/types.d.ts +30 -1
  112. package/dist/parse/types.d.ts.map +1 -1
  113. package/dist/pipeline/build.d.ts.map +1 -1
  114. package/dist/pipeline/build.js +40 -7
  115. package/dist/pipeline/build.js.map +1 -1
  116. package/dist/pipeline/buildBlockKind.d.ts.map +1 -1
  117. package/dist/pipeline/buildBlockKind.js +9 -0
  118. package/dist/pipeline/buildBlockKind.js.map +1 -1
  119. package/dist/pipeline/buildMeasurement.d.ts.map +1 -1
  120. package/dist/pipeline/buildMeasurement.js +22 -0
  121. package/dist/pipeline/buildMeasurement.js.map +1 -1
  122. package/dist/pipeline/calloutLayout.d.ts.map +1 -1
  123. package/dist/pipeline/calloutLayout.js +14 -3
  124. package/dist/pipeline/calloutLayout.js.map +1 -1
  125. package/dist/pipeline/codeBlocks.d.ts.map +1 -1
  126. package/dist/pipeline/codeBlocks.js +4 -2
  127. package/dist/pipeline/codeBlocks.js.map +1 -1
  128. package/dist/pipeline/columnBalancing.d.ts.map +1 -1
  129. package/dist/pipeline/columnBalancing.js +7 -1
  130. package/dist/pipeline/columnBalancing.js.map +1 -1
  131. package/dist/pipeline/config.d.ts.map +1 -1
  132. package/dist/pipeline/config.js +3 -1
  133. package/dist/pipeline/config.js.map +1 -1
  134. package/dist/pipeline/frameLayout.js +1 -1
  135. package/dist/pipeline/frameLayout.js.map +1 -1
  136. package/dist/pipeline/lineNumbers.js +1 -1
  137. package/dist/pipeline/lineNumbers.js.map +1 -1
  138. package/dist/pipeline/resourceLayout.d.ts.map +1 -1
  139. package/dist/pipeline/resourceLayout.js +9 -0
  140. package/dist/pipeline/resourceLayout.js.map +1 -1
  141. package/dist/pipeline/scoreBlocks.d.ts +44 -0
  142. package/dist/pipeline/scoreBlocks.d.ts.map +1 -0
  143. package/dist/pipeline/scoreBlocks.js +172 -0
  144. package/dist/pipeline/scoreBlocks.js.map +1 -0
  145. package/dist/pipeline/tashkil.js +1 -1
  146. package/dist/pipeline/tashkil.js.map +1 -1
  147. package/dist/react/createLayout.d.ts.map +1 -1
  148. package/dist/react/createLayout.js +4 -0
  149. package/dist/react/createLayout.js.map +1 -1
  150. package/dist/types.d.ts +76 -1
  151. package/dist/types.d.ts.map +1 -1
  152. package/dist/vdt.d.ts +43 -4
  153. package/dist/vdt.d.ts.map +1 -1
  154. package/dist/vdt.js.map +1 -1
  155. package/dist/worker/layout.worker.js +10 -0
  156. package/dist/worker/layout.worker.js.map +1 -1
  157. package/package.json +3 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"musicEngine.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/musicEngine.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,102 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
+ import { initMusicEngine, renderScore } from '../music/index.js';
3
+ const ODE = `X:1
4
+ T:Ode to Joy
5
+ C:L. van Beethoven
6
+ M:4/4
7
+ L:1/4
8
+ K:D
9
+ FFGA|AGFE|DDEF|F3/2E/2E2|FFGA|AGFE|DDEF|E3/2D/2D2|
10
+ EEFD|EF/2G/2FD|EF/2G/2FE|DEA,2|FFGA|AGFE|DDEF|E3/2D/2D2|]
11
+ `;
12
+ const OPTS = {
13
+ staffSizePx: 24, font: 'Bravura', spacing: 1, barNumbers: 'system', systemSpacing: 4,
14
+ };
15
+ describe('music engine', () => {
16
+ beforeAll(async () => { await initMusicEngine(); }, 60_000);
17
+ it('engraves ABC into one slice per system, narrower measures giving more systems', () => {
18
+ const wide = renderScore(ODE, 'abc', 700, OPTS);
19
+ const narrow = renderScore(ODE, 'abc', 300, OPTS);
20
+ expect(wide.error).toBeUndefined();
21
+ expect(wide.systems.length).toBeGreaterThan(0);
22
+ expect(narrow.systems.length).toBeGreaterThan(wide.systems.length);
23
+ for (const s of narrow.systems) {
24
+ expect(s.widthPx).toBe(300);
25
+ expect(s.heightPx).toBeGreaterThan(24);
26
+ expect(s.items.some((i) => i.type === 'path' && i.fill)).toBe(true);
27
+ expect(s.items.some((i) => i.type === 'path' && !i.fill)).toBe(true);
28
+ expect(s.svg).not.toMatch(/<use|<style|<svg[^>]*><svg/);
29
+ }
30
+ expect(wide.title).toBe('Ode to Joy');
31
+ expect(wide.composer).toBe('L. van Beethoven');
32
+ });
33
+ it('keeps every painted item inside the slice', () => {
34
+ const r = renderScore(ODE, 'abc', 400, OPTS);
35
+ for (const s of r.systems) {
36
+ for (const it of s.items) {
37
+ if (it.type !== 'path')
38
+ continue;
39
+ const nums = it.d.match(/-?\d*\.?\d+(?:e-?\d+)?/g).map(Number);
40
+ const xs = nums.filter((_, k) => k % 2 === 0);
41
+ expect(Math.min(...xs)).toBeGreaterThan(-5);
42
+ expect(Math.max(...xs)).toBeLessThan(405);
43
+ }
44
+ }
45
+ });
46
+ it('engraves a four-part chorale written in Humdrum', () => {
47
+ const kern = [
48
+ '**kern\t**kern\t**kern\t**kern',
49
+ '*clefF4\t*clefGv2\t*clefG2\t*clefG2',
50
+ '*k[f#]\t*k[f#]\t*k[f#]\t*k[f#]',
51
+ '*M4/4\t*M4/4\t*M4/4\t*M4/4',
52
+ '4GG\t4B\t4d\t4b',
53
+ '4D\t4d\t4f#\t4a',
54
+ '4E\t4B\t4e\t4g',
55
+ '4D\t4d\t4f#\t4a',
56
+ '=\t=\t=\t=',
57
+ '1GG\t1B\t1d\t1g',
58
+ '==\t==\t==\t==',
59
+ '*-\t*-\t*-\t*-',
60
+ ].join('\n');
61
+ const r = renderScore(kern, 'humdrum', 500, OPTS);
62
+ expect(r.error).toBeUndefined();
63
+ expect(r.systems.length).toBeGreaterThan(0);
64
+ // Four staves: a system much taller than one staff.
65
+ expect(r.systems[0].heightPx).toBeGreaterThan(OPTS.staffSizePx * 4);
66
+ // The bracket joining the staves stays inside the slice.
67
+ for (const it of r.systems[0].items) {
68
+ if (it.type !== 'path')
69
+ continue;
70
+ for (const m of it.d.matchAll(/[MLC]([^A-Za-z]*)/g)) {
71
+ const xs = m[1].trim().split(/[\s,]+/).map(Number).filter((_, k) => k % 2 === 0);
72
+ expect(Math.min(...xs)).toBeGreaterThanOrEqual(-0.01);
73
+ }
74
+ }
75
+ });
76
+ it('prints bar numbers at each system, on every bar, or not at all', () => {
77
+ const bars = `X:1\nM:4/4\nL:1/4\nK:C\n${'CDEF|GABc|cBAG|FEDC|'.repeat(3)}]\n`;
78
+ const words = (barNumbers) => renderScore(bars, 'abc', 330, { ...OPTS, barNumbers }).systems.map((s) => s.items.filter((i) => i.type === 'text').map((i) => i.text));
79
+ const system = words('system');
80
+ expect(system[0]).toEqual([]);
81
+ expect(system.slice(1).every((w) => w.length === 1 && /^\d+$/.test(w[0]))).toBe(true);
82
+ expect(words('every').flat().length).toBeGreaterThan(system.flat().length);
83
+ expect(words('none').flat()).toEqual([]);
84
+ });
85
+ it('keeps a chord symbol\'s raised figure smaller and on its own baseline (**harm)', () => {
86
+ const kern = ['**kern\t**harm', '*clefF4\t*', '*M4/4\t*', '4G\tI', '4D\tV7', '4C\tIV', '4G\tI', '==\t==', '*-\t*-'].join('\n');
87
+ const words = renderScore(kern, 'humdrum', 600, OPTS).systems.flatMap((s) => s.items.filter((i) => i.type === 'text'));
88
+ const v = words.find((w) => w.text === 'V');
89
+ const seven = words.find((w) => w.text === '7');
90
+ expect(v).toBeDefined();
91
+ expect(seven).toBeDefined();
92
+ expect(seven.sizePx).toBeLessThan(v.sizePx);
93
+ expect(seven.y).not.toBeCloseTo(v.y, 1);
94
+ expect(seven.x).toBeGreaterThan(v.x);
95
+ expect(words.some((w) => w.text === 'V7')).toBe(false);
96
+ });
97
+ it('reports a source that does not load', () => {
98
+ const r = renderScore('<not-music/>', 'mei', 400, OPTS);
99
+ expect(r.systems).toHaveLength(0);
100
+ });
101
+ });
102
+ //# sourceMappingURL=musicEngine.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"musicEngine.test.js","sourceRoot":"","sources":["../../src/__tests__/musicEngine.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=musicLayout.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"musicLayout.test.d.ts","sourceRoot":"","sources":["../../src/__tests__/musicLayout.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,146 @@
1
+ import { describe, it, expect, beforeAll } from 'vitest';
2
+ import { buildDocument } from '../pipeline/index.js';
3
+ import { renderToHtmlIndexed } from '../html-backend.js';
4
+ import { initMusicEngine } from '../music/index.js';
5
+ import { parseMarkdown } from '../parse/index.js';
6
+ // Deterministic text measurement stub (no DOM in the node test env).
7
+ class StubCtx {
8
+ font = '';
9
+ measureText(s) {
10
+ return { width: s.length * 7 };
11
+ }
12
+ }
13
+ globalThis.OffscreenCanvas = class {
14
+ getContext() {
15
+ return new StubCtx();
16
+ }
17
+ };
18
+ const TUNE = `X:1
19
+ T:Study in D
20
+ C:Anonymous
21
+ M:4/4
22
+ L:1/8
23
+ K:D
24
+ ${Array.from({ length: 12 }, () => 'DFAd fdAF|GBdg bgdB|Acea c\'aec|d2f2 d4|').join('\n')}|]`;
25
+ const MARKDOWN = `# Scales
26
+
27
+ Some text before the score.
28
+
29
+ \`\`\`abc {alt="A study in D"}
30
+ ${TUNE}
31
+ \`\`\`
32
+
33
+ Text after the score.
34
+ `;
35
+ const CONFIG = { page: { width: { value: 12, unit: 'cm' }, height: { value: 16, unit: 'cm' } } };
36
+ function scoreBlocks(doc) {
37
+ const out = [];
38
+ for (const page of doc.pages)
39
+ for (const col of page.columns)
40
+ for (const b of col.blocks)
41
+ if (b.type === 'score')
42
+ out.push({ page: page.index, block: b });
43
+ return out;
44
+ }
45
+ describe('music scores in the layout', () => {
46
+ beforeAll(async () => { await initMusicEngine(); }, 60_000);
47
+ it('parses a notation fence as a score, and a {listing} fence as code', () => {
48
+ const blocks = parseMarkdown('```abc\nX:1\nK:C\nCDEF|\n```\n\n```abc {listing}\nX:1\n```\n');
49
+ expect(blocks.map((b) => b.type)).toEqual(['score', 'code']);
50
+ expect(blocks[0].score).toMatchObject({ format: 'abc', source: 'X:1\nK:C\nCDEF|' });
51
+ });
52
+ it('sets one block per system, running on over pages', () => {
53
+ const doc = buildDocument({ markdown: MARKDOWN }, CONFIG);
54
+ const systems = scoreBlocks(doc);
55
+ expect(systems.length).toBeGreaterThan(4);
56
+ const pages = new Set(systems.map((s) => s.page));
57
+ expect(pages.size).toBeGreaterThan(1);
58
+ systems.forEach(({ block }, i) => {
59
+ expect(block.score).toMatchObject({ index: i, count: systems.length });
60
+ expect(block.lines).toHaveLength(1);
61
+ expect(block.lines[0]?.segments?.[0]?.kind).toBe('score');
62
+ });
63
+ expect(systems[0]?.block.score?.alt).toBe('A study in D');
64
+ // Systems never overlap, and their staves stay in their column.
65
+ const inkHeight = (b) => b.lines[0]?.bbox.height ?? 0;
66
+ for (const page of doc.pages) {
67
+ for (const col of page.columns) {
68
+ const ss = col.blocks.filter((b) => b.type === 'score');
69
+ for (let k = 1; k < ss.length; k++)
70
+ expect(ss[k].bbox.y).toBeGreaterThanOrEqual(ss[k - 1].bbox.y + inkHeight(ss[k - 1]) - 0.01);
71
+ for (const b of ss)
72
+ expect(b.bbox.y + inkHeight(b)).toBeLessThanOrEqual(col.bbox.y + col.bbox.height + 0.5);
73
+ }
74
+ }
75
+ });
76
+ it('keeps the first and last systems together under minSystemsAtBreak', () => {
77
+ const runsOf = (m, lead) => {
78
+ const md = `# S\n\n${'Text before the score. '.repeat(lead * 8)}\n\n\`\`\`abc\n${TUNE}\n\`\`\`\n\nAfter.\n`;
79
+ const doc = buildDocument({ markdown: md }, {
80
+ ...CONFIG,
81
+ layout: { layoutType: 'single' },
82
+ scoreStyle: { minSystemsAtBreak: m, staffSize: { value: 9, unit: 'mm' } },
83
+ });
84
+ const runs = [];
85
+ for (const p of doc.pages)
86
+ for (const c of p.columns) {
87
+ const n = c.blocks.filter((b) => b.type === 'score').length;
88
+ if (n > 0)
89
+ runs.push(n);
90
+ }
91
+ return runs;
92
+ };
93
+ // One system left at the foot of the first page, one carried alone to
94
+ // the last: kept with their neighbours under a minimum of three.
95
+ expect(runsOf(1, 12)[0]).toBe(1);
96
+ expect(runsOf(3, 12)[0]).toBeGreaterThanOrEqual(3);
97
+ expect(runsOf(1, 1).at(-1)).toBe(1);
98
+ expect(runsOf(3, 1).at(-1)).toBeGreaterThanOrEqual(3);
99
+ });
100
+ it('paints the systems as inline SVG in HTML', () => {
101
+ const doc = buildDocument({ markdown: MARKDOWN }, CONFIG);
102
+ const html = renderToHtmlIndexed(doc).html;
103
+ expect(html.split('aria-label="A study in D"').length - 1).toBe(1);
104
+ expect(html).toContain('aria-hidden="true"');
105
+ });
106
+ it('keeps notation fences as code when scoreStyle.enabled is off', () => {
107
+ const doc = buildDocument({ markdown: MARKDOWN }, { ...CONFIG, scoreStyle: { enabled: false } });
108
+ expect(scoreBlocks(doc)).toHaveLength(0);
109
+ });
110
+ });
111
+ describe('score fences in configurations written before them', () => {
112
+ it('keeps a notation fence a listing in a configuration of version 19 whose text has one', async () => {
113
+ const { migrateConfig } = await import('../bundle/configVersion.js');
114
+ expect(migrateConfig({}, 19, { content: '```abc\nX:1\n```\n' }).scoreStyle).toEqual({ enabled: false });
115
+ expect(migrateConfig({}, 19, { content: '```js\nlet a;\n```\n' }).scoreStyle).toBeUndefined();
116
+ expect(migrateConfig({ scoreStyle: { enabled: true } }, 19, { content: '```abc\n```' }).scoreStyle).toEqual({ enabled: true });
117
+ expect(migrateConfig({}, 20, { content: '```abc\nX:1\n```\n' }).scoreStyle).toBeUndefined();
118
+ });
119
+ });
120
+ describe('score resources', () => {
121
+ beforeAll(async () => { await initMusicEngine(); }, 60_000);
122
+ const resource = {
123
+ id: 'ex-ode',
124
+ typeId: 'example',
125
+ kind: 'score',
126
+ caption: 'The opening of the tune',
127
+ createdAt: 0,
128
+ updatedAt: 0,
129
+ score: { format: 'abc', source: 'X:1\nT:Ode to Joy\nM:4/4\nL:1/4\nK:D\nFFGA|AGFE|DDEF|F3/2E/2E2|\n' },
130
+ };
131
+ it('numbers a score resource as an example, in the document language', () => {
132
+ const markdown = '# One\n\nAs :ref{id="ex-ode"} shows:\n\n::resource{id="ex-ode"}\n\nAfter.\n';
133
+ for (const [locale, prefix] of [['en', 'Example'], ['es', 'Ejemplo'], ['de', 'Notenbeispiel'], ['ja', '譜例']]) {
134
+ const doc = buildDocument({ markdown, resources: [resource] }, { ...CONFIG, locale });
135
+ const blocks = doc.pages.flatMap((p) => p.columns.flatMap((c) => c.blocks)).concat(doc.pages.flatMap((p) => p.floats ?? []));
136
+ const rb = blocks.find((b) => b.resourceBlock?.kind === 'score')?.resourceBlock;
137
+ expect(rb, locale).toBeDefined();
138
+ expect(rb.captionPrefix).toBe(prefix);
139
+ expect(rb.number).toMatch(/^1[.-]1$/);
140
+ expect(rb.score.systems.length).toBeGreaterThan(0);
141
+ expect(rb.score.alt).toBe('Ode to Joy');
142
+ expect(rb.bodyRect.height).toBeGreaterThan(20);
143
+ }
144
+ });
145
+ });
146
+ //# sourceMappingURL=musicLayout.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"musicLayout.test.js","sourceRoot":"","sources":["../../src/__tests__/musicLayout.test.ts"],"names":[],"mappings":"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"}
@@ -76,7 +76,7 @@ describe('paragraph styles inside a box (#1119)', () => {
76
76
  });
77
77
  describe('rules 17: pinLegacyBoxParagraphStyles (#1119)', () => {
78
78
  it('comes before the current rule set', () => {
79
- expect(CONFIG_VERSION).toBe(19);
79
+ expect(CONFIG_VERSION).toBe(20);
80
80
  });
81
81
  it('pins a configuration stored under 16 that declares paragraph styles', () => {
82
82
  const migrated = migrateConfig(CONFIG, 16);
@@ -85,7 +85,7 @@ describe('rules 17: pinLegacyBoxParagraphStyles (#1119)', () => {
85
85
  // A current one, one without styles, and one that names the setting
86
86
  // are left as they are.
87
87
  expect(migrateConfig(CONFIG, 17).bodyText?.paragraphStylesInBoxes).toBeUndefined();
88
- expect(migrateConfig(CONFIG, 19)).toBe(CONFIG);
88
+ expect(migrateConfig(CONFIG, 20)).toBe(CONFIG);
89
89
  const plain = { bodyText: { fontSize: pt(10) } };
90
90
  expect(pinLegacyBoxParagraphStyles(plain)).toBe(plain);
91
91
  const named = { ...CONFIG, bodyText: { paragraphStylesInBoxes: 'box' } };
@@ -101,7 +101,7 @@ describe('configurations stored before rules 6 keep the 1.4 box spacing', () =>
101
101
  // It names the box cut (EF-115), so the box gap is the pin that shows.
102
102
  const config = { layout: { layoutType: 'single', boxChildSplitMinLines: 2 } };
103
103
  it('pins a configuration whose book embeds a resource in a box, once', () => {
104
- expect(CONFIG_VERSION).toBe(19);
104
+ expect(CONFIG_VERSION).toBe(20);
105
105
  // Stamped 5 (a 1.5 prerelease): the box gap is the only pin it gets.
106
106
  expect(migrateConfig(config, 5, { content: MD }).layout).toEqual({ layoutType: 'single', boxChildSplitMinLines: 2, inlineResourceGapInBoxes: false });
107
107
  // Unversioned (1.4): both gap pins.
@@ -155,7 +155,7 @@ describe('layout.boxChildSplitMinLines', () => {
155
155
  it('is pinned to 1 for configurations stored before rules 6 whose book holds a box', () => {
156
156
  const cfg = { layout: { layoutType: 'single', inlineResourceGap: 'around', inlineResourceGapInBoxes: true } };
157
157
  const box = twoLineItems(3);
158
- expect(CONFIG_VERSION).toBe(19);
158
+ expect(CONFIG_VERSION).toBe(20);
159
159
  // Unversioned (1.4) and stamped 5 (a 1.5 prerelease): pinned.
160
160
  expect(migrateConfig(cfg, undefined, { content: box }).layout?.boxChildSplitMinLines).toBe(1);
161
161
  expect(migrateConfig(cfg, 5, { content: ['No box here.', box] }).layout?.boxChildSplitMinLines).toBe(1);
@@ -110,7 +110,7 @@ describe('colonListRoom: \'line\' keeps the postext 1.4 room check (EF-110)', ()
110
110
  describe('configurations stored before rules 6 keep the 1.4 colon-list room', () => {
111
111
  const LIST = 'Look for these signs:\n\n- one\n- two';
112
112
  it('pins a configuration older than 6 whose book introduces a list with a colon, once', () => {
113
- expect(CONFIG_VERSION).toBe(19);
113
+ expect(CONFIG_VERSION).toBe(20);
114
114
  const stored = { bodyText: { fontFamily: 'Georgia' } };
115
115
  for (const version of [undefined, 3, 4, 5]) {
116
116
  expect(migrateConfig(stored, version, { content: LIST }).bodyText, `${version}`)
@@ -121,7 +121,7 @@ describe('a break after a compound’s hyphen on both paths (EF-186)', () => {
121
121
  expect(other).toBeGreaterThan(0);
122
122
  });
123
123
  it('is pinned off for configurations stored before rules 8 whose text sets a compound', () => {
124
- expect(CONFIG_VERSION).toBe(19);
124
+ expect(CONFIG_VERSION).toBe(20);
125
125
  const stored = { bodyText: { fontFamily: 'Georgia' } };
126
126
  for (const version of [undefined, 3, 6, 7]) {
127
127
  expect(migrateConfig(stored, version, { content: EN }).bodyText?.breakAfterHyphens, `${version}`).toBe(false);
@@ -303,7 +303,7 @@ describe('breakAfterDashes in the configuration', () => {
303
303
  expect(stripBodyTextDefaults({ breakAfterDashes: false })).toEqual({ breakAfterDashes: false });
304
304
  });
305
305
  it('is pinned off for configurations stored before rules 7 whose text sets a closed dash', () => {
306
- expect(CONFIG_VERSION).toBe(19);
306
+ expect(CONFIG_VERSION).toBe(20);
307
307
  const stored = { bodyText: { fontFamily: 'Georgia' } };
308
308
  for (const version of [undefined, 3, 5, 6]) {
309
309
  expect(migrateConfig(stored, version, { content: ALICE }).bodyText?.breakAfterDashes, `${version}`).toBe(false);
@@ -103,7 +103,7 @@ describe('a paragraph kept with the heading above it splits by the orphan rule t
103
103
  }
104
104
  // Stored under today's rules, it is read as it is.
105
105
  expect(migrateConfig(stored, CONFIG_VERSION, { content: markdown })).toBe(stored);
106
- expect(CONFIG_VERSION).toBe(19);
106
+ expect(CONFIG_VERSION).toBe(20);
107
107
  });
108
108
  it('pins only what the setting changes', () => {
109
109
  const plain = { bodyText: { fontFamily: 'Georgia' } };
@@ -126,7 +126,7 @@ describe('layout.inlineResourceGap and configurations stored before postext 1.5
126
126
  });
127
127
  it('pins a stored configuration whose book embeds a resource, once', () => {
128
128
  const config = { layout: { layoutType: 'single' } };
129
- expect(CONFIG_VERSION).toBe(19);
129
+ expect(CONFIG_VERSION).toBe(20);
130
130
  const pinned = migrateConfig(config, undefined, { content: MD });
131
131
  expect(pinned.layout).toEqual({ layoutType: 'single', inlineResourceGap: 'above' });
132
132
  // Stamped 4 (a 1.5 prerelease): the gap is the only pin it gets.
@@ -240,7 +240,7 @@ describe('paragraphStyles[].snapToGrid (EF-184)', () => {
240
240
  describe('configurations stored before rules 8 keep the 1.4 space under containers', () => {
241
241
  const stored = { bodyText: { fontFamily: 'Georgia' }, paragraphStyles: [{ id: 's' }] };
242
242
  it('pins \'add\' when the book holds a :::paragraphs container', () => {
243
- expect(CONFIG_VERSION).toBe(19);
243
+ expect(CONFIG_VERSION).toBe(20);
244
244
  for (const version of [undefined, 3, 5, 6, 7]) {
245
245
  expect(migrateConfig(stored, version, { content: GROUP_THEN_HEADING }).bodyText?.paragraphContainerSpacing, `${version}`).toBe('add');
246
246
  }
@@ -168,7 +168,7 @@ describe('optimalRagged in the configuration', () => {
168
168
  expect(stripBodyTextDefaults({ optimalRagged: false })).toEqual({ optimalRagged: false });
169
169
  });
170
170
  it('is pinned off for configurations stored before rules 7 that set running text ragged', () => {
171
- expect(CONFIG_VERSION).toBe(19);
171
+ expect(CONFIG_VERSION).toBe(20);
172
172
  const ragged = { bodyText: { textAlign: 'left' } };
173
173
  for (const version of [undefined, 3, 5, 6]) {
174
174
  expect(migrateConfig(ragged, version, { content: 'Text.' }).bodyText, `${version}`).toEqual({ textAlign: 'left', optimalRagged: false, scriptContext: false, shapingLanguage: 'host', breakAfterSlashes: false });
@@ -142,7 +142,7 @@ describe('pinLegacySlashBreaks (#1164)', () => {
142
142
  }
143
143
  });
144
144
  it('pins every version before 19, whatever the chapters hold, and none from 19', () => {
145
- expect(CONFIG_VERSION).toBe(19);
145
+ expect(CONFIG_VERSION).toBe(20);
146
146
  for (const v of [undefined, 1, 8, 12, 15, 16, 17, 18]) {
147
147
  expect(migrateConfig({}, v, { content: 'Words.' }).bodyText?.breakAfterSlashes, String(v)).toBe(false);
148
148
  }
@@ -438,7 +438,7 @@ describe('bodyText.verse and the configurations stored before #620', () => {
438
438
  const PLAIN = ':::verse\nA line\nAnother\n:::';
439
439
  const BAYT = ':::verse\nA || B\n:::';
440
440
  it('pins the 1.22 verse layout when the text holds a poem with no separator', () => {
441
- expect(CONFIG_VERSION).toBe(19);
441
+ expect(CONFIG_VERSION).toBe(20);
442
442
  const stored = { bodyText: { fontFamily: 'Georgia' } };
443
443
  for (const version of [undefined, 3, 7, 8]) {
444
444
  expect(migrateConfig(stored, version, { content: PLAIN }).bodyText?.verse, `${version}`).toEqual({ layout: 'bayt' });
@@ -1 +1 @@
1
- {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/bundle/codec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/bundle/codec.ts"],"names":[],"mappings":"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"}
@@ -3,6 +3,7 @@
3
3
  // written out. `readBundle` turns manifest + files into chapters, config,
4
4
  // resources and file payloads; `planBundle` / `resolveBundleFiles` do the
5
5
  // reverse. Nothing here touches storage.
6
+ import { scoreFormatOfFile } from '../music/types.js';
6
7
  import { cloneDefaultColorPalette, defaultResourceTypes, stripConfigDefaults } from '../defaults/index.js';
7
8
  import { bitmapInfo, bundleStart, chapterFileName, extensionForBitmapFormat, extensionForImageMime, extensionForResource, extensionForVideo, fontsToCustomFonts, isBitmapFile, isBundleManifest, isPdfFile, isSvgFile, mimeForFile, pickBundleStart, pickChapterSpecs, pickLocaleOverrides, resolveBundleConfigLocale, resolveBundleLocale, resourceFromSpec, slugify, svgSize, uniqueSlug, } from './manifest.js';
8
9
  import { CONFIG_VERSION, migrateBundleConfig } from './configVersion.js';
@@ -116,6 +117,15 @@ export async function readBundle(manifest, readFile, options = {}) {
116
117
  }
117
118
  return resourceFromSpec(resolved, size, ids.blob);
118
119
  }
120
+ if (spec.kind === 'score' || (file && scoreFormatOfFile(file))) {
121
+ // A music example (#1172): a notation file's text is the score.
122
+ const bytes = file ? await readFile(file).catch(() => null) : null;
123
+ if (file && !bytes)
124
+ onWarning?.(`${spec.id}: score "${file}" not found, ignored`);
125
+ const source = bytes ? decoder.decode(bytes) : spec.score?.source ?? '';
126
+ const format = spec.score?.format ?? (file ? scoreFormatOfFile(file) : undefined) ?? 'abc';
127
+ return resourceFromSpec({ ...spec, kind: 'score', file: undefined, score: { ...spec.score, format, source } }, undefined, ids.blob);
128
+ }
119
129
  if (!file)
120
130
  return resourceFromSpec(spec, undefined, ids.blob);
121
131
  const mime = mimeForFile(file);