rumdl 0.0.53__tar.gz → 0.0.55__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 (253) hide show
  1. {rumdl-0.0.53 → rumdl-0.0.55}/Cargo.lock +1 -1
  2. {rumdl-0.0.53 → rumdl-0.0.55}/Cargo.toml +1 -1
  3. {rumdl-0.0.53 → rumdl-0.0.55}/Makefile +3 -2
  4. {rumdl-0.0.53 → rumdl-0.0.55}/PKG-INFO +1 -1
  5. rumdl-0.0.55/src/rules/md007_ul_indent.rs +185 -0
  6. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md030_list_marker_space.rs +5 -105
  7. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md035_hr_style.rs +28 -39
  8. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/element_cache.rs +85 -50
  9. rumdl-0.0.55/tests/rules/md007_test.rs +127 -0
  10. rumdl-0.0.55/tests/rules/md030_test.rs +48 -0
  11. rumdl-0.0.55/tests/rules/md035_test.rs +153 -0
  12. rumdl-0.0.53/src/rules/md007_ul_indent.rs +0 -276
  13. rumdl-0.0.53/tests/rules/md007_test.rs +0 -69
  14. rumdl-0.0.53/tests/rules/md030_test.rs +0 -221
  15. rumdl-0.0.53/tests/rules/md035_test.rs +0 -61
  16. {rumdl-0.0.53 → rumdl-0.0.55}/.rumdl.toml +0 -0
  17. {rumdl-0.0.53 → rumdl-0.0.55}/MANIFEST.in +0 -0
  18. {rumdl-0.0.53 → rumdl-0.0.55}/README.md +0 -0
  19. {rumdl-0.0.53 → rumdl-0.0.55}/assets/logo.png +0 -0
  20. {rumdl-0.0.53 → rumdl-0.0.55}/benches/range_performance.rs +0 -0
  21. {rumdl-0.0.53 → rumdl-0.0.55}/benches/range_utils_benchmark.rs +0 -0
  22. {rumdl-0.0.53 → rumdl-0.0.55}/benches/rule_performance.rs +0 -0
  23. {rumdl-0.0.53 → rumdl-0.0.55}/docs/RULES.md +0 -0
  24. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md001.md +0 -0
  25. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md002.md +0 -0
  26. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md003.md +0 -0
  27. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md004.md +0 -0
  28. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md005.md +0 -0
  29. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md006.md +0 -0
  30. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md007.md +0 -0
  31. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md008.md +0 -0
  32. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md009.md +0 -0
  33. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md010.md +0 -0
  34. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md011.md +0 -0
  35. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md012.md +0 -0
  36. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md013.md +0 -0
  37. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md014.md +0 -0
  38. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md015.md +0 -0
  39. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md018.md +0 -0
  40. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md019.md +0 -0
  41. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md020.md +0 -0
  42. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md021.md +0 -0
  43. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md022.md +0 -0
  44. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md023.md +0 -0
  45. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md024.md +0 -0
  46. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md025.md +0 -0
  47. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md026.md +0 -0
  48. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md027.md +0 -0
  49. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md028.md +0 -0
  50. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md029.md +0 -0
  51. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md030.md +0 -0
  52. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md031.md +0 -0
  53. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md032.md +0 -0
  54. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md033.md +0 -0
  55. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md034.md +0 -0
  56. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md035.md +0 -0
  57. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md036.md +0 -0
  58. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md037.md +0 -0
  59. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md038.md +0 -0
  60. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md039.md +0 -0
  61. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md040.md +0 -0
  62. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md041.md +0 -0
  63. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md042.md +0 -0
  64. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md043.md +0 -0
  65. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md044.md +0 -0
  66. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md045.md +0 -0
  67. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md046.md +0 -0
  68. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md047.md +0 -0
  69. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md048.md +0 -0
  70. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md049.md +0 -0
  71. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md050.md +0 -0
  72. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md051.md +0 -0
  73. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md052.md +0 -0
  74. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md053.md +0 -0
  75. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md054.md +0 -0
  76. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md055.md +0 -0
  77. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md056.md +0 -0
  78. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md057.md +0 -0
  79. {rumdl-0.0.53 → rumdl-0.0.55}/docs/md058.md +0 -0
  80. {rumdl-0.0.53 → rumdl-0.0.55}/issues/plan-rule-parity-with-markdownlint.md +0 -0
  81. {rumdl-0.0.53 → rumdl-0.0.55}/pyproject.toml +0 -0
  82. {rumdl-0.0.53 → rumdl-0.0.55}/python/MANIFEST.in +0 -0
  83. {rumdl-0.0.53 → rumdl-0.0.55}/python/PYTHON-README.md +0 -0
  84. {rumdl-0.0.53 → rumdl-0.0.55}/python/rumdl/__init__.py +0 -0
  85. {rumdl-0.0.53 → rumdl-0.0.55}/python/rumdl/__main__.py +0 -0
  86. {rumdl-0.0.53 → rumdl-0.0.55}/python/rumdl/py.typed +0 -0
  87. {rumdl-0.0.53 → rumdl-0.0.55}/rumdl.toml.example +0 -0
  88. {rumdl-0.0.53 → rumdl-0.0.55}/src/config.rs +0 -0
  89. {rumdl-0.0.53 → rumdl-0.0.55}/src/init.rs +0 -0
  90. {rumdl-0.0.53 → rumdl-0.0.55}/src/lib.rs +0 -0
  91. {rumdl-0.0.53 → rumdl-0.0.55}/src/lint_context.rs +0 -0
  92. {rumdl-0.0.53 → rumdl-0.0.55}/src/main.rs +0 -0
  93. {rumdl-0.0.53 → rumdl-0.0.55}/src/markdownlint_config.rs +0 -0
  94. {rumdl-0.0.53 → rumdl-0.0.55}/src/profiling.rs +0 -0
  95. {rumdl-0.0.53 → rumdl-0.0.55}/src/python.rs +0 -0
  96. {rumdl-0.0.53 → rumdl-0.0.55}/src/rule.rs +0 -0
  97. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/blockquote_utils.rs +0 -0
  98. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/code_block_utils.rs +0 -0
  99. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/code_fence_utils.rs +0 -0
  100. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/emphasis_style.rs +0 -0
  101. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/front_matter_utils.rs +0 -0
  102. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/heading_utils.rs +0 -0
  103. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/list_utils.rs +0 -0
  104. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md001_heading_increment.rs +0 -0
  105. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md002_first_heading_h1.rs +0 -0
  106. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md003_heading_style.rs +0 -0
  107. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md004_unordered_list_style.rs +0 -0
  108. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md005_list_indent.rs +0 -0
  109. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md006_start_bullets.rs +0 -0
  110. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md008_ul_style.rs +0 -0
  111. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md009_trailing_spaces.rs +0 -0
  112. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md010_no_hard_tabs.rs +0 -0
  113. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md011_no_reversed_links.rs +0 -0
  114. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md012_no_multiple_blanks.rs +0 -0
  115. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md013_line_length.rs +0 -0
  116. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md014_commands_show_output.rs +0 -0
  117. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md015_no_missing_space_after_list_marker.rs +0 -0
  118. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md018_no_missing_space_atx.rs +0 -0
  119. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md019_no_multiple_space_atx.rs +0 -0
  120. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
  121. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
  122. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md022_blanks_around_headings.rs +0 -0
  123. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md023_heading_start_left.rs +0 -0
  124. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md024_no_duplicate_heading.rs +0 -0
  125. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md025_single_title.rs +0 -0
  126. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md026_no_trailing_punctuation.rs +0 -0
  127. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
  128. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md028_no_blanks_blockquote.rs +0 -0
  129. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md029_ordered_list_prefix.rs +0 -0
  130. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md031_blanks_around_fences.rs +0 -0
  131. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md032_blanks_around_lists.rs +0 -0
  132. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md033_no_inline_html.rs +0 -0
  133. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md034_no_bare_urls.rs +0 -0
  134. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md036_no_emphasis_only_first.rs +0 -0
  135. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md037_spaces_around_emphasis.rs +0 -0
  136. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md038_no_space_in_code.rs +0 -0
  137. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md039_no_space_in_links.rs +0 -0
  138. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md040_fenced_code_language.rs +0 -0
  139. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md041_first_line_heading.rs +0 -0
  140. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md042_no_empty_links.rs +0 -0
  141. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md043_required_headings.rs +0 -0
  142. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md044_proper_names.rs +0 -0
  143. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md045_no_alt_text.rs +0 -0
  144. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md046_code_block_style.rs +0 -0
  145. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md047_single_trailing_newline.rs +0 -0
  146. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md048_code_fence_style.rs +0 -0
  147. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md049_emphasis_style.rs +0 -0
  148. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md050_strong_style.rs +0 -0
  149. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md051_link_fragments.rs +0 -0
  150. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md052_reference_links_images.rs +0 -0
  151. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md053_link_image_reference_definitions.rs +0 -0
  152. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md054_link_image_style.rs +0 -0
  153. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md055_table_pipe_style.rs +0 -0
  154. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md056_table_column_count.rs +0 -0
  155. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md057_existing_relative_links.rs +0 -0
  156. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/md058_blanks_around_tables.rs +0 -0
  157. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/mod.rs +0 -0
  158. {rumdl-0.0.53 → rumdl-0.0.55}/src/rules/strong_style.rs +0 -0
  159. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/code_block_utils.rs +0 -0
  160. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/document_structure.rs +0 -0
  161. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/early_returns.rs +0 -0
  162. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/markdown_elements.rs +0 -0
  163. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/mod.rs +0 -0
  164. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/range_utils.rs +0 -0
  165. {rumdl-0.0.53 → rumdl-0.0.55}/src/utils/regex_cache.rs +0 -0
  166. {rumdl-0.0.53 → rumdl-0.0.55}/tests/advanced_integration_tests.rs +0 -0
  167. {rumdl-0.0.53 → rumdl-0.0.55}/tests/cli_duplication_test.rs +0 -0
  168. {rumdl-0.0.53 → rumdl-0.0.55}/tests/cli_integration_tests.rs +0 -0
  169. {rumdl-0.0.53 → rumdl-0.0.55}/tests/commonmark_compliance_tests.rs +0 -0
  170. {rumdl-0.0.53 → rumdl-0.0.55}/tests/comprehensive_integration_tests.rs +0 -0
  171. {rumdl-0.0.53 → rumdl-0.0.55}/tests/config_application_tests.rs +0 -0
  172. {rumdl-0.0.53 → rumdl-0.0.55}/tests/config_tests.rs +0 -0
  173. {rumdl-0.0.53 → rumdl-0.0.55}/tests/init_command_test.rs +0 -0
  174. {rumdl-0.0.53 → rumdl-0.0.55}/tests/init_tests.rs +0 -0
  175. {rumdl-0.0.53 → rumdl-0.0.55}/tests/integration_tests.rs +0 -0
  176. {rumdl-0.0.53 → rumdl-0.0.55}/tests/lib.rs +0 -0
  177. {rumdl-0.0.53 → rumdl-0.0.55}/tests/markdownlint_cli_integration.rs +0 -0
  178. {rumdl-0.0.53 → rumdl-0.0.55}/tests/markdownlint_config_test.rs +0 -0
  179. {rumdl-0.0.53 → rumdl-0.0.55}/tests/md030_edge_cases.md +0 -0
  180. {rumdl-0.0.53 → rumdl-0.0.55}/tests/output_format_tests.rs +0 -0
  181. {rumdl-0.0.53 → rumdl-0.0.55}/tests/perf_check.rs +0 -0
  182. {rumdl-0.0.53 → rumdl-0.0.55}/tests/pyproject_config_tests.rs +0 -0
  183. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md001_test.rs +0 -0
  184. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md001_unicode_test.rs +0 -0
  185. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md002_test.rs +0 -0
  186. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md003_test.rs +0 -0
  187. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md004_test.rs +0 -0
  188. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md005_test.rs +0 -0
  189. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md006_test.rs +0 -0
  190. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md006_unicode_test.rs +0 -0
  191. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md008_test.rs +0 -0
  192. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md009_test.rs +0 -0
  193. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md010_test.rs +0 -0
  194. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md011_test.rs +0 -0
  195. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md012_test.rs +0 -0
  196. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md013_test.rs +0 -0
  197. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md014_test.rs +0 -0
  198. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md015_proptest.rs +0 -0
  199. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md015_test.rs +0 -0
  200. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md018_test.rs +0 -0
  201. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md019_test.rs +0 -0
  202. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md020_test.rs +0 -0
  203. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md021_test.rs +0 -0
  204. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md022_test.rs +0 -0
  205. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md023_extended_test.rs +0 -0
  206. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md023_test.rs +0 -0
  207. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md024_test.rs +0 -0
  208. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md025_test.rs +0 -0
  209. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md026_test.rs +0 -0
  210. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md027_test.rs +0 -0
  211. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md028_test.rs +0 -0
  212. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md029_test.rs +0 -0
  213. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md031_test.rs +0 -0
  214. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md032_test.rs +0 -0
  215. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md033_extended_test.rs +0 -0
  216. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md033_test.rs +0 -0
  217. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md034_test.rs +0 -0
  218. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md036_test.rs +0 -0
  219. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md037_test.rs +0 -0
  220. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md038_test.rs +0 -0
  221. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md039_test.rs +0 -0
  222. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md040_test.rs +0 -0
  223. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md041_test.rs +0 -0
  224. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md042_test.rs +0 -0
  225. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md043_test.rs +0 -0
  226. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md044_test.rs +0 -0
  227. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md045_test.rs +0 -0
  228. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md046_test.rs +0 -0
  229. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md047_test.rs +0 -0
  230. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md048_test.rs +0 -0
  231. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md049_test.rs +0 -0
  232. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md050_test.rs +0 -0
  233. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md051_test.rs +0 -0
  234. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md052_test.rs +0 -0
  235. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md053_additional_test.rs +0 -0
  236. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md053_proptest.rs +0 -0
  237. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md053_test.rs +0 -0
  238. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md054_test.rs +0 -0
  239. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md054_unicode_test.rs +0 -0
  240. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md055_test.rs +0 -0
  241. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md056_test.rs +0 -0
  242. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md057_test.rs +0 -0
  243. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/md058_test.rs +0 -0
  244. {rumdl-0.0.53 → rumdl-0.0.55}/tests/rules/mod.rs +0 -0
  245. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/blockquote_utils_test.rs +0 -0
  246. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/code_block_utils_extended_test.rs +0 -0
  247. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/code_block_utils_test.rs +0 -0
  248. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/core_utils_test.rs +0 -0
  249. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/front_matter_utils_test.rs +0 -0
  250. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/line_index_test.rs +0 -0
  251. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils/mod.rs +0 -0
  252. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils_markdown_edge_cases.rs +0 -0
  253. {rumdl-0.0.53 → rumdl-0.0.55}/tests/utils_tests.rs +0 -0
