rumdl 0.0.114__tar.gz → 0.0.116__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 (384) hide show
  1. {rumdl-0.0.114 → rumdl-0.0.116}/.config/nextest.toml +24 -0
  2. {rumdl-0.0.114 → rumdl-0.0.116}/CHANGELOG.md +19 -1
  3. {rumdl-0.0.114 → rumdl-0.0.116}/Cargo.lock +17 -17
  4. {rumdl-0.0.114 → rumdl-0.0.116}/Cargo.toml +1 -1
  5. {rumdl-0.0.114 → rumdl-0.0.116}/Makefile +5 -0
  6. {rumdl-0.0.114 → rumdl-0.0.116}/PKG-INFO +1 -1
  7. {rumdl-0.0.114 → rumdl-0.0.116}/scripts/pre-release.sh +29 -6
  8. {rumdl-0.0.114 → rumdl-0.0.116}/src/config.rs +112 -0
  9. {rumdl-0.0.114 → rumdl-0.0.116}/src/lint_context.rs +57 -11
  10. {rumdl-0.0.114 → rumdl-0.0.116}/src/main.rs +26 -1
  11. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md020_no_missing_space_closed_atx.rs +15 -10
  12. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md026_no_trailing_punctuation/md026_config.rs +6 -1
  13. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md026_no_trailing_punctuation.rs +32 -148
  14. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md034_no_bare_urls.rs +9 -10
  15. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md051_link_fragments.rs +192 -1
  16. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/kramdown_utils.rs +38 -1
  17. {rumdl-0.0.114 → rumdl-0.0.116}/tests/comprehensive_output_format_tests.rs +9 -7
  18. rumdl-0.0.116/tests/fixable_unfixable_config_test.rs +227 -0
  19. rumdl-0.0.116/tests/rules/md020_test.rs +267 -0
  20. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md026_kramdown_test.rs +45 -17
  21. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md026_test.rs +42 -95
  22. rumdl-0.0.116/tests/rules/md029_issue42_test.rs +320 -0
  23. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md034_test.rs +41 -0
  24. rumdl-0.0.114/tests/rules/md020_test.rs +0 -130
  25. {rumdl-0.0.114 → rumdl-0.0.116}/.mise.toml +0 -0
  26. {rumdl-0.0.114 → rumdl-0.0.116}/.pre-commit-config.yaml +0 -0
  27. {rumdl-0.0.114 → rumdl-0.0.116}/.rumdl.toml +0 -0
  28. {rumdl-0.0.114 → rumdl-0.0.116}/.rustfmt.toml +0 -0
  29. {rumdl-0.0.114 → rumdl-0.0.116}/LICENSE +0 -0
  30. {rumdl-0.0.114 → rumdl-0.0.116}/MANIFEST.in +0 -0
  31. {rumdl-0.0.114 → rumdl-0.0.116}/README.md +0 -0
  32. {rumdl-0.0.114 → rumdl-0.0.116}/assets/logo.png +0 -0
  33. {rumdl-0.0.114 → rumdl-0.0.116}/benches/fix_performance.rs +0 -0
  34. {rumdl-0.0.114 → rumdl-0.0.116}/benches/range_performance.rs +0 -0
  35. {rumdl-0.0.114 → rumdl-0.0.116}/benches/range_utils_benchmark.rs +0 -0
  36. {rumdl-0.0.114 → rumdl-0.0.116}/benches/rule_performance.rs +0 -0
  37. {rumdl-0.0.114 → rumdl-0.0.116}/benches/simple_fix_bench.rs +0 -0
  38. {rumdl-0.0.114 → rumdl-0.0.116}/benchmark/bin/bench_lint_context.rs +0 -0
  39. {rumdl-0.0.114 → rumdl-0.0.116}/benchmark/bin/benchmark.rs +0 -0
  40. {rumdl-0.0.114 → rumdl-0.0.116}/benchmark/bin/benchmark_rule.rs +0 -0
  41. {rumdl-0.0.114 → rumdl-0.0.116}/benchmark/bin/file_parallel_benchmark.rs +0 -0
  42. {rumdl-0.0.114 → rumdl-0.0.116}/benchmark/bin/measure_code_span_performance.rs +0 -0
  43. {rumdl-0.0.114 → rumdl-0.0.116}/docs/RULES.md +0 -0
  44. {rumdl-0.0.114 → rumdl-0.0.116}/docs/global-settings.md +0 -0
  45. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md001.md +0 -0
  46. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md002.md +0 -0
  47. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md003.md +0 -0
  48. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md004.md +0 -0
  49. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md005.md +0 -0
  50. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md006.md +0 -0
  51. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md007.md +0 -0
  52. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md009.md +0 -0
  53. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md010.md +0 -0
  54. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md011.md +0 -0
  55. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md012.md +0 -0
  56. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md013.md +0 -0
  57. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md014.md +0 -0
  58. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md018.md +0 -0
  59. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md019.md +0 -0
  60. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md020.md +0 -0
  61. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md021.md +0 -0
  62. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md022.md +0 -0
  63. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md023.md +0 -0
  64. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md024.md +0 -0
  65. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md025.md +0 -0
  66. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md026.md +0 -0
  67. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md027.md +0 -0
  68. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md028.md +0 -0
  69. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md029.md +0 -0
  70. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md030.md +0 -0
  71. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md031.md +0 -0
  72. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md032.md +0 -0
  73. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md033.md +0 -0
  74. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md034.md +0 -0
  75. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md035.md +0 -0
  76. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md036.md +0 -0
  77. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md037.md +0 -0
  78. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md038.md +0 -0
  79. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md039.md +0 -0
  80. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md040.md +0 -0
  81. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md041.md +0 -0
  82. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md042.md +0 -0
  83. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md043.md +0 -0
  84. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md044.md +0 -0
  85. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md045.md +0 -0
  86. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md046.md +0 -0
  87. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md047.md +0 -0
  88. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md048.md +0 -0
  89. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md049.md +0 -0
  90. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md050.md +0 -0
  91. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md051.md +0 -0
  92. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md052.md +0 -0
  93. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md053.md +0 -0
  94. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md054.md +0 -0
  95. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md055.md +0 -0
  96. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md056.md +0 -0
  97. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md057.md +0 -0
  98. {rumdl-0.0.114 → rumdl-0.0.116}/docs/md058.md +0 -0
  99. {rumdl-0.0.114 → rumdl-0.0.116}/docs/vscode-extension.md +0 -0
  100. {rumdl-0.0.114 → rumdl-0.0.116}/parity_check.py +0 -0
  101. {rumdl-0.0.114 → rumdl-0.0.116}/pyproject.toml +0 -0
  102. {rumdl-0.0.114 → rumdl-0.0.116}/python/MANIFEST.in +0 -0
  103. {rumdl-0.0.114 → rumdl-0.0.116}/python/PYTHON-README.md +0 -0
  104. {rumdl-0.0.114 → rumdl-0.0.116}/python/rumdl/__init__.py +0 -0
  105. {rumdl-0.0.114 → rumdl-0.0.116}/python/rumdl/__main__.py +0 -0
  106. {rumdl-0.0.114 → rumdl-0.0.116}/python/rumdl/py.typed +0 -0
  107. {rumdl-0.0.114 → rumdl-0.0.116}/rumdl.toml.example +0 -0
  108. {rumdl-0.0.114 → rumdl-0.0.116}/rust-toolchain.toml +0 -0
  109. {rumdl-0.0.114 → rumdl-0.0.116}/scripts/extract-changelog.sh +0 -0
  110. {rumdl-0.0.114 → rumdl-0.0.116}/scripts/generate-downloads-table.sh +0 -0
  111. {rumdl-0.0.114 → rumdl-0.0.116}/scripts/prepare-release.sh +0 -0
  112. {rumdl-0.0.114 → rumdl-0.0.116}/scripts/setup-pre-commit.sh +0 -0
  113. {rumdl-0.0.114 → rumdl-0.0.116}/scripts/update-pre-commit-docs.sh +0 -0
  114. {rumdl-0.0.114 → rumdl-0.0.116}/src/exit_codes.rs +0 -0
  115. {rumdl-0.0.114 → rumdl-0.0.116}/src/inline_config.rs +0 -0
  116. {rumdl-0.0.114 → rumdl-0.0.116}/src/lib.rs +0 -0
  117. {rumdl-0.0.114 → rumdl-0.0.116}/src/lsp/mod.rs +0 -0
  118. {rumdl-0.0.114 → rumdl-0.0.116}/src/lsp/server.rs +0 -0
  119. {rumdl-0.0.114 → rumdl-0.0.116}/src/lsp/types.rs +0 -0
  120. {rumdl-0.0.114 → rumdl-0.0.116}/src/markdownlint_config.rs +0 -0
  121. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/azure.rs +0 -0
  122. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/concise.rs +0 -0
  123. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/github.rs +0 -0
  124. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/gitlab.rs +0 -0
  125. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/grouped.rs +0 -0
  126. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/json.rs +0 -0
  127. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/json_lines.rs +0 -0
  128. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/junit.rs +0 -0
  129. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/mod.rs +0 -0
  130. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/pylint.rs +0 -0
  131. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/sarif.rs +0 -0
  132. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/formatters/text.rs +0 -0
  133. {rumdl-0.0.114 → rumdl-0.0.116}/src/output/mod.rs +0 -0
  134. {rumdl-0.0.114 → rumdl-0.0.116}/src/parallel.rs +0 -0
  135. {rumdl-0.0.114 → rumdl-0.0.116}/src/performance.rs +0 -0
  136. {rumdl-0.0.114 → rumdl-0.0.116}/src/profiling.rs +0 -0
  137. {rumdl-0.0.114 → rumdl-0.0.116}/src/python.rs +0 -0
  138. {rumdl-0.0.114 → rumdl-0.0.116}/src/rule.rs +0 -0
  139. {rumdl-0.0.114 → rumdl-0.0.116}/src/rule_config.rs +0 -0
  140. {rumdl-0.0.114 → rumdl-0.0.116}/src/rule_config_serde.rs +0 -0
  141. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/blockquote_utils.rs +0 -0
  142. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/code_block_utils.rs +0 -0
  143. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/code_fence_utils.rs +0 -0
  144. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/emphasis_style.rs +0 -0
  145. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/front_matter_utils.rs +0 -0
  146. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/heading_utils.rs +0 -0
  147. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/list_utils.rs +0 -0
  148. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md001_heading_increment.rs +0 -0
  149. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md002_first_heading_h1/md002_config.rs +0 -0
  150. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md002_first_heading_h1.rs +0 -0
  151. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md003_heading_style/md003_config.rs +0 -0
  152. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md003_heading_style.rs +0 -0
  153. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md004_unordered_list_style/md004_config.rs +0 -0
  154. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md004_unordered_list_style.rs +0 -0
  155. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md005_list_indent.rs +0 -0
  156. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md006_start_bullets.rs +0 -0
  157. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md007_ul_indent/md007_config.rs +0 -0
  158. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md007_ul_indent.rs +0 -0
  159. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md009_trailing_spaces/md009_config.rs +0 -0
  160. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md009_trailing_spaces.rs +0 -0
  161. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md010_no_hard_tabs/md010_config.rs +0 -0
  162. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md010_no_hard_tabs.rs +0 -0
  163. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md011_no_reversed_links.rs +0 -0
  164. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md012_no_multiple_blanks/md012_config.rs +0 -0
  165. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md012_no_multiple_blanks.rs +0 -0
  166. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md013_line_length/md013_config.rs +0 -0
  167. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md013_line_length.rs +0 -0
  168. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md014_commands_show_output/md014_config.rs +0 -0
  169. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md014_commands_show_output.rs +0 -0
  170. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md018_no_missing_space_atx.rs +0 -0
  171. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md019_no_multiple_space_atx.rs +0 -0
  172. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
  173. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md022_blanks_around_headings/md022_config.rs +0 -0
  174. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md022_blanks_around_headings.rs +0 -0
  175. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md023_heading_start_left.rs +0 -0
  176. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md024_no_duplicate_heading/md024_config.rs +0 -0
  177. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md024_no_duplicate_heading.rs +0 -0
  178. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md025_single_title/md025_config.rs +0 -0
  179. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md025_single_title.rs +0 -0
  180. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
  181. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md028_no_blanks_blockquote.rs +0 -0
  182. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md029_ordered_list_prefix/md029_config.rs +0 -0
  183. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md029_ordered_list_prefix.rs +0 -0
  184. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md030_list_marker_space/md030_config.rs +0 -0
  185. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md030_list_marker_space.rs +0 -0
  186. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md031_blanks_around_fences.rs +0 -0
  187. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md032_blanks_around_lists.rs +0 -0
  188. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md033_no_inline_html/md033_config.rs +0 -0
  189. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md033_no_inline_html.rs +0 -0
  190. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md035_hr_style/md035_config.rs +0 -0
  191. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md035_hr_style.rs +0 -0
  192. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md036_no_emphasis_only_first/md036_config.rs +0 -0
  193. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md036_no_emphasis_only_first.rs +0 -0
  194. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md037_spaces_around_emphasis.rs +0 -0
  195. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md038_no_space_in_code.rs +0 -0
  196. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md039_no_space_in_links.rs +0 -0
  197. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md040_fenced_code_language.rs +0 -0
  198. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md041_first_line_heading.rs +0 -0
  199. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md042_no_empty_links.rs +0 -0
  200. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md043_required_headings.rs +0 -0
  201. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md044_proper_names/md044_config.rs +0 -0
  202. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md044_proper_names.rs +0 -0
  203. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md045_no_alt_text/md045_config.rs +0 -0
  204. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md045_no_alt_text.rs +0 -0
  205. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md046_code_block_style/md046_config.rs +0 -0
  206. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md046_code_block_style.rs +0 -0
  207. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md047_single_trailing_newline.rs +0 -0
  208. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md048_code_fence_style/md048_config.rs +0 -0
  209. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md048_code_fence_style.rs +0 -0
  210. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md049_emphasis_style/md049_config.rs +0 -0
  211. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md049_emphasis_style.rs +0 -0
  212. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md050_strong_style/md050_config.rs +0 -0
  213. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md050_strong_style.rs +0 -0
  214. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md052_reference_links_images.rs +0 -0
  215. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md053_link_image_reference_definitions.rs +0 -0
  216. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md054_link_image_style/md054_config.rs +0 -0
  217. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md054_link_image_style.rs +0 -0
  218. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md055_table_pipe_style/md055_config.rs +0 -0
  219. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md055_table_pipe_style.rs +0 -0
  220. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md056_table_column_count.rs +0 -0
  221. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md057_existing_relative_links/md057_config.rs +0 -0
  222. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md057_existing_relative_links.rs +0 -0
  223. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/md058_blanks_around_tables.rs +0 -0
  224. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/mod.rs +0 -0
  225. {rumdl-0.0.114 → rumdl-0.0.116}/src/rules/strong_style.rs +0 -0
  226. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/ast_utils.rs +0 -0
  227. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/code_block_utils.rs +0 -0
  228. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/document_structure.rs +0 -0
  229. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/early_returns.rs +0 -0
  230. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/element_cache.rs +0 -0
  231. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/emphasis_utils.rs +0 -0
  232. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/fix_utils.rs +0 -0
  233. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/markdown_elements.rs +0 -0
  234. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/mod.rs +0 -0
  235. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/range_utils.rs +0 -0
  236. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/regex_cache.rs +0 -0
  237. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/string_interner.rs +0 -0
  238. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/table_utils.rs +0 -0
  239. {rumdl-0.0.114 → rumdl-0.0.116}/src/utils/text_reflow.rs +0 -0
  240. {rumdl-0.0.114 → rumdl-0.0.116}/src/vscode.rs +0 -0
  241. {rumdl-0.0.114 → rumdl-0.0.116}/tests/advanced_integration_tests.rs +0 -0
  242. {rumdl-0.0.114 → rumdl-0.0.116}/tests/character_ranges/additional_tests.rs +0 -0
  243. {rumdl-0.0.114 → rumdl-0.0.116}/tests/character_ranges/basic_tests.rs +0 -0
  244. {rumdl-0.0.114 → rumdl-0.0.116}/tests/character_ranges/comprehensive_tests.rs +0 -0
  245. {rumdl-0.0.114 → rumdl-0.0.116}/tests/character_ranges/extended_tests.rs +0 -0
  246. {rumdl-0.0.114 → rumdl-0.0.116}/tests/character_ranges/mod.rs +0 -0
  247. {rumdl-0.0.114 → rumdl-0.0.116}/tests/character_ranges/unicode_utils.rs +0 -0
  248. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cli_duplication_test.rs +0 -0
  249. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cli_explain_test.rs +0 -0
  250. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cli_flag_precedence_test.rs +0 -0
  251. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cli_integration_tests.rs +0 -0
  252. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cli_lsp_fix_consistency.rs +0 -0
  253. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cli_statistics_test.rs +0 -0
  254. {rumdl-0.0.114 → rumdl-0.0.116}/tests/common/cli_test_utils.rs +0 -0
  255. {rumdl-0.0.114 → rumdl-0.0.116}/tests/common/fixtures.rs +0 -0
  256. {rumdl-0.0.114 → rumdl-0.0.116}/tests/common/mod.rs +0 -0
  257. {rumdl-0.0.114 → rumdl-0.0.116}/tests/common/test_utils.rs +0 -0
  258. {rumdl-0.0.114 → rumdl-0.0.116}/tests/commonmark_compliance_tests.rs +0 -0
  259. {rumdl-0.0.114 → rumdl-0.0.116}/tests/comprehensive_integration_tests.rs +0 -0
  260. {rumdl-0.0.114 → rumdl-0.0.116}/tests/config_application_tests.rs +0 -0
  261. {rumdl-0.0.114 → rumdl-0.0.116}/tests/config_file_command_test.rs +0 -0
  262. {rumdl-0.0.114 → rumdl-0.0.116}/tests/config_tests.rs +0 -0
  263. {rumdl-0.0.114 → rumdl-0.0.116}/tests/configuration_inheritance_tests.rs +0 -0
  264. {rumdl-0.0.114 → rumdl-0.0.116}/tests/consistency_regression_tests.rs +0 -0
  265. {rumdl-0.0.114 → rumdl-0.0.116}/tests/cross_platform_compatibility_tests.rs +0 -0
  266. {rumdl-0.0.114 → rumdl-0.0.116}/tests/deeply_nested_lists_performance_test.rs +0 -0
  267. {rumdl-0.0.114 → rumdl-0.0.116}/tests/escaped_brackets_test.rs +0 -0
  268. {rumdl-0.0.114 → rumdl-0.0.116}/tests/final_confidence_assessment.rs +0 -0
  269. {rumdl-0.0.114 → rumdl-0.0.116}/tests/init_command_test.rs +0 -0
  270. {rumdl-0.0.114 → rumdl-0.0.116}/tests/init_tests.rs +0 -0
  271. {rumdl-0.0.114 → rumdl-0.0.116}/tests/inline_config_blocks_test.rs +0 -0
  272. {rumdl-0.0.114 → rumdl-0.0.116}/tests/inline_config_test.rs +0 -0
  273. {rumdl-0.0.114 → rumdl-0.0.116}/tests/integration_tests.rs +0 -0
  274. {rumdl-0.0.114 → rumdl-0.0.116}/tests/json_output_test.rs +0 -0
  275. {rumdl-0.0.114 → rumdl-0.0.116}/tests/kramdown_integration_test.rs +0 -0
  276. {rumdl-0.0.114 → rumdl-0.0.116}/tests/lib.rs +0 -0
  277. {rumdl-0.0.114 → rumdl-0.0.116}/tests/lsp_editor_integration_tests.rs +0 -0
  278. {rumdl-0.0.114 → rumdl-0.0.116}/tests/lsp_integration_tests.rs +0 -0
  279. {rumdl-0.0.114 → rumdl-0.0.116}/tests/lsp_memory_leak_tests.rs +0 -0
  280. {rumdl-0.0.114 → rumdl-0.0.116}/tests/lsp_tests.rs +0 -0
  281. {rumdl-0.0.114 → rumdl-0.0.116}/tests/malformed_markdown_stress_tests.rs +0 -0
  282. {rumdl-0.0.114 → rumdl-0.0.116}/tests/markdownlint_cli_integration.rs +0 -0
  283. {rumdl-0.0.114 → rumdl-0.0.116}/tests/markdownlint_config_test.rs +0 -0
  284. {rumdl-0.0.114 → rumdl-0.0.116}/tests/markdownlintignore_test.rs +0 -0
  285. {rumdl-0.0.114 → rumdl-0.0.116}/tests/md013_reflow_integration_test.rs +0 -0
  286. {rumdl-0.0.114 → rumdl-0.0.116}/tests/nested_code_block_test.rs +0 -0
  287. {rumdl-0.0.114 → rumdl-0.0.116}/tests/output_format_integration_tests.rs +0 -0
  288. {rumdl-0.0.114 → rumdl-0.0.116}/tests/output_format_tests.rs +0 -0
  289. {rumdl-0.0.114 → rumdl-0.0.116}/tests/perf_check.rs +0 -0
  290. {rumdl-0.0.114 → rumdl-0.0.116}/tests/performance_validation_tests.rs +0 -0
  291. {rumdl-0.0.114 → rumdl-0.0.116}/tests/pyproject_config_tests.rs +0 -0
  292. {rumdl-0.0.114 → rumdl-0.0.116}/tests/python_bindings_test.rs +0 -0
  293. {rumdl-0.0.114 → rumdl-0.0.116}/tests/real_world_repository_tests.rs +0 -0
  294. {rumdl-0.0.114 → rumdl-0.0.116}/tests/regression_prevention_tests.rs +0 -0
  295. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/emphasis_edge_cases_test.rs +0 -0
  296. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/heading_edge_cases_test.rs +0 -0
  297. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/inline_content_edge_cases_test.rs +0 -0
  298. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/link_edge_cases_test.rs +0 -0
  299. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/list_rules_integration_test.rs +0 -0
  300. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md001_test.rs +0 -0
  301. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md001_unicode_test.rs +0 -0
  302. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md002_test.rs +0 -0
  303. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md003_test.rs +0 -0
  304. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md004_test.rs +0 -0
  305. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md005_test.rs +0 -0
  306. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md005_unicode_test.rs +0 -0
  307. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md006_test.rs +0 -0
  308. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md006_unicode_test.rs +0 -0
  309. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md007_test.rs +0 -0
  310. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md009_test.rs +0 -0
  311. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md010_test.rs +0 -0
  312. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md011_test.rs +0 -0
  313. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md012_test.rs +0 -0
  314. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md013_test.rs +0 -0
  315. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md014_test.rs +0 -0
  316. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md018_test.rs +0 -0
  317. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md019_test.rs +0 -0
  318. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md021_test.rs +0 -0
  319. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md022_test.rs +0 -0
  320. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md023_extended_test.rs +0 -0
  321. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md023_test.rs +0 -0
  322. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md024_test.rs +0 -0
  323. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md025_test.rs +0 -0
  324. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md027_test.rs +0 -0
  325. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md028_test.rs +0 -0
  326. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md029_test.rs +0 -0
  327. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md029_unicode_test.rs +0 -0
  328. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md030_test.rs +0 -0
  329. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md031_kramdown_test.rs +0 -0
  330. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md031_test.rs +0 -0
  331. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md032_test.rs +0 -0
  332. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md033_extended_test.rs +0 -0
  333. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md033_kramdown_test.rs +0 -0
  334. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md033_test.rs +0 -0
  335. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md034_ipv6_test.rs +0 -0
  336. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md035_test.rs +0 -0
  337. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md036_test.rs +0 -0
  338. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md037_kramdown_test.rs +0 -0
  339. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md037_test.rs +0 -0
  340. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md038_nested_backticks_test.rs +0 -0
  341. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md038_test.rs +0 -0
  342. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md039_test.rs +0 -0
  343. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md040_test.rs +0 -0
  344. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md041_test.rs +0 -0
  345. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md042_test.rs +0 -0
  346. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md043_test.rs +0 -0
  347. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md044_test.rs +0 -0
  348. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md045_test.rs +0 -0
  349. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md046_test.rs +0 -0
  350. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md047_test.rs +0 -0
  351. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md048_test.rs +0 -0
  352. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md049_test.rs +0 -0
  353. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md050_test.rs +0 -0
  354. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md051_test.rs +0 -0
  355. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md051_unicode_test.rs +0 -0
  356. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md052_test.rs +0 -0
  357. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md053_additional_test.rs +0 -0
  358. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md053_proptest.rs +0 -0
  359. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md053_test.rs +0 -0
  360. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md054_test.rs +0 -0
  361. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md054_unicode_test.rs +0 -0
  362. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md055_test.rs +0 -0
  363. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md056_test.rs +0 -0
  364. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md057_test.rs +0 -0
  365. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md058_kramdown_test.rs +0 -0
  366. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/md058_test.rs +0 -0
  367. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules/mod.rs +0 -0
  368. {rumdl-0.0.114 → rumdl-0.0.116}/tests/rules_mod_test.rs +0 -0
  369. {rumdl-0.0.114 → rumdl-0.0.116}/tests/thread_safety_tests.rs +0 -0
  370. {rumdl-0.0.114 → rumdl-0.0.116}/tests/unicode_edge_case_tests.rs +0 -0
  371. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/blockquote_utils_test.rs +0 -0
  372. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/code_block_utils_extended_test.rs +0 -0
  373. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/code_block_utils_test.rs +0 -0
  374. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/core_utils_test.rs +0 -0
  375. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/front_matter_utils_test.rs +0 -0
  376. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/line_index_test.rs +0 -0
  377. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils/mod.rs +0 -0
  378. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils_markdown_edge_cases.rs +0 -0
  379. {rumdl-0.0.114 → rumdl-0.0.116}/tests/utils_tests.rs +0 -0
  380. {rumdl-0.0.114 → rumdl-0.0.116}/tests/vscode_extension_fixes.rs +0 -0
  381. {rumdl-0.0.114 → rumdl-0.0.116}/tests/vscode_test.rs +0 -0
  382. {rumdl-0.0.114 → rumdl-0.0.116}/tests/vscode_tests.rs +0 -0
  383. {rumdl-0.0.114 → rumdl-0.0.116}/tests/vscode_windows_comprehensive_test.rs +0 -0
  384. {rumdl-0.0.114 → rumdl-0.0.116}/tests/vscode_windows_test.rs +0 -0
