PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/vendor/s9e/text-formatter/src/Plugins/FancyPants/Parser.php

https://bitbucket.org/cmwdosp/cmwbb3
PHP | 187 lines | 181 code | 1 blank | 5 comment | 4 complexity | d86160658e94fda64035ab88461c7a5b MD5 | raw file
Possible License(s): BSD-3-Clause
  1. <?php
  2. /*
  3. * @package s9e\TextFormatter
  4. * @copyright Copyright (c) 2010-2017 The s9e Authors
  5. * @license http://www.opensource.org/licenses/mit-license.php The MIT License
  6. */
  7. namespace s9e\TextFormatter\Plugins\FancyPants;
  8. use s9e\TextFormatter\Plugins\ParserBase;
  9. class Parser extends ParserBase
  10. {
  11. protected $hasDoubleQuote;
  12. protected $hasSingleQuote;
  13. protected $text;
  14. public function parse($text, array $matches)
  15. {
  16. $this->text = $text;
  17. $this->hasSingleQuote = (\strpos($text, "'") !== \false);
  18. $this->hasDoubleQuote = (\strpos($text, '"') !== \false);
  19. if (empty($this->config['disableQuotes']))
  20. {
  21. $this->parseSingleQuotes();
  22. $this->parseSingleQuotePairs();
  23. $this->parseDoubleQuotePairs();
  24. }
  25. if (empty($this->config['disableGuillemets']))
  26. $this->parseGuillemets();
  27. if (empty($this->config['disableMathSymbols']))
  28. {
  29. $this->parseNotEqualSign();
  30. $this->parseSymbolsAfterDigits();
  31. $this->parseFractions();
  32. }
  33. if (empty($this->config['disablePunctuation']))
  34. $this->parseDashesAndEllipses();
  35. if (empty($this->config['disableSymbols']))
  36. $this->parseSymbolsInParentheses();
  37. unset($this->text);
  38. }
  39. protected function addTag($tagPos, $tagLen, $chr, $prio = 0)
  40. {
  41. $tag = $this->parser->addSelfClosingTag($this->config['tagName'], $tagPos, $tagLen, $prio);
  42. $tag->setAttribute($this->config['attrName'], $chr);
  43. return $tag;
  44. }
  45. protected function parseDashesAndEllipses()
  46. {
  47. if (\strpos($this->text, '...') === \false && \strpos($this->text, '--') === \false)
  48. return;
  49. $chrs = array(
  50. '--' => "\xE2\x80\x93",
  51. '---' => "\xE2\x80\x94",
  52. '...' => "\xE2\x80\xA6"
  53. );
  54. $regexp = '/---?|\\.\\.\\./S';
  55. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  56. foreach ($matches[0] as $m)
  57. $this->addTag($m[1], \strlen($m[0]), $chrs[$m[0]]);
  58. }
  59. protected function parseDoubleQuotePairs()
  60. {
  61. if ($this->hasDoubleQuote)
  62. $this->parseQuotePairs(
  63. '/(?<![0-9\\pL])"[^"\\n]+"(?![0-9\\pL])/uS',
  64. "\xE2\x80\x9C",
  65. "\xE2\x80\x9D"
  66. );
  67. }
  68. protected function parseFractions()
  69. {
  70. if (\strpos($this->text, '/') === \false)
  71. return;
  72. $map = array(
  73. '1/4' => "\xC2\xBC",
  74. '1/2' => "\xC2\xBD",
  75. '3/4' => "\xC2\xBE",
  76. '1/7' => "\xE2\x85\x90",
  77. '1/9' => "\xE2\x85\x91",
  78. '1/10' => "\xE2\x85\x92",
  79. '1/3' => "\xE2\x85\x93",
  80. '2/3' => "\xE2\x85\x94",
  81. '1/5' => "\xE2\x85\x95",
  82. '2/5' => "\xE2\x85\x96",
  83. '3/5' => "\xE2\x85\x97",
  84. '4/5' => "\xE2\x85\x98",
  85. '1/6' => "\xE2\x85\x99",
  86. '5/6' => "\xE2\x85\x9A",
  87. '1/8' => "\xE2\x85\x9B",
  88. '3/8' => "\xE2\x85\x9C",
  89. '5/8' => "\xE2\x85\x9D",
  90. '7/8' => "\xE2\x85\x9E",
  91. '0/3' => "\xE2\x86\x89"
  92. );
  93. $regexp = '/\\b(?:0\\/3|1\\/(?:[2-9]|10)|2\\/[35]|3\\/[458]|4\\/5|5\\/[68]|7\\/8)\\b/S';
  94. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  95. foreach ($matches[0] as $m)
  96. $this->addTag($m[1], \strlen($m[0]), $map[$m[0]]);
  97. }
  98. protected function parseGuillemets()
  99. {
  100. if (\strpos($this->text, '<<') === \false)
  101. return;
  102. $regexp = '/<<( ?)(?! )[^\\n<>]*?[^\\n <>]\\1>>(?!>)/';
  103. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  104. foreach ($matches[0] as $m)
  105. {
  106. $left = $this->addTag($m[1], 2, "\xC2\xAB");
  107. $right = $this->addTag($m[1] + \strlen($m[0]) - 2, 2, "\xC2\xBB");
  108. $left->cascadeInvalidationTo($right);
  109. }
  110. }
  111. protected function parseNotEqualSign()
  112. {
  113. if (\strpos($this->text, '!=') === \false && \strpos($this->text, '=/=') === \false)
  114. return;
  115. $regexp = '/\\b (?:!|=\\/)=(?= \\b)/';
  116. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  117. foreach ($matches[0] as $m)
  118. $this->addTag($m[1] + 1, \strlen($m[0]) - 1, "\xE2\x89\xA0");
  119. }
  120. protected function parseQuotePairs($regexp, $leftQuote, $rightQuote)
  121. {
  122. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  123. foreach ($matches[0] as $m)
  124. {
  125. $left = $this->addTag($m[1], 1, $leftQuote);
  126. $right = $this->addTag($m[1] + \strlen($m[0]) - 1, 1, $rightQuote);
  127. $left->cascadeInvalidationTo($right);
  128. }
  129. }
  130. protected function parseSingleQuotePairs()
  131. {
  132. if ($this->hasSingleQuote)
  133. $this->parseQuotePairs(
  134. "/(?<![0-9\\pL])'[^'\\n]+'(?![0-9\\pL])/uS",
  135. "\xE2\x80\x98",
  136. "\xE2\x80\x99"
  137. );
  138. }
  139. protected function parseSingleQuotes()
  140. {
  141. if (!$this->hasSingleQuote)
  142. return;
  143. $regexp = "/(?<=\\pL)'|(?<!\\S)'(?=\\pL|[0-9]{2})/uS";
  144. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  145. foreach ($matches[0] as $m)
  146. $this->addTag($m[1], 1, "\xE2\x80\x99", 10);
  147. }
  148. protected function parseSymbolsAfterDigits()
  149. {
  150. if (!$this->hasSingleQuote && !$this->hasDoubleQuote && \strpos($this->text, 'x') === \false)
  151. return;
  152. $map = array(
  153. "'s" => "\xE2\x80\x99",
  154. "'" => "\xE2\x80\xB2",
  155. "' " => "\xE2\x80\xB2",
  156. "'x" => "\xE2\x80\xB2",
  157. '"' => "\xE2\x80\xB3",
  158. '" ' => "\xE2\x80\xB3",
  159. '"x' => "\xE2\x80\xB3"
  160. );
  161. $regexp = "/[0-9](?>'s|[\"']? ?x(?= ?[0-9])|[\"'])/S";
  162. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  163. foreach ($matches[0] as $m)
  164. {
  165. if (\substr($m[0], -1) === 'x')
  166. $this->addTag($m[1] + \strlen($m[0]) - 1, 1, "\xC3\x97");
  167. $str = \substr($m[0], 1, 2);
  168. if (isset($map[$str]))
  169. $this->addTag($m[1] + 1, 1, $map[$str]);
  170. }
  171. }
  172. protected function parseSymbolsInParentheses()
  173. {
  174. if (\strpos($this->text, '(') === \false)
  175. return;
  176. $chrs = array(
  177. '(c)' => "\xC2\xA9",
  178. '(r)' => "\xC2\xAE",
  179. '(tm)' => "\xE2\x84\xA2"
  180. );
  181. $regexp = '/\\((?>c|r|tm)\\)/i';
  182. \preg_match_all($regexp, $this->text, $matches, \PREG_OFFSET_CAPTURE);
  183. foreach ($matches[0] as $m)
  184. $this->addTag($m[1], \strlen($m[0]), $chrs[\strtr($m[0], 'CMRT', 'cmrt')]);
  185. }
  186. }