@@ -1385,7 +1385,7 @@ dependencies = [
1385
1385
 
1386
1386
  [[package]]
1387
1387
  name = "rumdl"
1388
- version = "0.0.53"
1388
+ version = "0.0.55"
1389
1389
  dependencies = [
1390
1390
  "anyhow",
1391
1391
  "assert_cmd",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rumdl"
3
- version = "0.0.53"
3
+ version = "0.0.55"
4
4
  edition = "2021"
5
5
  description = "A fast Markdown linter written in Rust (Ru(st) MarkDown Linter)"
6
6
  authors = ["Ruben J. Jongejan <ruben.jongejan@gmail.com>"]
@@ -12,6 +12,7 @@ clean:
12
12
  fmt:
13
13
  cargo fmt
14
14
  cargo clippy --fix --allow-dirty --allow-staged
15
+ cargo fix --allow-dirty --allow-staged
15
16
 
16
17
  lint:
17
18
  cargo clippy --all-targets --all-features -- -D warnings
@@ -117,14 +118,14 @@ version-push:
117
118
  # Combined targets for one-step release
118
119
  release-major: version-major version-push
119
120
  release-minor: version-minor version-push
120
- release-patch: version-patch version-push
121
+ release-patch: version-patch version-push
121
122
 
122
123
  maturin-build:
123
124
  uv run --with pip,maturin[zig],cffi maturin build --release
124
125
 
125
126
  maturin-sdist:
126
127
  uv run --with pip,maturin[zig],cffi maturin sdist
127
-
128
+
128
129
  run:
129
130
  cargo run --release --bin rumdl check .
130
131
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rumdl
3
- Version: 0.0.53
3
+ Version: 0.0.55
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -0,0 +1,185 @@
1
+ /// Rule MD007: Unordered list indentation
2
+ ///
3
+ /// See [docs/md007.md](../../docs/md007.md) for full documentation, configuration, and examples.
4
+ use crate::rule::{LintError, LintResult, LintWarning, Rule, RuleCategory, Severity};
5
+ use crate::utils::document_structure::{DocumentStructure, DocumentStructureExtensions};
6
+ use crate::utils::element_cache::{ElementCache, ListMarkerType};
7
+ use lazy_static::lazy_static;
8
+ use regex::Regex;
9
+ use toml;
10
+
11
+ #[derive(Debug, Clone)]
12
+ pub struct MD007ULIndent {
13
+ pub indent: usize,
14
+ }
15
+
16
+ impl Default for MD007ULIndent {
17
+ fn default() -> Self {
18
+ Self { indent: 2 }
19
+ }
20
+ }
21
+
22
+ impl MD007ULIndent {
23
+ pub fn new(indent: usize) -> Self {
24
+ Self { indent }
25
+ }
26
+
27
+ #[allow(dead_code)]
28
+ fn is_in_code_block(content: &str, line_idx: usize) -> bool {
29
+ lazy_static! {
30
+ static ref CODE_BLOCK_MARKER: Regex = Regex::new(r"^(```|~~~)").unwrap();
31
+ }
32
+
33
+ let lines: Vec<&str> = content.lines().collect();
34
+ let mut in_code_block = false;
35
+
36
+ for (i, line) in lines.iter().enumerate() {
37
+ if i > line_idx {
38
+ break;
39
+ }
40
+
41
+ if CODE_BLOCK_MARKER.is_match(line.trim_start()) {
42
+ in_code_block = !in_code_block;
43
+ }
44
+
45
+ if i == line_idx {
46
+ return in_code_block;
47
+ }
48
+ }
49
+
50
+ false
51
+ }
52
+ }
53
+
54
+ impl Rule for MD007ULIndent {
55
+ fn name(&self) -> &'static str {
56
+ "MD007"
57
+ }
58
+
59
+ fn description(&self) -> &'static str {
60
+ "Unordered list indentation"
61
+ }
62
+
63
+ fn check(&self, ctx: &crate::lint_context::LintContext) -> LintResult {
64
+ let content = ctx.content;
65
+ let element_cache = ElementCache::new(content);
66
+ let mut warnings = Vec::new();
67
+ for item in element_cache.get_list_items() {
68
+ // Only unordered list items
69
+ // Skip list items inside code blocks (including YAML/front matter)
70
+ if element_cache.is_in_code_block(item.line_number) {
71
+ continue;
72
+ }
73
+ if matches!(item.marker_type, ListMarkerType::Asterisk | ListMarkerType::Plus | ListMarkerType::Minus) {
74
+ let expected_indent = item.nesting_level * self.indent;
75
+ if item.indentation != expected_indent {
76
+ warnings.push(LintWarning {
77
+ rule_name: Some(self.name()),
78
+ message: format!(
79
+ "Incorrect indentation: expected {} spaces for nesting level {}, found {}",
80
+ expected_indent, item.nesting_level, item.indentation
81
+ ),
82
+ line: item.line_number,
83
+ column: item.blockquote_prefix.len() + item.indentation + 1, // correct column for marker
84
+ severity: Severity::Warning,
85
+ fix: None,
86
+ });
87
+ }
88
+ }
89
+ }
90
+ Ok(warnings)
91
+ }
92
+
93
+ /// Optimized check using document structure
94
+ fn check_with_structure(
95
+ &self,
96
+ ctx: &crate::lint_context::LintContext,
97
+ _doc_structure: &DocumentStructure,
98
+ ) -> LintResult {
99
+ self.check(ctx)
100
+ }
101
+
102
+ fn fix(&self, ctx: &crate::lint_context::LintContext) -> Result<String, LintError> {
103
+ let content = ctx.content;
104
+ let element_cache = ElementCache::new(content);
105
+ let mut lines: Vec<&str> = content.lines().collect();
106
+ for item in element_cache.get_list_items() {
107
+ if element_cache.is_in_code_block(item.line_number) {
108
+ continue;
109
+ }
110
+ if matches!(item.marker_type, ListMarkerType::Asterisk | ListMarkerType::Plus | ListMarkerType::Minus) {
111
+ let expected_indent = item.nesting_level * self.indent;
112
+ if item.indentation != expected_indent {
113
+ // Reconstruct the line: blockquote_prefix + correct_indent + marker + spaces_after_marker + content
114
+ let correct_indent = " ".repeat(expected_indent);
115
+ let marker = &item.marker;
116
+ let after_marker = " ".repeat(item.spaces_after_marker.max(1));
117
+ let new_line = format!(
118
+ "{}{}{}{}{}",
119
+ item.blockquote_prefix,
120
+ correct_indent,
121
+ marker,
122
+ after_marker,
123
+ item.content
124
+ );
125
+ lines[item.line_number - 1] = Box::leak(new_line.into_boxed_str());
126
+ }
127
+ }
128
+ }
129
+ Ok(lines.join("\n"))
130
+ }
131
+
132
+ /// Get the category of this rule for selective processing
133
+ fn category(&self) -> RuleCategory {
134
+ RuleCategory::List
135
+ }
136
+
137
+ /// Check if this rule should be skipped
138
+ fn should_skip(&self, ctx: &crate::lint_context::LintContext) -> bool {
139
+ ctx.content.is_empty()
140
+ || (!ctx.content.contains('*')
141
+ && !ctx.content.contains('-')
142
+ && !ctx.content.contains('+'))
143
+ }
144
+
145
+ fn as_any(&self) -> &dyn std::any::Any {
146
+ self
147
+ }
148
+
149
+ fn default_config_section(&self) -> Option<(String, toml::Value)> {
150
+ let mut map = toml::map::Map::new();
151
+ map.insert(
152
+ "indent".to_string(),
153
+ toml::Value::Integer(self.indent as i64),
154
+ );
155
+ Some((self.name().to_string(), toml::Value::Table(map)))
156
+ }
157
+
158
+ fn from_config(config: &crate::config::Config) -> Box<dyn Rule>
159
+ where
160
+ Self: Sized,
161
+ {
162
+ let indent =
163
+ crate::config::get_rule_config_value::<usize>(config, "MD007", "indent").unwrap_or(2);
164
+ Box::new(MD007ULIndent::new(indent))
165
+ }
166
+ }
167
+
168
+ impl DocumentStructureExtensions for MD007ULIndent {
169
+ fn has_relevant_elements(
170
+ &self,
171
+ _ctx: &crate::lint_context::LintContext,
172
+ doc_structure: &DocumentStructure,
173
+ ) -> bool {
174
+ // Use the document structure to check if there are any unordered list elements
175
+ !doc_structure.list_lines.is_empty()
176
+ }
177
+ }
178
+
179
+ #[cfg(test)]
180
+ mod tests {
181
+ use super::*;
182
+ use crate::lint_context::LintContext;
183
+
184
+ // Remove test_with_document_structure, as the rule no longer uses DocumentStructure for its logic
185
+ }
@@ -7,7 +7,7 @@ use crate::rules::list_utils::ListType;
7
7
  use crate::utils::range_utils::LineIndex;
