From 05863bc8956624209b318cc9e96cc285db8c17df Mon Sep 17 00:00:00 2001 From: mrducky Date: Tue, 25 Aug 2026 14:24:38 +0000 Subject: [PATCH 1/5] Fix issue #1600, allow \\ to escape a backslash in replacement string --- tools/proofers/srchrep.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/tools/proofers/srchrep.js b/tools/proofers/srchrep.js index c06eeaf3e5..4fe4bca1e6 100644 --- a/tools/proofers/srchrep.js +++ b/tools/proofers/srchrep.js @@ -17,7 +17,16 @@ var srchrep = (function () { function doReplace() { var search = document.getElementById("search").value; - var replacetext = document.getElementById("replace").value.replace(new RegExp("\\\\n", "g"), "\r\n"); + // Handle \n for newline. And \ becomes just . So \\ becomes a single \. + var replacetext = document.getElementById("replace").value.replace(/\\(.)/g, (match, esc) => { + switch (esc) { + case "n": + return "\r\n"; + default: + return esc; // anything else, leave as is without the backslash + } + }); + saveText(); if (!document.getElementById("is_regex").checked) { search = escapeRegExp(search); From cf83fc1a09d6fc511b5ff539d9dcc13facecdbcf Mon Sep 17 00:00:00 2001 From: mrducky Date: Fri, 4 Sep 2026 00:30:29 +0000 Subject: [PATCH 2/5] in search/replace, special newline and escaping is only for regex mode --- tools/proofers/srchrep.js | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/tools/proofers/srchrep.js b/tools/proofers/srchrep.js index 4fe4bca1e6..27363dd678 100644 --- a/tools/proofers/srchrep.js +++ b/tools/proofers/srchrep.js @@ -17,23 +17,24 @@ var srchrep = (function () { function doReplace() { var search = document.getElementById("search").value; - // Handle \n for newline. And \ becomes just . So \\ becomes a single \. - var replacetext = document.getElementById("replace").value.replace(/\\(.)/g, (match, esc) => { - switch (esc) { - case "n": - return "\r\n"; - default: - return esc; // anything else, leave as is without the backslash - } - }); + var replacetext = document.getElementById("replace").value; saveText(); if (!document.getElementById("is_regex").checked) { search = escapeRegExp(search); - // Replace $ in replace text with $$ to avoid special replacement patterns. // Note, $ here is in a .replace function and must be escaped so '$$' becomes '$$$$'. replacetext = replacetext.replace(/\$/g, "$$$$"); + } else { + // Handle \n for newline. And \ becomes just . So \\ becomes a single \. + replacetext = replacetext.replace(/\\(.)/g, (match, esc) => { + switch (esc) { + case "n": + return "\r\n"; + default: + return esc; // anything else, leave as is without the backslash + } + }); } opener.parent.docRef.editform.text_data.value = opener.parent.docRef.editform.text_data.value.replace(new RegExp(search, "gum"), replacetext); setUndoButtonDisabled(false); From 08b4af06265970a2d1b2a0716d6e1cc1d38de885 Mon Sep 17 00:00:00 2001 From: mrducky Date: Fri, 4 Sep 2026 00:41:59 +0000 Subject: [PATCH 3/5] Fix srchrep unit test for the new behavior. --- SETUP/tests/jsTests/srchrepTests.js | 1 + 1 file changed, 1 insertion(+) diff --git a/SETUP/tests/jsTests/srchrepTests.js b/SETUP/tests/jsTests/srchrepTests.js index 2340d00629..ae15e2a50a 100644 --- a/SETUP/tests/jsTests/srchrepTests.js +++ b/SETUP/tests/jsTests/srchrepTests.js @@ -99,6 +99,7 @@ QUnit.module("srchrep tests", (hooks) => { setTextValue("Example search -- and replace search text value."); $("#search").val("search"); $("#replace").val("s\\n"); + $("#is_regex").prop("checked", true); srchrep.doReplace(); assert.strictEqual( window.opener.parent.docRef.editform.text_data.value, From 016f35581dc3cde9620ccec2abe60ea528b48e77 Mon Sep 17 00:00:00 2001 From: mrducky Date: Fri, 4 Sep 2026 00:53:47 +0000 Subject: [PATCH 4/5] Add srchrep unit test for \n behavior without regex --- SETUP/tests/jsTests/srchrepTests.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/SETUP/tests/jsTests/srchrepTests.js b/SETUP/tests/jsTests/srchrepTests.js index ae15e2a50a..c884804d51 100644 --- a/SETUP/tests/jsTests/srchrepTests.js +++ b/SETUP/tests/jsTests/srchrepTests.js @@ -108,4 +108,17 @@ QUnit.module("srchrep tests", (hooks) => { ); assert.notOk($("#undo").prop("disabled"), "Undo should be enabled."); }); + + QUnit.test("\\n is just backslash n without regex", function (assert) { + setTextValue("Example search -- and replace search text value."); + $("#search").val("search"); + $("#replace").val("s\\n"); + srchrep.doReplace(); + assert.strictEqual( + window.opener.parent.docRef.editform.text_data.value, + "Example s\\n -- and replace s\\n text value.", + "Search replace replaces with just \\n, not newline, without regex.", + ); + assert.notOk($("#undo").prop("disabled"), "Undo should be enabled."); + }); }); From ddb0bffa0a89d5f838ca8f44af8c90583260db7d Mon Sep 17 00:00:00 2001 From: mrducky Date: Fri, 4 Sep 2026 19:53:22 +0000 Subject: [PATCH 5/5] Update PI help page for search/replace with \n --- faq/prooffacehelp.php | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/faq/prooffacehelp.php b/faq/prooffacehelp.php index 11f48a8677..27ee84b9b1 100644 --- a/faq/prooffacehelp.php +++ b/faq/prooffacehelp.php @@ -619,11 +619,9 @@ function echo_row(string $name, string $tooltip, string $button_image_base, stri [Aa]{6} — six As of either case
A{2,8} — between 2 and 8 capital As
[hb]e — 'he' or 'be'
+ \n — new line

-

- To replace matched text with a new line, \n may be used in the replace field. -

Help