Created
April 24, 2024 14:48
Curl quotes (transform straight quotes into curly ones) (PHP5)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function curl_quotes($str) { | |
// Adapted from: https://github.com/kellym/smartquotes.js/blob/master/lib/replacements.js | |
// Single quotes | |
$sx = "'"; // straight (\u0027) | |
$s1 = "‘"; // Opening (\u2018) | |
$s2 = "’"; // Closing (\u2019) | |
// Double quotes | |
$dx = '"'; // straight (\u0022) | |
$d1 = "“"; // Opening (\u201C) | |
$d2 = "”"; // Closing (\u201D) | |
// Primes | |
$prime1 = '′'; // Single prime, also for ft (\u2032) | |
$prime2 = '″'; // Double prime (\u2033) | |
$prime3 = '‴'; // Triple prime (\u2034) | |
$prime4 = '⁗'; // Quadruple prime (\u2057) | |
// word character range | |
$wcr = 'a-zA-ZáàâäãåçéèêëíìîïñóòôöõúùûüýÿæœÁÀÂÄÃÅÇÉÈÊËÍÌÎÏÑÓÒÔÖÕÚÙÛÜÝŸÆŒ'; | |
// word groups | |
$word = "[${wcr}_0-9]"; | |
$nonword = "[^${wcr}_0-9]"; | |
// quadruple prime | |
$str = preg_replace( | |
"/${sx}${sx}${sx}${sx}/i", | |
"${prime4}", | |
$str | |
); | |
// triple prime | |
// [/'''/g, retainLength => '\u2034' + (retainLength ? '\u2063\u2063' : '')], | |
$str = preg_replace( | |
"/${sx}${sx}${sx}/i", | |
"${prime3}", | |
$str | |
); | |
// beginning " | |
// [new RegExp(`(${nonWord}|^)"(${word})`, 'g'), '$1\u201c$2'], | |
// Using preg_replace_callback to support multiple straight quotes in a row | |
$str = preg_replace_callback( | |
"/(${nonword}|^)(${dx}+)(${word})/", | |
function ($match) use ($d1) { | |
return $match[1].str_repeat($d1, strlen($match[2])).$match[3]; | |
}, | |
$str | |
); | |
// ending " | |
// [/(\u201c[^"]*)"([^"]*$|[^\u201c"]*\u201c)/g, '$1\u201d$2'], | |
// Using preg_replace_callback to support multiple straight quotes in a row | |
$str = preg_replace_callback( | |
"/(${d1}[^${dx}]*)(${dx}+)([^${dx}]*$|[^${d1}${dx}]*${d1})/", | |
function ($match) use ($d2) { | |
return $match[1].str_repeat($d2, strlen($match[2])).$match[3]; | |
}, | |
$str | |
); | |
// remaining " at end of word | |
// [/([^0-9])"/g, '$1\u201d'], | |
// Using preg_replace_callback to support multiple straight quotes in a row | |
$str = preg_replace_callback( | |
"/([^0-9])(${dx}+)/", | |
function ($match) use ($d2) { | |
return $match[1].str_repeat($d2, strlen($match[2])); | |
}, | |
$str | |
); | |
// double prime as two single quotes | |
// [/''/g, retainLength => '\u2033' + (retainLength ? '\u2063' : '')], | |
$str = preg_replace( | |
"/${sx}${sx}/i", | |
"${prime2}", | |
$str | |
); | |
// beginning ' | |
// [new RegExp(`(${nonWord}|^)'(\\S)`, 'g'), '$1\u2018$2'], | |
$str = preg_replace( | |
"/(${nonword}|^)${sx}([^\s])/", | |
"$1${s1}$2", | |
$str | |
); | |
// conjunction's possession | |
// [new RegExp(`(${word})'([${pL}])`, 'ig'), '$1\u2019$2'], | |
$str = preg_replace( | |
"/(${word})${sx}(${wcr})/i", | |
"$1${s2}$2", | |
$str | |
); | |
// abbrev. years like '93 | |
// [new RegExp(`(\\u2018)([0-9]{2}[^\\u2019]*)(\\u2018([^0-9]|$)|$|\\u2019[${pL}])`, 'ig'), '\u2019$2$3'], | |
$str = preg_replace( | |
"/(${s1})([0-9]{2}[^${s2}]*)(${s1}([^0-9]|$)|$|${s2}[${wcr}])/i", | |
"${s2}$2$3", | |
$str | |
); | |
// ending ' | |
// [new RegExp(`((\\u2018[^']*)|[${pL}])'([^0-9]|$)`, 'ig'), '$1\u2019$3'], | |
$str = preg_replace( | |
"/((${s1}[^']*)|[${wcr}])'([^0-9]|$)/", | |
"$1${s2}$3", | |
$str | |
); | |
// backwards apostrophe | |
// [new RegExp(`(\\B|^)\\u2018(?=([^\\u2018\\u2019]*\\u2019\\b)*([^\\u2018\\u2019]*\\B${nonWord}[\\u2018\\u2019]\\b|[^\\u2018\\u2019]*$))`, 'ig'), '$1\u2019'], | |
// AAAAAAHHHHHH I HAVE NO IDEA WHAT THIS DOES | |
$str = preg_replace( | |
"/(\\B|^)${s1}(?=([^${s1}${s2}]*${s2}\\b)*([^${s1}${s2}]*\\B${nonword}[${s1}${s2}]\\b|[^${s1}${s2}]*$))/i", | |
"$1${s2}$3", | |
$str | |
); | |
// double prime | |
// [/"/g, '\u2033'], | |
$str = preg_replace( | |
"/${dx}/i", | |
"${prime2}", | |
$str | |
); | |
// prime | |
//[/'/g, '\u2032'] | |
$str = preg_replace( | |
"/${sx}/i", | |
"${prime1}", | |
$str | |
); | |
return $str; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment