rumdl 0.0.84__tar.gz → 0.0.85__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of rumdl might be problematic. Click here for more details.
- rumdl-0.0.85/.config/nextest.toml +46 -0
- rumdl-0.0.85/.mise.toml +107 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/CHANGELOG.md +4 -1
- {rumdl-0.0.84 → rumdl-0.0.85}/Cargo.lock +1 -1
- {rumdl-0.0.84 → rumdl-0.0.85}/Cargo.toml +2 -1
- {rumdl-0.0.84 → rumdl-0.0.85}/Makefile +65 -2
- {rumdl-0.0.84 → rumdl-0.0.85}/PKG-INFO +1 -1
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md051.md +4 -1
- rumdl-0.0.85/rust-toolchain.toml +10 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/lint_context.rs +3 -4
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md051_link_fragments.rs +84 -14
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/ast_utils.rs +3 -4
- rumdl-0.0.85/tests/rules/md051_test.rs +1128 -0
- rumdl-0.0.84/tests/rules/md051_test.rs +0 -581
- {rumdl-0.0.84 → rumdl-0.0.85}/.rumdl.toml +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/MANIFEST.in +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/README.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/assets/logo.png +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/benches/fix_performance.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/benches/range_performance.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/benches/range_utils_benchmark.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/benches/rule_performance.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/benches/simple_fix_bench.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/RULES.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/global-settings.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md001.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md002.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md003.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md004.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md005.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md006.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md007.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md009.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md010.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md011.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md012.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md013.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md014.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md018.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md019.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md020.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md021.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md022.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md023.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md024.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md025.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md026.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md027.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md028.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md029.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md030.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md031.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md032.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md033.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md034.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md035.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md036.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md037.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md038.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md039.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md040.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md041.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md042.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md043.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md044.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md045.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md046.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md047.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md048.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md049.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md050.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md052.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md053.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md054.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md055.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md056.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md057.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/docs/md058.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/issues/plan-rule-parity-with-markdownlint.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/parity_check.py +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/pyproject.toml +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/python/MANIFEST.in +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/python/PYTHON-README.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/python/rumdl/__init__.py +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/python/rumdl/__main__.py +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/python/rumdl/py.typed +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/rumdl.toml.example +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/scripts/extract-changelog.sh +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/scripts/prepare-release.sh +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/init.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/lib.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/lsp/mod.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/lsp/server.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/lsp/types.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/main.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/markdownlint_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/parallel.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/performance.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/profiling.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/python.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rule.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rule_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rule_config_serde.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/blockquote_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/code_block_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/code_fence_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/emphasis_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/front_matter_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/heading_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/list_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md001_heading_increment.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md002_first_heading_h1/md002_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md002_first_heading_h1.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md003_heading_style/md003_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md003_heading_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md004_unordered_list_style/md004_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md004_unordered_list_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md005_list_indent.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md006_start_bullets.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md007_ul_indent/md007_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md007_ul_indent.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md009_trailing_spaces/md009_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md009_trailing_spaces.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md010_no_hard_tabs/md010_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md010_no_hard_tabs.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md011_no_reversed_links.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md012_no_multiple_blanks/md012_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md012_no_multiple_blanks.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md013_line_length/md013_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md013_line_length.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md014_commands_show_output/md014_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md014_commands_show_output.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md018_no_missing_space_atx.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md019_no_multiple_space_atx.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md022_blanks_around_headings/md022_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md022_blanks_around_headings.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md023_heading_start_left.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md024_no_duplicate_heading/md024_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md024_no_duplicate_heading.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md025_single_title/md025_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md025_single_title.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md026_no_trailing_punctuation/md026_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md026_no_trailing_punctuation.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md028_no_blanks_blockquote.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md029_ordered_list_prefix.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md030_list_marker_space/md030_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md030_list_marker_space.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md031_blanks_around_fences.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md032_blanks_around_lists.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md033_no_inline_html/md033_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md033_no_inline_html.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md034_no_bare_urls.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md035_hr_style/md035_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md035_hr_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md036_no_emphasis_only_first/md036_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md036_no_emphasis_only_first.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md037_spaces_around_emphasis.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md038_no_space_in_code.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md039_no_space_in_links.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md040_fenced_code_language.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md041_first_line_heading.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md042_no_empty_links.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md043_required_headings.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md044_proper_names/md044_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md044_proper_names.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md045_no_alt_text.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md046_code_block_style/md046_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md046_code_block_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md047_single_trailing_newline.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md048_code_fence_style/md048_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md048_code_fence_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md049_emphasis_style/md049_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md049_emphasis_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md050_strong_style/md050_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md050_strong_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md052_reference_links_images.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md053_link_image_reference_definitions.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md054_link_image_style/md054_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md054_link_image_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md055_table_pipe_style/md055_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md055_table_pipe_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md056_table_column_count.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md057_existing_relative_links/md057_config.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md057_existing_relative_links.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/md058_blanks_around_tables.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/mod.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/rules/strong_style.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/code_block_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/document_structure.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/early_returns.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/element_cache.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/fix_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/markdown_elements.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/mod.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/range_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/regex_cache.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/string_interner.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/src/utils/table_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/advanced_integration_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/character_ranges/additional_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/character_ranges/basic_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/character_ranges/comprehensive_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/character_ranges/extended_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/character_ranges/mod.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/character_ranges/unicode_utils.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/cli_duplication_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/cli_integration_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/cli_lsp_fix_consistency.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/commonmark_compliance_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/comprehensive_integration_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/config_application_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/config_file_command_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/config_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/configuration_inheritance_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/consistency_regression_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/cross_platform_compatibility_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/final_confidence_assessment.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/init_command_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/init_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/integration_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/json_output_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/lib.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/lsp_editor_integration_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/lsp_integration_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/lsp_memory_leak_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/lsp_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/malformed_markdown_stress_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/markdownlint_cli_integration.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/markdownlint_config_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/md030_edge_cases.md +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/output_format_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/perf_check.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/performance_validation_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/pyproject_config_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/real_world_repository_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/regression_prevention_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md001_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md001_unicode_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md002_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md003_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md004_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md005_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md006_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md006_unicode_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md007_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md009_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md010_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md011_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md012_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md013_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md014_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md018_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md019_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md020_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md021_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md022_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md023_extended_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md023_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md024_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md025_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md026_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md027_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md028_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md029_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md030_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md031_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md032_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md033_extended_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md033_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md034_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md035_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md036_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md037_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md038_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md039_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md040_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md041_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md042_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md043_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md044_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md045_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md046_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md047_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md048_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md049_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md050_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md052_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md053_additional_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md053_proptest.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md053_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md054_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md054_unicode_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md055_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md056_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md057_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/md058_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/rules/mod.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/thread_safety_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/unicode_edge_case_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/blockquote_utils_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/code_block_utils_extended_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/code_block_utils_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/core_utils_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/front_matter_utils_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/line_index_test.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils/mod.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils_markdown_edge_cases.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/utils_tests.rs +0 -0
- {rumdl-0.0.84 → rumdl-0.0.85}/tests/vscode_extension_fixes.rs +0 -0
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Nextest configuration
|
|
2
|
+
# https://nexte.st/book/configuration
|
|
3
|
+
|
|
4
|
+
[profile.default]
|
|
5
|
+
# Detect flaky tests and retry them
|
|
6
|
+
retries = { backoff = "exponential", count = 2, delay = "1s", max-delay = "10s" }
|
|
7
|
+
|
|
8
|
+
# Run tests with 2x the number of CPUs
|
|
9
|
+
test-threads = "num-cpus"
|
|
10
|
+
|
|
11
|
+
# Fail fast on first failure in CI
|
|
12
|
+
fail-fast = false
|
|
13
|
+
|
|
14
|
+
# Show failed tests immediately
|
|
15
|
+
failure-output = "immediate"
|
|
16
|
+
|
|
17
|
+
# Show successful tests at the end
|
|
18
|
+
success-output = "final"
|
|
19
|
+
|
|
20
|
+
# Status output level
|
|
21
|
+
status-level = "pass"
|
|
22
|
+
|
|
23
|
+
[profile.ci]
|
|
24
|
+
|
|
25
|
+
# More conservative in CI
|
|
26
|
+
test-threads = "num-cpus"
|
|
27
|
+
|
|
28
|
+
# Always show all output in CI
|
|
29
|
+
failure-output = "immediate"
|
|
30
|
+
success-output = "immediate"
|
|
31
|
+
status-level = "all"
|
|
32
|
+
|
|
33
|
+
# No retries in CI to catch flaky tests
|
|
34
|
+
retries = 0
|
|
35
|
+
|
|
36
|
+
# Quick profile for development
|
|
37
|
+
[profile.quick]
|
|
38
|
+
|
|
39
|
+
# Skip slow tests
|
|
40
|
+
default-filter = 'not test(/memory/) and not test(/stress/) and not test(/large/)'
|
|
41
|
+
|
|
42
|
+
# Even more parallel execution locally
|
|
43
|
+
test-threads = "num-cpus"
|
|
44
|
+
|
|
45
|
+
# Less verbose output
|
|
46
|
+
status-level = "fail"
|
rumdl-0.0.85/.mise.toml
ADDED
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# mise configuration for rumdl development environment
|
|
2
|
+
# This file manages development tools and their versions
|
|
3
|
+
|
|
4
|
+
[env]
|
|
5
|
+
# Environment variables for the project
|
|
6
|
+
RUST_BACKTRACE = "1"
|
|
7
|
+
|
|
8
|
+
[tools]
|
|
9
|
+
# Rust toolchain - version matches rust-toolchain.toml
|
|
10
|
+
rust = "1.87.0"
|
|
11
|
+
|
|
12
|
+
# Python for maturin/python bindings
|
|
13
|
+
python = "3.12"
|
|
14
|
+
|
|
15
|
+
# UV - Fast Python package and tool manager
|
|
16
|
+
uv = "latest"
|
|
17
|
+
|
|
18
|
+
# Development tools installed via cargo
|
|
19
|
+
"cargo:cargo-nextest" = "latest"
|
|
20
|
+
"cargo:cargo-watch" = "latest"
|
|
21
|
+
"cargo:maturin" = "latest"
|
|
22
|
+
"cargo:cargo-binstall" = "latest"
|
|
23
|
+
|
|
24
|
+
# Zig for cross-compilation (used by maturin)
|
|
25
|
+
zig = "0.13"
|
|
26
|
+
|
|
27
|
+
# Optional: Additional useful Rust development tools
|
|
28
|
+
# Uncomment to enable
|
|
29
|
+
# "cargo:cargo-edit" = "latest" # For cargo add/rm/upgrade commands
|
|
30
|
+
# "cargo:cargo-outdated" = "latest" # Check for outdated dependencies
|
|
31
|
+
# "cargo:cargo-audit" = "latest" # Security audit dependencies
|
|
32
|
+
# "cargo:cargo-deny" = "latest" # Lint dependencies
|
|
33
|
+
|
|
34
|
+
# Note: Python packages like maturin, cffi, and twine are installed
|
|
35
|
+
# separately. maturin is already installed via cargo above.
|
|
36
|
+
|
|
37
|
+
[settings]
|
|
38
|
+
# Use cargo-binstall when available for faster installations
|
|
39
|
+
cargo_binstall = true
|
|
40
|
+
|
|
41
|
+
# Experimental features
|
|
42
|
+
experimental = true
|
|
43
|
+
|
|
44
|
+
# Enable idiomatic version files (like rust-toolchain.toml)
|
|
45
|
+
idiomatic_version_file_enable_tools = ["rust"]
|
|
46
|
+
|
|
47
|
+
# Configure rust/cargo homes if you want isolation from system rust
|
|
48
|
+
# rust_cache_dir = "./.mise/rust"
|
|
49
|
+
# cargo_home = "./.mise/cargo"
|
|
50
|
+
|
|
51
|
+
[tasks.setup]
|
|
52
|
+
description = "Set up the complete development environment"
|
|
53
|
+
run = """
|
|
54
|
+
echo "Setting up rumdl development environment..."
|
|
55
|
+
echo "Installing Rust toolchain and tools..."
|
|
56
|
+
mise install
|
|
57
|
+
echo "Installing Python tools with uv..."
|
|
58
|
+
uv tool install twine
|
|
59
|
+
echo "Development environment setup complete!"
|
|
60
|
+
echo ""
|
|
61
|
+
echo "Installed tools:"
|
|
62
|
+
mise list
|
|
63
|
+
echo ""
|
|
64
|
+
echo "Python tools:"
|
|
65
|
+
uv tool list
|
|
66
|
+
"""
|
|
67
|
+
|
|
68
|
+
[tasks.verify]
|
|
69
|
+
description = "Verify all tools are installed correctly"
|
|
70
|
+
run = """
|
|
71
|
+
echo "Verifying development environment..."
|
|
72
|
+
echo "Rust version: $(rustc --version)"
|
|
73
|
+
echo "Cargo version: $(cargo --version)"
|
|
74
|
+
echo "Python version: $(python --version)"
|
|
75
|
+
echo "cargo-nextest version: $(cargo nextest --version)"
|
|
76
|
+
echo "maturin version: $(maturin --version)"
|
|
77
|
+
echo ""
|
|
78
|
+
echo "Running quick test to verify setup..."
|
|
79
|
+
make test-quick
|
|
80
|
+
"""
|
|
81
|
+
|
|
82
|
+
[tasks.ci]
|
|
83
|
+
description = "Run CI checks"
|
|
84
|
+
run = """
|
|
85
|
+
echo "Running CI checks..."
|
|
86
|
+
make fmt
|
|
87
|
+
make lint
|
|
88
|
+
make test-quick
|
|
89
|
+
"""
|
|
90
|
+
|
|
91
|
+
# CI environment variables (set these in CI workflow)
|
|
92
|
+
# Example for GitHub Actions:
|
|
93
|
+
# env:
|
|
94
|
+
# RUST_BACKTRACE: "full"
|
|
95
|
+
# CARGO_INCREMENTAL: "0"
|
|
96
|
+
# CARGO_NET_RETRY: "10"
|
|
97
|
+
# RUSTFLAGS: "-D warnings"
|
|
98
|
+
|
|
99
|
+
# Platform-specific tool versions (optional)
|
|
100
|
+
# [tools.linux]
|
|
101
|
+
# rust = "1.87.0"
|
|
102
|
+
#
|
|
103
|
+
# [tools.macos]
|
|
104
|
+
# rust = "1.87.0"
|
|
105
|
+
#
|
|
106
|
+
# [tools.windows]
|
|
107
|
+
# rust = "1.87.0"
|
|
@@ -7,6 +7,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.0.85] - 2025-06-11
|
|
11
|
+
|
|
10
12
|
## [0.0.84] - 2025-06-10
|
|
11
13
|
|
|
12
14
|
## [0.0.84] - 2025-06-10
|
|
@@ -55,7 +57,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
55
57
|
### Added
|
|
56
58
|
- Initial implementation of remaining rules for markdownlint parity
|
|
57
59
|
|
|
58
|
-
[Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.
|
|
60
|
+
[Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.85...HEAD
|
|
61
|
+
[0.0.85]: https://github.com/rvben/rumdl/compare/v0.0.84...v0.0.85
|
|
59
62
|
[0.0.84]: https://github.com/rvben/rumdl/compare/v0.0.83...v0.0.84
|
|
60
63
|
[0.0.84]: https://github.com/rvben/rumdl/compare/v0.0.83...v0.0.84
|
|
61
64
|
[0.0.84]: https://github.com/rvben/rumdl/compare/v0.0.83...v0.0.84
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
[package]
|
|
2
2
|
name = "rumdl"
|
|
3
|
-
version = "0.0.
|
|
3
|
+
version = "0.0.85"
|
|
4
4
|
edition = "2021"
|
|
5
|
+
rust-version = "1.87.0"
|
|
5
6
|
description = "A fast Markdown linter written in Rust (Ru(st) MarkDown Linter)"
|
|
6
7
|
authors = ["Ruben J. Jongejan <ruben.jongejan@gmail.com>"]
|
|
7
8
|
license = "MIT"
|
|
@@ -1,4 +1,61 @@
|
|
|
1
|
-
.PHONY: build test clean fmt check doc version-major version-minor version-patch build-python build-wheel dev-install
|
|
1
|
+
.PHONY: build test clean fmt check doc version-major version-minor version-patch build-python build-wheel dev-install setup-mise dev-setup dev-verify
|
|
2
|
+
|
|
3
|
+
# Development environment setup
|
|
4
|
+
setup-mise:
|
|
5
|
+
@echo "Checking if mise is installed..."
|
|
6
|
+
@command -v mise >/dev/null 2>&1 || { \
|
|
7
|
+
echo "mise is not installed. Installing mise..."; \
|
|
8
|
+
curl https://mise.run | sh; \
|
|
9
|
+
echo 'eval "$$(~/.local/bin/mise activate bash)"' >> ~/.bashrc; \
|
|
10
|
+
echo 'eval "$$(~/.local/bin/mise activate zsh)"' >> ~/.zshrc; \
|
|
11
|
+
echo ""; \
|
|
12
|
+
echo "mise installed! Please run:"; \
|
|
13
|
+
echo " source ~/.bashrc # or source ~/.zshrc"; \
|
|
14
|
+
echo "Then run 'make dev-setup' to continue"; \
|
|
15
|
+
exit 1; \
|
|
16
|
+
}
|
|
17
|
+
@echo "mise is installed at: $$(which mise)"
|
|
18
|
+
|
|
19
|
+
dev-setup: setup-mise
|
|
20
|
+
@echo "Installing development environment with mise..."
|
|
21
|
+
mise install
|
|
22
|
+
@echo ""
|
|
23
|
+
@echo "Development environment setup complete!"
|
|
24
|
+
@echo "Run 'make dev-verify' to verify the installation"
|
|
25
|
+
|
|
26
|
+
dev-verify:
|
|
27
|
+
@echo "Verifying development environment..."
|
|
28
|
+
@echo "===================="
|
|
29
|
+
@echo "Rust version: $$(rustc --version)"
|
|
30
|
+
@echo "Cargo version: $$(cargo --version)"
|
|
31
|
+
@echo "Python version: $$(python --version)"
|
|
32
|
+
@echo "cargo-nextest: $$(cargo nextest --version 2>/dev/null || echo 'not installed')"
|
|
33
|
+
@echo "maturin: $$(maturin --version 2>/dev/null || echo 'not installed')"
|
|
34
|
+
@echo "cargo-binstall: $$(cargo binstall --version 2>/dev/null || echo 'not installed')"
|
|
35
|
+
@echo "===================="
|
|
36
|
+
|
|
37
|
+
# CI-specific setup (uses mise if available, falls back to direct installation)
|
|
38
|
+
ci-setup:
|
|
39
|
+
@if command -v mise >/dev/null 2>&1; then \
|
|
40
|
+
echo "Using mise for CI setup..."; \
|
|
41
|
+
mise install; \
|
|
42
|
+
else \
|
|
43
|
+
echo "mise not found, using direct installation..."; \
|
|
44
|
+
if ! command -v cargo-nextest >/dev/null 2>&1; then \
|
|
45
|
+
echo "Installing cargo-nextest..."; \
|
|
46
|
+
curl -LsSf https://get.nexte.st/latest/linux | tar zxf - -C $${CARGO_HOME:-~/.cargo}/bin; \
|
|
47
|
+
fi; \
|
|
48
|
+
if ! command -v cargo-binstall >/dev/null 2>&1; then \
|
|
49
|
+
echo "Installing cargo-binstall..."; \
|
|
50
|
+
curl -L --proto '=https' --tlsv1.2 -sSf https://raw.githubusercontent.com/cargo-bins/cargo-binstall/main/install-from-binstall-release.sh | bash; \
|
|
51
|
+
fi; \
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Install mise in CI environment
|
|
55
|
+
ci-install-mise:
|
|
56
|
+
@echo "Installing mise for CI..."
|
|
57
|
+
@curl https://mise.run | MISE_INSTALL_PATH=/usr/local/bin/mise sh
|
|
58
|
+
@echo "mise installed at: $$(which mise)"
|
|
2
59
|
|
|
3
60
|
build:
|
|
4
61
|
cargo build --release
|
|
@@ -6,8 +63,14 @@ build:
|
|
|
6
63
|
test:
|
|
7
64
|
cargo test
|
|
8
65
|
|
|
66
|
+
test-nextest:
|
|
67
|
+
cargo nextest run
|
|
68
|
+
|
|
9
69
|
test-quick:
|
|
10
|
-
cargo
|
|
70
|
+
cargo nextest run --profile quick
|
|
71
|
+
|
|
72
|
+
test-ci:
|
|
73
|
+
cargo nextest run --profile ci
|
|
11
74
|
|
|
12
75
|
clean:
|
|
13
76
|
cargo clean
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## What this rule does
|
|
4
4
|
|
|
5
|
-
Ensures that links to sections within the same document (like `#introduction`) point to actual headings that exist.
|
|
5
|
+
Ensures that links to sections within the same document (like `#introduction`) point to actual headings that exist. Cross-file fragment links (like `file.md#heading`) are not validated by this rule.
|
|
6
6
|
|
|
7
7
|
## Why this matters
|
|
8
8
|
|
|
@@ -26,6 +26,9 @@ Jump to [Getting Started](#getting-started) to begin.
|
|
|
26
26
|
# Working with **bold** and *italic*
|
|
27
27
|
|
|
28
28
|
Link to [formatted heading](#working-with-bold-and-italic)
|
|
29
|
+
|
|
30
|
+
<!-- Cross-file links are ignored by MD051 -->
|
|
31
|
+
See [external documentation](README.md#setup) for setup instructions.
|
|
29
32
|
```
|
|
30
33
|
|
|
31
34
|
### ❌ Incorrect
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
use log::warn;
|
|
2
1
|
use markdown::{mdast::Node, to_mdast, ParseOptions};
|
|
3
2
|
use std::panic;
|
|
4
3
|
use crate::utils::code_block_utils::CodeBlockUtils;
|
|
@@ -280,7 +279,7 @@ impl<'a> LintContext<'a> {
|
|
|
280
279
|
pub fn new(content: &'a str) -> Self {
|
|
281
280
|
// Check for problematic patterns that cause the markdown crate to panic
|
|
282
281
|
if content_has_problematic_lists(content) {
|
|
283
|
-
|
|
282
|
+
log::debug!("Detected problematic list patterns in LintContext, skipping AST parsing");
|
|
284
283
|
let ast = Node::Root(markdown::mdast::Root {
|
|
285
284
|
children: vec![],
|
|
286
285
|
position: None,
|
|
@@ -332,7 +331,7 @@ impl<'a> LintContext<'a> {
|
|
|
332
331
|
}
|
|
333
332
|
Ok(Err(err)) => {
|
|
334
333
|
// Parsing failed with an error
|
|
335
|
-
|
|
334
|
+
log::debug!("Failed to parse markdown AST: {:?}", err);
|
|
336
335
|
Node::Root(markdown::mdast::Root {
|
|
337
336
|
children: vec![],
|
|
338
337
|
position: None,
|
|
@@ -340,7 +339,7 @@ impl<'a> LintContext<'a> {
|
|
|
340
339
|
}
|
|
341
340
|
Err(_) => {
|
|
342
341
|
// Parsing panicked
|
|
343
|
-
|
|
342
|
+
log::debug!("Markdown AST parsing panicked, falling back to empty AST");
|
|
344
343
|
Node::Root(markdown::mdast::Root {
|
|
345
344
|
children: vec![],
|
|
346
345
|
position: None,
|
|
@@ -19,8 +19,8 @@ lazy_static! {
|
|
|
19
19
|
///
|
|
20
20
|
/// See [docs/md051.md](../../docs/md051.md) for full documentation, configuration, and examples.
|
|
21
21
|
///
|
|
22
|
-
/// This rule is triggered when a link anchor (the part after #) doesn't exist in the document.
|
|
23
|
-
/// This only applies to internal document links, not to external URLs.
|
|
22
|
+
/// This rule is triggered when a link anchor (the part after #) doesn't exist in the current document.
|
|
23
|
+
/// This only applies to internal document links (like #heading), not to external URLs or cross-file links (like file.md#heading).
|
|
24
24
|
#[derive(Clone)]
|
|
25
25
|
pub struct MD051LinkFragments;
|
|
26
26
|
|
|
@@ -48,7 +48,7 @@ impl MD051LinkFragments {
|
|
|
48
48
|
for line_info in &ctx.lines {
|
|
49
49
|
if let Some(heading) = &line_info.heading {
|
|
50
50
|
let line = &line_info.content;
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
// Check for TOC section
|
|
53
53
|
if TOC_SECTION_START.is_match(line) {
|
|
54
54
|
in_toc = true;
|
|
@@ -134,7 +134,7 @@ impl MD051LinkFragments {
|
|
|
134
134
|
if !QUICK_MARKDOWN_CHECK.is_match(text) {
|
|
135
135
|
return text.to_string();
|
|
136
136
|
}
|
|
137
|
-
|
|
137
|
+
|
|
138
138
|
// Use single regex to capture all markdown formatting at once
|
|
139
139
|
let result = MARKDOWN_STRIP.replace_all(text, |caps: ®ex::Captures| {
|
|
140
140
|
// Return the captured content (group 1-7 for different formatting types)
|
|
@@ -154,6 +154,69 @@ impl MD051LinkFragments {
|
|
|
154
154
|
}
|
|
155
155
|
}
|
|
156
156
|
|
|
157
|
+
/// Check if a path has a file extension indicating it's a file reference
|
|
158
|
+
fn has_file_extension(path: &str) -> bool {
|
|
159
|
+
// First, strip query parameters and other URL components
|
|
160
|
+
// Split on ? to remove query parameters, and on & to handle other URL components
|
|
161
|
+
let clean_path = path.split('?').next().unwrap_or(path)
|
|
162
|
+
.split('&').next().unwrap_or(path);
|
|
163
|
+
|
|
164
|
+
// Common file extensions that indicate cross-file references
|
|
165
|
+
let file_extensions = [
|
|
166
|
+
// Markdown and documentation formats
|
|
167
|
+
".md", ".markdown", ".mdown", ".mkdn", ".mdx", ".md2", ".mdtext",
|
|
168
|
+
".rst", ".txt", ".adoc", ".asciidoc", ".org",
|
|
169
|
+
|
|
170
|
+
// Web formats
|
|
171
|
+
".html", ".htm", ".xhtml", ".xml", ".svg",
|
|
172
|
+
|
|
173
|
+
// Data and config formats
|
|
174
|
+
".json", ".yaml", ".yml", ".toml", ".ini", ".cfg", ".conf",
|
|
175
|
+
|
|
176
|
+
// Office documents
|
|
177
|
+
".pdf", ".doc", ".docx", ".odt", ".rtf",
|
|
178
|
+
|
|
179
|
+
// Programming and script files (often contain documentation)
|
|
180
|
+
".py", ".js", ".ts", ".rs", ".go", ".java", ".cpp", ".c", ".h",
|
|
181
|
+
".sh", ".bash", ".zsh", ".fish", ".ps1", ".bat", ".cmd",
|
|
182
|
+
|
|
183
|
+
// Other common file types that might have fragments
|
|
184
|
+
".tex", ".bib", ".csv", ".tsv", ".log"
|
|
185
|
+
];
|
|
186
|
+
|
|
187
|
+
// Case-insensitive extension matching
|
|
188
|
+
let path_lower = clean_path.to_lowercase();
|
|
189
|
+
for ext in &file_extensions {
|
|
190
|
+
if path_lower.ends_with(ext) {
|
|
191
|
+
return true;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Also check for any extension pattern (dot followed by 2-10 alphanumeric characters)
|
|
196
|
+
// This catches extensions not in our known list like .backup, .tmp, .orig, etc.
|
|
197
|
+
if let Some(last_dot) = path_lower.rfind('.') {
|
|
198
|
+
// Special case: if path starts with a dot, it might be a hidden file
|
|
199
|
+
// Only treat it as having an extension if there's a second dot
|
|
200
|
+
if path_lower.starts_with('.') {
|
|
201
|
+
// For hidden files like .gitignore, .bashrc, we need a second dot to be a file extension
|
|
202
|
+
// e.g., .config.json has extension .json, but .gitignore has no extension
|
|
203
|
+
if last_dot == 0 {
|
|
204
|
+
// Only one dot at the beginning - not a file extension
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
let potential_ext = &path_lower[last_dot + 1..];
|
|
210
|
+
// Valid extension: 2-10 characters, alphanumeric (allows for longer extensions like .backup)
|
|
211
|
+
if potential_ext.len() >= 2 && potential_ext.len() <= 10 &&
|
|
212
|
+
potential_ext.chars().all(|c| c.is_ascii_alphanumeric()) {
|
|
213
|
+
return true;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
false
|
|
218
|
+
}
|
|
219
|
+
|
|
157
220
|
/// Fast external URL detection with optimized patterns
|
|
158
221
|
#[inline]
|
|
159
222
|
fn is_external_url_fast(&self, url: &str) -> bool {
|
|
@@ -193,7 +256,7 @@ impl Rule for MD051LinkFragments {
|
|
|
193
256
|
}
|
|
194
257
|
|
|
195
258
|
fn description(&self) -> &'static str {
|
|
196
|
-
"Link anchors (# references) should exist"
|
|
259
|
+
"Link anchors (# references) should exist in the current document"
|
|
197
260
|
}
|
|
198
261
|
|
|
199
262
|
fn check(&self, ctx: &crate::lint_context::LintContext) -> LintResult {
|
|
@@ -224,10 +287,10 @@ impl Rule for MD051LinkFragments {
|
|
|
224
287
|
|
|
225
288
|
// Extract headings once for the entire document
|
|
226
289
|
let headings = self.extract_headings_from_context(ctx);
|
|
227
|
-
|
|
290
|
+
|
|
228
291
|
// If no headings, no need to check TOC sections
|
|
229
292
|
let has_headings = !headings.is_empty();
|
|
230
|
-
|
|
293
|
+
|
|
231
294
|
let mut warnings = Vec::new();
|
|
232
295
|
let mut in_toc_section = false;
|
|
233
296
|
|
|
@@ -244,28 +307,35 @@ impl Rule for MD051LinkFragments {
|
|
|
244
307
|
} else {
|
|
245
308
|
&link.url
|
|
246
309
|
};
|
|
247
|
-
|
|
310
|
+
|
|
248
311
|
// Skip if external URL
|
|
249
312
|
if self.is_external_url_fast(url) {
|
|
250
313
|
continue;
|
|
251
314
|
}
|
|
252
|
-
|
|
315
|
+
|
|
253
316
|
// Check if URL has a fragment
|
|
254
317
|
if let Some(hash_pos) = url.find('#') {
|
|
255
318
|
let fragment = &url[hash_pos + 1..].to_lowercase();
|
|
256
|
-
|
|
319
|
+
|
|
257
320
|
// Skip empty fragments
|
|
258
321
|
if fragment.is_empty() {
|
|
259
322
|
continue;
|
|
260
323
|
}
|
|
261
|
-
|
|
324
|
+
|
|
325
|
+
// Skip cross-file fragment links - only validate fragments in same document
|
|
326
|
+
// If URL contains a file path (has file extension like .md, .rst, .html, etc.), it's a cross-file link
|
|
327
|
+
let path_before_hash = &url[..hash_pos];
|
|
328
|
+
if Self::has_file_extension(path_before_hash) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
|
|
262
332
|
// Check if in TOC section
|
|
263
333
|
if in_toc_section {
|
|
264
334
|
continue;
|
|
265
335
|
}
|
|
266
|
-
|
|
336
|
+
|
|
267
337
|
let line_info = &ctx.lines[link.line - 1];
|
|
268
|
-
|
|
338
|
+
|
|
269
339
|
// Check if we're entering a TOC section
|
|
270
340
|
if has_headings && TOC_SECTION_START.is_match(&line_info.content) {
|
|
271
341
|
in_toc_section = true;
|
|
@@ -276,7 +346,7 @@ impl Rule for MD051LinkFragments {
|
|
|
276
346
|
if in_toc_section && line_info.content.starts_with('#') && !TOC_SECTION_START.is_match(&line_info.content) {
|
|
277
347
|
in_toc_section = false;
|
|
278
348
|
}
|
|
279
|
-
|
|
349
|
+
|
|
280
350
|
// Check if the fragment exists in headings
|
|
281
351
|
if !has_headings || !headings.contains(fragment) {
|
|
282
352
|
warnings.push(LintWarning {
|
|
@@ -6,7 +6,6 @@
|
|
|
6
6
|
|
|
7
7
|
use crate::rule::MarkdownAst;
|
|
8
8
|
use lazy_static::lazy_static;
|
|
9
|
-
use log::warn;
|
|
10
9
|
use std::collections::HashMap;
|
|
11
10
|
use std::panic;
|
|
12
11
|
use std::sync::{Arc, Mutex};
|
|
@@ -98,7 +97,7 @@ pub fn clear_ast_cache() {
|
|
|
98
97
|
pub fn parse_markdown_ast(content: &str) -> MarkdownAst {
|
|
99
98
|
// Check for problematic patterns that cause the markdown crate to panic
|
|
100
99
|
if content_has_problematic_lists(content) {
|
|
101
|
-
|
|
100
|
+
log::debug!("Detected problematic list patterns, skipping AST parsing");
|
|
102
101
|
return MarkdownAst::Root(markdown::mdast::Root {
|
|
103
102
|
children: vec![],
|
|
104
103
|
position: None,
|
|
@@ -115,7 +114,7 @@ pub fn parse_markdown_ast(content: &str) -> MarkdownAst {
|
|
|
115
114
|
}
|
|
116
115
|
Ok(Err(err)) => {
|
|
117
116
|
// Parsing failed with an error
|
|
118
|
-
|
|
117
|
+
log::debug!("Failed to parse markdown AST in ast_utils: {:?}", err);
|
|
119
118
|
MarkdownAst::Root(markdown::mdast::Root {
|
|
120
119
|
children: vec![],
|
|
121
120
|
position: None,
|
|
@@ -123,7 +122,7 @@ pub fn parse_markdown_ast(content: &str) -> MarkdownAst {
|
|
|
123
122
|
}
|
|
124
123
|
Err(_) => {
|
|
125
124
|
// Parsing panicked
|
|
126
|
-
|
|
125
|
+
log::debug!("Markdown AST parsing panicked in ast_utils, falling back to empty AST");
|
|
127
126
|
MarkdownAst::Root(markdown::mdast::Root {
|
|
128
127
|
children: vec![],
|
|
129
128
|
position: None,
|