All notable changes to this project will be documented in this file. See conventional commits for commit guidelines.
- (sentence) keep journal title abbreviations inside the sentence - (4904216) - HaoZeke
- default to native parsers, fix markdown sentence splits and binstall assets (#524) - (d57a91d) - HaoZeke
- keep filled labels readable in dark themes - (b71af34) - HaoZeke
- keep link hover off filled buttons - (15c336b) - HaoZeke
- describe the release archives and journal title abbreviations - (12f8f41) - HaoZeke
- record the section padding as 6rem 0 - (c5fd704) - HaoZeke
- record the page radii and section padding - (bcc9722) - HaoZeke
- record the product and the shipping design - (1bacd33) - HaoZeke
- turn on the design detector hook - (202286b) - HaoZeke
- keep the scroll hint still when motion is reduced - (c9b079c) - HaoZeke
- lead the feature list with one proof - (872900e) - HaoZeke
- share one face across the TurtleTech sites - (7e39642) - HaoZeke
- (pandoc) keep org file keywords and add no heading drawers - (18520c0) - HaoZeke
- (site) pin the homepage to v0.11.8 - (783e674) - HaoZeke
- (markdown) accept the line-block terminator on the structure span - (6f3cd8c) - HaoZeke
- (markdown) keep the paragraph after an unclosed bracket - (037c3de) - HaoZeke
- (markdown) unclosed bracket math must not swallow the next line - (9223256) - HaoZeke
- restore the 42 CLI tests the consolidated binary overwrote - (df6b271) - HaoZeke
- the fancyvrb VerbatimInput test is named for what it checks - (9d043bb) - HaoZeke
- a nested test runs at the top level, and the clippy lints in the consolidated tests are cleared - (eeb13b4) - HaoZeke
- (release) the bump moves every pre-commit rev pin, which now live under docs/orgmode - (ed8847a) - HaoZeke
- (release) a bump moves only the workspace crates in the lockfile - (439519a) - HaoZeke
- (tests) one integration test binary links the library once - (f0c1e75) - HaoZeke
- (org) hang the vale item description under its tag - (9bda344) - HaoZeke
- cli reference reflowed where a sentence opens with a number - (918162e) - HaoZeke
- keep the 0.11.7 changelog on the released notes - (1029ef1) - HaoZeke
- (build) use thin LTO for the release profile - (bf92050) - HaoZeke
- (latex) keep letter-delimited verb and url spans whole - (dee2151) - HaoZeke
- (latex) keep pgfplots group and special axes whole - (c8fb922) - HaoZeke
- (latex) keep breqn dgroup and darray whole - (4ca94ae) - HaoZeke
- (latex) keep more math and verbatim environments whole - (1e41fb9) - HaoZeke
- (latex) keep leftover math and filecontents bodies whole - (2af7677) - HaoZeke
- (markdown) keep mid-line bracket display math whole - (3633660) - HaoZeke
- (markdown) hang the second sentence of a pandoc example item - (d1a833f) - HaoZeke
- (markdown) match shortcut labels without lookahead - (45405fd) - HaoZeke
- (markdown) keep shortcut labels, citations, and dollar math whole - (25d078f) - HaoZeke
- (markdown) keep pandoc line blocks and example lists whole - (37f3086) - HaoZeke
- (markdown) keep LaTeX non-prose environments whole - (c22f021) - HaoZeke
- (markdown) end a bracket math search at a blank line - (3b1e7bd) - HaoZeke
- (markdown) do not treat a div fence as a definition marker - (c124ffa) - HaoZeke
- (markdown) keep bracket math and div fences out of prose - (2a93456) - HaoZeke
- (org) take the item tag through the last separator - (ad67258) - HaoZeke
- (org) keep list item tags on the item line - (7a13061) - HaoZeke
- (org,rst) keep continued tags and titles whole - (711f7a8) - HaoZeke
- (pandoc) shield alltt, BVerbatim, and luacode - (3e207aa) - HaoZeke
- (pandoc) shield starred verbatim, lstlisting, and minted - (ceb11e5) - HaoZeke
- (plaintext) do not split a balanced quote on a period - (7a87430) - HaoZeke
- (rst) hang the indented line after a same-line title - (66651ec) - HaoZeke
- (rst) keep csv-table title continuations as structure - (2547a67) - HaoZeke
- (rst) keep directive title arguments on the directive line - (389e864) - HaoZeke
- (sentence) lowercase academic abbreviations rejoin a number after them - (67b0547) - HaoZeke
- (sentence) a number opens a sentence, and a lowercase start can be asked for - (e0a7df2) - HaoZeke
- (latex) sort imports with the edition 2024 formatter - (b5de4ca) - HaoZeke
- (org,rst) wrap the lines rustfmt rejected - (3356281) - HaoZeke
- (pandoc) wrap the starred-verbatim test input - (1aefe7d) - HaoZeke
- (rst) keep the title-body fixture on one line - (c325926) - HaoZeke
- unwrap_or_else with panic! over expect(&format!) in tests, and two needless borrows - (db7b015) - HaoZeke
- clear the clippy lints Rust 1.98 raises in tests and the LaTeX parser - (ee1f49e) - HaoZeke
- generated pre-commit hook runs under bash so the format loop runs on Ubuntu
- leftover LaTeX yquant body stays non-prose
- leftover LaTeX quantikz body stays non-prose
- leftover LaTeX numcases body stays non-prose
- leftover LaTeX intertext argument stays prose
- leftover LaTeX empheq body stays non-prose
- leftover LaTeX prooftree body stays non-prose
- leftover LaTeX CD diagram body stays non-prose
- leftover LaTeX subarray body stays non-prose
- leftover LaTeX xalignat body stays non-prose
- leftover LaTeX smallmatrix body stays non-prose
- leftover markdown hang-plus-four line stays in an open list paragraph
- leftover org nested item returns to the parent list
- leftover org item ends at the bullet column
- leftover LaTeX verb with an internal space stays one wrap token
- leftover markdown HTML type 6 and 7 blocks run to a blank line
- leftover markdown footnote continuation keeps an ATX heading
- leftover markdown list marker remainder stays blocks
- leftover org plain list ends on two blanks
- leftover RST anonymous target keeps its indented link block
- leftover bare colon paragraph opens an RST literal block
- leftover org ordered marker past nine digits skip-cut
- leftover short markdown setext underline is escaped
- leftover wrap-created LaTeX sectioning command skip-cut
- leftover org item bullet allows a tab
- leftover markdown closing fence with a non-space tail stays inside the code block
- leftover wrap-created RST plus-fragment skip-cut
- leftover wrap-created RST jinja statement and anonymous target skip-cut
- leftover wrap-created RST grid-table top skip-cut
- leftover type-6 void HTML (
param/track) does not swallow following prose - leftover wrap-created RST simple-table border skip-cut
- leftover org bibtex/eshell/w3m plain links hang and wrap
- leftover wrap-created RST section adornment skip-cut (snapper-7xd3)
- leftover type-6 void HTML (
hr/col/link/base) does not swallow following prose (snapper-56tj) - leftover RST include/raw/literalinclude same-line hang
- leftover wrap-created org/md markers and extra-compact DL hang
- site 404 page instead of the landing page
- leftover native-parser walkers vs Docutils pulldown org-element and TeX (#482)
- (latex) tokenize leftover moreverb listingcont as one walker (#477)
- (latex) tokenize leftover fancyvrb DefineShortVerb as one walker (#474)
- (latex) tokenize leftover moreverb verbatimwrite as one walker (#472)
- (latex) tokenize leftover fvextra buffer cmds as one walker (#469)
- (latex) tokenize leftover moreverb verbatimtabinput as one walker (#466)
- (latex) tokenize leftover CatchFileDef CatchFileEdef as one walker (#464)
- (org) do not slice #+CAPTION prefix inside a UTF-8 char (#460)
- (latex) tokenize leftover UseVerb Verb EscVerb as one walker (#458)
- (latex) tokenize leftover verb-span cmds as one walker (#456)
- (latex) tokenize scontents leftover cmds as one walker (#455)
- (latex) tokenize pythonhighlight leftover pyth as one walker (#454)
- (latex) tokenize pythontex leftover pythontexcustomc as one walker (#453)
- (latex) tokenize sagetex leftover inline cmds as one walker (#448)
- (latex) tokenize pythontex usefamily leftover inlines as one walker (#447)
- (latex) tokenize pythonhighlight leftover file-input as one walker (#444)
- (latex) tokenize pythontex leftover inline cmds as one walker (#442)
- (latex) tokenize leftover filename-input cmds as one walker (#440)
- (latex) tokenize scontents inputsc like lstinputlisting (#437) (#438)
- (rst) hang and split same-line meta field body (#434) (#435)
- (latex) tokenize pythontex inputpylab inputsympy like inputpy (#436)
- (rst) hang and split same-line line-block body (#432)
- (latex) tokenize sagetex sageinput like lstinputlisting (#428) (#431)
- (rst) hang and split same-line parsed-literal body (#426) (#429)
- (latex) tokenize moreverb listinginput like lstinputlisting (#427)
- (rst) hang and split same-line header footer body (#422) (#425)
- (latex) tokenize pythontex inputpy like lstinputlisting (#419) (#423)
- (rst) hang and split same-line substitution replace body (#417) (#421)
- (org) leftover object-lex steals src_ after word-underscore (#420)
- (latex) tokenize piton PitonInputFile like lstinputlisting (#418)
- (latex) tokenize tcolorbox tcbinputlisting like lstinputlisting (#401)
- (md) treat footnote definition body as leftover prose (#415)
- (rst) do not swallow flush prose after line-block (#409) (#414)
- (latex) tokenize fancyvrb VerbatimInput like lstinputlisting (#403)
- (latex) tokenize verbatim verbatiminput like lstinputlisting (#402)
- (latex) tokenize minted inputminted like mintinline (#397)
- (org) treat verse-block body as leftover structure (#395) (#396)
- (latex) tokenize listings lstinputlisting like lstinline (#393)
- (rst) hang and reflow parsed-literal bodies (#392)
- (latex) treat luacode leftover luaexec as code (#390)
- (rst) hang leftover container directive bodies (#389)
- (latex) treat pythontex option-family envs as code (#388)
- (latex) treat sverb leftover write and demo envs as code (#387)
- (rst) hang and split same-line note body after :: (#349) (#384)
- (sentence) do not split markup closers inside an open quote (#374) (#383)
- (latex) treat codehigh leftover envs as code (#382)
- (latex) treat luamplib mplibcode as code (#381)
- (rst) treat unmatched simple-table top as structure (#347) (#380)
- (md) keep mid-paragraph link-reference definitions in prose (#357) (#379)
- (org) treat unmatched begin blocks as paragraphs (#355) (#378)
- (latex) treat pyluatex pythonq and pythonrepl as code (#377)
- (rst) do not swallow flush prose after compact note (#344) (#376)
- (md) end closed type-7 HTML blocks at the matching close (#373)
- (latex) treat showexpl LTXexample as code (#375)
- (org) keep export-snippet trailing prose and Emacs backends (#354) (#372)
- (rst) treat lone .. as empty comment not section underline (#343) (#371)
- (latex) treat texments/pygmentex pygmented as code (#342) (#370)
- (md) do not join unquoted prose onto quoted HTML blocks (#369)
- (rst) treat interior-colon field names as field markers (#368)
- (md) treat quoted empty list markers as Structure (#339) (#367)
- (org) keep brace subscript wrap atomic across interior punct (#366)
- (org) keep latex-fragments atomic across interior punctuation (#365)
- (org) keep angular links atomic across interior punctuation (#335) (#364)
- (md) treat padded empty CommonMark list markers as Structure (#337) (#363)
- (latex) treat leftover tcolorbox write and listing envs as code (#362)
- (md) end closed type-6 HTML blocks at the matching close (#332) (#360)
- (latex) treat leftover pythontex default-family envs as code (#361)
- (rst) treat empty doctest opener as Structure (#331) (#359)
- (rst) treat empty field-list markers at EOL as Structure (#330) (#358)
- (md) treat empty CommonMark list markers as Structure (#326) (#329)
- (md) treat empty ATX headings as Structure (#327) (#328)
- (rst) treat empty and unicode Docutils bullets as Structure (#324) (#325)
- (org) treat empty list bullets at EOL as Structure (#320) (#323)
- (org) treat Emacs word-char drawer names as structure (#318) (#322)
- (org) treat mixed-case planning and clock as Structure (#321)
- (latex) treat verbments pyglist as code (#316)
- (org) treat table-rule lines as structure (#310) (#317)
- (org) treat column-0 diary-sexp as Structure (#315)
- (latex) treat pythonhighlight python as code (#314)
- (latex) treat piton.sty Piton env and piton pipe as code (#312)
- (latex) treat moreverb verbatimwrite as code (#313)
- (latex) treat scontents and verbatimsc as code (#311)
- (latex) treat sagetex sageverbatim family as code (#301)
- (latex) treat filecontentsdef leftover sibling envs as code (#300)
- (latex) treat fvextra VerbatimBuffer as code (#296)
- (latex) treat fvextra VerbEnv as code (#293) (#297)
- (latex) treat filecontentsdef env as code (#295)
- (latex) treat tcolorbox verbatim write envs as code (#290)
- (latex) treat pythontex pylab envs as verbatim (#278) (#289)
- (latex) treat moreverb listing envs as code (#288)
- (latex) treat pythontex sympy envs as verbatim (#277) (#287)
- (latex) treat pythontex starred py envs as verbatim (#276) (#286)
- (latex) treat minted-star env as code (#284)
- (latex) tokenize fancyvrb SaveVerb like Verb (#275) (#283)
- (latex) treat pythontex pygments env as verbatim (#282)
- (latex) treat pythontex pyblock pyverbatim pyconsole as code (#257)
- (latex) treat moreverb verbatimtab as code (#256)
- (latex) treat fvextra VerbatimWrite as code (#255)
- (latex) treat tcolorbox tcblisting-star as code (#254)
- (latex) tokenize fancyvrb Verb and Verb* like verb (#253)
- (latex) tokenize minted mintinline and mint like lstinline (#252)
- (latex) treat fancyvrb Verbatim-star envs as code (#251)
- (latex) treat spverbatim and spverb as verbatim (#242)
- (latex) treat listings lstlisting* as code (#238)
- (latex) treat alltt as code so listing bodies do not reflow as prose (#236)
- (latex) treat fancyvrb SaveVerbatim and VerbatimOut as code (#224)
- (latex) treat fancyvrb BVerbatim and LVerbatim as code (#223)
- (latex) treat IEEEeqnarray xltabular and math-star as structure (#187)
- (latex) treat NiceTabular listabla and spreadtab as structure (#188)
- (latex) reflow figure and table caption long arguments (#156)
- (latex) treat tikzcd axis and pgfpicture as structure (#152)
- (latex) treat optional section short title as Structure (#150)
- (latex) treat Verbatim boxedverbatim and tcblisting as code (#147)
- (latex) treat mid-line display math opener as Structure (#124)
- (latex) keep comment env and iffalse as raw (#116)
- (latex) treat dollar-dollar display math as Structure (#115)
- (latex) treat tree-sitter and latexindent math/table envs as structure (#114)
- (latex) treat filecontents and trivia envs as code (#113)
- (latex) hang enumerate item continuation sentences (#78)
- (markdown) treat dest-on-next-line link references as Structure (#202)
- (markdown) treat link-reference and footnote definitions as Structure (#190)
- (markdown) treat 0-3 space ATX headings as Structure (#189)
- (markdown) treat CommonMark > with optional space as a quote (#155)
- (markdown) treat CommonMark thematic breaks as Structure (#149)
- (markdown) keep GFM tables without flanking pipes as structure (#140)
- (markdown) keep list items open across blank indent (#137)
- (markdown) treat $$ display math as Structure (#123)
- (markdown) treat CommonMark HTML blocks as Structure (#122)
- (markdown) treat CommonMark indented code as Code (#121)
- (markdown) treat quoted fences as Code (#119)
- (md) treat ordered start != 1 as setext title text (#271)
- (md) reject list setext underlines shallower than the open item hang (#270)
- (md) count every quote marker so matching > > setext promotes (#269)
- (md) do not treat 4-space > - as a quoted list opener (#268)
- (md) count nested quote markers after 0-3 spaces (#267)
- (md) reject list setext underlines shallower than the item hang (#265)
- (md) promote only the open paragraph for setext titles (#228)
- (md) keep definition list terms and : markers as structure (#225)
- (md) keep GFM alert type markers as structure (#222)
- (md) close YAML front matter on ... and keep blank --- as a break (#217)
- (md) cap ordered list markers at 9 digits (#191)
- (md) keep same-line 0. A. opener with its sentence (#184)
- (md) keep sentence break after punct inside link tails (#201)
- (org) keep two-sentence verse lines as one physical line (#285)
- (org) keep timestamps atomic across interior punctuation (#264)
- (org) keep inline src_ and call_ atomic (#240)
- (org) treat \ at EOL as an org-element line break (#239)
- (org) keep inline footnote references atomic (#237)
- (org) keep macros atomic across interior punctuation (#229)
- (org) keep radio and angle targets atomic (#226)
- (org) hang and reflow #+CAPTION values (#221)
- (org) treat footnote definitions as hung prose (#199)
- (org) reflow special-block interiors as prose (#197)
- (org) stop file: token swallowing sentence punct (#185)
- (org) treat #+BEGIN: dynamic blocks as Structure (#178) (#195)
- (org) require space or EOL after hash comments (#194)
- (org) treat [cite...] as an atomic inline token (#153)
- (org) treat indented star lists as list items (#148)
- (org) treat planning and clock lines as Structure (#145)
- (org) classify same-line display math and latex env (#141)
- (org) treat quote/verse/center as structure plus inner prose (#139)
- (org) classify drawers, fixed-width, and rules (#128)
- (org) treat $$ display math as Structure (#120)
- (org) close greater blocks by matching NAME (#117)
- (reflow) hang RST enumerated item continuations (#74)
- (rst) keep substitution references atomic (#241)
- (rst) hang and reflow admonition and figure bodies (#219)
- (rst) keep substitution references out of leftover table rows (#218)
- (rst) keep consecutive Jinja statements on their own lines (#216)
- (rst) treat footnotes and citations as hung prose (#193)
- (rst) keep two-space list hang inside open inline literals (#164)
- (rst) keep line blocks out of the grid-table arm (#192)
- (rst) keep two-space list hang inside open quotes (#160)
- (rst) blank closes comments so later indent is a hung quote (#198)
- (rst) treat suffix role closer as sentence end (#183)
- (rst) keep compact list-like prose as one paragraph (#163)
- (rst) keep two-space bullet marker hang width (#162)
- (rst) keep definition hang after nested directives (#165)
- (rst) keep two-space list hang inside open parentheses (#161)
- (rst) keep nested list continuation hang at inner width (#154)
- (rst) keep two-space list hang after abbreviations (#158)
- (rst) keep over-indented list continuation as a definition (#159)
- (rst) hang list sentences after a :role:` continuation (#157)
- (rst) treat full Docutils adornment charset as section underline (#151)
- (rst) scan simple tables to the matching-width closer (#146)
- (rst) treat anonymous hyperlink targets as structure (#144)
- (rst) treat quoted literal blocks as structure (#142)
- (rst) treat doctest blocks as structure (#138)
- (rst) hang alpha, roman, and paren enumerators (#136)
- (rst) treat option lists as structure plus hung prose (#127)
- (rst) treat role closer as sentence end (#76)
- (rst) keep block quote indent (#75)
- (rst) keep section adornments on their own line (#73)
- (rst) keep two-space code-block bodies indented (#72)
- (sentence) peel shortest closer before quote-capital (#272)
- (sentence) keep markdown reference links atomic (#227)
- (sentence) split same-line lowercase proper noun after period (#186)
- (sentence) do not split bang inside markdown code (#118)
- (sentence) keep break before lowercase proper noun (#77)
- (docs) do not serialize PR builds on the pages lock (#200)
- (cli) default to pandoc when a writer is available (#68)
- (pandoc) keep RST comments and snapper pragmas on write (#67)
- (pandoc) write reflowed AST through pandoc writer (#56)
- (ci) install cargo-dist on Windows and macOS ARM (#42)
- (markdown) keep indented inner fences as code body (#55)
- (pandoc) write in-process when FFI exports a writer (#63)
- (pandoc) refuse comments and snapper pragmas instead of dropping them (#62)
- (rst) join compact list hangs into one prose region (#66)
- (rst) keep two-space directive bodies as structure (#54)
- (rst) keep comment bodies as structure (#52)
- (rst) keep list continuation paragraph hang (#51)
- (rst) keep definition lists as structure (#50)
- (rst) keep simple tables as structure (#49)
- (sentence) markup closer-split needs a real next sentence (#53)
- (i18n) regenerate gettext catalogs for v0.11 docs (#69)
- (pandoc) keep wasm and editors on native parsers (#64)
- (mcp)
#[tool_handler]implementslist_tools/call_tool;initializeadvertises tools and names the serversnapperinstead of the emptyrmcpdefault - (vscode)
vscode-languageclientis a runtime dependency only, sovsce packageships the module the extensionrequires - (vscode)
out/extension.jsis an esbuild bundle (vscodestays external); the VSIX no longer needsnode_modulesat runtime - (ci) release and nvim workflows install cargo-dist from a sha256-pinned archive and Rust via
dtolnay/rust-toolchain; they no longer pipe rustup.sh or cargo-dist-installer.sh intosh - (sentence) a period immediately before Markdown/Org closers (
**,*, backticks,](url)) is a sentence end, so**Bold sentence.** Nextsplits and a hand break survives the next run - (latex)
% snapper:no-preambleand chapter files with no\\begin{document}/\\documentclassare body; class and package files stay preamble - (rst) adjacent
*,-,+,1., and#.list items stay separate regions, so compact lists are not glued onto one line
- (latex)
[latex].verbatim_envs/structure_envs/verbatim_commandsin.snapperrc.tomladd names to the built-in lists (minted/lstlisting/verbatim,NON_PROSE_ENVS,\\verb/\\lstinline); missing keys keep today's defaults. Extra command names are tokenized like\\verbbefore split. No regexother:key - (reflow)
--clause-breaks/clause_breakswithmax_width = 0inserts a newline after every independent-clause mark (,,;,:, em dash,--) that is already followed by whitespace; a one-clause sentence stays one line;max_width > 0keeps wrap-prefer-clause. Tokens such as1,000, URLs,--flags, and unspaced dashes never split.--checkuses the same mode - (cli / check)
--check --output-format json|sarifemits 1-indexedfused/wrap/longdiagnostics with excerpts;longis advisory unless--strict-long; stdin--checkhonors the same JSON/SARIF and exit codes; SARIF URIs are repo-relative (orfile:plusinvocations[0].workingDirectory) - (mcp)
mcpis a default feature, so publishedsnapper/snapper-fmtbinaries include the stdio server; agents should call it (or the CLI) instead of applying sembr/skills by hand - (mcp)
format_textacceptsclause_breaks,range(start/end, 1-indexed inclusive), andmax_width(default 0) - (mcp)
check_formattingacceptsclause_breaks(default false) and returnswould_reformatidentical to CLI--check, plus the same line diagnostics - (safety) native parsers record source byte ranges and splice reflowed prose into the original document; Structure/Code/Blank are input slices
- (safety)
format_textruns to a byte fixpoint (cap 4, including A/B cycles) or returns the original; a format-local oracle (region-kind + slice tree; Markdown HTML plus a code-byte check) mismatch also returns the original - (safety)
format_bytesrefuses invalid UTF-8 withInvalidUtf8Error;--use-pandocrefuses (PandocCannotSplice) because the AST has no source offsets - (safety) property tests and a
cargo fuzztarget (fixture corpus) driveformat_textper format with the backstops off - (code-block) comment reflow copies non-comment lines as original slices; only comment spans are rewritten
- (latex) render oracle and
--checkpayloads honor[latex]extras, so a configured\\Verb!%!is not a comment and production backstops no longer revert the file - (latex) tokenize
\\verb/\\lstinline(optional[...]) before split so inner%is not a comment and inner.!?do not split; unmatched\\verbruns to EOL; unlisted\\begin/\\endare region bounds (optional[...]stays on the begin token); mid-line\\begin{equation}leaves leading words as prose; nested same-name envs (including verbatim/lstlisting) close on matching depth, so\\end{python}inside lstlisting does not steal the closer; listing body scans raw\\begin/\\end(no%stop, no\\verbskip) soprint(1) % \\end{lstlisting}andprint(\"%\")still close - (check) fused and long run on the parser prose payload, so
1. Hello world.andSee Fig. 1. % TODO citeare not false fused - (reflow) splice keeps the trailing space before a mid-line TeX
%comment so that line stays one source line - (reflow)
--max-widthkeeps links, images, inline code, autolinks,$math$, and Org[[...]]on one line (overlong token may sit alone; no hyphen splits); wrap-created lines that the format grammar would read as a new block (fences, thematic breaks,[ref]:, HTML,>foo, LaTeX%/\begin/\section, RST.., Org|, lists) are backslash-escaped in Markdown or skip-cut (loop) elsewhere;<https://...>/<user@host>are autolinks, not HTML openers, so wrap does not inject\\<; skip-cut wins when a\\would corrupt an inline token; wrap measures hanging indent and tests interrupt after it; no NBSP; first line of a list item stays a list; second pass does not accumulate backslashes; the render oracle treats wrap-created Markdown escapes (\-,1\\.) as the source words so splice does not return the original - (reflow) list continuation sentences hang at the marker width so Org rejoins the item on reparse; Markdown quotes repeat the
>prefix (> One./> Two., nested> >) - (latex) a trailing
%eats the newline (TeX nospace join), sofoo%\\nbaris no longer emitted asfoo% bar(which comments outbar); mid-line%comments leave prose - (sentence)
w.r.t.is a multi-word abbreviation;\\(...\\)and$$...$$stay atomic like$...$ - (cli) unknown source extensions (
.rs,.py, no extension) are refused unless--formatis explicit;.txtremains plaintext - (org / sentence) verbatim and inline-code spans pair to the first closer that satisfies Org's border and post rules, so an
=or~inside the span no longer orphans the real closer onto the next line - (sentence) CommonMark
*/**and GFM~~pair by flanking rules, so**the end. Still bold**stays one sentence while**complex**. Equitymay split after the closer - (markdown)
>is kept on each reflowed content line (includingmax_widthwraps; prefix counts toward width); two-space and backslash hard breaks are not joined with a space; a quote hard break does not leave a stray>on the next non-quote line; multiline<!-- ... -->is structure (<!-- snapper:off -->still works)
- README distinguishes snapper from admk/sembr and sembr/skills; crate keywords include
sembrandmarkdown - (markdown / sentence) inline code delimited by two or more backticks can contain a shorter backtick run
- (code-block) a block-comment closer inside a string no longer ends the comment; quote-sequence closers (
""") still match naively so Python docstrings reflow - (sentence) abbreviation merge does not invent a space before LaTeX
~(soEq.~\ref{}stays attached once org~code~pairing no longer swallows that tilde) - (sentence) restore wrapped placeholders from the outside in, so a markdown-link regex match that contains a paired-span token cannot leak
\x00PHn\x00into output
- Native
format_textrefuses--use-pandoc(PandocCannotSplice); splice needs source offsets the AST does not carry --clause-breakswith the defaultmax_width = 0is SemBr rule 5 (break at existing whitespace after clause punct);max_width > 0still wrap-prefers- Published binaries include the MCP server (
mcpis a default feature)
- (reflow) clause breaks only engage when a sentence exceeds
max_widthand only at whitespace after the punctuation; v0.9.0 split at every clause mark, including inside tokens (1,000,10:30, URLs,--flags, unspaced em dashes), which inserted spaces into rendered output - (cli)
--color autohonors theNO_COLORenvironment variable - (neural) nnsplit model loads are serialized process-wide; concurrent first-use construction could read a partially downloaded model
- v0.9.1 supersedes v0.9.0 on every channel; do not use v0.9.0 with
--clause-breaks RELEASING.mddocuments the release channels and recovery rules;scripts/check_release_ready.shgates version parity, tag hygiene, and the conda sha256
- (cli / diff) global
--color auto|always|neverfor top-level--diff,sdiff, andgit-diff; shared ANSI styling for headers, hunks, additions, and removals (closes #6) - (reflow)
--clause-breaks/clause_breaksconfig: prefer soft breaks after independent-clause punctuation (comma, semicolon, colon, em dash) undermax_width(closes #7)
- Subcommand
--no-colorremains as an alias for--color never --color autohonors theNO_COLORenvironment variable- Clause breaks only apply to sentences that exceed
max_width, and only at whitespace after the punctuation; tokens such as1,000,10:30, URLs, and--flagsnever split
- (pre-commit) ship a real
id: snapperhook (snapper --in-place) with extension-basedfilesmatching; drop leftover SemBrid/entryand invalid identify typeorg - (lockfile) CI asserts
Cargo.tomlpackage version equals thesnapper-fmtentry inCargo.lockand thatcargo metadata --lockedsucceeds (catches the 0.7.9 tag skew)
- (cli) install
snapper-fmtas a second binary name (same program assnapper) so hosts that already own openSUSE'ssnappercan call the formatter without PATH surgery
- Installation: name collision with openSUSE snapper; prefer
snapper-fmton those systems - Pre-commit section: which extensions the hook matches and that Rust is required to build it
- (pandoc) optional
--use-pandocpath: parse with pandoc (CLI JSON or in-process FFI), classify regions from AST node kinds, reflow only prose (Para/Plain); structure (headers, code fences, tables, lists, math islands) preserved - (pandoc)
--pandoc-backend auto|ffi|cli(default auto: prefer warm FFI when available, else CLI); explicitffifails closed if the library is missing - (pandoc) content-addressed AST cache (
SNAPPER_PANDOC_CACHE/SNAPPER_PANDOC_CACHE_DIR) - (pandoc-colink) opt-in Cargo feature: absorb
libsnapper_pandoc.afromnative/snapper-pandoc/build-static.sh(ghc -staticlib) into onesnapperbinary — noSNAPPER_PANDOC_LIBdiscovery, nolibHS*RUNPATH graph; not enabled by default (default/cargo-dist remain GHC-free)
- (org / latex) keep full headline and sectioning lines as Structure (do not reflow multi-sentence titles; no orphan title lines without stars / mid-brace splits)
- (markdown) keep setext headings (title +
=/-underline) as Structure so multi-sentence titles do not reflow and underlines are not glued onto title text - (ci) exclude
pandoc-colinkfrom WASM feature matrix (--all-featurespanic without static archive); colink still fail-closed in main CI
- Native flib README: static archive vs shared dlopen; howto orgmode pandoc backend; UPX is optional packer only (not used in release)
- Formats reference: Org headlines, LaTeX sectioning, Markdown ATX and setext headings are full Structure lines
- AST fixture tests (JSON on disk) run without pandoc binary; live CLI/FFI parity tests skip cleanly when neither is installed; CI asserts colink without
.afails with archive message; defaultcargo teststays green without GHC - Unit and format_text coverage for multi-sentence Org headlines, LaTeX
\section{...}titles, and Markdown setext
- Plain release binaries stay ~16 MiB class; static-colink builds are larger (~64 MiB class on linux) and optional for multi-format in-process use
- (markdown) keep ATX headings as a single Structure line (do not reflow titles after
### 1.or mid-heading periods; fixes orphan### N.lines, snapper-25kc)
- Unit and integration coverage for numbered ATX headings with inline code
- (wasm / word) local
wasm-packbuild ofpackages/snapper-wasmand Word add-indist/for sideload; VS Code extension published 0.7.8 to Marketplace - (parser)
Region::Codefor Org/Markdown/LaTeX/RST source blocks;[code.<lang>]comment reflow and optional--format-code - (sentence) delimiter-span post-pipeline (quotes, parens, brackets); shared by rules and
--neural - (sentence) neural path protects inline tokens (links, emphasis, …) before the model, then restores and refines
- (cli) multi-file splitter reuse (one build per format/lang/neural/extras key); parallel multi-file always
- (reflow) parallel region reflow for large documents (
clifeature, ≥32 regions)
- (org / sentence) trailing
>on headings; org emphasis not pseudo-headlines; space-safe segment glue after neural cuts
- Span policy in formats reference; README/pre-commit pin v0.7.8; MCP/site/VS Code code-block accuracy
sentence_delim_propsmatrix + proptest; multi-format and code-comment span tests; CI dogfoodsnapper --checkon docs/examples
- (config) honor project config across cli and watch - (5f5179d) - HaoZeke
- (markdown) join list-item continuation lines before sentence splitting - (8e45528) - HaoZeke