@barmark/render

中文文档
0.16.2发布于 2026/11/08MITTypeScriptES Module构建来源已验证近 30 天下载 4803

Render barmark chord charts as a clean, accessible bar grid: HTML with Declarative Shadow DOM, or the web component.

原始使用文档
文档目录11 节
  1. As HTML (no browser JavaScript needed)
  2. As a web component
  3. Options and attributes
  4. Numerals
  5. Spoken names
  6. Styling on purpose
  7. Light, dark and print
  8. Accessibility
  9. The font
  10. What it draws
  11. License

@barmark/render

Renders barmark chord charts as a clean, evenly spaced bar grid that looks the same on any page, follows light and dark mode, scales with the reader's text size, and reads to a screen reader as music.

npm install @barmark/render

As HTML (no browser JavaScript needed)

import { renderChart } from "@barmark/render";

const html = renderChart(chartText, { fontUrl: "/fonts/Edwin-Roman.otf" });

renderChart returns a <barmark-chart> element holding a declarative shadow root: put it in any page, server-rendered or static, and it shows the chart with no script. The shadow root keeps the page's CSS out, so a blog's resets and fonts cannot rearrange the bars. Browsers attach a declarative shadow root only while parsing HTML: to insert the markup from script, use setHTMLUnsafe (or the element below), not innerHTML.

renderChartUnwrapped(text, options) returns the same markup without the shadow root (classes prefixed bm-), for pages that include stylesheet themselves.

As a web component

<script type="module">import "@barmark/render/element";</script>

<barmark-chart src="/charts/peaceful-dreams.chart.md"></barmark-chart>

<barmark-chart theme="dark" rehearsal-letters>
    <script type="text/barmark">
        ## Verse
        | D | A | Bm | G |
    </script>
</barmark-chart>

The element renders from its text property, its src URL, or a child <script type="text/barmark"> (indentation is removed), and renders again whenever one changes; it fetches a src once, and renders once however many properties and attributes change together. A chart rendered on the server by renderChart keeps its music until it has a source of its own, and still follows theme, bar-numbers and wrap; a change to numerals, rehearsal-letters or show-part needs the chart's text, so it waits for a source.

For a live editor, set text:

const chart = document.querySelector("barmark-chart");
editor.addEventListener("input", () => { chart.text = editor.value; });

While text is a string it wins over src and the script child, and no fetch happens; set it to null to go back to them. Any string is safe: the chart escapes it, and problems show as diagnostics, never errors. There is no text attribute: chart text belongs in the property or the script child.

The element registers the font itself, from the fonts/ folder beside its own module. If your bundler moves that file, register it yourself before the element loads, with <style data-barmark-font> holding fontFaceCss(yourUrl); the element then leaves it alone.

Options and attributes

renderChart optionElement attribute (property)Default
themetheme (theme)"auto""auto" follows the system; "light" or "dark" force one
barNumbersbar-numbers="off" (barNumbers)truebar numbers at the start of each row
rehearsalLettersrehearsal-letters (rehearsalLetters)falseboxed A, B, C… on each section as played
numeralsnumerals (numerals)none"nashville" (6m⁷) or "roman" (vi⁷): each chord as its degree in its bar's key
wrapwrap="off" (wrap)truewrap a section's rows when it is wider than the chart's box; off, rows keep their columns and the chart overflows, for its page to scroll
partshow-part (showPart)nonedraw only the part with this label, as one player reads it: tutti bars, its own bars, and "tacet" where it rests. The attribute isn't part, which HTML keeps for ::part() styling
diagnosticsfalselist the chart's errors and warnings below it
fontUrlnoneemit Edwin's @font-face rule before the chart
(the text argument)(text)nullthe chart to draw; wins over src and the script child

Numerals

With numerals, each chord shows as its degree in the key its bar is played in, so a modulation renumbers from its next bar. Degrees count from the key's tonic against the major scale, in every mode: in key: Am, Am is 1m and C is ♭3. Nashville keeps the chord's quality and superscript after the number (Bm7 in D is 6m⁷, D/F♯ is 1/3); Roman shows minor and diminished in lower case (ii, vii°, ♭VII). Both raise a power chord's 5 into the superscript (D5 in D is 1⁵ and I⁵, never 15). A bar with no key, note sets, N.C., ? and -- look as they always do, and a screen reader hears both: "bar 5: five, A seven". Numbered chords carry data-numeral. It's a view: the music and bar numbers don't change.

Spoken names

speakChord(record, key?) gives a chord the name a screen reader hears in the chart, for other tools that want to say a chord aloud:

import { parseChord } from "barmark";
import { speakChord } from "@barmark/render";

const r = parseChord("Cø");
if (r.ok) speakChord(r.value); // "C minor seven flat five"

With a key, it speaks the degree too, as the numerals view does.

Styling on purpose

Set these custom properties on the element or anything above it:

PropertyWhat it sets
--barmark-fontthe chords' typeface
--barmark-text-fontlyrics and ### note lines (default Georgia)
--barmark-label-fontthe meta line, mid-chart changes, headings and diagnostics (default the system sans)
--barmark-sizethe chord size everything scales from (default 1rem)
--barmark-inkchords and text
--barmark-paperthe background
--barmark-mutedholds, bar numbers, braces, meta lines
--barmark-rulebar lines
--barmark-accenterrors
--barmark-directivemid-chart changes (default the muted colour)
--barmark-note### note lines (default the ink colour)
--barmark-lyricssyllables under a voice line and in lyric rows (default the ink colour)
barmark-chart {
    --barmark-size: 0.9rem;
    --barmark-paper: transparent;
    --barmark-text-font: "Noto Serif", Georgia, serif;
}
barmark-chart::part(heading) {
    color: teal;
}

