diff --git a/README.md b/README.md
index 84347a7..1ff556b 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ products store as ADF.
* `commonMarkToAdf` — reads strict CommonMark only. Extensions like tables or `~~` come out as plain text.
* `adfToLosslessMarkdown` — ADF to adf-codec's own markdown flavour, which spells ADF's special nodes (panels, mentions, statuses and so on) and carries node types this version doesn't know, so nothing is lost.
* `losslessMarkdownToAdf` — the way back: gives you the ADF you started from.
-* `adfToPortableMarkdown` — ADF to markdown that GitHub, GitLab and Obsidian render. Keeps text, images by URL and link targets, and drops the rest.
+* `adfToPortableMarkdown` — ADF to markdown that GitHub, GitLab and Obsidian render. Keeps the content and drops colours, layout and other attributes.
* `adfToHtml` — ADF to HTML.
* `htmlToAdf` — HTML to ADF.
diff --git a/ci.sh b/ci.sh
index 40b3dc2..5c8210a 100755
--- a/ci.sh
+++ b/ci.sh
@@ -61,7 +61,7 @@ leg "tests ($deno_image)" in_image "$deno_image" deno test --allow-env=PROPERTY_
leg "tests ($bun_image)" in_image "$bun_image" bun test src/
leg "corpus-gathering tests ($node_image)" in_image "$node_image" node --test corpus-gathering/
leg "feature table tests ($node_image)" in_image "$node_image" node --test feature-table/
-leg "release tooling tests ($node_image)" in_image "$node_image" node --test release-tooling/
+in_image_memory=1g leg "release tooling tests ($node_image)" in_image "$node_image" node --test release-tooling/
leg "build ($node_image)" in_image "$node_image" npm run build
leg "feature table is current ($node_image)" in_image "$node_image" node feature-table/build.mjs --check
diff --git a/publish.sh b/publish.sh
index ee45a49..ab70462 100755
--- a/publish.sh
+++ b/publish.sh
@@ -36,7 +36,7 @@ if [ -z "$published" ]; then
leg "install ($node_image)" in_image "$node_image" npm ci
leg "build ($node_image)" in_image "$node_image" npm run build
# npmjs shows the README's tagline, which package.json's description is overwritten with here.
- leg "copy the README tagline to the description ($node_image)" in_image "$node_image" node release-tooling/write-description.mjs
+ in_image_memory=1g leg "copy the README tagline to the description ($node_image)" in_image "$node_image" node release-tooling/write-description.mjs
leg "publish $name@$version ($node_image)" \
docker run --rm -u "$(id -u):$(id -g)" -e HOME=/tmp -e NPM_TOKEN -v "$PWD:/app" -w /app --entrypoint sh "$node_image" -c \
'printf "//registry.npmjs.org/:_authToken=%s\n" "$NPM_TOKEN" > "$HOME/.npmrc" && npm publish --access public'
diff --git a/release-tooling/tagline.mjs b/release-tooling/tagline.mjs
index 79f3e18..e7343b6 100644
--- a/release-tooling/tagline.mjs
+++ b/release-tooling/tagline.mjs
@@ -1,8 +1,8 @@
-const markup = /[`[\]*_<>]/
+const markup = /[`[\]*_<>~]/
// The README's first paragraph after the title and the badges.
export function readmeTagline(readme) {
- const lines = readme.split('\n').filter((line) => !line.startsWith('# ') && !line.startsWith('[!['))
+ const lines = readme.split('\n').filter((line, index, all) => index !== all.findIndex((first) => first.startsWith('# ')) && !line.startsWith('[!['))
const start = lines.findIndex((line) => line.trim() !== '')
if (start === -1 || lines[start].startsWith('#')) return { error: 'README.md has no tagline paragraph before its first section', ok: false }
const end = lines.findIndex((line, index) => index > start && line.trim() === '')
diff --git a/release-tooling/tagline.test.mjs b/release-tooling/tagline.test.mjs
index 565b208..cd3585d 100644
--- a/release-tooling/tagline.test.mjs
+++ b/release-tooling/tagline.test.mjs
@@ -18,8 +18,12 @@ test('refuses a README with no paragraph before its first section', () => {
assert.equal(readmeTagline(`${title}## Install\n`).ok, false)
})
+test('refuses a README whose next section follows the badges, whatever its heading level', () => {
+ assert.equal(readmeTagline(`${title}# Install\n\nRun it with Jira.\n`).ok, false)
+})
+
test('refuses markup, which npm would show as raw characters', () => {
- for (const markup of ['`code`', '[link](https://example.com)', '**bold**', '_em_', 'x']) {
+ for (const markup of ['`code`', '[link](https://example.com)', '**bold**', '_em_', '~~old~~', 'x']) {
assert.equal(readmeTagline(`${title}Convert ${markup}.\n`).ok, false, markup)
}
})