fix(wiki): canonicalize whitespace across a whole section, not just its ends
Review of PR #129 found MergeReport's disagreement check compared strings.TrimSpace(sA.content) against strings.TrimSpace(sB.content) -- only leading/trailing whitespace is tolerated. Every other content comparison in this file (appendNew, mergeBullets) already canonicalizes internal whitespace runs too, because a re-extraction's exact spacing isn't byte-stable (#103). A mid-line double-space would false-positive as a "disagreement" here even though the file's own established tolerance says it shouldn't. canonicalBlock applies the existing canonicalLine per line of a multi-line section body. A genuine content difference is still caught (TestMerge_ReportsSectionsWhereTheFreshVersionWasDiscarded stays green); only internal-whitespace-only variants stop false-positiving. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -84,7 +84,7 @@ func MergeReport(a, b Page) (Page, []string) {
|
||||
secsA[i].content = appendNew(sA.content, sB.content)
|
||||
default:
|
||||
// a wins — but say that b disagreed, rather than dropping it mute.
|
||||
if strings.TrimSpace(sA.content) != strings.TrimSpace(sB.content) {
|
||||
if canonicalBlock(sA.content) != canonicalBlock(sB.content) {
|
||||
conflicts = append(conflicts, sB.heading)
|
||||
}
|
||||
}
|
||||
@@ -329,6 +329,21 @@ func canonicalLine(line string) string {
|
||||
return strings.Join(strings.Fields(line), " ")
|
||||
}
|
||||
|
||||
// canonicalBlock applies canonicalLine per line of a multi-line section body
|
||||
// — the same whitespace-insensitivity appendNew/mergeBullets already give a
|
||||
// single line, extended to a whole section for MergeReport's disagreement
|
||||
// check (found in review, PR #129: comparing raw strings.TrimSpace only
|
||||
// tolerated leading/trailing whitespace, not a re-extraction's mid-line
|
||||
// spacing, which every other comparison in this file already tolerates).
|
||||
func canonicalBlock(block string) string {
|
||||
lines := strings.Split(block, "\n")
|
||||
out := make([]string, len(lines))
|
||||
for i, l := range lines {
|
||||
out[i] = canonicalLine(l)
|
||||
}
|
||||
return strings.Join(out, "\n")
|
||||
}
|
||||
|
||||
// appendNew concatenates the lines of b that a does not already carry.
|
||||
//
|
||||
// Append sections used to concatenate wholesale, which is correct exactly once.
|
||||
|
||||
Reference in New Issue
Block a user