markdown-prose-hooks 0.0.1__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.
Files changed (434) hide show
  1. markdown_prose_hooks-0.0.1/.codespellrc +57 -0
  2. markdown_prose_hooks-0.0.1/.git-blame-ignore-revs +6 -0
  3. markdown_prose_hooks-0.0.1/.gitattributes +50 -0
  4. markdown_prose_hooks-0.0.1/.github/dependabot.yml +85 -0
  5. markdown_prose_hooks-0.0.1/.github/workflows/CI.yml +234 -0
  6. markdown_prose_hooks-0.0.1/.github/workflows/bot-automerge-disarm.yml +107 -0
  7. markdown_prose_hooks-0.0.1/.github/workflows/bot-automerge.yml +390 -0
  8. markdown_prose_hooks-0.0.1/.github/workflows/release.yml +193 -0
  9. markdown_prose_hooks-0.0.1/.gitignore +1055 -0
  10. markdown_prose_hooks-0.0.1/.gitlint +141 -0
  11. markdown_prose_hooks-0.0.1/.markdownlint-cli2.jsonc +9 -0
  12. markdown_prose_hooks-0.0.1/.markdownlint.yml +10 -0
  13. markdown_prose_hooks-0.0.1/.markdownlintignore +8 -0
  14. markdown_prose_hooks-0.0.1/.pre-commit-config.yaml +164 -0
  15. markdown_prose_hooks-0.0.1/.pre-commit-hooks.yaml +62 -0
  16. markdown_prose_hooks-0.0.1/.prettierignore +4 -0
  17. markdown_prose_hooks-0.0.1/.prettierrc +4 -0
  18. markdown_prose_hooks-0.0.1/.unwrapignore +14 -0
  19. markdown_prose_hooks-0.0.1/.yamllint +17 -0
  20. markdown_prose_hooks-0.0.1/CLAUDE.md +75 -0
  21. markdown_prose_hooks-0.0.1/CONTRIBUTING.md +88 -0
  22. markdown_prose_hooks-0.0.1/Cargo.lock +7 -0
  23. markdown_prose_hooks-0.0.1/Cargo.toml +49 -0
  24. markdown_prose_hooks-0.0.1/LICENSE +21 -0
  25. markdown_prose_hooks-0.0.1/Makefile +80 -0
  26. markdown_prose_hooks-0.0.1/PKG-INFO +233 -0
  27. markdown_prose_hooks-0.0.1/README.md +210 -0
  28. markdown_prose_hooks-0.0.1/_typos.toml +9 -0
  29. markdown_prose_hooks-0.0.1/action.yml +191 -0
  30. markdown_prose_hooks-0.0.1/cliff.toml +127 -0
  31. markdown_prose_hooks-0.0.1/corpus/README.md +59 -0
  32. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-does-not-absorb-the-prose-beneath-it/case.txt +4 -0
  33. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-does-not-absorb-the-prose-beneath-it/expected.md +3 -0
  34. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-does-not-absorb-the-prose-beneath-it/input.md +4 -0
  35. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-indented-under-a-list-item-is-preserved/case.txt +4 -0
  36. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-indented-under-a-list-item-is-preserved/expected.md +3 -0
  37. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-indented-under-a-list-item-is-preserved/input.md +3 -0
  38. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-keeps-every-link-on-its-own-line/case.txt +4 -0
  39. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-keeps-every-link-on-its-own-line/expected.md +3 -0
  40. markdown_prose_hooks-0.0.1/corpus/cases/a-badge-block-keeps-every-link-on-its-own-line/input.md +3 -0
  41. markdown_prose_hooks-0.0.1/corpus/cases/a-blockquoted-badge-block-keeps-its-links-on-their-lines/case.txt +4 -0
  42. markdown_prose_hooks-0.0.1/corpus/cases/a-blockquoted-badge-block-keeps-its-links-on-their-lines/expected.md +3 -0
  43. markdown_prose_hooks-0.0.1/corpus/cases/a-blockquoted-badge-block-keeps-its-links-on-their-lines/input.md +3 -0
  44. markdown_prose_hooks-0.0.1/corpus/cases/a-deeper-quoted-badge-line-stays-in-the-run/case.txt +4 -0
  45. markdown_prose_hooks-0.0.1/corpus/cases/a-deeper-quoted-badge-line-stays-in-the-run/expected.md +3 -0
  46. markdown_prose_hooks-0.0.1/corpus/cases/a-deeper-quoted-badge-line-stays-in-the-run/input.md +4 -0
  47. markdown_prose_hooks-0.0.1/corpus/cases/a-lazily-continued-badge-block-is-preserved/case.txt +4 -0
  48. markdown_prose_hooks-0.0.1/corpus/cases/a-lazily-continued-badge-block-is-preserved/expected.md +2 -0
  49. markdown_prose_hooks-0.0.1/corpus/cases/a-lazily-continued-badge-block-is-preserved/input.md +2 -0
  50. markdown_prose_hooks-0.0.1/corpus/cases/a-line-separator-is-not-a-line-boundary/case.txt +4 -0
  51. markdown_prose_hooks-0.0.1/corpus/cases/a-line-separator-is-not-a-line-boundary/expected.md +3 -0
  52. markdown_prose_hooks-0.0.1/corpus/cases/a-line-separator-is-not-a-line-boundary/input.md +3 -0
  53. markdown_prose_hooks-0.0.1/corpus/cases/a-non-ascii-digit-does-not-open-a-list/case.txt +4 -0
  54. markdown_prose_hooks-0.0.1/corpus/cases/a-non-ascii-digit-does-not-open-a-list/expected.md +2 -0
  55. markdown_prose_hooks-0.0.1/corpus/cases/a-non-ascii-digit-does-not-open-a-list/input.md +2 -0
  56. markdown_prose_hooks-0.0.1/corpus/cases/a-pipe-inside-a-double-backtick-span-still-unwraps/case.txt +4 -0
  57. markdown_prose_hooks-0.0.1/corpus/cases/a-pipe-inside-a-double-backtick-span-still-unwraps/expected.md +1 -0
  58. markdown_prose_hooks-0.0.1/corpus/cases/a-pipe-inside-a-double-backtick-span-still-unwraps/input.md +2 -0
  59. markdown_prose_hooks-0.0.1/corpus/cases/a-run-does-not-reach-back-over-a-quote-boundary/case.txt +4 -0
  60. markdown_prose_hooks-0.0.1/corpus/cases/a-run-does-not-reach-back-over-a-quote-boundary/expected.md +2 -0
  61. markdown_prose_hooks-0.0.1/corpus/cases/a-run-does-not-reach-back-over-a-quote-boundary/input.md +3 -0
  62. markdown_prose_hooks-0.0.1/corpus/cases/a-table-directly-after-a-paragraph-is-untouched/case.txt +4 -0
  63. markdown_prose_hooks-0.0.1/corpus/cases/a-table-directly-after-a-paragraph-is-untouched/expected.md +5 -0
  64. markdown_prose_hooks-0.0.1/corpus/cases/a-table-directly-after-a-paragraph-is-untouched/input.md +6 -0
  65. markdown_prose_hooks-0.0.1/corpus/cases/a-table-row-whose-cells-hold-code-spans-is-untouched/case.txt +4 -0
  66. markdown_prose_hooks-0.0.1/corpus/cases/a-table-row-whose-cells-hold-code-spans-is-untouched/expected.md +3 -0
  67. markdown_prose_hooks-0.0.1/corpus/cases/a-table-row-whose-cells-hold-code-spans-is-untouched/input.md +3 -0
  68. markdown_prose_hooks-0.0.1/corpus/cases/a-vertical-tab-is-not-a-line-boundary/case.txt +4 -0
  69. markdown_prose_hooks-0.0.1/corpus/cases/a-vertical-tab-is-not-a-line-boundary/expected.md +3 -0
  70. markdown_prose_hooks-0.0.1/corpus/cases/a-vertical-tab-is-not-a-line-boundary/input.md +3 -0
  71. markdown_prose_hooks-0.0.1/corpus/cases/a-wrapped-middle-label-value-joins-only-its-own-row/case.txt +4 -0
  72. markdown_prose_hooks-0.0.1/corpus/cases/a-wrapped-middle-label-value-joins-only-its-own-row/expected.md +3 -0
  73. markdown_prose_hooks-0.0.1/corpus/cases/a-wrapped-middle-label-value-joins-only-its-own-row/input.md +4 -0
  74. markdown_prose_hooks-0.0.1/corpus/cases/an-unterminated-backtick-run-stays-structural/case.txt +4 -0
  75. markdown_prose_hooks-0.0.1/corpus/cases/an-unterminated-backtick-run-stays-structural/expected.md +2 -0
  76. markdown_prose_hooks-0.0.1/corpus/cases/an-unterminated-backtick-run-stays-structural/input.md +2 -0
  77. markdown_prose_hooks-0.0.1/corpus/cases/bare-pipe-stays-wrapped/case.txt +4 -0
  78. markdown_prose_hooks-0.0.1/corpus/cases/bare-pipe-stays-wrapped/expected.md +2 -0
  79. markdown_prose_hooks-0.0.1/corpus/cases/bare-pipe-stays-wrapped/input.md +2 -0
  80. markdown_prose_hooks-0.0.1/corpus/cases/blank-line-inside-raw-html-block-is-preserved/case.txt +4 -0
  81. markdown_prose_hooks-0.0.1/corpus/cases/blank-line-inside-raw-html-block-is-preserved/expected.md +6 -0
  82. markdown_prose_hooks-0.0.1/corpus/cases/blank-line-inside-raw-html-block-is-preserved/input.md +6 -0
  83. markdown_prose_hooks-0.0.1/corpus/cases/blank-line-separates-paragraphs/case.txt +4 -0
  84. markdown_prose_hooks-0.0.1/corpus/cases/blank-line-separates-paragraphs/expected.md +3 -0
  85. markdown_prose_hooks-0.0.1/corpus/cases/blank-line-separates-paragraphs/input.md +5 -0
  86. markdown_prose_hooks-0.0.1/corpus/cases/bold-label-rows-are-preserved/case.txt +4 -0
  87. markdown_prose_hooks-0.0.1/corpus/cases/bold-label-rows-are-preserved/expected.md +2 -0
  88. markdown_prose_hooks-0.0.1/corpus/cases/bold-label-rows-are-preserved/input.md +2 -0
  89. markdown_prose_hooks-0.0.1/corpus/cases/cdata-inside-blockquote-is-preserved/case.txt +4 -0
  90. markdown_prose_hooks-0.0.1/corpus/cases/cdata-inside-blockquote-is-preserved/expected.md +4 -0
  91. markdown_prose_hooks-0.0.1/corpus/cases/cdata-inside-blockquote-is-preserved/input.md +4 -0
  92. markdown_prose_hooks-0.0.1/corpus/cases/crlf-line-endings-survive/case.txt +4 -0
  93. markdown_prose_hooks-0.0.1/corpus/cases/crlf-line-endings-survive/expected.md +1 -0
  94. markdown_prose_hooks-0.0.1/corpus/cases/crlf-line-endings-survive/input.md +2 -0
  95. markdown_prose_hooks-0.0.1/corpus/cases/fenced-code-block-is-untouched/case.txt +4 -0
  96. markdown_prose_hooks-0.0.1/corpus/cases/fenced-code-block-is-untouched/expected.md +4 -0
  97. markdown_prose_hooks-0.0.1/corpus/cases/fenced-code-block-is-untouched/input.md +4 -0
  98. markdown_prose_hooks-0.0.1/corpus/cases/fenced-code-inside-blockquote-is-preserved/case.txt +4 -0
  99. markdown_prose_hooks-0.0.1/corpus/cases/fenced-code-inside-blockquote-is-preserved/expected.md +4 -0
  100. markdown_prose_hooks-0.0.1/corpus/cases/fenced-code-inside-blockquote-is-preserved/input.md +4 -0
  101. markdown_prose_hooks-0.0.1/corpus/cases/flat-list-is-untouched/case.txt +4 -0
  102. markdown_prose_hooks-0.0.1/corpus/cases/flat-list-is-untouched/expected.md +3 -0
  103. markdown_prose_hooks-0.0.1/corpus/cases/flat-list-is-untouched/input.md +3 -0
  104. markdown_prose_hooks-0.0.1/corpus/cases/gfm-table-untouched/case.txt +4 -0
  105. markdown_prose_hooks-0.0.1/corpus/cases/gfm-table-untouched/expected.md +4 -0
  106. markdown_prose_hooks-0.0.1/corpus/cases/gfm-table-untouched/input.md +4 -0
  107. markdown_prose_hooks-0.0.1/corpus/cases/github-alert-marker-stays-on-its-own-line/case.txt +4 -0
  108. markdown_prose_hooks-0.0.1/corpus/cases/github-alert-marker-stays-on-its-own-line/expected.md +2 -0
  109. markdown_prose_hooks-0.0.1/corpus/cases/github-alert-marker-stays-on-its-own-line/input.md +3 -0
  110. markdown_prose_hooks-0.0.1/corpus/cases/hard-break-line-is-preserved/case.txt +4 -0
  111. markdown_prose_hooks-0.0.1/corpus/cases/hard-break-line-is-preserved/expected.md +2 -0
  112. markdown_prose_hooks-0.0.1/corpus/cases/hard-break-line-is-preserved/input.md +2 -0
  113. markdown_prose_hooks-0.0.1/corpus/cases/hard-break-preserved/case.txt +4 -0
  114. markdown_prose_hooks-0.0.1/corpus/cases/hard-break-preserved/expected.md +2 -0
  115. markdown_prose_hooks-0.0.1/corpus/cases/hard-break-preserved/input.md +2 -0
  116. markdown_prose_hooks-0.0.1/corpus/cases/html-cdata-preserved/case.txt +4 -0
  117. markdown_prose_hooks-0.0.1/corpus/cases/html-cdata-preserved/expected.md +4 -0
  118. markdown_prose_hooks-0.0.1/corpus/cases/html-cdata-preserved/input.md +4 -0
  119. markdown_prose_hooks-0.0.1/corpus/cases/html-declaration-preserved/case.txt +4 -0
  120. markdown_prose_hooks-0.0.1/corpus/cases/html-declaration-preserved/expected.md +4 -0
  121. markdown_prose_hooks-0.0.1/corpus/cases/html-declaration-preserved/input.md +4 -0
  122. markdown_prose_hooks-0.0.1/corpus/cases/html-processing-instruction-preserved/case.txt +4 -0
  123. markdown_prose_hooks-0.0.1/corpus/cases/html-processing-instruction-preserved/expected.md +4 -0
  124. markdown_prose_hooks-0.0.1/corpus/cases/html-processing-instruction-preserved/input.md +4 -0
  125. markdown_prose_hooks-0.0.1/corpus/cases/indented-code-inside-blockquote-is-preserved/case.txt +4 -0
  126. markdown_prose_hooks-0.0.1/corpus/cases/indented-code-inside-blockquote-is-preserved/expected.md +2 -0
  127. markdown_prose_hooks-0.0.1/corpus/cases/indented-code-inside-blockquote-is-preserved/input.md +2 -0
  128. markdown_prose_hooks-0.0.1/corpus/cases/inline-speaker-turns-keep-their-boundaries/case.txt +4 -0
  129. markdown_prose_hooks-0.0.1/corpus/cases/inline-speaker-turns-keep-their-boundaries/expected.md +2 -0
  130. markdown_prose_hooks-0.0.1/corpus/cases/inline-speaker-turns-keep-their-boundaries/input.md +4 -0
  131. markdown_prose_hooks-0.0.1/corpus/cases/label-row-wrapped-tail/case.txt +4 -0
  132. markdown_prose_hooks-0.0.1/corpus/cases/label-row-wrapped-tail/expected.md +3 -0
  133. markdown_prose_hooks-0.0.1/corpus/cases/label-row-wrapped-tail/input.md +4 -0
  134. markdown_prose_hooks-0.0.1/corpus/cases/lettered-subitems-remain-structural/case.txt +4 -0
  135. markdown_prose_hooks-0.0.1/corpus/cases/lettered-subitems-remain-structural/expected.md +3 -0
  136. markdown_prose_hooks-0.0.1/corpus/cases/lettered-subitems-remain-structural/input.md +3 -0
  137. markdown_prose_hooks-0.0.1/corpus/cases/longer-backtick-fence-is-untouched/case.txt +4 -0
  138. markdown_prose_hooks-0.0.1/corpus/cases/longer-backtick-fence-is-untouched/expected.md +4 -0
  139. markdown_prose_hooks-0.0.1/corpus/cases/longer-backtick-fence-is-untouched/input.md +4 -0
  140. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-block-is-preserved/case.txt +4 -0
  141. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-block-is-preserved/expected.md +8 -0
  142. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-block-is-preserved/input.md +10 -0
  143. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-comment-inside-blockquote-is-preserved/case.txt +4 -0
  144. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-comment-inside-blockquote-is-preserved/expected.md +4 -0
  145. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-comment-inside-blockquote-is-preserved/input.md +4 -0
  146. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-comment-is-preserved/case.txt +4 -0
  147. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-comment-is-preserved/expected.md +8 -0
  148. markdown_prose_hooks-0.0.1/corpus/cases/multiline-html-comment-is-preserved/input.md +10 -0
  149. markdown_prose_hooks-0.0.1/corpus/cases/multiword-speaker-turns-keep-their-boundaries/case.txt +4 -0
  150. markdown_prose_hooks-0.0.1/corpus/cases/multiword-speaker-turns-keep-their-boundaries/expected.md +2 -0
  151. markdown_prose_hooks-0.0.1/corpus/cases/multiword-speaker-turns-keep-their-boundaries/input.md +4 -0
  152. markdown_prose_hooks-0.0.1/corpus/cases/nested-list-is-preserved/case.txt +4 -0
  153. markdown_prose_hooks-0.0.1/corpus/cases/nested-list-is-preserved/expected.md +2 -0
  154. markdown_prose_hooks-0.0.1/corpus/cases/nested-list-is-preserved/input.md +4 -0
  155. markdown_prose_hooks-0.0.1/corpus/cases/one-link-only-line-inside-a-blockquote-still-unwraps/case.txt +4 -0
  156. markdown_prose_hooks-0.0.1/corpus/cases/one-link-only-line-inside-a-blockquote-still-unwraps/expected.md +1 -0
  157. markdown_prose_hooks-0.0.1/corpus/cases/one-link-only-line-inside-a-blockquote-still-unwraps/input.md +3 -0
  158. markdown_prose_hooks-0.0.1/corpus/cases/one-link-only-line-inside-a-paragraph-still-unwraps/case.txt +4 -0
  159. markdown_prose_hooks-0.0.1/corpus/cases/one-link-only-line-inside-a-paragraph-still-unwraps/expected.md +1 -0
  160. markdown_prose_hooks-0.0.1/corpus/cases/one-link-only-line-inside-a-paragraph-still-unwraps/input.md +3 -0
  161. markdown_prose_hooks-0.0.1/corpus/cases/ordered-list-continuations-use-marker-width/case.txt +4 -0
  162. markdown_prose_hooks-0.0.1/corpus/cases/ordered-list-continuations-use-marker-width/expected.md +2 -0
  163. markdown_prose_hooks-0.0.1/corpus/cases/ordered-list-continuations-use-marker-width/input.md +4 -0
  164. markdown_prose_hooks-0.0.1/corpus/cases/pipe-inside-inline-code/case.txt +4 -0
  165. markdown_prose_hooks-0.0.1/corpus/cases/pipe-inside-inline-code/expected.md +1 -0
  166. markdown_prose_hooks-0.0.1/corpus/cases/pipe-inside-inline-code/input.md +2 -0
  167. markdown_prose_hooks-0.0.1/corpus/cases/prose-inside-a-blockquote-joins-but-keeps-the-marker/case.txt +4 -0
  168. markdown_prose_hooks-0.0.1/corpus/cases/prose-inside-a-blockquote-joins-but-keeps-the-marker/expected.md +1 -0
  169. markdown_prose_hooks-0.0.1/corpus/cases/prose-inside-a-blockquote-joins-but-keeps-the-marker/input.md +2 -0
  170. markdown_prose_hooks-0.0.1/corpus/cases/prose-that-merely-ends-in-a-link-still-unwraps/case.txt +4 -0
  171. markdown_prose_hooks-0.0.1/corpus/cases/prose-that-merely-ends-in-a-link-still-unwraps/expected.md +1 -0
  172. markdown_prose_hooks-0.0.1/corpus/cases/prose-that-merely-ends-in-a-link-still-unwraps/input.md +2 -0
  173. markdown_prose_hooks-0.0.1/corpus/cases/quoted-indented-code-does-not-open-a-badge-run/case.txt +4 -0
  174. markdown_prose_hooks-0.0.1/corpus/cases/quoted-indented-code-does-not-open-a-badge-run/expected.md +2 -0
  175. markdown_prose_hooks-0.0.1/corpus/cases/quoted-indented-code-does-not-open-a-badge-run/input.md +3 -0
  176. markdown_prose_hooks-0.0.1/corpus/cases/raw-html-inside-blockquote-preserves-internal-blank-line/case.txt +4 -0
  177. markdown_prose_hooks-0.0.1/corpus/cases/raw-html-inside-blockquote-preserves-internal-blank-line/expected.md +6 -0
  178. markdown_prose_hooks-0.0.1/corpus/cases/raw-html-inside-blockquote-preserves-internal-blank-line/input.md +6 -0
  179. markdown_prose_hooks-0.0.1/corpus/cases/single-label-row-wrapped-tail/case.txt +4 -0
  180. markdown_prose_hooks-0.0.1/corpus/cases/single-label-row-wrapped-tail/expected.md +1 -0
  181. markdown_prose_hooks-0.0.1/corpus/cases/single-label-row-wrapped-tail/input.md +2 -0
  182. markdown_prose_hooks-0.0.1/corpus/cases/soft-wrapped-paragraph-joins-into-one-line/case.txt +4 -0
  183. markdown_prose_hooks-0.0.1/corpus/cases/soft-wrapped-paragraph-joins-into-one-line/expected.md +1 -0
  184. markdown_prose_hooks-0.0.1/corpus/cases/soft-wrapped-paragraph-joins-into-one-line/input.md +2 -0
  185. markdown_prose_hooks-0.0.1/corpus/cases/tilde-fence-is-untouched/case.txt +4 -0
  186. markdown_prose_hooks-0.0.1/corpus/cases/tilde-fence-is-untouched/expected.md +4 -0
  187. markdown_prose_hooks-0.0.1/corpus/cases/tilde-fence-is-untouched/input.md +4 -0
  188. markdown_prose_hooks-0.0.1/corpus/cases/utf8-bom-front-matter-is-preserved/case.txt +4 -0
  189. markdown_prose_hooks-0.0.1/corpus/cases/utf8-bom-front-matter-is-preserved/expected.md +5 -0
  190. markdown_prose_hooks-0.0.1/corpus/cases/utf8-bom-front-matter-is-preserved/input.md +6 -0
  191. markdown_prose_hooks-0.0.1/corpus/cases/yaml-front-matter-is-preserved/case.txt +4 -0
  192. markdown_prose_hooks-0.0.1/corpus/cases/yaml-front-matter-is-preserved/expected.md +5 -0
  193. markdown_prose_hooks-0.0.1/corpus/cases/yaml-front-matter-is-preserved/input.md +6 -0
  194. markdown_prose_hooks-0.0.1/corpus/cli/README.md +72 -0
  195. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/case.txt +4 -0
  196. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/expected/!bang.md +2 -0
  197. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/expected/#hash.md +2 -0
  198. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/expected/.unwrapignore +2 -0
  199. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/expected/keep.md +1 -0
  200. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/stdout.txt +12 -0
  201. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/tree/!bang.md +2 -0
  202. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/tree/#hash.md +2 -0
  203. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/tree/.unwrapignore +2 -0
  204. markdown_prose_hooks-0.0.1/corpus/cli/a-backslash-escapes-a-comment-or-negation-marker/tree/keep.md +2 -0
  205. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-argument-is-skipped-silently/case.txt +4 -0
  206. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-argument-is-skipped-silently/expected/note.md +1 -0
  207. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-argument-is-skipped-silently/expected/sub/nested.md +2 -0
  208. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-argument-is-skipped-silently/stdout.txt +12 -0
  209. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-argument-is-skipped-silently/tree/note.md +2 -0
  210. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-argument-is-skipped-silently/tree/sub/nested.md +2 -0
  211. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-as-files-from-names-the-condition/case.txt +4 -0
  212. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-as-files-from-names-the-condition/expected/sub/kept.md +2 -0
  213. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-as-files-from-names-the-condition/stdout.txt +7 -0
  214. markdown_prose_hooks-0.0.1/corpus/cli/a-directory-as-files-from-names-the-condition/tree/sub/kept.md +2 -0
  215. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/case.txt +4 -0
  216. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/expected/.unwrapignore +1 -0
  217. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/expected/a/b.md +2 -0
  218. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/expected/a/m/n/b.md +2 -0
  219. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/expected/other/b.md +1 -0
  220. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/stdout.txt +12 -0
  221. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/tree/.unwrapignore +1 -0
  222. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/tree/a/b.md +2 -0
  223. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/tree/a/m/n/b.md +2 -0
  224. markdown_prose_hooks-0.0.1/corpus/cli/a-double-star-crosses-separators/tree/other/b.md +2 -0
  225. markdown_prose_hooks-0.0.1/corpus/cli/a-files-from-too-long-to-stat-is-reported/case.txt +4 -0
  226. markdown_prose_hooks-0.0.1/corpus/cli/a-files-from-too-long-to-stat-is-reported/expected/note.md +1 -0
  227. markdown_prose_hooks-0.0.1/corpus/cli/a-files-from-too-long-to-stat-is-reported/stdout.txt +14 -0
  228. markdown_prose_hooks-0.0.1/corpus/cli/a-files-from-too-long-to-stat-is-reported/tree/note.md +2 -0
  229. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/case.txt +4 -0
  230. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/expected/.unwrapignore +1 -0
  231. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/expected/sub/top.md +1 -0
  232. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/expected/top.md +2 -0
  233. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/stdout.txt +12 -0
  234. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/tree/.unwrapignore +1 -0
  235. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/tree/sub/top.md +2 -0
  236. markdown_prose_hooks-0.0.1/corpus/cli/a-leading-slash-anchors-to-the-root/tree/top.md +2 -0
  237. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-ignore-file-is-an-error/case.txt +4 -0
  238. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-ignore-file-is-an-error/expected/a.md +2 -0
  239. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-ignore-file-is-an-error/stdout.txt +14 -0
  240. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-ignore-file-is-an-error/tree/a.md +2 -0
  241. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-path-is-skipped-silently/case.txt +4 -0
  242. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-path-is-skipped-silently/expected/note.md +1 -0
  243. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-path-is-skipped-silently/stdout.txt +12 -0
  244. markdown_prose_hooks-0.0.1/corpus/cli/a-missing-path-is-skipped-silently/tree/note.md +2 -0
  245. markdown_prose_hooks-0.0.1/corpus/cli/a-negative-number-argument-is-a-path/case.txt +4 -0
  246. markdown_prose_hooks-0.0.1/corpus/cli/a-negative-number-argument-is-a-path/expected/note.md +1 -0
  247. markdown_prose_hooks-0.0.1/corpus/cli/a-negative-number-argument-is-a-path/stdout.txt +12 -0
  248. markdown_prose_hooks-0.0.1/corpus/cli/a-negative-number-argument-is-a-path/tree/note.md +1 -0
  249. markdown_prose_hooks-0.0.1/corpus/cli/a-non-ascii-digit-timestamp-is-not-a-transcript/case.txt +4 -0
  250. markdown_prose_hooks-0.0.1/corpus/cli/a-non-ascii-digit-timestamp-is-not-a-transcript/expected/talk.md +3 -0
  251. markdown_prose_hooks-0.0.1/corpus/cli/a-non-ascii-digit-timestamp-is-not-a-transcript/stdout.txt +12 -0
  252. markdown_prose_hooks-0.0.1/corpus/cli/a-non-ascii-digit-timestamp-is-not-a-transcript/tree/talk.md +7 -0
  253. markdown_prose_hooks-0.0.1/corpus/cli/a-non-utf8-file-is-reported/case.txt +4 -0
  254. markdown_prose_hooks-0.0.1/corpus/cli/a-non-utf8-file-is-reported/expected/bad.md +1 -0
  255. markdown_prose_hooks-0.0.1/corpus/cli/a-non-utf8-file-is-reported/expected/fine.md +1 -0
  256. markdown_prose_hooks-0.0.1/corpus/cli/a-non-utf8-file-is-reported/stdout.txt +14 -0
  257. markdown_prose_hooks-0.0.1/corpus/cli/a-non-utf8-file-is-reported/tree/bad.md +1 -0
  258. markdown_prose_hooks-0.0.1/corpus/cli/a-non-utf8-file-is-reported/tree/fine.md +2 -0
  259. markdown_prose_hooks-0.0.1/corpus/cli/a-path-too-long-to-stat-is-skipped-silently/case.txt +4 -0
  260. markdown_prose_hooks-0.0.1/corpus/cli/a-path-too-long-to-stat-is-skipped-silently/expected/note.md +1 -0
  261. markdown_prose_hooks-0.0.1/corpus/cli/a-path-too-long-to-stat-is-skipped-silently/stdout.txt +12 -0
  262. markdown_prose_hooks-0.0.1/corpus/cli/a-path-too-long-to-stat-is-skipped-silently/tree/note.md +2 -0
  263. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/case.txt +4 -0
  264. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/expected/.unwrapignore +1 -0
  265. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/expected/noote.md +1 -0
  266. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/expected/note.md +2 -0
  267. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/expected/nte.md +1 -0
  268. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/stdout.txt +18 -0
  269. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/tree/.unwrapignore +1 -0
  270. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/tree/noote.md +2 -0
  271. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/tree/note.md +2 -0
  272. markdown_prose_hooks-0.0.1/corpus/cli/a-question-mark-matches-one-character/tree/nte.md +2 -0
  273. markdown_prose_hooks-0.0.1/corpus/cli/a-symlink-is-skipped-silently/case.txt +4 -0
  274. markdown_prose_hooks-0.0.1/corpus/cli/a-symlink-is-skipped-silently/expected/link.md +1 -0
  275. markdown_prose_hooks-0.0.1/corpus/cli/a-symlink-is-skipped-silently/expected/target.md +2 -0
  276. markdown_prose_hooks-0.0.1/corpus/cli/a-symlink-is-skipped-silently/stdout.txt +5 -0
  277. markdown_prose_hooks-0.0.1/corpus/cli/a-symlink-is-skipped-silently/tree/link.md +1 -0
  278. markdown_prose_hooks-0.0.1/corpus/cli/a-symlink-is-skipped-silently/tree/target.md +2 -0
  279. markdown_prose_hooks-0.0.1/corpus/cli/a-transcript-is-skipped-whole/case.txt +4 -0
  280. markdown_prose_hooks-0.0.1/corpus/cli/a-transcript-is-skipped-whole/expected/talk.md +9 -0
  281. markdown_prose_hooks-0.0.1/corpus/cli/a-transcript-is-skipped-whole/stdout.txt +12 -0
  282. markdown_prose_hooks-0.0.1/corpus/cli/a-transcript-is-skipped-whole/tree/talk.md +9 -0
  283. markdown_prose_hooks-0.0.1/corpus/cli/an-excluded-file-does-not-trip-fail-on-change/case.txt +4 -0
  284. markdown_prose_hooks-0.0.1/corpus/cli/an-excluded-file-does-not-trip-fail-on-change/expected/.unwrapignore +1 -0
  285. markdown_prose_hooks-0.0.1/corpus/cli/an-excluded-file-does-not-trip-fail-on-change/expected/wrapped.md +2 -0
  286. markdown_prose_hooks-0.0.1/corpus/cli/an-excluded-file-does-not-trip-fail-on-change/stdout.txt +5 -0
  287. markdown_prose_hooks-0.0.1/corpus/cli/an-excluded-file-does-not-trip-fail-on-change/tree/.unwrapignore +1 -0
  288. markdown_prose_hooks-0.0.1/corpus/cli/an-excluded-file-does-not-trip-fail-on-change/tree/wrapped.md +2 -0
  289. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/case.txt +4 -0
  290. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/expected/.unwrapignore +1 -0
  291. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/expected/keep.md +1 -0
  292. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/expected/skipped.md +2 -0
  293. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/stdout.txt +12 -0
  294. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/tree/.unwrapignore +1 -0
  295. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/tree/keep.md +2 -0
  296. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-explicit-arguments/tree/skipped.md +2 -0
  297. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/case.txt +4 -0
  298. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/expected/.unwrapignore +1 -0
  299. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/expected/keep.md +1 -0
  300. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/expected/list.txt +2 -0
  301. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/expected/skipped.md +2 -0
  302. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/stdout.txt +12 -0
  303. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/tree/.unwrapignore +1 -0
  304. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/tree/keep.md +2 -0
  305. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/tree/list.txt +2 -0
  306. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-applies-to-files-from/tree/skipped.md +2 -0
  307. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/case.txt +4 -0
  308. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/expected/.unwrapignore +1 -0
  309. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/expected/fixtures/wrapped.md +2 -0
  310. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/expected/keep.md +1 -0
  311. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/stdout.txt +12 -0
  312. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/tree/.unwrapignore +1 -0
  313. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/tree/fixtures/wrapped.md +2 -0
  314. markdown_prose_hooks-0.0.1/corpus/cli/an-ignore-file-excludes-a-directory/tree/keep.md +2 -0
  315. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/case.txt +4 -0
  316. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/expected/.unwrapignore +1 -0
  317. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/expected/deep/docs/note.md +2 -0
  318. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/expected/docs/note.md +2 -0
  319. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/expected/keep.md +1 -0
  320. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/stdout.txt +12 -0
  321. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/tree/.unwrapignore +1 -0
  322. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/tree/deep/docs/note.md +2 -0
  323. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/tree/docs/note.md +2 -0
  324. markdown_prose_hooks-0.0.1/corpus/cli/an-unanchored-pattern-matches-at-any-depth/tree/keep.md +2 -0
  325. markdown_prose_hooks-0.0.1/corpus/cli/an-unreadable-file-is-reported/case.txt +5 -0
  326. markdown_prose_hooks-0.0.1/corpus/cli/an-unreadable-file-is-reported/expected/fine.md +1 -0
  327. markdown_prose_hooks-0.0.1/corpus/cli/an-unreadable-file-is-reported/expected/locked.md +2 -0
  328. markdown_prose_hooks-0.0.1/corpus/cli/an-unreadable-file-is-reported/stdout.txt +14 -0
  329. markdown_prose_hooks-0.0.1/corpus/cli/an-unreadable-file-is-reported/tree/fine.md +2 -0
  330. markdown_prose_hooks-0.0.1/corpus/cli/an-unreadable-file-is-reported/tree/locked.md +2 -0
  331. markdown_prose_hooks-0.0.1/corpus/cli/crlf-survives-a-rewrite/case.txt +4 -0
  332. markdown_prose_hooks-0.0.1/corpus/cli/crlf-survives-a-rewrite/expected/crlf.md +1 -0
  333. markdown_prose_hooks-0.0.1/corpus/cli/crlf-survives-a-rewrite/stdout.txt +1 -0
  334. markdown_prose_hooks-0.0.1/corpus/cli/crlf-survives-a-rewrite/tree/crlf.md +2 -0
  335. markdown_prose_hooks-0.0.1/corpus/cli/default-reports-without-writing/case.txt +4 -0
  336. markdown_prose_hooks-0.0.1/corpus/cli/default-reports-without-writing/expected/note.md +2 -0
  337. markdown_prose_hooks-0.0.1/corpus/cli/default-reports-without-writing/stdout.txt +1 -0
  338. markdown_prose_hooks-0.0.1/corpus/cli/default-reports-without-writing/tree/note.md +2 -0
  339. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-and-write-compose/case.txt +4 -0
  340. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-and-write-compose/expected/note.md +1 -0
  341. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-and-write-compose/stdout.txt +1 -0
  342. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-and-write-compose/tree/note.md +2 -0
  343. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-gates-without-writing/case.txt +4 -0
  344. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-gates-without-writing/expected/note.md +2 -0
  345. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-gates-without-writing/stdout.txt +1 -0
  346. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-gates-without-writing/tree/note.md +2 -0
  347. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-passes-when-already-unwrapped/case.txt +4 -0
  348. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-passes-when-already-unwrapped/expected/clean.md +1 -0
  349. markdown_prose_hooks-0.0.1/corpus/cli/fail-on-change-passes-when-already-unwrapped/tree/clean.md +1 -0
  350. markdown_prose_hooks-0.0.1/corpus/cli/files-from-missing-is-an-error/case.txt +4 -0
  351. markdown_prose_hooks-0.0.1/corpus/cli/files-from-missing-is-an-error/expected/note.md +2 -0
  352. markdown_prose_hooks-0.0.1/corpus/cli/files-from-missing-is-an-error/stdout.txt +7 -0
  353. markdown_prose_hooks-0.0.1/corpus/cli/files-from-missing-is-an-error/tree/note.md +2 -0
  354. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/case.txt +4 -0
  355. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/expected/first.md +1 -0
  356. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/expected/list.txt +1 -0
  357. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/expected/second.md +1 -0
  358. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/stdout.txt +2 -0
  359. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/tree/first.md +2 -0
  360. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/tree/list.txt +1 -0
  361. markdown_prose_hooks-0.0.1/corpus/cli/files-from-reads-a-newline-delimited-list/tree/second.md +2 -0
  362. markdown_prose_hooks-0.0.1/corpus/cli/json-lists-every-file-in-argument-order/case.txt +4 -0
  363. markdown_prose_hooks-0.0.1/corpus/cli/json-lists-every-file-in-argument-order/expected/a.md +1 -0
  364. markdown_prose_hooks-0.0.1/corpus/cli/json-lists-every-file-in-argument-order/expected/b.md +1 -0
  365. markdown_prose_hooks-0.0.1/corpus/cli/json-lists-every-file-in-argument-order/stdout.txt +18 -0
  366. markdown_prose_hooks-0.0.1/corpus/cli/json-lists-every-file-in-argument-order/tree/a.md +2 -0
  367. markdown_prose_hooks-0.0.1/corpus/cli/json-lists-every-file-in-argument-order/tree/b.md +1 -0
  368. markdown_prose_hooks-0.0.1/corpus/cli/json-payload-shape/case.txt +4 -0
  369. markdown_prose_hooks-0.0.1/corpus/cli/json-payload-shape/expected/note.md +1 -0
  370. markdown_prose_hooks-0.0.1/corpus/cli/json-payload-shape/stdout.txt +12 -0
  371. markdown_prose_hooks-0.0.1/corpus/cli/json-payload-shape/tree/note.md +2 -0
  372. markdown_prose_hooks-0.0.1/corpus/cli/no-ignore-file-excludes-nothing/case.txt +4 -0
  373. markdown_prose_hooks-0.0.1/corpus/cli/no-ignore-file-excludes-nothing/expected/a.md +1 -0
  374. markdown_prose_hooks-0.0.1/corpus/cli/no-ignore-file-excludes-nothing/expected/b.md +1 -0
  375. markdown_prose_hooks-0.0.1/corpus/cli/no-ignore-file-excludes-nothing/stdout.txt +18 -0
  376. markdown_prose_hooks-0.0.1/corpus/cli/no-ignore-file-excludes-nothing/tree/a.md +2 -0
  377. markdown_prose_hooks-0.0.1/corpus/cli/no-ignore-file-excludes-nothing/tree/b.md +2 -0
  378. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/case.txt +4 -0
  379. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/expected/a.md +2 -0
  380. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/expected/b.md +2 -0
  381. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/expected/keep.md +1 -0
  382. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/stdout.txt +12 -0
  383. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/tree/a.md +2 -0
  384. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/tree/b.md +2 -0
  385. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-is-repeatable/tree/keep.md +2 -0
  386. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/case.txt +4 -0
  387. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/expected/.unwrapignore +2 -0
  388. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/expected/kept.md +2 -0
  389. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/expected/other.md +2 -0
  390. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/stdout.txt +5 -0
  391. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/tree/.unwrapignore +2 -0
  392. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/tree/kept.md +2 -0
  393. markdown_prose_hooks-0.0.1/corpus/cli/the-exclude-flag-runs-after-the-ignore-file/tree/other.md +2 -0
  394. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/case.txt +4 -0
  395. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/expected/.unwrapignore +4 -0
  396. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/expected/a.md +2 -0
  397. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/expected/keep.md +1 -0
  398. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/stdout.txt +12 -0
  399. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/tree/.unwrapignore +4 -0
  400. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/tree/a.md +2 -0
  401. markdown_prose_hooks-0.0.1/corpus/cli/the-last-matching-pattern-wins/tree/keep.md +2 -0
  402. markdown_prose_hooks-0.0.1/corpus/cli/write-rewrites-a-wrapped-file/case.txt +4 -0
  403. markdown_prose_hooks-0.0.1/corpus/cli/write-rewrites-a-wrapped-file/expected/note.md +1 -0
  404. markdown_prose_hooks-0.0.1/corpus/cli/write-rewrites-a-wrapped-file/stdout.txt +1 -0
  405. markdown_prose_hooks-0.0.1/corpus/cli/write-rewrites-a-wrapped-file/tree/note.md +2 -0
  406. markdown_prose_hooks-0.0.1/docs/benchmarks-bytes.svg +1544 -0
  407. markdown_prose_hooks-0.0.1/docs/benchmarks-startup.svg +1331 -0
  408. markdown_prose_hooks-0.0.1/docs/benchmarks.ipynb +1559 -0
  409. markdown_prose_hooks-0.0.1/docs/benchmarks.svg +2405 -0
  410. markdown_prose_hooks-0.0.1/docs/post-release-checklist.md +65 -0
  411. markdown_prose_hooks-0.0.1/docs/superpowers/plans/2026-08-07-rust-port.md +2324 -0
  412. markdown_prose_hooks-0.0.1/docs/superpowers/specs/2026-08-06-rust-port-design.md +299 -0
  413. markdown_prose_hooks-0.0.1/examples/fuzz.rs +300 -0
  414. markdown_prose_hooks-0.0.1/pyproject.toml +96 -0
  415. markdown_prose_hooks-0.0.1/scripts/concat-gitignores.sh +349 -0
  416. markdown_prose_hooks-0.0.1/src/bin/unwrap-markdown-prose-rs.rs +24 -0
  417. markdown_prose_hooks-0.0.1/src/cli.rs +820 -0
  418. markdown_prose_hooks-0.0.1/src/code_span.rs +259 -0
  419. markdown_prose_hooks-0.0.1/src/fuzz.rs +398 -0
  420. markdown_prose_hooks-0.0.1/src/ignore.rs +398 -0
  421. markdown_prose_hooks-0.0.1/src/label.rs +284 -0
  422. markdown_prose_hooks-0.0.1/src/lib.rs +28 -0
  423. markdown_prose_hooks-0.0.1/src/links.rs +285 -0
  424. markdown_prose_hooks-0.0.1/src/markdown_prose_hooks/__init__.py +9 -0
  425. markdown_prose_hooks-0.0.1/src/markdown_prose_hooks/__main__.py +19 -0
  426. markdown_prose_hooks-0.0.1/src/markdown_prose_hooks/unwrap.py +1226 -0
  427. markdown_prose_hooks-0.0.1/src/paragraph.rs +638 -0
  428. markdown_prose_hooks-0.0.1/src/scan.rs +765 -0
  429. markdown_prose_hooks-0.0.1/src/transcript.rs +246 -0
  430. markdown_prose_hooks-0.0.1/tests/corpus.rs +183 -0
  431. markdown_prose_hooks-0.0.1/tests/test_cli_corpus.py +251 -0
  432. markdown_prose_hooks-0.0.1/tests/test_corpus.py +100 -0
  433. markdown_prose_hooks-0.0.1/tests/test_unwrap.py +334 -0
  434. markdown_prose_hooks-0.0.1/uv.lock +3144 -0
