UNPKG

upfront-editable

Version:
137 lines (116 loc) 4.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.replaceAllQuotes = replaceAllQuotes; var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray")); var doubleQuotePairs = [['«', '»'], // ch german, french ['»', '«'], // danish ['"', '"'], // danish, not specified ['“', '”'], // english US ['”', '”'], // swedish ['“', '“'], // chinese simplified ['„', '“'] // german ]; var singleQuotePairs = [['‘', '’'], // english UK ['‹', '›'], // ch german, french ['‚', '‘'], // german ['’', '’'], // swedish ['›', '‹'], // danish ["'", "'"], // danish, not specified ["\u2018", "\u2019"] // chinese simplified ]; var apostrophe = ['’', // german "'" // default ]; var quotesRegex = /([‘’‹›‚'«»"“”„])(?![^<]*?>)/g; // whitespace end of tag, or any dash (normal, en or em-dash) // or any opening double quote var beforeOpeningQuote = /\s|[>\-–—«»”"“„]/; // whitespace begin of tag, or any dash (normal, en or em-dash) // or any closing quote, or any punctuation var afterClosingQuote = /\s|[<\-–—«»”"“‘’‹›'.;?:,]/; var replacements; function replaceAllQuotes(str, replaceQuotesRules) { replacements = replaceQuotesRules || {}; replacements.quotes = replacements.quotes || [undefined, undefined]; replacements.singleQuotes = replacements.singleQuotes || [undefined, undefined]; var matches = getAllQuotes(str); if (matches.length > 0) { replaceMatchedQuotes(matches, 0); return replaceExistingQuotes(str, matches); } return str; } function replaceMatchedQuotes(matches, position) { while (position < matches.length) { var closingTag = findClosingQuote(matches, position); if (closingTag) { matches[position].replace = closingTag.type === 'double' ? replacements.quotes[0] : replacements.singleQuotes[0]; matches[closingTag.position].replace = closingTag.type === 'double' ? replacements.quotes[1] : replacements.singleQuotes[1]; if (closingTag.position !== position + 1) { var nestedMatches = matches.slice(position + 1, closingTag.position); if (nestedMatches) { replaceMatchedQuotes(nestedMatches, 0); } } position = closingTag.position + 1; } else { matches[position].replace = replaceApostrophe(matches[position]["char"]); position += 1; } } } function findClosingQuote(matches, position) { if (position === matches.length - 1) return; var current = matches[position]; var openingQuote = current["char"]; if (current.before && !beforeOpeningQuote.test(current.before)) return; var possibleClosingSingleQuotes = getPossibleClosingQuotes(openingQuote, singleQuotePairs); var possibleClosingDoubleQuotes = getPossibleClosingQuotes(openingQuote, doubleQuotePairs); for (var i = position + 1; i < matches.length; i++) { if (matches[i].after && afterClosingQuote.test(matches[i].after) || !matches[i].after) { if (possibleClosingSingleQuotes.includes(matches[i]["char"])) { return { position: i, type: 'single' }; } if (possibleClosingDoubleQuotes.includes(matches[i]["char"])) { return { position: i, type: 'double' }; } } } } function getPossibleClosingQuotes(openingQuote, pairs) { return pairs.filter(function (quotePair) { return quotePair[0] === openingQuote; }).map(function (quotePair) { return quotePair[1]; }); } function replaceApostrophe(quote) { if (apostrophe.includes(quote)) { return replacements.apostrophe; } } function getAllQuotes(str) { return (0, _toConsumableArray2["default"])(str.matchAll(quotesRegex)).map(function (match) { var index = match.index; return { "char": match[1], before: index > 0 ? str[index - 1] : '', after: index + 1 < str.length ? str[index + 1] : '' }; }); } function replaceExistingQuotes(str, matches) { var index = 0; return str.replace(quotesRegex, function (match) { var replacement = matches[index].replace || matches[index]["char"]; index += 1; return replacement; }); }