rumdl 0.0.116__tar.gz → 0.0.118__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.116 → rumdl-0.0.118}/CHANGELOG.md +16 -1
- {rumdl-0.0.116 → rumdl-0.0.118}/Cargo.lock +9 -9
- {rumdl-0.0.116 → rumdl-0.0.118}/Cargo.toml +1 -1
- {rumdl-0.0.116 → rumdl-0.0.118}/PKG-INFO +1 -1
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md011_no_reversed_links.rs +94 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md037_spaces_around_emphasis.rs +31 -6
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md052_reference_links_images.rs +76 -6
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/emphasis_utils.rs +3 -1
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/kramdown_utils.rs +105 -9
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/mod.rs +1 -0
- rumdl-0.0.118/src/utils/skip_context.rs +291 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/emphasis_edge_cases_test.rs +6 -2
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md051_test.rs +54 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md052_test.rs +10 -3
- rumdl-0.0.118/tests/skip_context_tests.rs +377 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/.config/nextest.toml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/.mise.toml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/.pre-commit-config.yaml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/.rumdl.toml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/.rustfmt.toml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/LICENSE +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/MANIFEST.in +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/Makefile +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/README.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/assets/logo.png +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benches/fix_performance.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benches/range_performance.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benches/range_utils_benchmark.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benches/rule_performance.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benches/simple_fix_bench.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benchmark/bin/bench_lint_context.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benchmark/bin/benchmark.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benchmark/bin/benchmark_rule.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benchmark/bin/file_parallel_benchmark.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/benchmark/bin/measure_code_span_performance.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/RULES.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/global-settings.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md001.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md002.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md003.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md004.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md005.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md006.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md007.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md009.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md010.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md011.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md012.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md013.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md014.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md018.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md019.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md020.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md021.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md022.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md023.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md024.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md025.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md026.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md027.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md028.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md029.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md030.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md031.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md032.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md033.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md034.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md035.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md036.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md037.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md038.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md039.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md040.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md041.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md042.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md043.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md044.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md045.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md046.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md047.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md048.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md049.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md050.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md051.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md052.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md053.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md054.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md055.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md056.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md057.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/md058.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/docs/vscode-extension.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/parity_check.py +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/pyproject.toml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/python/MANIFEST.in +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/python/PYTHON-README.md +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/python/rumdl/__init__.py +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/python/rumdl/__main__.py +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/python/rumdl/py.typed +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/rumdl.toml.example +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/rust-toolchain.toml +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/scripts/extract-changelog.sh +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/scripts/generate-downloads-table.sh +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/scripts/pre-release.sh +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/scripts/prepare-release.sh +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/scripts/setup-pre-commit.sh +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/scripts/update-pre-commit-docs.sh +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/exit_codes.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/inline_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/lib.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/lint_context.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/lsp/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/lsp/server.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/lsp/types.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/main.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/markdownlint_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/azure.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/concise.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/github.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/gitlab.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/grouped.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/json.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/json_lines.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/junit.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/pylint.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/sarif.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/formatters/text.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/output/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/parallel.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/performance.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/profiling.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/python.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rule.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rule_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rule_config_serde.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/blockquote_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/code_block_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/code_fence_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/emphasis_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/front_matter_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/heading_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/list_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md001_heading_increment.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md002_first_heading_h1/md002_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md002_first_heading_h1.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md003_heading_style/md003_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md003_heading_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md004_unordered_list_style/md004_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md004_unordered_list_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md005_list_indent.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md006_start_bullets.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md007_ul_indent/md007_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md007_ul_indent.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md009_trailing_spaces/md009_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md009_trailing_spaces.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md010_no_hard_tabs/md010_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md010_no_hard_tabs.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md012_no_multiple_blanks/md012_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md012_no_multiple_blanks.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md013_line_length/md013_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md013_line_length.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md014_commands_show_output/md014_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md014_commands_show_output.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md018_no_missing_space_atx.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md019_no_multiple_space_atx.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md022_blanks_around_headings/md022_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md022_blanks_around_headings.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md023_heading_start_left.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md024_no_duplicate_heading/md024_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md024_no_duplicate_heading.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md025_single_title/md025_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md025_single_title.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md026_no_trailing_punctuation/md026_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md026_no_trailing_punctuation.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md028_no_blanks_blockquote.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md029_ordered_list_prefix/md029_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md029_ordered_list_prefix.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md030_list_marker_space/md030_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md030_list_marker_space.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md031_blanks_around_fences.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md032_blanks_around_lists.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md033_no_inline_html/md033_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md033_no_inline_html.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md034_no_bare_urls.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md035_hr_style/md035_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md035_hr_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md036_no_emphasis_only_first/md036_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md036_no_emphasis_only_first.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md038_no_space_in_code.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md039_no_space_in_links.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md040_fenced_code_language.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md041_first_line_heading.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md042_no_empty_links.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md043_required_headings.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md044_proper_names/md044_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md044_proper_names.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md045_no_alt_text/md045_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md045_no_alt_text.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md046_code_block_style/md046_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md046_code_block_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md047_single_trailing_newline.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md048_code_fence_style/md048_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md048_code_fence_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md049_emphasis_style/md049_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md049_emphasis_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md050_strong_style/md050_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md050_strong_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md051_link_fragments.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md053_link_image_reference_definitions.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md054_link_image_style/md054_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md054_link_image_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md055_table_pipe_style/md055_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md055_table_pipe_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md056_table_column_count.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md057_existing_relative_links/md057_config.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md057_existing_relative_links.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/md058_blanks_around_tables.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/rules/strong_style.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/ast_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/code_block_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/document_structure.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/early_returns.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/element_cache.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/fix_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/markdown_elements.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/range_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/regex_cache.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/string_interner.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/table_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/utils/text_reflow.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/src/vscode.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/advanced_integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/character_ranges/additional_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/character_ranges/basic_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/character_ranges/comprehensive_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/character_ranges/extended_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/character_ranges/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/character_ranges/unicode_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cli_duplication_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cli_explain_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cli_flag_precedence_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cli_integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cli_lsp_fix_consistency.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cli_statistics_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/common/cli_test_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/common/fixtures.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/common/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/common/test_utils.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/commonmark_compliance_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/comprehensive_integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/comprehensive_output_format_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/config_application_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/config_file_command_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/config_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/configuration_inheritance_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/consistency_regression_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/cross_platform_compatibility_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/deeply_nested_lists_performance_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/escaped_brackets_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/final_confidence_assessment.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/fixable_unfixable_config_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/init_command_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/init_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/inline_config_blocks_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/inline_config_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/json_output_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/kramdown_integration_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/lib.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/lsp_editor_integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/lsp_integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/lsp_memory_leak_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/lsp_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/malformed_markdown_stress_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/markdownlint_cli_integration.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/markdownlint_config_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/markdownlintignore_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/md013_reflow_integration_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/nested_code_block_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/output_format_integration_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/output_format_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/perf_check.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/performance_validation_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/pyproject_config_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/python_bindings_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/real_world_repository_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/regression_prevention_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/heading_edge_cases_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/inline_content_edge_cases_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/link_edge_cases_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/list_rules_integration_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md001_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md001_unicode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md002_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md003_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md004_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md005_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md005_unicode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md006_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md006_unicode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md007_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md009_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md010_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md011_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md012_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md013_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md014_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md018_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md019_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md020_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md021_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md022_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md023_extended_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md023_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md024_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md025_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md026_kramdown_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md026_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md027_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md028_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md029_issue42_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md029_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md029_unicode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md030_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md031_kramdown_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md031_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md032_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md033_extended_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md033_kramdown_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md033_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md034_ipv6_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md034_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md035_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md036_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md037_kramdown_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md037_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md038_nested_backticks_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md038_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md039_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md040_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md041_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md042_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md043_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md044_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md045_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md046_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md047_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md048_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md049_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md050_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md051_unicode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md053_additional_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md053_proptest.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md053_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md054_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md054_unicode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md055_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md056_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md057_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md058_kramdown_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/md058_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/rules_mod_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/thread_safety_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/unicode_edge_case_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/blockquote_utils_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/code_block_utils_extended_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/code_block_utils_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/core_utils_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/front_matter_utils_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/line_index_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils/mod.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils_markdown_edge_cases.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/utils_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/vscode_extension_fixes.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/vscode_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/vscode_tests.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/vscode_windows_comprehensive_test.rs +0 -0
- {rumdl-0.0.116 → rumdl-0.0.118}/tests/vscode_windows_test.rs +0 -0
|
@@ -7,6 +7,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.0.118] - 2025-08-14
|
|
11
|
+
|
|
12
|
+
## [0.0.117] - 2025-08-14
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
- MD037: Fixed false positive with asterisks in inline code spans (issue #49)
|
|
16
|
+
- Inline code content is now properly masked before emphasis detection
|
|
17
|
+
- MD011: Fixed false positive with array access patterns in link titles (issue #50)
|
|
18
|
+
- Context detection now properly skips patterns inside code spans
|
|
19
|
+
- MD052: Fixed false positive with square brackets in HTML attributes (issue #51)
|
|
20
|
+
- HTML tag detection prevents reference checking within HTML elements
|
|
21
|
+
- Added centralized skip context detection for improved accuracy across rules
|
|
22
|
+
|
|
10
23
|
## [0.0.116] - 2025-08-13
|
|
11
24
|
|
|
12
25
|
### Added
|
|
@@ -324,7 +337,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
324
337
|
|
|
325
338
|
- Initial implementation of remaining rules for markdownlint parity
|
|
326
339
|
|
|
327
|
-
[Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.
|
|
340
|
+
[Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.118...HEAD
|
|
341
|
+
[0.0.118]: https://github.com/rvben/rumdl/compare/v0.0.117...v0.0.118
|
|
342
|
+
[0.0.117]: https://github.com/rvben/rumdl/compare/v0.0.116...v0.0.117
|
|
328
343
|
[0.0.116]: https://github.com/rvben/rumdl/compare/v0.0.115...v0.0.116
|
|
329
344
|
[0.0.115]: https://github.com/rvben/rumdl/compare/v0.0.114...v0.0.115
|
|
330
345
|
[0.0.114]: https://github.com/rvben/rumdl/compare/v0.0.113...v0.0.114
|
|
@@ -121,9 +121,9 @@ dependencies = [
|
|
|
121
121
|
|
|
122
122
|
[[package]]
|
|
123
123
|
name = "async-trait"
|
|
124
|
-
version = "0.1.
|
|
124
|
+
version = "0.1.89"
|
|
125
125
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
126
|
-
checksum = "
|
|
126
|
+
checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb"
|
|
127
127
|
dependencies = [
|
|
128
128
|
"proc-macro2",
|
|
129
129
|
"quote",
|
|
@@ -1435,9 +1435,9 @@ dependencies = [
|
|
|
1435
1435
|
|
|
1436
1436
|
[[package]]
|
|
1437
1437
|
name = "rayon"
|
|
1438
|
-
version = "1.
|
|
1438
|
+
version = "1.11.0"
|
|
1439
1439
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1440
|
-
checksum = "
|
|
1440
|
+
checksum = "368f01d005bf8fd9b1206fb6fa653e6c4a81ceb1466406b81792d87c5677a58f"
|
|
1441
1441
|
dependencies = [
|
|
1442
1442
|
"either",
|
|
1443
1443
|
"rayon-core",
|
|
@@ -1445,9 +1445,9 @@ dependencies = [
|
|
|
1445
1445
|
|
|
1446
1446
|
[[package]]
|
|
1447
1447
|
name = "rayon-core"
|
|
1448
|
-
version = "1.
|
|
1448
|
+
version = "1.13.0"
|
|
1449
1449
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1450
|
-
checksum = "
|
|
1450
|
+
checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91"
|
|
1451
1451
|
dependencies = [
|
|
1452
1452
|
"crossbeam-deque",
|
|
1453
1453
|
"crossbeam-utils",
|
|
@@ -1493,7 +1493,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
|
|
1493
1493
|
|
|
1494
1494
|
[[package]]
|
|
1495
1495
|
name = "rumdl"
|
|
1496
|
-
version = "0.0.
|
|
1496
|
+
version = "0.0.118"
|
|
1497
1497
|
dependencies = [
|
|
1498
1498
|
"anyhow",
|
|
1499
1499
|
"assert_cmd",
|
|
@@ -1723,9 +1723,9 @@ checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
|
|
|
1723
1723
|
|
|
1724
1724
|
[[package]]
|
|
1725
1725
|
name = "syn"
|
|
1726
|
-
version = "2.0.
|
|
1726
|
+
version = "2.0.105"
|
|
1727
1727
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
1728
|
-
checksum = "
|
|
1728
|
+
checksum = "7bc3fcb250e53458e712715cf74285c1f889686520d79294a9ef3bd7aa1fc619"
|
|
1729
1729
|
dependencies = [
|
|
1730
1730
|
"proc-macro2",
|
|
1731
1731
|
"quote",
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
/// See [docs/md011.md](../../docs/md011.md) for full documentation, configuration, and examples.
|
|
4
4
|
use crate::rule::{Fix, LintError, LintResult, LintWarning, Rule, Severity};
|
|
5
5
|
use crate::utils::range_utils::calculate_match_range;
|
|
6
|
+
use crate::utils::skip_context::{is_in_front_matter, is_in_html_comment, is_in_math_context};
|
|
6
7
|
use lazy_static::lazy_static;
|
|
7
8
|
use regex::Regex;
|
|
8
9
|
|
|
@@ -216,6 +217,21 @@ impl Rule for MD011NoReversedLinks {
|
|
|
216
217
|
continue;
|
|
217
218
|
}
|
|
218
219
|
|
|
220
|
+
// Skip if in HTML comment
|
|
221
|
+
if is_in_html_comment(content, match_byte_pos) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
// Skip if in math context
|
|
226
|
+
if is_in_math_context(ctx, match_byte_pos) {
|
|
227
|
+
continue;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Skip if in front matter (line_num is 0-based)
|
|
231
|
+
if is_in_front_matter(content, line_num) {
|
|
232
|
+
continue;
|
|
233
|
+
}
|
|
234
|
+
|
|
219
235
|
// Check if the match contains escaped brackets or parentheses
|
|
220
236
|
let match_text = match_obj.as_str();
|
|
221
237
|
|
|
@@ -283,6 +299,21 @@ impl Rule for MD011NoReversedLinks {
|
|
|
283
299
|
continue;
|
|
284
300
|
}
|
|
285
301
|
|
|
302
|
+
// Skip if in HTML comment
|
|
303
|
+
if is_in_html_comment(content, match_byte_pos) {
|
|
304
|
+
continue;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
// Skip if in math context
|
|
308
|
+
if is_in_math_context(ctx, match_byte_pos) {
|
|
309
|
+
continue;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
// Skip if in front matter (line_num is 0-based)
|
|
313
|
+
if is_in_front_matter(content, line_num) {
|
|
314
|
+
continue;
|
|
315
|
+
}
|
|
316
|
+
|
|
286
317
|
// Calculate precise character range for the malformed syntax
|
|
287
318
|
let (start_line, start_col, end_line, end_col) = calculate_match_range(line_num + 1, line, start, len);
|
|
288
319
|
|
|
@@ -367,6 +398,7 @@ impl Rule for MD011NoReversedLinks {
|
|
|
367
398
|
mod tests {
|
|
368
399
|
use super::*;
|
|
369
400
|
use crate::lint_context::LintContext;
|
|
401
|
+
use crate::utils::skip_context::is_in_front_matter;
|
|
370
402
|
|
|
371
403
|
#[test]
|
|
372
404
|
fn test_capture_group_order_fix() {
|
|
@@ -453,6 +485,68 @@ mod tests {
|
|
|
453
485
|
}
|
|
454
486
|
}
|
|
455
487
|
|
|
488
|
+
#[test]
|
|
489
|
+
fn test_front_matter_detection() {
|
|
490
|
+
let content = r#"---
|
|
491
|
+
title: "My Post"
|
|
492
|
+
tags: ["test", "example"]
|
|
493
|
+
description: "Pattern (like)[this] in frontmatter"
|
|
494
|
+
---
|
|
495
|
+
|
|
496
|
+
# Content
|
|
497
|
+
|
|
498
|
+
Regular (https://example.com)[reversed link] that should be flagged.
|
|
499
|
+
|
|
500
|
+
+++
|
|
501
|
+
title = "TOML frontmatter"
|
|
502
|
+
tags = ["more", "tags"]
|
|
503
|
+
pattern = "(toml)[pattern]"
|
|
504
|
+
+++
|
|
505
|
+
|
|
506
|
+
# More Content
|
|
507
|
+
|
|
508
|
+
Another (https://test.com)[reversed] link should be flagged."#;
|
|
509
|
+
|
|
510
|
+
// Test line by line
|
|
511
|
+
for (idx, line) in content.lines().enumerate() {
|
|
512
|
+
let line_num = idx; // 0-based
|
|
513
|
+
let in_fm = is_in_front_matter(content, line_num);
|
|
514
|
+
|
|
515
|
+
println!("Line {:2} (0-idx: {:2}): in_fm={:5} | {:?}", idx + 1, idx, in_fm, line);
|
|
516
|
+
|
|
517
|
+
// Lines 0-4 should be in YAML front matter
|
|
518
|
+
if idx <= 4 {
|
|
519
|
+
assert!(
|
|
520
|
+
in_fm,
|
|
521
|
+
"Line {} (0-idx: {}) should be in YAML front matter but got false. Content: {:?}",
|
|
522
|
+
idx + 1,
|
|
523
|
+
idx,
|
|
524
|
+
line
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
// Lines 10-14 are NOT front matter (TOML block not at beginning)
|
|
528
|
+
else if (10..=14).contains(&idx) {
|
|
529
|
+
assert!(
|
|
530
|
+
!in_fm,
|
|
531
|
+
"Line {} (0-idx: {}) should NOT be in front matter (TOML block not at beginning). Content: {:?}",
|
|
532
|
+
idx + 1,
|
|
533
|
+
idx,
|
|
534
|
+
line
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
// Everything else should NOT be in front matter
|
|
538
|
+
else {
|
|
539
|
+
assert!(
|
|
540
|
+
!in_fm,
|
|
541
|
+
"Line {} (0-idx: {}) should NOT be in front matter but got true. Content: {:?}",
|
|
542
|
+
idx + 1,
|
|
543
|
+
idx,
|
|
544
|
+
line
|
|
545
|
+
);
|
|
546
|
+
}
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
|
|
456
550
|
#[test]
|
|
457
551
|
fn test_malformed_link_detection() {
|
|
458
552
|
let rule = MD011NoReversedLinks;
|
|
@@ -3,9 +3,12 @@
|
|
|
3
3
|
/// See [docs/md037.md](../../docs/md037.md) for full documentation, configuration, and examples.
|
|
4
4
|
use crate::rule::{Fix, LintError, LintResult, LintWarning, Rule, RuleCategory, Severity};
|
|
5
5
|
use crate::utils::document_structure::{DocumentStructure, DocumentStructureExtensions};
|
|
6
|
-
use crate::utils::emphasis_utils::{
|
|
6
|
+
use crate::utils::emphasis_utils::{
|
|
7
|
+
EmphasisSpan, find_emphasis_markers, find_emphasis_spans, has_doc_patterns, replace_inline_code,
|
|
8
|
+
};
|
|
7
9
|
use crate::utils::kramdown_utils::has_span_ial;
|
|
8
10
|
use crate::utils::regex_cache::UNORDERED_LIST_MARKER_REGEX;
|
|
11
|
+
use crate::utils::skip_context::{is_in_html_comment, is_in_math_context, is_in_table_cell};
|
|
9
12
|
use lazy_static::lazy_static;
|
|
10
13
|
use regex::Regex;
|
|
11
14
|
|
|
@@ -116,7 +119,7 @@ impl Rule for MD037NoSpaceInEmphasis {
|
|
|
116
119
|
self.check_line_for_emphasis_issues_fast(line, line_num + 1, &mut warnings);
|
|
117
120
|
}
|
|
118
121
|
|
|
119
|
-
// Filter out warnings for emphasis markers that are inside links
|
|
122
|
+
// Filter out warnings for emphasis markers that are inside links, HTML comments, or math
|
|
120
123
|
let mut filtered_warnings = Vec::new();
|
|
121
124
|
let mut line_start_pos = 0;
|
|
122
125
|
|
|
@@ -129,8 +132,12 @@ impl Rule for MD037NoSpaceInEmphasis {
|
|
|
129
132
|
// Calculate byte position of the warning
|
|
130
133
|
let byte_pos = line_start_pos + (warning.column - 1);
|
|
131
134
|
|
|
132
|
-
//
|
|
133
|
-
if !self.is_in_link(ctx, byte_pos)
|
|
135
|
+
// Skip if inside links, HTML comments, math contexts, or tables
|
|
136
|
+
if !self.is_in_link(ctx, byte_pos)
|
|
137
|
+
&& !is_in_html_comment(content, byte_pos)
|
|
138
|
+
&& !is_in_math_context(ctx, byte_pos)
|
|
139
|
+
&& !is_in_table_cell(ctx, line_num, warning.column)
|
|
140
|
+
{
|
|
134
141
|
filtered_warnings.push(warning.clone());
|
|
135
142
|
}
|
|
136
143
|
}
|
|
@@ -314,14 +321,17 @@ impl MD037NoSpaceInEmphasis {
|
|
|
314
321
|
offset: usize,
|
|
315
322
|
warnings: &mut Vec<LintWarning>,
|
|
316
323
|
) {
|
|
324
|
+
// Replace inline code to avoid false positives with emphasis markers inside backticks
|
|
325
|
+
let processed_content = replace_inline_code(content);
|
|
326
|
+
|
|
317
327
|
// Find all emphasis markers using optimized parsing
|
|
318
|
-
let markers = find_emphasis_markers(
|
|
328
|
+
let markers = find_emphasis_markers(&processed_content);
|
|
319
329
|
if markers.is_empty() {
|
|
320
330
|
return;
|
|
321
331
|
}
|
|
322
332
|
|
|
323
333
|
// Find valid emphasis spans
|
|
324
|
-
let spans = find_emphasis_spans(
|
|
334
|
+
let spans = find_emphasis_spans(&processed_content, markers);
|
|
325
335
|
|
|
326
336
|
// Check each span for spacing issues
|
|
327
337
|
for span in spans {
|
|
@@ -473,6 +483,21 @@ This has * real spaced emphasis * that should be flagged."#;
|
|
|
473
483
|
assert!(result[0].line == 1);
|
|
474
484
|
}
|
|
475
485
|
|
|
486
|
+
#[test]
|
|
487
|
+
fn test_issue_49_asterisk_in_inline_code() {
|
|
488
|
+
// Test for issue #49 - Asterisk within backticks identified as for emphasis
|
|
489
|
+
let rule = MD037NoSpaceInEmphasis;
|
|
490
|
+
|
|
491
|
+
// Test case from issue #49
|
|
492
|
+
let content = "The `__mul__` method is needed for left-hand multiplication (`vector * 3`) and `__rmul__` is needed for right-hand multiplication (`3 * vector`).";
|
|
493
|
+
let ctx = LintContext::new(content);
|
|
494
|
+
let result = rule.check(&ctx).unwrap();
|
|
495
|
+
assert!(
|
|
496
|
+
result.is_empty(),
|
|
497
|
+
"Should not flag asterisks inside inline code as emphasis (issue #49). Got: {result:?}"
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
|
|
476
501
|
#[test]
|
|
477
502
|
fn test_issue_28_inline_code_in_emphasis() {
|
|
478
503
|
// Test for issue #28 - MD037 should not flag inline code inside emphasis as spaces
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
use crate::rule::{LintError, LintResult, LintWarning, Rule, Severity};
|
|
2
|
-
use crate::rules::front_matter_utils::FrontMatterUtils;
|
|
3
2
|
use crate::utils::range_utils::calculate_match_range;
|
|
4
3
|
use crate::utils::regex_cache::HTML_COMMENT_PATTERN;
|
|
4
|
+
use crate::utils::skip_context::{is_in_front_matter, is_in_math_context, is_in_table_cell};
|
|
5
5
|
use fancy_regex::Regex as FancyRegex;
|
|
6
6
|
use lazy_static::lazy_static;
|
|
7
7
|
use regex::Regex;
|
|
@@ -19,9 +19,9 @@ lazy_static! {
|
|
|
19
19
|
static ref REF_IMAGE_REGEX: FancyRegex = FancyRegex::new(r"(?<!\\)!\[((?:[^\[\]\\]|\\.|\[[^\]]*\])*)\]\[([^\]]*)\]").unwrap();
|
|
20
20
|
|
|
21
21
|
// Pattern for shortcut reference links [reference]
|
|
22
|
-
// Must not be preceded by ] (to avoid matching second part of [text][ref])
|
|
22
|
+
// Must not be preceded by ] or ) (to avoid matching second part of [text][ref] or reversed links (url)[text])
|
|
23
23
|
// Must not be followed by [ or ( (to avoid matching first part of [text][ref] or [text](url))
|
|
24
|
-
static ref SHORTCUT_REF_REGEX: FancyRegex = FancyRegex::new(r"(?<![\\])\[([^\]]+)\](?!\s*[\[\(])").unwrap();
|
|
24
|
+
static ref SHORTCUT_REF_REGEX: FancyRegex = FancyRegex::new(r"(?<![\\)\]])\[([^\]]+)\](?!\s*[\[\(])").unwrap();
|
|
25
25
|
|
|
26
26
|
// Pattern to match inline links and images (to exclude them)
|
|
27
27
|
static ref INLINE_LINK_REGEX: FancyRegex = FancyRegex::new(r"(?<!\\)\[([^\]]+)\]\(([^)]+)\)").unwrap();
|
|
@@ -73,6 +73,17 @@ impl MD052ReferenceLinkImages {
|
|
|
73
73
|
false
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/// Check if a byte position is within an HTML tag
|
|
77
|
+
fn is_in_html_tag(ctx: &crate::lint_context::LintContext, byte_pos: usize) -> bool {
|
|
78
|
+
// Check HTML tags
|
|
79
|
+
for html_tag in ctx.html_tags().iter() {
|
|
80
|
+
if html_tag.byte_offset <= byte_pos && byte_pos < html_tag.byte_end {
|
|
81
|
+
return true;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
false
|
|
85
|
+
}
|
|
86
|
+
|
|
76
87
|
fn extract_references(&self, content: &str) -> HashSet<String> {
|
|
77
88
|
let mut references = HashSet::new();
|
|
78
89
|
let mut in_code_block = false;
|
|
@@ -141,8 +152,18 @@ impl MD052ReferenceLinkImages {
|
|
|
141
152
|
continue;
|
|
142
153
|
}
|
|
143
154
|
|
|
155
|
+
// Skip links inside math contexts
|
|
156
|
+
if is_in_math_context(ctx, link.byte_offset) {
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Skip links inside table cells
|
|
161
|
+
if is_in_table_cell(ctx, link.line, link.start_col) {
|
|
162
|
+
continue;
|
|
163
|
+
}
|
|
164
|
+
|
|
144
165
|
// Skip links inside frontmatter (convert from 1-based to 0-based line numbers)
|
|
145
|
-
if
|
|
166
|
+
if is_in_front_matter(content, link.line.saturating_sub(1)) {
|
|
146
167
|
continue;
|
|
147
168
|
}
|
|
148
169
|
|
|
@@ -191,8 +212,18 @@ impl MD052ReferenceLinkImages {
|
|
|
191
212
|
continue;
|
|
192
213
|
}
|
|
193
214
|
|
|
215
|
+
// Skip images inside math contexts
|
|
216
|
+
if is_in_math_context(ctx, image.byte_offset) {
|
|
217
|
+
continue;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Skip images inside table cells
|
|
221
|
+
if is_in_table_cell(ctx, image.line, image.start_col) {
|
|
222
|
+
continue;
|
|
223
|
+
}
|
|
224
|
+
|
|
194
225
|
// Skip images inside frontmatter (convert from 1-based to 0-based line numbers)
|
|
195
|
-
if
|
|
226
|
+
if is_in_front_matter(content, image.line.saturating_sub(1)) {
|
|
196
227
|
continue;
|
|
197
228
|
}
|
|
198
229
|
|
|
@@ -248,7 +279,7 @@ impl MD052ReferenceLinkImages {
|
|
|
248
279
|
|
|
249
280
|
for (line_num, line) in lines.iter().enumerate() {
|
|
250
281
|
// Skip lines in frontmatter (line_num is already 0-based)
|
|
251
|
-
if
|
|
282
|
+
if is_in_front_matter(content, line_num) {
|
|
252
283
|
continue;
|
|
253
284
|
}
|
|
254
285
|
|
|
@@ -316,6 +347,22 @@ impl MD052ReferenceLinkImages {
|
|
|
316
347
|
if Self::is_in_html_comment(content, byte_pos) {
|
|
317
348
|
continue;
|
|
318
349
|
}
|
|
350
|
+
|
|
351
|
+
// Skip if inside HTML tag
|
|
352
|
+
if Self::is_in_html_tag(ctx, byte_pos) {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
// Skip if inside math context
|
|
357
|
+
if is_in_math_context(ctx, byte_pos) {
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
// Skip if inside table cell
|
|
362
|
+
if is_in_table_cell(ctx, line_num + 1, col) {
|
|
363
|
+
continue;
|
|
364
|
+
}
|
|
365
|
+
|
|
319
366
|
let byte_end = byte_pos + (full_match.end() - full_match.start());
|
|
320
367
|
|
|
321
368
|
// Check if this shortcut ref overlaps with any parsed link/image
|
|
@@ -723,6 +770,29 @@ Multiple `[one]` and `[two]` in code ignored, but [three] is not.
|
|
|
723
770
|
assert_eq!(result.len(), 0);
|
|
724
771
|
}
|
|
725
772
|
|
|
773
|
+
#[test]
|
|
774
|
+
fn test_issue_51_html_attribute_not_reference() {
|
|
775
|
+
// Test for issue #51 - HTML attributes with square brackets shouldn't be treated as references
|
|
776
|
+
let rule = MD052ReferenceLinkImages::new();
|
|
777
|
+
let content = r#"# Example
|
|
778
|
+
|
|
779
|
+
## Test
|
|
780
|
+
|
|
781
|
+
Want to fill out this form?
|
|
782
|
+
|
|
783
|
+
<form method="post">
|
|
784
|
+
<input type="email" name="fields[email]" id="drip-email" placeholder="email@domain.com">
|
|
785
|
+
</form>"#;
|
|
786
|
+
let ctx = LintContext::new(content);
|
|
787
|
+
let result = rule.check(&ctx).unwrap();
|
|
788
|
+
|
|
789
|
+
assert_eq!(
|
|
790
|
+
result.len(),
|
|
791
|
+
0,
|
|
792
|
+
"HTML attributes with square brackets should not be flagged as undefined references"
|
|
793
|
+
);
|
|
794
|
+
}
|
|
795
|
+
|
|
726
796
|
#[test]
|
|
727
797
|
fn test_extract_references() {
|
|
728
798
|
let rule = MD052ReferenceLinkImages::new();
|
|
@@ -56,6 +56,7 @@ pub struct EmphasisSpan {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
/// Enhanced inline code replacement with optimized performance
|
|
59
|
+
/// Replaces inline code with 'X' characters to prevent false positives in emphasis detection
|
|
59
60
|
#[inline]
|
|
60
61
|
pub fn replace_inline_code(line: &str) -> String {
|
|
61
62
|
// Quick check: if no backticks, return original
|
|
@@ -72,7 +73,8 @@ pub fn replace_inline_code(line: &str) -> String {
|
|
|
72
73
|
{
|
|
73
74
|
let match_start = full_match.start();
|
|
74
75
|
let match_end = full_match.end();
|
|
75
|
-
|
|
76
|
+
// Use 'X' instead of spaces to avoid false positives for "spaces in emphasis"
|
|
77
|
+
let placeholder = "X".repeat(match_end - match_start);
|
|
76
78
|
|
|
77
79
|
result.replace_range(match_start + offset..match_end + offset, &placeholder);
|
|
78
80
|
offset += placeholder.len() - (match_end - match_start);
|
|
@@ -10,10 +10,11 @@ lazy_static! {
|
|
|
10
10
|
/// Pattern for Kramdown span IAL: text{:.class #id key="value"}
|
|
11
11
|
static ref SPAN_IAL_PATTERN: Regex = Regex::new(r"\{[:\.#][^}]*\}$").unwrap();
|
|
12
12
|
|
|
13
|
-
/// Pattern for
|
|
13
|
+
/// Pattern for custom header IDs supporting both kramdown and python-markdown attr-list formats
|
|
14
|
+
/// Supports: {#id}, { #id }, {:#id}, {: #id } (all variations with optional colon and spaces)
|
|
14
15
|
/// Permissive but safe: Unicode letters/numbers, hyphens, underscores, colons (Kramdown allows)
|
|
15
|
-
/// Rejects: spaces, quotes, brackets, HTML/CSS special chars
|
|
16
|
-
static ref HEADER_ID_PATTERN: Regex = Regex::new(r"\s*\{
|
|
16
|
+
/// Rejects: spaces in ID, quotes, brackets, HTML/CSS special chars
|
|
17
|
+
static ref HEADER_ID_PATTERN: Regex = Regex::new(r"\s*\{\s*:?\s*#\s*[\w\-:]+\s*\}\s*$").unwrap();
|
|
17
18
|
|
|
18
19
|
/// Pattern for Kramdown extensions opening: {::comment}, {::nomarkdown}, etc.
|
|
19
20
|
static ref EXTENSION_OPEN_PATTERN: Regex = Regex::new(r"^\s*\{::([a-z]+)(?:\s+[^}]*)?\}\s*$").unwrap();
|
|
@@ -119,6 +120,12 @@ pub fn remove_header_id(line: &str) -> String {
|
|
|
119
120
|
/// Extract custom header ID from a heading line
|
|
120
121
|
/// Returns a tuple of (clean_text, Option<custom_id>)
|
|
121
122
|
///
|
|
123
|
+
/// Supports both kramdown and python-markdown attr-list formats:
|
|
124
|
+
/// - `{#custom-id}` (kramdown style)
|
|
125
|
+
/// - `{ #custom-id }` (attr-list with spaces)
|
|
126
|
+
/// - `{:#custom-id}` (attr-list with colon)
|
|
127
|
+
/// - `{: #custom-id }` (attr-list with colon and spaces)
|
|
128
|
+
///
|
|
122
129
|
/// # Examples
|
|
123
130
|
/// ```
|
|
124
131
|
/// use rumdl::utils::kramdown_utils::extract_header_id;
|
|
@@ -127,6 +134,14 @@ pub fn remove_header_id(line: &str) -> String {
|
|
|
127
134
|
/// assert_eq!(text, "## Header");
|
|
128
135
|
/// assert_eq!(id, Some("custom-id".to_string()));
|
|
129
136
|
///
|
|
137
|
+
/// let (text, id) = extract_header_id("## Header { #spaced-id }");
|
|
138
|
+
/// assert_eq!(text, "## Header");
|
|
139
|
+
/// assert_eq!(id, Some("spaced-id".to_string()));
|
|
140
|
+
///
|
|
141
|
+
/// let (text, id) = extract_header_id("## Header {: #colon-id }");
|
|
142
|
+
/// assert_eq!(text, "## Header");
|
|
143
|
+
/// assert_eq!(id, Some("colon-id".to_string()));
|
|
144
|
+
///
|
|
130
145
|
/// let (text, id) = extract_header_id("## Normal Header");
|
|
131
146
|
/// assert_eq!(text, "## Normal Header");
|
|
132
147
|
/// assert_eq!(id, None);
|
|
@@ -138,13 +153,21 @@ pub fn extract_header_id(line: &str) -> (String, Option<String>) {
|
|
|
138
153
|
// Extract the clean text without the ID
|
|
139
154
|
let clean_text = line[..id_match.start()].trim_end().to_string();
|
|
140
155
|
|
|
141
|
-
// Extract the ID from {#
|
|
156
|
+
// Extract the ID from various formats: {#id}, { #id }, {:#id}, {: #id }
|
|
142
157
|
let id_str = id_match.as_str().trim();
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
158
|
+
|
|
159
|
+
// Remove braces and extract content
|
|
160
|
+
let inner = id_str.trim_start_matches('{').trim_end_matches('}').trim();
|
|
161
|
+
|
|
162
|
+
// Handle optional colon and find the hash
|
|
163
|
+
let after_colon = if inner.starts_with(':') {
|
|
164
|
+
inner.trim_start_matches(':').trim()
|
|
165
|
+
} else {
|
|
166
|
+
inner
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// Extract ID after hash
|
|
170
|
+
let id = after_colon.trim_start_matches('#').trim().to_string();
|
|
148
171
|
|
|
149
172
|
return (clean_text, Some(id));
|
|
150
173
|
}
|
|
@@ -286,4 +309,77 @@ mod tests {
|
|
|
286
309
|
assert!(is_kramdown_block_attribute("\t{:#id}\t"));
|
|
287
310
|
assert!(is_kramdown_block_attribute(" {:.class #id} "));
|
|
288
311
|
}
|
|
312
|
+
|
|
313
|
+
#[test]
|
|
314
|
+
fn test_header_id_detection() {
|
|
315
|
+
// Kramdown style (original format)
|
|
316
|
+
assert!(has_header_id("# Header {#custom-id}"));
|
|
317
|
+
assert!(has_header_id("## Section {#section-1}"));
|
|
318
|
+
|
|
319
|
+
// Python-markdown attr-list with spaces
|
|
320
|
+
assert!(has_header_id("# Header { #spaced-id }"));
|
|
321
|
+
assert!(has_header_id("## Section { #section-with-spaces }"));
|
|
322
|
+
|
|
323
|
+
// Python-markdown attr-list with colon
|
|
324
|
+
assert!(has_header_id("# Header {:#colon-id}"));
|
|
325
|
+
assert!(has_header_id("## Section {: #colon-with-spaces }"));
|
|
326
|
+
|
|
327
|
+
// Combined colon and spaces
|
|
328
|
+
assert!(has_header_id("# Header {: #full-format }"));
|
|
329
|
+
|
|
330
|
+
// Should not match
|
|
331
|
+
assert!(!has_header_id("# Regular Header"));
|
|
332
|
+
assert!(!has_header_id("# Header { no hash }"));
|
|
333
|
+
assert!(!has_header_id("# Header {#}")); // Empty ID
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
#[test]
|
|
337
|
+
fn test_header_id_extraction() {
|
|
338
|
+
// Kramdown style (original format)
|
|
339
|
+
let (text, id) = extract_header_id("## Header {#test-id}");
|
|
340
|
+
assert_eq!(text, "## Header");
|
|
341
|
+
assert_eq!(id, Some("test-id".to_string()));
|
|
342
|
+
|
|
343
|
+
// Python-markdown attr-list with spaces
|
|
344
|
+
let (text, id) = extract_header_id("# Title { #spaced-id }");
|
|
345
|
+
assert_eq!(text, "# Title");
|
|
346
|
+
assert_eq!(id, Some("spaced-id".to_string()));
|
|
347
|
+
|
|
348
|
+
// Python-markdown attr-list with colon (no spaces)
|
|
349
|
+
let (text, id) = extract_header_id("### Subsection {:#compact-colon}");
|
|
350
|
+
assert_eq!(text, "### Subsection");
|
|
351
|
+
assert_eq!(id, Some("compact-colon".to_string()));
|
|
352
|
+
|
|
353
|
+
// Python-markdown attr-list with colon and spaces
|
|
354
|
+
let (text, id) = extract_header_id("#### Deep Section {: #colon-spaces }");
|
|
355
|
+
assert_eq!(text, "#### Deep Section");
|
|
356
|
+
assert_eq!(id, Some("colon-spaces".to_string()));
|
|
357
|
+
|
|
358
|
+
// No header ID
|
|
359
|
+
let (text, id) = extract_header_id("## Normal Header");
|
|
360
|
+
assert_eq!(text, "## Normal Header");
|
|
361
|
+
assert_eq!(id, None);
|
|
362
|
+
|
|
363
|
+
// Complex ID with allowed characters
|
|
364
|
+
let (text, id) = extract_header_id("# Header {#complex-id_with:colons}");
|
|
365
|
+
assert_eq!(text, "# Header");
|
|
366
|
+
assert_eq!(id, Some("complex-id_with:colons".to_string()));
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
#[test]
|
|
370
|
+
fn test_header_id_edge_cases() {
|
|
371
|
+
// Test that extra spaces are handled correctly
|
|
372
|
+
let (text, id) = extract_header_id("# Header { : # extra-spaces }");
|
|
373
|
+
assert_eq!(text, "# Header");
|
|
374
|
+
assert_eq!(id, Some("extra-spaces".to_string()));
|
|
375
|
+
|
|
376
|
+
// Test minimal format variations
|
|
377
|
+
let (text, id) = extract_header_id("# Header {#a}");
|
|
378
|
+
assert_eq!(text, "# Header");
|
|
379
|
+
assert_eq!(id, Some("a".to_string()));
|
|
380
|
+
|
|
381
|
+
let (text, id) = extract_header_id("# Header {:# b}");
|
|
382
|
+
assert_eq!(text, "# Header");
|
|
383
|
+
assert_eq!(id, Some("b".to_string()));
|
|
384
|
+
}
|
|
289
385
|
}
|