rumdl 0.0.58__tar.gz → 0.0.59__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.58 → rumdl-0.0.59}/Cargo.lock +1 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/Cargo.toml +1 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/PKG-INFO +1 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/src/main.rs +3 -3
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/blockquote_utils.rs +22 -6
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md001_heading_increment.rs +9 -68
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md002_first_heading_h1.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md003_heading_style.rs +17 -57
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md004_unordered_list_style.rs +14 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md005_list_indent.rs +5 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md006_start_bullets.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md007_ul_indent.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md012_no_multiple_blanks.rs +32 -2
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md013_line_length.rs +37 -3
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md018_no_missing_space_atx.rs +11 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md019_no_multiple_space_atx.rs +11 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md020_no_missing_space_closed_atx.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md021_no_multiple_space_closed_atx.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md022_blanks_around_headings.rs +30 -28
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md023_heading_start_left.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md024_no_duplicate_heading.rs +40 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md025_single_title.rs +16 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md026_no_trailing_punctuation.rs +76 -2
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md028_no_blanks_blockquote.rs +33 -54
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md029_ordered_list_prefix.rs +45 -115
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md030_list_marker_space.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md032_blanks_around_lists.rs +72 -6
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md033_no_inline_html.rs +29 -21
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md034_no_bare_urls.rs +44 -3
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md037_spaces_around_emphasis.rs +20 -209
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md038_no_space_in_code.rs +10 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md039_no_space_in_links.rs +4 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md044_proper_names.rs +30 -4
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md046_code_block_style.rs +65 -117
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md051_link_fragments.rs +101 -111
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/document_structure.rs +68 -26
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/regex_cache.rs +40 -2
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/advanced_integration_tests.rs +1 -1
- {rumdl-0.0.58 → rumdl-0.0.59}/.rumdl.toml +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/MANIFEST.in +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/Makefile +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/README.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/assets/logo.png +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/benches/range_performance.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/benches/range_utils_benchmark.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/benches/rule_performance.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/RULES.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md001.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md002.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md003.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md004.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md005.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md006.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md007.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md009.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md010.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md011.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md012.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md013.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md014.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md018.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md019.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md020.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md021.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md022.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md023.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md024.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md025.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md026.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md027.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md028.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md029.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md030.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md031.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md032.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md033.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md034.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md035.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md036.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md037.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md038.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md039.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md040.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md041.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md042.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md043.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md044.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md045.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md046.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md047.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md048.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md049.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md050.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md051.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md052.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md053.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md054.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md055.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md056.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md057.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/docs/md058.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/issues/plan-rule-parity-with-markdownlint.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/parity_check.py +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/pyproject.toml +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/python/MANIFEST.in +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/python/PYTHON-README.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/python/rumdl/__init__.py +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/python/rumdl/__main__.py +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/python/rumdl/py.typed +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/rumdl.toml.example +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/config.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/init.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/lib.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/lint_context.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/markdownlint_config.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/profiling.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/python.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rule.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/code_block_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/code_fence_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/emphasis_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/front_matter_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/heading_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/list_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md009_trailing_spaces.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md010_no_hard_tabs.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md011_no_reversed_links.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md014_commands_show_output.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md031_blanks_around_fences.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md035_hr_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md036_no_emphasis_only_first.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md040_fenced_code_language.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md041_first_line_heading.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md042_no_empty_links.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md043_required_headings.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md045_no_alt_text.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md047_single_trailing_newline.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md048_code_fence_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md049_emphasis_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md050_strong_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md052_reference_links_images.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md053_link_image_reference_definitions.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md054_link_image_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md055_table_pipe_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md056_table_column_count.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md057_existing_relative_links.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/md058_blanks_around_tables.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/mod.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/rules/strong_style.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/code_block_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/early_returns.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/element_cache.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/markdown_elements.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/mod.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/src/utils/range_utils.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/cli_duplication_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/cli_integration_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/commonmark_compliance_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/comprehensive_integration_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/config_application_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/config_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/init_command_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/init_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/integration_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/json_output_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/lib.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/markdownlint_cli_integration.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/markdownlint_config_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/md030_edge_cases.md +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/output_format_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/perf_check.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/pyproject_config_tests.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md001_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md001_unicode_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md002_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md003_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md004_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md005_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md006_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md006_unicode_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md007_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md009_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md010_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md011_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md012_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md013_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md014_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md018_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md019_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md020_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md021_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md022_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md023_extended_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md023_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md024_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md025_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md026_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md027_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md028_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md029_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md030_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md031_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md032_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md033_extended_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md033_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md034_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md035_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md036_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md037_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md038_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md039_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md040_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md041_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md042_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md043_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md044_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md045_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md046_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md047_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md048_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md049_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md050_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md051_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md052_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md053_additional_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md053_proptest.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md053_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md054_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md054_unicode_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md055_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md056_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md057_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/md058_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/rules/mod.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/blockquote_utils_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/code_block_utils_extended_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/code_block_utils_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/core_utils_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/front_matter_utils_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/line_index_test.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils/mod.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils_markdown_edge_cases.rs +0 -0
- {rumdl-0.0.58 → rumdl-0.0.59}/tests/utils_tests.rs +0 -0
|
@@ -1388,11 +1388,11 @@ fn process_file(
|
|
|
1388
1388
|
// Fix issues if requested
|
|
1389
1389
|
let mut warnings_fixed = 0;
|
|
1390
1390
|
if _fix {
|
|
1391
|
-
//
|
|
1391
|
+
// Apply fixes for rules that have warnings, regardless of whether individual warnings have fixes
|
|
1392
1392
|
for rule in rules {
|
|
1393
1393
|
if all_warnings
|
|
1394
1394
|
.iter()
|
|
1395
|
-
.any(|w| w.rule_name == Some(rule.name())
|
|
1395
|
+
.any(|w| w.rule_name == Some(rule.name()))
|
|
1396
1396
|
{
|
|
1397
1397
|
let ctx = LintContext::new(&content);
|
|
1398
1398
|
match rule.fix(&ctx) {
|
|
@@ -1402,7 +1402,7 @@ fn process_file(
|
|
|
1402
1402
|
// Apply fixes for this rule - we consider all warnings for the rule fixed
|
|
1403
1403
|
warnings_fixed += all_warnings
|
|
1404
1404
|
.iter()
|
|
1405
|
-
.filter(|w| w.rule_name == Some(rule.name())
|
|
1405
|
+
.filter(|w| w.rule_name == Some(rule.name()))
|
|
1406
1406
|
.count();
|
|
1407
1407
|
}
|
|
1408
1408
|
}
|
|
@@ -5,11 +5,11 @@ lazy_static! {
|
|
|
5
5
|
// Pattern to match blockquote lines
|
|
6
6
|
static ref BLOCKQUOTE_LINE: Regex = Regex::new(r"^(\s*)>\s?(.*)$").unwrap();
|
|
7
7
|
|
|
8
|
-
// Pattern to match empty blockquote lines
|
|
9
|
-
static ref EMPTY_BLOCKQUOTE_LINE: Regex = Regex::new(r"^(\s*)
|
|
8
|
+
// Pattern to match empty blockquote lines (> with no space or content)
|
|
9
|
+
static ref EMPTY_BLOCKQUOTE_LINE: Regex = Regex::new(r"^(\s*)>$").unwrap();
|
|
10
10
|
|
|
11
|
-
// Pattern to match nested empty blockquote lines
|
|
12
|
-
static ref NESTED_EMPTY_BLOCKQUOTE_LINE: Regex = Regex::new(r"^(\s*)
|
|
11
|
+
// Pattern to match nested empty blockquote lines (>> with no space or content)
|
|
12
|
+
static ref NESTED_EMPTY_BLOCKQUOTE_LINE: Regex = Regex::new(r"^(\s*)>+$").unwrap();
|
|
13
13
|
|
|
14
14
|
// Pattern to match blockquote lines with no space after >
|
|
15
15
|
static ref BLOCKQUOTE_NO_SPACE: Regex = Regex::new(r"^(\s*)>([^\s].*)$").unwrap();
|
|
@@ -32,12 +32,12 @@ impl BlockquoteUtils {
|
|
|
32
32
|
|
|
33
33
|
/// Check if a line is an empty blockquote (> with no content)
|
|
34
34
|
pub fn is_empty_blockquote(line: &str) -> bool {
|
|
35
|
-
// Check for simple empty blockquote
|
|
35
|
+
// Check for simple empty blockquote (> with no space)
|
|
36
36
|
if EMPTY_BLOCKQUOTE_LINE.is_match(line) {
|
|
37
37
|
return true;
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
-
// Check for nested empty blockquote
|
|
40
|
+
// Check for nested empty blockquote (>> with no space)
|
|
41
41
|
if NESTED_EMPTY_BLOCKQUOTE_LINE.is_match(line) {
|
|
42
42
|
return true;
|
|
43
43
|
}
|
|
@@ -51,6 +51,22 @@ impl BlockquoteUtils {
|
|
|
51
51
|
false
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
/// Check if an empty blockquote line needs fixing for MD028
|
|
55
|
+
/// This is more restrictive than is_empty_blockquote - only flags lines that actually need fixing
|
|
56
|
+
pub fn needs_md028_fix(line: &str) -> bool {
|
|
57
|
+
// Only flag blockquotes that have NO space after the > marker
|
|
58
|
+
// Lines with a single space ("> ") are already correct and don't need fixing
|
|
59
|
+
if EMPTY_BLOCKQUOTE_LINE.is_match(line) {
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if NESTED_EMPTY_BLOCKQUOTE_LINE.is_match(line) {
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
false
|
|
68
|
+
}
|
|
69
|
+
|
|
54
70
|
/// Check if a blockquote line has no space after the > marker
|
|
55
71
|
pub fn has_no_space_after_marker(line: &str) -> bool {
|
|
56
72
|
BLOCKQUOTE_NO_SPACE.is_match(line)
|
|
@@ -76,77 +76,14 @@ impl Rule for MD001HeadingIncrement {
|
|
|
76
76
|
return Ok(vec![]);
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
|
|
80
|
-
if
|
|
79
|
+
// Quick check for headings
|
|
80
|
+
if !content.contains('#') && !content.contains("===") && !content.contains("---") {
|
|
81
81
|
return Ok(vec![]);
|
|
82
82
|
}
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
let
|
|
86
|
-
|
|
87
|
-
let lines: Vec<&str> = content.lines().collect();
|
|
88
|
-
|
|
89
|
-
// Process headings using pre-computed heading information
|
|
90
|
-
for i in 0..structure.heading_lines.len() {
|
|
91
|
-
let line_num = structure.heading_lines[i];
|
|
92
|
-
let level = structure.heading_levels[i];
|
|
93
|
-
|
|
94
|
-
// Check if this heading level is more than one level deeper than the previous
|
|
95
|
-
if prev_level > 0 && level > prev_level + 1 {
|
|
96
|
-
let adjusted_line_num = line_num - 1; // Convert 1-indexed to 0-indexed
|
|
97
|
-
let indentation = if adjusted_line_num < lines.len() {
|
|
98
|
-
HeadingUtils::get_indentation(lines[adjusted_line_num])
|
|
99
|
-
} else {
|
|
100
|
-
0
|
|
101
|
-
};
|
|
102
|
-
|
|
103
|
-
// Get the heading text
|
|
104
|
-
let heading_text = if adjusted_line_num < lines.len() {
|
|
105
|
-
lines[adjusted_line_num]
|
|
106
|
-
.trim_start()
|
|
107
|
-
.trim_start_matches('#')
|
|
108
|
-
.trim()
|
|
109
|
-
.to_string()
|
|
110
|
-
} else {
|
|
111
|
-
String::new()
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
// Determine heading style
|
|
115
|
-
let style = if adjusted_line_num + 1 < lines.len()
|
|
116
|
-
&& (lines[adjusted_line_num + 1].trim().starts_with('=')
|
|
117
|
-
|| lines[adjusted_line_num + 1].trim().starts_with('-'))
|
|
118
|
-
{
|
|
119
|
-
if lines[adjusted_line_num + 1].trim().starts_with('=') {
|
|
120
|
-
HeadingStyle::Setext1
|
|
121
|
-
} else {
|
|
122
|
-
HeadingStyle::Setext2
|
|
123
|
-
}
|
|
124
|
-
} else {
|
|
125
|
-
HeadingStyle::Atx
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
// Create a fix with the correct heading level
|
|
129
|
-
let fixed_level = prev_level + 1;
|
|
130
|
-
let replacement =
|
|
131
|
-
HeadingUtils::convert_heading_style(&heading_text, fixed_level as u32, style);
|
|
132
|
-
|
|
133
|
-
warnings.push(LintWarning {
|
|
134
|
-
rule_name: Some(self.name()),
|
|
135
|
-
line: line_num,
|
|
136
|
-
column: indentation + 1,
|
|
137
|
-
message: format!("Heading level should be {} for this level", prev_level + 1),
|
|
138
|
-
severity: Severity::Warning,
|
|
139
|
-
fix: Some(Fix {
|
|
140
|
-
range: line_index.line_col_to_byte_range(line_num, indentation + 1),
|
|
141
|
-
replacement: format!("{}{}", " ".repeat(indentation), replacement),
|
|
142
|
-
}),
|
|
143
|
-
});
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
prev_level = level;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
Ok(warnings)
|
|
84
|
+
// Fallback path: create structure manually (should rarely be used)
|
|
85
|
+
let structure = DocumentStructure::new(content);
|
|
86
|
+
self.check_with_structure(ctx, &structure)
|
|
150
87
|
}
|
|
151
88
|
|
|
152
89
|
/// Optimized check using document structure
|
|
@@ -312,6 +249,10 @@ impl Rule for MD001HeadingIncrement {
|
|
|
312
249
|
self
|
|
313
250
|
}
|
|
314
251
|
|
|
252
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
253
|
+
Some(self)
|
|
254
|
+
}
|
|
255
|
+
|
|
315
256
|
fn from_config(_config: &crate::config::Config) -> Box<dyn Rule>
|
|
316
257
|
where
|
|
317
258
|
Self: Sized,
|
|
@@ -333,6 +333,10 @@ impl Rule for MD002FirstHeadingH1 {
|
|
|
333
333
|
self
|
|
334
334
|
}
|
|
335
335
|
|
|
336
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
337
|
+
Some(self)
|
|
338
|
+
}
|
|
339
|
+
|
|
336
340
|
fn default_config_section(&self) -> Option<(String, toml::Value)> {
|
|
337
341
|
let mut map = toml::map::Map::new();
|
|
338
342
|
map.insert("level".to_string(), toml::Value::Integer(self.level as i64));
|
|
@@ -160,64 +160,9 @@ impl Rule for MD003HeadingStyle {
|
|
|
160
160
|
return Ok(Vec::new());
|
|
161
161
|
}
|
|
162
162
|
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
// Create DocumentStructure and use it for heading info
|
|
163
|
+
// Fallback path: create structure manually (should rarely be used)
|
|
166
164
|
let structure = DocumentStructure::new(content);
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
let lines: Vec<&str> = content.lines().collect();
|
|
170
|
-
for (idx, &line_num) in structure.heading_lines.iter().enumerate() {
|
|
171
|
-
let level = structure.heading_levels[idx];
|
|
172
|
-
let region = structure.heading_regions[idx];
|
|
173
|
-
// Determine the current style of the heading
|
|
174
|
-
let style = if region.0 != region.1 {
|
|
175
|
-
// Setext heading (has an underline)
|
|
176
|
-
if level == 1 {
|
|
177
|
-
HeadingStyle::Setext1
|
|
178
|
-
} else {
|
|
179
|
-
HeadingStyle::Setext2
|
|
180
|
-
}
|
|
181
|
-
} else {
|
|
182
|
-
// ATX heading
|
|
183
|
-
let line = lines.get(line_num - 1).map_or("", |v| *v);
|
|
184
|
-
if line.trim().ends_with('#') {
|
|
185
|
-
HeadingStyle::AtxClosed
|
|
186
|
-
} else {
|
|
187
|
-
HeadingStyle::Atx
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
// For markdownlint parity: when target style is Setext, all headings are expected to be Setext
|
|
192
|
-
// This will flag level 3+ as violations since they can't be represented as Setext
|
|
193
|
-
let expected_style = if target_style == HeadingStyle::Setext1
|
|
194
|
-
|| target_style == HeadingStyle::Setext2
|
|
195
|
-
{
|
|
196
|
-
if level == 1 {
|
|
197
|
-
HeadingStyle::Setext1
|
|
198
|
-
} else {
|
|
199
|
-
HeadingStyle::Setext2
|
|
200
|
-
}
|
|
201
|
-
} else {
|
|
202
|
-
target_style
|
|
203
|
-
};
|
|
204
|
-
|
|
205
|
-
if style != expected_style {
|
|
206
|
-
result.push(LintWarning {
|
|
207
|
-
rule_name: Some(self.name()),
|
|
208
|
-
line: line_num,
|
|
209
|
-
column: 1,
|
|
210
|
-
message: format!(
|
|
211
|
-
"Heading style should be {:?} (found {:?})",
|
|
212
|
-
expected_style, style
|
|
213
|
-
),
|
|
214
|
-
severity: Severity::Warning,
|
|
215
|
-
fix: None,
|
|
216
|
-
});
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
Ok(result)
|
|
165
|
+
self.check_with_structure(ctx, &structure)
|
|
221
166
|
}
|
|
222
167
|
|
|
223
168
|
fn fix(&self, ctx: &crate::lint_context::LintContext) -> Result<String, LintError> {
|
|
@@ -468,6 +413,10 @@ impl Rule for MD003HeadingStyle {
|
|
|
468
413
|
self
|
|
469
414
|
}
|
|
470
415
|
|
|
416
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
417
|
+
Some(self)
|
|
418
|
+
}
|
|
419
|
+
|
|
471
420
|
fn default_config_section(&self) -> Option<(String, toml::Value)> {
|
|
472
421
|
let mut map = toml::map::Map::new();
|
|
473
422
|
map.insert(
|
|
@@ -488,6 +437,17 @@ impl Rule for MD003HeadingStyle {
|
|
|
488
437
|
}
|
|
489
438
|
}
|
|
490
439
|
|
|
440
|
+
impl crate::utils::document_structure::DocumentStructureExtensions for MD003HeadingStyle {
|
|
441
|
+
fn has_relevant_elements(
|
|
442
|
+
&self,
|
|
443
|
+
_ctx: &crate::lint_context::LintContext,
|
|
444
|
+
doc_structure: &crate::utils::document_structure::DocumentStructure,
|
|
445
|
+
) -> bool {
|
|
446
|
+
// This rule is only relevant if there are headings
|
|
447
|
+
!doc_structure.heading_lines.is_empty()
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
|
|
491
451
|
#[cfg(test)]
|
|
492
452
|
mod tests {
|
|
493
453
|
use super::*;
|
|
@@ -167,7 +167,21 @@ impl Rule for MD004UnorderedListStyle {
|
|
|
167
167
|
"Use consistent style for unordered list markers"
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
171
|
+
Some(self)
|
|
172
|
+
}
|
|
173
|
+
|
|
170
174
|
fn check(&self, ctx: &LintContext) -> LintResult {
|
|
175
|
+
// Early returns for performance
|
|
176
|
+
if ctx.content.is_empty() {
|
|
177
|
+
return Ok(Vec::new());
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
// Quick check for any list markers before processing
|
|
181
|
+
if !ctx.content.contains(|c: char| c == '*' || c == '-' || c == '+') {
|
|
182
|
+
return Ok(Vec::new());
|
|
183
|
+
}
|
|
184
|
+
|
|
171
185
|
let mut warnings = Vec::new();
|
|
172
186
|
let content = &ctx.content;
|
|
173
187
|
let mut in_code_block = false;
|
|
@@ -743,11 +743,15 @@ impl Rule for MD005ListIndent {
|
|
|
743
743
|
self
|
|
744
744
|
}
|
|
745
745
|
|
|
746
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
747
|
+
Some(self)
|
|
748
|
+
}
|
|
749
|
+
|
|
746
750
|
fn default_config_section(&self) -> Option<(String, toml::Value)> {
|
|
747
751
|
None
|
|
748
752
|
}
|
|
749
753
|
|
|
750
|
-
fn from_config(
|
|
754
|
+
fn from_config(config: &crate::config::Config) -> Box<dyn Rule>
|
|
751
755
|
where
|
|
752
756
|
Self: Sized,
|
|
753
757
|
{
|
|
@@ -309,6 +309,10 @@ impl Rule for MD006StartBullets {
|
|
|
309
309
|
self
|
|
310
310
|
}
|
|
311
311
|
|
|
312
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
313
|
+
Some(self)
|
|
314
|
+
}
|
|
315
|
+
|
|
312
316
|
fn from_config(_config: &crate::config::Config) -> Box<dyn Rule>
|
|
313
317
|
where
|
|
314
318
|
Self: Sized,
|
|
@@ -216,6 +216,10 @@ impl Rule for MD007ULIndent {
|
|
|
216
216
|
self
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
220
|
+
Some(self)
|
|
221
|
+
}
|
|
222
|
+
|
|
219
223
|
fn default_config_section(&self) -> Option<(String, toml::Value)> {
|
|
220
224
|
let mut map = toml::map::Map::new();
|
|
221
225
|
map.insert(
|
|
@@ -63,8 +63,29 @@ impl Rule for MD012NoMultipleBlanks {
|
|
|
63
63
|
"Multiple consecutive blank lines"
|
|
64
64
|
}
|
|
65
65
|
|
|
66
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
67
|
+
Some(self)
|
|
68
|
+
}
|
|
69
|
+
|
|
66
70
|
fn check(&self, ctx: &crate::lint_context::LintContext) -> LintResult {
|
|
67
71
|
let content = ctx.content;
|
|
72
|
+
|
|
73
|
+
// Early return for empty content
|
|
74
|
+
if content.is_empty() {
|
|
75
|
+
return Ok(Vec::new());
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// Quick check for consecutive newlines or potential whitespace-only lines before processing
|
|
79
|
+
// Look for multiple consecutive lines that could be blank (empty or whitespace-only)
|
|
80
|
+
let lines: Vec<&str> = content.lines().collect();
|
|
81
|
+
let has_potential_blanks = lines.windows(2).any(|pair| {
|
|
82
|
+
pair[0].trim().is_empty() && pair[1].trim().is_empty()
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
if !has_potential_blanks {
|
|
86
|
+
return Ok(Vec::new());
|
|
87
|
+
}
|
|
88
|
+
|
|
68
89
|
let _line_index = LineIndex::new(content.to_string());
|
|
69
90
|
|
|
70
91
|
let mut warnings = Vec::new();
|
|
@@ -72,8 +93,6 @@ impl Rule for MD012NoMultipleBlanks {
|
|
|
72
93
|
let mut blank_count = 0;
|
|
73
94
|
let mut blank_start = 0;
|
|
74
95
|
|
|
75
|
-
let lines: Vec<&str> = content.lines().collect();
|
|
76
|
-
|
|
77
96
|
for (line_num, &line) in lines.iter().enumerate() {
|
|
78
97
|
// Skip code blocks and front matter
|
|
79
98
|
if Self::is_in_code_block(&lines, line_num)
|
|
@@ -255,3 +274,14 @@ impl Rule for MD012NoMultipleBlanks {
|
|
|
255
274
|
Box::new(MD012NoMultipleBlanks::new(maximum))
|
|
256
275
|
}
|
|
257
276
|
}
|
|
277
|
+
|
|
278
|
+
impl crate::utils::document_structure::DocumentStructureExtensions for MD012NoMultipleBlanks {
|
|
279
|
+
fn has_relevant_elements(
|
|
280
|
+
&self,
|
|
281
|
+
ctx: &crate::lint_context::LintContext,
|
|
282
|
+
_structure: &crate::utils::document_structure::DocumentStructure,
|
|
283
|
+
) -> bool {
|
|
284
|
+
// MD012 checks for consecutive blank lines, so it's relevant for any non-empty content
|
|
285
|
+
!ctx.content.is_empty()
|
|
286
|
+
}
|
|
287
|
+
}
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
///
|
|
3
3
|
/// See [docs/md013.md](../../docs/md013.md) for full documentation, configuration, and examples.
|
|
4
4
|
use crate::rule::{LintError, LintResult, LintWarning, Rule, Severity};
|
|
5
|
-
use crate::utils::document_structure::DocumentStructure;
|
|
5
|
+
use crate::utils::document_structure::{DocumentStructure, DocumentStructureExtensions};
|
|
6
6
|
use lazy_static::lazy_static;
|
|
7
7
|
use regex::Regex;
|
|
8
8
|
use toml;
|
|
@@ -119,13 +119,31 @@ impl Rule for MD013LineLength {
|
|
|
119
119
|
|
|
120
120
|
fn check(&self, ctx: &crate::lint_context::LintContext) -> LintResult {
|
|
121
121
|
let content = ctx.content;
|
|
122
|
-
|
|
122
|
+
|
|
123
|
+
// Early return for empty content
|
|
124
|
+
if content.is_empty() {
|
|
125
|
+
return Ok(Vec::new());
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// Fallback path: create structure manually (should rarely be used)
|
|
123
129
|
let structure = DocumentStructure::new(content);
|
|
130
|
+
self.check_with_structure(ctx, &structure)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/// Optimized check using pre-computed document structure
|
|
134
|
+
fn check_with_structure(
|
|
135
|
+
&self,
|
|
136
|
+
ctx: &crate::lint_context::LintContext,
|
|
137
|
+
structure: &DocumentStructure,
|
|
138
|
+
) -> LintResult {
|
|
139
|
+
let content = ctx.content;
|
|
140
|
+
let mut warnings = Vec::new();
|
|
124
141
|
let lines: Vec<&str> = content.lines().collect();
|
|
125
142
|
|
|
126
143
|
// Create a quick lookup set for heading lines
|
|
127
144
|
let heading_lines_set: std::collections::HashSet<usize> =
|
|
128
145
|
structure.heading_lines.iter().cloned().collect();
|
|
146
|
+
|
|
129
147
|
// Create a quick lookup for setext headings (where start_line != end_line in regions)
|
|
130
148
|
let _setext_lines_set: std::collections::HashSet<usize> = structure
|
|
131
149
|
.heading_regions
|
|
@@ -133,6 +151,7 @@ impl Rule for MD013LineLength {
|
|
|
133
151
|
.filter(|(start, end)| start != end)
|
|
134
152
|
.flat_map(|(start, end)| (*start..=*end).collect::<Vec<usize>>())
|
|
135
153
|
.collect();
|
|
154
|
+
|
|
136
155
|
// Create a quick lookup set for list item lines (including continuations)
|
|
137
156
|
let _list_lines_set: std::collections::HashSet<usize> =
|
|
138
157
|
structure.list_lines.iter().cloned().collect();
|
|
@@ -168,7 +187,7 @@ impl Rule for MD013LineLength {
|
|
|
168
187
|
}
|
|
169
188
|
|
|
170
189
|
// Skip lines that are only a URL, image ref, or link ref
|
|
171
|
-
if self.should_ignore_line(line, &lines, line_num,
|
|
190
|
+
if self.should_ignore_line(line, &lines, line_num, structure) {
|
|
172
191
|
continue;
|
|
173
192
|
}
|
|
174
193
|
}
|
|
@@ -207,6 +226,10 @@ impl Rule for MD013LineLength {
|
|
|
207
226
|
self
|
|
208
227
|
}
|
|
209
228
|
|
|
229
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
230
|
+
Some(self)
|
|
231
|
+
}
|
|
232
|
+
|
|
210
233
|
fn default_config_section(&self) -> Option<(String, toml::Value)> {
|
|
211
234
|
let mut map = toml::map::Map::new();
|
|
212
235
|
map.insert(
|
|
@@ -248,3 +271,14 @@ impl Rule for MD013LineLength {
|
|
|
248
271
|
))
|
|
249
272
|
}
|
|
250
273
|
}
|
|
274
|
+
|
|
275
|
+
impl DocumentStructureExtensions for MD013LineLength {
|
|
276
|
+
fn has_relevant_elements(
|
|
277
|
+
&self,
|
|
278
|
+
ctx: &crate::lint_context::LintContext,
|
|
279
|
+
_doc_structure: &DocumentStructure,
|
|
280
|
+
) -> bool {
|
|
281
|
+
// This rule always applies unless content is empty
|
|
282
|
+
!ctx.content.is_empty()
|
|
283
|
+
}
|
|
284
|
+
}
|
|
@@ -74,6 +74,13 @@ impl Rule for MD018NoMissingSpaceAtx {
|
|
|
74
74
|
|
|
75
75
|
fn check(&self, ctx: &crate::lint_context::LintContext) -> LintResult {
|
|
76
76
|
let content = ctx.content;
|
|
77
|
+
|
|
78
|
+
// Early return for empty content or content without ATX headings
|
|
79
|
+
if content.is_empty() || !content.contains('#') {
|
|
80
|
+
return Ok(Vec::new());
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Fallback path: create structure manually (should rarely be used)
|
|
77
84
|
let structure = DocumentStructure::new(content);
|
|
78
85
|
self.check_with_structure(ctx, &structure)
|
|
79
86
|
}
|
|
@@ -171,6 +178,10 @@ impl Rule for MD018NoMissingSpaceAtx {
|
|
|
171
178
|
self
|
|
172
179
|
}
|
|
173
180
|
|
|
181
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
182
|
+
Some(self)
|
|
183
|
+
}
|
|
184
|
+
|
|
174
185
|
fn from_config(_config: &crate::config::Config) -> Box<dyn Rule>
|
|
175
186
|
where
|
|
176
187
|
Self: Sized,
|
|
@@ -60,6 +60,13 @@ impl Rule for MD019NoMultipleSpaceAtx {
|
|
|
60
60
|
|
|
61
61
|
fn check(&self, ctx: &crate::lint_context::LintContext) -> LintResult {
|
|
62
62
|
let content = ctx.content;
|
|
63
|
+
|
|
64
|
+
// Early return for empty content or content without ATX headings
|
|
65
|
+
if content.is_empty() || !content.contains('#') {
|
|
66
|
+
return Ok(Vec::new());
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Fallback path: create structure manually (should rarely be used)
|
|
63
70
|
let structure = DocumentStructure::new(content);
|
|
64
71
|
self.check_with_structure(ctx, &structure)
|
|
65
72
|
}
|
|
@@ -160,6 +167,10 @@ impl Rule for MD019NoMultipleSpaceAtx {
|
|
|
160
167
|
self
|
|
161
168
|
}
|
|
162
169
|
|
|
170
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
171
|
+
Some(self)
|
|
172
|
+
}
|
|
173
|
+
|
|
163
174
|
fn from_config(_config: &crate::config::Config) -> Box<dyn Rule>
|
|
164
175
|
where
|
|
165
176
|
Self: Sized,
|
|
@@ -221,6 +221,10 @@ impl Rule for MD020NoMissingSpaceClosedAtx {
|
|
|
221
221
|
self
|
|
222
222
|
}
|
|
223
223
|
|
|
224
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
225
|
+
Some(self)
|
|
226
|
+
}
|
|
227
|
+
|
|
224
228
|
fn from_config(_config: &crate::config::Config) -> Box<dyn Rule>
|
|
225
229
|
where
|
|
226
230
|
Self: Sized,
|
|
@@ -224,6 +224,10 @@ impl Rule for MD021NoMultipleSpaceClosedAtx {
|
|
|
224
224
|
self
|
|
225
225
|
}
|
|
226
226
|
|
|
227
|
+
fn as_maybe_document_structure(&self) -> Option<&dyn crate::rule::MaybeDocumentStructure> {
|
|
228
|
+
Some(self)
|
|
229
|
+
}
|
|
230
|
+
|
|
227
231
|
fn from_config(_config: &crate::config::Config) -> Box<dyn Rule>
|
|
228
232
|
where
|
|
229
233
|
Self: Sized,
|