From a1ca871b24df4ecbe7c227c0743d585342c6101f Mon Sep 17 00:00:00 2001
From: Robert Dyer <rdyer@unl.edu>
Date: Wed, 14 Aug 2024 12:40:06 -0500
Subject: [PATCH] Allow escaping tags with double ##. (#3246)

* Allow escaping tags with double ##.

* add release note

* convert '#' to '##' in bank sync-generated notes
---
 .../src/components/transactions/TransactionList.jsx       | 2 +-
 .../src/components/transactions/TransactionsTable.jsx     | 7 +++++++
 packages/loot-core/src/server/accounts/sync.ts            | 8 +++++---
 upcoming-release-notes/3246.md                            | 6 ++++++
 4 files changed, 19 insertions(+), 4 deletions(-)
 create mode 100644 upcoming-release-notes/3246.md

diff --git a/packages/desktop-client/src/components/transactions/TransactionList.jsx b/packages/desktop-client/src/components/transactions/TransactionList.jsx
index 137cc61bc..9b3eb7895 100644
--- a/packages/desktop-client/src/components/transactions/TransactionList.jsx
+++ b/packages/desktop-client/src/components/transactions/TransactionList.jsx
@@ -192,7 +192,7 @@ export function TransactionList({
     onApplyFilter({
       field: 'notes',
       op: 'matches',
-      value: `(^|\\s|\\w|#)${escapeRegExp(tag)}($|\\s|#)`,
+      value: `(^|\\s|\\w)${escapeRegExp(tag)}($|\\s|#)`,
       type: 'string',
     });
   });
diff --git a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx
index b5a445ea9..c421da17e 100644
--- a/packages/desktop-client/src/components/transactions/TransactionsTable.jsx
+++ b/packages/desktop-client/src/components/transactions/TransactionsTable.jsx
@@ -2494,6 +2494,7 @@ function notesTagFormatter(notes, onNotesTagClick) {
       {words.map((word, i, arr) => {
         const separator = arr.length - 1 === i ? '' : ' ';
         if (word.includes('#') && word.length > 1) {
+          let lastEmptyTag = -1;
           // Treat tags in a single word as separate tags.
           // #tag1#tag2 => (#tag1)(#tag2)
           // not-a-tag#tag2#tag3 => not-a-tag(#tag2)(#tag3)
@@ -2503,9 +2504,15 @@ function notesTagFormatter(notes, onNotesTagClick) {
             }
 
             if (!tag) {
+              lastEmptyTag = ti;
               return '#';
             }
 
+            if (lastEmptyTag === ti - 1) {
+              return `${tag} `;
+            }
+            lastEmptyTag = -1;
+
             const validTag = `#${tag}`;
             return (
               <span key={`${validTag}${ti}`}>
diff --git a/packages/loot-core/src/server/accounts/sync.ts b/packages/loot-core/src/server/accounts/sync.ts
index b83c5ddd6..cf2e25197 100644
--- a/packages/loot-core/src/server/accounts/sync.ts
+++ b/packages/loot-core/src/server/accounts/sync.ts
@@ -272,6 +272,10 @@ async function normalizeBankSyncTransactions(transactions, acctId) {
 
     trans.cleared = Boolean(trans.booked);
 
+    const notes =
+      trans.remittanceInformationUnstructured ||
+      (trans.remittanceInformationUnstructuredArray || []).join(', ');
+
     normalized.push({
       payee_name: trans.payeeName,
       trans: {
@@ -279,9 +283,7 @@ async function normalizeBankSyncTransactions(transactions, acctId) {
         payee: trans.payee,
         account: trans.account,
         date: trans.date,
-        notes:
-          trans.remittanceInformationUnstructured ||
-          (trans.remittanceInformationUnstructuredArray || []).join(', '),
+        notes: notes.trim().replace('#', '##'),
         imported_id: trans.transactionId,
         imported_payee: trans.imported_payee,
         cleared: trans.cleared,
diff --git a/upcoming-release-notes/3246.md b/upcoming-release-notes/3246.md
new file mode 100644
index 000000000..6a03af438
--- /dev/null
+++ b/upcoming-release-notes/3246.md
@@ -0,0 +1,6 @@
+---
+category: Enhancements
+authors: [psybers]
+---
+
+Allow escaping tags with double ##.
-- 
GitLab