You are here

public static function SmartyPants::process in Typogrify 8

SmartyPants.

Parameters

string $text: Text to be parsed.

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

string $ctx: MT context object (unused).

Return value

string The modified text.

4 calls to SmartyPants::process()
SmartyPants::modifierSmartypants in src/SmartyPants.php
Wrapper method for SmartyPants.
Typogrify::filter in src/Typogrify.php
Typogrify.
Typogrify::filter in src/TwigExtension/Typogrify.php
Filter text by Typogrify.
TypogrifyFilter::process in src/Plugin/Filter/TypogrifyFilter.php
Performs the filter processing.

File

src/SmartyPants.php, line 177

Class

SmartyPants
SmartyPants - Smart punctuation for web sites.

Namespace

Drupal\typogrify

Code

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

  // Options to specify which transformations to make.
  $do_stupefy = FALSE;

  // Should we translate " entities into normal quotes?
  $convert_quot = 0;

  // Parse attributes:
  // 0 : do nothing
  // 1 : set all
  // 2 : set all, using old school en- and em- dash shortcuts
  // 3 : set all, using inverted old school en and em- dash shortcuts
  //
  // q : quotes
  // b : backtick quotes (``double'' and ,,double`` only)
  // B : backtick quotes (``double'', ,,double``, ,single` and `single')
  // d : dashes
  // D : old school dashes
  // i : inverted old school dashes
  // e : ellipses
  // w : convert " entities to " for Dreamweaver users.
  if ($attr == "0") {

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

    // Do everything, turn all options on.
    $do_quotes = 2;
    $do_backticks = 1;
    $do_dashes = 1;
    $do_ellipses = 1;
  }
  elseif ($attr == "2") {

    // Do everything, turn all options on, use old school dash shorthand.
    $do_quotes = 2;
    $do_backticks = 1;
    $do_dashes = 2;
    $do_ellipses = 1;
  }
  elseif ($attr == "3") {

    // Do everything, turn all options on,
    // use inverted old school dash shorthand.
    $do_quotes = 2;
    $do_backticks = 1;
    $do_dashes = 3;
    $do_ellipses = 1;
  }
  elseif ($attr == "-1") {

    // Special "stupefy" mode.
    $do_stupefy = 1;
  }
  else {
    $chars = preg_split('//', $attr);
    foreach ($chars as $c) {
      if ($c == "q") {
        $do_quotes = 1;
      }
      elseif ($c == "Q") {
        $do_quotes = 2;
      }
      elseif ($c == "b") {
        $do_backticks = 1;
      }
      elseif ($c == "B") {
        $do_backticks = 2;
      }
      elseif ($c == "d") {
        $do_dashes = 1;
      }
      elseif ($c == "D") {
        $do_dashes = 2;
      }
      elseif ($c == "i") {
        $do_dashes = 3;
      }
      elseif ($c == "e") {
        $do_ellipses = 1;
      }
      elseif ($c == "w") {
        $convert_quot = 1;
      }
    }
  }
  if ($do_quotes == 2) {
    $doc_lang = $ctx['langcode'];
  }
  else {
    $doc_lang = 'en';
  }
  $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 {

        // Reading language from span.
        if (preg_match('/<span .*(xml:)?lang="(..)"/', $cur_token[1], $matches)) {
          $span_lang = $matches[2];
        }
        elseif ($cur_token[1] == '</span>') {
          unset($span_lang);
        }
      }
    }
    else {
      $t = $cur_token[1];

      // Remember last char of this token before processing.
      $last_char = mb_substr($t, -1);
      if (!$in_pre) {
        $quotes = self::i18nQuotes(isset($span_lang) ? $span_lang : $doc_lang);
        $t = self::processEscapes($t);
        if ($convert_quot) {
          $t = preg_replace('/&quot;/', '"', $t);
        }
        if ($do_dashes) {
          if ($do_dashes == 1) {
            $t = self::educateDashes($t);
          }
          elseif ($do_dashes == 2) {
            $t = self::educateDashesOldSchool($t);
          }
          elseif ($do_dashes == 3) {
            $t = self::educateDashesOldSchoolInverted($t);
          }
        }
        if ($do_ellipses) {
          $t = self::educateEllipses($t);
        }

        // Note: backticks need to be processed before quotes.
        if ($do_backticks) {
          $t = self::educateBackticks($t);
          if ($do_backticks == 2) {
            $t = self::educateSingleBackticks($t);
          }
        }
        if ($do_quotes) {
          $t = self::educateBackticks($t);
          if ($t == "'") {

            // Special case: single-character ' token.
            if (preg_match('/\\S/', $prev_token_last_char)) {
              $t = $quotes[3];
            }
            else {
              $t = $quotes[2];
            }
          }
          elseif ($t == '"') {

            // Special case: single-character " token.
            if (preg_match('/\\S/', $prev_token_last_char)) {
              $t = $quotes[1];
            }
            else {
              $t = $quotes[0];
            }
          }
          else {

            // Normal case:
            $t = self::educateQuotes($t, $quotes);
          }
        }
        if ($do_stupefy) {
          $t = self::stupefyEntities($t);
        }
      }
      $prev_token_last_char = $last_char;
      $result .= $t;
    }
  }
  return $result;
}