8
8
 
9
9
  use crate::lint_context::LintContext;
10
- use crate::rule::{Fix, LintError, LintResult, LintWarning, Rule, RuleCategory, Severity};
10
+ use crate::rule::{Fix, LintResult, LintWarning, Rule, RuleCategory, Severity};
11
11
  use crate::utils::document_structure::{DocumentStructure, DocumentStructureExtensions};
12
12
  use fancy_regex::Regex;
13
13
  use lazy_static::lazy_static;
@@ -73,68 +73,6 @@ impl MD030ListMarkerSpace {
73
73
  line.to_string()
74
74
  }
75
75
  }
76
-
77
- fn precompute_states(&self, lines: &[&str]) -> (Vec<bool>, Vec<bool>) {
78
- let mut is_list_line = vec![false; lines.len()];
79
- let mut multi_line = vec![false; lines.len()];
80
- let mut in_code_block = false;
81
-
82
- // First pass: mark code blocks and list items
83
- for (i, &line) in lines.iter().enumerate() {
84
- if CODE_BLOCK_REGEX.is_match(line).unwrap_or(false) {
85
- in_code_block = !in_code_block;
86
- continue;
87
- }
88
- if !in_code_block {
89
- // Check both patterns
90
- if let Ok(Some(_)) = LIST_REGEX.captures(line) {
91
- is_list_line[i] = true;
92
- } else if let Ok(Some(_)) = LIST_NO_SPACE_REGEX.captures(line) {
93
- is_list_line[i] = true;
94
- }
95
- }
96
- }
97
-
98
- // Second pass: compute multi-line states
99
- for i in 0..lines.len() {
100
- if is_list_line[i] {
101
- let mut found_continuation = false;
102
- let curr_indent = lines[i].chars().take_while(|c| c.is_whitespace()).count();
103
- let j = i + 1;
104
- while j < lines.len() {
105
- let next_line = lines[j];
106
- if next_line.trim().is_empty() {
107
- found_continuation = true; // blank line always makes multi-line
108
- break;
109
- }
110
- let next_indent = next_line.chars().take_while(|c| c.is_whitespace()).count();
111
- let is_next_list = LIST_REGEX.captures(next_line).is_ok()
112
- && LIST_REGEX.captures(next_line).as_ref().unwrap().is_some()
113
- || LIST_NO_SPACE_REGEX.captures(next_line).is_ok()
114
- && LIST_NO_SPACE_REGEX
115
- .captures(next_line)
116
- .as_ref()
117
- .unwrap()
118
- .is_some();
119
- if is_next_list {
120
- if next_indent > curr_indent {
121
- found_continuation = true; // parent of nested list is multi-line
122
- }
123
- break;
124
- }
125
- if next_indent > curr_indent {
126
- found_continuation = true; // paragraph continuation
127
- break;
128
- } else {
129
- break;
130
- }
131
- }
132
- multi_line[i] = found_continuation;
133
- }
134
- }
135
-
136
- (is_list_line, multi_line)
137
- }
138
76
  }
