@barmark/render 0.9.0 → 0.10.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/CHANGELOG.md CHANGED
@@ -6,6 +6,25 @@ package uses [semantic versioning](https://semver.org/).
6
6
 
7
7
  ## [Unreleased]
8
8
 
9
+ ## [0.10.0] - 2026-11-03
10
+
11
+ ### Added
12
+
13
+ - **The part** a chart names (`part: Electric Guitar 1`) leads the
14
+ header line: "Electric Guitar 1 · G major". The model gains `part`.
15
+
16
+ ## [0.9.1] - 2026-11-03
17
+
18
+ ### Fixed
19
+
20
+ - **Bar numbers count the bars as written** (issue #92), each once, as a
21
+ band counts them and as `PlayedBar.written` gives them. Before, the
22
+ margin counted played bars, so a second ending or anything after a
23
+ repeat or a jump numbered past the printed score. A replayed section
24
+ now shows the numbers it was written with; the coda after a
25
+ `D.S. al Coda`, and bars after an open repeat, are numbered instead
26
+ of left blank. Screen readers hear the same numbers.
27
+
9
28
  ## [0.9.0] - 2026-11-03
10
29
 
11
30
  ### Added
@@ -256,7 +275,9 @@ that needs no script or as the `<barmark-chart>` web component. Requires
256
275
  zoom without sideways scrolling, the element renders and re-renders, and
257
276
  a screen reader hears "bar 9: D". Run them with `bun run test:browser`.
258
277
 
259
- [Unreleased]: https://github.com/kevinpeckham/barmark/compare/render-v0.9.0...HEAD
278
+ [Unreleased]: https://github.com/kevinpeckham/barmark/compare/render-v0.10.0...HEAD
279
+ [0.10.0]: https://github.com/kevinpeckham/barmark/compare/render-v0.9.1...render-v0.10.0
280
+ [0.9.1]: https://github.com/kevinpeckham/barmark/compare/render-v0.9.0...render-v0.9.1
260
281
  [0.9.0]: https://github.com/kevinpeckham/barmark/compare/render-v0.8.0...render-v0.9.0
261
282
  [0.8.0]: https://github.com/kevinpeckham/barmark/compare/render-v0.7.3...render-v0.8.0
262
283
  [0.7.3]: https://github.com/kevinpeckham/barmark/compare/render-v0.7.2...render-v0.7.3
package/README.md CHANGED
@@ -178,8 +178,10 @@ At the default size chords are 16px and no label is under 12px.
178
178
 
179
179
  Chords appear in their canonical form whatever the author typed (`Cø`
180
180
  shows as Cm⁷(♭5)). `%` is drawn as the bar it copies; a replayed section
181
- is drawn in full with its own bar numbers, and its own lyrics replace the
182
- written section's. A line with an error shows as written, underlined,
181
+ is drawn in full, and its own lyrics replace the written section's. Bar
182
+ numbers count the bars as written, each once, as a band counts them: a
183
+ repeat, an ending, a jump or a replay doesn't move them, so a replayed
184
+ section shows the numbers it was written with. A line with an error shows as written, underlined,
183
185
  with its message. `layoutChart(text)` returns all of this as data, if
184
186
  you want to draw it yourself.
185
187
 
package/dist/html.js CHANGED
@@ -48,7 +48,9 @@ function headerHtml(model) {
48
48
  const title = model.title
49
49
  ? `<h2 class="bm-title" part="title">${escapeHtml(model.title)}</h2>`
50
50
  : "";
51
- const meta = metaText(model.header);
51
+ const meta = [model.part ? escapeHtml(model.part.name) : "", metaText(model.header)]
52
+ .filter(Boolean)
53
+ .join(" · ");
52
54
  if (!title && !meta)
53
55
  return "";
54
56
  return `<header class="bm-header">${title}${meta ? `<p class="bm-meta" part="meta">${meta}</p>` : ""}</header>`;
package/dist/model.js CHANGED
@@ -13,13 +13,12 @@ export function layoutChart(text, options = {}) {
13
13
  parse,
14
14
  source: text.split(/\r?\n/),
15
15
  errors: errorsByLine(parse),
16
- lastKnownBar: lastKnownBar(parse.events),
17
16
  written: new Map(groups.flatMap((g) => (g.heading ? [[g.heading.line, g]] : []))),
18
17
  };
19
18
  const blocks = groups.map((g) => layoutGroup(g, ctx));
20
19
  if (options.rehearsalLetters)
21
20
  letterBlocks(blocks);
22
- return { title: parse.title, header, blocks, diagnostics: parse.diagnostics };
21
+ return { title: parse.title, part: parse.part, header, blocks, diagnostics: parse.diagnostics };
23
22
  }
24
23
  /** Rehearsal letters mark position: every section occurrence, and leading bars, in play order. */
25
24
  function letterBlocks(blocks) {
@@ -44,34 +43,13 @@ function errorsByLine(parse) {
44
43
  }
45
44
  return errors;
46
45
  }
47
- /** The count of bars up to the end of the first open repeat (all of them if there is none). */
48
- function lastKnownBar(events) {
49
- let count = 0;
50
- const countBars = (es) => {
51
- for (const e of es) {
52
- if (e.kind === "bar")
53
- count++;
54
- else if (e.kind === "open")
55
- countBars(e.events);
56
- }
57
- };
58
- for (const e of events) {
59
- if (e.kind === "open") {
60
- countBars(e.events);
61
- return count;
62
- }
63
- if (e.kind === "bar")
64
- count++;
65
- }
66
- return Number.POSITIVE_INFINITY;
67
- }
68
46
  /** The title line, and the directives before any other content, form the header. */
69
47
  function splitHeader(lines) {
70
48
  const header = {};
71
49
  let i = 0;
72
50
  for (; i < lines.length; i++) {
73
51
  const l = lines[i];
74
- if (l?.kind === "title")
52
+ if (l?.kind === "title" || l?.kind === "part")
75
53
  continue;
76
54
  if (l?.kind !== "directive")
77
55
  break;
@@ -80,7 +58,7 @@ function splitHeader(lines) {
80
58
  delete header.swingPercent;
81
59
  Object.assign(header, l.set);
82
60
  }
83
- return { header, body: lines.slice(i).filter((l) => l.kind !== "title") };
61
+ return { header, body: lines.slice(i).filter((l) => l.kind !== "title" && l.kind !== "part") };
84
62
  }
85
63
  function groupLines(lines) {
86
64
  const groups = [];
@@ -226,11 +204,11 @@ function layoutRow(l, played, previous, ctx) {
226
204
  prev = model;
227
205
  cells.push(model);
228
206
  }
229
- const firstIndex = played[0]?.index;
230
207
  return {
231
208
  kind: "row",
232
209
  line: l.line,
233
- barNumber: firstIndex !== undefined && firstIndex <= ctx.lastKnownBar ? firstIndex : null,
210
+ // Numbered as written, as a band counts (issue #92): repeats, endings, jumps and replays don't move it.
211
+ barNumber: (played[0] ?? written[0])?.written ?? null,
234
212
  opens: l.opens,
235
213
  closes: l.closes,
236
214
  repeat: l.repeat,
package/dist/types.d.ts CHANGED
@@ -1,10 +1,12 @@
1
- import type { ChartDiagnostic, Direction, Directives, Key, Meter, Repeat, Slot, Words } from "barmark";
1
+ import type { ChartDiagnostic, Direction, Directives, Key, Meter, Part, Repeat, Slot, Words } from "barmark";
2
2
  export type LayoutOptions = {
3
3
  rehearsalLetters?: boolean;
4
4
  };
5
5
  /** What to draw, with every musical decision already made. */
6
6
  export type ChartModel = {
7
7
  title: string | null;
8
+ /** What `part:` names; null when the chart names none. */
9
+ part: Part | null;
8
10
  /** Directives before the first heading, bar line or text line. */
9
11
  header: Directives;
10
12
  blocks: SectionBlock[];
@@ -25,7 +27,7 @@ export type SectionBlock = {
25
27
  export type BlockItem = {
26
28
  kind: "row";
27
29
  line: number;
28
- /** The play-order number of the row's first bar on its first pass. */
30
+ /** The written number of the row's first bar (`PlayedBar.written`); a replay shows its section's numbers. Null for a row with no bar. */
29
31
  barNumber: number | null;
30
32
  opens: boolean;
31
33
  closes: boolean;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@barmark/render",
3
- "version": "0.9.0",
3
+ "version": "0.10.0",
4
4
  "description": "Render barmark chord charts as a clean, accessible bar grid: HTML with Declarative Shadow DOM, or the <barmark-chart> web component.",
5
5
  "type": "module",
6
6
  "exports": {
@@ -47,7 +47,7 @@
47
47
  "url": "https://github.com/kevinpeckham/barmark/issues"
48
48
  },
49
49
  "dependencies": {
50
- "barmark": "^0.12.0"
50
+ "barmark": "^0.13.0"
51
51
  },
52
52
  "scripts": {
53
53
  "build": "rm -rf dist && tsc -p tsconfig.build.json",