rumdl 0.0.84__tar.gz → 0.0.85__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of rumdl might be problematic. Click here for more details.

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