function EducateQuotes in Typogrify 7
Same name and namespace in other branches
- 5 smartypants.php \EducateQuotes()
- 6 smartypants.php \EducateQuotes()
EducatedQuotes. Example input: "Isn't this fun?" Example output: [0]Isn’t this fun?[1];
Parameters
string $_: Input text.
Return value
string The string, with "educated" curly quote HTML entities.
2 calls to EducateQuotes()
- SmartQuotes in ./
smartypants.php - SmartQuotes
- SmartyPants in ./
smartypants.php - SmartyPants.
File
- ./
smartypants.php, line 831 - SmartyPants - Smart punctuation for web sites
Code
function EducateQuotes($_, $quotes) {
// Make our own "punctuation" character class, because the POSIX-style
// [:PUNCT:] is only available in Perl 5.6 or later:
$punct_class = "[!\"#\\\$\\%'()*+,-.\\/:;<=>?\\@\\[\\\\\\]\\^_`{|}~]";
// Special case if the very first character is a quote
// followed by punctuation at a non-word-break.
// Close the quotes by brute force:
$_ = preg_replace(array(
"/^'(?={$punct_class}\\B)/",
"/^\"(?={$punct_class}\\B)/",
), array(
$quotes[3],
$quotes[1],
), $_);
// Special case for double sets of quotes, e.g.:
// <p>He said, "'Quoted' words in a larger quote."</p>.
$spacer = ' ';
$_ = preg_replace(array(
"/\"'(?=\\p{L})/u",
"/'\"(?=\\p{L})/u",
"/(\\p{L})\"'/u",
"/(\\p{L})'\"/u",
), array(
$quotes[0] . $spacer . $quotes[2],
$quotes[2] . $spacer . $quotes[0],
'\\1' . $quotes[1] . $spacer . $quotes[3],
'\\1' . $quotes[3] . $spacer . $quotes[1],
), $_);
// Special case for decade abbreviations (the '80s):
$_ = preg_replace("/'(?=\\d{2}s)/", '’', $_);
// Special case for apostroph.
$_ = preg_replace("/(\\p{L})(')(?=\\p{L}|\$)/u", '\\1’', $_);
$close_class = '[^\\ \\t\\r\\n\\[\\{\\(\\-]';
$dec_dashes = '&\\#8211;|&\\#8212;';
// Get most opening single quotes:
$_ = preg_replace("{\n (\n \\s | # a whitespace char, or\n | # a non-breaking space entity, or\n -- | # dashes, or\n &[mn]dash; | # named dash entities\n {$dec_dashes} | # or decimal entities\n &\\#x201[34]; # or hex\n )\n ' # the quote\n (?=\\p{L}) # followed by a word character\n }x", '\\1' . $quotes[2], $_);
// Single closing quotes:
$_ = preg_replace("{\n ({$close_class})?\n '\n (?(1)| # If \$1 captured, then do nothing;\n (?=\\s | s\\b) # otherwise, positive lookahead for a whitespace\n ) # char or an 's' at a word ending position. This\n # is a special case to handle something like:\n # \"<i>Custer</i>'s Last Stand.\"\n }xi", '\\1' . $quotes[3], $_);
// Any remaining single quotes should be opening ones:
$_ = str_replace("'", $quotes[2], $_);
// Get most opening double quotes:
$_ = preg_replace("{\n (\n \\s | # a whitespace char, or\n | # a non-breaking space entity, or\n -- | # dashes, or\n &[mn]dash; | # named dash entities\n {$dec_dashes} | # or decimal entities\n &\\#x201[34]; # or hex\n )\n \" # the quote\n (?=\\p{L}) # followed by a word character\n }x", '\\1' . $quotes[0], $_);
// Double closing quotes:
$_ = preg_replace("{\n ({$close_class})?\n \"\n (?(1)|(?=\\s)) # If \$1 captured, then do nothing;\n # if not, then make sure the next char is whitespace.\n }x", '\\1' . $quotes[1], $_);
// Any remaining quotes should be opening ones.
$_ = str_replace('"', $quotes[0], $_);
return $_;
}