git clone https://github.com/docToolchain/asciidoc-linter.git
cd asciidoc-linter
Development Guide
Setting Up Development Environment
Clone the Repository
Create Virtual Environment
python -m venv venv
source venv/bin/activate # On Windows: venv\Scripts\activate
pip install -e .
Project Structure
asciidoc-linter/
├── asciidoc_linter/ # Main package
│ ├── __init__.py
│ ├── cli.py # Command line interface
│ ├── rules/ # Rule implementations
│ │ ├── __init__.py
│ │ ├── base.py # Base classes for rules
│ │ ├── heading_rules.py
│ │ ├── block_rules.py
│ │ ├── whitespace_rules.py
│ │ └── image_rules.py
│ ├── parser.py # AsciiDoc parser
│ └── reporter.py # Output formatters
├── tests/ # Test files
│ └── rules/ # Rule-specific tests
├── docs/ # Documentation
└── README.adoc
Current Implementation Status
Implemented Features
-
Core rule engine with base classes
-
Rule implementations:
-
Heading rules (hierarchy, format, multiple top-level)
-
Block rules (termination, spacing)
-
Whitespace rules (spacing, formatting)
-
Image rules (attributes, file verification)
-
-
Basic command line interface
-
Multiple output formats (console, JSON, HTML)
-
Comprehensive test suite
Planned Features
-
Configuration system (YAML/JSON)
-
Rule enabling/disabling
-
Severity customization
-
Custom rule parameters
-
-
Additional rule types
-
IDE integration
-
Git hooks
Adding New Rules
Rule Implementation Steps
-
Create a new rule class:
from .base import Rule, Finding, Severity, Position class MyNewRule(Rule): """ RULE_ID: Short description. Detailed explanation of what the rule checks. """ def __init__(self): super().__init__() self.id = "RULE_ID" @property def description(self) -> str: return "Description of what this rule checks" def check(self, content: str) -> List[Finding]: findings = [] # Implementation here return findings
-
Add tests for the rule:
class TestMyNewRule(unittest.TestCase): def setUp(self): self.rule = MyNewRule() def test_valid_case(self): content = "Valid content" findings = self.rule.check(content) self.assertEqual(len(findings), 0) def test_invalid_case(self): content = "Invalid content" findings = self.rule.check(content) self.assertEqual(len(findings), 1) self.assertEqual(findings[0].rule_id, "RULE_ID")
-
Register the rule in the linter
-
Update documentation
Rule Guidelines
-
Clear rule IDs and descriptions
-
Meaningful error messages
-
Proper severity levels
-
Contextual information in findings
-
Comprehensive test cases
-
Documentation with examples
Code Style
Python Guidelines
-
Follow PEP 8
-
Use type hints
-
Write docstrings (Google style)
-
Keep functions focused and testable
-
Maximum line length: 100 characters
-
Use meaningful variable names
Documentation Guidelines
-
Use AsciiDoc format
-
Include examples for all features
-
Explain error messages
-
Document configuration options
-
Keep README.adoc up to date
Testing
Running Tests
# Run all tests
python run_tests.py
# Run specific test file
python -m unittest tests/rules/test_heading_rules.py
# Run specific test case
python -m unittest tests.rules.test_heading_rules.TestHeadingHierarchyRule
Test Guidelines
-
Write tests for all new features
-
Include both positive and negative test cases
-
Test edge cases
-
Maintain high test coverage
-
Use meaningful test names
Pull Request Process
-
Create feature branch
-
Implement changes
-
Add/update tests
-
Update documentation
-
Run full test suite
-
Submit PR
Release Process
-
Update version number in init.py
-
Update changelog
-
Run full test suite
-
Create release notes
-
Tag release
-
Build and publish
Getting Help
-
GitHub Issues: https://github.com/docToolchain/asciidoc-linter/issues
-
Project Wiki: https://github.com/docToolchain/asciidoc-linter/wiki
-
docToolchain Community: https://doctoolchain.org/community
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.