string-apostrophes
Version:
Comprehensive, HTML-entities-aware tool to typographically-correct the apostrophes and single/double quotes
11 lines (9 loc) • 7.12 kB
JavaScript
/**
* @name string-apostrophes
* @fileoverview Comprehensive, HTML-entities-aware tool to typographically-correct the apostrophes and single/double quotes
* @version 4.1.0
* @author Roy Revelt
* @license MIT
* {@link https://codsen.com/os/string-apostrophes/}
*/
import{rApply as q}from"ranges-apply";import{leftSingleQuote as m,rightSingleQuote as l,leftDoubleQuote as p,rightDoubleQuote as t,singlePrime as g,doublePrime as f,punctuationChars as E,isNumberChar as b,isLetter as c}from"codsen-utils";var h="4.1.0";var P=h,d={convertEntities:!1,convertApostrophes:!0};function V(o,$){if(typeof o!="string")throw new Error(`string-apostrophes/convertOne(): [THROW_ID_01] first input argument should be string! It's been passed as ${o} (its typeof ${typeof o})`);if(typeof $!="object"||Array.isArray($))throw new Error(`string-apostrophes/convertOne(): [THROW_ID_02] options object should be a plain object. It has was passed as ${JSON.stringify($,null,4)} (its typeof is ${typeof $})`);if(!Number.isInteger($.from)||$.from<0)throw new Error(`string-apostrophes/convertOne(): [THROW_ID_03] options objects key "to", a starting string index, should be a natural number! It was given as ${$.from} (its typeof is ${typeof $.from})`);if($.from>=o.length)throw new Error(`string-apostrophes/convertOne(): [THROW_ID_04] opts.from is beyond str length! opts.from was passed as ${$.from} and str.length is ${o.length}`);let{from:s=0,to:e,value:r,convertEntities:n,convertApostrophes:u,offsetBy:a}={...d,...$};Number.isInteger(e)||(e=s+1);let i=[];return r&&["'",m,l,g].includes(r)||e===s+1&&["'",m,l,g].includes(o[s])?o[s-1]&&o[e]&&b(o[s-1])&&!c(o[e])?u&&o.slice(s,e)!==(n?"′":g)&&r!==(n?"′":g)?i.push([s,e,n?"′":g]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):o[e]&&o[e+1]&&o[e]==="n"&&o.slice(s,e)===o.slice(e+1,e+1+(e-s))?u&&o.slice(s,e+2)!==(n?"’n’":`${l}n${l}`)&&r!==(n?"’n’":`${l}n${l}`)?(i.push([s,e+2,n?"’n’":`${l}n${l}`]),typeof a=="function"&&a(2)):!u&&o.slice(s,e+2)!=="'n'"&&r!=="'n'"&&(i.push([s,e+2,"'n'"]),typeof a=="function"&&a(2)):o[e]&&o[e].toLowerCase()==="t"&&(!o[e+1]?.trim()||o[e+1].toLowerCase()==="i")||o[e]&&o[e+2]&&o[e].toLowerCase()==="t"&&o[e+1].toLowerCase()==="w"&&(o[e+2].toLowerCase()==="a"||o[e+2].toLowerCase()==="e"||o[e+2].toLowerCase()==="i"||o[e+2].toLowerCase()==="o")||o[e]&&o[e+1]&&o[e].toLowerCase()==="e"&&o[e+1].toLowerCase()==="m"||o[e]&&o[e+4]&&o[e].toLowerCase()==="c"&&o[e+1].toLowerCase()==="a"&&o[e+2].toLowerCase()==="u"&&o[e+3].toLowerCase()==="s"&&o[e+4].toLowerCase()==="e"||o[e]&&b(o[e])?u&&o.slice(s,e)!==(n?"’":l)&&r!==(n?"’":l)?i.push([s,e,n?"’":l]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):o[s-1]&&o[e]&&E.includes(o[s-1])?o[e].trim()?o[e]==='"'&&o[e+1]&&!o[e+1].trim()&&(u&&o.slice(s,e+1)!==(n?"’”":`${l}${t}`)&&r!==(n?"’”":`${l}${t}`)?(i.push([s,e+1,`${n?"’”":`${l}${t}`}`]),typeof a=="function"&&a(1)):!u&&o.slice(s,e+1)!==`'"`&&r!==`'"`&&(i.push([s,e+1,`'"`]),typeof a=="function"&&a(1))):u&&o.slice(s,e)!==(n?"’":l)&&r!==(n?"’":l)?i.push([s,e,n?"’":l]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):s===0&&o.slice(e).trim()?u&&o.slice(s,e)!==(n?"‘":m)&&r!==(n?"‘":m)?i.push([s,e,n?"‘":m]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):!o[e]&&o.slice(0,s).trim()?u&&o.slice(s,e)!==(n?"’":l)&&r!==(n?"’":l)?i.push([s,e,n?"’":l]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):o[s-1]&&o[e]&&(c(o[s-1])||b(o[s-1]))&&(c(o[e])||b(o[e]))?u?(o[e]&&o[s-5]&&o[s-5].toLowerCase()==="h"&&o[s-4].toLowerCase()==="a"&&o[s-3].toLowerCase()==="w"&&o[s-2].toLowerCase()==="a"&&o[s-1].toLowerCase()==="i"&&o[e].toLowerCase()==="i"||o[s-1]&&o[s-1].toLowerCase()==="o"&&o[e+2]&&o[e].toLowerCase()==="a"&&o[e+1].toLowerCase()==="h"&&o[e+2].toLowerCase()==="u")&&o.slice(s,e)!==(n?"‘":m)&&r!==(n?"‘":m)?i.push([s,e,n?"‘":m]):o.slice(s,e)!==(n?"’":l)&&r!==(n?"’":l)&&i.push([s,e,n?"’":l]):o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):o[e]&&(c(o[e])||b(o[e]))?u&&o.slice(s,e)!==(n?"‘":m)&&r!==(n?"‘":m)?i.push([s,e,n?"‘":m]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):c(o[s-1])||b(o[s-1])?u&&o.slice(s,e)!==(n?"’":l)&&r!==(n?"’":l)?i.push([s,e,n?"’":l]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):o[s-1]&&!o[s-1].trim()?u&&o.slice(s,e)!==(n?"‘":m)&&r!==(n?"‘":m)?i.push([s,e,n?"‘":m]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"]):o[e]&&!o[e].trim()&&(u&&o.slice(s,e)!==(n?"’":l)&&r!==(n?"’":l)?i.push([s,e,n?"’":l]):!u&&o.slice(s,e)!=="'"&&r!=="'"&&i.push([s,e,"'"])):(['"',p,t,f].includes(r)||e===s+1&&['"',p,t,f].includes(o[s]))&&(o[s-1]&&b(o[s-1])&&o[e]&&o[e]!=="'"&&o[e]!=='"'&&o[e]!==l&&o[e]!==t&&o[e]!==m&&o[e]!==p?u&&o.slice(s,e)!==(n?"″":f)&&r!==(n?"″":f)?i.push([s,e,n?"″":f]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):o[s-1]&&o[e]&&E.includes(o[s-1])?o[e].trim()?o[e]==="'"&&o[e+1]&&!o[e+1].trim()&&(u&&o.slice(s,e+1)!==(n?"”’":`${t}${l}`)&&r!==(n?"”’":`${t}${l}`)?(i.push([s,e+1,n?"”’":`${t}${l}`]),typeof a=="function"&&a(1)):!u&&o.slice(s,e+1)!==`"'`&&r!==`"'`&&(i.push([s,e+1,`"'`]),typeof a=="function"&&a(1))):u&&o.slice(s,e)!==(n?"”":t)&&r!==(n?"”":t)?i.push([s,e,n?"”":t]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):s===0&&o[e]&&o.slice(e).trim()?u&&o.slice(s,e)!==(n?"“":p)&&r!==(n?"“":p)?i.push([s,e,n?"“":p]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):!o[e]&&o.slice(0,s).trim()?u&&o.slice(s,e)!==(n?"”":t)&&r!==(n?"”":t)?i.push([s,e,n?"”":t]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):o[e]&&(c(o[e])||b(o[e]))?u&&o.slice(s,e)!==(n?"“":p)&&r!==(n?"“":p)?i.push([s,e,n?"“":p]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):o[s-1]&&(c(o[s-1])||b(o[s-1]))?u&&o.slice(s,e)!==(n?"”":t)&&r!==(n?"”":t)?i.push([s,e,n?"”":t]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):o[s-1]&&!o[s-1].trim()?u&&o.slice(s,e)!==(n?"“":p)&&r!==(n?"“":p)?i.push([s,e,n?"“":p]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']):o[e]&&!o[e].trim()&&(u&&o.slice(s,e)!==(n?"”":t)&&r!==(n?"”":t)?i.push([s,e,n?"”":t]):!u&&o.slice(s,e)!=='"'&&r!=='"'&&i.push([s,e,'"']))),i}function H(o,$){if(typeof o!="string")throw new Error(`string-apostrophes: [THROW_ID_10] first input argument should be string! It's been passed as ${o} (its typeof ${typeof o})`);if($&&(typeof $!="object"||Array.isArray($)))throw new Error(`string-apostrophes: [THROW_ID_11] options object should be a plain object! It was passed as ${JSON.stringify($,null,4)} (its typeof is ${typeof $})`);if(!o)return{result:o,ranges:null};let s=[],e={...d,...$},r=o.length;for(let n=0;n<r;n++){e.from=n,e.offsetBy=a=>{n+=a};let u=V(o,e);Array.isArray(u)&&u.length&&(s=s.concat(u))}return{result:q(o,s),ranges:s}}export{H as convertAll,V as convertOne,d as defaults,P as version};