rumdl 0.0.93__tar.gz → 0.0.94__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.93 → rumdl-0.0.94}/CHANGELOG.md +4 -1
- {rumdl-0.0.93 → rumdl-0.0.94}/Cargo.lock +3 -3
- {rumdl-0.0.93 → rumdl-0.0.94}/Cargo.toml +1 -1
- {rumdl-0.0.93 → rumdl-0.0.94}/PKG-INFO +1 -1
- rumdl-0.0.94/src/bin/benchmark_rule.rs +156 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/bin/measure_code_span_performance.rs +1 -1
- {rumdl-0.0.93 → rumdl-0.0.94}/src/lint_context.rs +22 -6
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md009_trailing_spaces.rs +10 -12
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md013_line_length.rs +121 -36
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md034_no_bare_urls.rs +98 -119
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md038_no_space_in_code.rs +32 -11
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md044_proper_names.rs +93 -89
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md047_single_trailing_newline.rs +36 -21
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md052_reference_links_images.rs +7 -3
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md053_link_image_reference_definitions.rs +62 -48
- {rumdl-0.0.93 → rumdl-0.0.94}/.config/nextest.toml +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/.mise.toml +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/.rumdl.toml +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/.rustfmt.toml +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/LICENSE +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/MANIFEST.in +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/Makefile +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/README.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/assets/logo.png +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/benches/fix_performance.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/benches/range_performance.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/benches/range_utils_benchmark.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/benches/rule_performance.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/benches/simple_fix_bench.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/RULES.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/global-settings.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md001.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md002.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md003.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md004.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md005.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md006.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md007.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md009.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md010.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md011.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md012.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md013.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md014.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md018.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md019.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md020.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md021.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md022.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md023.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md024.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md025.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md026.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md027.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md028.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md029.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md030.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md031.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md032.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md033.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md034.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md035.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md036.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md037.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md038.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md039.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md040.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md041.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md042.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md043.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md044.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md045.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md046.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md047.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md048.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md049.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md050.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md051.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md052.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md053.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md054.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md055.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md056.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md057.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/md058.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/docs/vscode-extension.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/parity_check.py +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/pyproject.toml +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/python/MANIFEST.in +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/python/PYTHON-README.md +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/python/rumdl/__init__.py +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/python/rumdl/__main__.py +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/python/rumdl/py.typed +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/rumdl.toml.example +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/rust-toolchain.toml +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/scripts/extract-changelog.sh +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/scripts/prepare-release.sh +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/bin/benchmark.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/bin/file_parallel_benchmark.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/init.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/inline_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/lib.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/lsp/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/lsp/server.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/lsp/types.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/main.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/markdownlint_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/azure.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/concise.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/github.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/gitlab.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/grouped.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/json.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/json_lines.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/junit.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/pylint.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/sarif.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/formatters/text.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/output/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/parallel.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/performance.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/profiling.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/python.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rule.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rule_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rule_config_serde.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/blockquote_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/code_block_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/code_fence_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/emphasis_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/front_matter_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/heading_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/list_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md001_heading_increment.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md002_first_heading_h1/md002_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md002_first_heading_h1.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md003_heading_style/md003_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md003_heading_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md004_unordered_list_style/md004_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md004_unordered_list_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md005_list_indent.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md006_start_bullets.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md007_ul_indent/md007_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md007_ul_indent.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md009_trailing_spaces/md009_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md010_no_hard_tabs/md010_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md010_no_hard_tabs.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md011_no_reversed_links.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md012_no_multiple_blanks/md012_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md012_no_multiple_blanks.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md013_line_length/md013_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md014_commands_show_output/md014_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md014_commands_show_output.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md018_no_missing_space_atx.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md019_no_multiple_space_atx.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md022_blanks_around_headings/md022_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md022_blanks_around_headings.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md023_heading_start_left.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md024_no_duplicate_heading/md024_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md024_no_duplicate_heading.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md025_single_title/md025_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md025_single_title.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md026_no_trailing_punctuation/md026_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md026_no_trailing_punctuation.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md028_no_blanks_blockquote.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md029_ordered_list_prefix.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md030_list_marker_space/md030_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md030_list_marker_space.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md031_blanks_around_fences.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md032_blanks_around_lists.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md033_no_inline_html/md033_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md033_no_inline_html.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md035_hr_style/md035_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md035_hr_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md036_no_emphasis_only_first/md036_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md036_no_emphasis_only_first.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md037_spaces_around_emphasis.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md039_no_space_in_links.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md040_fenced_code_language.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md041_first_line_heading.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md042_no_empty_links.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md043_required_headings.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md044_proper_names/md044_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md045_no_alt_text/md045_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md045_no_alt_text.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md046_code_block_style/md046_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md046_code_block_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md048_code_fence_style/md048_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md048_code_fence_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md049_emphasis_style/md049_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md049_emphasis_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md050_strong_style/md050_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md050_strong_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md051_link_fragments.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md054_link_image_style/md054_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md054_link_image_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md055_table_pipe_style/md055_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md055_table_pipe_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md056_table_column_count.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md057_existing_relative_links/md057_config.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md057_existing_relative_links.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/md058_blanks_around_tables.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/rules/strong_style.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/ast_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/code_block_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/document_structure.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/early_returns.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/element_cache.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/emphasis_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/fix_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/markdown_elements.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/range_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/regex_cache.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/string_interner.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/utils/table_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/src/vscode.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/advanced_integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/character_ranges/additional_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/character_ranges/basic_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/character_ranges/comprehensive_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/character_ranges/extended_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/character_ranges/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/character_ranges/unicode_utils.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/cli_duplication_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/cli_integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/cli_lsp_fix_consistency.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/cli_statistics_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/commonmark_compliance_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/comprehensive_integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/comprehensive_output_format_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/config_application_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/config_file_command_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/config_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/configuration_inheritance_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/consistency_regression_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/cross_platform_compatibility_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/final_confidence_assessment.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/init_command_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/init_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/inline_config_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/json_output_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/lib.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/lsp_editor_integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/lsp_integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/lsp_memory_leak_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/lsp_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/malformed_markdown_stress_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/markdownlint_cli_integration.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/markdownlint_config_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/markdownlintignore_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/nested_code_block_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/output_format_integration_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/output_format_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/perf_check.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/performance_validation_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/pyproject_config_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/real_world_repository_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/regression_prevention_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md001_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md001_unicode_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md002_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md003_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md004_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md005_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md006_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md006_unicode_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md007_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md009_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md010_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md011_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md012_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md013_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md014_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md018_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md019_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md020_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md021_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md022_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md023_extended_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md023_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md024_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md025_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md026_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md027_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md028_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md029_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md030_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md031_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md032_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md033_extended_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md033_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md034_ipv6_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md034_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md035_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md036_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md037_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md038_nested_backticks_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md038_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md039_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md040_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md041_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md042_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md043_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md044_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md045_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md046_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md047_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md048_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md049_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md050_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md051_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md051_unicode_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md052_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md053_additional_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md053_proptest.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md053_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md054_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md054_unicode_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md055_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md056_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md057_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/md058_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/rules_mod_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/thread_safety_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/unicode_edge_case_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/blockquote_utils_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/code_block_utils_extended_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/code_block_utils_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/core_utils_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/front_matter_utils_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/line_index_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils/mod.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils_markdown_edge_cases.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/utils_tests.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/vscode_extension_fixes.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/vscode_test.rs +0 -0
- {rumdl-0.0.93 → rumdl-0.0.94}/tests/vscode_tests.rs +0 -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.94] - 2025-07-04
|
|
11
|
+
|
|
10
12
|
## [0.0.93] - 2025-07-03
|
|
11
13
|
|
|
12
14
|
## [0.0.92] - 2025-07-02
|
|
@@ -133,7 +135,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
133
135
|
|
|
134
136
|
- Initial implementation of remaining rules for markdownlint parity
|
|
135
137
|
|
|
136
|
-
[Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.
|
|
138
|
+
[Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.94...HEAD
|
|
139
|
+
[0.0.94]: https://github.com/rvben/rumdl/compare/v0.0.93...v0.0.94
|
|
137
140
|
[0.0.93]: https://github.com/rvben/rumdl/compare/v0.0.92...v0.0.93
|
|
138
141
|
[0.0.92]: https://github.com/rvben/rumdl/compare/v0.0.91...v0.0.92
|
|
139
142
|
[0.0.91]: https://github.com/rvben/rumdl/compare/v0.0.90...v0.0.91
|
|
@@ -220,9 +220,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
|
|
220
220
|
|
|
221
221
|
[[package]]
|
|
222
222
|
name = "cc"
|
|
223
|
-
version = "1.2.
|
|
223
|
+
version = "1.2.28"
|
|
224
224
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
225
|
-
checksum = "
|
|
225
|
+
checksum = "4ad45f4f74e4e20eaa392913b7b33a7091c87e59628f4dd27888205ad888843c"
|
|
226
226
|
dependencies = [
|
|
227
227
|
"shlex",
|
|
228
228
|
]
|
|
@@ -1465,7 +1465,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
|
|
1465
1465
|
|
|
1466
1466
|
[[package]]
|
|
1467
1467
|
name = "rumdl"
|
|
1468
|
-
version = "0.0.
|
|
1468
|
+
version = "0.0.94"
|
|
1469
1469
|
dependencies = [
|
|
1470
1470
|
"anyhow",
|
|
1471
1471
|
"assert_cmd",
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
use rumdl::config::Config;
|
|
2
|
+
use rumdl::lint_context::LintContext;
|
|
3
|
+
use rumdl::rule::Rule;
|
|
4
|
+
use rumdl::rules::all_rules;
|
|
5
|
+
use std::env;
|
|
6
|
+
use std::time::Instant;
|
|
7
|
+
|
|
8
|
+
fn benchmark_rule(rule: &dyn Rule, test_cases: &[(&str, &str)], iterations: u32) -> Vec<(String, u64, u64)> {
|
|
9
|
+
let mut results = Vec::new();
|
|
10
|
+
|
|
11
|
+
for (name, content) in test_cases {
|
|
12
|
+
// Warm up
|
|
13
|
+
for _ in 0..10 {
|
|
14
|
+
let ctx = LintContext::new(content);
|
|
15
|
+
let _ = rule.check(&ctx);
|
|
16
|
+
let _ = rule.fix(&ctx);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
// Benchmark check
|
|
20
|
+
let start = Instant::now();
|
|
21
|
+
for _ in 0..iterations {
|
|
22
|
+
let ctx = LintContext::new(content);
|
|
23
|
+
let _ = rule.check(&ctx);
|
|
24
|
+
}
|
|
25
|
+
let check_time = start.elapsed().as_micros() as u64 / iterations as u64;
|
|
26
|
+
|
|
27
|
+
// Benchmark fix
|
|
28
|
+
let start = Instant::now();
|
|
29
|
+
for _ in 0..iterations {
|
|
30
|
+
let ctx = LintContext::new(content);
|
|
31
|
+
let _ = rule.fix(&ctx);
|
|
32
|
+
}
|
|
33
|
+
let fix_time = start.elapsed().as_micros() as u64 / iterations as u64;
|
|
34
|
+
|
|
35
|
+
results.push((name.to_string(), check_time, fix_time));
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
results
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fn generate_test_content(rule_name: &str) -> Vec<(&'static str, String)> {
|
|
42
|
+
match rule_name {
|
|
43
|
+
"MD009" => vec![
|
|
44
|
+
("No trailing spaces", "Line without trailing spaces\n".repeat(100)),
|
|
45
|
+
("With trailing spaces", "Line with trailing spaces \n".repeat(100)),
|
|
46
|
+
("Mixed content", "Normal line\nLine with spaces \nAnother normal\n".repeat(50)),
|
|
47
|
+
("Empty lines", "\n\n\n".repeat(100)),
|
|
48
|
+
],
|
|
49
|
+
"MD013" => vec![
|
|
50
|
+
("Short lines", "Short line\n".repeat(1000)),
|
|
51
|
+
("Long lines", "This is a very long line that exceeds the default line length limit of 80 characters and should trigger MD013\n".repeat(500)),
|
|
52
|
+
("Mixed lengths", "Short\nThis is a very long line that exceeds the limit\nShort again\n".repeat(300)),
|
|
53
|
+
("Code blocks", "```\nThis is a very long line in a code block that should be ignored by MD013\n```\n".repeat(100)),
|
|
54
|
+
],
|
|
55
|
+
"MD047" => vec![
|
|
56
|
+
("Correct ending", "Content with proper ending\n".to_string()),
|
|
57
|
+
("Missing newline", "Content without newline at end".to_string()),
|
|
58
|
+
("Multiple newlines", "Content with multiple newlines\n\n\n".to_string()),
|
|
59
|
+
("Empty file", "".to_string()),
|
|
60
|
+
("Large file correct", "Line\n".repeat(1000)),
|
|
61
|
+
("Large file incorrect", format!("{}\n\n", "Line\n".repeat(1000))),
|
|
62
|
+
],
|
|
63
|
+
"MD038" => vec![
|
|
64
|
+
("No code spans", "Regular text without code\n".repeat(100)),
|
|
65
|
+
("Correct code spans", "Text with `correct code` spans\n".repeat(100)),
|
|
66
|
+
("Spaces in code", "Text with ` spaced code ` spans\n".repeat(100)),
|
|
67
|
+
("Multiple backticks", "Text with ``code with ` backtick`` spans\n".repeat(100)),
|
|
68
|
+
("Mixed content", "Normal text\n`good code`\n` bad code `\n".repeat(100)),
|
|
69
|
+
],
|
|
70
|
+
"MD044" => vec![
|
|
71
|
+
("No proper names", "regular text without any proper names\n".repeat(100)),
|
|
72
|
+
("Correct names", "Using JavaScript and Python correctly\n".repeat(100)),
|
|
73
|
+
("Incorrect names", "Using javascript and python incorrectly\n".repeat(100)),
|
|
74
|
+
("Mixed case", "JavaScript is good, but javascript is bad\n".repeat(100)),
|
|
75
|
+
("Many names", "JavaScript Python TypeScript Ruby Go Rust Java\n".repeat(100)),
|
|
76
|
+
],
|
|
77
|
+
"MD034" => vec and [another](https://test.com)\n".repeat(100)),
|
|
80
|
+
("Bare URLs", "Check out http://example.com and https://test.com for more\n".repeat(100)),
|
|
81
|
+
("Mixed URLs", "Visit [site](http://a.com) or just go to http://b.com directly\n".repeat(100)),
|
|
82
|
+
("Complex URLs", "IPv6: http://[2001:db8::1]/path and port: http://example.com:8080/path?query=1\n".repeat(50)),
|
|
83
|
+
("Many URLs", {
|
|
84
|
+
let mut content = String::new();
|
|
85
|
+
for i in 0..200 {
|
|
86
|
+
content.push_str(&format!("URL {}: http://example{}.com/path/{}/file?id={}\n", i, i, i, i));
|
|
87
|
+
}
|
|
88
|
+
content
|
|
89
|
+
}),
|
|
90
|
+
],
|
|
91
|
+
"MD053" => vec![
|
|
92
|
+
("No references", "Simple text without any links or references\n".repeat(100)),
|
|
93
|
+
("Used references", "[link1][ref1] and [link2][ref2]\n\n[ref1]: http://example1.com\n[ref2]: http://example2.com\n".repeat(50)),
|
|
94
|
+
("Unused references", "Some text here\n\n[unused1]: http://unused1.com\n[unused2]: http://unused2.com\n".repeat(50)),
|
|
95
|
+
("Mixed references", "[used][ref1]\n\n[ref1]: http://used.com\n[unused]: http://unused.com\n".repeat(100)),
|
|
96
|
+
("Many references", {
|
|
97
|
+
let mut content = String::new();
|
|
98
|
+
for i in 0..100 {
|
|
99
|
+
content.push_str(&format!("[link{}][ref{}]\n", i, i));
|
|
100
|
+
}
|
|
101
|
+
content.push_str("\n");
|
|
102
|
+
for i in 0..200 {
|
|
103
|
+
content.push_str(&format!("[ref{}]: http://example{}.com\n", i, i));
|
|
104
|
+
}
|
|
105
|
+
content
|
|
106
|
+
}),
|
|
107
|
+
],
|
|
108
|
+
_ => vec![
|
|
109
|
+
("Default test", "Default test content\n".repeat(100)),
|
|
110
|
+
],
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fn main() {
|
|
115
|
+
let args: Vec<String> = env::args().collect();
|
|
116
|
+
if args.len() != 2 {
|
|
117
|
+
eprintln!("Usage: {} <rule_name>", args[0]);
|
|
118
|
+
std::process::exit(1);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let rule_name = &args[1];
|
|
122
|
+
let config = Config::default();
|
|
123
|
+
let rules = all_rules(&config);
|
|
124
|
+
|
|
125
|
+
let rule = rules.into_iter()
|
|
126
|
+
.find(|r| r.name() == rule_name)
|
|
127
|
+
.unwrap_or_else(|| {
|
|
128
|
+
eprintln!("Rule {} not found", rule_name);
|
|
129
|
+
std::process::exit(1);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
let test_cases_vec = generate_test_content(rule_name);
|
|
133
|
+
let test_cases: Vec<(&str, &str)> = test_cases_vec.iter()
|
|
134
|
+
.map(|(name, content)| (*name, content.as_str()))
|
|
135
|
+
.collect();
|
|
136
|
+
|
|
137
|
+
println!("Benchmarking {} Rule", rule_name);
|
|
138
|
+
println!("{}", "=".repeat(50));
|
|
139
|
+
println!();
|
|
140
|
+
|
|
141
|
+
let results = benchmark_rule(rule.as_ref(), &test_cases, 100);
|
|
142
|
+
|
|
143
|
+
let mut total_check = 0u64;
|
|
144
|
+
let mut total_fix = 0u64;
|
|
145
|
+
|
|
146
|
+
for (test_name, check_time, fix_time) in &results {
|
|
147
|
+
println!("{:<30} Check: {:>6} μs Fix: {:>6} μs", test_name, check_time, fix_time);
|
|
148
|
+
total_check += check_time;
|
|
149
|
+
total_fix += fix_time;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
println!();
|
|
153
|
+
println!("Average times:");
|
|
154
|
+
println!(" Check: {} μs", total_check / results.len() as u64);
|
|
155
|
+
println!(" Fix: {} μs", total_fix / results.len() as u64);
|
|
156
|
+
}
|
|
@@ -243,6 +243,8 @@ pub struct ListBlock {
|
|
|
243
243
|
pub nesting_level: usize,
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
+
use std::sync::{Arc, Mutex};
|
|
247
|
+
|
|
246
248
|
pub struct LintContext<'a> {
|
|
247
249
|
pub content: &'a str,
|
|
248
250
|
pub line_offsets: Vec<usize>,
|
|
@@ -251,7 +253,7 @@ pub struct LintContext<'a> {
|
|
|
251
253
|
pub links: Vec<ParsedLink>, // Pre-parsed links
|
|
252
254
|
pub images: Vec<ParsedImage>, // Pre-parsed images
|
|
253
255
|
pub reference_defs: Vec<ReferenceDef>, // Reference definitions
|
|
254
|
-
|
|
256
|
+
code_spans_cache: Mutex<Option<Arc<Vec<CodeSpan>>>>, // Lazy-loaded inline code spans
|
|
255
257
|
pub list_blocks: Vec<ListBlock>, // Pre-parsed list blocks
|
|
256
258
|
}
|
|
257
259
|
|
|
@@ -270,11 +272,11 @@ impl<'a> LintContext<'a> {
|
|
|
270
272
|
// Pre-compute line information
|
|
271
273
|
let lines = Self::compute_line_info(content, &line_offsets, &code_blocks);
|
|
272
274
|
|
|
273
|
-
// Parse links, images, references,
|
|
275
|
+
// Parse links, images, references, and list blocks
|
|
276
|
+
// Skip code spans - they'll be computed lazily
|
|
274
277
|
let links = Self::parse_links(content, &lines, &code_blocks);
|
|
275
278
|
let images = Self::parse_images(content, &lines, &code_blocks);
|
|
276
279
|
let reference_defs = Self::parse_reference_defs(content, &lines);
|
|
277
|
-
let code_spans = Self::parse_code_spans(content, &lines);
|
|
278
280
|
let list_blocks = Self::parse_list_blocks(&lines);
|
|
279
281
|
|
|
280
282
|
Self {
|
|
@@ -285,11 +287,25 @@ impl<'a> LintContext<'a> {
|
|
|
285
287
|
links,
|
|
286
288
|
images,
|
|
287
289
|
reference_defs,
|
|
288
|
-
|
|
290
|
+
code_spans_cache: Mutex::new(None),
|
|
289
291
|
list_blocks,
|
|
290
292
|
}
|
|
291
293
|
}
|
|
292
294
|
|
|
295
|
+
/// Get code spans - computed lazily on first access
|
|
296
|
+
pub fn code_spans(&self) -> Arc<Vec<CodeSpan>> {
|
|
297
|
+
let mut cache = self.code_spans_cache.lock().unwrap();
|
|
298
|
+
|
|
299
|
+
// Check if we need to compute code spans
|
|
300
|
+
if cache.is_none() {
|
|
301
|
+
let code_spans = Self::parse_code_spans(self.content, &self.lines);
|
|
302
|
+
*cache = Some(Arc::new(code_spans));
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
// Return a reference to the cached code spans
|
|
306
|
+
cache.as_ref().unwrap().clone()
|
|
307
|
+
}
|
|
308
|
+
|
|
293
309
|
/// Map a byte offset to (line, column)
|
|
294
310
|
pub fn offset_to_line_col(&self, offset: usize) -> (usize, usize) {
|
|
295
311
|
match self.line_offsets.binary_search(&offset) {
|
|
@@ -308,8 +324,8 @@ impl<'a> LintContext<'a> {
|
|
|
308
324
|
return true;
|
|
309
325
|
}
|
|
310
326
|
|
|
311
|
-
// Check inline code spans
|
|
312
|
-
self.code_spans
|
|
327
|
+
// Check inline code spans (lazy load if needed)
|
|
328
|
+
self.code_spans()
|
|
313
329
|
.iter()
|
|
314
330
|
.any(|span| pos >= span.byte_offset && pos < span.byte_end)
|
|
315
331
|
}
|
|
@@ -35,15 +35,7 @@ impl MD009TrailingSpaces {
|
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
fn count_trailing_spaces(line: &str) -> usize {
|
|
38
|
-
|
|
39
|
-
for c in line.chars().rev() {
|
|
40
|
-
if c == ' ' {
|
|
41
|
-
count += 1;
|
|
42
|
-
} else {
|
|
43
|
-
break;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
count
|
|
38
|
+
line.chars().rev().take_while(|&c| c == ' ').count()
|
|
47
39
|
}
|
|
48
40
|
|
|
49
41
|
fn is_empty_list_item_line(line: &str, prev_line: Option<&str>) -> bool {
|
|
@@ -224,6 +216,7 @@ impl Rule for MD009TrailingSpaces {
|
|
|
224
216
|
}
|
|
225
217
|
|
|
226
218
|
let trimmed = line.trim_end();
|
|
219
|
+
let trailing_spaces = Self::count_trailing_spaces(line);
|
|
227
220
|
|
|
228
221
|
// Handle empty lines - fast regex replacement
|
|
229
222
|
if trimmed.is_empty() {
|
|
@@ -256,20 +249,25 @@ impl Rule for MD009TrailingSpaces {
|
|
|
256
249
|
}
|
|
257
250
|
|
|
258
251
|
// Handle lines with trailing spaces
|
|
259
|
-
let trailing_spaces = Self::count_trailing_spaces(line);
|
|
260
252
|
let is_truly_last_line = i == lines.len() - 1 && !content.ends_with('\n');
|
|
261
253
|
|
|
262
254
|
result.push_str(trimmed);
|
|
263
255
|
|
|
264
256
|
// In non-strict mode, preserve line breaks by normalizing to br_spaces
|
|
265
257
|
if !self.config.strict && !is_truly_last_line && trailing_spaces > 0 {
|
|
266
|
-
|
|
258
|
+
// Optimize for common case of 2 spaces
|
|
259
|
+
match self.config.br_spaces {
|
|
260
|
+
0 => {},
|
|
261
|
+
1 => result.push(' '),
|
|
262
|
+
2 => result.push_str(" "),
|
|
263
|
+
n => result.push_str(&" ".repeat(n)),
|
|
264
|
+
}
|
|
267
265
|
}
|
|
268
266
|
result.push('\n');
|
|
269
267
|
}
|
|
270
268
|
|
|
271
269
|
// Preserve original ending (with or without final newline)
|
|
272
|
-
if !content.ends_with('\n') {
|
|
270
|
+
if !content.ends_with('\n') && result.ends_with('\n') {
|
|
273
271
|
result.pop();
|
|
274
272
|
}
|
|
275
273
|
|
|
@@ -135,8 +135,36 @@ impl Rule for MD013LineLength {
|
|
|
135
135
|
if content.is_empty() {
|
|
136
136
|
return Ok(Vec::new());
|
|
137
137
|
}
|
|
138
|
+
|
|
139
|
+
// Quick check: if total content is shorter than line limit, definitely no violations
|
|
140
|
+
if content.len() <= self.config.line_length {
|
|
141
|
+
return Ok(Vec::new());
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// More aggressive early return - check if any line could possibly be long
|
|
145
|
+
let has_long_lines = if !ctx.lines.is_empty() {
|
|
146
|
+
ctx.lines.iter().any(|line| line.content.len() > self.config.line_length)
|
|
147
|
+
} else {
|
|
148
|
+
// Fallback: do a quick scan for newlines to estimate max line length
|
|
149
|
+
let mut max_line_len = 0;
|
|
150
|
+
let mut current_line_len = 0;
|
|
151
|
+
for ch in content.chars() {
|
|
152
|
+
if ch == '\n' {
|
|
153
|
+
max_line_len = max_line_len.max(current_line_len);
|
|
154
|
+
current_line_len = 0;
|
|
155
|
+
} else {
|
|
156
|
+
current_line_len += 1;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
max_line_len = max_line_len.max(current_line_len);
|
|
160
|
+
max_line_len > self.config.line_length
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
if !has_long_lines {
|
|
164
|
+
return Ok(Vec::new());
|
|
165
|
+
}
|
|
138
166
|
|
|
139
|
-
//
|
|
167
|
+
// Create structure manually
|
|
140
168
|
let structure = DocumentStructure::new(content);
|
|
141
169
|
self.check_with_structure(ctx, &structure)
|
|
142
170
|
}
|
|
@@ -149,12 +177,15 @@ impl Rule for MD013LineLength {
|
|
|
149
177
|
) -> LintResult {
|
|
150
178
|
let content = ctx.content;
|
|
151
179
|
let mut warnings = Vec::new();
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
180
|
+
|
|
181
|
+
// Early return was already done in check(), so we know there are long lines
|
|
182
|
+
|
|
183
|
+
// Use ctx.lines if available for better performance
|
|
184
|
+
let lines: Vec<&str> = if !ctx.lines.is_empty() {
|
|
185
|
+
ctx.lines.iter().map(|l| l.content.as_str()).collect()
|
|
186
|
+
} else {
|
|
187
|
+
content.lines().collect()
|
|
188
|
+
};
|
|
158
189
|
|
|
159
190
|
// Pre-compute LineIndex for efficient byte range calculations
|
|
160
191
|
let line_index = crate::utils::range_utils::LineIndex::new(content.to_string());
|
|
@@ -166,9 +197,18 @@ impl Rule for MD013LineLength {
|
|
|
166
197
|
let table_lines_set: std::collections::HashSet<usize> = if self.config.tables {
|
|
167
198
|
let mut table_lines = std::collections::HashSet::new();
|
|
168
199
|
let mut in_table = false;
|
|
200
|
+
|
|
169
201
|
for (i, line) in lines.iter().enumerate() {
|
|
170
202
|
let line_number = i + 1;
|
|
171
|
-
|
|
203
|
+
|
|
204
|
+
// Quick check if in code block using pre-computed blocks from context or structure
|
|
205
|
+
let in_code = if !ctx.code_blocks.is_empty() {
|
|
206
|
+
ctx.code_blocks.iter().any(|(start, end)| *start <= line_number && line_number <= *end)
|
|
207
|
+
} else {
|
|
208
|
+
structure.is_in_code_block(line_number)
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
if !in_code && line.contains('|') {
|
|
172
212
|
in_table = true;
|
|
173
213
|
table_lines.insert(line_number);
|
|
174
214
|
} else if in_table && line.trim().is_empty() {
|
|
@@ -236,18 +276,25 @@ impl Rule for MD013LineLength {
|
|
|
236
276
|
// Generate simplified fix (avoid expensive sentence splitting for now)
|
|
237
277
|
let fix = if !self.should_skip_line_for_fix(line, line_num, structure) {
|
|
238
278
|
// First try trimming trailing whitespace
|
|
239
|
-
let
|
|
240
|
-
if
|
|
241
|
-
let
|
|
242
|
-
|
|
243
|
-
|
|
279
|
+
let last_char = line.chars().last();
|
|
280
|
+
if last_char == Some(' ') || last_char == Some('\t') {
|
|
281
|
+
let trimmed = line.trim_end();
|
|
282
|
+
// Calculate trimmed length to avoid re-scanning
|
|
283
|
+
let trimmed_len = self.calculate_effective_length(trimmed);
|
|
284
|
+
if trimmed_len <= line_limit {
|
|
285
|
+
let line_start = line_index.line_col_to_byte_range(line_number, 1).start;
|
|
286
|
+
let line_end = if line_number < lines.len() {
|
|
287
|
+
line_index.line_col_to_byte_range(line_number + 1, 1).start - 1
|
|
288
|
+
} else {
|
|
289
|
+
content.len()
|
|
290
|
+
};
|
|
291
|
+
Some(crate::rule::Fix {
|
|
292
|
+
range: line_start..line_end,
|
|
293
|
+
replacement: trimmed.to_string(),
|
|
294
|
+
})
|
|
244
295
|
} else {
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
Some(crate::rule::Fix {
|
|
248
|
-
range: line_start..line_end,
|
|
249
|
-
replacement: trimmed.to_string(),
|
|
250
|
-
})
|
|
296
|
+
None
|
|
297
|
+
}
|
|
251
298
|
} else {
|
|
252
299
|
None // Skip expensive sentence splitting for performance
|
|
253
300
|
}
|
|
@@ -289,16 +336,35 @@ impl Rule for MD013LineLength {
|
|
|
289
336
|
// Get all warnings with their fixes
|
|
290
337
|
let warnings = self.check(ctx)?;
|
|
291
338
|
|
|
292
|
-
// If no warnings, return original content
|
|
339
|
+
// If no warnings, return original content without allocation
|
|
293
340
|
if warnings.is_empty() {
|
|
294
341
|
return Ok(ctx.content.to_string());
|
|
295
342
|
}
|
|
296
343
|
|
|
297
|
-
// Collect all fixes
|
|
344
|
+
// Collect all fixes - check if any exist before allocating
|
|
345
|
+
let mut has_any_fix = false;
|
|
346
|
+
for w in &warnings {
|
|
347
|
+
if w.fix.is_some() {
|
|
348
|
+
has_any_fix = true;
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
if !has_any_fix {
|
|
354
|
+
return Ok(ctx.content.to_string());
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Now collect fixes since we know there's at least one
|
|
298
358
|
let mut fixes: Vec<_> = warnings
|
|
299
359
|
.iter()
|
|
300
360
|
.filter_map(|w| w.fix.as_ref().map(|f| (f.range.start, f.range.end, &f.replacement)))
|
|
301
361
|
.collect();
|
|
362
|
+
|
|
363
|
+
// This should not happen given our check above, but just in case
|
|
364
|
+
if fixes.is_empty() {
|
|
365
|
+
return Ok(ctx.content.to_string());
|
|
366
|
+
}
|
|
367
|
+
|
|
302
368
|
fixes.sort_by(|a, b| b.0.cmp(&a.0));
|
|
303
369
|
|
|
304
370
|
// Apply fixes from end to beginning to preserve byte offsets
|
|
@@ -325,8 +391,18 @@ impl Rule for MD013LineLength {
|
|
|
325
391
|
}
|
|
326
392
|
|
|
327
393
|
fn should_skip(&self, ctx: &crate::lint_context::LintContext) -> bool {
|
|
328
|
-
// Skip if content is empty
|
|
329
|
-
ctx.content.is_empty()
|
|
394
|
+
// Skip if content is empty
|
|
395
|
+
if ctx.content.is_empty() {
|
|
396
|
+
return true;
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
// Quick check: if total content is shorter than line limit, definitely skip
|
|
400
|
+
if ctx.content.len() <= self.config.line_length {
|
|
401
|
+
return true;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
// Use more efficient check - any() with early termination instead of all()
|
|
405
|
+
!ctx.lines.iter().any(|line| line.content.len() > self.config.line_length)
|
|
330
406
|
}
|
|
331
407
|
|
|
332
408
|
fn default_config_section(&self) -> Option<(String, toml::Value)> {
|
|
@@ -399,29 +475,38 @@ impl MD013LineLength {
|
|
|
399
475
|
return line.chars().count();
|
|
400
476
|
}
|
|
401
477
|
|
|
478
|
+
// Quick check: if line doesn't contain "http" or "[", it can't have URLs or markdown links
|
|
479
|
+
if !line.contains("http") && !line.contains('[') {
|
|
480
|
+
return line.chars().count();
|
|
481
|
+
}
|
|
482
|
+
|
|
402
483
|
let mut effective_line = line.to_string();
|
|
403
484
|
|
|
404
485
|
// First handle markdown links to avoid double-counting URLs
|
|
405
486
|
// Pattern: [text](very-long-url) -> [text](url)
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
if url.
|
|
409
|
-
|
|
410
|
-
|
|
487
|
+
if line.contains('[') && line.contains("](") {
|
|
488
|
+
for cap in MARKDOWN_LINK_PATTERN.captures_iter(&effective_line.clone()) {
|
|
489
|
+
if let (Some(full_match), Some(text), Some(url)) = (cap.get(0), cap.get(1), cap.get(2)) {
|
|
490
|
+
if url.as_str().len() > 15 {
|
|
491
|
+
let replacement = format!("[{}](url)", text.as_str());
|
|
492
|
+
effective_line = effective_line.replacen(full_match.as_str(), &replacement, 1);
|
|
493
|
+
}
|
|
411
494
|
}
|
|
412
495
|
}
|
|
413
496
|
}
|
|
414
497
|
|
|
415
498
|
// Then replace bare URLs with a placeholder of reasonable length
|
|
416
499
|
// This allows lines with long URLs to pass if the rest of the content is reasonable
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
500
|
+
if effective_line.contains("http") {
|
|
501
|
+
for url_match in URL_IN_TEXT.find_iter(&effective_line.clone()) {
|
|
502
|
+
let url = url_match.as_str();
|
|
503
|
+
// Skip if this URL is already part of a markdown link we handled
|
|
504
|
+
if !effective_line.contains(&format!("({url})")) {
|
|
505
|
+
// Replace URL with placeholder that represents a "reasonable" URL length
|
|
506
|
+
// Using 15 chars as a reasonable URL placeholder (e.g., "https://ex.com")
|
|
507
|
+
let placeholder = "x".repeat(15.min(url.len()));
|
|
508
|
+
effective_line = effective_line.replacen(url, &placeholder, 1);
|
|
509
|
+
}
|
|
425
510
|
}
|
|
426
511
|
}
|
|
427
512
|
|