rumdl 0.0.109__tar.gz → 0.0.111__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 (376) hide show
  1. {rumdl-0.0.109 → rumdl-0.0.111}/.mise.toml +2 -1
  2. {rumdl-0.0.109 → rumdl-0.0.111}/CHANGELOG.md +3 -0
  3. {rumdl-0.0.109 → rumdl-0.0.111}/Cargo.lock +3 -3
  4. {rumdl-0.0.109 → rumdl-0.0.111}/Cargo.toml +1 -1
  5. {rumdl-0.0.109 → rumdl-0.0.111}/Makefile +17 -1
  6. {rumdl-0.0.109 → rumdl-0.0.111}/PKG-INFO +1 -1
  7. {rumdl-0.0.109 → rumdl-0.0.111}/src/lint_context.rs +15 -15
  8. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md031_blanks_around_fences.rs +5 -0
  9. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md032_blanks_around_lists.rs +38 -2
  10. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md058_blanks_around_tables.rs +35 -24
  11. rumdl-0.0.111/src/utils/kramdown_utils.rs +94 -0
  12. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/mod.rs +1 -0
  13. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md005_test.rs +33 -0
  14. rumdl-0.0.111/tests/rules/md031_kramdown_test.rs +125 -0
  15. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md032_test.rs +52 -1
  16. rumdl-0.0.111/tests/rules/md058_kramdown_test.rs +139 -0
  17. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/mod.rs +2 -0
  18. {rumdl-0.0.109 → rumdl-0.0.111}/.config/nextest.toml +0 -0
  19. {rumdl-0.0.109 → rumdl-0.0.111}/.pre-commit-config.yaml +0 -0
  20. {rumdl-0.0.109 → rumdl-0.0.111}/.rumdl.toml +0 -0
  21. {rumdl-0.0.109 → rumdl-0.0.111}/.rustfmt.toml +0 -0
  22. {rumdl-0.0.109 → rumdl-0.0.111}/LICENSE +0 -0
  23. {rumdl-0.0.109 → rumdl-0.0.111}/MANIFEST.in +0 -0
  24. {rumdl-0.0.109 → rumdl-0.0.111}/README.md +0 -0
  25. {rumdl-0.0.109 → rumdl-0.0.111}/assets/logo.png +0 -0
  26. {rumdl-0.0.109 → rumdl-0.0.111}/benches/fix_performance.rs +0 -0
  27. {rumdl-0.0.109 → rumdl-0.0.111}/benches/range_performance.rs +0 -0
  28. {rumdl-0.0.109 → rumdl-0.0.111}/benches/range_utils_benchmark.rs +0 -0
  29. {rumdl-0.0.109 → rumdl-0.0.111}/benches/rule_performance.rs +0 -0
  30. {rumdl-0.0.109 → rumdl-0.0.111}/benches/simple_fix_bench.rs +0 -0
  31. {rumdl-0.0.109 → rumdl-0.0.111}/benchmark/bin/bench_lint_context.rs +0 -0
  32. {rumdl-0.0.109 → rumdl-0.0.111}/benchmark/bin/benchmark.rs +0 -0
  33. {rumdl-0.0.109 → rumdl-0.0.111}/benchmark/bin/benchmark_rule.rs +0 -0
  34. {rumdl-0.0.109 → rumdl-0.0.111}/benchmark/bin/file_parallel_benchmark.rs +0 -0
  35. {rumdl-0.0.109 → rumdl-0.0.111}/benchmark/bin/measure_code_span_performance.rs +0 -0
  36. {rumdl-0.0.109 → rumdl-0.0.111}/docs/RULES.md +0 -0
  37. {rumdl-0.0.109 → rumdl-0.0.111}/docs/global-settings.md +0 -0
  38. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md001.md +0 -0
  39. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md002.md +0 -0
  40. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md003.md +0 -0
  41. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md004.md +0 -0
  42. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md005.md +0 -0
  43. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md006.md +0 -0
  44. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md007.md +0 -0
  45. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md009.md +0 -0
  46. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md010.md +0 -0
  47. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md011.md +0 -0
  48. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md012.md +0 -0
  49. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md013.md +0 -0
  50. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md014.md +0 -0
  51. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md018.md +0 -0
  52. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md019.md +0 -0
  53. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md020.md +0 -0
  54. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md021.md +0 -0
  55. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md022.md +0 -0
  56. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md023.md +0 -0
  57. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md024.md +0 -0
  58. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md025.md +0 -0
  59. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md026.md +0 -0
  60. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md027.md +0 -0
  61. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md028.md +0 -0
  62. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md029.md +0 -0
  63. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md030.md +0 -0
  64. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md031.md +0 -0
  65. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md032.md +0 -0
  66. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md033.md +0 -0
  67. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md034.md +0 -0
  68. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md035.md +0 -0
  69. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md036.md +0 -0
  70. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md037.md +0 -0
  71. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md038.md +0 -0
  72. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md039.md +0 -0
  73. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md040.md +0 -0
  74. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md041.md +0 -0
  75. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md042.md +0 -0
  76. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md043.md +0 -0
  77. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md044.md +0 -0
  78. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md045.md +0 -0
  79. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md046.md +0 -0
  80. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md047.md +0 -0
  81. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md048.md +0 -0
  82. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md049.md +0 -0
  83. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md050.md +0 -0
  84. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md051.md +0 -0
  85. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md052.md +0 -0
  86. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md053.md +0 -0
  87. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md054.md +0 -0
  88. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md055.md +0 -0
  89. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md056.md +0 -0
  90. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md057.md +0 -0
  91. {rumdl-0.0.109 → rumdl-0.0.111}/docs/md058.md +0 -0
  92. {rumdl-0.0.109 → rumdl-0.0.111}/docs/vscode-extension.md +0 -0
  93. {rumdl-0.0.109 → rumdl-0.0.111}/parity_check.py +0 -0
  94. {rumdl-0.0.109 → rumdl-0.0.111}/pyproject.toml +0 -0
  95. {rumdl-0.0.109 → rumdl-0.0.111}/python/MANIFEST.in +0 -0
  96. {rumdl-0.0.109 → rumdl-0.0.111}/python/PYTHON-README.md +0 -0
  97. {rumdl-0.0.109 → rumdl-0.0.111}/python/rumdl/__init__.py +0 -0
  98. {rumdl-0.0.109 → rumdl-0.0.111}/python/rumdl/__main__.py +0 -0
  99. {rumdl-0.0.109 → rumdl-0.0.111}/python/rumdl/py.typed +0 -0
  100. {rumdl-0.0.109 → rumdl-0.0.111}/rumdl.toml.example +0 -0
  101. {rumdl-0.0.109 → rumdl-0.0.111}/rust-toolchain.toml +0 -0
  102. {rumdl-0.0.109 → rumdl-0.0.111}/scripts/extract-changelog.sh +0 -0
  103. {rumdl-0.0.109 → rumdl-0.0.111}/scripts/prepare-release.sh +0 -0
  104. {rumdl-0.0.109 → rumdl-0.0.111}/scripts/setup-pre-commit.sh +0 -0
  105. {rumdl-0.0.109 → rumdl-0.0.111}/scripts/update-pre-commit-docs.sh +0 -0
  106. {rumdl-0.0.109 → rumdl-0.0.111}/src/bin/debug_frontmatter.rs +0 -0
  107. {rumdl-0.0.109 → rumdl-0.0.111}/src/config.rs +0 -0
  108. {rumdl-0.0.109 → rumdl-0.0.111}/src/exit_codes.rs +0 -0
  109. {rumdl-0.0.109 → rumdl-0.0.111}/src/inline_config.rs +0 -0
  110. {rumdl-0.0.109 → rumdl-0.0.111}/src/lib.rs +0 -0
  111. {rumdl-0.0.109 → rumdl-0.0.111}/src/lsp/mod.rs +0 -0
  112. {rumdl-0.0.109 → rumdl-0.0.111}/src/lsp/server.rs +0 -0
  113. {rumdl-0.0.109 → rumdl-0.0.111}/src/lsp/types.rs +0 -0
  114. {rumdl-0.0.109 → rumdl-0.0.111}/src/main.rs +0 -0
  115. {rumdl-0.0.109 → rumdl-0.0.111}/src/markdownlint_config.rs +0 -0
  116. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/azure.rs +0 -0
  117. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/concise.rs +0 -0
  118. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/github.rs +0 -0
  119. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/gitlab.rs +0 -0
  120. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/grouped.rs +0 -0
  121. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/json.rs +0 -0
  122. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/json_lines.rs +0 -0
  123. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/junit.rs +0 -0
  124. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/mod.rs +0 -0
  125. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/pylint.rs +0 -0
  126. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/sarif.rs +0 -0
  127. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/formatters/text.rs +0 -0
  128. {rumdl-0.0.109 → rumdl-0.0.111}/src/output/mod.rs +0 -0
  129. {rumdl-0.0.109 → rumdl-0.0.111}/src/parallel.rs +0 -0
  130. {rumdl-0.0.109 → rumdl-0.0.111}/src/performance.rs +0 -0
  131. {rumdl-0.0.109 → rumdl-0.0.111}/src/profiling.rs +0 -0
  132. {rumdl-0.0.109 → rumdl-0.0.111}/src/python.rs +0 -0
  133. {rumdl-0.0.109 → rumdl-0.0.111}/src/rule.rs +0 -0
  134. {rumdl-0.0.109 → rumdl-0.0.111}/src/rule_config.rs +0 -0
  135. {rumdl-0.0.109 → rumdl-0.0.111}/src/rule_config_serde.rs +0 -0
  136. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/blockquote_utils.rs +0 -0
  137. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/code_block_utils.rs +0 -0
  138. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/code_fence_utils.rs +0 -0
  139. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/emphasis_style.rs +0 -0
  140. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/front_matter_utils.rs +0 -0
  141. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/heading_utils.rs +0 -0
  142. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/list_utils.rs +0 -0
  143. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md001_heading_increment.rs +0 -0
  144. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md002_first_heading_h1/md002_config.rs +0 -0
  145. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md002_first_heading_h1.rs +0 -0
  146. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md003_heading_style/md003_config.rs +0 -0
  147. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md003_heading_style.rs +0 -0
  148. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md004_unordered_list_style/md004_config.rs +0 -0
  149. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md004_unordered_list_style.rs +0 -0
  150. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md005_list_indent.rs +0 -0
  151. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md006_start_bullets.rs +0 -0
  152. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md007_ul_indent/md007_config.rs +0 -0
  153. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md007_ul_indent.rs +0 -0
  154. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md009_trailing_spaces/md009_config.rs +0 -0
  155. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md009_trailing_spaces.rs +0 -0
  156. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md010_no_hard_tabs/md010_config.rs +0 -0
  157. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md010_no_hard_tabs.rs +0 -0
  158. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md011_no_reversed_links.rs +0 -0
  159. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md012_no_multiple_blanks/md012_config.rs +0 -0
  160. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md012_no_multiple_blanks.rs +0 -0
  161. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md013_line_length/md013_config.rs +0 -0
  162. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md013_line_length.rs +0 -0
  163. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md014_commands_show_output/md014_config.rs +0 -0
  164. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md014_commands_show_output.rs +0 -0
  165. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md018_no_missing_space_atx.rs +0 -0
  166. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md019_no_multiple_space_atx.rs +0 -0
  167. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md020_no_missing_space_closed_atx.rs +0 -0
  168. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md021_no_multiple_space_closed_atx.rs +0 -0
  169. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md022_blanks_around_headings/md022_config.rs +0 -0
  170. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md022_blanks_around_headings.rs +0 -0
  171. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md023_heading_start_left.rs +0 -0
  172. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md024_no_duplicate_heading/md024_config.rs +0 -0
  173. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md024_no_duplicate_heading.rs +0 -0
  174. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md025_single_title/md025_config.rs +0 -0
  175. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md025_single_title.rs +0 -0
  176. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md026_no_trailing_punctuation/md026_config.rs +0 -0
  177. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md026_no_trailing_punctuation.rs +0 -0
  178. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md027_multiple_spaces_blockquote.rs +0 -0
  179. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md028_no_blanks_blockquote.rs +0 -0
  180. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md029_ordered_list_prefix/md029_config.rs +0 -0
  181. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md029_ordered_list_prefix.rs +0 -0
  182. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md030_list_marker_space/md030_config.rs +0 -0
  183. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md030_list_marker_space.rs +0 -0
  184. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md033_no_inline_html/md033_config.rs +0 -0
  185. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md033_no_inline_html.rs +0 -0
  186. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md034_no_bare_urls.rs +0 -0
  187. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md035_hr_style/md035_config.rs +0 -0
  188. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md035_hr_style.rs +0 -0
  189. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md036_no_emphasis_only_first/md036_config.rs +0 -0
  190. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md036_no_emphasis_only_first.rs +0 -0
  191. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md037_spaces_around_emphasis.rs +0 -0
  192. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md038_no_space_in_code.rs +0 -0
  193. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md039_no_space_in_links.rs +0 -0
  194. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md040_fenced_code_language.rs +0 -0
  195. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md041_first_line_heading.rs +0 -0
  196. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md042_no_empty_links.rs +0 -0
  197. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md043_required_headings.rs +0 -0
  198. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md044_proper_names/md044_config.rs +0 -0
  199. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md044_proper_names.rs +0 -0
  200. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md045_no_alt_text/md045_config.rs +0 -0
  201. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md045_no_alt_text.rs +0 -0
  202. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md046_code_block_style/md046_config.rs +0 -0
  203. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md046_code_block_style.rs +0 -0
  204. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md047_single_trailing_newline.rs +0 -0
  205. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md048_code_fence_style/md048_config.rs +0 -0
  206. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md048_code_fence_style.rs +0 -0
  207. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md049_emphasis_style/md049_config.rs +0 -0
  208. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md049_emphasis_style.rs +0 -0
  209. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md050_strong_style/md050_config.rs +0 -0
  210. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md050_strong_style.rs +0 -0
  211. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md051_link_fragments.rs +0 -0
  212. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md052_reference_links_images.rs +0 -0
  213. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md053_link_image_reference_definitions.rs +0 -0
  214. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md054_link_image_style/md054_config.rs +0 -0
  215. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md054_link_image_style.rs +0 -0
  216. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md055_table_pipe_style/md055_config.rs +0 -0
  217. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md055_table_pipe_style.rs +0 -0
  218. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md056_table_column_count.rs +0 -0
  219. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md057_existing_relative_links/md057_config.rs +0 -0
  220. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/md057_existing_relative_links.rs +0 -0
  221. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/mod.rs +0 -0
  222. {rumdl-0.0.109 → rumdl-0.0.111}/src/rules/strong_style.rs +0 -0
  223. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/ast_utils.rs +0 -0
  224. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/code_block_utils.rs +0 -0
  225. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/document_structure.rs +0 -0
  226. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/early_returns.rs +0 -0
  227. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/element_cache.rs +0 -0
  228. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/emphasis_utils.rs +0 -0
  229. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/fix_utils.rs +0 -0
  230. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/markdown_elements.rs +0 -0
  231. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/range_utils.rs +0 -0
  232. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/regex_cache.rs +0 -0
  233. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/string_interner.rs +0 -0
  234. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/table_utils.rs +0 -0
  235. {rumdl-0.0.109 → rumdl-0.0.111}/src/utils/text_reflow.rs +0 -0
  236. {rumdl-0.0.109 → rumdl-0.0.111}/src/vscode.rs +0 -0
  237. {rumdl-0.0.109 → rumdl-0.0.111}/tests/advanced_integration_tests.rs +0 -0
  238. {rumdl-0.0.109 → rumdl-0.0.111}/tests/character_ranges/additional_tests.rs +0 -0
  239. {rumdl-0.0.109 → rumdl-0.0.111}/tests/character_ranges/basic_tests.rs +0 -0
  240. {rumdl-0.0.109 → rumdl-0.0.111}/tests/character_ranges/comprehensive_tests.rs +0 -0
  241. {rumdl-0.0.109 → rumdl-0.0.111}/tests/character_ranges/extended_tests.rs +0 -0
  242. {rumdl-0.0.109 → rumdl-0.0.111}/tests/character_ranges/mod.rs +0 -0
  243. {rumdl-0.0.109 → rumdl-0.0.111}/tests/character_ranges/unicode_utils.rs +0 -0
  244. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cli_duplication_test.rs +0 -0
  245. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cli_explain_test.rs +0 -0
  246. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cli_flag_precedence_test.rs +0 -0
  247. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cli_integration_tests.rs +0 -0
  248. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cli_lsp_fix_consistency.rs +0 -0
  249. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cli_statistics_test.rs +0 -0
  250. {rumdl-0.0.109 → rumdl-0.0.111}/tests/common/cli_test_utils.rs +0 -0
  251. {rumdl-0.0.109 → rumdl-0.0.111}/tests/common/fixtures.rs +0 -0
  252. {rumdl-0.0.109 → rumdl-0.0.111}/tests/common/mod.rs +0 -0
  253. {rumdl-0.0.109 → rumdl-0.0.111}/tests/common/test_utils.rs +0 -0
  254. {rumdl-0.0.109 → rumdl-0.0.111}/tests/commonmark_compliance_tests.rs +0 -0
  255. {rumdl-0.0.109 → rumdl-0.0.111}/tests/comprehensive_integration_tests.rs +0 -0
  256. {rumdl-0.0.109 → rumdl-0.0.111}/tests/comprehensive_output_format_tests.rs +0 -0
  257. {rumdl-0.0.109 → rumdl-0.0.111}/tests/config_application_tests.rs +0 -0
  258. {rumdl-0.0.109 → rumdl-0.0.111}/tests/config_file_command_test.rs +0 -0
  259. {rumdl-0.0.109 → rumdl-0.0.111}/tests/config_tests.rs +0 -0
  260. {rumdl-0.0.109 → rumdl-0.0.111}/tests/configuration_inheritance_tests.rs +0 -0
  261. {rumdl-0.0.109 → rumdl-0.0.111}/tests/consistency_regression_tests.rs +0 -0
  262. {rumdl-0.0.109 → rumdl-0.0.111}/tests/cross_platform_compatibility_tests.rs +0 -0
  263. {rumdl-0.0.109 → rumdl-0.0.111}/tests/deeply_nested_lists_performance_test.rs +0 -0
  264. {rumdl-0.0.109 → rumdl-0.0.111}/tests/escaped_brackets_test.rs +0 -0
  265. {rumdl-0.0.109 → rumdl-0.0.111}/tests/final_confidence_assessment.rs +0 -0
  266. {rumdl-0.0.109 → rumdl-0.0.111}/tests/init_command_test.rs +0 -0
  267. {rumdl-0.0.109 → rumdl-0.0.111}/tests/init_tests.rs +0 -0
  268. {rumdl-0.0.109 → rumdl-0.0.111}/tests/inline_config_blocks_test.rs +0 -0
  269. {rumdl-0.0.109 → rumdl-0.0.111}/tests/inline_config_test.rs +0 -0
  270. {rumdl-0.0.109 → rumdl-0.0.111}/tests/integration_tests.rs +0 -0
  271. {rumdl-0.0.109 → rumdl-0.0.111}/tests/json_output_test.rs +0 -0
  272. {rumdl-0.0.109 → rumdl-0.0.111}/tests/lib.rs +0 -0
  273. {rumdl-0.0.109 → rumdl-0.0.111}/tests/lsp_editor_integration_tests.rs +0 -0
  274. {rumdl-0.0.109 → rumdl-0.0.111}/tests/lsp_integration_tests.rs +0 -0
  275. {rumdl-0.0.109 → rumdl-0.0.111}/tests/lsp_memory_leak_tests.rs +0 -0
  276. {rumdl-0.0.109 → rumdl-0.0.111}/tests/lsp_tests.rs +0 -0
  277. {rumdl-0.0.109 → rumdl-0.0.111}/tests/malformed_markdown_stress_tests.rs +0 -0
  278. {rumdl-0.0.109 → rumdl-0.0.111}/tests/markdownlint_cli_integration.rs +0 -0
  279. {rumdl-0.0.109 → rumdl-0.0.111}/tests/markdownlint_config_test.rs +0 -0
  280. {rumdl-0.0.109 → rumdl-0.0.111}/tests/markdownlintignore_test.rs +0 -0
  281. {rumdl-0.0.109 → rumdl-0.0.111}/tests/md013_reflow_integration_test.rs +0 -0
  282. {rumdl-0.0.109 → rumdl-0.0.111}/tests/nested_code_block_test.rs +0 -0
  283. {rumdl-0.0.109 → rumdl-0.0.111}/tests/output_format_integration_tests.rs +0 -0
  284. {rumdl-0.0.109 → rumdl-0.0.111}/tests/output_format_tests.rs +0 -0
  285. {rumdl-0.0.109 → rumdl-0.0.111}/tests/perf_check.rs +0 -0
  286. {rumdl-0.0.109 → rumdl-0.0.111}/tests/performance_validation_tests.rs +0 -0
  287. {rumdl-0.0.109 → rumdl-0.0.111}/tests/pyproject_config_tests.rs +0 -0
  288. {rumdl-0.0.109 → rumdl-0.0.111}/tests/python_bindings_test.rs +0 -0
  289. {rumdl-0.0.109 → rumdl-0.0.111}/tests/real_world_repository_tests.rs +0 -0
  290. {rumdl-0.0.109 → rumdl-0.0.111}/tests/regression_prevention_tests.rs +0 -0
  291. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/emphasis_edge_cases_test.rs +0 -0
  292. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/heading_edge_cases_test.rs +0 -0
  293. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/inline_content_edge_cases_test.rs +0 -0
  294. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/link_edge_cases_test.rs +0 -0
  295. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/list_rules_integration_test.rs +0 -0
  296. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md001_test.rs +0 -0
  297. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md001_unicode_test.rs +0 -0
  298. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md002_test.rs +0 -0
  299. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md003_test.rs +0 -0
  300. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md004_test.rs +0 -0
  301. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md005_unicode_test.rs +0 -0
  302. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md006_test.rs +0 -0
  303. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md006_unicode_test.rs +0 -0
  304. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md007_test.rs +0 -0
  305. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md009_test.rs +0 -0
  306. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md010_test.rs +0 -0
  307. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md011_test.rs +0 -0
  308. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md012_test.rs +0 -0
  309. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md013_test.rs +0 -0
  310. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md014_test.rs +0 -0
  311. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md018_test.rs +0 -0
  312. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md019_test.rs +0 -0
  313. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md020_test.rs +0 -0
  314. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md021_test.rs +0 -0
  315. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md022_test.rs +0 -0
  316. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md023_extended_test.rs +0 -0
  317. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md023_test.rs +0 -0
  318. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md024_test.rs +0 -0
  319. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md025_test.rs +0 -0
  320. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md026_test.rs +0 -0
  321. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md027_test.rs +0 -0
  322. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md028_test.rs +0 -0
  323. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md029_test.rs +0 -0
  324. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md029_unicode_test.rs +0 -0
  325. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md030_test.rs +0 -0
  326. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md031_test.rs +0 -0
  327. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md033_extended_test.rs +0 -0
  328. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md033_test.rs +0 -0
  329. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md034_ipv6_test.rs +0 -0
  330. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md034_test.rs +0 -0
  331. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md035_test.rs +0 -0
  332. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md036_test.rs +0 -0
  333. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md037_test.rs +0 -0
  334. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md038_nested_backticks_test.rs +0 -0
  335. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md038_test.rs +0 -0
  336. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md039_test.rs +0 -0
  337. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md040_test.rs +0 -0
  338. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md041_test.rs +0 -0
  339. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md042_test.rs +0 -0
  340. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md043_test.rs +0 -0
  341. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md044_test.rs +0 -0
  342. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md045_test.rs +0 -0
  343. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md046_test.rs +0 -0
  344. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md047_test.rs +0 -0
  345. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md048_test.rs +0 -0
  346. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md049_test.rs +0 -0
  347. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md050_test.rs +0 -0
  348. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md051_test.rs +0 -0
  349. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md051_unicode_test.rs +0 -0
  350. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md052_test.rs +0 -0
  351. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md053_additional_test.rs +0 -0
  352. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md053_proptest.rs +0 -0
  353. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md053_test.rs +0 -0
  354. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md054_test.rs +0 -0
  355. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md054_unicode_test.rs +0 -0
  356. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md055_test.rs +0 -0
  357. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md056_test.rs +0 -0
  358. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md057_test.rs +0 -0
  359. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules/md058_test.rs +0 -0
  360. {rumdl-0.0.109 → rumdl-0.0.111}/tests/rules_mod_test.rs +0 -0
  361. {rumdl-0.0.109 → rumdl-0.0.111}/tests/thread_safety_tests.rs +0 -0
  362. {rumdl-0.0.109 → rumdl-0.0.111}/tests/unicode_edge_case_tests.rs +0 -0
  363. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/blockquote_utils_test.rs +0 -0
  364. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/code_block_utils_extended_test.rs +0 -0
  365. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/code_block_utils_test.rs +0 -0
  366. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/core_utils_test.rs +0 -0
  367. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/front_matter_utils_test.rs +0 -0
  368. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/line_index_test.rs +0 -0
  369. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils/mod.rs +0 -0
  370. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils_markdown_edge_cases.rs +0 -0
  371. {rumdl-0.0.109 → rumdl-0.0.111}/tests/utils_tests.rs +0 -0
  372. {rumdl-0.0.109 → rumdl-0.0.111}/tests/vscode_extension_fixes.rs +0 -0
  373. {rumdl-0.0.109 → rumdl-0.0.111}/tests/vscode_test.rs +0 -0
  374. {rumdl-0.0.109 → rumdl-0.0.111}/tests/vscode_tests.rs +0 -0
  375. {rumdl-0.0.109 → rumdl-0.0.111}/tests/vscode_windows_comprehensive_test.rs +0 -0
  376. {rumdl-0.0.109 → rumdl-0.0.111}/tests/vscode_windows_test.rs +0 -0
