Contributing to SwiftMarkdownParser
July 3, 2025 ยท View on GitHub
Thank you for your interest in contributing to SwiftMarkdownParser! We welcome contributions from the community and are excited to see what you'll bring to the project.
๐ค How to Contribute
1. Fork the Repository
- Fork the project on GitHub by clicking the "Fork" button in the top-right corner
- Clone your fork to your local machine:
git clone https://github.com/YOUR_USERNAME/SwiftMarkdownParser.git cd SwiftMarkdownParser - Add the original repository as a remote:
git remote add upstream https://github.com/sciasxp/SwiftMarkdownParser.git
2. Set Up Development Environment
-
Requirements:
- Xcode 16.0+ with Swift 6.0+
- iOS 18.0+ / macOS 15.0+ SDK
-
Verify setup:
swift --version swift test -
Open in Xcode (optional):
open Package.swift
3. Create a Feature Branch
Always create a new branch for your changes:
git checkout -b feature/your-feature-name
# or
git checkout -b fix/issue-description
# or
git checkout -b docs/documentation-update
Branch naming conventions:
feature/- New features or enhancementsfix/- Bug fixesdocs/- Documentation updatestest/- Test improvementsrefactor/- Code refactoring
4. Make Your Changes
Code Guidelines
- Follow Swift conventions: Use SwiftLint rules and Swift API Design Guidelines
- Write tests: All new features should include comprehensive tests
- Document your code: Add inline documentation for public APIs
- Keep commits atomic: One logical change per commit
Testing Your Changes
# Run all tests
swift test
# Run specific test suites
swift test --filter SwiftMarkdownParserTests
# Run with verbose output
swift test --verbose
# Test on different platforms (if available)
swift test --destination platform=iOS
swift test --destination platform=macOS
Code Style
- Indentation: 4 spaces (no tabs)
- Line length: 120 characters maximum
- Access control: Explicit access levels (
public,internal,private) - Naming:
PascalCasefor types and protocolscamelCasefor functions and variablesUPPER_CASEfor constants
Example:
/// Parse a GFM table from markdown tokens
///
/// - Parameter tokens: The token stream to parse
/// - Returns: A GFMTableNode or nil if parsing fails
/// - Throws: MarkdownParsingError if the table structure is invalid
public func parseGFMTable(_ tokens: TokenStream) throws -> AST.GFMTableNode? {
// Implementation here
}
5. Commit Your Changes
Write clear, descriptive commit messages:
git add .
git commit -m "Add support for GFM table alignment
- Implement left, center, right alignment parsing
- Add alignment property to GFMTableCellNode
- Update HTML renderer to output alignment styles
- Add comprehensive tests for all alignment types
Fixes #123"
Commit message format:
- First line: Brief description (50 chars max)
- Blank line
- Body: Detailed explanation of what and why
- Footer: Reference issues with "Fixes #123" or "Closes #123"
6. Push and Create Pull Request
-
Push your branch:
git push origin feature/your-feature-name -
Create Pull Request on GitHub:
- Go to your fork on GitHub
- Click "Compare & pull request"
- Fill out the PR template with details
-
PR Guidelines:
- Clear title: Describe what the PR does
- Detailed description: Explain the changes and reasoning
- Link issues: Reference related issues with "Fixes #123"
- Screenshots: Include screenshots for UI changes
- Breaking changes: Clearly mark any breaking changes
๐ Reporting Issues
Before Reporting
- Search existing issues to avoid duplicates
- Test with latest version to ensure the issue still exists
- Minimal reproduction: Create the smallest possible example
Issue Template
**Description**
A clear description of the issue.
**Expected Behavior**
What you expected to happen.
**Actual Behavior**
What actually happened.
**Minimal Reproduction**
```swift
let markdown = "..."
let parser = SwiftMarkdownParser()
// Steps to reproduce
Environment
- iOS/macOS version:
- Xcode version:
- Swift version:
- SwiftMarkdownParser version:
Additional Context Any other relevant information.
## ๐ฏ Areas for Contribution
### High Priority
- **Performance optimizations**: Tokenizer and parser improvements
- **GFM extensions**: Math support, footnotes, definition lists
- **SwiftUI renderer**: Native SwiftUI output format
- **Documentation**: API docs, tutorials, examples
- **Test coverage**: Edge cases, performance tests
### Medium Priority
- **Syntax highlighting**: Code block language support
- **Custom extensions**: Plugin system for custom markdown elements
- **Error handling**: Better error messages and recovery
- **Accessibility**: VoiceOver and accessibility improvements
### Good First Issues
- **Documentation fixes**: Typos, clarifications, examples
- **Test additions**: Missing test cases, edge cases
- **Code cleanup**: Refactoring, code organization
- **Example projects**: Sample apps demonstrating usage
## ๐งช Testing Guidelines
### Test Structure
```swift
func test_featureName_condition_expectedResult() async throws {
// Arrange
let markdown = "..."
let parser = SwiftMarkdownParser()
// Act
let ast = try await parser.parseToAST(markdown)
// Assert
XCTAssertEqual(ast.children.count, 1)
XCTAssertTrue(ast.children.first is AST.ParagraphNode)
}
Test Categories
- Unit tests: Individual components and functions
- Integration tests: End-to-end parsing and rendering
- Performance tests: Large document handling
- Edge case tests: Malformed input, boundary conditions
Coverage Goals
- New features: 100% test coverage
- Bug fixes: Test that reproduces the bug + fix verification
- Refactoring: Maintain existing test coverage
๐ Documentation
API Documentation
- Use Swift's documentation comments (
///) - Include parameter descriptions and return values
- Provide usage examples for complex APIs
- Document throwing behavior and error conditions
README Updates
- Keep examples current and working
- Update feature lists when adding capabilities
- Maintain accurate installation instructions
Code Examples
/// Example of parsing a complex markdown document
///
/// ```swift
/// let parser = SwiftMarkdownParser()
/// let ast = try await parser.parseToAST(complexMarkdown)
/// let html = try await parser.parseToHTML(complexMarkdown)
/// ```
๐ Review Process
What to Expect
- Automated checks: Tests, linting, and build verification
- Code review: Maintainer review for code quality and design
- Feedback: Constructive feedback and suggestions
- Iteration: You may need to make changes based on feedback
Review Criteria
- Functionality: Does it work as intended?
- Tests: Are there adequate tests?
- Documentation: Is it properly documented?
- Performance: Does it maintain or improve performance?
- API design: Is it consistent with existing APIs?
- Breaking changes: Are they necessary and well-documented?
๐ Release Process
Versioning
We follow Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
Release Checklist
- All tests passing
- Documentation updated
- CHANGELOG.md updated
- Version bumped in Package.swift
- Git tag created
- GitHub release created
๐ Getting Help
Communication Channels
- GitHub Issues: Bug reports and feature requests
- GitHub Discussions: Questions and community discussion
- Pull Request Comments: Code-specific questions
Maintainer Response Time
- Issues: We aim to respond within 48 hours
- Pull Requests: Initial review within 72 hours
- Questions: Community discussions within 24 hours
๐ Recognition
Contributors will be:
- Listed in CONTRIBUTORS.md: All contributors are recognized
- Mentioned in release notes: Significant contributions highlighted
- Invited as collaborators: Regular contributors may be invited as maintainers
๐ License
By contributing to SwiftMarkdownParser, you agree that your contributions will be licensed under the MIT License.
Thank you for contributing to SwiftMarkdownParser! Your efforts help make markdown parsing better for the entire Swift community. ๐