@@ -0,0 +1,57 @@
1
+ [codespell]
2
+ # codespell earns its place next to typos for exactly one dictionary. Measured on this
3
+ # tree at the time this file landed: `clear,rare,usage` finds nothing typos does not
4
+ # already gate, and adding `en-GB_to_en-US` finds eight. typos does not do dialect
5
+ # conversion at all -- it corrects misspellings, and a British spelling is not one -- so
6
+ # nothing else here would ever catch them. The wider two are kept anyway because they
7
+ # cost nothing measurable on this tree and this repository is mostly prose, which is
8
+ # where `rare` and `usage` earn out.
9
+ #
10
+ # The net is not complete, and the gap is worth knowing rather than rediscovering. The
11
+ # dictionary carries a base form and its plural but not every inflection, and it does
12
+ # not split identifiers -- so a past participle, a prefixed form, or a British spelling
13
+ # inside a name such as `test_a_dispatch_is_honoured` passes clean. This gates the easy
14
+ # majority; it does not retire the need for a person.
15
+ builtin = clear,rare,usage,en-GB_to_en-US
16
+ # Load-bearing, not decorative. codespell skips dotfiles and dotted directories by
17
+ # default, which here means all of .github/ plus .git-blame-ignore-revs -- six of the
18
+ # eight findings in the sweep that preceded this file. Without this line the hook lands
19
+ # green over the bulk of what it is meant to read.
20
+ check-hidden = true
21
+ # `Nd` is the Unicode general category of decimal digits, which is what Python's `\d`
22
+ # selects and what the Rust port has to reproduce; _typos.toml carries the same
23
+ # exemption for the same reason. This list is case-sensitive -- verified, not assumed:
24
+ # `Nd` is spared while the lowercase form still blocks, which is what keeps the
25
+ # exemption to the category name without also excusing a typo for "and".
26
+ ignore-words-list = Nd
27
+ # Globs, not directory prefixes: codespell matches each entry against the basename and
28
+ # against the path as a glob, so a bare `corpus/cli` silently matches nothing. The
29
+ # leading `*` is load-bearing too, and is why these are not written `corpus/cli/*`:
30
+ # pre-commit passes `corpus/cli/...` while a shell `codespell .` walks to
31
+ # `./corpus/cli/...`, and only a pattern indifferent to the prefix covers both. The
32
+ # corpus entries are belt-and-braces -- the `exclude:` in .pre-commit-config.yaml
33
+ # already keeps every tier of it away from the hook -- and what they buy is a bare
34
+ # `codespell` run free of decode warnings from the deliberately non-UTF8 fixture under
35
+ # corpus/cli/. `corpus/README.md` is prose about the corpus and stays in scope,
36
+ # matching the other four engines.
37
+ #
38
+ # .gitignore is generated by concatenating community templates, and its .NET
39
+ # boilerplate trips this twelve times: package-manager names, and the word fragments a
40
+ # split bracket expression leaves behind. They are described rather than quoted, and
41
+ # that is the finding worth keeping -- a spell-check config that names a false positive
42
+ # contains one, and there is no single directive that buys silence from both gates on
43
+ # this tree. codespell wants a bare `codespell:ignore` as the last thing on the line
44
+ # (the word-list form `codespell:ignore a,b` is unrecognized, and reads its own words
45
+ # as prose, so the line flags twice rather than none), while typos wants
46
+ # `spellchecker:disable-line` in that same final position. Describing beats quoting.
47
+ # Not ours to correct either way, which is the same call _typos.toml makes.
48
+ #
49
+ # CHANGELOG.md is preemptive: none ships yet, but cliff.toml means one will, and it is
50
+ # generated from commit messages already gated by gitlint.
51
+ #
52
+ # Unlike the typos hook above it in .pre-commit-config.yaml, this needs no duplicate
53
+ # `exclude:` there. That hook repeats its exclusion because typos treats `[files]
54
+ # extend-exclude` as file-discovery config and pre-commit hands it an explicit list
55
+ # instead. codespell's `skip` does apply to explicitly-passed filenames -- verified --
56
+ # so this file is the only place the rule is written.
57
+ skip = uv.lock,.git,.venv,.gitignore,CHANGELOG.md,*corpus/cases/*,*corpus/cli/*
@@ -0,0 +1,6 @@
1
+ # Reformats only. Skipped by `git blame` so a line points at the change that
2
+ # wrote it rather than at the pass that requoted it. GitHub honors this file
3
+ # automatically; locally it needs `blame.ignoreRevsFile`, which `make develop`
4
+ # sets.
5
+ 33b7cc6809cd23e9110dfe507e5201f7f8c2e0cb # style: single-quote the TOML in pyproject
6
+ 47b72dc10e4724f3a2ab56a69e615dcbfa79e01a # style: format Python with single quotes
@@ -0,0 +1,50 @@
1
+ # List any file patterns that are text and should have line endings
2
+ # normalized, i.e. convert crlf => lf
3
+ .dockerignore text
4
+ .editorconfig text
5
+ .gitattributes text
6
+ .gitignore text
7
+ .project text
8
+ .yamllint text diff=yaml eol=lf
9
+ *.cfg text
10
+ *.conf text
11
+ *.csv text eol=lf
12
+ *.css text diff=css
13
+ *.htm text diff=html
14
+ *.html text diff=html
15
+ *.java text diff=java
16
+ *.js text
17
+ *.json text
18
+ *.jsp text
19
+ *.md text diff=markdown
20
+ *.php text diff=php
21
+ *.properties text
22
+ *.py text eol=lf diff=python
23
+ *.pyi text eol=lf diff=python
24
+ *.rs text eol=lf diff=rust
25
+ *.sh text eol=lf diff=bash
26
+ *.sql text
27
+ *.tf text
28
+ *.toml text
29
+ *.ts text
30
+ *.txt text
31
+ *.xml text
32
+ *.yaml text
33
+ *.yml text
34
+ CODEOWNERS text
35
+ Dockerfile text
36
+
37
+ *.gif filter=lfs diff=lfs merge=lfs -text
38
+ *.jpeg filter=lfs diff=lfs merge=lfs -text
39
+ *.jpg filter=lfs diff=lfs merge=lfs -text
40
+ *.png filter=lfs diff=lfs merge=lfs -text
41
+
42
+ *.mp3 filter=lfs diff=lfs merge=lfs -text
43
+ *.wav filter=lfs diff=lfs merge=lfs -text
44
+ corpus/cases/**/*.md -text -diff
45
+
46
+ # The CLI tier for the same reason, widened from `*.md` to the whole subtree:
47
+ # its `case.txt` and `stdout.txt` are asserted byte for byte alongside the
48
+ # fixtures, and a case pinning CRLF stops pinning anything once git normalizes
49
+ # it on checkout.
50
+ corpus/cli/** -text -diff
@@ -0,0 +1,85 @@
1
+ ---
2
+ # Two ecosystems, not three. There is deliberately no `pre-commit` entry: pre-commit.ci
3
+ # is installed on this repository and its `autoupdate_schedule` accepts only weekly,
4
+ # monthly or quarterly -- no value stands it down -- so it raises hook bumps whatever
5
+ # this file says. Adding the ecosystem would duplicate those pull requests rather than
6
+ # replace them, and two bots opening the same bump is worse than either owning it.
7
+ # .pre-commit-config.yaml sets that cadence; bot-automerge.yml arms both authors.
8
+ version: 2
9
+ updates:
10
+ # Nothing here is a runtime dependency: `dependencies = []`, and the lock file covers
11
+ # the dev group alone -- pytest, pytest-cov, ruff. A bump cannot reach a repository
12
+ # that installs this hook, only the test run that would catch it, so patch and minor
13
+ # ride on green CI and a major waits for a person.
14
+ #
15
+ # For ruff that split does almost no work, and saying so is the honest version. Ruff
16
+ # is on 0.x, where a breaking release lands as 0.16 -> 0.17 and Dependabot types it
17
+ # `semver-minor`, so the major hold will not fire until 1.0 -- and ruff decides this
18
+ # repository's formatting, which is the one dev dependency whose bump arrives as a
19
+ # diff rather than as a passing build. The `default-days` below is what actually
20
+ # covers it: a soak on every update, not only the class that never occurs.
21
+ #
22
+ # Both keys, deliberately. `semver-major-days` alone left the soak on the class this
23
+ # repository already holds for a human, while the updates that merge unattended --
24
+ # polled daily -- had none at all, which is the threat model backwards.
25
+ - package-ecosystem: uv
26
+ directory: /
27
+ schedule:
28
+ interval: daily
29
+ groups:
30
+ uv-major:
31
+ update-types: [major]
32
+ uv-minor-patch:
33
+ update-types: [minor, patch]
34
+ cooldown:
35
+ semver-major-days: 30
36
+
37
+ # Actions here ride a floating major tag wherever upstream publishes one, so Dependabot
38
+ # raises a pull request only when a major moves. Holding majors -- the obvious policy,
39
+ # and the one the sibling repositories started with -- would therefore hold nearly every
40
+ # actions pull request this repository ever receives. That is an outage, not a policy.
41
+ # The cooldown below is what replaces the hold, and the two are a matched pair:
42
+ # bot-automerge.yml arms actions majors, and this delay is the only soak period between
43
+ # a release being published and it merging here unattended.
44
+ #
45
+ # Three pins do not float, and `grep -rn 'uses:' .github/workflows` lists them rather
46
+ # than this comment counting them. `astral-sh/setup-uv` is pinned exactly because
47
+ # upstream stopped publishing major tags at v8, which makes it the one action whose
48
+ # patch and minor releases show up here; CI.yml carries that reasoning at the pin
49
+ # itself. `dtolnay/rust-toolchain` carries the declared MSRV rather than a version to
50
+ # bump, which is what the `ignore:` entry below is for. `pypa/gh-action-pypi-publish`
51
+ # is used through the `release/v1` branch upstream documents, so it has no major tag
52
+ # to follow.
53
+ #
54
+ # Still no cargo ecosystem, for the reason there is no runtime Python one: the
55
+ # Rust crate declares no dependencies either, so the entry would poll a lock
56
+ # file that only ever records the crate itself.
57
+ - package-ecosystem: github-actions
58
+ directory: /
59
+ schedule:
60
+ interval: cron
61
+ cronjob: '0 0 1,15 * *' # 1st and 15th monthly at midnight UTC
62
+ groups:
63
+ actions:
64
+ patterns: ['*']
65
+ ignore:
66
+ # `dtolnay/rust-toolchain@1.86.0` is not a dependency held at a version --
67
+ # the version *is* the declared MSRV, matching `rust-version` in
68
+ # Cargo.toml. Dependabot reads the tag as semver and would raise it to the
69
+ # newest release, and bot-automerge.yml arms actions updates, so the floor
70
+ # this repository promises could rise unattended and untested. Raising it
71
+ # is a decision with a changelog entry, taken in both files at once.
72
+ - dependency-name: dtolnay/rust-toolchain
73
+ cooldown:
74
+ # `default-days` only. GitHub rejects the `semver-*` keys for this ecosystem --
75
+ # "not supported for the package ecosystem 'github-actions'" -- and an invalid key
76
+ # here does not degrade gracefully: it invalidates the file and drops this whole
77
+ # entry, grouping included. Nothing local catches that. The published schema admits
78
+ # the key in a cooldown block generally and the ecosystem restriction is enforced
79
+ # server-side, so the file lints clean and fails in the Dependabot tab.
80
+ #
81
+ # One number therefore covers every actions update, which is the right net anyway:
82
+ # these packages execute with this repository's own token inside jobs holding
83
+ # contents and pull-requests write, and a patch is not safer than a major when the
84
+ # risk is a compromised publisher rather than a changed interface.
85
+ default-days: 30
@@ -0,0 +1,234 @@
1
+ ---
2
+ name: CI
3
+
4
+ on:
5
+ push:
6
+ branches: [main]
7
+ pull_request:
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ concurrency:
14
+ group: ${{ github.workflow }}-${{ github.ref }}
15
+ cancel-in-progress: true
16
+
17
+ # `astral-sh/setup-uv` is pinned to an exact version where most of the actions here ride
18
+ # a floating major tag, and that asymmetry is upstream's rather than a slip here: v8
19
+ # stopped publishing major and minor tags outright, citing the tj-actions compromise, so
20
+ # `@v9` is not a ref that exists. The exact pin is what its release notes prescribe.
21
+ #
22
+ # The consequence worth knowing is for dependabot.yml: this is the one action whose patch
23
+ # and minor releases raise a pull request. The floating majors move only on a major;
24
+ # `dtolnay/rust-toolchain` is held out there because its version is the declared MSRV, as
25
+ # the comment above `rust-lint` says; and `pypa/gh-action-pypi-publish` in release.yml
26
+ # follows upstream's `release/v1` branch.
27
+ #
28
+ # Also from v9: `prune-cache` now defaults to false. Left at the new default -- with
29
+ # `dependencies = []` there is next to nothing to prune, so the cache this grows is small
30
+ # enough that the repository limit is not in play.
31
+
32
+ jobs:
33
+ lint:
34
+ runs-on: ubuntu-latest
35
+ steps:
36
+ - uses: actions/checkout@v7
37
+ - uses: astral-sh/setup-uv@v9.0.0
38
+ with:
39
+ enable-cache: true
40
+ - run: uv run ruff check .
41
+ - run: uv run ruff format --check .
42
+
43
+ test:
44
+ runs-on: ${{ matrix.os }}
45
+ strategy:
46
+ fail-fast: false
47
+ matrix:
48
+ # Every supported interpreter on Linux, plus the floor and the ceiling on
49
+ # macOS and Windows. Windows earns its place here rather than being taken
50
+ # on trust: this tool decides what a line ending is, and that is the one
51
+ # platform where getting it wrong rewrites every file it touches.
52
+ os: [ubuntu-latest]
53
+ python-version: ['3.10', '3.11', '3.12', '3.13']
54
+ include:
55
+ - os: macos-latest
56
+ python-version: '3.10'
57
+ - os: macos-latest
58
+ python-version: '3.13'
59
+ - os: windows-latest
60
+ python-version: '3.10'
61
+ - os: windows-latest
62
+ python-version: '3.13'
63
+ steps:
64
+ - uses: actions/checkout@v7
65
+ - uses: astral-sh/setup-uv@v9.0.0
66
+ with:
67
+ enable-cache: true
68
+ python-version: ${{ matrix.python-version }}
69
+ - run: uv run --python ${{ matrix.python-version }} python -m pytest -q
70
+
71
+ coverage:
72
+ # One upload on Ubuntu is enough: the suite is interpreter-agnostic Python, and
73
+ # Codecov merges flags rather than needing a matrix of identical reports.
74
+ #
75
+ # `use_oidc` rather than an upload token, for the reason release.yml prefers
76
+ # Trusted Publishing: a long-lived secret in a repository that needs none is
77
+ # a liability with no offsetting convenience. Codecov refuses an anonymous
78
+ # upload outright -- "Token required - not valid tokenless upload" -- so this
79
+ # is the only authentication left that stores nothing, and `id-token: write`
80
+ # is what mints the assertion it checks. The permission is granted on this
81
+ # job alone; the workflow default above stays read-only.
82
+ #
83
+ # `fail_ci_if_error` is on because the alternative had already happened: with
84
+ # it off, every upload since the badge was added was refused for want of a
85
+ # token while this job reported success, so the only place the failure showed
86
+ # was the badge reading "unknown". This job is not a required context, so a
87
+ # Codecov outage is visible here without blocking a merge.
88
+ runs-on: ubuntu-latest
89
+ permissions:
90
+ contents: read
91
+ id-token: write
92
+ env:
93
+ COVERAGE_REPORT: coverage.xml
94
+ steps:
95
+ - uses: actions/checkout@v7
96
+ with:
97
+ fetch-depth: 2 # fetch-depth of 2 enables diff coverage
98
+ - uses: astral-sh/setup-uv@v9.0.0
99
+ with:
100
+ enable-cache: true
101
+ python-version: '3.13'
102
+ - run: uv run python -m pytest --cov --cov-report=xml -q
103
+ - uses: codecov/codecov-action@v7
104
+ with:
105
+ files: ${{ env.COVERAGE_REPORT }}
106
+ fail_ci_if_error: true
107
+ use_oidc: true
108
+
109
+ hook:
110
+ # Resolving the hook through the framework is the only check that reads
111
+ # `.pre-commit-hooks.yaml` the way a consumer does; the console script passing
112
+ # says nothing about whether the hook definition is valid.
113
+ runs-on: ubuntu-latest
114
+ steps:
115
+ - uses: actions/checkout@v7
116
+ - uses: actions/setup-python@v7
117
+ with:
118
+ python-version: '3.13'
119
+ - run: python -m pip install --disable-pip-version-check pre-commit
120
+ # `--all-files`, with no list to build and nothing to keep in step. The tool
121
+ # reads `.unwrapignore` itself, so the exclusion reaches this caller exactly as
122
+ # it reaches `pre-commit run` and the action -- which is what `exclude:` could
123
+ # never do here, since try-repo builds its config from `.pre-commit-hooks.yaml`
124
+ # and never reads `.pre-commit-config.yaml`.
125
+ - run: pre-commit try-repo . unwrap-markdown-prose-py --all-files --verbose
126
+ - run: pre-commit try-repo . unwrap-markdown-prose-py-check --all-files --verbose
127
+ # The Rust pair resolves through the same framework, and `language: rust`
128
+ # builds it from source -- which is the install cost the README tells a
129
+ # consumer about, exercised here rather than asserted.
130
+ - uses: dtolnay/rust-toolchain@1.86.0
131
+ - run: pre-commit try-repo . unwrap-markdown-prose-rs --all-files --verbose
132
+ - run: pre-commit try-repo . unwrap-markdown-prose-rs-check --all-files --verbose
133
+
134
+ action:
135
+ # The composite action shares no code path with the hook beyond the CLI, so a
136
+ # green `hook` job does not cover it.
137
+ runs-on: ubuntu-latest
138
+ steps:
139
+ - uses: actions/checkout@v7
140
+ # No `paths`: the action's default sweep is every tracked Markdown file, and
141
+ # the tool now drops the corpus from that list on its own. Letting the default
142
+ # run is the stronger test anyway -- it exercises the path a consumer takes.
143
+ - name: Run the action against this repository
144
+ uses: ./
145
+ with:
146
+ write: 'false'
147
+ fail-on-change: 'true'
148
+
149
+ # The toolchain is pinned to the MSRV rather than to `stable`, so a language
150
+ # feature newer than `rust-version` in Cargo.toml fails here rather than in a
151
+ # consumer's `cargo install`. The two have to move together, which is why
152
+ # dependabot.yml holds this action out of its actions group.
153
+ #
154
+ # No build cache on either job. `[dependencies]` is empty and stays that way,
155
+ # so a cold compile is a couple of seconds -- less than restoring a cache
156
+ # would cost, and one fewer action running with this repository's token.
157
+ rust-lint:
158
+ runs-on: ubuntu-latest
159
+ steps:
160
+ - uses: actions/checkout@v7
161
+ - uses: dtolnay/rust-toolchain@1.86.0
162
+ with:
163
+ components: rustfmt, clippy
164
+ - run: cargo fmt --check
165
+ - run: cargo clippy --all-targets -- -D warnings
166
+
167
+ rust-test:
168
+ runs-on: ${{ matrix.os }}
169
+ strategy:
170
+ fail-fast: false
171
+ matrix:
172
+ # The same three platforms the Python matrix uses, for the same reason:
173
+ # this tool decides what a line ending is, and Windows is where getting
174
+ # that wrong rewrites every file it touches. The corpus is checked out
175
+ # verbatim there -- `.gitattributes` marks it `-text` -- so a case
176
+ # pinning CRLF pins it on every runner.
177
+ os: [ubuntu-latest, macos-latest, windows-latest]
178
+ steps:
179
+ - uses: actions/checkout@v7
180
+ - uses: dtolnay/rust-toolchain@1.86.0
181
+ - run: cargo test
182
+
183
+ parity:
184
+ # The CLI tier over both implementations. It is its own job rather than a
185
+ # step on `test` because it needs a Rust toolchain, and rather than a step on
186
+ # `rust-test` because it needs an interpreter: the harness that drives both
187
+ # binaries is the Python one.
188
+ runs-on: ${{ matrix.os }}
189
+ strategy:
190
+ fail-fast: false
191
+ matrix:
192
+ os: [ubuntu-latest, macos-latest, windows-latest]
193
+ steps:
194
+ - uses: actions/checkout@v7
195
+ - uses: dtolnay/rust-toolchain@1.86.0
196
+ - uses: astral-sh/setup-uv@v9.0.0
197
+ with:
198
+ enable-cache: true
199
+ - run: cargo build --release
200
+ # `_runners()` skips the Rust binary when it is absent, so that a
201
+ # Python-only checkout still runs the tier. Here that skip would turn a
202
+ # failed build into a silent half-run reported as a pass, so the harness is
203
+ # told to fail instead.
204
+ - run: uv run python -m pytest tests/test_cli_corpus.py -q
205
+ env:
206
+ REQUIRE_RUST_BINARY: '1'
207
+ # The enumerated tier says the two implementations agree about what was
208
+ # anticipated; only this says anything about what was not. The fixed range
209
+ # is a regression net *only while the generator is frozen* -- any edit to
210
+ # its fragment bank renames every seed -- so a fresh range derived from the
211
+ # run number rides along and keeps exploring. A divergence worth keeping
212
+ # becomes a corpus case, never a seed number.
213
+ - name: Fuzz both implementations differentially
214
+ shell: bash
215
+ run: |
216
+ python="$(uv run python -c 'import sys; print(sys.executable)')"
217
+ cargo run --release --quiet --example fuzz -- \
218
+ --start 1 --count 400 --python "$python -m markdown_prose_hooks"
219
+ cargo run --release --quiet --example fuzz -- \
220
+ --start $(( ${{ github.run_number }} * 400 + 100000 )) --count 200 \
221
+ --python "$python -m markdown_prose_hooks"
222
+
223
+ build:
224
+ runs-on: ubuntu-latest
225
+ steps:
226
+ - uses: actions/checkout@v7
227
+ - uses: astral-sh/setup-uv@v9.0.0
228
+ with:
229
+ enable-cache: true
230
+ - run: uv build
231
+ - uses: actions/upload-artifact@v7
232
+ with:
233
+ name: dist
234
+ path: dist/
@@ -0,0 +1,107 @@
1
+ ---
2
+ name: Bot auto-merge disarm
3
+
4
+ # The half that makes arming defensible. bot-automerge.yml arms GitHub's native
5
+ # auto-merge with no human action, and that has to be revocable: a label that cannot
6
+ # take the merge back is a one-way door, and the margin it removes is the one a mistake
7
+ # needs.
8
+ #
9
+ # Gating the arming job on the label is not enough. Once auto-merge is enabled it lives
10
+ # server-side, so a label applied afterwards stops the workflow from running again while
11
+ # GitHub still merges the moment requirements pass. Something has to actively turn it
12
+ # off.
13
+ #
14
+ # No branch filter and no fork guard, deliberately. A suppressor must be at least as
15
+ # broad as the thing it suppresses, and disarming a pull request that was never armed is
16
+ # a no-op -- so the cheap failure is running when it need not, and the expensive one is
17
+ # declining to run when it should. A `branches:` filter in particular would mean a pull
18
+ # request retargeted after arming kept its armed state and lost its switch.
19
+
20
+ on:
21
+ pull_request:
22
+ types: [labeled]
23
+
24
+ # `pull-requests: write` alone. This job never checks out and never writes a ref -- it
25
+ # reads pull request state and calls `disablePullRequestAutoMerge` -- so the
26
+ # `contents: write` its sibling needs to complete a merge grants real authority here for
27
+ # no reader. Declaring this block sets every unlisted scope to `none`, which is the
28
+ # point: the suppressor should not be able to do more than suppress.
29
+ permissions:
30
+ pull-requests: write
31
+
32
+ concurrency:
33
+ # Keyed on the label as well as the number, and not canceled in flight: a disarm must
34
+ # not be superseded by a different label event arriving on the same pull request.
35
+ # Setting cancel-in-progress here would mean labeling twice in quick succession could
36
+ # cancel the disarm and leave the pull request armed.
37
+ group: bot-automerge-disarm-${{ github.event.pull_request.number }}-${{ github.event.label.name }}
38
+ cancel-in-progress: false
39
+
40
+ jobs:
41
+ disarm:
42
+ # Case-insensitive already, and deliberately left as a bare `==`. Expression string
43
+ # comparison ignores case -- "GitHub ignores case when comparing strings" -- so
44
+ # "Do Not Auto-Merge" reaches this job just as the lowercase spelling does, which is
45
+ # what it has to do: GitHub treats label names as unique case-insensitively, so the
46
+ # two are one switch to a human. Recorded because it reads like a bug and has already
47
+ # been reported as one; the usual suggested repair, `toLower(...)`, is not a function
48
+ # Actions has. The shell in bot-automerge.yml matches with `grep -qixF` instead
49
+ # because that check runs in bash, where the case-folding is not free.
50
+ if: github.event.label.name == 'do not auto-merge'
51
+ runs-on: ubuntu-latest
52
+ timeout-minutes: 5
53
+ env:
54
+ GH_TOKEN: ${{ github.token }}
55
+ GH_REPO: ${{ github.repository }}
56
+ PR_NUMBER: ${{ github.event.pull_request.number }}
57
+ steps:
58
+ # Fails closed, which is the property to preserve if this is ever edited. The
59
+ # tempting shape -- read the label back, and disable only when the answer is `true`
60
+ # -- inverts the guard: a swallowed read then reports "the label is absent", skips
61
+ # the disable, and leaves the pull request armed with its kill switch applied. A
62
+ # swallowed read on a guard removes the guard rather than relaxing it, so there is
63
+ # no `2>/dev/null` and no `|| false` anywhere below.
64
+ #
65
+ # Verified rather than trusted: each attempt re-reads whether auto-merge is still
66
+ # on, so a `--disable-auto` that reported success without taking effect is caught.
67
+ - name: Disarm auto-merge
68
+ run: |
69
+ # An unreadable state falls through to the disarm loop rather than exiting, so
70
+ # the fallback here is the safe direction. Only a confirmed CLOSED or MERGED
71
+ # short-circuits, because those are the two states where there is nothing to
72
+ # disarm and the loop would spin for no reason.
73
+ state=$(gh pr view "$PR_NUMBER" --json state --jq .state || echo "")
74
+ if [ "$state" = "CLOSED" ] || [ "$state" = "MERGED" ]; then
75
+ echo "::notice::PR #${PR_NUMBER} is ${state}; nothing to disarm."
76
+ exit 0
77
+ fi
78
+ for attempt in 1 2 3; do
79
+ # stderr stays visible on purpose: this probe is allowed to fail, because the
80
+ # disable below runs regardless, but a silent failure would hide why a disarm
81
+ # needed three attempts.
82
+ armed=$(gh pr view "$PR_NUMBER" --json autoMergeRequest \
83
+ --jq '.autoMergeRequest != null') || armed=""
84
+ if [ "$armed" = "false" ]; then
85
+ echo "::notice::Auto-merge is off on PR #${PR_NUMBER}."
86
+ exit 0
87
+ fi
88
+ # Attempt the disable whenever "off" was not positively confirmed, which
89
+ # includes the probe having failed and left $armed empty. Only confirmed-off
90
+ # exits above. Gating this on "true" would mean a transient error skipped the
91
+ # attempt entirely and left the pull request armed -- the outcome this
92
+ # workflow exists to prevent.
93
+ gh pr merge --disable-auto "$PR_NUMBER" || true
94
+ echo "::warning::attempt ${attempt}: auto-merge not yet confirmed off on #${PR_NUMBER}."
95
+ sleep 5
96
+ done
97
+ # One last read: the loop disables on its final pass and then falls straight
98
+ # through, so without this a disarm that worked on attempt three still reports
99
+ # failure and pages somebody to do what has already been done.
100
+ if [ "$(gh pr view "$PR_NUMBER" --json autoMergeRequest \
101
+ --jq '.autoMergeRequest != null')" = "false" ]; then
102
+ echo "::notice::Auto-merge is off on PR #${PR_NUMBER}."
103
+ exit 0
104
+ fi
105
+ echo "::error::Could not confirm auto-merge is off on #${PR_NUMBER}. Disable it by hand:"
106
+ echo "::error::gh pr merge --disable-auto ${PR_NUMBER} --repo ${GH_REPO}"
107
+ exit 1