Widen the prettier gate to markdown and CSS everywhere (closes #12) #32

Merged
clawbot merged 2 commits from issue-12-widen-prettier-scope into main 2026-08-09 18:30:36 +02:00
5 changed files with 112 additions and 62 deletions

View File

@@ -1,2 +1,25 @@
node_modules/
yarn.lock
# Site content. Measured, not assumed: formatting content/_index.md
# re-wrapped one list item, and the rendered public/index.html changed
# with it - the wrap landed as a literal newline between "7 PM at" and
# the following <a> tag. HTML collapses that newline to a space, so the
# page looks the same, but the published bytes are not the same, and
# this content carries raw HTML blocks (div/span/br) that goldmark
# passes through verbatim because hugo.toml sets
# markup.goldmark.renderer.unsafe = true. A formatter that can silently
# change a published page is not worth the consistency, so content/ is
# formatted by hand.
content/
# Hugo layout templates. REPO_POLICIES.md puts HTML in prettier's
# scope, but these files are not HTML: they are Go templates carrying
# {{ define }}, {{ block }}, {{ .Content }} and
# {{ readFile ... | safeCSS }}. Prettier has no Go-template parser, so
# it would either fail outright or reflow the delimiters into markup
# Hugo can no longer parse. Formatting them would require an
# out-of-tree prettier plugin, which in turn requires a package.json -
# deliberately out of scope for this repo. Excluded on purpose, not by
# oversight.
themes/loravega/layouts/

19
TODO.md
View File

@@ -28,6 +28,25 @@ remaining policy scaffold is otherwise complete.
# Completed Steps
- 2026-08-09: widened the prettier gate from top-level markdown to `'**/*.md'`
and `'**/*.css'` (closes #12). `themes/loravega/static/css/style.css` was
never formatted or gated even though it is inlined into every page; it is now
both, and the reformat landed as its own commit ahead of the script change so
no commit in the branch is red. `content/` is excluded in `.prettierignore`,
and that exclusion is measured rather than assumed: with `content/` in scope,
prettier re-wrapped one list item in `content/_index.md` and the rendered
`public/index.html` changed with it (the wrap became a literal newline between
`7 PM at` and the following `<a>`). HTML collapses that newline to a space so
the page looks identical, but the published bytes are not, and this content
carries raw HTML that goldmark passes through verbatim under `unsafe = true`.
`themes/loravega/layouts/` is excluded too, with the reason recorded: those
files are Go templates, not HTML, and prettier has no parser for `{{ ... }}`
covering them would need a plugin and therefore a `package.json`. Verified by
extracting `public/` from the built image before and after: with the final
scope, `index.html`, `index.xml` and `sitemap.xml` are byte-identical and only
the verbatim-copied `public/css/style.css` changes, in whitespace only — the
minified `<style>` block inlined into `index.html` is unchanged, which is the
direct evidence that CSS formatting cannot reach the rendered page
- 2026-08-09: added the canonical policy dotfiles and hardened both ignore files
(closes #8). `REPO_POLICIES.md` is a byte-identical copy of the canonical
`prompts` file, front matter intact; `.editorconfig`, `.prettierrc` and

View File

@@ -1,8 +1,11 @@
#!/bin/sh
# script/fmt: format the repo's own top-level markdown docs (README.md,
# TODO.md, ...) with prettier, using our standard settings. Scope is
# deliberately limited to top-level docs: site content under content/
# is left untouched so rendered output cannot change.
# script/fmt: format this repo's markdown and CSS with prettier, using
# our standard settings. Scope is every markdown and CSS file in the
# tree, per REPO_POLICIES.md ("prettier for JS/CSS/Markdown/HTML").
# What is deliberately NOT covered is recorded in .prettierignore, with
# the reason next to each entry: the Hugo layout templates, which are
# Go templates and not HTML, and content/, whose reformatting was
# measured to change the rendered page.
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
@@ -12,7 +15,7 @@ PRETTIER_VERSION="3.4.2"
main() {
cd "$ROOT"
npx --yes "prettier@${PRETTIER_VERSION}" --write \
'*.md' --tab-width 4 --prose-wrap always
'**/*.md' '**/*.css' --tab-width 4 --prose-wrap always
}
main "$@"

View File

@@ -1,7 +1,7 @@
#!/bin/sh
# script/fmt-check: check the formatting of the repo's own top-level
# markdown docs (read-only). Same scope as script/fmt, but fails
# instead of writing.
# script/fmt-check: check the formatting of this repo's markdown and
# CSS (read-only). Same scope and same settings as script/fmt - keep
# the two in sync - but fails instead of writing.
set -eu
ROOT="$(cd "$(dirname "$0")/.." && pwd -P)"
@@ -11,7 +11,7 @@ PRETTIER_VERSION="3.4.2"
main() {
cd "$ROOT"
npx --yes "prettier@${PRETTIER_VERSION}" --check \
'*.md' --tab-width 4 --prose-wrap always
'**/*.md' '**/*.css' --tab-width 4 --prose-wrap always
}
main "$@"

View File

@@ -1,101 +1,106 @@
:root {
--bg: #ffffff;
--fg: #1a1a1a;
--accent: #0066cc;
--muted: #666;
--max-w: 600px;
--bg: #ffffff;
--fg: #1a1a1a;
--accent: #0066cc;
--muted: #666;
--max-w: 600px;
}
* { margin: 0; padding: 0; box-sizing: border-box; }
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
body {
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
background: var(--bg);
color: var(--fg);
line-height: 1.6;
padding: 2rem 1rem;
max-width: 90%;
margin: 0 auto;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
"Helvetica Neue", Arial, sans-serif;
background: var(--bg);
color: var(--fg);
line-height: 1.6;
padding: 2rem 1rem;
max-width: 90%;
margin: 0 auto;
}
h1 {
font-size: 1.8rem;
margin-bottom: 0.25rem;
font-size: 1.8rem;
margin-bottom: 0.25rem;
}
.tagline {
color: var(--muted);
margin-bottom: 2rem;
color: var(--muted);
margin-bottom: 2rem;
}
h2 {
font-size: 1.2rem;
margin-top: 2rem;
margin-bottom: 0.5rem;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 0.25rem;
font-size: 1.2rem;
margin-top: 2rem;
margin-bottom: 0.5rem;
border-bottom: 1px solid #e0e0e0;
padding-bottom: 0.25rem;
}
h3 {
font-size: 1rem;
margin-top: 1.5rem;
margin-bottom: 0.5rem;
font-weight: 600;
color: var(--muted);
font-size: 1rem;
margin-top: 1.5rem;
margin-bottom: 0.5rem;
font-weight: 600;
color: var(--muted);
}
ul {
list-style: none;
padding: 0;
list-style: none;
padding: 0;
}
li {
margin-bottom: 0.5rem;
margin-bottom: 0.5rem;
}
a {
color: var(--accent);
text-decoration: none;
color: var(--accent);
text-decoration: none;
}
a:hover {
text-decoration: underline;
text-decoration: underline;
}
.settings {
background: #f8f8f8;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 1rem;
margin-top: 0.5rem;
font-family: "SF Mono", "Fira Code", "Consolas", monospace;
font-size: 0.9rem;
line-height: 1.8;
overflow-wrap: break-word;
word-break: break-all;
background: #f8f8f8;
border: 1px solid #e0e0e0;
border-radius: 4px;
padding: 1rem;
margin-top: 0.5rem;
font-family: "SF Mono", "Fira Code", "Consolas", monospace;
font-size: 0.9rem;
line-height: 1.8;
overflow-wrap: break-word;
word-break: break-all;
}
.settings .label {
color: var(--muted);
color: var(--muted);
}
.settings .value {
color: var(--accent);
color: var(--accent);
}
.mono-link {
font-family: "SF Mono", "Fira Code", "Consolas", monospace;
font-size: 0.85rem;
font-family: "SF Mono", "Fira Code", "Consolas", monospace;
font-size: 0.85rem;
}
footer {
margin-top: 3rem;
color: var(--muted);
font-size: 0.8rem;
border-top: 1px solid #e0e0e0;
padding-top: 1rem;
margin-top: 3rem;
color: var(--muted);
font-size: 0.8rem;
border-top: 1px solid #e0e0e0;
padding-top: 1rem;
}
.contribute-link {
font-size: 0.7rem;
font-size: 0.7rem;
}