@@ -20,6 +20,7 @@ uv = "latest"
20
20
  "cargo:cargo-watch" = "latest"
21
21
  "cargo:maturin" = "latest"
22
22
  "cargo:cargo-binstall" = "latest"
23
+ "cargo:cargo-zigbuild" = "latest" # For building static Linux binaries
23
24
 
24
25
  # Zig for cross-compilation (used by maturin)
25
26
  zig = "0.13"
@@ -104,4 +105,4 @@ make test-quick
104
105
  # rust = "1.87.0"
105
106
  #
106
107
  # [tools.windows]
107
- # rust = "1.87.0"
108
+ # rust = "1.87.0"
@@ -9,6 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
9
9
 
10
10
  ## [0.0.110] - 2025-08-08
11
11
 
12
+ ## [0.0.110] - 2025-08-08
13
+
12
14
  ## [0.0.107] - 2025-08-06
13
15
 
14
16
  ## [0.0.107] - 2025-08-06
@@ -302,6 +304,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
302
304
 
303
305
  [Unreleased]: https://github.com/rvben/rumdl/compare/v0.0.110...HEAD
304
306
  [0.0.110]: https://github.com/rvben/rumdl/compare/v0.0.109...v0.0.110
307
+ [0.0.110]: https://github.com/rvben/rumdl/compare/v0.0.109...v0.0.110
305
308
  [0.0.107]: https://github.com/rvben/rumdl/compare/v0.0.106...v0.0.107