::part() names: title, meta, heading, bar, chord, text, bar-number, rehearsal, lyrics (each verse's line of words, inside its bar). These, the custom properties and the attributes are the public surface: changing them is a breaking change.

Light, dark and print

Both palettes meet WCAG AA contrast (4.5:1 for text). theme="auto" follows prefers-color-scheme; a page with its own dark-mode switch sets theme or the colour properties. Printing always uses the light palette, and Windows High Contrast keeps bar lines and marks visible.

Accessibility

  • Everything is sized in em from --barmark-size, so text size and zoom scale the chart; a section too wide for its container wraps its rows instead of scrolling sideways.
  • Every bar has a spoken name built from the parsed chart: "bar 9: A seven sus four, hold", "triplet: D, E, F sharp minor", "note E", "C over E". Sections are labelled by their headings, and repeats are spoken ("play 2 times").

The font

Edwin, MuseScore's text font for music, ships unmodified in @barmark/render/fonts/Edwin-Roman.otf with its SIL Open Font License (fonts/OFL.txt). It is registered under the family name "barmark Edwin". Serve the file and pass its URL as fontUrl, or call fontFaceCss(url) once per page; without it the chart uses Georgia or another serif.

What it draws

Bar numbers sit in a gutter at the left edge; section headings, lyrics, note lines and mid-chart changes start at the first bar line. Chords start at the left of their share of the bar. A change written mid-chart names itself: time: 3/4, tempo: 120 draws as "→ Time 3/4 · Tempo ♩ = 120". At the default size chords are 16px and no label is under 12px.

Chords appear in their canonical form whatever the author typed (Cø shows as Cm⁷(♭5)). % is drawn as the bar it copies; a replayed section is drawn in full, and its own lyrics replace the written section's. Bar numbers count the bars as written, each once, as a band counts them: a repeat, an ending, a jump or a replay doesn't move them, so a replayed section shows the numbers it was written with. A line with an error shows as written, underlined, with its message. layoutChart(text) returns all of this as data, if you want to draw it yourself, and typesetChord(parts) with glyphs gives a chord's pieces as the page sets them (root and quality, the raised extension, the bass after a slash, ♯ and ♭), and typesetNumeral(parts, key, style) its Nashville or Roman numeral, so a PDF or canvas drawer matches it. A section block's bars counts its widest row's bars (0 when it has none), where columns also counts its fermata, direction and rehearsal cells.

A chart of several parts (barmark's grammar 7.4) draws each system as stacked rows, one per part in score order, with the part's label in the gutter and one bar number on the top row. A part tacet in a system gets an empty row that says "tacet" in its first bar, so every system keeps its shape; a tutti line is one row. The header lists the parts' names, and each part row is announced by name to a screen reader. On a screen too narrow for a section, its rows wrap one by one, as any row does.

A voice line (barmark's grammar 4.3 and 7.7: the line a part sings on, such as Vox.Mel under a lead sheet's bare Vox chord line) draws each note as its pitch name (every note of a set, without octaves) and under it, in italics, the syllable each verse sings there: verse 1 from the syllables on the notes, then each lyrics N: row, numbered "1.", "2." left of the first bar when there are several. A hyphen follows a syllable whose word goes on, and a held syllable (:/) draws an extender line. The notes are spaced by beat, each as wide as the widest note or syllable. Verses come from the parser as played, placed under the written bars: a repeat's verse 2 is drawn under the bars it is sung on, and a replay draws its own words. A voice line with no words draws as any part line does. A lyric row on no melody (the chart's words, or a singer who writes no notes there) draws its words inside the bars it covers, a line per verse spaced by beat, so on a narrow screen they wrap with their bars; under a system they go in its last row. A screen reader hears the words after each bar's notes: "bar 2: note G four, hold, …, verse 1 “maz-ing”, verse 2 “grace that”".

License

MIT. Edwin is © MuseScore Limited, under the SIL Open Font License 1.1.

版本与发布记录

@barmark/render 共发布 26 个版本,首次发布于 2026/11/01;过去 12 个月发布了 26 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
0.16.2latest2026/11/08今天
0.16.12026/11/08今天
0.16.02026/11/07今天
0.15.12026/11/07今天
0.15.02026/11/07今天
0.14.02026/11/052 天前

关于 @barmark/render 的常见问题

@barmark/render 是什么?

Render barmark chord charts as a clean, accessible bar grid: HTML with Declarative Shadow DOM, or the web component.

如何安装 @barmark/render?

在项目目录运行 npm install @barmark/render,或使用 pnpm add / yarn add / bun add。

@barmark/render 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@barmark/render 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@barmark/render 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@barmark/render 可以商用吗?

@barmark/render 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@barmark/render 的下载量有多少?

根据 npm 官方下载统计,@barmark/render 在 2026/10/08 – 2026/11/06 这 30 天内被下载 4,803 次,日均约 160 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@barmark/render 还在维护吗?

最新版本 0.16.2 发布于 2026/11/08(今天);至今共发布 26 个版本,其中过去 12 个月发布了 26 个;首次发布于 2026/11/01。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。