Skip to content

Commit 262991e

Browse files
fix: add check on closing quote
1 parent 2b4ec42 commit 262991e

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

spec/clipboard.spec.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -302,6 +302,42 @@ describe('Clipboard', function () {
302302
expect(block).toEqual(`It’s a cat’s world.`)
303303
})
304304

305+
it('does not replace two apostrophe with quotes inside quotes', function () {
306+
const updatedConfig = cloneDeep(config)
307+
updatedConfig.pastedHtmlRules.replaceQuotes = {
308+
quotes: ['«', '»'],
309+
singleQuotes: ['‹', '›'],
310+
apostrophe: '’'
311+
}
312+
313+
updateConfig(updatedConfig)
314+
const block = extractSingleBlock(`'It's a cat's world.'`)
315+
expect(block).toEqual(`‹It’s a cat’s world.›`)
316+
})
317+
318+
it('does not replace apostrophe at the beginning or end with quotes', function () {
319+
const updatedConfig = cloneDeep(config)
320+
updatedConfig.pastedHtmlRules.replaceQuotes = {
321+
quotes: ['«', '»'],
322+
singleQuotes: ['‹', '›'],
323+
apostrophe: '’'
324+
}
325+
326+
updateConfig(updatedConfig)
327+
const block = extractSingleBlock(`Can I ask you somethin'? “'Twas the night before Christmas,” he said.`)
328+
expect(block).toEqual(`Can I ask you somethin’? «’Twas the night before Christmas,» he said.`)
329+
})
330+
331+
it('does not replace apostrophe at the beginning or end with quotes', function () {
332+
const block = extractSingleBlock(`Gehen S' 'nauf!`)
333+
expect(block).toEqual(`Gehen S’ ’nauf!`)
334+
})
335+
336+
it('replaces quotes with punctuation after the closing quote', function () {
337+
const block = extractSingleBlock(`Beginning of the sentence "inside quote".`)
338+
expect(block).toEqual(`Beginning of the sentence “inside quote”.`)
339+
})
340+
305341
it('replaces nested quotes with single quotes inside nested', function () {
306342
const block = extractSingleBlock(`text outside "text 'inside „second inside text“'"`)
307343
expect(block).toEqual('text outside “text ‘inside “second inside text”’”')

src/quotes.js

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ const quotesRegex = /([‘’‹›‚'«»"“”„])(?![^<]*?>)/g
2525
// whitespace end of tag, or any dash (normal, en or em-dash)
2626
// or any opening double quote
2727
const beforeOpeningQuote = /\s|[>\-«»"]/
28+
29+
// whitespace begin of tag, or any dash (normal, en or em-dash)
30+
// or any closing quote, or any punctuation
31+
const afterClosingQuote = /\s|[<\-«»"'.;?:,]/
2832
let replacements
2933

3034
export function replaceAllQuotes (str, replaceQuotesRules) {
@@ -80,11 +84,13 @@ function findClosingQuote (matches, position) {
8084
const possibleClosingSingleQuotes = getPossibleClosingQuotes(openingQuote, singleQuotePairs)
8185
const possibleClosingDoubleQuotes = getPossibleClosingQuotes(openingQuote, doubleQuotePairs)
8286
for (let i = position + 1; i < matches.length; i++) {
83-
if (possibleClosingSingleQuotes.includes(matches[i].char)) {
84-
return {position: i, type: 'single'}
85-
}
86-
if (possibleClosingDoubleQuotes.includes(matches[i].char)) {
87-
return {position: i, type: 'double'}
87+
if ((matches[i].after && afterClosingQuote.test(matches[i].after)) || !matches[i].after) {
88+
if (possibleClosingSingleQuotes.includes(matches[i].char)) {
89+
return {position: i, type: 'single'}
90+
}
91+
if (possibleClosingDoubleQuotes.includes(matches[i].char)) {
92+
return {position: i, type: 'double'}
93+
}
8894
}
8995
}
9096
}

0 commit comments

Comments
 (0)