139
77
 
140
78
  impl Rule for MD030ListMarkerSpace {
@@ -387,48 +325,6 @@ impl Rule for MD030ListMarkerSpace {
387
325
  Ok(warnings)
388
326
  }
389
327
 
390
- fn fix(&self, ctx: &LintContext) -> Result<String, LintError> {
391
- let content = ctx.content;
392
- let mut fixed_lines = Vec::new();
393
- let lines: Vec<&str> = content.lines().collect();
394
- let (is_list_line, multi_line) = self.precompute_states(&lines);
395
- for (i, &line) in lines.iter().enumerate() {
396
- if !is_list_line[i] {
397
- fixed_lines.push(line.to_string());
398
- continue;
399
- }
400
- // Use LIST_FIX_REGEX to capture marker, spaces, and rest of line
401
- if let Ok(Some(caps)) = LIST_FIX_REGEX.captures(line) {
402
- let indent = caps.get(1).map_or("", |m| m.as_str());
403
- let marker = caps.get(2).map_or("", |m| m.as_str());
404
- let spaces = caps.get(3).map_or("", |m| m.as_str());
405
- let after = &line[(indent.len() + marker.len() + spaces.len())..];
406
- let actual_spaces = spaces.len();
407
- let required_spaces = if multi_line[i] {
408
- self.ul_multi
409
- } else {
410
- self.ul_single
411
- };
412
- if actual_spaces < required_spaces {
413
- let fixed_line = format!(
414
- "{}{}{}{}",
415
- indent,
416
- marker,
417
- " ".repeat(required_spaces),
418
- after
419
- );
420
- fixed_lines.push(fixed_line);
421
- } else {
422
- fixed_lines.push(line.to_string());
423
- }
424
- continue;
425
- } else {
426
- fixed_lines.push(line.to_string());
427
- }
428
- }
429
- Ok(fixed_lines.join("\n"))
430
- }
431
-
432
328
  /// Get the category of this rule for selective processing
433
329
  fn category(&self) -> RuleCategory {
434
330
  RuleCategory::List
@@ -487,6 +383,10 @@ impl Rule for MD030ListMarkerSpace {
487
383
  ul_single, ul_multi, ol_single, ol_multi,
488
384
  ))
489
385
  }
