You are here

protected static function SmartyPants::smartQuotes in Typogrify 8

SmartQuotes.

Parameters

string $text: Text to be parsed.

string $attr: Value of the smart_quotes="" attribute.

string $ctx: MT context object (unused).

Return value

string $text with replacements.

File

src/SmartyPants.php, line 385

Class

SmartyPants
SmartyPants - Smart punctuation for web sites.

Namespace

Drupal\typogrify

Code

protected static function smartQuotes($text, $attr = NULL, $ctx = NULL) {
  if ($attr == NULL) {
    $attr = self::$smartypantsAttr;
  }

  // Should we educate ``backticks'' -style quotes?
  $do_backticks;
  if ($attr == 0) {

    // Do nothing.
    return $text;
  }
  elseif ($attr == 2) {

    // Smarten ``backticks'' -style quotes.
    $do_backticks = 1;
  }
  else {
    $do_backticks = 0;
  }

  // Special case to handle quotes at the very end of $text when preceded by
  // an HTML tag. Add a space to give the quote education algorithm a bit of
  // context, so that it can guess correctly that it's a closing quote:
  $add_extra_space = 0;
  if (preg_match("/>['\"]\\z/", $text)) {

    // Remember, so we can trim the extra space later.
    $add_extra_space = 1;
    $text .= " ";
  }
  $tokens = self::tokenizeHtml($text);
  $result = '';

  // Keep track of when we're inside <pre> or <code> tags.
  $in_pre = 0;

  // This is a cheat, used to get some context
  // for one-character tokens that consist of
  // just a quote char. What we do is remember
  // the last character of the previous text
  // token, to use as context to curl single-
  // character quote tokens correctly.
  $prev_token_last_char = "";
  foreach ($tokens as $cur_token) {
    if ($cur_token[0] == "tag") {

      // Don't mess with quotes inside tags.
      $result .= $cur_token[1];
      if (preg_match(self::SMARTYPANTS_TAGS_TO_SKIP, $cur_token[1], $matches)) {
        $in_pre = isset($matches[1]) && $matches[1] == '/' ? 0 : 1;
      }
    }
    else {
      $t = $cur_token[1];

      // Remember last char of this token before processing.
      $last_char = mb_substr($t, -1);
      if (!$in_pre) {
        $t = self::processEscapes($t);
        if ($do_backticks) {
          $t = self::educateBackticks($t);
        }
        if ($t == "'") {

          // Special case: single-character ' token.
          if (preg_match('/\\S/', $prev_token_last_char)) {
            $t = "&#8217;";
          }
          else {
            $t = "&#8216;";
          }
        }
        elseif ($t == '"') {

          // Special case: single-character " token.
          if (preg_match('/\\S/', $prev_token_last_char)) {
            $t = "&#8221;";
          }
          else {
            $t = "&#8220;";
          }
        }
        else {

          // Normal case:
          $t = self::educateQuotes($t);
        }
      }
      $prev_token_last_char = $last_char;
      $result .= $t;
    }
  }
  if ($add_extra_space) {

    // Trim trailing space if we added one earlier.
    preg_replace('/ \\z/', '', $result);
  }
  return $result;
}