Skip to content

Commit e298f59

Browse files
authored
Preparations for LDML 48 release (#1096)
* Use normal spaces for PDI name * Update Acknowledgments section, fixing trailing whitespaces * Define _numeric operand_ as a term * Make section names unique * Add header & footer from unicode-org/cldr@5565730 Here, specifically: https://github.com/unicode-org/cldr/blob/556573054c05e2c352229ac0ec93e7b3d3960432/docs/ldml/tr35-messageFormat.md * Add publication script & instructions * Drop docs/checklist-for-pourover-creation.md * Drop version specifier from semantic skeletons link * git submodule add -b main git@github.com:unicode-org/cldr.git publish/cldr * Rewrite publish scripts in Node.js, use tr-archive tool * ci: Add GitHub Pages deployment script * ci: Add paths filter * ci: Add build_spec action
1 parent 65e432f commit e298f59

19 files changed

+406
-141
lines changed

.github/workflows/build_spec.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Build spec as HTML
2+
3+
on:
4+
pull_request:
5+
paths:
6+
- 'publish/**'
7+
- 'spec/**'
8+
workflow_dispatch:
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
with:
16+
submodules: true
17+
- run: make dist/index.html
18+
working-directory: ./publish

.github/workflows/deploy_pages.yml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
name: Deploy spec to GitHub Pages
2+
3+
permissions:
4+
contents: read
5+
pages: write
6+
id-token: write
7+
8+
on:
9+
push:
10+
branches: [main]
11+
paths:
12+
- 'publish/**'
13+
- 'spec/**'
14+
workflow_dispatch:
15+
16+
concurrency:
17+
group: pages
18+
cancel-in-progress: false
19+
20+
jobs:
21+
deploy:
22+
environment:
23+
name: github-pages
24+
url: ${{ steps.deployment.outputs.page_url }}
25+
runs-on: ubuntu-latest
26+
steps:
27+
- uses: actions/checkout@v4
28+
with:
29+
submodules: true
30+
- uses: actions/configure-pages@v5
31+
- run: make
32+
working-directory: ./publish
33+
- uses: actions/upload-pages-artifact@v3
34+
with:
35+
path: publish/dist/
36+
- uses: actions/deploy-pages@v4
37+
id: deployment

.gitmodules

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[submodule "publish/cldr"]
2+
path = publish/cldr
3+
url = git@github.com:unicode-org/cldr.git
4+
branch = main

docs/checklist-for-pourover-creation.md

Lines changed: 0 additions & 76 deletions
This file was deleted.

publish/.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
/dist/
2+
/gtag.html
3+
/header.html
4+
/reports-v2.css

publish/Makefile

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
ldml = cldr/docs/ldml
2+
mf-target = $(ldml)/tr35-messageFormat.md
3+
tr-archive = cldr/tools/scripts/tr-archive
4+
5+
all: dist
6+
.PHONY: prepare dist clean
7+
prepare: cldr/.git $(tr-archive)/node_modules/.package-lock.json header.md
8+
dist: dist/index.html dist/css/reports-v2.css dist/css/tr35.css dist/js/anchor.min.js dist/js/tr35search.js
9+
clean:
10+
rm -r dist gtag.html header.html
11+
cd cldr && git restore .
12+
13+
dist/index.html: $(mf-target) fix-archive.mjs gtag.html header.html
14+
@mkdir -p dist
15+
cp $(mf-target) ./dist/index.md
16+
node $(tr-archive)/archive.js
17+
node fix-archive.mjs
18+
rm ./dist/index.md
19+
20+
$(mf-target): cldr/.git $(tr-archive)/node_modules/.package-lock.json collect.mjs check-toc.mjs $(shell find ../spec -type f) | header.md
21+
node collect.mjs > $(mf-target)
22+
cd $(tr-archive) && node fix-tocs.js
23+
node check-toc.mjs < $(mf-target)
24+
25+
cldr/.git:
26+
git submodule update --init --remote --rebase cldr
27+
$(tr-archive)/node_modules/.package-lock.json: $(tr-archive)/package-lock.json
28+
cd $(tr-archive) && npm ci
29+
30+
header.md: update-header-footer.mjs
31+
node update-header-footer.mjs < $(mf-target)
32+
33+
dist/css/reports-v2.css:
34+
@mkdir -p dist/css
35+
cd dist/css && curl -O 'https://www.unicode.org/reports/reports-v2.css'
36+
dist/css/tr35.css: $(tr-archive)/assets/css/tr35.css
37+
@mkdir -p dist/css
38+
cp $< $@
39+
dist/js/anchor.min.js: $(tr-archive)/node_modules/.package-lock.json $(tr-archive)/node_modules/anchor-js/anchor.min.js
40+
@mkdir -p dist/js
41+
cp $< $@
42+
dist/js/tr35search.js: $(tr-archive)/assets/js/tr35search.js
43+
@mkdir -p dist/js
44+
cp $< $@
45+
46+
gtag.html: $(tr-archive)/gtag.html
47+
ln -s $<
48+
header.html: $(tr-archive)/header.html
49+
ln -s $<

publish/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Tools for publication
2+
3+
The contents of [Unicode MessageFormat Standard](./spec/) are published
4+
as a part of [Unicode Technical Standard #35](https://unicode.org/reports/tr35/).
5+
6+
The contents of this directory are used to collect the spec parts into a single file for publication,
7+
and to fix internal and external links.
8+
9+
The scripts require Node.js 20 or later, and expect to be run in a POSIX environment.
10+
11+
To build a spec update:
12+
13+
1. Use `make prepare` to:
14+
1. Update the CLDR submodule
15+
1. Install `tr-archive` tool dependencies
16+
1. Update `header.md` and `footer.md`
17+
1. Apply any updates needed in `header.md`.
18+
1. Update `collect.mjs` as required for any structural changes or new links.
19+
1. Use `make dist` to:
20+
1. Collect the current spec parts into `cldr/docs/ldml/tr35-messageFormat.md`.
21+
1. Fix link targets.
22+
1. Add the Table of Contents.
23+
1. Check the Table of Contents for duplicate section title links.
24+
1. Build a local copy of the rendered HTML at `dist/index.html`.
25+
1. Inspect the results; `git diff` in the `cldr/` submodule may be useful.
26+
1. Apply fixes and repeat as necessary until the output is clean.

publish/check-toc.mjs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env node
2+
3+
import { readFileSync } from "node:fs";
4+
import { exit } from "node:process";
5+
6+
const lines = readFileSync(0, "utf8").split("\n"); // 0: stdin
7+
8+
let i = lines.findIndex((line) => line.startsWith('## <a name="Contents"'));
9+
if (i < 0) throw new Error("ToC start not found");
10+
while (lines[++i] === "");
11+
12+
/** @type {Record<string, string[]>} */
13+
const links = {};
14+
let match;
15+
while ((match = /\(#(.+?)\)$/.exec(lines[i]))) {
16+
const target = match[1];
17+
if (target in links) links[target].push(i);
18+
else links[target] = [i];
19+
++i;
20+
}
21+
22+
const n = Object.keys(links).length;
23+
if (n < 20) throw new Error(`ToC too small: ${n} entries`);
24+
25+
let ok = true;
26+
for (const a of Object.values(links)) {
27+
if (a.length > 1) {
28+
if (ok) console.error("Duplicate ToC links:");
29+
for (const i of a) console.error(`\tline ${i + 1}: ${lines[i]}`);
30+
ok = false;
31+
}
32+
}
33+
exit(ok ? 0 : 1);

publish/cldr

Submodule cldr added at 5565730

publish/collect.mjs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/usr/bin/env node
2+
3+
import { readFileSync } from "node:fs";
4+
5+
// order matters here
6+
const parts = {
7+
header: "header.md",
8+
intro: "../spec/intro.md",
9+
syntax: "../spec/syntax.md",
10+
abnf: "../spec/message.abnf",
11+
formatting: "../spec/formatting.md",
12+
errors: "../spec/errors.md",
13+
functions: "../spec/functions/README.md",
14+
stringFunctions: "../spec/functions/string.md",
15+
numberFunctions: "../spec/functions/number.md",
16+
datetimeFunctions: "../spec/functions/datetime.md",
17+
uNamespace: "../spec/u-namespace.md",
18+
datamodel: "../spec/data-model/README.md",
19+
json: "../spec/data-model/message.json",
20+
appendices: "../spec/appendices.md",
21+
footer: "footer.md",
22+
};
23+
24+
for (const [name, path] of Object.entries(parts)) {
25+
parts[name] = readFileSync(path, "utf8").trim();
26+
}
27+
28+
parts.abnf = "## message.abnf\n\n```abnf\n" + parts.abnf + "\n```";
29+
parts.json = "## message.json\n\n```json\n" + parts.json + "\n```";
30+
31+
// Strip title + table of contents
32+
const introStart = parts.intro.indexOf("## Introduction");
33+
if (introStart < 0) throw new Error("Intro start not found");
34+
parts.intro = parts.intro.substring(introStart);
35+
36+
parts.functions = parts.functions.replace(
37+
/^#+ Table of Contents\n\n(.*?)\n\n/ms,
38+
""
39+
);
40+
41+
const result = Object.values(parts)
42+
.join("\n\n")
43+
.replace(/ +$/g, "")
44+
.replace(/\n{3,}/g, "\n\n")
45+
.replace(/\[(.+?)\]\((.+?)\)/g, fixLink);
46+
console.log(result);
47+
48+
/**
49+
* @param {string} link
50+
* @param {string} label
51+
* @param {string} target
52+
*/
53+
function fixLink(link, label, target) {
54+
if (target === "../docs/why_mf_next.md") return label;
55+
if (target.endsWith("message.abnf")) return `[${label}](#messageabnf)`;
56+
if (target.endsWith("message.abnf")) return `[${label}](#messageabnf)`;
57+
if (target.endsWith("syntax.md")) return `[${label}](#syntax)`;
58+
const local = /^(?:\.\/)?[\w./]+\.md(#.+)/.exec(target);
59+
if (local) return `[${label}](${local[1]})`;
60+
const tr35 = /\/(tr35(?:-\w+)?)\.html(#.+)?$/.exec(target);
61+
if (tr35) return `[${label}](${tr35[1]}.md${tr35[2]})`;
62+
return link;
63+
}

0 commit comments

Comments
 (0)