386
+
387
+ fn fix(&self, _ctx: &crate::lint_context::LintContext) -> Result<String, crate::rule::LintError> {
388
+ Err(crate::rule::LintError::FixFailed("Automatic fixing is not supported for MD030. See todos/md030_fix_strategy.md for details.".to_string()))
389
+ }
490
390
  }
491
391
 
492
392
  impl DocumentStructureExtensions for MD030ListMarkerSpace {
@@ -57,23 +57,35 @@ impl MD035HRStyle {
57
57
  }
58
58
 
59
59
  let line = lines[i].trim();
60
-
61
60
  let prev_line = lines[i - 1].trim();
62
61
 
63
- // Check if the current line is all dashes or equals signs
64
-
65
62
  let is_dash_line = !line.is_empty() && line.chars().all(|c| c == '-');
66
-
67
63
  let is_equals_line = !line.is_empty() && line.chars().all(|c| c == '=');
68
-
69
- // Check if the previous line is not empty and not a horizontal rule
70
-
71
64
  let prev_line_has_content = !prev_line.is_empty() && !Self::is_horizontal_rule(prev_line);
72
-
73
- // If the current line is all dashes or equals signs and the previous line has content,
74
- // it's likely a Setext heading
75
65
  (is_dash_line || is_equals_line) && prev_line_has_content
76
66
  }