306
309
  [0.0.107]: https://github.com/rvben/rumdl/compare/v0.0.106...v0.0.107
307
310
  [0.0.105]: https://github.com/rvben/rumdl/compare/v0.0.104...v0.0.105
@@ -220,9 +220,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
220
220
 
221
221
  [[package]]
222
222
  name = "cc"
223
- version = "1.2.31"
223
+ version = "1.2.32"
224
224
  source = "registry+https://github.com/rust-lang/crates.io-index"
225
- checksum = "c3a42d84bb6b69d3a8b3eaacf0d88f179e1929695e1ad012b6cf64d9caaa5fd2"
225
+ checksum = "2352e5597e9c544d5e6d9c95190d5d27738ade584fa8db0a16e130e5c2b5296e"
226
226
  dependencies = [
227
227
  "shlex",
228
228
  ]
@@ -1493,7 +1493,7 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
1493
1493
 
1494
1494
  [[package]]
1495
1495
  name = "rumdl"
1496
- version = "0.0.109"
1496
+ version = "0.0.111"
1497
1497
  dependencies = [
1498
1498
  "anyhow",
1499
1499
  "assert_cmd",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "rumdl"
3
- version = "0.0.109"
3
+ version = "0.0.111"
4
4
  edition = "2024"
5
5
  rust-version = "1.88.0"
6
6
  description = "A fast Markdown linter written in Rust (Ru(st) MarkDown Linter)"
@@ -1,4 +1,4 @@
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 update-dependencies update-rust-version pre-release
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 update-dependencies update-rust-version pre-release build-static-linux-x64 build-static-linux-arm64 build-static-all
2
2
 
3
3
  # Development environment setup
4
4
  setup-mise:
@@ -60,6 +60,22 @@ ci-install-mise:
60
60
  build:
61
61
  cargo build --release
62
62
 
63
+ # Static binary builds for Linux (musl)
64
+ build-static-linux-x64:
65
+ @echo "Building static Linux x86_64 binary..."
66
+ rustup target add x86_64-unknown-linux-musl 2>/dev/null || true
67
+ mise exec -- cargo zigbuild --release --target x86_64-unknown-linux-musl
68
+ @echo "Static binary built at: target/x86_64-unknown-linux-musl/release/rumdl"
69
+
70
+ build-static-linux-arm64:
71
+ @echo "Building static Linux ARM64 binary..."
72
+ rustup target add aarch64-unknown-linux-musl 2>/dev/null || true
73
+ mise exec -- cargo zigbuild --release --target aarch64-unknown-linux-musl
74
+ @echo "Static binary built at: target/aarch64-unknown-linux-musl/release/rumdl"
75
+
76
+ build-static-all: build-static-linux-x64 build-static-linux-arm64
77
+ @echo "All static Linux binaries built successfully"
78
+
63
79
  test:
64
80
  cargo nextest run --profile dev
65
81
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: rumdl
3
- Version: 0.0.109
3
+ Version: 0.0.111
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Environment :: Console
6
6
  Classifier: Intended Audience :: Developers
@@ -906,6 +906,19 @@ impl<'a> LintContext<'a> {
906
906
  let content_lines: Vec<&str> = content.lines().collect();
907
907
  let mut lines = Vec::with_capacity(content_lines.len());
908
908
 
909
+ // Detect front matter boundaries FIRST, before any other parsing
910
+ let mut in_front_matter = false;
911
+ let mut front_matter_end = 0;
912
+ if content_lines.first().map(|l| l.trim()) == Some("---") {
913
+ in_front_matter = true;
914
+ for (idx, line) in content_lines.iter().enumerate().skip(1) {
915
+ if line.trim() == "---" {
916
+ front_matter_end = idx;
917
+ break;
918
+ }
919
+ }
920
+ }
921
+
909
922
  for (i, line) in content_lines.iter().enumerate() {
910
923
  let byte_offset = line_offsets.get(i).copied().unwrap_or(0);
911
924
  let indent = line.len() - line.trim_start().len();
@@ -933,8 +946,8 @@ impl<'a> LintContext<'a> {
933
946
  byte_offset >= start && byte_offset < end && (is_multiline || is_fenced || is_indented)
934
947
  });
935
948
 
936
- // Detect list items
937
- let list_item = if !in_code_block && !is_blank {
949
+ // Detect list items (skip if in frontmatter)
950
+ let list_item = if !(in_code_block || is_blank || in_front_matter && i <= front_matter_end) {
938
951
  // Strip blockquote prefix if present for list detection
939
952
  let (line_for_list_check, blockquote_prefix_len) = if let Some(caps) = BLOCKQUOTE_REGEX.captures(line) {
940
953
  let prefix = caps.get(1).unwrap().as_str();
@@ -1011,19 +1024,6 @@ impl<'a> LintContext<'a> {
1011
1024
  });
1012
1025
  }
1013
1026
 
1014
- // Detect front matter boundaries
1015
- let mut in_front_matter = false;
1016
- let mut front_matter_end = 0;
1017
- if content_lines.first().map(|l| l.trim()) == Some("---") {
1018
- in_front_matter = true;
1019
- for (idx, line) in content_lines.iter().enumerate().skip(1) {
1020
- if line.trim() == "---" {
1021
- front_matter_end = idx;
1022
- break;
1023
- }
1024
- }
1025
- }
1026
-
1027
1027
  // Second pass: detect headings (including Setext which needs look-ahead) and blockquotes
1028
1028
  for i in 0..content_lines.len() {
1029
1029
  if lines[i].in_code_block {
@@ -4,6 +4,7 @@
4
4
  use crate::rule::{Fix, LintError, LintResult, LintWarning, Rule, RuleCategory, Severity};
5
5
  use crate::rule_config_serde::RuleConfig;
6
6
  use crate::utils::document_structure::{DocumentStructure, DocumentStructureExtensions};
7
+ use crate::utils::kramdown_utils::is_kramdown_block_attribute;
7
8
  use crate::utils::range_utils::{LineIndex, calculate_line_range};
8
9
  use serde::{Deserialize, Serialize};
9
10
 
@@ -169,8 +170,10 @@ impl Rule for MD031BlanksAroundFences {
169
170
  current_fence_marker = None;
170
171
 
171
172
  // Check for blank line after closing fence
173
+ // Allow Kramdown block attributes if configured
172
174
  if i + 1 < lines.len()
173
175
  && !Self::is_empty_line(lines[i + 1])
176
+ && !is_kramdown_block_attribute(lines[i + 1])
174
177
  && self.should_require_blank_line(i, &lines)
175
178
  {
176
179
  let (start_line, start_col, end_line, end_col) = calculate_line_range(i + 1, lines[i]);
@@ -277,8 +280,10 @@ impl Rule for MD031BlanksAroundFences {
277
280
  current_fence_marker = None;
278
281
 
279
282
  // Add blank line after closing fence if needed
283
+ // Don't add if next line is a Kramdown block attribute
280
284
  if i + 1 < lines.len()
281
285
  && !Self::is_empty_line(lines[i + 1])
286
+ && !is_kramdown_block_attribute(lines[i + 1])
282
287
  && self.should_require_blank_line(i, &lines)
283
288
  {
284
289
  result.push(String::new());
@@ -111,6 +111,7 @@ impl MD032BlanksAroundLists {
111
111
  ctx: &crate::lint_context::LintContext,
112
112
  structure: &DocumentStructure,
113
113
  prev_line_num: usize,
114
+ current_line_num: usize,
114
115
  ) -> bool {
115
116
  let trimmed_prev = prev_line.trim();
116
117
 
@@ -119,6 +120,11 @@ impl MD032BlanksAroundLists {
119
120
  return true;
120
121
  }
121
122
 
123
+ // Always allow nested lists (lists indented within other list items)
124
+ if self.is_nested_list(ctx, prev_line_num, current_line_num) {
125
+ return false;
126
+ }
127
+
122
128
  // Allow lists after headings if configured
123
129
  if self.allow_after_headings && self.is_heading_line_from_context(ctx, prev_line_num - 1) {
124
130
  return false;
@@ -142,6 +148,30 @@ impl MD032BlanksAroundLists {
142
148
  }
143
149
  }
144
150
 
151
+ /// Check if the current list is nested within another list item
152
+ fn is_nested_list(
153
+ &self,
154
+ ctx: &crate::lint_context::LintContext,
155
+ prev_line_num: usize, // 1-indexed
156
+ current_line_num: usize, // 1-indexed
157
+ ) -> bool {
158
+ // Check if current line is indented (typical for nested lists)
159
+ if current_line_num > 0 && current_line_num - 1 < ctx.lines.len() {
160
+ let current_line = &ctx.lines[current_line_num - 1];
161
+ if current_line.indent >= 2 {
162
+ // Check if previous line is a list item or list content
163
+ if prev_line_num > 0 && prev_line_num - 1 < ctx.lines.len() {
164
+ let prev_line = &ctx.lines[prev_line_num - 1];
165
+ // Previous line is a list item or indented content
166
+ if prev_line.list_item.is_some() || prev_line.indent >= 2 {
167
+ return true;
168
+ }
169
+ }
170
+ }
171
+ }
172
+ false
173
+ }
174
+
145
175
  // Convert centralized list blocks to the format expected by perform_checks
146
176
  fn convert_list_blocks(&self, ctx: &crate::lint_context::LintContext) -> Vec<(usize, usize, String)> {
147
177
  let mut blocks: Vec<(usize, usize, String)> = Vec::new();
@@ -291,8 +321,13 @@ impl MD032BlanksAroundLists {
291
321
 
292
322
  // Only require blank lines for content in the same context (same blockquote level)
293
323
  // and when the context actually requires it
294
- let should_require =
295
- self.should_require_blank_line_before(prev_line_str, ctx, structure, prev_line_actual_idx_1);
324
+ let should_require = self.should_require_blank_line_before(
325
+ prev_line_str,
326
+ ctx,
327
+ structure,
328
+ prev_line_actual_idx_1,
329
+ start_line,
330
+ );
296
331
  if !is_prev_excluded && !prev_is_blank && prefixes_match && should_require {
297
332
  // Calculate precise character range for the entire list line that needs a blank line before it
298
333
  let (start_line, start_col, end_line, end_col) =
@@ -488,6 +523,7 @@ impl MD032BlanksAroundLists {
488
523
  ctx,
489
524
  structure,
490
525
  prev_line_actual_idx_1,
526
+ start_line,
491
527
  );
492
528
  if !is_prev_excluded
493
529
  && !is_blank_in_context(lines[prev_line_actual_idx_0])
@@ -1,5 +1,6 @@
1
1
  use crate::rule::{Fix, LintError, LintResult, LintWarning, Rule, Severity};
2
2
  use crate::rule_config_serde::RuleConfig;
3
+ use crate::utils::kramdown_utils::is_kramdown_block_attribute;
3
4
  use crate::utils::range_utils::LineIndex;
4
5
  use crate::utils::table_utils::TableUtils;
5
6
  use serde::{Deserialize, Serialize};
@@ -149,31 +150,41 @@ impl Rule for MD058BlanksAroundTables {
149
150
 
150
151
  // Check for sufficient blank lines after table
151
152
  if table_block.end_line < lines.len() - 1 {
152
- let blank_lines_after = self.count_blank_lines_after(&lines, table_block.end_line);
153
- if blank_lines_after < self.config.minimum_after {
154
- let needed = self.config.minimum_after - blank_lines_after;
155
- let message = if self.config.minimum_after == 1 {
156
- "Missing blank line after table".to_string()
157
- } else {
158
- format!("Missing {needed} blank lines after table")
159
- };
153
+ // Check if the next line is a Kramdown block attribute
154
+ let next_line_is_attribute = if table_block.end_line + 1 < lines.len() {
155
+ is_kramdown_block_attribute(lines[table_block.end_line + 1])
156
+ } else {
157
+ false
158
+ };
160
159
 
161
- warnings.push(LintWarning {
162
- rule_name: Some(self.name()),
163
- message,
164
- line: table_block.end_line + 1,
165
- column: lines[table_block.end_line].len() + 1,
166
- end_line: table_block.end_line + 1,
167
- end_column: lines[table_block.end_line].len() + 2,
168
- severity: Severity::Warning,
169
- fix: Some(Fix {
170
- range: _line_index.line_col_to_byte_range(
171
- table_block.end_line + 1,
172
- lines[table_block.end_line].len() + 1,
173
- ),
174
- replacement: format!("{}{}", lines[table_block.end_line], "\n".repeat(needed)),
175
- }),
176
- });
160
+ // Skip check if next line is a block attribute
161
+ if !next_line_is_attribute {
162
+ let blank_lines_after = self.count_blank_lines_after(&lines, table_block.end_line);
163
+ if blank_lines_after < self.config.minimum_after {
164
+ let needed = self.config.minimum_after - blank_lines_after;
165
+ let message = if self.config.minimum_after == 1 {
166
+ "Missing blank line after table".to_string()
167
+ } else {
168
+ format!("Missing {needed} blank lines after table")
169
+ };
170
+
171
+ warnings.push(LintWarning {
172
+ rule_name: Some(self.name()),
173
+ message,
174
+ line: table_block.end_line + 1,
175
+ column: lines[table_block.end_line].len() + 1,
176
+ end_line: table_block.end_line + 1,
177
+ end_column: lines[table_block.end_line].len() + 2,
178
+ severity: Severity::Warning,
179
+ fix: Some(Fix {
180
+ range: _line_index.line_col_to_byte_range(
181
+ table_block.end_line + 1,
182
+ lines[table_block.end_line].len() + 1,
183
+ ),
184
+ replacement: format!("{}{}", lines[table_block.end_line], "\n".repeat(needed)),
185
+ }),
186
+ });
187
+ }
177
188
  }
178
189
  }
179
190
  }
@@ -0,0 +1,94 @@
1
+ //! Utilities for handling Kramdown-specific syntax
2
+ //!
3
+ //! Kramdown is a superset of Markdown that adds additional features like
4
+ //! Inline Attribute Lists (IAL) for adding attributes to elements.
5
+
6
+ /// Check if a line is a Kramdown block attribute (IAL - Inline Attribute List)
7
+ ///
8
+ /// Kramdown IAL syntax allows adding attributes to block elements:
9
+ /// - `{:.class}` - CSS class
10
+ /// - `{:#id}` - Element ID
11
+ /// - `{:attribute="value"}` - Generic attributes
12
+ /// - `{:.class #id attribute="value"}` - Combinations
13
+ ///
14
+ /// # Examples
15
+ ///
16
+ /// ```
17
+ /// use rumdl::utils::kramdown_utils::is_kramdown_block_attribute;
18
+ ///
19
+ /// assert!(is_kramdown_block_attribute("{:.wrap}"));
20
+ /// assert!(is_kramdown_block_attribute("{:#my-id}"));
21
+ /// assert!(is_kramdown_block_attribute("{:.class #id}"));
22
+ /// assert!(is_kramdown_block_attribute("{:style=\"color: red\"}"));
23
+ ///
24
+ /// assert!(!is_kramdown_block_attribute("{just text}"));
25
+ /// assert!(!is_kramdown_block_attribute("{}"));
26
+ /// assert!(!is_kramdown_block_attribute("{"));
27
+ /// ```
28
+ pub fn is_kramdown_block_attribute(line: &str) -> bool {
29
+ let trimmed = line.trim();
30
+
31
+ // Must start with { and end with }
32
+ if !trimmed.starts_with('{') || !trimmed.ends_with('}') || trimmed.len() < 3 {
33
+ return false;
34
+ }
35
+
36
+ // Check if it matches Kramdown IAL patterns
37
+ // Valid patterns start with {: or {# or {.
38
+ let second_char = trimmed.chars().nth(1);
39
+ matches!(second_char, Some(':') | Some('#') | Some('.'))
40
+ }
41
+
42
+ #[cfg(test)]
43
+ mod tests {
44
+ use super::*;
45
+
46
+ #[test]
47
+ fn test_kramdown_class_attributes() {
48
+ assert!(is_kramdown_block_attribute("{:.wrap}"));
49
+ assert!(is_kramdown_block_attribute("{:.class-name}"));
50
+ assert!(is_kramdown_block_attribute("{:.multiple .classes}"));
51
+ }
52
+
53
+ #[test]
54
+ fn test_kramdown_id_attributes() {
55
+ assert!(is_kramdown_block_attribute("{:#my-id}"));
56
+ assert!(is_kramdown_block_attribute("{:#section-1}"));
57
+ }
58
+
59
+ #[test]
60
+ fn test_kramdown_generic_attributes() {
61
+ assert!(is_kramdown_block_attribute("{:style=\"color: red\"}"));
62
+ assert!(is_kramdown_block_attribute("{:data-value=\"123\"}"));
63
+ }
64
+
65
+ #[test]
66
+ fn test_kramdown_combined_attributes() {
67
+ assert!(is_kramdown_block_attribute("{:.class #id}"));
68
+ assert!(is_kramdown_block_attribute("{:#id .class style=\"color: blue\"}"));
69
+ assert!(is_kramdown_block_attribute("{:.wrap #my-code .highlight}"));
70
+ }
71
+
72
+ #[test]
73
+ fn test_non_kramdown_braces() {
74
+ assert!(!is_kramdown_block_attribute("{just some text}"));
75
+ assert!(!is_kramdown_block_attribute("{not kramdown}"));
76
+ assert!(!is_kramdown_block_attribute("{ spaces }"));
77
+ }
78
+
79
+ #[test]
80
+ fn test_edge_cases() {
81
+ assert!(!is_kramdown_block_attribute("{}"));
82
+ assert!(!is_kramdown_block_attribute("{"));
83
+ assert!(!is_kramdown_block_attribute("}"));
84
+ assert!(!is_kramdown_block_attribute(""));
85
+ assert!(!is_kramdown_block_attribute("not braces"));
86
+ }
87
+
88
+ #[test]
89
+ fn test_whitespace_handling() {
90
+ assert!(is_kramdown_block_attribute(" {:.wrap} "));
91
+ assert!(is_kramdown_block_attribute("\t{:#id}\t"));
92
+ assert!(is_kramdown_block_attribute(" {:.class #id} "));
93
+ }
94
+ }
@@ -9,6 +9,7 @@ pub mod early_returns;
9
9
  pub mod element_cache;
10
10
  pub mod emphasis_utils;
11
11
  pub mod fix_utils;
12
+ pub mod kramdown_utils;
12
13
  pub mod markdown_elements;
13
14
  pub mod range_utils;
14
15
  pub mod regex_cache;
@@ -32,6 +32,39 @@ fn test_valid_ordered_list() {
32
32
  assert!(result.is_empty());
33
33
  }
34
34
 
35
+ #[test]
36
+ fn test_frontmatter_yaml_lists_not_detected() {
37
+ // Test for issue #35 - YAML lists in frontmatter should not be detected as Markdown lists
38
+ let rule = MD005ListIndent;
39
+ let content = "\
40
+ ---
41
+ layout: post
42
+ title: \"title\"
43
+ creator:
44
+ - 'user1'
45
+ - 'user2'
46
+ creator_num:
47
+ - 1253217
48
+ - 1615089
49
+ tags: [tag1, tag2, tag3]
50
+ ---
51
+
52
+ # TITLE
53
+
54
+ ## Heading
55
+
56
+ Whatever
57
+
58
+ And a list:
59
+
60
+ - Item1
61
+ - Item2";
62
+ let ctx = LintContext::new(content);
63
+ let result = rule.check(&ctx).unwrap();
64
+ // Should not flag YAML lists in frontmatter
65
+ assert!(result.is_empty(), "MD005 should not check lists in frontmatter");
66
+ }
67
+
35
68
  #[test]
36
69
  fn test_invalid_unordered_indent() {
37
70
  let rule = MD005ListIndent;
@@ -0,0 +1,125 @@
1
+ use rumdl::lint_context::LintContext;
2
+ use rumdl::rule::Rule;
3
+ use rumdl::rules::MD031BlanksAroundFences;
4
+
5
+ #[test]
6
+ fn test_kramdown_block_attributes_auto_detected() {
7
+ // Kramdown attributes should be auto-detected without configuration
8
+ let rule = MD031BlanksAroundFences::default();
9
+ let content = r#"# Title
10
+
11
+ ```bash
12
+ echo hello
13
+ ```
14
+ {:.wrap}
15
+
16
+ Some text"#;
17
+ let ctx = LintContext::new(content);
18
+ let result = rule.check(&ctx).unwrap();
19
+ assert!(result.is_empty(), "Should auto-detect Kramdown block attributes");
20
+ }
21
+
22
+ #[test]
23
+ fn test_non_kramdown_braces_still_flagged() {
24
+ // Lines with braces that don't match Kramdown IAL syntax should still be flagged
25
+ let rule = MD031BlanksAroundFences::default();
26
+ let content = r#"# Title
27
+
28
+ ```bash
29
+ echo hello
30
+ ```
31
+ {not kramdown}
32
+
33
+ Some text"#;
34
+ let ctx = LintContext::new(content);
35
+ let result = rule.check(&ctx).unwrap();
36
+ assert_eq!(result.len(), 1, "Should flag non-Kramdown brace lines");
37
+ assert!(result[0].message.contains("No blank line after"));
38
+ }
39
+
40
+ #[test]
41
+ fn test_kramdown_css_class_variants() {
42
+ // Test various Kramdown attribute syntax variations
43
+ let rule = MD031BlanksAroundFences::default();
44
+
45
+ // Class attribute
46
+ let content1 = r#"```bash
47
+ echo hello
48
+ ```
49
+ {:.wrap}"#;
50
+ let ctx = LintContext::new(content1);
51
+ assert!(rule.check(&ctx).unwrap().is_empty());
52
+
53
+ // ID attribute
54
+ let content2 = r#"```bash
55
+ echo hello
56
+ ```
57
+ {:#my-code}"#;
58
+ let ctx = LintContext::new(content2);
59
+ assert!(rule.check(&ctx).unwrap().is_empty());
60
+
61
+ // Multiple attributes
62
+ let content3 = r#"```bash
63
+ echo hello
64
+ ```
65
+ {:.wrap #my-code .highlight}"#;
66
+ let ctx = LintContext::new(content3);
67
+ assert!(rule.check(&ctx).unwrap().is_empty());
68
+ }
69
+
70
+ #[test]
71
+ fn test_kramdown_no_blank_after_attribute() {
72
+ // Kramdown attributes don't need blank lines after them
73
+ let rule = MD031BlanksAroundFences::default();
74
+ let content = r#"```bash
75
+ echo hello
76
+ ```
77
+ {:.wrap}
78
+ Some text immediately after"#;
79
+ let ctx = LintContext::new(content);
80
+ let result = rule.check(&ctx).unwrap();
81
+ // This should not flag since the Kramdown attribute is auto-detected
82
+ assert!(result.is_empty(), "Should auto-detect Kramdown attributes");
83
+ }
84
+
85
+ #[test]
86
+ fn test_normal_code_blocks_still_checked() {
87
+ // Normal code blocks without attributes should still be checked
88
+ let rule = MD031BlanksAroundFences::default();
89
+ let content = r#"# Title
90
+
91
+ ```bash
92
+ echo hello
93
+ ```
94
+ Some text immediately after"#;
95
+ let ctx = LintContext::new(content);
96
+ let result = rule.check(&ctx).unwrap();
97
+ assert_eq!(
98
+ result.len(),
99
+ 1,
100
+ "Should still flag missing blank line for normal code blocks"
101
+ );
102
+ }
103
+
104
+ #[test]
105
+ fn test_fix_preserves_kramdown_attributes() {
106
+ let rule = MD031BlanksAroundFences::default();
107
+ let content = r#"Text before
108
+ ```bash
109
+ echo hello
110
+ ```
111
+ {:.wrap}
112
+ Text after"#;
113
+ let ctx = LintContext::new(content);
114
+ let fixed = rule.fix(&ctx).unwrap();
115
+
116
+ // Should add blank line before the code block but not after (due to attribute)
117
+ let expected = r#"Text before
118
+
119
+ ```bash
120
+ echo hello
121
+ ```
122
+ {:.wrap}
123
+ Text after"#;
124
+ assert_eq!(fixed, expected);
125
+ }
@@ -171,16 +171,67 @@ fn test_multiple_lists() {
171
171
 
172
172
  #[test]
173
173
  fn test_nested_lists() {
174
+ // Nested lists should not require blank lines between parent and child items
174
175
  let rule = MD032BlanksAroundLists::default();
175
176
  let content = "Text\n* Item 1\n * Nested 1\n * Nested 2\n* Item 2\nText";
176
177
  let ctx = LintContext::new(content);
177
178
  let result = rule.check(&ctx).unwrap();
178
- assert_eq!(result.len(), 2);
179
+ // Should only warn about missing blank lines around the outer list, not the nested items
180
+ assert_eq!(
181
+ result.len(),
182
+ 2,
183
+ "Should only warn about outer list boundaries, not nested items"
184
+ );
179
185
  let fixed = rule.fix(&ctx).unwrap();
180
186
  let _ctx_fixed = LintContext::new(&fixed);
181
187
  assert_eq!(fixed, "Text\n\n* Item 1\n * Nested 1\n * Nested 2\n* Item 2\n\nText");
182
188
  }
183
189
 
190
+ #[test]
191
+ fn test_nested_lists_with_strict_mode() {
192
+ // Even in strict mode, nested lists are a standard Markdown pattern and shouldn't require blank lines
193
+ let rule = MD032BlanksAroundLists::strict();
194
+ let content = "Text\n\n* Item 1\n * Nested 1\n * Nested 2\n* Item 2\n\nText";
195
+ let ctx = LintContext::new(content);
196
+ let result = rule.check(&ctx).unwrap();
197
+ // Even strict mode should not warn about nested lists - this is standard Markdown
198
+ assert!(
199
+ result.is_empty(),
200
+ "Nested lists are standard Markdown and shouldn't trigger warnings even in strict mode"
201
+ );
202
+ }
203
+
204
+ #[test]
205
+ fn test_deeply_nested_lists() {
206
+ // Test multiple levels of nesting
207
+ let rule = MD032BlanksAroundLists::default();
208
+ let content = "## Section\n\n* Level 1\n * Level 2\n * Level 3\n * Level 4\n * Back to Level 2\n* Back to Level 1\n\nText";
209
+ let ctx = LintContext::new(content);
210
+ let result = rule.check(&ctx).unwrap();
211
+ // Should not warn about nested list transitions
212
+ assert!(result.is_empty(), "Should not warn about deeply nested lists");
213
+ }
214
+
215
+ #[test]
216
+ fn test_nested_ordered_lists() {
217
+ // Test nested ordered lists
218
+ let rule = MD032BlanksAroundLists::default();
219
+ let content = "## Section\n\n1. First item\n 1. Sub item 1.1\n 2. Sub item 1.2\n2. Second item\n 1. Sub item 2.1\n\nText";
220
+ let ctx = LintContext::new(content);
221
+ let result = rule.check(&ctx).unwrap();
222
+ assert!(result.is_empty(), "Should not warn about nested ordered lists");
223
+ }
224
+
225
+ #[test]
226
+ fn test_mixed_nested_list_types() {
227
+ // Test mixing ordered and unordered lists in nesting
228
+ let rule = MD032BlanksAroundLists::default();
229
+ let content = "## Section\n\n1. Ordered item\n - Unordered sub-item\n - Another unordered sub-item\n2. Another ordered item\n * Different unordered marker\n\nText";
230
+ let ctx = LintContext::new(content);
231
+ let result = rule.check(&ctx).unwrap();
232
+ assert!(result.is_empty(), "Should not warn about mixed nested list types");
233
+ }
234
+
184
235
  #[test]
185
236
  fn test_mixed_list_types() {
186
237
  let rule = MD032BlanksAroundLists::default();