feat(scanner): source-markdown scanner + fixer (#1963) - #1965
Merged
Conversation
Detect + fix at source the malformed-markdown classes the render pipeline currently patches in flight (scripts/parsers/*.ts pre-processors), and open one PR per sap-tutorials source repo so the pre-processors can be retired. - scripts/scan-markdown-source.ts: registry of 5 source-fixable classes (blockquote-fence, list-continuation-fence #1931, list-continuation-prose, blockquote-notes #1741, image-directive-comment #1137) reusing the exact pre-processor transforms, plus render-time hugo-delimiters (report-only). Frontmatter-verbatim split, EOL preservation, LCS line-diff findings, golden-render gate (steps/body/intro equality), dry-run default, --fix, --open-prs (clone+re-gate+PR per repo), --retirement-status. - scripts/parsers/images.ts: extract stripImageDirectiveComments so scanner and pre-processor share one #1137 transform (behavior-preserving). - test/parsers/scan-markdown-source.test.ts: detection, idempotency, golden-render, frontmatter + EOL preservation, render-time never written. Retirement of the in-flight pre-processors is gated on merged source PRs and is NOT performed here. 🤖 Generated with Claude Code
- --open-prs now also targets each published repo's <repo>-Contribution upstream (default on; --no-contribution to disable), so a source fix can't be overwritten the next time Contribution is copied forward. PR flow is now clone-driven: each repo is cloned and re-scanned against its own current content, golden-gated, then fixed — works for Contribution repos not in the local discovery cache. - Fixes are chunked into ≤--batch-size (default 10) tutorials per PR, one branch (fix/md-source-1963[-batch-N]) + PR each, so large repos stay reviewable. - Idempotent: skips a batch whose head branch already has a PR (any state). - chunk() extracted + unit-tested. 🤖 Generated with Claude Code
Contributor
Author
|
Updated per review feedback:
Live verification: sap-tutorials/eda-Contribution#1 (the Contribution pair for the earlier eda#7). |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #1963 (subsystem B — source-markdown scanner/fixer; attachment dead-links are subsystem A, tracked separately).
What
A CLI (
npm run scan-tutorial-markdown) that detects the malformed-markdown classes our render pipeline currently patches in flight (scripts/parsers/*.ts), fixes them at source, and opens one PR persap-tutorialssource repo — so the pre-processors can eventually be retired.Key insight: each pre-processor is a pure, idempotent
(md)=>mdtransform, so each is its own fixer (finding = output ≠ input). Applying the fix at source + re-running the still-present pre-processor yields byte-identical compose output — the golden-render gate.Classes
Source-fixable (detected + fixed):
blockquote-fence,list-continuation-fence(#1931),list-continuation-prose,blockquote-notes(#1741),image-directive-comment(#1137).Render-time (report-only, never written):
hugo-delimiters. (Image URL rewrite / prerequisites-markup are correct at source and excluded.)Design
stripImageDirectiveCommentsextracted fromimages.tsfor the same reason.{steps, body, intro}equality (the pre-processor-governed fields) before any file is written/PR'd; failures are quarantined as NEEDS-MANUAL-REVIEW.--fix(stage) →--open-prs(clone + re-gate against fresh source + PR per repo).--retirement-status,--class/--repo/--slug/--limit.Scale (current cache)
17,614 findings across 855 files. Source-fixable spans 15 repos / 847 files; golden gate passes all 847 (0 manual-review).
list-continuation-fence= 450 files (matches the issue's ~469 estimate).Retirement
--retirement-statusreports per-class remaining occurrences and, at zero, the exact removal checklist. Deletion is deferred — gated on merged source PRs (none are zero yet).Tests
test/parsers/scan-markdown-source.test.ts(14): per-class detection, idempotency (fix→re-scan=0), golden-render, frontmatter + EOL preservation, render-time never written. Existingimages.test.ts+compose.test.tsstill green.Verification done
First live source PR opened + inspected: sap-tutorials/eda#7 (clean, conservative de-indent). Remaining repos pending maintainer go-ahead given the footprint.
🤖 Generated with Claude Code