Repository navigation
Simplify Paragraph#substitute - #201
Merged
Merged
Conversation
Split the substitution loop into private helpers so #substitute reads as "find the next match, replace it, move on": - find_match returns the next non-empty match of the paragraph text - replace_text_range replaces a range of the paragraph text across its w:t nodes (using one boundaries array instead of offsets + lengths) - text_nodes collects the paragraph's w:t in document order No behavior change. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mutation check showed no spec failed when the guard against empty matches was removed, although without it a pattern like /x*/ loops forever. Pin the existing behavior, under a timeout so a regression fails instead of hanging. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
After #199,
Paragraph#substitutedid everything in one ~40-lineloop do … break … end:w:tnodes and compute their offsetsw:tthe match spansThat made it hard to see what the method does.
What
The method body is now just "find the next match, replace it, move on":
with private helpers:
find_match(pattern, from): the next match in the paragraph text, ornil. An empty match also givesnil, the same as the previousbreak.replace_text_range(range, string): replaces a range of the paragraph text across itsw:tnodes. A singleboundariesarray (texts[i]spansboundaries[i]...boundaries[i + 1]) replaces the separate offsets and length arithmetic, and the single-node case returns early.text_nodes: the paragraph'sw:tin document order.No behavior change. The only cost is that the
w:tXPath runs twice per match instead of once.Verification
search_fromadvance makes the "does not re-match" spec loop forever, so it is detected, but as a hang rather than a failure./x*/then loops forever. This PR adds a spec for it, run under a timeout so a regression fails instead of hanging.🤖 Generated with Claude Code