@@ -22,6 +22,10 @@ status-level = "pass"
22
22
 
23
23
  [profile.ci]
24
24
 
25
+ # Skip performance tests in CI (they're flaky due to resource variability)
26
+ # Exclude specific integration test binaries and performance-related test functions
27
+ default-filter = 'not (package(rumdl) and binary(deeply_nested_lists_performance_test)) and not (package(rumdl) and binary(performance_validation_tests)) and not (package(rumdl) and binary(perf_check)) and not test(/performance|benchmark/)'
28
+
25
29
  # More conservative in CI
26
30
  test-threads = "num-cpus"
27
31
 
@@ -80,3 +84,23 @@ retries = 0
80
84
 
81
85
  # Fail fast on first failure
82
86
  fail-fast = true
87
+
88
+ # Performance testing profile - for scheduled/manual runs
89
+ [profile.performance]
90
+
91
+ # Only run performance and benchmark tests
92
+ default-filter = 'test(performance) or test(benchmark) or test(deeply_nested)'
93
+
94
+ # Run tests serially to reduce noise
95
+ test-threads = 1
96
+
97
+ # Show detailed output
98
+ failure-output = "immediate"
99
+ success-output = "immediate"
100
+ status-level = "all"
101
+
102
+ # Allow retries for flaky tests
103
+ retries = { backoff = "exponential", count = 3, delay = "1s", max-delay = "10s" }
104
+
105
+ # Don't fail fast - run all performance tests
106
+ fail-fast = false
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.0.116] - 2025-08-13
11
+
12
+ ### Added
13
+ - Kramdown-style custom header IDs support (#44)
14
+ - Headers can now have custom IDs using the `{#custom-id}` syntax
15
+ - Custom IDs are preserved when fixing MD051 (link fragments)
16
+ - MD026 (trailing punctuation) now ignores headers with custom IDs
17
+ - Safe character validation: accepts Unicode letters/numbers, hyphens, underscores, and colons
18
+ - Rejects problematic characters like spaces, quotes, brackets, and HTML/CSS special chars
19
+
20
+ ### Fixed
21
+ - Pre-release script now correctly handles dynamic versioning in pyproject.toml
22
+ - Added Cargo.lock validation and `cargo publish --dry-run` checks to prevent release failures
23
+
24
+ ## [0.0.115] - 2025-08-12
25
+
10
26
  ## [0.0.114] - 2025-08-09
11
27
 
12
28
  ## [0.0.113] - 2025-08-09
@@ -308,7 +324,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
308
324
 
309
325
  - Initial implementation of remaining rules for markdownlint parity
310
326
 
311
- [Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.114...HEAD
327
+ [Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.116...HEAD
328
+ [0.0.116]: https://github.com/rvben/rumdl/compare/v0.0.115...v0.0.116
329
+ [0.0.115]: https://github.com/rvben/rumdl/compare/v0.0.114...v0.0.115
312
330
  [0.0.114]: https://github.com/rvben/rumdl/compare/v0.0.113...v0.0.114
313
331
  [0.0.113]: https://github.com/rvben/rumdl/compare/v0.0.112...v0.0.113
314
332
  [0.0.112]: https://github.com/rvben/rumdl/compare/v0.0.111...v0.0.112
@@ -99,9 +99,9 @@ dependencies = [
99
99
 
100
100
  [[package]]
101
101
  name = "anyhow"
102
- version = "1.0.98"
102
+ version = "1.0.99"
103
103
  source = "registry+https://github.com/rust-lang/crates.io-index"
104
- checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
104
+ checksum = "b0674a1ddeecb70197781e945de4b3b8ffb61fa939a5597bcf48503737663100"
105
105
 
106
106
  [[package]]
107
107
  name = "assert_cmd"
@@ -277,9 +277,9 @@ dependencies = [
277
277
 
278
278
  [[package]]
279
279
  name = "clap"
280
- version = "4.5.43"
280
+ version = "4.5.45"
281
281
  source = "registry+https://github.com/rust-lang/crates.io-index"
282
- checksum = "50fd97c9dc2399518aa331917ac6f274280ec5eb34e555dd291899745c48ec6f"
282
+ checksum = "1fc0e74a703892159f5ae7d3aac52c8e6c392f5ae5f359c70b5881d60aaac318"
283
283
  dependencies = [
284
284
  "clap_builder",
285
285
  "clap_derive",
@@ -287,9 +287,9 @@ dependencies = [
287
287
 
288
288
  [[package]]
289
289
  name = "clap_builder"
290
- version = "4.5.43"
290
+ version = "4.5.44"
291
291
  source = "registry+https://github.com/rust-lang/crates.io-index"
292
- checksum = "c35b5830294e1fa0462034af85cc95225a4cb07092c088c55bda3147cfcd8f65"
292
+ checksum = "b3e7f4214277f3c7aa526a59dd3fbe306a370daee1f8b7b8c987069cd8e888a8"
293
293
  dependencies = [
294
294
  "anstream",
295
295
  "anstyle",
@@ -299,9 +299,9 @@ dependencies = [
299
299
 
300
300
  [[package]]
301
301
  name = "clap_derive"
302
- version = "4.5.41"
302
+ version = "4.5.45"
303
303
  source = "registry+https://github.com/rust-lang/crates.io-index"
304
- checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
304
+ checksum = "14cb31bb0a7d536caef2639baa7fad459e15c3144efefa6dbd1c84562c4739f6"
305
305
  dependencies = [
306
306
  "heck",
307
307
  "proc-macro2",
@@ -951,9 +951,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
951
951
 
952
952
  [[package]]
953
953
  name = "libc"
954
- version = "0.2.174"
954
+ version = "0.2.175"
955
955
  source = "registry+https://github.com/rust-lang/crates.io-index"
956
- checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
956
+ checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543"
957
957
 
958
958
  [[package]]
959
959
  name = "linux-raw-sys"
@@ -1265,9 +1265,9 @@ dependencies = [
1265
1265
 
1266
1266
  [[package]]
1267
1267
  name = "proc-macro2"
1268
- version = "1.0.95"
1268
+ version = "1.0.97"
1269
1269
  source = "registry+https://github.com/rust-lang/crates.io-index"
1270
- checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778"
1270
+ checksum = "d61789d7719defeb74ea5fe81f2fdfdbd28a803847077cecce2ff14e1472f6f1"
1271
1271
  dependencies = [
1272
1272
  "unicode-ident",
1273
1273
  ]
@@ -1493,7 +1493,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
1493
1493
 
1494
1494
  [[package]]
1495
1495
  name = "rumdl"
1496
- version = "0.0.114"
1496
+ version = "0.0.116"
1497
1497
  dependencies = [
1498
1498
  "anyhow",
1499
1499
  "assert_cmd",
@@ -1770,18 +1770,18 @@ checksum = "8f50febec83f5ee1df3015341d8bd429f2d1cc62bcba7ea2076759d315084683"
1770
1770
 
1771
1771
  [[package]]
1772
1772
  name = "thiserror"
1773
- version = "2.0.12"
1773
+ version = "2.0.14"
1774
1774
  source = "registry+https://github.com/rust-lang/crates.io-index"
1775
- checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
1775
+ checksum = "0b0949c3a6c842cbde3f1686d6eea5a010516deb7085f79db747562d4102f41e"
1776
1776
  dependencies = [
1777
1777
  "thiserror-impl",
1778
1778
  ]
1779
1779
 
1780
1780
  [[package]]
1781
1781
  name = "thiserror-impl"
1782
- version = "2.0.12"
1782
+ version = "2.0.14"
1783
1783
  source = "registry+https://github.com/rust-lang/crates.io-index"
1784
- checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
1784
+ checksum = "cc5b44b4ab9c2fdd0e0512e6bece8388e214c0749f5862b114cc5b7a25daf227"
1785
1785
  dependencies = [
1786
1786
  "proc-macro2",
1787
1787
  "quote",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rumdl"
3
- version = "0.0.114"
3
+ version = "0.0.116"
4
4
  edition = "2024"
5
5
  rust-version = "1.89.0"
6
6
  description = "A fast Markdown linter written in Rust (Ru(st) MarkDown Linter)"
@@ -101,6 +101,11 @@ test-push:
101
101
  test-ci:
102
102
  cargo nextest run --profile ci
103
103
 
104
+ test-performance:
105
+ @echo "Running performance tests (this may take a few minutes)..."
106
+ @echo "Tests run serially to reduce noise - be patient!"
107
+ cargo nextest run --profile performance
108
+
104
109
  clean:
105
110
  cargo clean
106
111
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rumdl
3
- Version: 0.0.114
3
+ Version: 0.0.116
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -73,15 +73,24 @@ run_check "Release build" "cargo build --release"
73
73
  echo "6. Checking documentation..."
74
74
  run_check "Documentation" "cargo doc --no-deps"
75
75
 
76
- # 7. Verify Cargo.toml version
76
+ # 7. Verify Cargo.toml version (pyproject.toml uses dynamic versioning from Cargo.toml)
77
77
  echo "7. Checking version consistency..."
78
78
  CARGO_VERSION=$(grep '^version' Cargo.toml | head -1 | cut -d'"' -f2)
79
- PY_VERSION=$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2)
80
- if [ "$CARGO_VERSION" != "$PY_VERSION" ]; then
81
- echo -e "${RED}Version mismatch: Cargo.toml ($CARGO_VERSION) vs pyproject.toml ($PY_VERSION)${NC}"
82
- FAILED=1
79
+ # pyproject.toml uses dynamic = ["version"] to read from Cargo.toml
80
+ if grep -q 'dynamic = \["version"\]' pyproject.toml; then
81
+ echo -e "${GREEN}✓${NC} Version $CARGO_VERSION (pyproject.toml uses dynamic versioning)"
83
82
  else
84
- echo -e "${GREEN}✓${NC} Version $CARGO_VERSION is consistent"
83
+ # Fallback: check if there's a static version in pyproject.toml
84
+ PY_VERSION=$(grep '^version' pyproject.toml | head -1 | cut -d'"' -f2)
85
+ if [ -z "$PY_VERSION" ]; then
86
+ echo -e "${YELLOW}⚠${NC} pyproject.toml should use dynamic = [\"version\"] for version"
87
+ # Not a failure, just a warning
88
+ elif [ "$CARGO_VERSION" != "$PY_VERSION" ]; then
89
+ echo -e "${RED}Version mismatch: Cargo.toml ($CARGO_VERSION) vs pyproject.toml ($PY_VERSION)${NC}"
90
+ FAILED=1
91
+ else
92
+ echo -e "${GREEN}✓${NC} Version $CARGO_VERSION is consistent"
93
+ fi
85
94
  fi
86
95
 
87
96
  # 8. Check for uncommitted changes
@@ -111,6 +120,20 @@ else
111
120
  echo -e "${GREEN}✓${NC} Tag $TAG_VERSION is available"
112
121
  fi
113
122
 
123
+ # 11. Verify Cargo.lock is up to date
124
+ echo "11. Verifying Cargo.lock is up to date..."
125
+ if cargo update --workspace --dry-run 2>&1 | grep -q "Updating"; then
126
+ echo -e "${RED}✗ Cargo.lock needs updating${NC}"
127
+ echo " Run: cargo update --workspace"
128
+ FAILED=1
129
+ else
130
+ echo -e "${GREEN}✓${NC} Cargo.lock is up to date"
131
+ fi
132
+
133
+ # 12. Test cargo publish with --dry-run
134
+ echo "12. Testing cargo publish (dry run)..."
135
+ run_check "Cargo publish dry-run" "cargo publish --dry-run --locked"
136
+
114
137
  echo ""
115
138
  echo "====================================="
116
139
  if [ $FAILED -eq 0 ]; then
@@ -90,6 +90,16 @@ pub struct GlobalConfig {
90
90
  /// Output format for linting results (e.g., "text", "json", "pylint", etc.)
91
91
  #[serde(skip_serializing_if = "Option::is_none")]
92
92
  pub output_format: Option<String>,
93
+
94
+ /// Rules that are allowed to be fixed when --fix is used
95
+ /// If specified, only these rules will be fixed
96
+ #[serde(default)]
97
+ pub fixable: Vec<String>,
98
+
99
+ /// Rules that should never be fixed, even when --fix is used
100
+ /// Takes precedence over fixable
101
+ #[serde(default)]
102
+ pub unfixable: Vec<String>,
93
103
  }
94
104
 
95
105
  fn default_respect_gitignore() -> bool {
@@ -111,6 +121,8 @@ impl Default for GlobalConfig {
111
121
  respect_gitignore: true,
112
122
  line_length: 80,
113
123
  output_format: None,
124
+ fixable: Vec::new(),
125
+ unfixable: Vec::new(),
114
126
  }
115
127
  }
116
128
  }
@@ -999,6 +1011,8 @@ pub struct SourcedGlobalConfig {
999
1011
  pub respect_gitignore: SourcedValue<bool>,
1000
1012
  pub line_length: SourcedValue<u64>,
1001
1013
  pub output_format: Option<SourcedValue<String>>,
1014
+ pub fixable: SourcedValue<Vec<String>>,
1015
+ pub unfixable: SourcedValue<Vec<String>>,
1002
1016
  }
1003
1017
 
1004
1018
  impl Default for SourcedGlobalConfig {
@@ -1011,6 +1025,8 @@ impl Default for SourcedGlobalConfig {
1011
1025
  respect_gitignore: SourcedValue::new(true, ConfigSource::Default),
1012
1026
  line_length: SourcedValue::new(80, ConfigSource::Default),
1013
1027
  output_format: None,
1028
+ fixable: SourcedValue::new(Vec::new(), ConfigSource::Default),
1029
+ unfixable: SourcedValue::new(Vec::new(), ConfigSource::Default),
1014
1030
  }
1015
1031
  }
1016
1032
  }
@@ -1077,6 +1093,29 @@ impl SourcedConfig {
1077
1093
  .and_then(|o| o.file.clone()),
1078
1094
  fragment.global.respect_gitignore.overrides.first().and_then(|o| o.line),
1079
1095
  );
1096
+ self.global.line_length.merge_override(
1097
+ fragment.global.line_length.value,
1098
+ fragment.global.line_length.source,
1099
+ fragment
1100
+ .global
1101
+ .line_length
1102
+ .overrides
1103
+ .first()
1104
+ .and_then(|o| o.file.clone()),
1105
+ fragment.global.line_length.overrides.first().and_then(|o| o.line),
1106
+ );
1107
+ self.global.fixable.merge_override(
1108
+ fragment.global.fixable.value,
1109
+ fragment.global.fixable.source,
1110
+ fragment.global.fixable.overrides.first().and_then(|o| o.file.clone()),
1111
+ fragment.global.fixable.overrides.first().and_then(|o| o.line),
1112
+ );
1113
+ self.global.unfixable.merge_override(
1114
+ fragment.global.unfixable.value,
1115
+ fragment.global.unfixable.source,
1116
+ fragment.global.unfixable.overrides.first().and_then(|o| o.file.clone()),
1117
+ fragment.global.unfixable.overrides.first().and_then(|o| o.line),
1118
+ );
1080
1119
 
1081
1120
  // Merge output_format if present
1082
1121
  if let Some(output_format_fragment) = fragment.global.output_format {
@@ -1269,6 +1308,14 @@ impl SourcedConfig {
1269
1308
  None,
1270
1309
  None,
1271
1310
  );
1311
+ sourced_config
1312
+ .global
1313
+ .fixable
1314
+ .merge_override(cli.fixable.value.clone(), ConfigSource::Cli, None, None);
1315
+ sourced_config
1316
+ .global
1317
+ .unfixable
1318
+ .merge_override(cli.unfixable.value.clone(), ConfigSource::Cli, None, None);
1272
1319
  // No rule-specific CLI overrides implemented yet
1273
1320
  }
1274
1321
 
@@ -1298,6 +1345,8 @@ impl From<SourcedConfig> for Config {
1298
1345
  respect_gitignore: sourced.global.respect_gitignore.value,
1299
1346
  line_length: sourced.global.line_length.value,
1300
1347
  output_format: sourced.global.output_format.as_ref().map(|v| v.value.clone()),
1348
+ fixable: sourced.global.fixable.value,
1349
+ unfixable: sourced.global.unfixable.value,
1301
1350
  };
1302
1351
  Config { global, rules }
1303
1352
  }
@@ -1549,6 +1598,24 @@ fn parse_pyproject_toml(content: &str, path: &str) -> Result<Option<SourcedConfi
1549
1598
  .push_override(value, source, file.clone(), None);
1550
1599
  }
1551
1600
  }
1601
+ if let Some(fixable) = rumdl_table.get("fixable")
1602
+ && let Ok(values) = Vec::<String>::deserialize(fixable.clone())
1603
+ {
1604
+ let normalized_values = values.into_iter().map(|s| normalize_key(&s)).collect();
1605
+ fragment
1606
+ .global
1607
+ .fixable
1608
+ .push_override(normalized_values, source, file.clone(), None);
1609
+ }
1610
+ if let Some(unfixable) = rumdl_table.get("unfixable")
1611
+ && let Ok(values) = Vec::<String>::deserialize(unfixable.clone())
1612
+ {
1613
+ let normalized_values = values.into_iter().map(|s| normalize_key(&s)).collect();
1614
+ fragment
1615
+ .global
1616
+ .unfixable
1617
+ .push_override(normalized_values, source, file.clone(), None);
1618
+ }
1552
1619
 
1553
1620
  // --- Re-introduce special line-length handling ---
1554
1621
  let mut found_line_length_val: Option<toml::Value> = None;
@@ -1590,6 +1657,8 @@ fn parse_pyproject_toml(content: &str, path: &str) -> Result<Option<SourcedConfi
1590
1657
  "line-length",
1591
1658
  "output_format",
1592
1659
  "output-format",
1660
+ "fixable",
1661
+ "unfixable",
1593
1662
  ]
1594
1663
  .contains(&norm_rule_key.as_str())
1595
1664
  {
@@ -1683,6 +1752,9 @@ fn parse_pyproject_toml(content: &str, path: &str) -> Result<Option<SourcedConfi
1683
1752
  || !fragment.global.disable.value.is_empty()
1684
1753
  || !fragment.global.include.value.is_empty()
1685
1754
  || !fragment.global.exclude.value.is_empty()
1755
+ || !fragment.global.fixable.value.is_empty()
1756
+ || !fragment.global.unfixable.value.is_empty()
1757
+ || fragment.global.output_format.is_some()
1686
1758
  || !fragment.rules.is_empty();
1687
1759
  if has_any { Ok(Some(fragment)) } else { Ok(None) }
1688
1760
  }
@@ -1820,6 +1892,46 @@ fn parse_rumdl_toml(content: &str, path: &str) -> Result<SourcedConfigFragment,
1820
1892
  );
1821
1893
  }
1822
1894
  }
1895
+ "fixable" => {
1896
+ if let Some(toml_edit::Value::Array(formatted_array)) = value_item.as_value() {
1897
+ let values: Vec<String> = formatted_array
1898
+ .iter()
1899
+ .filter_map(|item| item.as_str())
1900
+ .map(normalize_key)
1901
+ .collect();
1902
+ fragment
1903
+ .global
1904
+ .fixable
1905
+ .push_override(values, source, file.clone(), None);
1906
+ } else {
1907
+ log::warn!(
1908
+ "[WARN] Expected array for global key '{}' in {}, found {}",
1909
+ key,
1910
+ path,
1911
+ value_item.type_name()
1912
+ );
1913
+ }
1914
+ }
1915
+ "unfixable" => {
1916
+ if let Some(toml_edit::Value::Array(formatted_array)) = value_item.as_value() {
1917
+ let values: Vec<String> = formatted_array
1918
+ .iter()
1919
+ .filter_map(|item| item.as_str())
1920
+ .map(normalize_key)
1921
+ .collect();
1922
+ fragment
1923
+ .global
1924
+ .unfixable
1925
+ .push_override(values, source, file.clone(), None);
1926
+ } else {
1927
+ log::warn!(
1928
+ "[WARN] Expected array for global key '{}' in {}, found {}",
1929
+ key,
1930
+ path,
1931
+ value_item.type_name()
1932
+ );
1933
+ }
1934
+ }
1823
1935
  _ => {
1824
1936
  // Add to unknown_keys for potential validation later
1825
1937
  // fragment.unknown_keys.push(("[global]".to_string(), key.to_string()));
@@ -197,8 +197,12 @@ pub struct HeadingInfo {
197
197
  pub marker_column: usize,
198
198
  /// Column where heading text starts
199
199
  pub content_column: usize,
200
- /// The heading text (without markers)
200
+ /// The heading text (without markers and without custom ID syntax)
201
201
  pub text: String,
202
+ /// Custom header ID if present (e.g., from {#custom-id} syntax)
203
+ pub custom_id: Option<String>,
204
+ /// Original heading text including custom ID syntax
205
+ pub raw_text: String,
202
206
  /// Whether it has a closing sequence (for ATX)
203
207
  pub has_closing_sequence: bool,
204
208
  /// The closing sequence if present
@@ -1088,10 +1092,23 @@ impl<'a> LintContext<'a> {
1088
1092
  let level = hashes.len() as u8;
1089
1093
  let marker_column = leading_spaces.len();
1090
1094
 
1091
- // Check for closing sequence
1095
+ // Check for closing sequence, but handle custom IDs that might come after
1092
1096
  let (text, has_closing, closing_seq) = {
1093
- // Find the start of a potential closing sequence
1094
- let trimmed_rest = rest.trim_end();
1097
+ // First check if there's a custom ID at the end
1098
+ let (rest_without_id, custom_id_part) = if let Some(id_start) = rest.rfind(" {#") {
1099
+ // Check if this looks like a valid custom ID (ends with })
1100
+ if rest[id_start..].trim_end().ends_with('}') {
1101
+ // Split off the custom ID
1102
+ (&rest[..id_start], &rest[id_start..])
1103
+ } else {
1104
+ (rest, "")
1105
+ }
1106
+ } else {
1107
+ (rest, "")
1108
+ };
1109
+
1110
+ // Now look for closing hashes in the part before the custom ID
1111
+ let trimmed_rest = rest_without_id.trim_end();
1095
1112
  if let Some(last_hash_pos) = trimmed_rest.rfind('#') {
1096
1113
  // Look for the start of the hash sequence
1097
1114
  let mut start_of_hashes = last_hash_pos;
@@ -1099,32 +1116,55 @@ impl<'a> LintContext<'a> {
1099
1116
  start_of_hashes -= 1;
1100
1117
  }
1101
1118
 
1102
- // Check if this is a valid closing sequence (all hashes to end of line)
1119
+ // Check if there's at least one space before the closing hashes
1120
+ let has_space_before = start_of_hashes == 0
1121
+ || trimmed_rest
1122
+ .chars()
1123
+ .nth(start_of_hashes - 1)
1124
+ .is_some_and(|c| c.is_whitespace());
1125
+
1126
+ // Check if this is a valid closing sequence (all hashes to end of trimmed part)
1103
1127
  let potential_closing = &trimmed_rest[start_of_hashes..];
1104
1128
  let is_all_hashes = potential_closing.chars().all(|c| c == '#');
1105
1129
 
1106
- if is_all_hashes {
1107
- // This is a closing sequence, regardless of spacing
1130
+ if is_all_hashes && has_space_before {
1131
+ // This is a closing sequence
1108
1132
  let closing_hashes = potential_closing.to_string();
1109
- let text_part = rest[..start_of_hashes].trim_end();
1110
- (text_part.to_string(), true, closing_hashes)
1133
+ // The text is everything before the closing hashes
1134
+ // Don't include the custom ID here - it will be extracted later
1135
+ let text_part = if !custom_id_part.is_empty() {
1136
+ // If we have a custom ID, append it back to get the full rest
1137
+ // This allows the extract_header_id function to handle it properly
1138
+ format!("{}{}", rest_without_id[..start_of_hashes].trim_end(), custom_id_part)
1139
+ } else {
1140
+ rest_without_id[..start_of_hashes].trim_end().to_string()
1141
+ };
1142
+ (text_part, true, closing_hashes)
1111
1143
  } else {
1144
+ // Not a valid closing sequence, return the full content
1112
1145
  (rest.to_string(), false, String::new())
1113
1146
  }
1114
1147
  } else {
1148
+ // No hashes found, return the full content
1115
1149
  (rest.to_string(), false, String::new())
1116
1150
  }
1117
1151
  };
1118
1152
 
1119
1153
  let content_column = marker_column + hashes.len() + spaces_after.len();
1120
1154
 
1155
+ // Extract custom header ID if present
1156
+ let raw_text = text.trim().to_string();
1157
+ let (clean_text, custom_id) = crate::utils::kramdown_utils::extract_header_id(&raw_text);
1158
+
1121
1159
  lines[i].heading = Some(HeadingInfo {
1122
1160
  level,
1123
1161
  style: HeadingStyle::ATX,
1124
1162
  marker: hashes.to_string(),
1125
1163
  marker_column,
1126
1164
  content_column,
1127
- text: text.trim().to_string(),
1165
+ text: clean_text,
1166
+ custom_id,
1167
+ raw_text,
1128
1168
  has_closing_sequence: has_closing,
1129
1169
  closing_sequence: closing_seq,
1130
1170
  });
@@ -1146,13 +1186,19 @@ impl<'a> LintContext<'a> {
1146
1186
  HeadingStyle::Setext2
1147
1187
  };
1148
1188
 
1189
+ // Extract custom header ID if present
1190
+ let raw_text = line.trim().to_string();
1191
+ let (clean_text, custom_id) = crate::utils::kramdown_utils::extract_header_id(&raw_text);
1192
+
1149
1193
  lines[i].heading = Some(HeadingInfo {
1150
1194
  level,
1151
1195
  style,
1152
1196
  marker: underline.to_string(),
1153
1197
  marker_column: next_line.len() - next_line.trim_start().len(),
1154
1198
  content_column: lines[i].indent,
1155
- text: line.trim().to_string(),
1199
+ text: clean_text,
1200
+ custom_id,
1201
+ raw_text,
1156
1202
  has_closing_sequence: false,
1157
1203
  closing_sequence: String::new(),
1158
1204
  });
@@ -2044,6 +2044,7 @@ fn run_check(args: &CheckArgs, global_config_path: Option<&str>, no_config: bool
2044
2044
  quiet,
2045
2045
  &output_format,
2046
2046
  &output_writer,
2047
+ &config,
2047
2048
  )
2048
2049
  })
2049
2050
  .collect();
@@ -2098,6 +2099,7 @@ fn run_check(args: &CheckArgs, global_config_path: Option<&str>, no_config: bool
2098
2099
  quiet,
2099
2100
  &output_format,
2100
2101
  &output_writer,
2102
+ &config,
2101
2103
  );
2102
2104
 
2103
2105
  total_files_processed += 1;
@@ -2354,6 +2356,7 @@ fn print_statistics(warnings: &[rumdl::rule::LintWarning]) {
2354
2356
  }
2355
2357
 
2356
2358
  // Process file with output formatter
2359
+ #[allow(clippy::too_many_arguments)]
2357
2360
  fn process_file_with_formatter(
2358
2361
  file_path: &str,
2359
2362
  rules: &[Box<dyn Rule>],
@@ -2362,6 +2365,7 @@ fn process_file_with_formatter(
2362
2365
  quiet: bool,
2363
2366
  output_format: &rumdl::output::OutputFormat,
2364
2367
  output_writer: &rumdl::output::OutputWriter,
2368
+ config: &rumdl_config::Config,
2365
2369
  ) -> (bool, usize, usize, usize, Vec<rumdl::rule::LintWarning>) {
2366
2370
  let formatter = output_format.create_formatter();
2367
2371
 
@@ -2387,7 +2391,7 @@ fn process_file_with_formatter(
2387
2391
  // Fix issues if requested
2388
2392
  let mut warnings_fixed = 0;
2389
2393
  if _fix {
2390
- warnings_fixed = apply_fixes(rules, &all_warnings, &mut content, file_path, quiet);
2394
+ warnings_fixed = apply_fixes(rules, &all_warnings, &mut content, file_path, quiet, config);
2391
2395
 
2392
2396
  // In fix mode, show warnings with [fixed] for issues that were fixed
2393
2397
  if !quiet {
@@ -2528,6 +2532,7 @@ fn apply_fixes(
2528
2532
  content: &mut String,
2529
2533
  file_path: &str,
2530
2534
  quiet: bool,
2535
+ config: &rumdl_config::Config,
2531
2536
  ) -> usize {
2532
2537
  let mut warnings_fixed = 0;
2533
2538
 
@@ -2549,6 +2554,26 @@ fn apply_fixes(
2549
2554
  });
2550
2555
 
2551
2556
  if has_non_disabled_warnings {
2557
+ // Check fixable/unfixable configuration
2558
+ let rule_name = rule.name();
2559
+
2560
+ // If unfixable list contains this rule, skip fixing
2561
+ if config
2562
+ .global
2563
+ .unfixable
2564
+ .iter()
2565
+ .any(|r| r.eq_ignore_ascii_case(rule_name))
2566
+ {
2567
+ continue;
2568
+ }
2569
+
2570
+ // If fixable list is specified and doesn't contain this rule, skip fixing
2571
+ if !config.global.fixable.is_empty()
2572
+ && !config.global.fixable.iter().any(|r| r.eq_ignore_ascii_case(rule_name))
2573
+ {
2574
+ continue;
2575
+ }
2576
+
2552
2577
  let ctx = LintContext::new(content);
2553
2578
  match rule.fix(&ctx) {
2554
2579
  Ok(fixed_content) => {