Skip to content

Commit fce0bc1

Browse files
authored
Merge pull request #108 from DEFRA/feat/DF-721-generate-and-send-answers-with-confirmation-email-receipt
More Escaping
2 parents 8c77af8 + d26c2f3 commit fce0bc1

3 files changed

Lines changed: 80 additions & 3 deletions

File tree

docs/notify.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ A more advanced escape function was required and has been developed with the fol
3333
- Single and double quotes are escaped with a backslash (eg `'` becomes `\'` and `"` becomes `\"`), first escaping any backslashes that would be escape characters for the quotes.
3434
- WARNING: Notify only supports up to 2 consecutive backslashes before quotes without formating issues and supporting that adds needless complexity.
3535
- NOTE: When escaping the backslash in `\'` for Notify, it needs to be escaped with an additional two backslashes, because Notify treats `\\'` the same as `\'` which results in no backslash in the final output.
36+
- A number followed by a period at the start of a line is escaped with a backslash (eg `1.` becomes `\1.`).
3637

3738
### E-mail Body Content to Test Escaping
3839

@@ -102,5 +103,14 @@ _ abc _ def abc_ def abc _def abc_def abc _ def
102103
103104
## Exclamation (!)
104105
! abc ! def abc! def abc !def abc!def abc ! def
106+
107+
## Numbered List
108+
1.1 First item
109+
110+
2. Second item
111+
112+
3.2 Third item
113+
114+
4. Fourth item with leading spaces
105115
`
106116
```

src/lib/notify.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ export function escapeFileLabel(str) {
6363

6464
/**
6565
* Advanced escape function for Markdown content with the following rules:
66-
* - A `-` or `*` or `#` character at the start of a line is escaped with a backslash.
66+
* - A `-` or `*` or `#` character at the start of a line (ignoring leading whitespace) is escaped with a backslash.
67+
* - A number immediately followed by a period at the start of a line (ignoring leading whitespace) has the period escaped with a backslash (e.g., `1.` becomes `1\.`).
6768
* - Tab characters are replaced with 4 HTML encoded spaces (` `).
6869
* - A `-` character surrounded by spaces or tabs has those spaces or tabs replaced with HTML encoded spaces (` `).
6970
* - ``` being the only content on a single line is replaced with ` ` `
@@ -92,8 +93,14 @@ export function escapeContent(str) {
9293
return line.replace('```', '` ` `')
9394
}
9495

95-
// Rule: A `-` or `*` or `#` character at the start of a line is escaped with a backslash
96-
const processedLine = line.replace(/^([-*#])/, String.raw`\$1`)
96+
// Rule: A `-` or `*` or `#` character at the start of a line (allowing leading whitespace) is escaped with a backslash
97+
let processedLine = line.replace(/^([ \t]*)([-*#])/, String.raw`$1\$2`)
98+
99+
// Rule: A number immediately followed by a period at the start of a line (allowing leading whitespace) has the period escaped
100+
processedLine = processedLine.replace(
101+
/^([ \t]*)(\d+)\./,
102+
String.raw`$1$2\.`
103+
)
97104

98105
return processedLine
99106
})

src/lib/notify.test.js

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,5 +241,65 @@ describe('Utils: Notify', () => {
241241
const result = escapeContent(input)
242242
expect(result).toBe('He said: \\\\\\\\\\"it\\\\\\\\\\\'s fine\\\\\\\\\\"')
243243
})
244+
245+
it('should escape period after number at start of line', () => {
246+
expect(escapeContent('1.1 abc')).toBe('1\\.1 abc')
247+
})
248+
249+
it('should escape period after number at start of line with no following content', () => {
250+
expect(escapeContent('3.')).toBe('3\\.')
251+
})
252+
253+
it('should not escape period when space between number and period at start of line', () => {
254+
expect(escapeContent('1 . abc')).toBe('1 . abc')
255+
})
256+
257+
it('should not escape number-period sequence in the middle of text', () => {
258+
expect(escapeContent('abc 1.1 hello')).toBe('abc 1.1 hello')
259+
})
260+
261+
it('should escape number-period on multiple lines', () => {
262+
expect(escapeContent('1. first\n2. second\n3. third')).toBe(
263+
'1\\. first\n2\\. second\n3\\. third'
264+
)
265+
})
266+
267+
it('should escape multi-digit number followed by period at start of line', () => {
268+
expect(escapeContent('123.456')).toBe('123\\.456')
269+
})
270+
271+
it('should escape hyphen with leading spaces', () => {
272+
expect(escapeContent(' - list item')).toBe(' \\- list item')
273+
})
274+
275+
it('should escape hyphen with leading tab', () => {
276+
expect(escapeContent('\t- list item')).toBe(
277+
'    \\- list item'
278+
)
279+
})
280+
281+
it('should escape asterisk with leading spaces', () => {
282+
expect(escapeContent(' *bold')).toBe(' \\*bold')
283+
})
284+
285+
it('should escape hash with leading spaces', () => {
286+
expect(escapeContent(' #heading')).toBe(' \\#heading')
287+
})
288+
289+
it('should escape number-period with leading spaces', () => {
290+
expect(escapeContent(' 1. item')).toBe(' 1\\. item')
291+
})
292+
293+
it('should escape number-period with leading tab', () => {
294+
expect(escapeContent('\t1. item')).toBe(
295+
'    1\\. item'
296+
)
297+
})
298+
299+
it('should escape indented numbered list across multiple lines', () => {
300+
expect(escapeContent(' 1. first\n 2. second')).toBe(
301+
' 1\\. first\n 2\\. second'
302+
)
303+
})
244304
})
245305
})

0 commit comments

Comments
 (0)