Skip to content

fix(generator)+feat(code): page anchor once per file; Code infers lexer from filename - #78

Merged
mhenrixon merged 2 commits into
mainfrom
issue-77-page-anchor-code-lexer
Aug 28, 2026
Merged

fix(generator)+feat(code): page anchor once per file; Code infers lexer from filename#78
mhenrixon merged 2 commits into
mainfrom
issue-77-page-anchor-code-lexer

Conversation

@mhenrixon

@mhenrixon mhenrixon commented Aug 28, 2026

Copy link
Copy Markdown
Collaborator

Closes #77

Summary

  • docs_kit:page injected the registry line once per group. #registry_anchor returned a Regexp (page line not followed by a page line), and Thor's inject_into_file replaces every match of a Regexp after: — so a grouped registry got one copy per group. The anchor is now the file's last page line as a String: one match, end of the last group.
  • DocsUI::Code infers the lexer from filename:. lexer: now defaults to nil; resolution is explicit lexer: → guess from the filename via Rouge's globs → ruby. config/deploy.yml → yaml, Dockerfile → docker, *.sh → shell. Unguessable filename / no filename → ruby as before.
  • Docs: README authoring convention, the Authoring + Components pages, the generated AGENTS.md template, and CHANGELOG.

Test plan

  • spec/generators/page_generator_spec.rb — grouped fixture (two groups, blank line + comment): exactly one line added after the last page line of the file; second run idempotent.
  • spec/docs_ui/code_spec.rb.ymldata-md-lang="yaml" with no err spans; Dockerfile → docker; explicit lexer: wins over the filename; unguessable filename → ruby; no args → ruby.
  • bundle exec rspec — 953 examples, 0 failures (94.7% line coverage)
  • bundle exec rubocop — no offenses
  • Manual (post-merge, dash docs/ with a path gem): bin/rails g docs_kit:page "Scratch" --group=Deploying twice → one line at the end of the last group

Deviations & judgment calls

  • Rouge::Lexer.guesses instead of Rouge::Lexer.guess. The issue named guess(filename:) with an Ambiguous rescue, but guess answers PlainText on a no-match (e.g. filename: "notes"), which is indistinguishable from a real guess and would have turned unguessable filenames into plaintext instead of the required ruby fallback. guesses returns an array — exactly one hit is a guess, zero or several is nil — and needs no rescue.
  • No code_filename_lexers config knob. The issue floated it as a possible follow-up for extension-less files (.dash/secrets); those still work with an explicit lexer:, so I didn't add config surface nobody has asked for yet.
  • No --sync migration. The AGENTS.md template change is a content edit an existing site picks up via the normal install/sync path; nothing new to install.

https://claude.ai/code/session_01KsqvKPn1c1hWu6NSEQHy1W


Summary by cubic

Fixes the docs_kit:page generator adding a registry entry once per group instead of once per file, and makes DocsUI::Code infer the lexer from filename: when no lexer: is given.

Bug Fixes

  • docs_kit:page now anchors on the file's last page line as a string, so grouped registries get exactly one new entry per run.
  • A second run is idempotent — no duplicate entries are added.

New Features

  • DocsUI::Code resolves the lexer as explicit lexer: → filename guess via Rouge → ruby; unguessable filenames and no filename stay ruby.
  • Explicit lexer: always overrides the filename guess.
  • Docs, README, and the generated AGENTS.md template now describe the new behavior; no migration step is needed—existing sites pick up the template change via the normal install/sync path.

Closes #77.

Written for commit 968d771. Summary will update on new commits.

Review in cubic

Thor's inject_into_file replaces every match of a Regexp `after:`, so the
"page line not followed by a page line" anchor fired once per blank-line
separated group and duplicated the registry entry. Anchor on the last
`page` line as a String instead — one match, end of the last group.

Refs #77

Claude-Session: https://claude.ai/code/session_01KsqvKPn1c1hWu6NSEQHy1W
DocsUI::Code(<<~YAML, filename: "config/deploy.yml") now highlights as
YAML via Rouge's filename globs. Explicit lexer: still wins; no filename
or an unguessable one keeps the ruby default so existing output is
unchanged. Also the changelog entry for the generator fix.

Refs #77

Claude-Session: https://claude.ai/code/session_01KsqvKPn1c1hWu6NSEQHy1W
@mhenrixon mhenrixon self-assigned this Aug 28, 2026
@mhenrixon mhenrixon added the bug Something isn't working label Aug 28, 2026
@mhenrixon
mhenrixon merged commit 72f80bb into main Aug 28, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Generator: docs_kit:page injects the registry line once per group; DocsUI::Code should infer the lexer from filename:

1 participant