From 8caeac9cc76ca3b44c13e3aa9ba2985f54c88648 Mon Sep 17 00:00:00 2001 From: Vijay Janapa Reddi Date: Thu, 12 Feb 2026 23:26:17 -0500 Subject: [PATCH] refactor(binder): rename validate/maintain subcommands for clarity MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rename verbose compound names to clean, noun-based names: - section-ids → headers - forbidden-footnotes → footnote-placement - footnotes → footnote-refs - figure-completeness → figures - figure-placement → float-flow - index-placement → indexes - render-patterns → rendering - dropcap → dropcaps - part-keys → parts - image-refs → images Updated in: validate.py, maintenance.py, pre-commit hooks, VSCode extension. --- .pre-commit-config.yaml | 20 ++--- book/cli/commands/maintenance.py | 4 +- book/cli/commands/validate.py | 144 +++++++++++++++---------------- book/vscode-ext/src/extension.ts | 4 +- 4 files changed, 86 insertions(+), 86 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 89013eac7..a28840778 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -121,7 +121,7 @@ repos: - id: book-verify-section-ids name: "Book: Verify all sections have IDs" # NOTE: Currently only checking Vol1 - Vol2 is still in early development - entry: ./book/binder validate section-ids --vol1 + entry: ./book/binder validate headers --vol1 language: system pass_filenames: false files: ^book/quarto/contents/vol1/.*\.qmd$ @@ -158,14 +158,14 @@ repos: - id: book-validate-footnotes name: "Book: Validate footnote references" - entry: ./book/binder validate footnotes + entry: ./book/binder validate footnote-refs language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ - id: book-check-forbidden-footnotes name: "Book: Check for footnotes in tables/captions" - entry: ./book/binder validate forbidden-footnotes + entry: ./book/binder validate footnote-placement language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ @@ -195,14 +195,14 @@ repos: - id: book-check-figure-completeness name: "Book: Check figures have captions and alt-text" - entry: ./book/binder validate figure-completeness + entry: ./book/binder validate figures language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ - id: book-check-figure-placement name: "Book: Check figure/table placement (near first reference)" - entry: ./book/binder validate figure-placement + entry: ./book/binder validate float-flow language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ @@ -231,7 +231,7 @@ repos: - id: book-check-render-patterns name: "Book: Check for rendering issues (LaTeX+Python)" - entry: ./book/binder validate render-patterns + entry: ./book/binder validate rendering language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ @@ -239,7 +239,7 @@ repos: - id: book-validate-dropcap name: "Book: Validate drop cap compatibility" - entry: ./book/binder validate dropcap + entry: ./book/binder validate dropcaps language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ @@ -261,14 +261,14 @@ repos: - id: book-check-index-placement name: "Book: Check index placement (not inline with headings/callouts)" - entry: ./book/binder validate index-placement + entry: ./book/binder validate indexes language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ - id: book-validate-part-keys name: "Book: Validate part keys" - entry: ./book/binder validate part-keys + entry: ./book/binder validate parts language: system pass_filenames: false files: ^book/.*\.qmd$ @@ -294,7 +294,7 @@ repos: - id: book-validate-image-references name: "Book: Check image references exist" - entry: ./book/binder validate image-refs + entry: ./book/binder validate images language: system pass_filenames: false files: ^book/quarto/contents/.*\.qmd$ diff --git a/book/cli/commands/maintenance.py b/book/cli/commands/maintenance.py index eb5272f42..0e40fd841 100644 --- a/book/cli/commands/maintenance.py +++ b/book/cli/commands/maintenance.py @@ -196,7 +196,7 @@ class MaintenanceCommand: description="Maintenance namespace for non-build workflows", add_help=True, ) - parser.add_argument("topic", nargs="?", choices=["glossary", "images", "repo-health", "section-ids", "footnotes"]) + parser.add_argument("topic", nargs="?", choices=["glossary", "images", "repo-health", "headers", "footnotes"]) parser.add_argument("action", nargs="?") parser.add_argument("--vol1", action="store_true", help="Scope to vol1") parser.add_argument("--vol2", action="store_true", help="Scope to vol2") @@ -251,7 +251,7 @@ class MaintenanceCommand: return False return self._maintain_repo_health(min_size_mb=ns.min_size_mb, json_output=ns.json) - if ns.topic == "section-ids": + if ns.topic == "headers": valid_actions = ("add", "repair", "list", "remove") if ns.action not in valid_actions: console.print(f"[red]❌ Supported actions: {', '.join(valid_actions)}[/red]") diff --git a/book/cli/commands/validate.py b/book/cli/commands/validate.py index ab64b71b2..bbe053ef0 100644 --- a/book/cli/commands/validate.py +++ b/book/cli/commands/validate.py @@ -114,16 +114,16 @@ class ValidateCommand: "duplicate-labels", "unreferenced-labels", "inline-refs", - "section-ids", - "forbidden-footnotes", - "footnotes", - "figure-completeness", - "figure-placement", - "index-placement", - "render-patterns", - "dropcap", - "part-keys", - "image-refs", + "headers", + "footnote-placement", + "footnote-refs", + "figures", + "float-flow", + "indexes", + "rendering", + "dropcaps", + "parts", + "images", "all", ], help="Validation command to run", @@ -167,16 +167,16 @@ class ValidateCommand: runs.append(self._run_duplicate_labels(root_path, label_types)) runs.append(self._run_unreferenced_labels(root_path, label_types)) runs.append(self._run_inline_refs(root_path, check_patterns=ns.check_patterns)) - runs.append(self._run_section_ids(root_path)) - runs.append(self._run_forbidden_footnotes(root_path)) - runs.append(self._run_footnotes(root_path)) - runs.append(self._run_figure_completeness(root_path)) - runs.append(self._run_figure_placement(root_path)) - runs.append(self._run_index_placement(root_path)) - runs.append(self._run_render_patterns(root_path)) - runs.append(self._run_dropcap(root_path)) - runs.append(self._run_part_keys(root_path)) - runs.append(self._run_image_refs(root_path)) + runs.append(self._run_headers(root_path)) + runs.append(self._run_footnote_placement(root_path)) + runs.append(self._run_footnote_refs(root_path)) + runs.append(self._run_figures(root_path)) + runs.append(self._run_float_flow(root_path)) + runs.append(self._run_indexes(root_path)) + runs.append(self._run_rendering(root_path)) + runs.append(self._run_dropcaps(root_path)) + runs.append(self._run_parts(root_path)) + runs.append(self._run_images(root_path)) elif ns.subcommand == "inline-python": runs.append(self._run_inline_python(root_path)) elif ns.subcommand == "refs": @@ -191,26 +191,26 @@ class ValidateCommand: runs.append(self._run_unreferenced_labels(root_path, self._selected_label_types(ns))) elif ns.subcommand == "inline-refs": runs.append(self._run_inline_refs(root_path, check_patterns=ns.check_patterns)) - elif ns.subcommand == "section-ids": - runs.append(self._run_section_ids(root_path)) - elif ns.subcommand == "forbidden-footnotes": - runs.append(self._run_forbidden_footnotes(root_path)) - elif ns.subcommand == "footnotes": - runs.append(self._run_footnotes(root_path)) - elif ns.subcommand == "figure-completeness": - runs.append(self._run_figure_completeness(root_path)) - elif ns.subcommand == "figure-placement": - runs.append(self._run_figure_placement(root_path)) - elif ns.subcommand == "index-placement": - runs.append(self._run_index_placement(root_path)) - elif ns.subcommand == "render-patterns": - runs.append(self._run_render_patterns(root_path)) - elif ns.subcommand == "dropcap": - runs.append(self._run_dropcap(root_path)) - elif ns.subcommand == "part-keys": - runs.append(self._run_part_keys(root_path)) - elif ns.subcommand == "image-refs": - runs.append(self._run_image_refs(root_path)) + elif ns.subcommand == "headers": + runs.append(self._run_headers(root_path)) + elif ns.subcommand == "footnote-placement": + runs.append(self._run_footnote_placement(root_path)) + elif ns.subcommand == "footnote-refs": + runs.append(self._run_footnote_refs(root_path)) + elif ns.subcommand == "figures": + runs.append(self._run_figures(root_path)) + elif ns.subcommand == "float-flow": + runs.append(self._run_float_flow(root_path)) + elif ns.subcommand == "indexes": + runs.append(self._run_indexes(root_path)) + elif ns.subcommand == "rendering": + runs.append(self._run_rendering(root_path)) + elif ns.subcommand == "dropcaps": + runs.append(self._run_dropcaps(root_path)) + elif ns.subcommand == "parts": + runs.append(self._run_parts(root_path)) + elif ns.subcommand == "images": + runs.append(self._run_images(root_path)) any_failed = any(not run.passed for run in runs) summary = { @@ -682,10 +682,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Section IDs (ported from manage_section_ids.py --verify) + # Headers (ported from manage_section_ids.py --verify) # ------------------------------------------------------------------ - def _run_section_ids(self, root: Path) -> ValidationRunResult: + def _run_headers(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -746,7 +746,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="section-ids", + name="headers", description="Verify all section headers have {#sec-...} IDs", files_checked=len(files), issues=issues, @@ -754,10 +754,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Forbidden Footnotes (ported from check_forbidden_footnotes.py) + # Footnote Placement (ported from check_forbidden_footnotes.py) # ------------------------------------------------------------------ - def _run_forbidden_footnotes(self, root: Path) -> ValidationRunResult: + def _run_footnote_placement(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -876,7 +876,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="forbidden-footnotes", + name="footnote-placement", description="Check footnotes in forbidden locations", files_checked=len(files), issues=issues, @@ -884,10 +884,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Footnote validation (ported from footnote_cleanup.py --validate) + # Footnote Refs (ported from footnote_cleanup.py --validate) # ------------------------------------------------------------------ - def _run_footnotes(self, root: Path) -> ValidationRunResult: + def _run_footnote_refs(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -962,7 +962,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="footnotes", + name="footnote-refs", description="Validate footnote references and definitions", files_checked=len(files), issues=issues, @@ -970,10 +970,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Figure completeness (ported from check_figure_completeness.py) + # Figures (ported from check_figure_completeness.py) # ------------------------------------------------------------------ - def _run_figure_completeness(self, root: Path) -> ValidationRunResult: + def _run_figures(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1060,7 +1060,7 @@ class ValidateCommand: cell_opts[opt_m.group(1)] = val return ValidationRunResult( - name="figure-completeness", + name="figures", description="Check figures have captions and alt-text", files_checked=len(files), issues=issues, @@ -1068,10 +1068,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Figure/table placement (ported from figure_table_flow_audit.py) + # Float Flow (ported from figure_table_flow_audit.py) # ------------------------------------------------------------------ - def _run_figure_placement(self, root: Path) -> ValidationRunResult: + def _run_float_flow(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1204,7 +1204,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="figure-placement", + name="float-flow", description="Audit figure/table placement relative to first reference", files_checked=len(files), issues=issues, @@ -1212,10 +1212,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Index placement (ported from check_index_placement.py) + # Indexes (ported from check_index_placement.py) # ------------------------------------------------------------------ - def _run_index_placement(self, root: Path) -> ValidationRunResult: + def _run_indexes(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1254,7 +1254,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="index-placement", + name="indexes", description="Check LaTeX \\index{} placement", files_checked=len(files), issues=issues, @@ -1262,10 +1262,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Render patterns (ported from check_render_patterns.py) + # Rendering (ported from check_render_patterns.py) # ------------------------------------------------------------------ - def _run_render_patterns(self, root: Path) -> ValidationRunResult: + def _run_rendering(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1339,7 +1339,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="render-patterns", + name="rendering", description="Check for problematic rendering patterns", files_checked=len(files), issues=issues, @@ -1347,10 +1347,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Drop cap compatibility (ported from validate_dropcap_compat.py) + # Dropcaps (ported from validate_dropcap_compat.py) # ------------------------------------------------------------------ - def _run_dropcap(self, root: Path) -> ValidationRunResult: + def _run_dropcaps(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1455,7 +1455,7 @@ class ValidateCommand: break return ValidationRunResult( - name="dropcap", + name="dropcaps", description="Validate drop cap compatibility", files_checked=len(files), issues=issues, @@ -1463,10 +1463,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Part keys (ported from validate_part_keys.py) + # Parts (ported from validate_part_keys.py) # ------------------------------------------------------------------ - def _run_part_keys(self, root: Path) -> ValidationRunResult: + def _run_parts(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1485,7 +1485,7 @@ class ValidateCommand: import yaml except ImportError: return ValidationRunResult( - name="part-keys", + name="parts", description="Validate part keys (skipped — pyyaml not installed)", files_checked=0, issues=[], @@ -1505,7 +1505,7 @@ class ValidateCommand: if not summaries_keys: # No summaries found — skip gracefully return ValidationRunResult( - name="part-keys", + name="parts", description="Validate part keys (skipped — no summaries.yml found)", files_checked=0, issues=[], @@ -1531,7 +1531,7 @@ class ValidateCommand: ) return ValidationRunResult( - name="part-keys", + name="parts", description="Validate \\part{{key:...}} against summaries.yml", files_checked=len(files), issues=issues, @@ -1539,10 +1539,10 @@ class ValidateCommand: ) # ------------------------------------------------------------------ - # Image references (ported from validate_image_references.py) + # Images (ported from validate_image_references.py) # ------------------------------------------------------------------ - def _run_image_refs(self, root: Path) -> ValidationRunResult: + def _run_images(self, root: Path) -> ValidationRunResult: start = time.time() files = self._qmd_files(root) issues: List[ValidationIssue] = [] @@ -1593,7 +1593,7 @@ class ValidateCommand: pass return ValidationRunResult( - name="image-refs", + name="images", description="Validate image references exist on disk", files_checked=len(files), issues=issues, diff --git a/book/vscode-ext/src/extension.ts b/book/vscode-ext/src/extension.ts index 9701e3adf..0463c42fc 100644 --- a/book/vscode-ext/src/extension.ts +++ b/book/vscode-ext/src/extension.ts @@ -259,7 +259,7 @@ export function activate(context: vscode.ExtensionContext): void { ? `--path ${editor.document.uri.fsPath}` : '--vol1'; runInVisibleTerminal( - `./book/binder maintain section-ids add ${target} --force`, + `./book/binder maintain headers add ${target} --force`, root, 'Add Section IDs', ); @@ -267,7 +267,7 @@ export function activate(context: vscode.ExtensionContext): void { vscode.commands.registerCommand('mlsysbook.verifySectionIds', () => { if (!root) { return; } runInVisibleTerminal( - './book/binder validate section-ids --vol1', + './book/binder validate headers --vol1', root, 'Verify Section IDs', );