All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
- classify-guides — New tool to classify AsciiDoc guides by Diataxis type (tutorial, howto, concept, reference)
- Reads
:diataxis-type:metadata from AsciiDoc file headers for instant HIGH confidence classification - Scoring-based structural heuristics detect tutorials, how-to guides, concepts, and reference docs
- Detects mixed-type documents (e.g.,
mixed:tutorial+reference) with split-point estimation - Optional LLM fallback with auto-detection of Google Gemini, Anthropic Claude, or local Ollama
- LLM acts as weighted tiebreaker, not override; results cached to avoid redundant API calls
- API keys read from environment variables (
GEMINI_API_KEY,ANTHROPIC_API_KEY); Ollama needs no key - YAML output with per-guide classification, confidence level, and reasoning
- Portable defaults: scans current directory by default, optional
--yaml-filefor quarkus.yaml metadata - CLI flags:
--llm,--llm-all,--llm-provider,--adoc-dir,--yaml-file,--output - 32 unit tests covering analysis, classification, and LLM merge logic
- Reads
- Added
docs/tools/classify-guides.mdwith full usage, LLM configuration, and output format reference - Updated
docs/tools/index.mdwith classify-guides entry
- convert-id-attributes-to-ids - New tool to convert
:id:attributes to AsciiDoc anchors- Converts
:id: valueto[id="value_{context}"]format - Optional
--clean-upflag removes boilerplate comments and include directives - Removes
// define ID as an attributecomments - Removes
// assign ID conditionallycomments - Removes
include::{modules}/common/id.adoc[]directives - Dry-run mode for safe preview
- CLI command:
convert-id-attributes-to-ids [--clean-up] [--dry-run] [path]
- Converts
-
insert-abstract-role - New tool to add
[role="_abstract"]for DITA short description conversion- Inserts
[role="_abstract"]above the first paragraph after the document title - Required for DITA short description conversion during documentation migration
- Dry-run mode by default for safe preview, use
--applyto modify files - Full exclusion support (
--exclude-dir,--exclude-file,--exclude-list) - CLI command:
insert-abstract-role [--apply] [--dry-run] [path]
- Inserts
-
insert-procedure-title - New tool to add
.Procedureblock title for DITA task compliance- Resolves
AsciiDocDITA.TaskContentsVale warnings - Inserts
.Procedureabove the first numbered step in procedure files - Detects procedure files by checking
:_mod-docs-content-type: PROCEDURE - Provides warnings for files needing manual attention (wrong content type, stub files)
- Dry-run mode by default for safe preview, use
--applyto modify files - Full exclusion support (
--exclude-dir,--exclude-file,--exclude-list) - CLI command:
insert-procedure-title [--apply] [--dry-run] [path]
- Resolves
-
callout_lib/detector.py - Fixed false "missing explanations" warnings when
{nbsp}spacers follow code blocks- Now correctly skips
{nbsp}(AsciiDoc non-breaking space macro) when looking for callout explanations - Stops collecting continuation lines when hitting
+,[NOTE],[IMPORTANT],[WARNING],[TIP],[CAUTION] - Prevents NOTE admonition content from being included in callout explanations
- Now correctly skips
-
convert-callouts-to-deflist - Fixed preservation of
{nbsp}and+markers between code blocks and explanations- Now preserves
{nbsp}spacers following code blocks in the converted output - Now preserves
+list continuation markers in the converted output - Prevents deletion of these AsciiDoc formatting elements during conversion
- Now preserves
-
convert-callouts-interactive - Applied same preservation fix for
{nbsp}and+markers- Interactive tool now has consistent behavior with batch tool
-
callout_lib/converter_deflist.py - Changed separator format from blank lines to
+continuation markers- Uses
+continuation markers before each definition term for proper list attachment - Improves compatibility with AsciiDoc list structures
- Uses
- Updated
docs/content-reuse-assessment.mdwith Task 7 for converting callouts- Added guidance for resolving
AsciiDocDITA.CalloutListVale warnings - Added both batch and interactive converter commands
- Added guidance for resolving
- Added tool documentation pages:
docs/tools/insert-abstract-role.mddocs/tools/insert-procedure-title.md
-
inventory-conditionals - New tool to create timestamped inventory of AsciiDoc conditionals
- Scans for
ifdef,ifndef,ifeval, andendifdirectives - Groups results by conditional name for easy review
- Auto-generates reports to
./reports/directory - Supports txt, csv, json, md output formats
- CLI command:
inventory-conditionals [directory] [options]
- Scans for
-
find-duplicate-content - New tool to find duplicate/similar content blocks across AsciiDoc files
- Detects duplicate notes, tips, warnings, tables, step sequences, and code blocks
- Uses Jaccard similarity for fuzzy matching (configurable threshold)
- Helps identify copy-pasted content that could be refactored into shared modules
- Auto-generates reports to
./reports/directory - CLI command:
find-duplicate-content [directory] [options]
-
find-duplicate-includes - New tool to find files included from multiple locations
- Scans for
include::macros and identifies multiply-included files - Excludes common files (attributes.adoc, etc.) by default
- Reports source file and line number for each inclusion
- Helps audit content reuse patterns in modular documentation
- CLI command:
find-duplicate-includes [directory] [options]
- Scans for
- find-unused-attributes - Added
--removeoption to automatically remove unused attribute definitions- Modifies attribute files in place after confirmation
- Provides preview output before removal
- Added Content Reuse Assessment guide (
docs/content-reuse-assessment.md)- Documents how to use doc-utils tools for Pre-Migration Reuse Readiness Tasks
- Maps tools to Content Reuse Assessment Worksheet tasks
- Added tool documentation pages:
docs/tools/inventory-conditionals.mddocs/tools/find-duplicate-content.mddocs/tools/find-duplicate-includes.md
- Updated CLAUDE.md with new tools and modules
- convert-freemarker-to-asciidoc - New tool to convert FreeMarker-templated AsciiDoc to standard AsciiDoc
- Converts Keycloak-style FreeMarker templates to plain AsciiDoc
- Removes
<#import ...>statements - Converts
<@tmpl.guide>and<@template.guide>blocks to AsciiDoc titles and summaries - Converts
<@links.*>macros to standardxref:cross-references- Supports: server, ha, observability, securingapps, gettingstarted, operator, migration
- Handles anchor attributes:
<@links.server id="x" anchor="y"/>→xref:server/x.adoc#y[]
- Converts
<@kc.*>command macros to code blocks- Supports: start, startdev, build, export, import, updatecompatibility, admin, bootstrapadmin
- Handles
<@profile.ifCommunity>and<@profile.ifProduct>conditional blocks- Default: keeps community content; use
--productto keep product content
- Default: keeps community content; use
- Processes
<#noparse>blocks (removes tags, preserves content) - Removes
<@opts.*>and<@features.table>macros with placeholder comments - Marks unconvertible patterns (
<#list>,<#if>,<#assign>) with TODO comments - CLI options:
--dry-run/-n: Preview changes without modifying files--verbose/-v: Show detailed output--structure-only: Only convert imports and guide blocks--product: Keep product content instead of community--base-path: Add prefix to xref links--only-freemarker: Only process files with FreeMarker markup
- CLI command:
convert-freemarker-to-asciidoc [OPTIONS] [PATH]
- Added comprehensive
docs/tools/convert-freemarker-to-asciidoc.mdwith:- Tables of all convertible and non-convertible patterns
- Conversion examples (before/after)
- Best practices and recommended workflow
- Troubleshooting guide
- convert-tables-to-deflists - New tool to convert AsciiDoc tables to definition lists
- Converts 2-column tables by default (column 1 → term, column 2 → definition)
- Multi-column support with
--columns TERM,DEFoption (e.g.,--columns 1,3) - Automatically skips callout tables (use convert-callouts-to-deflist for those)
- Detects and handles header rows automatically
- Preserves conditional directives (
ifdef::/ifndef::/endif::) - Dry-run mode by default for safe preview, use
--applyto modify files - Full exclusion support (
--exclude-dir,--exclude-file,--exclude-list) - CLI command:
convert-tables-to-deflists [--apply] [--columns TERM,DEF] [path]
- Added
docs/tools/convert-tables-to-deflists.mdwith full tool documentation - Updated
docs/tools/index.mdwith new tool entry - Updated
CLAUDE.mdwith new tool in CLI Tools list and Project Structure
- check-source-directives - New tool to detect and fix missing [source] directives in AsciiDoc code blocks
- Detects code blocks (----) that lack proper [source] directives
- Helps prevent AsciiDoc-to-DocBook XML conversion errors
- Auto-fix mode with
--fixflag to automatically insert [source] directives - Intelligent context-aware detection to minimize false positives
- Handles AsciiDoc block titles between [source] and ---- delimiters
- Skips valid patterns: attribute blocks, continuation markers, admonitions
- Exit code 1 when issues found (detection mode), 0 when clean or fixed
- CLI command:
check-source-directives [--fix] [directory] - Core module:
doc_utils/missing_source_directive.py - Documentation:
docs/tools/check-source-directives.md
- Commented references tracking - Enhanced archive-unused-files and archive-unused-images with intelligent handling of commented references
- New
--commentedflag to include files/images referenced only in commented lines in archive operations - Default behavior: Files/images referenced only in comments are considered "used" and will NOT be archived
- Automatic generation of detailed reports showing commented-only references with exact locations (file paths, line numbers, and text)
- Report paths:
./archive/commented-references-report.txt(files) and./archive/commented-image-references-report.txt(images) - Dual tracking system separates uncommented references from commented-only references
- State management automatically moves items from "commented-only" to "used" when uncommented reference found
- New
- Detection patterns - Added robust regex-based commented line detection
- Files:
^\s*//.*include::(.+?)\[detects commented includes with whitespace variations - Images:
^\s*//checks if entire line is commented before checking for image references - Handles AsciiDoc comment syntax variations correctly
- Files:
- GitHub Pages - Updated archive-unused-files.md with commented references behavior section
- Added explanation of default behavior vs --commented flag
- Added "Working with Commented References" examples section with practical workflows
- GitHub Pages - Updated archive-unused-images.md with commented references behavior section
- Added detailed commented references behavior documentation
- Added workflow examples for reviewing and archiving commented-only content
- GitHub Pages - Updated tools/index.md with "NEW" badges for commented references features
- Updated both archive-unused-files and archive-unused-images feature lists
- Updated quick usage examples to demonstrate new functionality
- CLAUDE.md - Added comprehensive "Commented References Tracking" section
- Documented implementation details, detection patterns, and test coverage
- Added to "Recent Improvements" section for future development reference
- Test coverage - Added comprehensive tests for commented references functionality
test_archive_unused_files_commented_references(): Verifies default behavior treats commented-only as "used"test_archive_unused_files_with_commented_flag(): Verifies --commented flag includes commented-only filestest_archive_unused_images_commented_references(): Verifies image detection for commented-only referencestest_archive_unused_images_with_commented_flag(): Verifies --commented flag includes commented-only images- All tests use line-by-line exact matching to avoid substring false positives
- Total test coverage: 10/10 tests passing (4 new tests added)
- Callout detection - Fixed false positives with Java generics and angle-bracket syntax
- Removed user-replaceable value extraction from both
detector.pyandconverter_deflist.py - Java generics like
CrudRepository<MyEntity, Integer>no longer incorrectly extracted - Full code lines now preserved in definition list terms
- Fixes issue where
<MyEntity, Integer>was extracted instead of the complete code line
- Removed user-replaceable value extraction from both
- Callout detection - Fixed semicolon removal bug in Java/C/C++/JavaScript code
- Removed semicolon (;) from CALLOUT_WITH_COMMENT regex pattern
- Semicolons now correctly preserved as statement terminators
- Example:
Optional<String> name; <1>now correctly becomesOptional<String> name; - Semicolon was being treated as comment marker (Lisp-style) causing false removal
- Interactive tool - Fixed quit/exit behavior and added explicit quit option
- Ctrl+C now immediately exits script (was continuing to summary)
- Added 'Q' (capital) option to quit script entirely at any prompt
- Clarified 'q' (lowercase) as "Skip current file" instead of ambiguous "Quit"
- All lowercase options now case-insensitive for better user experience
- GitHub Pages - Updated convert-callouts-to-deflist.md to reflect removal of angle-bracket extraction
- Changed "Intelligent Value Extraction" to "Code Line Extraction" section
- Updated examples to show full code lines in definition list terms
- GitHub Pages - Updated convert-callouts-interactive.md keyboard shortcuts
- Documented distinction between 'q' (skip file) and 'Q' (quit script)
- Added Ctrl+C immediate exit behavior
- CLAUDE.md - Added pipx installation and upgrade procedures
- Documented full upgrade procedure with build artifact cleaning
- Added key phrase "upgrade doc-utils" for Claude automation
- Explained why cleaning build artifacts is critical before reinstalling
- Version reporting - Fixed version.py not synced with pyproject.toml
- Updated doc_utils/version.py from 0.1.30 to match current release
- Now properly reports v0.1.32 instead of outdated v0.1.30
- CLI tools - Added
--versionoption to callout conversion toolsconvert-callouts-to-deflist --versionnow displays version informationconvert-callouts-interactive --versionnow displays version information- Both tools import version from doc_utils.version for consistency
-
convert-callouts-to-deflist - Added
--forceoption to strip callouts despite warnings- Allows conversion to proceed when callout warnings are present (missing explanations or mismatches)
- Strips callouts from blocks with missing explanations without creating explanation lists
- Converts blocks with callout mismatches using available explanations
- Requires confirmation prompt before proceeding (skipped in dry-run mode)
- Useful for intentionally shared explanations between conditional blocks
- Documented in warnings report and GitHub Pages with comprehensive examples
-
Warnings Report - Automatic generation of structured AsciiDoc warnings report
- Enabled by default, generates
callout-warnings-report.adocin current directory - Reduces console spam by showing minimal summary: "
⚠️ 4 Warning(s) - See callout-warnings-report.adoc for details" - Report includes summary by warning type, recommended actions, and force mode documentation
- Callout mismatch analysis detects duplicates, missing callouts, extra callouts, and off-by-one errors
- Missing explanations section lists possible causes (shared explanations, unexpected location, missing)
- Command-line options:
--warnings-report(default),--no-warnings-report,--warnings-file=<path> - Can be committed to git to track warning resolution progress
- Enabled by default, generates
-
convert-callouts-to-deflist - Warning for code blocks with callouts but no explanations
- Detects when code block has callouts but no explanation table or list found
- Provides helpful diagnostic message with possible causes
- Suggests manual review for shared explanations or documentation errors
-
Table parser - Improved detection of callout explanations in tables
- Now handles cell type specifiers without leading pipe (e.g.,
a|at start of line) - Accepts both
|cellanda|cellformats for AsciiDoc cell type specifiers - Recognizes all cell type specifiers: a, s, h, d, m, e, v
- Fixed issue where code block closing delimiter (
----) was incorrectly treated as new code block start - Added logic to skip closing delimiter before searching for callout table
- Now handles cell type specifiers without leading pipe (e.g.,
-
Table parser - Support for plain number callouts in tables (in addition to angle-bracket format)
- Tables can now use plain numbers (1, 2, 3) instead of angle-bracket format (
<1>,<2>,<3>) - Unified detection via
_is_callout_or_number()method accepting both formats - Increased detection rate: 58% more files detected, 130% more code blocks found
- Example: First column can be
1or<1>, both are recognized as callout references
- Tables can now use plain numbers (1, 2, 3) instead of angle-bracket format (
-
Validation warnings - Show duplicate callout numbers in explanations
- Warnings now preserve duplicates:
[1, 2, 3, 4, 5, 7, 8, 8, 9]instead of deduplicated[1, 2, 3, 4, 5, 7, 8, 9] - Added
get_table_callout_numbers()method to extract raw callout numbers from tables - Updated
validate_callouts()to return lists instead of sets to preserve duplicates - Helps identify table rows with incorrect callout numbering
- Warnings now preserve duplicates:
-
User guidance - Added suggestion messages when warnings occur
- Console shows: "Suggestion: Review and fix the callout issues listed in [report], then rerun this command."
- Warnings report includes "Recommended Actions" section with 4-step workflow
- Clear guidance on when to use force mode and how to review changes
- CRITICAL - Preserve content between code block and explanations
- Fixed bug where converter deleted
endif::directives, continuation markers (+), and paragraph text - Now uses
detector.last_table.start_lineto accurately find where explanations begin - Preserves slice
new_lines[content_end + 1:explanation_start_line]containing critical AsciiDoc directives - Applies to both comments format and definition list/bullets formats
- Prevents corruption of conditional compilation blocks in documentation
- Fixed bug where converter deleted
-
convert-callouts-to-deflist.md - Documented force mode option
- Added
--forceoption to Options section with "USE WITH CAUTION" warning - Added "Force Mode" subsection with confirmation prompt example
- Documented what force mode does for missing explanations and callout mismatches
- Included 6-step recommended workflow
- Provided real-world example of appropriate force mode usage (shared explanations in conditionals)
- Added
-
Warnings Report - Documented warnings report feature
- Added "Warnings Report File" section explaining enabled-by-default behavior
- Documented command-line options for controlling report generation
- Listed benefits: clean console output, structured format, git tracking, AsciiDoc rendering
-
convert-callouts-to-deflist/interactive - Fixed support for AsciiDoc table cells with
a|type specifier- Recognize
a|on its own line as cell separator with type specifier, not just a cell content marker a|now correctly starts a new cell rather than modifying the current cell type- Preserve blank lines as content within
a|(AsciiDoc) cells instead of treating them as row separators - Parse
colsattribute (e.g.,[cols="1,7a"]) to determine expected number of columns per row - Auto-finalize rows when column count is reached, enabling proper multi-row table parsing
- Recognize
-
convert-callouts-to-deflist/interactive - Fixed handling of conditionals in table cells
- Keep conditional directives (ifdef::/ifndef::/endif::) inline with cell content instead of extracting to separate lists
- Insert continuation markers (
+) before conditionals in definition lists to prevent list breakout - Insert continuation markers to bridge blank lines in explanations
- Prevents invalid AsciiDoc where blank lines would break definition list structure
- Conditionals within
a|cells are now preserved correctly across blank lines
- Table parser - Improved conditional handling logic
- Check if currently building a cell (
current_cell_linesnot empty) when processing conditionals - Conditionals are added to cell content when inside a cell, rather than to row-level conditional lists
- Preserve conditional context across blank lines in
a|cells
- Check if currently building a cell (
- Added
_parse_column_count()method to extract column count from tablecolsattribute - Added
_finalize_row_if_complete()method to auto-finalize rows based on column count - Updated conditional detection to handle cells being built vs cells already saved
- Tested on Debezium documentation repository (70 files, 12 files with callouts detected, 27 code blocks would convert)
-
format-asciidoc-spacing - Fixed conditional block cohesion to prevent unwanted blank lines
- Tool no longer inserts blank line between conditional directives (ifdef::/ifndef::/endif::) and their enclosed content
- Conditional directives and their content now stay "glued" together as a logical unit
- Prevents breaking block titles that immediately follow conditional directives
- Example:
ifndef::foo[]followed by.Additional resourcesno longer gets a blank line inserted between them
-
format-asciidoc-spacing - Fixed list continuity across conditional blocks
- Tool no longer inserts blank line after endif:: when next line is a list item
- Supports all list formats: bulleted (*), dashed (-), dotted (., ..), and numbered (1., 2., etc.)
- Supports list continuation marker (+)
- Ensures lists that span conditional blocks remain unbroken
- version_check.py - Updated install method detection to default to pipx
- Version update notifications now show
pipx upgradecommand by default - Improved detection for pipx installations including editable installs
- Made sys.prefix check case-insensitive for better compatibility
- Aligns with project guidelines to always recommend pipx as the preferred installation method
- Version update notifications now show
-
convert-callouts-to-deflist.md - Comprehensive documentation improvements
- Standardized section ordering for consistency with interactive tool documentation
- Fixed terminology: replaced "two-column" with "multi-column" throughout
- Restructured overly long examples section for better readability
- Enhanced Features section with better organization and Smart Comment Handling details
- Added Technical Details section with links to callout_lib library
-
convert-callouts-interactive.md - Added missing content and improved organization
- Added Automatic Format Detection feature section
- Added Smart Comment Handling feature with interactive warning details
- Added Validation and Safety feature section
- Added exclusion examples (--exclude-dir, --exclude-file, --exclude-list)
- Added missing CLI options to Options section (--max-comment-length, --exclude-file, --exclude-list)
- Added Technical Details section with library links and supported comment syntax
- doc_utils_cli.py - Added convert-callouts-interactive to help output
- Tool now appears in
doc-utils --helpanddoc-utils --listoutput - Updated convert-callouts-to-deflist description to clarify it's batch mode
- Both callout conversion tools now clearly documented with their use cases
- Tool now appears in
-
callout_lib/converter_deflist.py - Fixed whitespace handling in definition list terms
- Code lines now have leading and trailing whitespace stripped before wrapping in backticks
- Previously terms like
` 'execute-snapshot',`would preserve indentation from code blocks - Now properly formatted as
`'execute-snapshot',`without extra whitespace
-
callout_lib/converter_bullets.py - Fixed whitespace handling in bulleted list terms
- Applied same whitespace stripping fix as definition list converter
- Ensures consistent clean formatting across all output formats
-
callout_lib/table_parser.py - Fixed critical table parsing bug with multi-cell header rows
- Multi-cell lines (e.g.,
|Item |Field name |Description) now properly complete a row - Previously, header and first data row would merge into a single 6-cell row
- Caused first item in 3-column tables to be skipped during extraction
- Now correctly parses header as separate row, allowing all data rows to be processed
- Multi-cell lines (e.g.,
- callout_lib/detector.py - Updated 3-column table explanation format
- Changed from verbose "Refers to
value." pattern to simple label`value`: - More concise and cleaner output while maintaining clarity
- Format:
`op`:instead ofForop:orRefers toop. - Follows minimal label pattern that clearly identifies field being explained
- Changed from verbose "Refers to
- convert-callouts-to-deflist - Fixed bug where table-format callout explanations were not removed when converting to inline comments format
- Previously, only the callout numbers were converted to comments while the explanation table remained in the document
- Now properly skips over the entire table when converting to comments format
-
callout_lib/table_parser.py - Support for 3-column table format (Item | Value | Description) used in Debezium documentation
- Added
is_3column_callout_table()method to detect 3-column callout tables - Added
extract_3column_callout_explanations()method to extract data from 3-column tables - Added header row detection with automatic skipping using keyword matching
- Added inline cell separator parsing for tables with multiple cells on same line (e.g.,
|Cell1 |Cell2 |Cell3) - Updated
find_callout_table_after_code_block()to detect both 2-column and 3-column tables
- Added
-
callout_lib/detector.py - Enhanced to handle 3-column table format
- Added
_extract_from_3column_table()method - Detection priority: 3-column table → 2-column table → list format
- Combines value and description columns into meaningful explanations: "Refers to
value. Description..."
- Added
- Tested with real Debezium documentation from GitLab repository
- All 153 tests pass with new 3-column table support
- Updated GitHub Pages documentation for both convert-callouts tools with 3-column table examples
- Updated CLAUDE.md to reflect full 3-column table support
- callout_lib/table_parser.py - New AsciiDoc table parser module
- Parses two-column tables with callout numbers and explanations
- Detects callout explanation tables automatically with
is_callout_table()method - Extracts callout explanations from table format:
extract_callout_explanations_from_table() - Finds callout tables after code blocks:
find_callout_table_after_code_block() - Converts tables to definition lists:
convert_table_to_deflist() - Converts tables to bulleted lists:
convert_table_to_bullets() - Preserves conditional statements (ifdef/ifndef/endif) within table cells
- Designed for reusability - supports future utilities for general table conversion
- Comprehensive test coverage with 15 unit tests
-
callout_lib/detector.py - Now supports both list-format and table-format callout explanations
- Automatically detects callout explanation format (list vs table)
- Tries table format first, falls back to list format if not found
- Smart prioritization: list format closer to code block takes precedence over distant tables
- Prevents false positives by stopping search when encountering list-format explanations
- Integration tests verify mixed documents with both formats work correctly
-
convert-callouts-to-deflist and convert-callouts-interactive - Transparent table format support
- Both tools now automatically handle table-format callout explanations
- No CLI changes required - enhancement is transparent to users
- Supports conditional statements in table cells (ifdef/ifndef/endif)
- Converts table callouts to all three output formats: definition lists, bulleted lists, inline comments
- Updated callout_lib/README.md with table parser documentation
- Added table_parser.py to architecture diagram and module list
- Documented table parser API with usage examples
- Explained conditional statement support in tables
- Noted future use cases for general table conversion utilities
- Updated version history to v1.1
- Updated CLAUDE.md with table format support in recent improvements section
- Created comprehensive test fixtures with realistic examples based on Debezium documentation patterns
- Added tests/test_table_parser.py with 15 tests covering table parsing functionality
- Added tests/test_table_callout_conversion.py with 6 integration tests for end-to-end conversion workflows
- All 153 tests pass (100% success rate)
-
callout_lib - New modular library for AsciiDoc callout conversion
detector.py- Shared module for detecting and extracting callouts from code blocksconverter_deflist.py- Definition list converter moduleconverter_bullets.py- Bulleted list converter moduleconverter_comments.py- Inline comments converter with language-specific comment syntax- Supports 40+ programming languages with automatic comment syntax detection
- Includes
LongCommentWarningsystem for detecting overly long explanations - Proper separation of concerns with dataclasses for type safety
-
convert-callouts-interactive - New interactive callout conversion tool
- Per-code-block format selection with visual preview
- Color-coded output for better readability (highlights callouts, shows context)
- Choose format for each code block individually: definition list, bulleted list, or inline comments
- Interactive warning prompts for long comments with 4 options:
- Shorten to first sentence
- Fall back to definition list format
- Fall back to bulleted list format
- Skip the block
- "Apply to all" option for batch processing remaining blocks
- Context-aware display with configurable context lines (--context parameter)
- Full exclusion support (--exclude-dir)
- Dry-run mode for previewing all changes
-
convert-callouts-to-deflist - New
--format commentsoption for inline comments- Converts callouts to inline comments within the code itself
- Automatically detects programming language from [source,language] attribute
- Uses appropriate comment syntax: // for Java/C/Go, # for Python/YAML/Bash, <!-- for HTML/XML, etc.
- Removes separate explanation section entirely
- New
--max-comment-lengthparameter (default: 120 characters) - Automatic fallback to definition list when comments exceed length threshold
- Displays warnings showing which callouts are too long with character counts
- Best for code examples where explanations are brief and fit naturally as comments
- convert-callouts-to-deflist - Refactored to use new callout_lib modules
- Core conversion logic now in shared library for code reusability
- Both batch and interactive tools share same conversion engine
- Improved code organization with clear separation of concerns
- More maintainable architecture with modular converters
- Added comprehensive documentation for convert-callouts-interactive tool
- Updated convert-callouts-to-deflist documentation with new comments format
- Added inline comments format section with examples
- Added language support details (40+ languages)
- Updated options and examples
- Added decision guide callouts at top of both tool docs to help users choose the right tool
- Quick decision matrix: batch vs interactive, automation vs editorial review
- Cross-references between related tools
- Created callout_lib/README.md with library architecture and usage examples
- Updated CLAUDE.md with callout conversion utilities section
- Added tools to CLI Tools list
- Added callout_lib to Core Modules
- Updated project structure diagram
- Added detailed "Callout Conversion Utilities" to Recent Improvements
- convert-callouts-to-deflist - New
--formatoption to choose output format--format deflist(default): Definition list with "where:" prefix--format bullets: Bulleted list following Red Hat style guide format- Bulleted format uses
* \element`: explanation` syntax with proper indentation - Both formats support all existing features (merged callouts, optional markers, etc.)
- See: https://redhat-documentation.github.io/supplementary-style-guide/#explain-commands-variables-in-code-blocks
- Documentation - Improved navigation visibility on GitHub Pages
- All 9 tool pages now visible at top level of navigation (not hidden under collapsed section)
- Tools grouped together immediately after "Tools Reference" overview page
- Navigation order: Home → Getting Started → Tools Reference → 9 tool pages → Best Practices → Contributing
- Better discoverability and user experience
- Added "Output Formats" section with examples of both deflist and bullets formats
- Added guidance on when to use each format
- Updated Options, Best Practices, and Example Workflow sections
- convert-callouts-to-deflist - Automatic merging of multiple callouts on same line
- When multiple callouts appear on one line (e.g.,
@BasicAuthentication <1> <2>), their explanations are now merged - Uses AsciiDoc list continuation marker (
+) to combine related explanations - Results in cleaner, more semantic output without duplicate definition list terms
- Follows AsciiDoc best practices for merging related list items
- When multiple callouts appear on one line (e.g.,
- convert-callouts-to-deflist - Fixed detection of all callouts when multiple appear on one line
- Previously only detected the last callout, causing warnings like "code has [2, 3, 4], explanations have [1, 2, 3, 4]"
- Updated regex pattern from
<(\d+)>\s*$to<(\d+)>to match all callouts - Modified
extract_callouts_from_code()to usefinditer()for finding all matches - Enhanced
remove_callouts_from_code()to strip trailing whitespace after removing multiple callouts
- convert-callouts-to-deflist - Complete refactoring to support callout grouping
- Added
CalloutGroupdataclass to group callouts by their source code line - Modified
extract_callouts_from_code()to returnList[CalloutGroup]instead ofDict[int, str] - Updated
create_definition_list()to merge explanations for grouped callouts - Updated
validate_callouts()to work withCalloutGroupstructure
- Added
- Added Example 3 showing multiple callouts being merged with continuation markers
- Added prominent
⚠️ REVIEW CAREFULLY warnings about merged callouts - Added "Why This Matters" and "When to Review" sections
- Updated Edge Cases, Technical Details, and Processing Algorithm sections
- Clarified Limitations about multi-line explanation support
- convert-callouts-to-deflist - New tool for converting AsciiDoc callouts to definition list format
- Converts code blocks with callout-style annotations (
<1>,<2>, etc.) to cleaner definition list format - Uses "where:" prefix for semantic clarity
- Automatically extracts user-replaceable values from code (e.g.,
<my-secret>) - Falls back to using actual code lines when no replaceable values found
- Validates that callout numbers in code match explanation numbers
- Supports optional markers ("Optional." or "(Optional)")
- Handles non-sequential callout numbers
- Preserves legitimate angle brackets (Java generics, heredoc syntax)
- Processes all
.adocfiles recursively by default - Supports exclusion lists for directories and files
- Dry-run mode for previewing changes
- Displays warnings for callout mismatches with file and line numbers
- Automatically excludes
.valedirectory by default
- Converts code blocks with callout-style annotations (
- Added comprehensive documentation for convert-callouts-to-deflist tool
- Includes transformation examples, usage patterns, and edge cases
- Updated Tools Reference index with new tool
- format-asciidoc-spacing - Now adds blank lines between consecutive includes within conditional blocks
- Previously, includes inside
ifdef::/ifndef::blocks were left untouched - Now adds visual separation between includes enclosed in conditionals
- Improves readability and maintains consistency with non-conditional includes
- Example: Consecutive includes in
ifdef::openshift-rosa[]blocks now have blank lines between them
- Previously, includes inside
- Documentation - Removed
[EXPERIMENTAL]tags from tools now considered stablevalidate-links- No longer marked as experimentalformat-asciidoc-spacing- No longer marked as experimental- Updated all documentation, README, and CLI help text
- GitHub Pages - Navigation now keeps "Tools Reference" section expanded by default
- Added
nav_fold: falseconfiguration for better user experience - All 8 tools visible in left navigation without clicking to expand
- Added
- New
doc-utilscommand - Main CLI hub for discovering and accessing all toolsdoc-utils --helpshows comprehensive help with all tools listeddoc-utils --listdisplays quick list of available toolsdoc-utils --versionshows package version- Provides single entry point for users to discover functionality
- Version flag support - All 8 CLI tools now support
--versionflag- Centralized version management in
doc_utils/version.py - Version synchronized with
pyproject.toml - Example:
find-unused-attributes --version→find-unused-attributes 0.1.20
- Centralized version management in
- Smart upgrade notifications - Update notifications now detect installation method
- Automatically detects whether package was installed with
pipxorpip - Recommends appropriate upgrade command (
pipx upgradeorpip install --upgrade) - Respects user's chosen installation method
- Detection checks
sys.prefixandPIPX_HOMEenvironment variable
- Automatically detects whether package was installed with
- Test coverage - Added 12 new tests for version checking functionality
- Tests for installation method detection
- Tests for version parsing and comparison
- Tests for notification display logic
- Total test count increased from 120 to 132 tests (100% passing)
- format-asciidoc-spacing - Significant improvements to spacing logic based on modular-docs templates
- Now adds blank lines between consecutive include statements for better visual separation
- Comments preceding includes stay together as a logical unit (no blank line between comment and include)
- Comments preceding conditional blocks (ifdef/ifndef) stay together without intervening blank lines
- Added support for comment block spacing (blank line after closing
////delimiter) - Added support for block title spacing (blank line before
.Titleblocks like.Prerequisites) - Role blocks (
[role="..."]) are now recognized and handled appropriately - Improved handling of heading spacing (no blank line added when followed by comment block)
- All spacing rules now align with Red Hat modular documentation templates
- format-asciidoc-spacing - Fixed edge cases in spacing logic
- Standalone comments and attributes now handled correctly
- Block titles no longer add extra spacing when preceded by role blocks
- Better detection of logical groupings (comment+include, comment+conditional)
- Initial release tracking (version sync fix)
- find-unused-attributes - Fixed critical bug where conditional attributes were misidentified as unused
- Now detects attributes used in
ifdef::attr[],ifndef::attr[], andendif::attr[]directives - Previously only detected
{attribute}text substitution references - Fixes false positives for conditional attributes like
:rh-only:,:downstream:,:no-*: - Reduces incorrect "unused" reports by correctly identifying attributes used for conditional content inclusion/exclusion
- Now detects attributes used in
- find-unused-attributes - New
--comment-outoption to safely mark unused attributes- Comments out unused attributes with
// Unusedprefix instead of deleting them - Interactive confirmation prompt before modifying files
- Preserves all formatting, comments, and blank lines
- Non-destructive approach allows easy restoration by removing comment prefix
- Git-friendly workflow for managing attribute cleanup
- Comments out unused attributes with
- Added comprehensive test coverage for conditional directive detection (5 new tests)
- Added test coverage for comment-out functionality (3 new tests)
- Updated documentation with examples for both conditional directives and comment-out feature
- All 120 tests pass
- Automatic update notifications - All CLI tools now check for updates on PyPI
- Non-blocking check that won't interfere with tool operation
- Shows notification when a newer version is available
- Caches check results for 24 hours to minimize network requests
- Can be disabled with
DOC_UTILS_NO_VERSION_CHECK=1environment variable - Automatically skipped in CI environments or non-terminal contexts
- Added
version_check.pymodule with intelligent caching and error handling - Update notifications use stderr to avoid interfering with tool output
-
extract-link-attributes - Fixed critical bug where attributes files would become self-referencing
- Previously, the tool would replace attribute values with self-references (e.g.,
:link-foo: {link-foo}) - Now automatically excludes ALL attributes files from being scanned/modified
- Shows which attributes files are being excluded when multiple exist
- Prevents any attributes file from having its link/xref macros replaced
- Previously, the tool would replace attribute values with self-references (e.g.,
-
replace-link-attributes - Enhanced to exclude ALL attributes files from processing
- Previously only excluded the selected attributes file
- Now excludes all discovered attributes files to prevent unwanted modifications
- Shows exclusion list when multiple attributes files exist
- Ensures attributes files are treated as definition files, not content files
- Both tools now follow consistent safety principles for handling attributes files
- Improved user feedback showing which files are being excluded from processing
- Macro type filtering - Both
extract-link-attributesandreplace-link-attributesnow support--macro-typeoption- New
--macro-type {link,xref,both}option to limit operations to specific macro types - Process only
link:macros with--macro-type link - Process only
xref:macros with--macro-type xref - Process both (default) with
--macro-type both - Useful when you need to handle external links vs internal cross-references differently
- New
- Added comprehensive test coverage for macro type filtering
- New tests for
find_link_macros()with macro_type parameter - New tests for
replace_link_attributes_in_file()with macro_type parameter - All 112 tests passing
- New tests for
- Updated GitHub Pages documentation for both tools with macro type filtering examples
- Added usage examples for
--macro-typeoption
- extract-link-attributes - Now replaces link macros with existing attribute references
- Previously only created new attributes and skipped existing ones
- Now replaces link macros even when matching attributes already exist
- Useful for cleaning up existing documentation
- Provides clear feedback on created vs reused attributes
- Makes the tool more useful for ongoing maintenance
-
Link validation feature for
extract-link-attributestool- New
--validate-linksoption to validate URLs in link-* attributes before extraction - New
--fail-on-brokenoption to exit if broken links are found - Validates both existing link attributes and newly created attributes
- Reports broken links with line numbers for easy fixing
- Useful for CI/CD pipelines to ensure link quality
- New
-
Visual progress indicators (spinners) for all tools
- Added animated spinners to show progress during long operations
- Provides better user feedback when processing many files
- Thread-based implementation for smooth performance
- Shows success/failure indicators when operations complete
find-unused-attributesauto-discovery improvements- Better error messages for troubleshooting
- Clearer output when no attributes files are found
- Improved error handling across all tools
- Fixed display issues with spinner output clearing
- Replaced "abort/aborting" terminology with "exit/stopping" throughout codebase
- Added comprehensive documentation for link validation feature
- Updated GitHub Pages with validation examples
- Enhanced CI/CD integration examples with validation flags
- New
validate-linkstool [EXPERIMENTAL] for validating all documentation links- URL transposition feature for validating against preview/staging environments
- Format:
--transpose "https://prod.com--https://preview.com" - Concurrent link checking with configurable parallelism
- Resolves AsciiDoc attributes before validation
- Validates external URLs, internal xrefs, and image paths
- Smart caching and retry logic for transient failures
- Multiple output formats (text, JSON, JUnit planned)
--fail-on-brokenoption for CI/CD integration- Marked as EXPERIMENTAL - interface and behavior may change
-
find-unused-attributestool now includes auto-discovery feature- Can run without specifying file: just use
find-unused-attributes - Interactive file selection when multiple attributes files are found
- Searches for common patterns:
**/attributes.adoc,**/*attributes.adoc, etc. - Backward compatible: can still specify file directly
- Better error handling with helpful messages for missing files
- Consistent with
replace-link-attributesdiscovery behavior
- Can run without specifying file: just use
-
format-asciidoc-spacingtool marked as [EXPERIMENTAL]- Added experimental warning to documentation
- Formatting rules may evolve based on user feedback
- Improved error handling in
find-unused-attributesfor missing or invalid files- Now provides clear error messages instead of Python tracebacks
- Validates file existence and permissions before processing
- Added comprehensive documentation for
validate-linkstool - Updated
find-unused-attributesdocumentation with auto-discovery examples - Marked experimental features clearly in all documentation
- Updated release process in CLAUDE.md to avoid duplicate GitHub release errors
- New
extract-link-attributestool for creating reusable link attribute definitions- Extracts link: and xref: macros containing attributes into attribute definitions
- Handles link text variations with interactive selection mode
- Reuses existing attributes on subsequent runs (idempotent operation)
- Generates meaningful attribute names from URLs
- Supports both interactive and non-interactive modes
- Preserves macro type (link vs xref) in attribute values
- Automatically discovers attribute files or allows custom specification
- Dry-run mode to preview changes before applying
- Replaces original macros with attribute references throughout documentation
- Complementary tool to
replace-link-attributesfor complete link management workflow
- Added comprehensive documentation for
extract-link-attributestool - Updated all documentation to include the new tool
- Enhanced tool descriptions and usage examples
- New
replace-link-attributestool for resolving Vale AsciiDocDITA LinkAttribute issues- Replaces attribute references in link: and xref: macro URLs with their resolved values
- Preserves link text unchanged (only modifies URLs)
- Automatically discovers all attributes.adoc files in repository
- Interactive mode for selecting or specifying custom attribute files
- Supports any attribute file name/path via --attributes-file option
- Resolves nested attribute references automatically
- Dry-run mode to preview changes before applying
- Helps fix Vale LinkAttribute rule: "DITA 1.3 does not allow references to reusable content in link URLs"
- Refactored
format-asciidoc-spacingto follow project architecture pattern- Core logic moved to
doc_utils/format_asciidoc_spacing.pymodule - CLI script now imports from module (separation of concerns)
- Core logic moved to
- Added pipx upgrade instructions to README.md and getting-started.md
- Fixed incorrect Python file name references in documentation
- Improved release procedure in CLAUDE.md with better error handling and recovery steps
- Enhanced documentation based on user feedback
- Major improvements to
format-asciidoc-spacingtool:- Special handling for attribute includes near H1 headings (e.g., common-attributes.adoc)
- Ignores admonition block delimiters (====, ----, ...., ____) instead of treating them as headings
- Keeps comments directly above includes together as a unit with the include
- Keeps attributes directly above includes together as a unit with the include
- Treats conditional blocks (ifdef/ifndef/endif) as single units with proper spacing
- Consolidates multiple consecutive blank lines that would be inserted into a single blank line
- Improved detection of headings (requires space after = signs)
- Cleaned up repository structure by archiving duplicate documentation files from root directory
- Documentation for tools now centralized in
/docs/tools/for GitHub Pages site
- New
format-asciidoc-spacingtool for standardizing AsciiDoc formatting- Ensures blank lines after headings (=, ==, ===, etc.)
- Adds blank lines around include:: directives
- Supports dry-run mode to preview changes
- Verbose mode for detailed change tracking
- Processes single files or entire directories recursively
- Implemented in Python with no external dependencies
- Automatic directory discovery for
archive-unused-filestool- Recursively finds all
modulesandassembliesdirectories containing.adocfiles - Works with any repository structure (nested, multiple locations, etc.)
- New
--scan-diroption to override auto-discovery with specific directories - Shows discovered directories in output for transparency
- Recursively finds all
archive-unused-filesno longer requires hardcoded directory paths- Previously required
./modulesand./assembliesat root level - Now works from any repository root regardless of structure
- Backwards compatible:
--scan-diroption allows specifying custom paths
- Previously required
- Safety warnings displayed when running archive utilities
- Post-installation message reminding users about safety practices
- Comprehensive tests for symlink handling
- Fixed infinite loop/freeze when
archive-unused-filesencounters circular symbolic links- Replaced recursive glob with os.walk that explicitly skips symlink directories
- Prevents freezing when repositories contain circular symlinks (e.g., in .archive directories)
- Support for OpenShift-docs style repositories that use topic maps instead of master.adoc files
- New
topic_map_parser.pymodule for parsing_topic_maps/*.ymlfiles - Automatic repository type detection (topic maps vs traditional master.adoc)
- PyYAML dependency for parsing topic map YAML files
- 9 new tests for topic map parsing functionality
archive-unused-filestool now works with both OpenShift-docs and traditional AsciiDoc repositories- Updated documentation to explain dual repository type support
- Improved installation instructions to include pipx and --user options
- Comprehensive test coverage for core functionality
- Added 14 tests for
file_utils.pycovering file collection and archiving - Added 15 tests for CLI entry points
- Added 3 tests for exclusion list parsing
- Total test coverage increased to 47 tests with 100% pass rate
- Added 14 tests for
- New
parse_exclude_list_file()function infile_utils.pyfor centralized exclusion list parsing - Exclusion support (--exclude-dir, --exclude-file, --exclude-list) added to
check-scannabilitytool CLAUDE.mdfile for AI assistant context and development guidelines
- Refactored exclusion list parsing to eliminate code duplication across CLI tools
- Improved module import handling with
py-modulesconfiguration inpyproject.toml - Moved test fixtures from root directory to
tests/directory for better organization - Updated README.md with:
- Development installation instructions
- Comprehensive troubleshooting section for ModuleNotFoundError
- Directory/file exclusion documentation
- Fixed ModuleNotFoundError when running CLI commands without proper installation
- Fixed substring matching issues in tests that were causing false failures
- Corrected test expectations for check-scannability output behavior
- Removed unused
reimport fromfile_utils.py - Removed legacy test runner files (
test_run_*.py) - Removed obsolete
fixtures-README-legacy.txt
- Initial release with basic functionality