clone

a personal forge on plain git: static pages, stacked-diff reviews, signed local ci, repo sites and releases

Keep inline code whole at its hyphens

cat committed 9540f59
Prose broke inline code after a hyphen, so lib/text-widths.sh could end
a line at lib/text- and start the next at widths.sh. A hyphenated word
in inline code is kept whole now, and a path may break after its slashes
instead; the text copies as written.
commit
9540f59d9d2839a93825ba52a3f2d414e4b84a63
parent
7d3519b8032a2663d1f4400b4d53b1fb21ae13cb
author
cat <admin@dev.site>
ci
✓ passed in 77s, signed by cat
kind
fix risk score 1.5 of 3, Jev's estimate
review
#16 Panels with a head strip for content, and an even row hover
ci attestation
forge-attestation 1
type ci
commit 9540f59d9d2839a93825ba52a3f2d414e4b84a63
tree 10a3ce847ff33e186a2f5df30559abf32673038d
script .forge/ci aa9f4eac26627c6559e68cd4b5e5e76afb8e65e8
result pass
exit 0
started 2026-10-19T03:56:13Z
duration 77s
runner (not shown here; refs/notes/ci has it)
system Darwin 25.5.0 arm64
env host
log sha256:873eed4e27dd662e717c91519b648fcee08c67ef52aca9544cd3af200d2d2be5 265 lines
|pushed wip/i18n
|4b1d969 running .forge/ci: greet.sh: say what it is
|  | sh: /bin/sh
|  | ok   greet
|4b1d969 pass in 0s, signed
|pushed main
|remote: review #4: /dami/greet/reviews/4/
|pushed wip/i18n
|b0b7f93 running .forge/ci: wave at the world
|  | sh: /bin/sh
|  | FAIL greet : got 'hello, world o/', want 'hello, world'
|b0b7f93 fail in 0s, signed
|forge: 1 commit(s) did not pass
|remote: review #6: /dami/greet/reviews/6/
|pushed ana/wave
|670c0e2 running .forge/ci: update the test for the wave
|  | sh: /bin/sh
|  | ok   greet
|670c0e2 pass in 0s, signed
|remote: review #6: /dami/greet/reviews/6/
|pushed ana/wave
|warning: You appear to have cloned an empty repository.
|site home: deployed 1472c49 -> /sites/ana/dotfiles/home/
|created ana/notes
|remote: review #1: /ana/notes/reviews/1/
|pushed ana/todo
|landing #1 A todo list: ana/todo -> main
|02bf6fd running .forge/ci: web, server and Python versions of greet
|  | sh: /bin/sh
|  | ok   greet
|02bf6fd pass in 0s, signed
|pushed main
|e2541ed running .forge/ci: messages: notes for the later regions
|  | sh: /bin/sh
|  | ok   greet
|e2541ed pass in 0s, signed
|remote: review #7: /dami/greet/reviews/7/
|pushed dami/regions
|created dami/forge
|warning: You appear to have cloned an empty repository.
|site guide: mkdir -p guide/fonts && cp site/assets/fonts/*.woff2 guide/fonts/
|site guide: deployed 1c50760 -> /sites/dami/forge/guide/
|(node:33041) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time
|(Use `node --trace-warnings ...` to show where the warning was created)
|built ana/dotfiles in 0s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.hU9sif/wt/demo/root/.forge/www
|(node:33170) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time
|(Use `node --trace-warnings ...` to show where the warning was created)
|built ana/notes in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.hU9sif/wt/demo/root/.forge/www
|(node:33311) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time
|(Use `node --trace-warnings ...` to show where the warning was created)
|built dami/forge in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.hU9sif/wt/demo/root/.forge/www
|(node:33447) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time
|(Use `node --trace-warnings ...` to show where the warning was created)
|built dami/greet in 1s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.hU9sif/wt/demo/root/.forge/www
|(node:34142) ExperimentalWarning: stripTypeScriptTypes is an experimental feature and might change at any time
|(Use `node --trace-warnings ...` to show where the warning was created)
|built - in 0s -> /var/folders/b4/mv8w4c8j0zj0_mldppxdbdw00000gn/T/forge-ci.hU9sif/wt/demo/root/.forge/www
|234 of 234 pages render the same without 11ty
|guide: 8 files, links ok
|ok

Signature: good, cat

3 files changed, +30 -2
Mlib/markdown.ts15+++++++++++++--
Msite/assets/style.css3+++
Atest/scenarios/markdown-inline-code.sh14++++++++++++++
M lib/markdown.ts +13 -2
@@ -33,6 +33,16 @@ md.renderer.rules.fence = (tokens, idx, options, env: Env, self) => {
3333 return `<div>${env.token}:${env.diagrams.length - 1}</div>\n`;3434 };3535 36+// Inline code never breaks at a hyphen (lib/text-widths.sh isn't37+// lib/text- and widths.sh): a word with one is kept whole (.nobr in38+// style.css), and a path may break after its slashes instead. The text is39+// unchanged, for copying.40+md.renderer.rules.code_inline = (tokens, idx, _options, _env, self) => {41+ const t = tokens[idx];42+ const word = (w: string): string => w.split('/').map((part) => (part.includes('-') ? `<span class="nobr">${md.utils.escapeHtml(part)}</span>` : md.utils.escapeHtml(part))).join('/<wbr>');43+ return `<code${self.renderAttrs(t)}>${t.content.split(/(\s+)/).map((w, i) => (i % 2 ? md.utils.escapeHtml(w) : word(w))).join('')}</code>`;44+};45+3646 const isRelative = (u: string | null | undefined): u is string => !!u && !/^([a-z][a-z0-9+.-]*:|\/\/|#|\/)/i.test(u);3747 3848 // GitHub-style heading ids, so README links to #some-section resolve.
@@ -57,7 +67,7 @@ const ALLOWED = {
5767 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'ul', 'ol', 'li', 'dl', 'dt', 'dd', 'blockquote',5868 'pre', 'code', 'kbd', 'samp', 'var', 'sub', 'sup', 'b', 'i', 'em', 'strong', 's', 'del', 'ins', 'mark', 'small',5969 'table', 'thead', 'tbody', 'tfoot', 'tr', 'th', 'td', 'caption', 'colgroup', 'col', 'figure', 'figcaption',60- 'input',70+ 'input', 'wbr',6171 ],6272 allowedAttributes: {6373 '*': ['align', 'id', 'title', 'class', 'dir', 'lang'],
@@ -71,9 +81,10 @@ const ALLOWED = {
7181 input: ['type', 'checked', 'disabled'],7282 },7383 // highlight.js tokens: "hljs-title" plus sub-scopes like "function_".74- allowedClasses: { '*': [/^language-/], span: [/^hljs-/, /^[a-z]+_+$/] },84+ allowedClasses: { '*': [/^language-/], span: [/^hljs-/, /^[a-z]+_+$/, 'nobr'] },7585 allowedSchemes: ['http', 'https', 'mailto'],7686 allowProtocolRelative: false,87+ selfClosing: [...sanitize.defaults.selfClosing, 'wbr'],7788 };7889 7990 export function renderMarkdown(src: string, { link = (u) => u, image = (u) => u }: LinkResolver = {}): string {
M site/assets/style.css +3 -0
A test/scenarios/markdown-inline-code.sh +14 -0