67
+
68
+ /// Find the most prevalent HR style in the document (excluding setext headings)
69
+ fn most_prevalent_hr_style(lines: &[&str]) -> Option<String> {
70
+ use std::collections::HashMap;
71
+ let mut counts: HashMap<&str, usize> = HashMap::new();
72
+ let mut order: Vec<&str> = Vec::new();
73
+ for (i, line) in lines.iter().enumerate() {
74
+ if Self::is_horizontal_rule(line) && !Self::is_potential_setext_heading(lines, i) {
75
+ let style = line.trim();
76
+ let counter = counts.entry(style).or_insert(0);
77
+ *counter += 1;
78
+ if *counter == 1 {
79
+ order.push(style);
80
+ }
81
+ }
82
+ }
83
+ // Find the style with the highest count, breaking ties by first encountered
84
+ counts
85
+ .iter()
86
+ .max_by_key(|&(style, count)| (*count, -(order.iter().position(|&s| s == *style).unwrap_or(usize::MAX) as isize)))
87
+ .map(|(style, _)| style.to_string())
88
+ }
77
89
  }
78
90
 
79
91
  impl Rule for MD035HRStyle {
@@ -90,21 +102,11 @@ impl Rule for MD035HRStyle {
90
102
  let _line_index = LineIndex::new(content.to_string());
91
103
 
92
104
  let mut warnings = Vec::new();
93
-
94
105
  let lines: Vec<&str> = content.lines().collect();
95
106
 
96
- // Use the configured style or find the first HR style
97
-
98
- let expected_style = if self.style.is_empty() {
99
- // Find the first HR in the document
100
- let mut first_style = "---".to_string(); // Default if none found
101
- for (i, line) in lines.iter().enumerate() {
102
- if Self::is_horizontal_rule(line) && !Self::is_potential_setext_heading(&lines, i) {
103
- first_style = line.trim().to_string();
104
- break;
105
- }
106
- }
107
- first_style
107
+ // Use the configured style or find the most prevalent HR style
108
+ let expected_style = if self.style.is_empty() || self.style == "consistent" {
109
+ Self::most_prevalent_hr_style(&lines).unwrap_or_else(|| "---".to_string())
108
110
  } else {
109
111
  self.style.clone()
110
112
  };
@@ -148,21 +150,11 @@ impl Rule for MD035HRStyle {
148
150
  let _line_index = LineIndex::new(content.to_string());
149
151
 
150
152
  let mut result = Vec::new();
151
-
152
153
  let lines: Vec<&str> = content.lines().collect();
153
154
 
154
- // Use the configured style or find the first HR style
155
-
156
- let expected_style = if self.style.is_empty() {
157
- // Find the first HR in the document
158
- let mut first_style = "---".to_string(); // Default if none found
159
- for (i, line) in lines.iter().enumerate() {
160
- if Self::is_horizontal_rule(line) && !Self::is_potential_setext_heading(&lines, i) {
161
- first_style = line.trim().to_string();
162
- break;
163
- }
164
- }
165
- first_style
155
+ // Use the configured style or find the most prevalent HR style
156
+ let expected_style = if self.style.is_empty() || self.style == "consistent" {
157
+ Self::most_prevalent_hr_style(&lines).unwrap_or_else(|| "---".to_string())
166
158
  } else {
167
159
  self.style.clone()
168
160
  };
@@ -174,9 +166,6 @@ impl Rule for MD035HRStyle {
174
166
  continue;
175
167
  }
176
168
 
177
- let _trimmed = line.trim();
178
-
179
- // Simplify the horizontal rule detection and replacement
180
169
  if Self::is_horizontal_rule(line) {
181
170
  // Here we have a proper horizontal rule - replace it with the expected style
182
171
  result.push(expected_style.clone());