diff --git a/build.xml b/build.xml index 00952a4..2a1b1e0 100644 --- a/build.xml +++ b/build.xml @@ -1,6 +1,6 @@ - + @@ -34,7 +34,7 @@ - + diff --git a/juarticlesave.php b/juarticlesave.php index dc183b1..665bd87 100644 --- a/juarticlesave.php +++ b/juarticlesave.php @@ -6,14 +6,15 @@ * @subpackage plg_content_juarticlesave * * @author Denys Nosov, denys@joomla-ua.org - * @copyright 2018-2019 (C) Joomla! Ukraine, https://joomla-ua.org. All rights reserved. + * @copyright 2018-2020 (C) Joomla! Ukraine, https://joomla-ua.org. All rights reserved. * @license GNU General Public License version 2 or later; see LICENSE.txt */ defined('_JEXEC') or die; -require_once __DIR__ . '/lib/emt/EMT.php'; +require_once __DIR__ . '/lib/vendor/autoload.php'; +use Emuravjev\Mdash\Typograph; use Joomla\CMS\Factory; use Joomla\CMS\Language\Text; use Joomla\CMS\Plugin\CMSPlugin; @@ -104,18 +105,28 @@ public function onContentBeforeSave($context, $article, $isNew) */ public function _typo($text, $tags = 1) { - $typograf = new EMTypograph(); + $typograf = new Typograph(); preg_match_all('!(\[socpost\].*?\[/socpost\])!si', $text, $pre); $text = preg_replace('!\[socpost\].*?\[/socpost\]!si', '#pre#', $text); $typograf->set_text($text); $typograf->setup([ - 'Text.paragraphs' => 'off', - 'Text.breakline' => 'off', - 'OptAlign.all' => 'off', - 'Nobr.spaces_nobr_in_surname_abbr' => 'off', - 'Etc.split_number_to_triads' => 'off' + 'Text.paragraphs' => 'off', + 'Text.breakline' => 'off', + 'OptAlign.all' => 'off', + 'Nobr.spaces_nobr_in_surname_abbr' => 'off', + 'Nobr.nbsp_org_abbr' => 'off', + 'Nobr.nbsp_in_the_end' => 'off', + 'Nobr.phone_builder' => 'off', + 'Nobr.phone_builder_v2' => 'off', + 'Nobr.ip_address' => 'off', + 'Nobr.dots_for_surname_abbr' => 'off', + 'Nobr.hyphen_nowrap_in_small_words' => 'off', + 'Abbr.nobr_abbreviation' => 'off', + 'Abbr.nobr_acronym' => 'off', + 'Etc.unicode_convert' => 'off', + 'Etc.split_number_to_triads' => 'off' ]); if($tags == 0) diff --git a/juarticlesave.xml b/juarticlesave.xml index 863640a..977c883 100644 --- a/juarticlesave.xml +++ b/juarticlesave.xml @@ -7,7 +7,7 @@ https://joomla-ua.org @version@ http://www.gnu.org/copyleft/gpl.html GNU/GPL - (C) 2018-2019 Joomla! Ukraine. All rights reserved! + (C) 2018-2020 Joomla! Ukraine. All rights reserved! PLG_CONTENT_JUARTICLESAVE_XML_DESCRIPTION lib diff --git a/lib/emt/EMT.php b/lib/emt/EMT.php deleted file mode 100644 index b9b8403..0000000 --- a/lib/emt/EMT.php +++ /dev/null @@ -1,4618 +0,0 @@ - array( - 'html' => array( - '«', - '»', - '”', - '‘', - '„', - '“', - '"', - '«', - '»' - ), - 'utf8' => array( - 0x201E, - 0x201C, - 0x201F, - 0x201D, - 0x00AB, - 0x00BB - ) - ), - ' ' => array( - 'html' => array( - ' ', - ' ', - ' ' - ), - 'utf8' => array( - 0x00A0, - 0x2002, - 0x2003, - 0x2008, - 0x2009 - ) - ), - '-' => array( - 'html' => array( - '–', - '−', - '—', - '—', - '–' - ), - 'utf8' => array( - 0x002D, - 0x2010, - 0x2012, - 0x2013 - ) - ), - '—' => array( - 'html' => array( '—' ), - 'utf8' => array( 0x2014 ) - ), - '==' => array( - 'html' => array( '≡' ), - 'utf8' => array( 0x2261 ) - ), - '...' => array( - 'html' => array( - '…', - '…' - ), - 'utf8' => array( 0x2026 ) - ), - '!=' => array( - 'html' => array( - '≠', - '≠' - ), - 'utf8' => array( 0x2260 ) - ), - '<=' => array( - 'html' => array( - '≤', - '≤' - ), - 'utf8' => array( 0x2264 ) - ), - '>=' => array( - 'html' => array( - '≥', - '≥' - ), - 'utf8' => array( 0x2265 ) - ), - '1/2' => array( - 'html' => array( - '½', - '½' - ), - 'utf8' => array( 0x00BD ) - ), - '1/4' => array( - 'html' => array( - '¼', - '¼' - ), - 'utf8' => array( 0x00BC ) - ), - '3/4' => array( - 'html' => array( - '¾', - '¾' - ), - 'utf8' => array( 0x00BE ) - ), - '+-' => array( - 'html' => array( - '±', - '±' - ), - 'utf8' => array( 0x00B1 ) - ), - '&' => array( - 'html' => array( - '&', - '&' - ) - ), - '(tm)' => array( - 'html' => array( - '™', - '™' - ), - 'utf8' => array( 0x2122 ) - ), - '(r)' => array( - 'html' => array( - '®', - '®' - ), - 'utf8' => array( 0x00AE ) - ), - '(c)' => array( - 'html' => array( - '©', - '©' - ), - 'utf8' => array( 0x00A9 ) - ), - '§' => array( - 'html' => array( - '§', - '§' - ), - 'utf8' => array( 0x00A7 ) - ), - '`' => array( - 'html' => array( - '́' - ) - ), - '\'' => array( - 'html' => array( - '’', - '’' - ) - ), - 'x' => array( - 'html' => array( - '×', - '×' - ), - 'utf8' => array( - '×' - ) - ), - - ); - - /** - * Добавление к тегам атрибута 'id', благодаря которому - * при повторном типографирование текста будут удалены теги, - * расставленные данным типографом - * - * @var array - */ - protected static $_typographSpecificTagId = false; - - protected static $html4_char_ents = array( - 'nbsp' => 160, - 'iexcl' => 161, - 'cent' => 162, - 'pound' => 163, - 'curren' => 164, - 'yen' => 165, - 'brvbar' => 166, - 'sect' => 167, - 'uml' => 168, - 'copy' => 169, - 'ordf' => 170, - 'laquo' => 171, - 'not' => 172, - 'shy' => 173, - 'reg' => 174, - 'macr' => 175, - 'deg' => 176, - 'plusmn' => 177, - 'sup2' => 178, - 'sup3' => 179, - 'acute' => 180, - 'micro' => 181, - 'para' => 182, - 'middot' => 183, - 'cedil' => 184, - 'sup1' => 185, - 'ordm' => 186, - 'raquo' => 187, - 'frac14' => 188, - 'frac12' => 189, - 'frac34' => 190, - 'iquest' => 191, - 'Agrave' => 192, - 'Aacute' => 193, - 'Acirc' => 194, - 'Atilde' => 195, - 'Auml' => 196, - 'Aring' => 197, - 'AElig' => 198, - 'Ccedil' => 199, - 'Egrave' => 200, - 'Eacute' => 201, - 'Ecirc' => 202, - 'Euml' => 203, - 'Igrave' => 204, - 'Iacute' => 205, - 'Icirc' => 206, - 'Iuml' => 207, - 'ETH' => 208, - 'Ntilde' => 209, - 'Ograve' => 210, - 'Oacute' => 211, - 'Ocirc' => 212, - 'Otilde' => 213, - 'Ouml' => 214, - 'times' => 215, - 'Oslash' => 216, - 'Ugrave' => 217, - 'Uacute' => 218, - 'Ucirc' => 219, - 'Uuml' => 220, - 'Yacute' => 221, - 'THORN' => 222, - 'szlig' => 223, - 'agrave' => 224, - 'aacute' => 225, - 'acirc' => 226, - 'atilde' => 227, - 'auml' => 228, - 'aring' => 229, - 'aelig' => 230, - 'ccedil' => 231, - 'egrave' => 232, - 'eacute' => 233, - 'ecirc' => 234, - 'euml' => 235, - 'igrave' => 236, - 'iacute' => 237, - 'icirc' => 238, - 'iuml' => 239, - 'eth' => 240, - 'ntilde' => 241, - 'ograve' => 242, - 'oacute' => 243, - 'ocirc' => 244, - 'otilde' => 245, - 'ouml' => 246, - 'divide' => 247, - 'oslash' => 248, - 'ugrave' => 249, - 'uacute' => 250, - 'ucirc' => 251, - 'uuml' => 252, - 'yacute' => 253, - 'thorn' => 254, - 'yuml' => 255, - 'fnof' => 402, - 'Alpha' => 913, - 'Beta' => 914, - 'Gamma' => 915, - 'Delta' => 916, - 'Epsilon' => 917, - 'Zeta' => 918, - 'Eta' => 919, - 'Theta' => 920, - 'Iota' => 921, - 'Kappa' => 922, - 'Lambda' => 923, - 'Mu' => 924, - 'Nu' => 925, - 'Xi' => 926, - 'Omicron' => 927, - 'Pi' => 928, - 'Rho' => 929, - 'Sigma' => 931, - 'Tau' => 932, - 'Upsilon' => 933, - 'Phi' => 934, - 'Chi' => 935, - 'Psi' => 936, - 'Omega' => 937, - 'alpha' => 945, - 'beta' => 946, - 'gamma' => 947, - 'delta' => 948, - 'epsilon' => 949, - 'zeta' => 950, - 'eta' => 951, - 'theta' => 952, - 'iota' => 953, - 'kappa' => 954, - 'lambda' => 955, - 'mu' => 956, - 'nu' => 957, - 'xi' => 958, - 'omicron' => 959, - 'pi' => 960, - 'rho' => 961, - 'sigmaf' => 962, - 'sigma' => 963, - 'tau' => 964, - 'upsilon' => 965, - 'phi' => 966, - 'chi' => 967, - 'psi' => 968, - 'omega' => 969, - 'thetasym' => 977, - 'upsih' => 978, - 'piv' => 982, - 'bull' => 8226, - 'hellip' => 8230, - 'prime' => 8242, - 'Prime' => 8243, - 'oline' => 8254, - 'frasl' => 8260, - 'weierp' => 8472, - 'image' => 8465, - 'real' => 8476, - 'trade' => 8482, - 'alefsym' => 8501, - 'larr' => 8592, - 'uarr' => 8593, - 'rarr' => 8594, - 'darr' => 8595, - 'harr' => 8596, - 'crarr' => 8629, - 'lArr' => 8656, - 'uArr' => 8657, - 'rArr' => 8658, - 'dArr' => 8659, - 'hArr' => 8660, - 'forall' => 8704, - 'part' => 8706, - 'exist' => 8707, - 'empty' => 8709, - 'nabla' => 8711, - 'isin' => 8712, - 'notin' => 8713, - 'ni' => 8715, - 'prod' => 8719, - 'sum' => 8721, - 'minus' => 8722, - 'lowast' => 8727, - 'radic' => 8730, - 'prop' => 8733, - 'infin' => 8734, - 'ang' => 8736, - 'and' => 8743, - 'or' => 8744, - 'cap' => 8745, - 'cup' => 8746, - 'int' => 8747, - 'there4' => 8756, - 'sim' => 8764, - 'cong' => 8773, - 'asymp' => 8776, - 'ne' => 8800, - 'equiv' => 8801, - 'le' => 8804, - 'ge' => 8805, - 'sub' => 8834, - 'sup' => 8835, - 'nsub' => 8836, - 'sube' => 8838, - 'supe' => 8839, - 'oplus' => 8853, - 'otimes' => 8855, - 'perp' => 8869, - 'sdot' => 8901, - 'lceil' => 8968, - 'rceil' => 8969, - 'lfloor' => 8970, - 'rfloor' => 8971, - 'lang' => 9001, - 'rang' => 9002, - 'loz' => 9674, - 'spades' => 9824, - 'clubs' => 9827, - 'hearts' => 9829, - 'diams' => 9830, - 'quot' => 34, - 'amp' => 38, - 'lt' => 60, - 'gt' => 62, - 'OElig' => 338, - 'oelig' => 339, - 'Scaron' => 352, - 'scaron' => 353, - 'Yuml' => 376, - 'circ' => 710, - 'tilde' => 732, - 'ensp' => 8194, - 'emsp' => 8195, - 'thinsp' => 8201, - 'zwnj' => 8204, - 'zwj' => 8205, - 'lrm' => 8206, - 'rlm' => 8207, - 'ndash' => 8211, - 'mdash' => 8212, - 'lsquo' => 8216, - 'rsquo' => 8217, - 'sbquo' => 8218, - 'ldquo' => 8220, - 'rdquo' => 8221, - 'bdquo' => 8222, - 'dagger' => 8224, - 'Dagger' => 8225, - 'permil' => 8240, - 'lsaquo' => 8249, - 'rsaquo' => 8250, - 'euro' => 8364, - ); - - /** - * Удаление кодов HTML из текста - * - * - * // Remove UTF-8 chars: - * $str = EMT_Lib::clear_special_chars('your text', 'utf8'); - * // ... or HTML codes only: - * $str = EMT_Lib::clear_special_chars('your text', 'html'); - * // ... or combo: - * $str = EMT_Lib::clear_special_chars('your text'); - * - * - * @param string $text - * @param mixed $mode - * - * @return string|bool - * - * @since 3.5 - */ - public static function clear_special_chars($text, $mode = null) - { - if(is_string($mode)) - { - $mode = array( $mode ); - } - - if(is_null($mode)) - { - $mode = array( - 'utf8', - 'html' - ); - } - - if(!is_array($mode)) - { - return false; - } - - $moder = array(); - - foreach($mode as $mod) - { - if(in_array($mod, array( - 'utf8', - 'html' - ))) - { - $moder[] = $mod; - } - } - - if(count($moder) == 0) - { - return false; - } - - foreach(self::$_charsTable as $char => $vals) - { - foreach($mode as $type) - { - if(isset($vals[ $type ])) - { - foreach($vals[ $type ] as $v) - { - if('utf8' === $type && is_int($v)) - { - $v = self::_getUnicodeChar($v); - } - - if('html' === $type && preg_match("/<[a-z]+>/i", $v)) - { - $v = self::safe_tag_chars($v, true); - } - - $text = str_replace($v, $char, $text); - } - } - } - } - - return $text; - } - - /** - * Костыли для работы с символами UTF-8 - * - * @author somebody? - * - * @param int $c код символа в кодировке UTF-8 (например, 0x00AB) - * - * @return bool|string - * - * @since 3.5 - */ - public static function _getUnicodeChar($c) - { - if($c <= 0x7F) - { - return chr($c); - } - elseif($c <= 0x7FF) - { - return chr(0xC0 | $c >> 6) - . chr(0x80 | $c & 0x3F); - } - elseif($c <= 0xFFFF) - { - return chr(0xE0 | $c >> 12) - . chr(0x80 | $c >> 6 & 0x3F) - . chr(0x80 | $c & 0x3F); - } - elseif($c <= 0x10FFFF) - { - return chr(0xF0 | $c >> 18) - . chr(0x80 | $c >> 12 & 0x3F) - . chr(0x80 | $c >> 6 & 0x3F) - . chr(0x80 | $c & 0x3F); - } - else - { - return false; - } - } - - /** - * Сохраняем содержимое тегов HTML - * - * Тег 'a' кодируется со специальным префиксом для дальнейшей - * возможности выносить за него кавычки. - * - * @param string $text - * @param $way - * - * @return string - * - * @since 3.5 - */ - public static function safe_tag_chars($text, $way) - { - if($way) - { - $text = preg_replace_callback('/(\<\/?)([^<>]+?)(\>)/s', create_function('$m', 'return (strlen($m[1])==1 && substr(trim($m[2]), 0, 1) == \'-\' && substr(trim($m[2]), 1, 1) != \'-\')? $m[0] : $m[1].( substr(trim($m[2]), 0, 1) === "a" ? "%%___" : "" ) . EMT_Lib::encrypt_tag(trim($m[2])) . $m[3];'), $text); - } - else - { - $text = preg_replace_callback('/(\<\/?)([^<>]+?)(\>)/s', create_function('$m', 'return (strlen($m[1])==1 && substr(trim($m[2]), 0, 1) == \'-\' && substr(trim($m[2]), 1, 1) != \'-\')? $m[0] : $m[1].( substr(trim($m[2]), 0, 3) === "%%___" ? EMT_Lib::decrypt_tag(substr(trim($m[2]), 4)) : EMT_Lib::decrypt_tag(trim($m[2])) ) . $m[3];'), $text); - } - - return $text; - } - - /** - * Удаление тегов HTML из текста - * Тег
будет преобразов в перенос строки \n, сочетание тегов

- - * в двойной перенос - * - * @param string $text - * @param array $allowableTag массив из тегов, которые будут проигнорированы - * - * @return string - * - * @since 3.5 - */ - public static function remove_html_tags($text, $allowableTag = null) - { - $ignore = null; - - if(null !== $allowableTag) - { - if(is_string($allowableTag)) - { - $allowableTag = array( $allowableTag ); - } - - if(is_array($allowableTag)) - { - $tags = array(); - foreach($allowableTag as $tag) - { - if('<' !== substr($tag, 0, 1) || '>' !== substr($tag, -1, 1)) - { - continue; - } - - if('/' === substr($tag, 1, 1)) - { - continue; - } - - $tags [] = $tag; - } - - $ignore = implode('', $tags); - } - } - - $text = preg_replace(array( - '/\/i', - '/\<\/p\>\s*\/' - ), array( - "\n", - "\n\n" - ), $text); - $text = strip_tags($text, $ignore); - - return $text; - } - - /** - * Декодриует спец блоки - * - * @param string $text - * - * @return string - * - * @since 3.5 - */ - public static function decode_internal_blocks($text) - { - $text = preg_replace_callback('/' . self::INTERNAL_BLOCK_OPEN . '([a-zA-Z0-9\/=]+?)' . self::INTERNAL_BLOCK_CLOSE . '/s', create_function('$m', 'return EMT_Lib::decrypt_tag($m[1]);'), $text); - - return $text; - } - - /** - * Кодирует спец блок - * - * @param string $text - * - * @return string - * - * @since 3.5 - */ - public static function iblock($text) - { - return self::INTERNAL_BLOCK_OPEN . self::encrypt_tag($text) . self::INTERNAL_BLOCK_CLOSE; - } - - /** - * Метод, осуществляющий кодирование (сохранение) информации - * с целью невозможности типографировать ее - * - * @param string $text - * - * @return string - * - * @since 3.5 - */ - public static function encrypt_tag($text) - { - return base64_encode($text) . '='; - } - - /** - * Создание тега с защищенным содержимым - * - * @param string $content текст, который будет обрамлен тегом - * @param string $tag тэг - * @param array $attribute список атрибутов, где ключ - имя атрибута, а значение - само значение данного атрибута - * @param int $layout - * - * @return string - * - * @since 3.5 - */ - public static function build_safe_tag($content, $tag = 'span', $attribute = array(), $layout = EMT_Lib::LAYOUT_STYLE) - { - $htmlTag = $tag; - - if(self::$_typographSpecificTagId) - { - if(!isset($attribute[ 'id' ])) - { - $attribute[ 'id' ] = 'emt-2' . mt_rand(1000, 9999); - } - } - - $classname = ''; - - if(count($attribute)) - { - if($layout & EMT_lib::LAYOUT_STYLE) - { - if(isset($attribute[ '__style' ]) && $attribute[ '__style' ]) - { - if(isset($attribute[ 'style' ]) && $attribute[ 'style' ]) - { - $st = trim($attribute[ 'style' ]); - - if(mb_substr($st, -1) != ';') - { - $st .= ';'; - } - - $st .= $attribute[ '__style' ]; - $attribute[ 'style' ] = $st; - } - else - { - $attribute[ 'style' ] = $attribute[ '__style' ]; - } - - unset($attribute[ '__style' ]); - } - } - - foreach($attribute as $attr => $value) - { - if($attr == '__style') - { - continue; - } - - if($attr == 'class') - { - $classname = "$value"; - - continue; - } - - $htmlTag .= " $attr=\"$value\""; - } - } - - if(($layout & EMT_lib::LAYOUT_CLASS) && $classname) - { - $htmlTag .= " class=\"$classname\""; - } - - return '<' . self::encrypt_tag($htmlTag) . ">$content'; - } - - /** - * Метод, осуществляющий декодирование информации - * - * @param string $text - * - * @return string - * - * @since 3.5 - */ - public static function decrypt_tag($text) - { - return base64_decode(substr($text, 0, -1)); - } - - /** - * @param $haystack - * @param $needle - * @param null $offset - * - * @return array|bool|int - * - * @since 3.5 - */ - public static function strpos_ex(&$haystack, $needle, $offset = null) - { - if(is_array($needle)) - { - $m = false; - $w = false; - - foreach($needle as $n) - { - $p = strpos($haystack, $n, $offset); - - if($p === false) - { - continue; - } - - if($m === false) - { - $m = $p; - $w = $n; - - continue; - } - - if($p < $m) - { - $m = $p; - $w = $n; - } - } - - if($m === false) - { - return false; - } - - return array( - 'pos' => $m, - 'str' => $w - ); - } - - return strpos($haystack, $needle, $offset); - } - - /** - * @param $pattern - * - * - * @since 3.5 - */ - public static function _process_selector_pattern(&$pattern) - { - if($pattern === false) - { - return; - } - - $pattern = preg_quote($pattern, '/'); - $pattern = str_replace("\\*", "[a-z0-9_\-]*", $pattern); - $pattern = '/' . $pattern . '/i'; - } - - /** - * @param $pattern - * @param $text - * - * @return bool|false|int - * - * @since 3.5 - */ - public static function _test_pattern($pattern, $text) - { - if($pattern === false) - { - return true; - } - - return preg_match($pattern, $text); - } - - /** - * взято с http://www.w3.org/TR/html4/sgml/entities.html - * - * @param $string - * - * @return mixed - * - * @since 3.5 - */ - public static function strtolower($string) - { - $convert_to = array( - 'a', - 'b', - 'c', - 'd', - 'e', - 'f', - 'g', - 'h', - 'i', - 'j', - 'k', - 'l', - 'm', - 'n', - 'o', - 'p', - 'q', - 'r', - 's', - 't', - 'u', - 'v', - 'w', - 'x', - 'y', - 'z', - 'à', - 'á', - 'â', - 'ã', - 'ä', - 'å', - 'æ', - 'ç', - 'è', - 'é', - 'ê', - 'ë', - 'ì', - 'í', - 'î', - 'ï', - 'ð', - 'ñ', - 'ò', - 'ó', - 'ô', - 'õ', - 'ö', - 'ø', - 'ù', - 'ú', - 'û', - 'ü', - 'ý', - 'а', - 'б', - 'в', - 'г', - 'д', - 'е', - 'ё', - 'ж', - 'з', - 'и', - 'й', - 'к', - 'л', - 'м', - 'н', - 'о', - 'п', - 'р', - 'с', - 'т', - 'у', - 'ф', - 'х', - 'ц', - 'ч', - 'ш', - 'щ', - 'ъ', - 'ы', - 'ь', - 'э', - 'ю', - 'я' - ); - - $convert_from = array( - 'A', - 'B', - 'C', - 'D', - 'E', - 'F', - 'G', - 'H', - 'I', - 'J', - 'K', - 'L', - 'M', - 'N', - 'O', - 'P', - 'Q', - 'R', - 'S', - 'T', - 'U', - 'V', - 'W', - 'X', - 'Y', - 'Z', - 'À', - 'Á', - 'Â', - 'Ã', - 'Ä', - 'Å', - 'Æ', - 'Ç', - 'È', - 'É', - 'Ê', - 'Ë', - 'Ì', - 'Í', - 'Î', - 'Ï', - 'Ð', - 'Ñ', - 'Ò', - 'Ó', - 'Ô', - 'Õ', - 'Ö', - 'Ø', - 'Ù', - 'Ú', - 'Û', - 'Ü', - 'Ý', - 'А', - 'Б', - 'В', - 'Г', - 'Д', - 'Е', - 'Ё', - 'Ж', - 'З', - 'И', - 'Й', - 'К', - 'Л', - 'М', - 'Н', - 'О', - 'П', - 'Р', - 'С', - 'Т', - 'У', - 'Ф', - 'Х', - 'Ц', - 'Ч', - 'Ш', - 'Щ', - 'Ъ', - 'Ъ', - 'Ь', - 'Э', - 'Ю', - 'Я' - ); - - return str_replace($convert_from, $convert_to, $string); - } - - /** - * Вернуть уникод символ по html entinty - * - * @param string $entity - * - * @return string - * - * @since 3.5 - */ - public static function html_char_entity_to_unicode($entity) - { - if(isset(self::$html4_char_ents[ $entity ])) - { - return self::_getUnicodeChar(self::$html4_char_ents[ $entity ]); - } - - return false; - } - - /** - * Сконвериторвать все html entity в соответсвующие юникод символы - * - * @param string $text - * - * @since 3.5 - */ - public static function convert_html_entities_to_unicode(&$text) - { - $text = preg_replace_callback("/\&#([0-9]+)\;/", - create_function('$m', 'return EMT_Lib::_getUnicodeChar(intval($m[1]));') - , $text); - $text = preg_replace_callback("/\&#x([0-9A-F]+)\;/", - create_function('$m', 'return EMT_Lib::_getUnicodeChar(hexdec($m[1]));') - , $text); - $text = preg_replace_callback("/\&([a-zA-Z0-9]+)\;/", - create_function('$m', '$r = EMT_Lib::html_char_entity_to_unicode($m[1]); return $r ? $r : $m[0];') - , $text); - } - - /** - * @param $haystack - * @param $needle - * @param int $offset - * - * @return bool|false|int - * - * @since 3.5 - */ - public static function rstrpos($haystack, $needle, $offset = 0) - { - if(trim($haystack) != '' && trim($needle) != '' && $offset <= mb_strlen($haystack)) - { - $last_pos = $offset; - $found = false; - - while(($curr_pos = mb_strpos($haystack, $needle, $last_pos)) !== false) - { - $found = true; - $last_pos = $curr_pos + 1; - } - - if($found) - { - return $last_pos - 1; - } - else - { - return false; - } - } - else - { - return false; - } - } - - /** - * @param $cond - * @param $true - * @param $false - * - * @return mixed - * - * @since 3.5 - */ - public static function ifop($cond, $true, $false) - { - return $cond ? $true : $false; - } - - /** - * @param $num - * - * @return string - * - * @since 3.5 - */ - public function split_number($num) - { - return number_format($num, 0, '', ' '); - } -} - -/** - * Базовый класс для группы правил обработки текста - * Класс группы должен наследовать, данный класс и задавать - * в нём EMT_Tret::rules и EMT_Tret::$name - * - */ -class EMT_Tret -{ - /** - * Защищенные теги - * - * @todo привязать к методам из Jare_Typograph_Tool - */ - const BASE64_PARAGRAPH_TAG = 'cA==='; - const BASE64_BREAKLINE_TAG = 'YnIgLw==='; - const BASE64_NOBR_OTAG = 'bm9icg==='; - const BASE64_NOBR_CTAG = 'L25vYnI=='; - - /** - * Типы кавычек - */ - const QUOTE_FIRS_OPEN = '«'; - const QUOTE_FIRS_CLOSE = '»'; - const QUOTE_CRAWSE_OPEN = '„'; - const QUOTE_CRAWSE_CLOSE = '“'; - - /** - * Набор правил в данной группе, который задан изначально - * Его можно менять динамически добавляя туда правила с помощью put_rule - */ - public $rules; - public $title; - public $logging = false; - public $logs = false; - public $errors = false; - public $debug_enabled = false; - public $debug_info = array(); - public $class_names = array(); - public $classes = array(); // p - public $settings = array(); // br / (с пробелом и слэшем) - protected $_text = ''; // nobr - private $disabled = array(); // /nobr - private $enabled = array(); - private $use_layout = false; - private $use_layout_set = false; - private $class_layout_prefix = false; - private $thereplacement = ''; - - /** - * Установить режим разметки для данного Трэта если не было раньше установлено, - * EMT_Lib::LAYOUT_STYLE - с помощью стилей - * EMT_Lib::LAYOUT_CLASS - с помощью классов - * - * @param $layout - * - * @since 3.5 - */ - public function set_tag_layout_ifnotset($layout) - { - if($this->use_layout_set) - { - return; - } - - $this->use_layout = $layout; - } - - /** - * Установить режим разметки для данного Трэта, - * EMT_Lib::LAYOUT_STYLE - с помощью стилей - * EMT_Lib::LAYOUT_CLASS - с помощью классов - * EMT_Lib::LAYOUT_STYLE|EMT_Lib::LAYOUT_CLASS - оба метода - * - * @param int $layout - * - * @since 3.5 - */ - public function set_tag_layout($layout = EMT_Lib::LAYOUT_STYLE) - { - $this->use_layout = $layout; - $this->use_layout_set = true; - } - - /** - * @param $prefix - * - * - * @since 3.5 - */ - public function set_class_layout_prefix($prefix) - { - $this->class_layout_prefix = $prefix; - } - - /** - * - * - * @since 3.5 - */ - public function debug_on() - { - $this->debug_enabled = true; - } - - /** - * - * - * @since 3.5 - */ - public function log_on() - { - $this->debug_enabled = true; - } - - /** - * Добавить правило в группу - * - * @param string $name - * @param array $params - * - * @return \EMT_Tret - * - * @since 3.5 - */ - public function put_rule($name, $params) - { - $this->rules[ $name ] = $params; - - return $this; - } - - /** - * Добавить настройку в трет - * - * @param string $key ключ - * @param mixed $value значение - * - * @since 3.5 - */ - public function set($key, $value) - { - $this->settings[ $key ] = $value; - } - - /** - * @param $key - * - * @return string - * - * @since 3.5 - */ - public function ss($key) - { - if(!isset($this->settings[ $key ])) - { - return ''; - } - - return strval($this->settings[ $key ]); - } - - /** - * Добавить настройку в правило - * - * @param string $rulename идентификатор правила - * @param string $key ключ - * @param mixed $value значение - * - * @since 3.5 - */ - public function set_rule($rulename, $key, $value) - { - $this->rules[ $rulename ][ $key ] = $value; - } - - /** - * Включить правила, согласно списку - * - * @param array $list список правил - * @param boolean $disable выкллючить их или включить - * @param boolean $strict строго, т.е. те которые не в списку будут тоже обработаны - * - * @since 3.5 - */ - public function activate($list, $disable = false, $strict = true) - { - if(!is_array($list)) - { - return; - } - - foreach($list as $rulename) - { - if($disable) - { - $this->disable_rule($rulename); - } - else - { - $this->enable_rule($rulename); - } - } - - if($strict) - { - foreach($this->rules as $rulename => $v) - { - if(in_array($rulename, $list)) - { - continue; - } - - if(!$disable) - { - $this->disable_rule($rulename); - } - else - { - $this->enable_rule($rulename); - } - } - } - } - - /** - * Отключить правило, в обработке - * - * @param string $name - * - * @since 3.5 - */ - public function disable_rule($name) - { - $this->disabled[ $name ] = true; - - unset($this->enabled[ $name ]); - } - - /** - * Включить правило - * - * @param string $name - * - * @since 3.5 - */ - public function enable_rule($name) - { - $this->enabled[ $name ] = true; - - unset($this->disabled[ $name ]); - } - - /** - * @param $text - * - * - * @since 3.5 - */ - public function set_text(&$text) - { - $this->_text = &$text; - $this->debug_info = array(); - $this->logs = array(); - } - - /** - * Применить к тексту - * - * @param mixed $list - список правил, null - все правила - * - * @return string - * - * @since 3.5 - */ - public function apply($list = null) - { - if(is_string($list)) - { - $rlist = array( $list ); - } - elseif(is_array($list)) - { - $rlist = $list; - } - else - { - $rlist = array_keys($this->rules); - } - - $this->_apply($rlist); - - return $this->_text; - } - - /** - * @param $list - * - * - * @since 3.5 - */ - private function _apply($list) - { - $this->errors = array(); - $this->_pre_parse(); - - $this->log('Применяется набор правил', implode(',', $list)); - - $rulelist = array(); - - foreach($list as $k) - { - $rule = $this->rules[ $k ]; - $rule[ 'id' ] = $k; - $rule[ 'order' ] = isset($rule[ 'order' ]) ? $rule[ 'order' ] : 5; - $rulelist[] = $rule; - } - - foreach($rulelist as $rule) - { - $this->apply_rule($rule); - $this->debug($rule[ 'id' ], $this->_text); - } - - $this->_post_parse(); - } - - /** - * - * - * @since 3.5 - */ - private function _pre_parse() - { - $this->pre_parse(); - foreach($this->rules as $rule) - { - if(!isset($rule[ 'init' ])) - { - continue; - } - - $m = $this->getmethod($rule[ 'init' ]); - - if(!$m) - { - continue; - } - - call_user_func($m); - } - } - - /** - * Код, выполняем до того, как применить правила - * - * @since 3.5 - * - */ - public function pre_parse() - { - } - - /** - * @param $name - * - * @return array|bool - * - * @since 3.5 - */ - private function getmethod($name) - { - if(!$name) - { - return false; - } - - if(!method_exists($this, $name)) - { - return false; - } - - return array( - $this, - $name - ); - } - - /** - * @param $str - * @param null $data - * - * - * @since 3.5 - */ - private function log($str, $data = null) - { - if(!$this->logging) - { - return; - } - - $this->logs[] = array( - 'info' => $str, - 'data' => $data - ); - } - - /** - * @param $rule - * - * - * @since 3.5 - */ - private function apply_rule($rule) - { - $name = $rule[ 'id' ]; - $disabled = (isset($this->disabled[ $rule[ 'id' ] ]) && $this->disabled[ $rule[ 'id' ] ]) || ((isset($rule[ 'disabled' ]) && $rule[ 'disabled' ]) && !(isset($this->enabled[ $rule[ 'id' ] ]) && $this->enabled[ $rule[ 'id' ] ])); - - if($disabled) - { - $this->log("Правило $name", 'Правило отключено' . ((isset($rule[ 'disabled' ]) && $rule[ 'disabled' ]) ? ' (по умолчанию)' : '')); - - return; - } - if(isset($rule[ 'function' ]) && $rule[ 'function' ]) - { - if(!(isset($rule[ 'pattern' ]) && $rule[ 'pattern' ])) - { - if(method_exists($this, $rule[ 'function' ])) - { - $this->log("Правило $name", 'Используется метод ' . $rule[ 'function' ] . ' в правиле'); - - call_user_func(array( - $this, - $rule[ 'function' ] - )); - - return; - } - - if(function_exists($rule[ 'function' ])) - { - $this->log("Правило $name", 'Используется функция ' . $rule[ 'function' ] . ' в правиле'); - - call_user_func($rule[ 'function' ]); - - return; - } - - $this->error('Функция ' . $rule[ 'function' ] . ' из правила ' . $rule[ 'id' ] . ' не найдена'); - - return; - } - else - { - if(preg_match('/^[a-z_0-9]+$/i', $rule[ 'function' ])) - { - if(method_exists($this, $rule[ 'function' ])) - { - $this->log("Правило $name", 'Замена с использованием preg_replace_callback с методом ' . $rule[ 'function' ] . ''); - - $this->_text = preg_replace_callback($rule[ 'pattern' ], array( - $this, - $rule[ 'function' ] - ), $this->_text); - - return; - } - - if(function_exists($rule[ 'function' ])) - { - $this->log("Правило $name", 'Замена с использованием preg_replace_callback с функцией ' . $rule[ 'function' ] . ''); - - $this->_text = preg_replace_callback($rule[ 'pattern' ], $rule[ 'function' ], $this->_text); - - return; - } - - $this->error('Функция ' . $rule[ 'function' ] . ' из правила ' . $rule[ 'id' ] . ' не найдена'); - } - else - { - $this->_text = preg_replace_callback($rule[ 'pattern' ], create_function('$m', $rule[ 'function' ]), $this->_text); - $this->log('Замена с использованием preg_replace_callback с инлайн функцией из правила ' . $rule[ 'id' ]); - - return; - } - - return; - } - } - - if(isset($rule[ 'simple_replace' ]) && $rule[ 'simple_replace' ]) - { - if(isset($rule[ 'case_sensitive' ]) && $rule[ 'case_sensitive' ]) - { - $this->log("Правило $name", 'Простая замена с использованием str_replace'); - $this->_text = str_replace($rule[ 'pattern' ], $rule[ 'replacement' ], $this->_text); - - return; - } - - $this->log("Правило $name", 'Простая замена с использованием str_ireplace'); - $this->_text = str_ireplace($rule[ 'pattern' ], $rule[ 'replacement' ], $this->_text); - - return; - } - - $pattern = $rule[ 'pattern' ]; - - if(is_string($pattern)) - { - $pattern = array( $pattern ); - } - - $eval = false; - - foreach($pattern as $patt) - { - $chr = substr($patt, 0, 1); - $preg_arr = explode($chr, $patt); - - if(strpos($preg_arr[ count($preg_arr) - 1 ], 'e') !== false) - { - $eval = true; - - break; - } - } - - if(!$eval) - { - $this->log("Правило $name", 'Замена с использованием preg_replace'); - - do - { - $this->_text = preg_replace($rule[ 'pattern' ], $rule[ 'replacement' ], $this->_text); - - if(!(isset($rule[ 'cycled' ]) && $rule[ 'cycled' ])) - { - break; - } - } - while(preg_match($rule[ 'pattern' ], $this->_text)); - - return; - } - - $this->log("Правило $name", 'Замена с использованием preg_replace_callback вместо eval'); - - $k = 0; - foreach($pattern as $patt) - { - $repl = is_string($rule[ 'replacement' ]) ? $rule[ 'replacement' ] : $rule[ 'replacement' ][ $k ]; - - $chr = substr($patt, 0, 1); - $preg_arr = explode($chr, $patt); - - if(strpos($preg_arr[ count($preg_arr) - 1 ], 'e') !== false) // eval система - { - $preg_arr[ count($preg_arr) - 1 ] = str_replace('e', '', $preg_arr[ count($preg_arr) - 1 ]); - $patt = implode($chr, $preg_arr); - $this->thereplacement = $repl; - - do - { - $this->_text = preg_replace_callback($patt, array( - $this, - 'thereplcallback' - ), $this->_text); - - if(!(isset($rule[ 'cycled' ]) && $rule[ 'cycled' ])) - { - break; - } - } - while(preg_match($patt, $this->_text)); - - } - else - { - do - { - $this->_text = preg_replace($patt, $repl, $this->_text); - - if(!(isset($rule[ 'cycled' ]) && $rule[ 'cycled' ])) - { - break; - } - } - while(preg_match($patt, $this->_text)); - } - $k++; - } - } - - /** - * @param $info - * @param null $data - * - * - * @since 3.5 - */ - private function error($info, $data = null) - { - $this->errors[] = array( - 'info' => $info, - 'data' => $data - ); - - $this->log('ERROR: ' . $info, $data); - } - - public function debug($place, &$after_text) - { - if(!$this->debug_enabled) - { - return; - } - - $this->debug_info[] = array( - 'place' => $place, - 'text' => $after_text, - ); - } - - /** - * - * - * @since 3.5 - */ - private function _post_parse() - { - foreach($this->rules as $rule) - { - if(!isset($rule[ 'deinit' ])) - { - continue; - } - - $m = $this->getmethod($rule[ 'deinit' ]); - - if(!$m) - { - continue; - } - - call_user_func($m); - } - - $this->post_parse(); - } - - /** - * После выполнения всех правил, выполняется этот метод - * - * @since 3.5* - */ - public function post_parse() - { - } - - /** - * @param $pattern - * @param $replacement - * @param $text - * - * @return null|string|string[] - * - * @since 3.5 - */ - protected function preg_replace_e($pattern, $replacement, $text) - { - $chr = substr($pattern, 0, 1); - $preg_arr = explode($chr, $pattern); - - if(strpos($preg_arr[ count($preg_arr) - 1 ], 'e') === false) - { - return preg_replace($pattern, $replacement, $text); - } - - $preg_arr[ count($preg_arr) - 1 ] = str_replace('e', '', $preg_arr[ count($preg_arr) - 1 ]); - $patt = implode($chr, $preg_arr); - $this->thereplacement = $replacement; - - return preg_replace_callback($patt, array( - $this, - 'thereplcallback' - ), $text); - } - - /** - * Создание защищенного тега с содержимым - * - * @see EMT_lib::build_safe_tag - * - * @param string $content - * @param string $tag - * @param array $attribute - * - * @return string - * - * @since 3.5 - */ - protected function tag($content, $tag = 'span', $attribute = array()) - { - if(isset($attribute[ 'class' ])) - { - $classname = $attribute[ 'class' ]; - - if($classname == 'nowrap') - { - if(!$this->is_on('nowrap')) - { - $tag = 'nobr'; - $attribute = array(); - $classname = ''; - } - } - - if(isset($this->classes[ $classname ])) - { - $style_inline = $this->classes[ $classname ]; - - if($style_inline) - { - $attribute[ '__style' ] = $style_inline; - } - } - - $classname = (isset($this->class_names[ $classname ]) ? $this->class_names[ $classname ] : $classname); - $classname = ($this->class_layout_prefix ? $this->class_layout_prefix : '') . $classname; - $attribute[ 'class' ] = $classname; - } - - return EMT_Lib::build_safe_tag($content, $tag, $attribute, $this->use_layout === false ? EMT_Lib::LAYOUT_STYLE : $this->use_layout); - } - - /** - * Установлена ли настройка - * - * @param string $key - * - * @return bool - * - * @since 3.5 - */ - public function is_on($key) - { - if(!isset($this->settings[ $key ])) - { - return false; - } - - $kk = $this->settings[ $key ]; - - return ((strtolower($kk) == 'on') || ($kk === '1') || ($kk === true) || ($kk === 1)); - } - - /** - * @param $m - * - * @return int - * - * @since 3.5 - */ -/* private function rule_order_sort($a, $b) - { - if($a[ 'order' ] == $b[ 'order' ]) - { - return 0; - } - - if($a[ 'order' ] < $b[ 'order' ]) - { - return -1; - } - - return 1; - }*/ - - /** - * @param $m - * - * @return string - * - * @since 3.5 - */ - private function thereplcallback($m) - { - $x = ''; - - eval('$x = ' . ($this->thereplacement ? $this->thereplacement : '""') . ';'); - - return $x; - } -} - -/** - * @see EMT_Tret - */ -class EMT_Tret_Abbr extends EMT_Tret -{ - public $title = 'Сокращения'; - - public $domain_zones = array( - 'ru', - 'ру', - 'com', - 'ком', - 'org', - 'орг', - 'уа', - 'ua' - ); - - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - public $rules = array( - 'nobr_abbreviation' => array( - 'description' => 'Расстановка пробелов перед сокращениями dpi, lpi', - 'pattern' => '/(\s+|^|\>)(\d+)(\040|\t)*(dpi|lpi)([\s\;\.\?\!\:\(]|$)/i', - 'replacement' => '\1\2 \4\5' - ), - 'nobr_acronym' => array( - 'description' => 'Расстановка пробелов перед сокращениями гл., стр., рис., илл., ст., п.', - 'pattern' => '/(\s|^|\>|\()(гл|стр|рис|илл?|ст|п|с)\.(\040|\t)*(\d+)(\ \;|\s|\.|\,|\?|\!|$)/iu', - 'replacement' => '\1\2. \4\5' - ), - 'nobr_sm_im' => array( - 'description' => 'Расстановка пробелов перед сокращениями см., им.', - 'pattern' => '/(\s|^|\>|\()(см|им)\.(\040|\t)*([а-яёєїі0-9a-z]+)(\s|\.|\,|\?|\!|$)/iu', - 'replacement' => '\1\2. \4\5' - ), - 'nobr_locations' => array( - 'description' => 'Расстановка пробелов в сокращениях г., ул., пер., д.', - 'pattern' => array( - '/(\s|^|\>)(г|ул|пер|просп|пл|бул|наб|пр|ш|туп)\.(\040|\t)*([а-яёєїі0-9a-z]+)(\s|\.|\,|\?|\!|$)/iu', - '/(\s|^|\>)(б\-р|пр\-кт)(\040|\t)*([а-яёєїі0-9a-z]+)(\s|\.|\,|\?|\!|$)/iu', - '/(\s|^|\>)(д|кв|эт)\.(\040|\t)*(\d+)(\s|\.|\,|\?|\!|$)/iu', - ), - 'replacement' => array( - '\1\2. \4\5', - '\1\2 \4\5', - '\1\2. \4\5', - ) - ), - 'nbsp_before_unit' => array( - 'description' => 'Замена символов и привязка сокращений в размерных величинах: м, см, м2…', - 'pattern' => array( - '/(\s|^|\>|\ \;|\,)(\d+)( |\ \;)?(м|мм|см|дм|км|гм|km|dm|cm|mm)(\s|\.|\!|\?|\,|$|\±\;|\;|\<)/iu', - '/(\s|^|\>|\ \;|\,)(\d+)( |\ \;)?(м|мм|см|дм|км|гм|km|dm|cm|mm)([32]|³|²)(\s|\.|\!|\?|\,|$|\±\;|\;|\<)/iue' - ), - 'replacement' => array( - '\1\2 \4\5', - '$m[1].$m[2]." ".$m[4].($m[5]=="3"||$m[5]=="2"? "&sup".$m[5].";" : $m[5] ).$m[6]' - ), - ), - 'nbsp_before_weight_unit' => array( - 'description' => 'Замена символов и привязка сокращений в весовых величинах: г, кг, мг…', - 'pattern' => '/(\s|^|\>|\ \;|\,)(\d+)( |\ \;)?(г|кг|мг|т)(\s|\.|\!|\?|\,|$|\ \;|\;)/iu', - 'replacement' => '\1\2 \4\5', - ), - 'nobr_before_unit_volt' => array( - 'description' => 'Установка пробельных символов в сокращении вольт', - 'pattern' => '/(\d+)([вВ]| В)(\s|\.|\!|\?|\,|$)/u', - 'replacement' => '\1 В\3' - ), - 'ps_pps' => array( - 'description' => 'Объединение сокращений P.S., P.P.S.', - 'pattern' => '/(^|\040|\t|\>|\r|\n)(p\.\040?)(p\.\040?)?(s\.)([^\<])/ie', - 'replacement' => '$m[1] . $this->tag(trim($m[2]) . " " . ($m[3] ? trim($m[3]) . " " : ""). $m[4], "span", array("class" => "nowrap") ).$m[5] ' - ), - 'nobr_vtch_itd_itp' => array( - 'description' => 'Объединение сокращений и т.д., и т.п., в т.ч.', - 'cycled' => true, - 'pattern' => array( - '/(^|\s|\ \;)и( |\ \;)т\.?[ ]?д(\.|$|\s|\ \;)/ue', - '/(^|\s|\ \;)и( |\ \;)т\.?[ ]?п(\.|$|\s|\ \;)/ue', - '/(^|\s|\ \;)в( |\ \;)т\.?[ ]?ч(\.|$|\s|\ \;)/ue', - ), - 'replacement' => array( - '$m[1].$this->tag("и т. д.", "span", array("class" => "nowrap")).($m[3]!="."? $m[3] : "" )', - '$m[1].$this->tag("и т. п.", "span", array("class" => "nowrap")).($m[3]!="."? $m[3] : "" )', - '$m[1].$this->tag("в т. ч.", "span", array("class" => "nowrap")).($m[3]!="."? $m[3] : "" )', - ) - ), - 'nbsp_te' => array( - 'description' => 'Обработка т.е.', - 'pattern' => '/(^|\s|\ \;)([тТ])\.?[ ]?е\./ue', - 'replacement' => '$m[1].$this->tag($m[2].". е.", "span", array("class" => "nowrap"))', - ), - 'nbsp_money_abbr' => array( - 'description' => 'Форматирование денежных сокращений (расстановка пробелов и привязка названия валюты к числу)', - 'pattern' => '/(\d)((\040|\ \;)?(тыс|млн|млрд)\.?(\040|\ \;)?)?(\040|\ \;)?(руб\.|долл\.|евро|€|€|\$|у[\.]? ?е[\.]?)/ieu', - 'replacement' => '$m[1].($m[4]?" ".$m[4].($m[4]=="тыс"?".":""):"")." ".(!preg_match("#у[\\\\.]? ?е[\\\\.]?#iu",$m[7])?$m[7]:"у.е.")', - ), - 'nbsp_money_abbr_rev' => array( - 'description' => 'Привязка валюты к числу спереди', - 'pattern' => '/(€|€|\$)\s?(\d)/iu', - 'replacement' => '\1 \2' - ), - 'nbsp_org_abbr' => array( - 'description' => 'Привязка сокращений форм собственности к названиям организаций', - 'pattern' => '/([^a-zA-Zа-яёєїіА-ЯЁЄЇІ]|^)(ООО|ЗАО|ОАО|НИИ|ПБОЮЛ) ([a-zA-Zа-яёєїіА-ЯЁЄЇІ]|\"|\«\;|\&bdquo\;|<)/u', - 'replacement' => '\1\2 \3' - ), - 'nobr_gost' => array( - 'description' => 'Привязка сокращения ГОСТ к номеру', - 'pattern' => array( - '/(\040|\t|\ \;|^)ГОСТ( |\ \;)?(\d+)((\-|\&minus\;|\&mdash\;)(\d+))?(( |\ \;)(\-|\&mdash\;))?/ieu', - '/(\040|\t|\ \;|^|\>)ГОСТ( |\ \;)?(\d+)(\-|\&minus\;|\&mdash\;)(\d+)/ieu', - ), - 'replacement' => array( - '$m[1].$this->tag("ГОСТ ".$m[3].(isset($m[6])?"–".$m[6]:"").(isset($m[7])?" —":""),"span", array("class"=>"nowrap"))', - '$m[1]."ГОСТ ".$m[3]."–".$m[5]', - ), - ), - ); -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_Dash extends EMT_Tret -{ - public $title = 'Дефисы и тире'; - - public $rules = array( - 'mdash_symbol_to_html_mdash' => array( - 'description' => 'Замена символа тире на html конструкцию', - 'pattern' => '/—/iu', - 'replacement' => '—' - ), - 'mdash' => array( - 'description' => 'Тире после кавычек, скобочек, пунктуации', - 'pattern' => array( - '/([a-zа-яёєїі0-9]+|\,|\:|\)|\&(ra|ld)quo\;|\|\"|\>)(\040|\t)(—|\-|\&mdash\;)(\s|$|\<)/ui', - '/(\,|\:|\)|\")(—|\-|\&mdash\;)(\s|$|\<)/ui', - ), - 'replacement' => array( - '\1 —\5', - '\1 —\3', - ), - ), - 'mdash_2' => array( - 'description' => 'Тире после переноса строки', - 'pattern' => '/(\n|\r|^|\>)(\-|\&mdash\;)(\t|\040)/', - 'replacement' => '\1— ' - ), - 'mdash_3' => array( - 'description' => 'Тире после знаков восклицания, троеточия и прочее', - 'pattern' => '/(\.|\!|\?|\&hellip\;)(\040|\t|\ \;)(\-|\&mdash\;)(\040|\t|\ \;)/', - 'replacement' => '\1 — ' - ), - 'iz_za_pod' => array( - 'description' => 'Расстановка дефисов между из-за, из-под', - 'pattern' => '/(\s|\ \;|\>|^)(из)(\040|\t|\ \;)\-?(за|под)([\.\,\!\?\:\;]|\040|\ \;)/uie', - 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' - ), - 'to_libo_nibud' => array( - 'description' => 'Автоматическая простановка дефисов в обезличенных местоимениях и междометиях', - 'cycled' => true, - 'pattern' => '/(\s|^|\ \;|\>)(кто|кем|когда|зачем|почему|как|что|чем|где|чего|кого)\-?(\040|\t|\ \;)\-?(то|либо|нибудь)([\.\,\!\?\;]|\040|\ \;|$)/uie', - 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' - ), - 'koe_kak' => array( - 'description' => 'Кое-как, кой-кого, все-таки', - 'cycled' => true, - 'pattern' => array( - '/(\s|^|\ \;|\>)(кое)\-?(\040|\t|\ \;)\-?(как)([\.\,\!\?\;]|\040|\ \;|$)/uie', - '/(\s|^|\ \;|\>)(кой)\-?(\040|\t|\ \;)\-?(кого)([\.\,\!\?\;]|\040|\ \;|$)/uie', - '/(\s|^|\ \;|\>)(вс[её])\-?(\040|\t|\ \;)\-?(таки)([\.\,\!\?\;]|\040|\ \;|$)/uie', - ), - 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' - ), - 'ka_de_kas' => array( - 'description' => 'Расстановка дефисов с частицами ка, де, кась', - 'disabled' => true, - 'pattern' => array( - '/(\s|^|\ \;|\>)([а-яёєїі]+)(\040|\t|\ \;)(ка)([\.\,\!\?\;]|\040|\ \;|$)/uie', - '/(\s|^|\ \;|\>)([а-яёєїі]+)(\040|\t|\ \;)(де)([\.\,\!\?\;]|\040|\ \;|$)/uie', - '/(\s|^|\ \;|\>)([а-яёєїі]+)(\040|\t|\ \;)(кась)([\.\,\!\?\;]|\040|\ \;|$)/uie', - ), - 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' - ), - ); -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_Date extends EMT_Tret -{ - public $title = 'Даты и дни'; - - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - public $rules = array( - 'years' => array( - 'description' => 'Установка тире и пробельных символов в периодах дат', - 'pattern' => '/(с|по|период|середины|начала|начало|конца|конец|половины|в|между|\([cс]\)|\©\;)(\s+|\ \;)([\d]{4})(-|\&mdash\;|\&minus\;)([\d]{4})(( |\ \;)?(г\.г\.|гг\.|гг|г\.|г)([^а-яёєїіa-z]))?/eui', - 'replacement' => '$m[1].$m[2]. (intval($m[3])>=intval($m[5])? $m[3].$m[4].$m[5] : $m[3]."—".$m[5]) . (isset($m[6])? " гг.":"").(isset($m[9])?$m[9]:"")' - ), - 'mdash_month_interval' => array( - 'description' => 'Расстановка тире и объединение в неразрывные периоды месяцев', - 'disabled' => true, - 'pattern' => '/((январ|феврал|сентябр|октябр|ноябр|декабр)([ьяюе]|[её]м)|(апрел|июн|июл)([ьяюе]|ем)|(март|август)([ауе]|ом)?|ма[йяюе]|маем)\-((январ|феврал|сентябр|октябр|ноябр|декабр)([ьяюе]|[её]м)|(апрел|июн|июл)([ьяюе]|ем)|(март|август)([ауе]|ом)?|ма[йяюе]|маем)/iu', - 'replacement' => '\1—\8' - ), - 'nbsp_and_dash_month_interval' => array( - 'description' => 'Расстановка тире и объединение в неразрывные периоды дней', - 'disabled' => true, - 'pattern' => '/([^\>]|^)(\d+)(\-|\&minus\;|\&mdash\;)(\d+)( |\ \;)(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)([^\<]|$)/ieu', - 'replacement' => '$m[1].$this->tag($m[2]."—".$m[4]." ".$m[6],"span", array("class"=>"nowrap")).$m[7]' - ), - 'nobr_year_in_date' => array( - 'description' => 'Привязка года к дате', - 'pattern' => array( - '/(\s|\ \;)([0-9]{2}\.[0-9]{2}\.([0-9]{2})?[0-9]{2})(\s|\ \;)?г(\.|\s|\ \;)/eiu', - '/(\s|\ \;)([0-9]{2}\.[0-9]{2}\.([0-9]{2})?[0-9]{2})(\s|\ \;|\.(\s|\ \;|$)|$)/eiu', - ), - 'replacement' => array( - '$m[1].$this->tag($m[2]." г.","span", array("class"=>"nowrap")).($m[5]==="."?"":" ")', - '$m[1].$this->tag($m[2],"span", array("class"=>"nowrap")).$m[4]', - ), - ), - 'space_posle_goda' => array( - 'description' => 'Пробел после года', - 'pattern' => '/(^|\040|\ \;)([0-9]{3,4})(год([ауе]|ом)?)([^a-zа-яёєїі]|$)/ui', - 'replacement' => '\1\2 \3\5' - ), - 'nbsp_posle_goda_abbr' => array( - 'description' => 'Пробел после года', - 'pattern' => '/(^|\040|\ \;|\"|\«\;)([0-9]{3,4})[ ]?(г\.)([^a-zа-яёєїі]|$)/ui', - 'replacement' => '\1\2 \3\4' - ), - ); -} - -/** - * @see EMT_Tret - */ -class EMT_Tret_Etc extends EMT_Tret -{ - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - /** - * Базовые параметры тофа - * - * @var array - */ - public $title = 'Прочее'; - - public $rules = array( - 'acute_accent' => array( - 'description' => 'Акцент', - 'pattern' => '/(у|е|ы|а|о|э|я|и|ю|ё)\`(\w)/i', - 'replacement' => '\1́\2' - ), - 'word_sup' => array( - 'description' => 'Надстрочный текст после символа ^', - 'pattern' => '/((\s|\ \;|^)+)\^([a-zа-яёєїі0-9\.\:\,\-]+)(\s|\ \;|$|\.$)/ieu', - 'replacement' => '"" . $this->tag($this->tag($m[3],"small"),"sup") . $m[4]' - ), - 'century_period' => array( - 'description' => 'Тире между диапозоном веков', - 'pattern' => '/(\040|\t|\ \;|^)([XIV]{1,5})(-|\&mdash\;)([XIV]{1,5})(( |\ \;)?(в\.в\.|вв\.|вв|в\.|в))/eu', - 'replacement' => '$m[1] .$this->tag($m[2]."—".$m[4]." вв.","span", array("class"=>"nowrap"))' - ), - 'time_interval' => array( - 'description' => 'Тире и отмена переноса между диапозоном времени', - 'pattern' => '/([^\d\>]|^)([\d]{1,2}\:[\d]{2})(-|\&mdash\;|\&minus\;)([\d]{1,2}\:[\d]{2})([^\d\<]|$)/eui', - 'replacement' => '$m[1] . $this->tag($m[2]."—".$m[4],"span", array("class"=>"nowrap")).$m[5]' - ), - 'split_number_to_triads' => array( - 'description' => 'Разбиение числа на триады', - 'pattern' => '/([^a-zA-Z0-9<\)]|^)([0-9]{5,})([^a-zA-Z>\(]|$)/eu', - 'replacement' => '$m[1].str_replace(" "," ",EMT_Lib::split_number($m[2])).$m[3] ' - ), - 'expand_no_nbsp_in_nobr' => array( - 'description' => 'Удаление nbsp в nobr/nowrap тэгах', - 'function' => 'remove_nbsp' - ), - 'nobr_to_nbsp' => array( - 'description' => 'Преобразование nobr в nbsp', - 'disabled' => true, - 'function' => 'nobr_to_nbsp' - ), - ); - - /** - * - * - * @since 3.5 - */ - protected function remove_nbsp() - { - $thetag = $this->tag('###', 'span', array( 'class' => 'nowrap' )); - $arr = explode('###', $thetag); - $b = preg_quote($arr[ 0 ], '/'); - $e = preg_quote($arr[ 1 ], '/'); - - $match = '/(^|[^a-zа-яёєїі])([a-zа-яёєїі]+)\ \;(' . $b . ')/iu'; - - do - { - $this->_text = preg_replace($match, '\1\3\2 ', $this->_text); - } - while(preg_match($match, $this->_text)); - - $match = '/(' . $e . ')\ \;([a-zа-яёєїі]+)($|[^a-zа-яёєїі])/iu'; - - do - { - $this->_text = preg_replace($match, ' \2\1\3', $this->_text); - } - while(preg_match($match, $this->_text)); - - $this->_text = $this->preg_replace_e('/' . $b . '.*?' . $e . '/iue', 'str_replace(" "," ",$m[0]);', $this->_text); - } - - /** - * - * - * @since 3.5 - */ - protected function nobr_to_nbsp() - { - $thetag = $this->tag('###', 'span', array( 'class' => 'nowrap' )); - $arr = explode('###', $thetag); - $b = preg_quote($arr[ 0 ], '/'); - $e = preg_quote($arr[ 1 ], '/'); - $this->_text = $this->preg_replace_e('/' . $b . '(.*?)' . $e . '/iue', 'str_replace(" "," ",$m[1]);', $this->_text); - } -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_Nobr extends EMT_Tret -{ - public $title = 'Неразрывные конструкции'; - - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - public $rules = array( - 'super_nbsp' => array( - 'description' => 'Привязка союзов и предлогов к написанным после словам', - 'pattern' => '/(\s|^|\&(la|bd)quo\;|\>|\(|\&mdash\;\ \;)([a-zа-яёєїі]{1,2}\s+)([a-zа-яёєїі]{1,2}\s+)?([a-zа-яёєїі0-9\-]{2,}|[0-9])/ieu', - 'replacement' => '$m[1] . trim($m[3]) . " " . ($m[4] ? trim($m[4]) . " " : "") . $m[5]' - ), - 'nbsp_in_the_end' => array( - 'description' => 'Привязка союзов и предлогов к предыдущим словам в случае конца предложения', - 'pattern' => '/([a-zа-яёєїі0-9\-]{3,}) ([a-zа-яёєїі]{1,2})\.( [A-ZА-ЯЁЄЇІ]|$)/u', - 'replacement' => '\1 \2.\3' - ), - 'phone_builder' => array( - 'description' => 'Объединение в неразрывные конструкции номеров телефонов', - 'pattern' => - array( - '/([^\d\+]|^)([\+]?[0-9]{1,3})( |\ \;|\&thinsp\;)([0-9]{3,4}|\([0-9]{3,4}\))( |\ \;|\&thinsp\;)([0-9]{2,3})(-|\&minus\;)([0-9]{2})(-|\&minus\;)([0-9]{2})([^\d]|$)/e', - '/([^\d\+]|^)([\+]?[0-9]{1,3})( |\ \;|\&thinsp\;)([0-9]{3,4}|[0-9]{3,4})( |\ \;|\&thinsp\;)([0-9]{2,3})(-|\&minus\;)([0-9]{2})(-|\&minus\;)([0-9]{2})([^\d]|$)/e', - ), - 'replacement' => - array( - '$m[1] .(($m[1] == ">" || $m[11] == "<") ? $m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10] :$this->tag($m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10], "span", array("class"=>"nowrap")) ).$m[11]', - '$m[1] .(($m[1] == ">" || $m[11] == "<") ? $m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10] :$this->tag($m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10], "span", array("class"=>"nowrap")) ).$m[11]', - ), - ), - 'phone_builder_v2' => array( - 'description' => 'Дополнительный формат номеров телефонов', - 'pattern' => '/([^\d]|^)\+\s?([0-9]{1})\s?\(([0-9]{3,4})\)\s?(\d{3})(\d{2})(\d{2})([^\d]|$)/ie', - 'replacement' => '$m[1].$this->tag("+".$m[2]." ".$m[3]." ".$m[4]."-".$m[5]."-".$m[6], "span", array("class" => "nowrap")).$m[7]', - ), - 'ip_address' => array( - 'description' => 'Объединение IP-адресов', - 'pattern' => '/(\s|\ \;|^)(\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3})/ie', - 'replacement' => '$m[1] . $this->nowrap_ip_address($m[2])' - ), - 'dots_for_surname_abbr' => array( - 'disabled' => true, - 'description' => 'Простановка точек к инициалам у фамилии', - 'pattern' => - array( - '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁЄЇІ])\.?(\s|\ \;)?([А-ЯЁЄЇІ])(\s|\ \;)([А-ЯЁЄЇІ][а-яёєїі]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', - '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁЄЇІ][а-яёєїі]+)(\s|\ \;)([А-ЯЁЄЇІ])\.?(\s|\ \;)?([А-ЯЁЄЇІ])\.?(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', - ), - 'replacement' => - array( - '$m[1].$this->tag($m[2].". ".$m[4].". ".$m[6], "span", array("class" => "nowrap")).$m[7]', - '$m[1].$this->tag($m[2]." ".$m[4].". ".$m[6].".", "span", array("class" => "nowrap")).$m[7]', - ), - ), - 'spaces_nobr_in_surname_abbr' => array( - 'description' => 'Привязка инициалов к фамилиям', - 'pattern' => - array( - '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁЄЇІ])\.(\s|\ \;)?([А-ЯЁЄЇІ])\.(\s|\ \;)?([А-ЯЁЄЇІ][а-яёєїі]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', - '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁЄЇІ][а-яёєїі]+)(\s|\ \;)([А-ЯЁЄЇІ])\.(\s|\ \;)?([А-ЯЁЄЇІ])\.(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', - '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁЄЇІ])(\s|\ \;)?([А-ЯЁЄЇІ])(\s|\ \;)([А-ЯЁЄЇІ][а-яёєїі]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', - '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁЄЇІ][а-яёєїі]+)(\s|\ \;)([А-ЯЁЄЇІ])(\s|\ \;)?([А-ЯЁЄЇІ])(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', - ), - 'replacement' => - array( - '$m[1].$this->tag($m[2].". ".$m[4].". ".$m[6], "span", array("class" => "nowrap")).$m[7]', - '$m[1].$this->tag($m[2]." ".$m[4].". ".$m[6].".", "span", array("class" => "nowrap")).$m[7]', - '$m[1].$this->tag($m[2].(isset($m[3])? " " : "" ).$m[4].(isset($m[5])? " " : "" ).$m[6], "span", array("class" => "nowrap")).$m[7]', - '$m[1].$this->tag($m[2]." ".$m[4].(isset($m[5])? " " : "" ).$m[6], "span", array("class" => "nowrap")).$m[7]', - ), - ), - 'nbsp_before_particle' => array( - 'description' => 'Неразрывный пробел перед частицей', - 'pattern' => '/(\040|\t)+(ли|бы|б|же|ж)(\ \;|\.|\,|\:|\;|\&hellip\;|\?|\s)/iue', - 'replacement' => '" ".$m[2] . ($m[3] == " " ? " " : $m[3])' - ), - 'nbsp_v_kak_to' => array( - 'description' => 'Неразрывный пробел в как то', - 'pattern' => '/как то\:/ui', - 'replacement' => 'как то:' - ), - 'nbsp_celcius' => array( - 'description' => 'Привязка градусов к числу', - 'pattern' => '/(\s|^|\>|\ \;)(\d+)( |\ \;)?(°|\°\;)(C|С)(\s|\.|\!|\?|\,|$|\ \;|\;)/iu', - 'replacement' => '\1\2 \4C\6' - ), - 'hyphen_nowrap_in_small_words' => array( - 'description' => 'Обрамление пятисимвольных слов разделенных дефисом в неразрывные блоки', - 'disabled' => true, - 'cycled' => true, - 'pattern' => '/(\ \;|\s|\>|^)([a-zа-яёєїі]{1}\-[a-zа-яёєїі]{4}|[a-zа-яёєїі]{2}\-[a-zа-яёєїі]{3}|[a-zа-яёєїі]{3}\-[a-zа-яёєїі]{2}|[a-zа-яёєїі]{4}\-[a-zа-яёєїі]{1}|когда\-то|кое\-как|кой\-кого|вс[её]\-таки|[а-яёєїі]+\-(кась|ка|де))(\s|\.|\,|\!|\?|\ \;|\&hellip\;|$)/uie', - 'replacement' => '$m[1] . $this->tag($m[2], "span", array("class"=>"nowrap")) . $m[4]', - ), - 'hyphen_nowrap' => array( - 'description' => 'Отмена переноса слова с дефисом', - 'disabled' => true, - 'cycled' => true, - 'pattern' => '/(\ \;|\s|\>|^)([a-zа-яёєїі]+)((\-([a-zа-яёєїі]+)){1,2})(\s|\.|\,|\!|\?|\ \;|\&hellip\;|$)/uie', - 'replacement' => '$m[1] . $this->tag($m[2].$m[3], "span", array("class"=>"nowrap")) . $m[6]' - ), - ); - - /** - * @param $triads - * - * @return string - * - * @since 3.5 - */ - protected function nowrap_ip_address($triads) - { - $triad = explode('.', $triads); - $addTag = true; - - foreach($triad as $value) - { - $value = (int) $value; - - if($value > 255) - { - $addTag = false; - - break; - } - } - - if(true === $addTag) - { - $triads = $this->tag($triads, 'span', array( 'class' => 'nowrap' )); - } - - return $triads; - } -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_Number extends EMT_Tret -{ - public $title = 'Числа, дроби, математические знаки'; - - public $rules = array( - 'minus_between_nums' => array( - 'description' => 'Расстановка знака минус между числами', - 'pattern' => '/(\d+)\-(\d)/i', - 'replacement' => '\1−\2' - ), - 'minus_in_numbers_range' => array( - 'description' => 'Расстановка знака минус между диапозоном чисел', - 'pattern' => '/(^|\s|\ \;)(\&minus\;|\-)(\d+)(\.\.\.|\&hellip\;)(\s|\ \;)?(\+|\-|\&minus\;)?(\d+)/ie', - 'replacement' => '$m[1] ."−".$m[3] . $m[4].$m[5].($m[6]=="+"?$m[6]:"−").$m[7]' - ), - 'auto_times_x' => array( - 'description' => 'Замена x на символ × в размерных единицах', - 'cycled' => true, - 'pattern' => '/([^a-zA-Z><]|^)(\×\;)?(\d+)(\040*)(x|х)(\040*)(\d+)([^a-zA-Z><]|$)/u', - 'replacement' => '\1\2\3×\7\8' - ), - 'numeric_sub' => array( - 'description' => 'Нижний индекс', - 'pattern' => '/([a-zа-яёєїі0-9])\_([\d]{1,3})([^@а-яёєїіa-z0-9]|$)/ieu', - 'replacement' => '$m[1] . $this->tag($this->tag($m[2],"small"),"sub") . $m[3]' - ), - 'numeric_sup' => array( - 'description' => 'Верхний индекс', - 'pattern' => '/([a-zа-яёєїі0-9])\^([\d]{1,3})([^а-яёєїіa-z0-9]|$)/ieu', - 'replacement' => '$m[1] . $this->tag($this->tag($m[2],"small"),"sup") . $m[3]' - ), - 'simple_fraction' => array( - 'description' => 'Замена дробей 1/2, 1/4, 3/4 на соответствующие символы', - 'pattern' => array( - '/(^|\D)1\/(2|4)(\D)/', - '/(^|\D)3\/4(\D)/' - ), - 'replacement' => array( - '\1&frac1\2;\3', - '\1¾\2' - ) - ), - 'math_chars' => array( - 'description' => 'Математические знаки больше/меньше/плюс минус/неравно', - 'pattern' => array( - '/!=/', - '/\<=/', - '/([^=]|^)\>=/', - '/~=/', - '/\+-/' - ), - 'replacement' => array( - '≠', - '≤', - '\1≥', - '≅', - '±' - ) - ), - 'thinsp_between_number_triads' => array( - 'description' => 'Объединение триад чисел полупробелом', - 'pattern' => '/([0-9]{1,3}( [0-9]{3}){1,})(.|$)/ue', - 'replacement' => '($m[3]=="-"? $m[0]:str_replace(" "," ",$m[1]).$m[3])' - ), - 'thinsp_between_no_and_number' => array( - 'description' => 'Пробел между симоволом номера и числом', - 'pattern' => '/(№|\№\;)(\s| )*(\d)/iu', - 'replacement' => '№ \3' - ), - 'thinsp_between_sect_and_number' => array( - 'description' => 'Пробел между параграфом и числом', - 'pattern' => '/(§|\§\;)(\s| )*(\d+|[IVX]+|[a-zа-яёєїі]+)/ui', - 'replacement' => '§ \3' - ), - ); -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_OptAlign extends EMT_Tret -{ - public $classes = array( - 'oa_obracket_sp_s' => 'margin-right:0.3em;', - 'oa_obracket_sp_b' => 'margin-left:-0.3em;', - 'oa_obracket_nl_b' => 'margin-left:-0.3em;', - 'oa_comma_b' => 'margin-right:-0.2em;', - 'oa_comma_e' => 'margin-left:0.2em;', - 'oa_oquote_nl' => 'margin-left:-0.44em;', - 'oa_oqoute_sp_s' => 'margin-right:0.44em;', - 'oa_oqoute_sp_q' => 'margin-left:-0.44em;', - ); - - /** - * Базовые параметры тофа - * - * @var array - */ - public $title = 'Оптическое выравнивание'; - - public $rules = array( - 'oa_oquote' => array( - 'description' => 'Оптическое выравнивание открывающей кавычки', - //'disabled' => true, - 'pattern' => array( - '/([a-zа-яёєїі\-]{3,})(\040|\ \;|\t)(\«\;)/uie', - '/(\n|\r|^)(\«\;)/ei' - ), - 'replacement' => array( - '$m[1] . $this->tag($m[2], "span", array("class"=>"oa_oqoute_sp_s")) . $this->tag($m[3], "span", array("class"=>"oa_oqoute_sp_q"))', - '$m[1] . $this->tag($m[2], "span", array("class"=>"oa_oquote_nl"))', - ), - ), - 'oa_oquote_extra' => array( - 'description' => 'Оптическое выравнивание кавычки', - 'function' => 'oaquote_extra' - ), - 'oa_obracket_coma' => array( - 'description' => 'Оптическое выравнивание для пунктуации (скобка)', - 'pattern' => array( - '/(\040|\ \;|\t)\(/ei', - '/(\n|\r|^)\(/ei', - ), - 'replacement' => array( - '$this->tag($m[1], "span", array("class"=>"oa_obracket_sp_s")) . $this->tag("(", "span", array("class"=>"oa_obracket_sp_b"))', - '$m[1] . $this->tag("(", "span", array("class"=>"oa_obracket_nl_b"))', - ), - ), - ); - - /** - * Если стоит открывающая кавычка после

надо делать её висячей - * - * @return void - * - * @since 3.5 - */ - protected function oaquote_extra() - { - $this->_text = $this->preg_replace_e( - '/(<' . self::BASE64_PARAGRAPH_TAG . '>)([\040\t]+)?(\«\;)/e', - '$m[1] . $this->tag($m[3], "span", array("class"=>"oa_oquote_nl"))', - $this->_text); - } -} - -/** - * @see EMT_Tret - */ -class EMT_Tret_Punctmark extends EMT_Tret -{ - public $title = 'Пунктуация и знаки препинания'; - - public $rules = array( - 'auto_comma' => array( - 'description' => 'Расстановка запятых перед а, но', - 'pattern' => '/([a-zа-яёєїі])(\s| )(но|а)(\s| )/iu', - 'replacement' => '\1,\2\3\4' - ), - 'punctuation_marks_limit' => array( - 'description' => 'Лишние восклицательные, вопросительные знаки и точки', - 'pattern' => '/([\!\.\?]){4,}/', - 'replacement' => '\1\1\1' - ), - 'punctuation_marks_base_limit' => array( - 'description' => 'Лишние запятые, двоеточия, точки с запятой', - 'pattern' => '/([\,]|[\:]|[\;]]){2,}/', - 'replacement' => '\1' - ), - 'hellip' => array( - 'description' => 'Замена трех точек на знак многоточия', - 'simple_replace' => true, - 'pattern' => '...', - 'replacement' => '…' - ), - 'fix_excl_quest_marks' => array( - 'description' => 'Замена восклицательного и вопросительного знаков местами', - 'pattern' => '/([a-zа-яёєїі0-9])\!\?(\s|$|\<)/ui', - 'replacement' => '\1?!\2' - ), - 'fix_pmarks' => array( - 'description' => 'Замена сдвоенных знаков препинания на одинарные', - 'pattern' => array( - '/([^\!\?])\.\./', - '/([a-zа-яёєїі0-9])(\!|\.)(\!|\.|\?)(\s|$|\<)/ui', - '/([a-zа-яёєїі0-9])(\?)(\?)(\s|$|\<)/ui', - ), - 'replacement' => array( - '\1.', - '\1\2\4', - '\1\2\4' - ), - ), - 'fix_brackets' => array( - 'description' => 'Лишние пробелы после открывающей скобочки и перед закрывающей', - 'pattern' => array( - '/(\()(\040|\t)+/', - '/(\040|\t)+(\))/' - ), - 'replacement' => array( - '\1', - '\2' - ) - ), - 'fix_brackets_space' => array( - 'description' => 'Пробел перед открывающей скобочкой', - 'pattern' => '/([a-zа-яёєїі])(\()/iu', - 'replacement' => '\1 \2' - ), - 'dot_on_end' => array( - 'description' => 'Точка в конце текста, если её там нет', - 'disabled' => true, - 'pattern' => '/([a-zа-яёєїі0-9])(\040|\t|\ \;)*$/ui', - //'pattern' => '/(([^\.\!\?])|(&(ra|ld)quo;))$/', - 'replacement' => '\1.' - ), - ); -} - -/** - * @see EMT_Tret - */ -class EMT_Tret_Quote extends EMT_Tret -{ - /** - * Базовые параметры тофа - * - * @var array - */ - public $title = 'Кавычки'; - - public $rules = array( - 'quotes_outside_a' => array( - 'description' => 'Кавычки вне тэга ', - //'pattern' => '/(\<%%\_\_.+?\>)\"(.+?)\"(\<\/%%\_\_.+?\>)/s', - 'pattern' => '/(\<%%\_\_[^\>]+\>)\"(.+?)\"(\<\/%%\_\_[^\>]+\>)/s', - 'replacement' => '"\1\2\3"' - ), - 'open_quote' => array( - 'description' => 'Открывающая кавычка', - 'pattern' => '/(^|\(|\s|\>|-)((\"|\\\")+)(\S+)/iue', - 'replacement' => '$m[1] . str_repeat(self::QUOTE_FIRS_OPEN, substr_count($m[2],"\"") ) . $m[4]' - ), - 'close_quote' => array( - 'description' => 'Закрывающая кавычка', - 'pattern' => '/([a-zа-яёєїі0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:|\+|\%|\@|\#|\$|\*)((\"|\\\")+)(\.|\&hellip\;|\;|\:|\?|\!|\,|\s|\)|\<\/|\<|$)/uie', - 'replacement' => '$m[1] . str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[2],"\"") ) . $m[4]' - ), - 'close_quote_adv' => array( - 'description' => 'Закрывающая кавычка особые случаи', - 'pattern' => - array( - '/([a-zа-яёєїі0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:|\+|\%|\@|\#|\$|\*)((\"|\\\"|\«\;)+)(\<[^\>]+\>)(\.|\&hellip\;|\;|\:|\?|\!|\,|\)|\<\/|$| )/uie', - '/([a-zа-яёєїі0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:|\+|\%|\@|\#|\$|\*)(\s+)((\"|\\\")+)(\s+)(\.|\&hellip\;|\;|\:|\?|\!|\,|\)|\<\/|$| )/uie', - '/\>(\«\;)\.($|\s|\<)/ui', - '/\>(\«\;),($|\s|\<|\S)/ui', - '/\>(\«\;):($|\s|\<|\S)/ui', - '/\>(\«\;);($|\s|\<|\S)/ui', - '/\>(\«\;)\)($|\s|\<|\S)/ui', - '/((\"|\\\")+)$/uie', - ), - 'replacement' => - array( - '$m[1] . str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[2],"\"")+substr_count($m[2],"«") ) . $m[4]. $m[5]', - '$m[1] .$m[2]. str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[3],"\"")+substr_count($m[3],"«") ) . $m[5]. $m[6]', - '>».\2', - '>»,\2', - '>»:\2', - '>»;\2', - '>»)\2', - 'str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[1],"\"") )', - ), - ), - 'open_quote_adv' => array( - 'description' => 'Открывающая кавычка особые случаи', - 'pattern' => '/(^|\(|\s|\>)(\"|\\\")(\s)(\S+)/iue', - 'replacement' => '$m[1] . self::QUOTE_FIRS_OPEN .$m[4]' - ), - 'close_quote_adv_2' => array( - 'description' => 'Закрывающая кавычка последний шанс', - 'pattern' => '/(\S)((\"|\\\")+)(\.|\&hellip\;|\;|\:|\?|\!|\,|\s|\)|\<\/|\<|$)/uie', - 'replacement' => '$m[1] . str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[2],"\"") ) . $m[4]' - ), - 'quotation' => array( - 'description' => 'Внутренние кавычки-лапки и дюймы', - 'function' => 'build_sub_quotations' - ), - ); - - /** - * - * - * @since 3.5 - */ - protected function build_sub_quotations() - { - global $__ax, $__ay; - - $exp = strpos($this->_text, '') !== false ? '' : (strpos($this->_text, "\r\n") !== false ? "\r\n\r\n" : "\n\n"); - - $texts_in = explode($exp, $this->_text); - $texts_out = array(); - - foreach($texts_in as $textx) - { - $okposstack = array( '0' ); - $okpos = 0; - $level = 0; - $off = 0; - - while(true) - { - $p = EMT_Lib::strpos_ex($textx, array( - '«', - '»' - ), $off); - - if($p === false) - { - break; - } - - if($p[ 'str' ] == '«') - { - if($level > 0) - { - if(!$this->is_on('no_bdquotes')) - { - $this->inject_in($p[ 'pos' ], self::QUOTE_CRAWSE_OPEN, $textx); - } - } - $level++; - } - - if($p[ 'str' ] == '»') - { - $level--; - - if($level > 0) - { - if(!$this->is_on('no_bdquotes')) - { - $this->inject_in($p[ 'pos' ], self::QUOTE_CRAWSE_CLOSE, $textx); - } - } - } - - $off = $p[ 'pos' ] + strlen($p[ 'str' ]); - - if($level == 0) - { - $okpos = $off; - array_push($okposstack, $okpos); - } - elseif($level < 0) // уровень стал меньше нуля - { - if(!$this->is_on('no_inches')) - { - do - { - $lokpos = array_pop($okposstack); - $k = substr($textx, $lokpos, $off - $lokpos); - $k = str_replace(self::QUOTE_CRAWSE_OPEN, self::QUOTE_FIRS_OPEN, $k); - $k = str_replace(self::QUOTE_CRAWSE_CLOSE, self::QUOTE_FIRS_CLOSE, $k); - - $amount = 0; - $__ax = preg_match_all("/(^|[^0-9])([0-9]+)\»\;/ui", $k, $m); - $__ay = 0; - - if($__ax) - { - $k = preg_replace_callback("/(^|[^0-9])([0-9]+)\»\;/ui", - create_function('$m', 'global $__ax,$__ay; $__ay++; if($__ay==$__ax){ return $m[1].$m[2]."″";} return $m[0];'), - $k); - $amount = 1; - } - } - while(($amount == 0) && count($okposstack)); - - // успешно сделали замену - if($amount == 1) - { - // заново просмотрим содержимое - $textx = substr($textx, 0, $lokpos) . $k . substr($textx, $off); - $off = $lokpos; - $level = 0; - continue; - } - - // иначе просто заменим последнюю явно на " от отчаяния - if($amount == 0) - { - // говорим, что всё в порядке - $level = 0; - $textx = substr($textx, 0, $p[ 'pos' ]) . '"' . substr($textx, $off); - $off = $p[ 'pos' ] + strlen('"'); - $okposstack = array( $off ); - - continue; - } - } - } - - - } - // не совпало количество, отменяем все подкавычки - if($level != 0) - { - // закрывающих меньше, чем надо - if($level > 0) - { - $k = substr($textx, $okpos); - $k = str_replace(self::QUOTE_CRAWSE_OPEN, self::QUOTE_FIRS_OPEN, $k); - $k = str_replace(self::QUOTE_CRAWSE_CLOSE, self::QUOTE_FIRS_CLOSE, $k); - $textx = substr($textx, 0, $okpos) . $k; - } - } - $texts_out[] = $textx; - } - - $this->_text = implode($exp, $texts_out); - } - - /** - * @param $pos - * @param $text - * @param $thetext - * - * - * @since 3.5 - */ - protected function inject_in($pos, $text, &$thetext) - { - for($i = 0, $iMax = strlen($text); $i < $iMax; $i++) - { - $thetext[ $pos + $i ] = $text[ $i ]; - } - } -} - -/** - * @see EMT_Tret - */ -class EMT_Tret_Space extends EMT_Tret -{ - public $title = 'Расстановка и удаление пробелов'; - - public $domain_zones = array( - 'ru', - 'ру', - 'ком', - 'орг', - 'уа', - 'ua', - 'uk', - 'co', - 'fr', - 'com', - 'net', - 'edu', - 'gov', - 'org', - 'mil', - 'int', - 'info', - 'biz', - 'info', - 'name', - 'pro' - ); - - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - public $rules = array( - 'nobr_twosym_abbr' => array( - 'description' => 'Неразрывный перед 2х символьной аббревиатурой', - 'pattern' => '/([a-zA-Zа-яёєїіА-ЯЁЄЇІ])(\040|\t)+([A-ZА-ЯЁЄЇІ]{2})([\s\;\.\?\!\:\(\"]|\&(ra|ld)quo\;|$)/u', - 'replacement' => '\1 \3\4' - ), - 'remove_space_before_punctuationmarks' => array( - 'description' => 'Удаление пробела перед точкой, запятой, двоеточием, точкой с запятой', - 'pattern' => '/((\040|\t|\ \;)+)([\,\:\.\;\?])(\s+|$)/', - 'replacement' => '\3\4' - ), - 'autospace_after_comma' => array( - 'description' => 'Пробел после запятой', - 'pattern' => array( - '/(\040|\t|\ \;)\,([а-яёєїіa-z0-9])/iu', - '/([^0-9])\,([а-яёєїіa-z0-9])/iu', - ), - 'replacement' => array( - ', \2', - '\1, \2' - ), - ), - 'autospace_after_pmarks' => array( - 'description' => 'Пробел после знаков пунктуации, кроме точки', - 'pattern' => '/(\040|\t|\ \;|^|\n)([a-zа-яёєїі0-9]+)(\040|\t|\ \;)?(\:|\)|\,|\&hellip\;|(?:\!|\?)+)([а-яёєїіa-z])/iu', - 'replacement' => '\1\2\4 \5' - ), - 'autospace_after_dot' => array( - 'description' => 'Пробел после точки', - 'pattern' => array( - '/(\040|\t|\ \;|^)([a-zа-яёєїі0-9]+)(\040|\t|\ \;)?\.([а-яёєїіa-z]{5,})($|[^a-zа-яёєїі])/iue', - '/(\040|\t|\ \;|^)([a-zа-яёєїі0-9]+)\.([а-яёєїіa-z]{1,4})($|[^a-zа-яёєїі])/iue', - ), - 'replacement' => array( - //'\1\2. \4', - '$m[1].$m[2]."." .( $m[5] == "." ? "" : " ").$m[4].$m[5]', - '$m[1].$m[2]."." .(in_array(EMT_Lib::strtolower($m[3]), $this->domain_zones)? "":( $m[4] == "." ? "" : " ")). $m[3].$m[4]' - ), - ), - 'autospace_after_hellips' => array( - 'description' => 'Пробел после знаков троеточий с вопросительным или восклицательными знаками', - 'pattern' => '/([\?\!]\.\.)([а-яёєїіa-z])/iu', - 'replacement' => '\1 \2' - ), - 'many_spaces_to_one' => array( - 'description' => 'Удаление лишних пробельных символов и табуляций', - 'pattern' => '/(\040|\t)+/', - 'replacement' => ' ' - ), - 'clear_percent' => array( - 'description' => 'Удаление пробела перед символом процента', - 'pattern' => '/(\d+)([\t\040]+)\%/', - 'replacement' => '\1%' - ), - 'nbsp_before_open_quote' => array( - 'description' => 'Неразрывный пробел перед открывающей скобкой', - 'pattern' => '/(^|\040|\t|>)([a-zа-яёєїі]{1,2})\040(\«\;|\&bdquo\;)/u', - 'replacement' => '\1\2 \3' - ), - - 'nbsp_before_month' => array( - 'description' => 'Неразрывный пробел в датах перед числом и месяцем', - 'pattern' => '/(\d)(\s)+(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)([^\<]|$)/iu', - 'replacement' => '\1 \3\4' - ), - 'spaces_on_end' => array( - 'description' => 'Удаление пробелов в конце текста', - 'pattern' => '/ +$/', - 'replacement' => '' - ), - 'no_space_posle_hellip' => array( - 'description' => 'Отсутстввие пробела после троеточия после открывающей кавычки', - 'pattern' => '/(\«\;|\&bdquo\;)( |\ \;)?\&hellip\;( |\ \;)?([a-zа-яёєїі])/ui', - 'replacement' => '\1…\4' - ), - 'space_posle_goda' => array( - 'description' => 'Пробел после года', - 'pattern' => '/(^|\040|\ \;)([0-9]{3,4})(год([ауе]|ом)?)([^a-zа-яёєїі]|$)/ui', - 'replacement' => '\1\2 \3\5' - ), - ); -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_Symbol extends EMT_Tret -{ - /** - * Базовые параметры тофа - * - * @var array - */ - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - public $title = 'Специальные символы'; - - public $rules = array( - 'tm_replace' => array( - 'description' => 'Замена (tm) на символ торговой марки', - 'pattern' => '/([\040\t])?\(tm\)/i', - 'replacement' => '™' - ), - 'r_sign_replace' => array( - 'description' => 'Замена (R) на символ зарегистрированной торговой марки', - 'pattern' => array( - '/(.|^)\(r\)(.|$)/ie', - ), - 'replacement' => array( - '$m[1]."®".$m[2]', - ), - ), - 'copy_replace' => array( - 'description' => 'Замена (c) на символ копирайт', - 'pattern' => array( - '/\((c|с)\)\s+/iu', - '/\((c|с)\)($|\.|,|!|\?)/iu', - ), - 'replacement' => array( - '© ', - '©\2', - ), - ), - 'apostrophe' => array( - 'description' => 'Расстановка правильного апострофа в текстах', - 'pattern' => '/(\s|^|\>|\&rsquo\;)([a-zа-яёєїі]{1,})\'([a-zа-яёєїі]+)/ui', - 'replacement' => '\1\2’\3', - 'cycled' => true - ), - 'degree_f' => array( - 'description' => 'Градусы по Фаренгейту', - 'pattern' => '/([0-9]+)F($|\s|\.|\,|\;|\:|\ \;|\?|\!)/eu', - 'replacement' => '"".$this->tag($m[1]." °F","span", array("class"=>"nowrap")) .$m[2]' - ), - 'euro_symbol' => array( - 'description' => 'Символ евро', - 'simple_replace' => true, - 'pattern' => '€', - 'replacement' => '€' - ), - 'arrows_symbols' => array( - 'description' => 'Замена стрелок вправо-влево на html коды', - 'pattern' => array( - '/\-\>/', - '/\<\-/', - '/→/u', - '/←/u' - ), - 'replacement' => array( - '→', - '←', - '→', - '←' - ), - ), - ); -} - - -/** - * @see EMT_Tret - */ -class EMT_Tret_Text extends EMT_Tret -{ - public $classes = array( - 'nowrap' => 'word-spacing:nowrap;', - ); - - /** - * Базовые параметры тофа - * - * @var array - */ - public $title = 'Текст и абзацы'; - - public $rules = array( - 'auto_links' => array( - 'description' => 'Выделение ссылок из текста', - 'pattern' => '/(\s|^)(http|ftp|mailto|https)(:\/\/)([^\s\,\!\<]{4,})(\s|\.|\,|\!|\?|\<|$)/ieu', - 'replacement' => '$m[1] . $this->tag((substr($m[4],-1)=="."?substr($m[4],0,-1):$m[4]), "a", array("href" => $m[2].$m[3].(substr($m[4],-1)=="."?substr($m[4],0,-1):$m[4]))) . (substr($m[4],-1)=="."?".":"") .$m[5]' - ), - 'email' => array( - 'description' => 'Выделение эл. почты из текста', - 'pattern' => '/(\s|^|\ \;|\()([a-z0-9\-\_\.]{2,})\@([a-z0-9\-\.]{2,})\.([a-z]{2,6})(\)|\s|\.|\,|\!|\?|$|\<)/e', - 'replacement' => '$m[1] . $this->tag($m[2]."@".$m[3].".".$m[4], "a", array("href" => "mailto:".$m[2]."@".$m[3].".".$m[4])) . $m[5]' - ), - 'no_repeat_words' => array( - 'description' => 'Удаление повторяющихся слов', - 'disabled' => true, - 'pattern' => array( - '/([а-яёєїі]{3,})( |\t|\ \;)\1/iu', - '/(\s|\ \;|^|\.|\!|\?)(([А-ЯЁЄЇІ])([а-яёєїі]{2,}))( |\t|\ \;)(([а-яёєїі])\4)/eu', - ), - 'replacement' => array( - '\1', - '$m[1].($m[7] === EMT_Lib::strtolower($m[3]) ? $m[2] : $m[2].$m[5].$m[6] )', - ) - ), - 'paragraphs' => array( - 'description' => 'Простановка параграфов', - 'function' => 'build_paragraphs' - ), - 'breakline' => array( - 'description' => 'Простановка переносов строк', - 'function' => 'build_brs' - ), - - ); - - /** - * Расстановка защищенных тегов параграфа (

...

) и переноса строки - * - * @return void - */ - protected function build_paragraphs() - { - $r = mb_strpos($this->_text, '<' . self::BASE64_PARAGRAPH_TAG . '>'); - $p = EMT_Lib::rstrpos($this->_text, ''); - - if(($r !== false) && ($p !== false)) - { - $beg = mb_substr($this->_text, 0, $r); - $end = mb_substr($this->_text, $p + mb_strlen('')); - $this->_text = - (trim($beg) ? $this->do_paragraphs($beg) . "\n" : '') . '<' . self::BASE64_PARAGRAPH_TAG . '>' . - mb_substr($this->_text, $r + mb_strlen('<' . self::BASE64_PARAGRAPH_TAG . '>'), $p - ($r + mb_strlen('<' . self::BASE64_PARAGRAPH_TAG . '>'))) . '' . - (trim($end) ? "\n" . $this->do_paragraphs($end) : ''); - } - else - { - $this->_text = $this->do_paragraphs($this->_text); - } - } - - /** - * Расстановка защищенных тегов параграфа (

...

) и переноса строки - * - * @param $text - * - * @return string|string[]|void - * - * @since 3.5 - */ - protected function do_paragraphs($text) - { - $text = str_replace("\r\n", "\n", $text); - $text = str_replace("\r", "\n", $text); - $text = '<' . self::BASE64_PARAGRAPH_TAG . '>' . trim($text) . ''; - $text = $this->preg_replace_e('/([\040\t]+)?(\n)+([\040\t]*)(\n)+/e', '$m[1]."".EMT_Lib::iblock($m[2].$m[3])."<" .self::BASE64_PARAGRAPH_TAG . ">"', $text); - - //может от открвающего до закрывающего ?! - $text = preg_replace('/\<' . self::BASE64_PARAGRAPH_TAG . '\>(' . EMT_Lib::INTERNAL_BLOCK_OPEN . '[a-zA-Z0-9\/=]+?' . EMT_Lib::INTERNAL_BLOCK_CLOSE . ')?\<\/' . self::BASE64_PARAGRAPH_TAG . '\>/s', '', $text); - - return $text; - } - - /** - * Расстановка защищенных тегов параграфа (

...

) и переноса строки - * - * @return void - * - * @since 3.5 - */ - protected function build_brs() - { - $this->_text = $this->preg_replace_e('/(\<\/' . self::BASE64_PARAGRAPH_TAG . '\>)([\r\n \t]+)(\<' . self::BASE64_PARAGRAPH_TAG . '\>)/mse', '$m[1].EMT_Lib::iblock($m[2]).$m[3]', $this->_text); - - if(!preg_match('/\<' . self::BASE64_BREAKLINE_TAG . '\>/', $this->_text)) - { - $this->_text = str_replace("\r\n", "\n", $this->_text); - $this->_text = str_replace("\r", "\n", $this->_text); - $this->_text = $this->preg_replace_e('/(\n)/e', '"<" . self::BASE64_BREAKLINE_TAG . ">\n"', $this->_text); - } - } -} - -/** - * Evgeny Muravjev Typograph, http://mdash.ru - * Version: 3.5 Gold Master - * Release Date: July 2, 2015 - * Authors: Evgeny Muravjev & Alexander Drutsa - */ - - -/** - * Основной класс типографа Евгения Муравьёва - * реализует основные методы запуска и работы типографа - * - */ -class EMT_Base -{ - public $ok = false; - public $debug_enabled = false; - public $logging = false; - public $logs = array(); - public $errors = array(); - public $debug_info = array(); - public $disable_notg_replace = false; - public $remove_notg = false; - public $settings = array(); - - /** - * Список Трэтов, которые надо применить к типографированию - * - * @var array - */ - protected $trets = array(); - protected $trets_index = array(); - protected $tret_objects = array(); - protected $_safe_blocks = array(); - private $_text = ''; - private $inited = false; - private $use_layout = false; - private $class_layout_prefix = false; - private $use_layout_set = false; - - /** - * Включить режим отладки, чтобы посмотреть последовательность вызовов - * третов и правил после - * - */ - public function debug_on() - { - $this->debug_enabled = true; - } - - /** - * Включить режим отладки, чтобы посмотреть последовательность вызовов - * третов и правил после - * - */ - public function log_on() - { - $this->logging = true; - } - - /** - * Список защищенных блоков - * - * @return array - */ - public function get_all_safe_blocks() - { - return $this->_safe_blocks; - } - - /** - * Удаленного блока по его номеру ключа - * - * @param string $id идентифиактор защищённого блока - * - * @return void - */ - public function remove_safe_block($id) - { - foreach($this->_safe_blocks as $k => $block) - { - if($block[ 'id' ] == $id) - { - unset($this->_safe_blocks[ $k ]); - } - } - } - - /** - * Добавить Трэт, - * - * @param mixed $class - имя класса трета, или сам объект - * @param bool $altname - альтернативное имя, если хотим например иметь два одинаоковых терта в обработке - * - * @return bool - * - * @since 3.5 - */ - public function add_tret($class, $altname = false) - { - if(is_object($class)) - { - if(!is_a($class, 'EMT_Tret')) - { - $this->error("You are adding Tret that doesn't inherit base class EMT_Tret", get_class($class)); - - return false; - } - - $class->EMT = $this; - $class->logging = $this->logging; - $this->tret_objects[ $altname ? $altname : get_class($class) ] = $class; - $this->trets[] = ($altname ? $altname : get_class($class)); - - return true; - } - - if(is_string($class)) - { - $obj = $this->create_object($class); - - if($obj === null) - { - return false; - } - - $this->tret_objects[ $altname ? $altname : $class ] = $obj; - $this->trets[] = ($altname ? $altname : $class); - - return true; - } - - $this->error('Чтобы добавить трэт необходимо передать имя или объект'); - - return false; - } - - /** - * @param $info - * @param null $data - * - * - * @since 3.5 - */ - protected function error($info, $data = null) - { - $this->errors[] = array( - 'class' => '', - 'info' => $info, - 'data' => $data - ); - - $this->log("ERROR $info", $data); - } - - /** - * @param $str - * @param null $data - * - * - * @since 3.5 - */ - protected function log($str, $data = null) - { - if(!$this->logging) - { - return; - } - - $this->logs[] = array( - 'class' => '', - 'info' => $str, - 'data' => $data - ); - } - - /** - * @param $tret - * - * @return null - * - * @since 3.5 - */ - private function create_object($tret) - { - // если класса нету, попытаемся его прогрузить, например, если стандартный - if(!class_exists($tret)) - { - if(preg_match('/^EMT_Tret_([a-zA-Z0-9_]+)$/', $tret, $m)) - { - $tname = $m[ 1 ]; - $fname = str_replace('_', ' ', $tname); - $fname = ucwords($fname); - $fname = str_replace(' ', '.', $fname); - - $this->error($fname); - } - } - - if(!class_exists($tret)) - { - $this->error("Класс $tret не найден. Пожалуйста, подргузите нужный файл."); - - return null; - } - - $obj = new $tret(); - $obj->EMT = $this; - $obj->logging = $this->logging; - - return $obj; - } - - /** - * Задаём текст для применения типографа - * - * @param string $text - * - * @since 3.5 - */ - public function set_text($text) - { - $this->_text = $text; - } - - /** - * Запустить типограф на выполнение - * - * @param null $trets - * - * @return string - * - * @since 3.5 - */ - public function apply($trets = null) - { - $this->ok = false; - - $this->init(); - $this->_init(); - - $atrets = $this->trets; - - if(is_string($trets)) - { - $atrets = array( $trets ); - } - elseif(is_array($trets)) - { - $atrets = $trets; - } - - $this->debug($this, 'init', $this->_text); - - $this->_text = $this->safe_blocks($this->_text, true); - $this->debug($this, 'safe_blocks', $this->_text); - - $this->_text = EMT_Lib::safe_tag_chars($this->_text, true); - $this->debug($this, 'safe_tag_chars', $this->_text); - - $this->_text = EMT_Lib::clear_special_chars($this->_text); - $this->debug($this, 'clear_special_chars', $this->_text); - - foreach($atrets as $tret) - { - // если установлен режим разметки тэгов то выставим его - if($this->use_layout_set) - { - $this->tret_objects[ $tret ]->set_tag_layout_ifnotset($this->use_layout); - } - - if($this->class_layout_prefix) - { - $this->tret_objects[ $tret ]->set_class_layout_prefix($this->class_layout_prefix); - } - - // влючаем, если нужно - if($this->debug_enabled) - { - $this->tret_objects[ $tret ]->debug_on(); - } - if($this->logging) - { - $this->tret_objects[ $tret ]->logging = true; - } - - // применяем трэт - //$this->tret_objects[$tret]->set_text(&$this->_text); - $this->tret_objects[ $tret ]->set_text($this->_text); - $this->tret_objects[ $tret ]->apply(); - - // соберём ошибки если таковые есть - if(count($this->tret_objects[ $tret ]->errors) > 0) - { - foreach($this->tret_objects[ $tret ]->errors as $err) - { - $this->tret_error($tret, $err[ 'info' ], $err[ 'data' ]); - } - } - - // логгирование - if($this->logging) - { - if(count($this->tret_objects[ $tret ]->logs) > 0) - { - foreach($this->tret_objects[ $tret ]->logs as $log) - { - $this->tret_log($tret, $log[ 'info' ], $log[ 'data' ]); - } - } - } - - // отладка - if($this->debug_enabled) - { - foreach($this->tret_objects[ $tret ]->debug_info as $di) - { - $unsafetext = $di[ 'text' ]; - $unsafetext = EMT_Lib::safe_tag_chars($unsafetext, false); - $unsafetext = $this->safe_blocks($unsafetext, false); - $this->debug($tret, $di[ 'place' ], $unsafetext, $di[ 'text' ]); - } - } - } - - $this->_text = $this->decode_internal_blocks($this->_text); - $this->debug($this, 'decode_internal_blocks', $this->_text); - - if($this->is_on('dounicode')) - { - EMT_Lib::convert_html_entities_to_unicode($this->_text); - } - - $this->_text = EMT_Lib::safe_tag_chars($this->_text, false); - $this->debug($this, 'unsafe_tag_chars', $this->_text); - - $this->_text = $this->safe_blocks($this->_text, false); - $this->debug($this, 'unsafe_blocks', $this->_text); - - if(!$this->disable_notg_replace) - { - $repl = array( - '', - '' - ); - - if($this->remove_notg) - { - $repl = ''; - } - - $this->_text = str_replace(array( - '', - '' - ), $repl, $this->_text); - } - - $this->_text = trim($this->_text); - $this->ok = (count($this->errors) == 0); - - return $this->_text; - } - - /** - * Инициализация класса, используется чтобы задать список третов или - * список защищённых блоков, которые можно использовать. - * Также здесь можно отменить защищённые блоки по умлочнаию - * - * @since 3.5 - */ - public function init() - { - - } - - /** - * - * - * @since 3.5 - */ - private function _init() - { - foreach($this->trets as $tret) - { - if(isset($this->tret_objects[ $tret ])) - { - continue; - } - - $obj = $this->create_object($tret); - - if($obj == null) - { - continue; - } - - $this->tret_objects[ $tret ] = $obj; - } - - if(!$this->inited) - { - $this->add_safe_tag('pre'); - $this->add_safe_tag('script'); - $this->add_safe_tag('style'); - $this->add_safe_tag('notg'); - $this->add_safe_block('span-notg', '', ''); - } - - $this->inited = true; - } - - /** - * Добавление защищенного блока - * - * @param string $tag тэг, который должен быть защищён - * - * @return bool - * - * @since 3.5 - */ - public function add_safe_tag($tag) - { - $open = preg_quote('<', '/') . $tag . '[^>]*?' . preg_quote('>', '/'); - $close = preg_quote("", '/'); - $this->_add_safe_block($tag, $open, $close, $tag); - - return true; - } - - /** - * Добавление защищенного блока - * - * - * Jare_Typograph_Tool::addCustomBlocks('', ''); - * Jare_Typograph_Tool::addCustomBlocks('\', '\<\/span\>', true); - * - * - * @param string $id идентификатор - * @param string $open начало блока - * @param string $close конец защищенного блока - * @param string $tag тэг - * - * @return void - * - * @since 3.5 - */ - private function _add_safe_block($id, $open, $close, $tag) - { - $this->_safe_blocks[] = array( - 'id' => $id, - 'tag' => $tag, - 'open' => $open, - 'close' => $close, - ); - } - - /** - * Добавление защищенного блока - * - * @param $id - * @param string $open начало блока - * @param string $close конец защищенного блока - * @param bool $quoted специальные символы в начале и конце блока экранированы - * - * @return bool - * - * @since 3.5 - */ - public function add_safe_block($id, $open, $close, $quoted = false) - { - $open = trim($open); - $close = trim($close); - - if(empty($open) || empty($close)) - { - return false; - } - - if(false === $quoted) - { - $open = preg_quote($open, '/'); - $close = preg_quote($close, '/'); - } - - $this->_add_safe_block($id, $open, $close, ''); - - return true; - } - - protected function debug($class, $place, &$after_text, $after_text_raw = '') - { - if(!$this->debug_enabled) - { - return; - } - - $this->debug_info[] = array( - 'tret' => $class == $this ? false : true, - 'class' => is_object($class) ? get_class($class) : $class, - 'place' => $place, - 'text' => $after_text, - 'text_raw' => $after_text_raw, - ); - } - - /** - * Сохранение содержимого защищенных блоков - * - * @param string $text - * @param $way - * @param bool $show - * - * @return string - * - * @since 3.5 - */ - public function safe_blocks($text, $way, $show = true) - { - if(count($this->_safe_blocks)) - { - $safeType = true === $way ? 'EMT_Lib::encrypt_tag($m[2])' : 'stripslashes(EMT_Lib::decrypt_tag($m[2]))'; - $safeblocks = true === $way ? $this->_safe_blocks : array_reverse($this->_safe_blocks); - - foreach($safeblocks as $block) - { - $text = preg_replace_callback("/({$block['open']})(.+?)({$block['close']})/s", create_function('$m', 'return $m[1].' . $safeType . '.$m[3];'), $text); - } - } - - return $text; - } - - /** - * @param $tret - * @param $info - * @param null $data - * - * - * @since 3.5 - */ - protected function tret_error($tret, $info, $data = null) - { - $this->errors[] = array( - 'class' => $tret, - 'info' => $info, - 'data' => $data - ); - } - - /** - * @param $tret - * @param $str - * @param null $data - * - * - * @since 3.5 - */ - protected function tret_log($tret, $str, $data = null) - { - $this->logs[] = array( - 'class' => $tret, - 'info' => $str, - 'data' => $data - ); - } - - /** - * Декодирование блоков, которые были скрыты в момент типографирования - * - * @param string $text - * - * @return string - * - * @since 3.5 - */ - public function decode_internal_blocks($text) - { - return EMT_Lib::decode_internal_blocks($text); - } - - /** - * Установлена ли настройка - * - * @param string $key - * - * @return bool - * - * @since 3.5 - */ - public function is_on($key) - { - if(!isset($this->settings[ $key ])) - { - return false; - } - - $kk = $this->settings[ $key ]; - - return ((strtolower($kk) == 'on') || ($kk === '1') || ($kk === true) || ($kk === 1)); - } - - /** - * Получить содержимое при использовании классов - * - * @param bool $list false - вернуть в виде строки для style или как массив - * @param bool $compact не выводить пустые классы - * - * @return string|array - * - * @since 3.5 - */ - public function get_style($list = false, $compact = false) - { - $this->_init(); - - $res = array(); - foreach($this->trets as $tret) - { - $arr = $this->tret_objects[ $tret ]->classes; - - if(!is_array($arr)) - { - continue; - } - - foreach($arr as $classname => $str) - { - if($compact && (!$str)) - { - continue; - } - $clsname = ($this->class_layout_prefix ? $this->class_layout_prefix : '') . (isset($this->tret_objects[ $tret ]->class_names[ $classname ]) ? $this->tret_objects[ $tret ]->class_names[ $classname ] : $classname); - $res[ $clsname ] = $str; - } - } - - if($list) - { - return $res; - } - - $str = ''; - foreach($res as $k => $v) - { - $str .= ".$k { $v }\n"; - } - - return $str; - } - - /** - * Установить режим разметки, - * EMT_Lib::LAYOUT_STYLE - с помощью стилей - * EMT_Lib::LAYOUT_CLASS - с помощью классов - * EMT_Lib::LAYOUT_STYLE|EMT_Lib::LAYOUT_CLASS - оба метода - * - * @param int $layout - * - * @since 3.5 - */ - public function set_tag_layout($layout = EMT_Lib::LAYOUT_STYLE) - { - $this->use_layout = $layout; - $this->use_layout_set = true; - } - - /** - * Установить префикс для классов - * - * @param string|bool $prefix если true то префикс 'emt_', иначе то, что передали - * - * @since 3.5 - */ - public function set_class_layout_prefix($prefix) - { - $this->class_layout_prefix = $prefix === true ? 'emt_' : $prefix; - } - - /** - * Установить настройки для тертов и правил - * 1. если селектор является массивом, то тогда установка правил будет выполнена для каждого - * элемента этого массива, как отдельного селектора. - * 2. Если $key не является массивом, то эта настройка будет проставлена согласно селектору - * 3. Если $key массив - то будет задана группа настроек - * - если $value массив , то настройки определяются по ключам из массива $key, а значения из $value - * - иначе, $key содержит ключ-значение как массив - * 4. $exact_match - если true тогда array selector будет соответсвовать array $key, а не произведению массивов - * - * @param mixed $selector - * @param mixed $key - * @param mixed $value - * @param mixed $exact_match - * - * @since 3.5 - */ - public function set($selector, $key, $value = false, $exact_match = false) - { - if($exact_match && is_array($selector) && is_array($key) && count($selector) == count($key)) - { - $idx = 0; - foreach($key as $x => $y) - { - if(is_array($value)) - { - $kk = $y; - $vv = $value[ $x ]; - } - else - { - $kk = ($value ? $y : $x); - $vv = ($value ? $value : $y); - } - $this->set($selector[ $idx ], $kk, $vv); - $idx++; - } - - return; - } - - if(is_array($selector)) - { - foreach($selector as $val) - { - $this->set($val, $key, $value); - } - - return; - } - - if(is_array($key)) - { - foreach($key as $x => $y) - { - if(is_array($value)) - { - $kk = $y; - $vv = $value[ $x ]; - } - else - { - $kk = ($value ? $y : $x); - $vv = ($value ? $value : $y); - } - $this->set($selector, $kk, $vv); - } - - return; - } - - $this->doset($selector, $key, $value); - } - - /** - * Установить настройку - * - * @param mixed $selector - * @param $key - * @param mixed $value - * - * @since 3.5 - */ - protected function doset($selector, $key, $value) - { - $tret_pattern = false; - $rule_pattern = false; - - if(is_string($selector)) - { - if(strpos($selector, '.') === false) - { - $tret_pattern = $selector; - } - else - { - $pa = explode('.', $selector); - $tret_pattern = $pa[ 0 ]; - array_shift($pa); - $rule_pattern = implode('.', $pa); - } - } - - EMT_Lib::_process_selector_pattern($tret_pattern); - EMT_Lib::_process_selector_pattern($rule_pattern); - - if($selector == '*') - { - $this->settings[ $key ] = $value; - } - - foreach($this->trets as $tret) - { - $t1 = $this->get_short_tret($tret); - - if(!EMT_Lib::_test_pattern($tret_pattern, $t1)) - { - if(!EMT_Lib::_test_pattern($tret_pattern, $tret)) - { - continue; - } - } - - $tret_obj = $this->get_tret($tret); - - if($key == 'active') - { - foreach($tret_obj->rules as $rulename => $v) - { - if(!EMT_Lib::_test_pattern($rule_pattern, $rulename)) - { - continue; - } - - if((strtolower($value) === 'on') || ($value === 1) || ($value === true) || ($value == '1')) - { - $tret_obj->enable_rule($rulename); - } - - if((strtolower($value) === 'off') || ($value === 0) || ($value === false) || ($value == '0')) - { - $tret_obj->disable_rule($rulename); - } - } - } - else - { - if($rule_pattern === false) - { - $tret_obj->set($key, $value); - } - else - { - foreach($tret_obj->rules as $rulename => $v) - { - if(!EMT_Lib::_test_pattern($rule_pattern, $rulename)) - { - continue; - } - - $tret_obj->set_rule($rulename, $key, $value); - } - } - } - } - } - - /** - * @param $tretname - * - * @return mixed - * - * @since 3.5 - */ - private function get_short_tret($tretname) - { - if(preg_match('/^EMT_Tret_([a-zA-Z0-9_]+)$/', $tretname, $m)) - { - return $m[ 1 ]; - } - - return $tretname; - } - - /** - * Получаем ТРЕТ по идентификатору, т.е. названию класса - * - * @param $name - * - * @return bool|mixed - * - * @since 3.5 - */ - public function get_tret($name) - { - if(isset($this->tret_objects[ $name ])) - { - return $this->tret_objects[ $name ]; - } - - foreach($this->trets as $tret) - { - if($tret == $name) - { - $this->_init(); - - return $this->tret_objects[ $name ]; - } - - if($this->get_short_tret($tret) == $name) - { - $this->_init(); - - return $this->tret_objects[ $tret ]; - } - } - - $this->error("Трэт с идентификатором $name не найден"); - - return false; - } - - /** - * Возвращает список текущих третов, которые установлены - * - * @since 3.5 - */ - public function get_trets_list() - { - return $this->trets; - } - - /** - * Установить настройки - * - * @param array $setupmap - * - * @since 3.5 - */ - public function setup($setupmap) - { - if(!is_array($setupmap)) - { - return; - } - - if(isset($setupmap[ 'map' ]) || isset($setupmap[ 'maps' ])) - { - if(isset($setupmap[ 'map' ])) - { - $test = ''; - $ret[ 'map' ] = $test[ 'params' ][ 'map' ]; - $ret[ 'disable' ] = $test[ 'params' ][ 'map_disable' ]; - $ret[ 'strict' ] = $test[ 'params' ][ 'map_strict' ]; - $test[ 'params' ][ 'maps' ] = array( $ret ); - - unset($setupmap[ 'map' ], $setupmap[ 'map_disable' ], $setupmap[ 'map_strict' ]); - } - - if(is_array($setupmap[ 'maps' ])) - { - foreach($setupmap[ 'maps' ] as $map) - { - $this->set_enable_map - ($map[ 'map' ], - isset($map[ 'disable' ]) ? $map[ 'disable' ] : false, - isset($map[ 'strict' ]) ? $map[ 'strict' ] : false - ); - } - } - - unset($setupmap[ 'maps' ]); - } - - foreach($setupmap as $k => $v) - { - $this->do_setup($k, $v); - } - } - - /** - * Включить/отключить правила, согласно карте - * Формат карты: - * 'Название трэта 1' => array ( 'правило1', 'правило2' , ... ) - * 'Название трэта 2' => array ( 'правило1', 'правило2' , ... ) - * - * @param array $map - * @param boolean $disable если ложно, то $map соотвествует тем правилам, которые надо включить - * иначе это список правил, которые надо выключить - * @param boolean $strict строго, т.е. те которые не в списке будут тоже обработаны - * - * @since 3.5 - */ - public function set_enable_map($map, $disable = false, $strict = true) - { - if(!is_array($map)) - { - return; - } - - $trets = array(); - foreach($map as $tret => $list) - { - $tretx = $this->get_tret($tret); - - if(!$tretx) - { - $this->log("Трэт $tret не найден при применении карты включаемых правил"); - - continue; - } - - $trets[] = $tretx; - - if($list === true) // все - { - $tretx->activate(array(), !$disable, true); - } - elseif(is_string($list)) - { - $tretx->activate(array( $list ), $disable, $strict); - } - elseif(is_array($list)) - { - $tretx->activate($list, $disable, $strict); - } - } - - if($strict) - { - foreach($this->trets as $tret) - { - if(in_array($this->tret_objects[ $tret ], $trets)) - { - continue; - } - - $this->tret_objects[ $tret ]->activate(array(), $disable, true); - } - } - } - - /** - * Установка одной метанастройки - * - * @param string $name - * @param mixed $value - * - * @since 3.5 - */ - public function do_setup($name, $value) - { - - } -} - -class EMTypograph extends EMT_Base -{ - public $trets = array( - 'EMT_Tret_Quote', - 'EMT_Tret_Dash', - 'EMT_Tret_Symbol', - 'EMT_Tret_Punctmark', - 'EMT_Tret_Number', - 'EMT_Tret_Space', - 'EMT_Tret_Abbr', - 'EMT_Tret_Nobr', - 'EMT_Tret_Date', - 'EMT_Tret_OptAlign', - 'EMT_Tret_Etc', - 'EMT_Tret_Text' - ); - - protected $group_list = array( - 'Quote' => true, - 'Dash' => true, - 'Nobr' => true, - 'Symbol' => true, - 'Punctmark' => true, - 'Number' => true, - 'Date' => true, - 'Space' => true, - 'Abbr' => true, - 'OptAlign' => true, - 'Text' => true, - 'Etc' => true, - ); - - protected $all_options = array( - 'Quote.quotes' => array( - 'description' => 'Расстановка «кавычек-елочек» первого уровня', - 'selector' => 'Quote.*quote' - ), - 'Quote.quotation' => array( - 'description' => 'Внутренние кавычки-лапки', - 'selector' => 'Quote', - 'setting' => 'no_bdquotes', - 'reversed' => true - ), - - 'Dash.to_libo_nibud' => 'direct', - 'Dash.iz_za_pod' => 'direct', - 'Dash.ka_de_kas' => 'direct', - - 'Nobr.super_nbsp' => 'direct', - 'Nobr.nbsp_in_the_end' => 'direct', - 'Nobr.phone_builder' => 'direct', - 'Nobr.phone_builder_v2' => 'direct', - 'Nobr.ip_address' => 'direct', - 'Nobr.spaces_nobr_in_surname_abbr' => 'direct', - 'Nobr.dots_for_surname_abbr' => 'direct', - 'Nobr.nbsp_celcius' => 'direct', - 'Nobr.hyphen_nowrap_in_small_words' => 'direct', - 'Nobr.hyphen_nowrap' => 'direct', - 'Nobr.nowrap' => array( - 'description' => 'Nobr (по умолчанию) & nowrap', - 'disabled' => true, - 'selector' => '*', - 'setting' => 'nowrap' - ), - - 'Symbol.tm_replace' => 'direct', - 'Symbol.r_sign_replace' => 'direct', - 'Symbol.copy_replace' => 'direct', - 'Symbol.apostrophe' => 'direct', - 'Symbol.degree_f' => 'direct', - 'Symbol.arrows_symbols' => 'direct', - 'Symbol.no_inches' => array( - 'description' => 'Расстановка дюйма после числа', - 'selector' => 'Quote', - 'setting' => 'no_inches', - 'reversed' => true - ), - - 'Punctmark.auto_comma' => 'direct', - 'Punctmark.hellip' => 'direct', - 'Punctmark.fix_pmarks' => 'direct', - 'Punctmark.fix_excl_quest_marks' => 'direct', - 'Punctmark.dot_on_end' => 'direct', - - 'Number.minus_between_nums' => 'direct', - 'Number.minus_in_numbers_range' => 'direct', - 'Number.auto_times_x' => 'direct', - 'Number.simple_fraction' => 'direct', - 'Number.math_chars' => 'direct', - 'Number.thinsp_between_number_triads' => 'direct', - 'Number.thinsp_between_no_and_number' => 'direct', - 'Number.thinsp_between_sect_and_number' => 'direct', - - 'Date.years' => 'direct', - 'Date.mdash_month_interval' => 'direct', - 'Date.nbsp_and_dash_month_interval' => 'direct', - 'Date.nobr_year_in_date' => 'direct', - - 'Space.many_spaces_to_one' => 'direct', - 'Space.clear_percent' => 'direct', - 'Space.clear_before_after_punct' => array( - 'description' => 'Удаление пробелов перед и после знаков препинания в предложении', - 'selector' => 'Space.remove_space_before_punctuationmarks' - ), - 'Space.autospace_after' => array( - 'description' => 'Расстановка пробелов после знаков препинания', - 'selector' => 'Space.autospace_after_*' - ), - 'Space.bracket_fix' => array( - 'description' => 'Удаление пробелов внутри скобок, а также расстановка пробела перед скобками', - 'selector' => array( - 'Space.nbsp_before_open_quote', - 'Punctmark.fix_brackets' - ) - ), - - 'Abbr.nbsp_money_abbr' => array( - 'description' => 'Форматирование денежных сокращений (расстановка пробелов и привязка названия валюты к числу)', - 'selector' => array( - 'Abbr.nbsp_money_abbr', - 'Abbr.nbsp_money_abbr_rev' - ) - ), - 'Abbr.nobr_vtch_itd_itp' => 'direct', - 'Abbr.nobr_sm_im' => 'direct', - 'Abbr.nobr_acronym' => 'direct', - 'Abbr.nobr_locations' => 'direct', - 'Abbr.nobr_abbreviation' => 'direct', - 'Abbr.ps_pps' => 'direct', - 'Abbr.nbsp_org_abbr' => 'direct', - 'Abbr.nobr_gost' => 'direct', - 'Abbr.nobr_before_unit_volt' => 'direct', - 'Abbr.nbsp_before_unit' => 'direct', - - 'OptAlign.all' => array( - 'description' => 'Все настройки оптического выравнивания', - 'hide' => true, - 'selector' => 'OptAlign.*' - ), - 'OptAlign.oa_oquote' => 'direct', - 'OptAlign.oa_obracket_coma' => 'direct', - 'OptAlign.oa_oquote_extra' => 'direct', - 'OptAlign.layout' => array( 'description' => 'Inline стили или CSS' ), - - 'Text.paragraphs' => 'direct', - 'Text.auto_links' => 'direct', - 'Text.email' => 'direct', - 'Text.breakline' => 'direct', - 'Text.no_repeat_words' => 'direct', - - //'Etc.no_nbsp_in_nobr' => 'direct', - 'Etc.unicode_convert' => array( - 'description' => 'Преобразовывать html-сущности в юникод', - 'selector' => array( - '*', - 'Etc.nobr_to_nbsp' - ), - 'setting' => array( - 'dounicode', - 'active' - ), - 'exact_selector' => true, - 'disabled' => true - ), - 'Etc.nobr_to_nbsp' => 'direct', - 'Etc.split_number_to_triads' => 'direct', - ); - - /** - * Запустить типограф со стандартными параметрами - * - * @param string $text - * @param array $options - * - * @return string - * - * @since 3.5 - */ - public static function fast_apply($text, $options = null) - { - $obj = new self(); - if(is_array($options)) - { - $obj->setup($options); - } - - $obj->set_text($text); - - return $obj->apply(); - } - - /** - * * - * Получить список имеющихся опций - * - * @return array - * all - полный список - * group - сгруппированный по группам - * - * @since 3.5 - */ - public function get_options_list() - { - $arr[ 'all' ] = array(); - $bygroup = array(); - - foreach($this->all_options as $opt => $op) - { - $arr[ 'all' ][ $opt ] = $this->get_option_info($opt); - $x = explode('.', $opt); - $bygroup[ $x[ 0 ] ][] = $opt; - } - - $arr[ 'group' ] = array(); - - foreach($this->group_list as $group => $ginfo) - { - if($ginfo === true) - { - $tret = $this->get_tret($group); - if($tret) - { - $info[ 'title' ] = $tret->title; - } - else - { - $info[ 'title' ] = 'Не определено'; - } - } - else - { - $info = $ginfo; - } - - $info[ 'name' ] = $group; - $info[ 'options' ] = array(); - - if(is_array($bygroup[ $group ])) - { - foreach($bygroup[ $group ] as $opt) - { - $info[ 'options' ][] = $opt; - } - } - - $arr[ 'group' ][] = $info; - } - - return $arr; - } - - /** - * - * Получить информацию о настройке - * - * @param string $key - * - * @return array|false - * - * @since 3.5 - */ - protected function get_option_info($key) - { - if(!isset($this->all_options[ $key ])) - { - return false; - } - - if(is_array($this->all_options[ $key ])) - { - return $this->all_options[ $key ]; - } - - if(($this->all_options[ $key ] == 'direct') || ($this->all_options[ $key ] == 'reverse')) - { - $pa = explode('.', $key); - $tret_pattern = $pa[ 0 ]; - $tret = $this->get_tret($tret_pattern); - - if(!$tret) - { - return false; - } - - if(!isset($tret->rules[ $pa[ 1 ] ])) - { - return false; - } - - $array = $tret->rules[ $pa[ 1 ] ]; - $array[ 'way' ] = $this->all_options[ $key ]; - - return $array; - } - - return false; - } - - /** - * - * Установка одной метанастройки - * - * @param string $name - * @param mixed $value - * - * @since 3.5 - */ - public function do_setup($name, $value) - { - if(!isset($this->all_options[ $name ])) - { - return; - } - - // эта настрока связана с правилом ядра - if(is_string($this->all_options[ $name ])) - { - $this->set($name, 'active', $value); - - return; - } - - if(is_array($this->all_options[ $name ])) - { - if(isset($this->all_options[ $name ][ 'selector' ])) - { - $settingname = 'active'; - - if(isset($this->all_options[ $name ][ 'setting' ])) - { - $settingname = $this->all_options[ $name ][ 'setting' ]; - } - - $this->set($this->all_options[ $name ][ 'selector' ], $settingname, $value, isset($this->all_options[ $name ][ 'exact_selector' ])); - } - } - - if($name == 'OptAlign.layout') - { - if($value == 'style') - { - $this->set_tag_layout(EMT_Lib::LAYOUT_STYLE); - } - - if($value == 'class') - { - $this->set_tag_layout(EMT_Lib::LAYOUT_CLASS); - } - } - } -} \ No newline at end of file diff --git a/lib/emt/index.html b/lib/emt/index.html deleted file mode 100644 index 2efb97f..0000000 --- a/lib/emt/index.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/index.html b/lib/index.html deleted file mode 100644 index 2efb97f..0000000 --- a/lib/index.html +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/vendor/autoload.php b/lib/vendor/autoload.php new file mode 100644 index 0000000..857a556 --- /dev/null +++ b/lib/vendor/autoload.php @@ -0,0 +1,7 @@ + + * Jordi Boggiano + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Composer\Autoload; + +/** + * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. + * + * $loader = new \Composer\Autoload\ClassLoader(); + * + * // register classes with namespaces + * $loader->add('Symfony\Component', __DIR__.'/component'); + * $loader->add('Symfony', __DIR__.'/framework'); + * + * // activate the autoloader + * $loader->register(); + * + * // to enable searching the include path (eg. for PEAR packages) + * $loader->setUseIncludePath(true); + * + * In this example, if you try to use a class in the Symfony\Component + * namespace or one of its children (Symfony\Component\Console for instance), + * the autoloader will first look for the class under the component/ + * directory, and it will then fallback to the framework/ directory if not + * found before giving up. + * + * This class is loosely based on the Symfony UniversalClassLoader. + * + * @author Fabien Potencier + * @author Jordi Boggiano + * @see http://www.php-fig.org/psr/psr-0/ + * @see http://www.php-fig.org/psr/psr-4/ + */ +class ClassLoader +{ + // PSR-4 + private $prefixLengthsPsr4 = array(); + private $prefixDirsPsr4 = array(); + private $fallbackDirsPsr4 = array(); + + // PSR-0 + private $prefixesPsr0 = array(); + private $fallbackDirsPsr0 = array(); + + private $useIncludePath = false; + private $classMap = array(); + private $classMapAuthoritative = false; + private $missingClasses = array(); + private $apcuPrefix; + + public function getPrefixes() + { + if (!empty($this->prefixesPsr0)) { + return call_user_func_array('array_merge', $this->prefixesPsr0); + } + + return array(); + } + + public function getPrefixesPsr4() + { + return $this->prefixDirsPsr4; + } + + public function getFallbackDirs() + { + return $this->fallbackDirsPsr0; + } + + public function getFallbackDirsPsr4() + { + return $this->fallbackDirsPsr4; + } + + public function getClassMap() + { + return $this->classMap; + } + + /** + * @param array $classMap Class to filename map + */ + public function addClassMap(array $classMap) + { + if ($this->classMap) { + $this->classMap = array_merge($this->classMap, $classMap); + } else { + $this->classMap = $classMap; + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, either + * appending or prepending to the ones previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 root directories + * @param bool $prepend Whether to prepend the directories + */ + public function add($prefix, $paths, $prepend = false) + { + if (!$prefix) { + if ($prepend) { + $this->fallbackDirsPsr0 = array_merge( + (array) $paths, + $this->fallbackDirsPsr0 + ); + } else { + $this->fallbackDirsPsr0 = array_merge( + $this->fallbackDirsPsr0, + (array) $paths + ); + } + + return; + } + + $first = $prefix[0]; + if (!isset($this->prefixesPsr0[$first][$prefix])) { + $this->prefixesPsr0[$first][$prefix] = (array) $paths; + + return; + } + if ($prepend) { + $this->prefixesPsr0[$first][$prefix] = array_merge( + (array) $paths, + $this->prefixesPsr0[$first][$prefix] + ); + } else { + $this->prefixesPsr0[$first][$prefix] = array_merge( + $this->prefixesPsr0[$first][$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, either + * appending or prepending to the ones previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * @param bool $prepend Whether to prepend the directories + * + * @throws \InvalidArgumentException + */ + public function addPsr4($prefix, $paths, $prepend = false) + { + if (!$prefix) { + // Register directories for the root namespace. + if ($prepend) { + $this->fallbackDirsPsr4 = array_merge( + (array) $paths, + $this->fallbackDirsPsr4 + ); + } else { + $this->fallbackDirsPsr4 = array_merge( + $this->fallbackDirsPsr4, + (array) $paths + ); + } + } elseif (!isset($this->prefixDirsPsr4[$prefix])) { + // Register directories for a new namespace. + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } elseif ($prepend) { + // Prepend directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + (array) $paths, + $this->prefixDirsPsr4[$prefix] + ); + } else { + // Append directories for an already registered namespace. + $this->prefixDirsPsr4[$prefix] = array_merge( + $this->prefixDirsPsr4[$prefix], + (array) $paths + ); + } + } + + /** + * Registers a set of PSR-0 directories for a given prefix, + * replacing any others previously set for this prefix. + * + * @param string $prefix The prefix + * @param array|string $paths The PSR-0 base directories + */ + public function set($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr0 = (array) $paths; + } else { + $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; + } + } + + /** + * Registers a set of PSR-4 directories for a given namespace, + * replacing any others previously set for this namespace. + * + * @param string $prefix The prefix/namespace, with trailing '\\' + * @param array|string $paths The PSR-4 base directories + * + * @throws \InvalidArgumentException + */ + public function setPsr4($prefix, $paths) + { + if (!$prefix) { + $this->fallbackDirsPsr4 = (array) $paths; + } else { + $length = strlen($prefix); + if ('\\' !== $prefix[$length - 1]) { + throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); + } + $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; + $this->prefixDirsPsr4[$prefix] = (array) $paths; + } + } + + /** + * Turns on searching the include path for class files. + * + * @param bool $useIncludePath + */ + public function setUseIncludePath($useIncludePath) + { + $this->useIncludePath = $useIncludePath; + } + + /** + * Can be used to check if the autoloader uses the include path to check + * for classes. + * + * @return bool + */ + public function getUseIncludePath() + { + return $this->useIncludePath; + } + + /** + * Turns off searching the prefix and fallback directories for classes + * that have not been registered with the class map. + * + * @param bool $classMapAuthoritative + */ + public function setClassMapAuthoritative($classMapAuthoritative) + { + $this->classMapAuthoritative = $classMapAuthoritative; + } + + /** + * Should class lookup fail if not found in the current class map? + * + * @return bool + */ + public function isClassMapAuthoritative() + { + return $this->classMapAuthoritative; + } + + /** + * APCu prefix to use to cache found/not-found classes, if the extension is enabled. + * + * @param string|null $apcuPrefix + */ + public function setApcuPrefix($apcuPrefix) + { + $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; + } + + /** + * The APCu prefix in use, or null if APCu caching is not enabled. + * + * @return string|null + */ + public function getApcuPrefix() + { + return $this->apcuPrefix; + } + + /** + * Registers this instance as an autoloader. + * + * @param bool $prepend Whether to prepend the autoloader or not + */ + public function register($prepend = false) + { + spl_autoload_register(array($this, 'loadClass'), true, $prepend); + } + + /** + * Unregisters this instance as an autoloader. + */ + public function unregister() + { + spl_autoload_unregister(array($this, 'loadClass')); + } + + /** + * Loads the given class or interface. + * + * @param string $class The name of the class + * @return bool|null True if loaded, null otherwise + */ + public function loadClass($class) + { + if ($file = $this->findFile($class)) { + includeFile($file); + + return true; + } + } + + /** + * Finds the path to the file where the class is defined. + * + * @param string $class The name of the class + * + * @return string|false The path if found, false otherwise + */ + public function findFile($class) + { + // class map lookup + if (isset($this->classMap[$class])) { + return $this->classMap[$class]; + } + if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { + return false; + } + if (null !== $this->apcuPrefix) { + $file = apcu_fetch($this->apcuPrefix.$class, $hit); + if ($hit) { + return $file; + } + } + + $file = $this->findFileWithExtension($class, '.php'); + + // Search for Hack files if we are running on HHVM + if (false === $file && defined('HHVM_VERSION')) { + $file = $this->findFileWithExtension($class, '.hh'); + } + + if (null !== $this->apcuPrefix) { + apcu_add($this->apcuPrefix.$class, $file); + } + + if (false === $file) { + // Remember that this class does not exist. + $this->missingClasses[$class] = true; + } + + return $file; + } + + private function findFileWithExtension($class, $ext) + { + // PSR-4 lookup + $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; + + $first = $class[0]; + if (isset($this->prefixLengthsPsr4[$first])) { + $subPath = $class; + while (false !== $lastPos = strrpos($subPath, '\\')) { + $subPath = substr($subPath, 0, $lastPos); + $search = $subPath . '\\'; + if (isset($this->prefixDirsPsr4[$search])) { + $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); + foreach ($this->prefixDirsPsr4[$search] as $dir) { + if (file_exists($file = $dir . $pathEnd)) { + return $file; + } + } + } + } + } + + // PSR-4 fallback dirs + foreach ($this->fallbackDirsPsr4 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { + return $file; + } + } + + // PSR-0 lookup + if (false !== $pos = strrpos($class, '\\')) { + // namespaced class name + $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) + . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); + } else { + // PEAR-like class name + $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; + } + + if (isset($this->prefixesPsr0[$first])) { + foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { + if (0 === strpos($class, $prefix)) { + foreach ($dirs as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + } + } + } + + // PSR-0 fallback dirs + foreach ($this->fallbackDirsPsr0 as $dir) { + if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { + return $file; + } + } + + // PSR-0 include paths. + if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { + return $file; + } + + return false; + } +} + +/** + * Scope isolated include. + * + * Prevents access to $this/self from included files. + */ +function includeFile($file) +{ + include $file; +} diff --git a/lib/vendor/composer/autoload_classmap.php b/lib/vendor/composer/autoload_classmap.php new file mode 100644 index 0000000..51c6cd6 --- /dev/null +++ b/lib/vendor/composer/autoload_classmap.php @@ -0,0 +1,25 @@ + $vendorDir . '/emuravjev/mdash/src/Lib.php', + 'Emuravjev\\Mdash\\Tret\\Abbr' => $vendorDir . '/emuravjev/mdash/src/Tret/Abbr.php', + 'Emuravjev\\Mdash\\Tret\\Base' => $vendorDir . '/emuravjev/mdash/src/Tret/Base.php', + 'Emuravjev\\Mdash\\Tret\\Dash' => $vendorDir . '/emuravjev/mdash/src/Tret/Dash.php', + 'Emuravjev\\Mdash\\Tret\\Date' => $vendorDir . '/emuravjev/mdash/src/Tret/Date.php', + 'Emuravjev\\Mdash\\Tret\\Etc' => $vendorDir . '/emuravjev/mdash/src/Tret/Etc.php', + 'Emuravjev\\Mdash\\Tret\\Nobr' => $vendorDir . '/emuravjev/mdash/src/Tret/Nobr.php', + 'Emuravjev\\Mdash\\Tret\\Number' => $vendorDir . '/emuravjev/mdash/src/Tret/Number.php', + 'Emuravjev\\Mdash\\Tret\\OptAlign' => $vendorDir . '/emuravjev/mdash/src/Tret/OptAlign.php', + 'Emuravjev\\Mdash\\Tret\\Punctmark' => $vendorDir . '/emuravjev/mdash/src/Tret/Punctmark.php', + 'Emuravjev\\Mdash\\Tret\\Quote' => $vendorDir . '/emuravjev/mdash/src/Tret/Quote.php', + 'Emuravjev\\Mdash\\Tret\\Space' => $vendorDir . '/emuravjev/mdash/src/Tret/Space.php', + 'Emuravjev\\Mdash\\Tret\\Symbol' => $vendorDir . '/emuravjev/mdash/src/Tret/Symbol.php', + 'Emuravjev\\Mdash\\Tret\\Text' => $vendorDir . '/emuravjev/mdash/src/Tret/Text.php', + 'Emuravjev\\Mdash\\Typograph' => $vendorDir . '/emuravjev/mdash/src/Typograph.php', + 'Emuravjev\\Mdash\\TypographBase' => $vendorDir . '/emuravjev/mdash/src/TypographBase.php', +); diff --git a/lib/vendor/composer/autoload_namespaces.php b/lib/vendor/composer/autoload_namespaces.php new file mode 100644 index 0000000..b7fc012 --- /dev/null +++ b/lib/vendor/composer/autoload_namespaces.php @@ -0,0 +1,9 @@ + array($baseDir . '/src'), + 'Emuravjev\\Mdash\\' => array($vendorDir . '/emuravjev/mdash/src'), +); diff --git a/lib/vendor/composer/autoload_real.php b/lib/vendor/composer/autoload_real.php new file mode 100644 index 0000000..b82d054 --- /dev/null +++ b/lib/vendor/composer/autoload_real.php @@ -0,0 +1,52 @@ += 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded()); + if ($useStaticLoader) { + require_once __DIR__ . '/autoload_static.php'; + + call_user_func(\Composer\Autoload\ComposerStaticInit371aeab417b0809125223b89ea34c67a::getInitializer($loader)); + } else { + $map = require __DIR__ . '/autoload_namespaces.php'; + foreach ($map as $namespace => $path) { + $loader->set($namespace, $path); + } + + $map = require __DIR__ . '/autoload_psr4.php'; + foreach ($map as $namespace => $path) { + $loader->setPsr4($namespace, $path); + } + + $classMap = require __DIR__ . '/autoload_classmap.php'; + if ($classMap) { + $loader->addClassMap($classMap); + } + } + + $loader->register(true); + + return $loader; + } +} diff --git a/lib/vendor/composer/autoload_static.php b/lib/vendor/composer/autoload_static.php new file mode 100644 index 0000000..cc2006e --- /dev/null +++ b/lib/vendor/composer/autoload_static.php @@ -0,0 +1,59 @@ + + array ( + 'JUArticleSave\\' => 14, + ), + 'E' => + array ( + 'Emuravjev\\Mdash\\' => 16, + ), + ); + + public static $prefixDirsPsr4 = array ( + 'JUArticleSave\\' => + array ( + 0 => __DIR__ . '/../..' . '/src', + ), + 'Emuravjev\\Mdash\\' => + array ( + 0 => __DIR__ . '/..' . '/emuravjev/mdash/src', + ), + ); + + public static $classMap = array ( + 'Emuravjev\\Mdash\\Lib' => __DIR__ . '/..' . '/emuravjev/mdash/src/Lib.php', + 'Emuravjev\\Mdash\\Tret\\Abbr' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Abbr.php', + 'Emuravjev\\Mdash\\Tret\\Base' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Base.php', + 'Emuravjev\\Mdash\\Tret\\Dash' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Dash.php', + 'Emuravjev\\Mdash\\Tret\\Date' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Date.php', + 'Emuravjev\\Mdash\\Tret\\Etc' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Etc.php', + 'Emuravjev\\Mdash\\Tret\\Nobr' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Nobr.php', + 'Emuravjev\\Mdash\\Tret\\Number' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Number.php', + 'Emuravjev\\Mdash\\Tret\\OptAlign' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/OptAlign.php', + 'Emuravjev\\Mdash\\Tret\\Punctmark' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Punctmark.php', + 'Emuravjev\\Mdash\\Tret\\Quote' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Quote.php', + 'Emuravjev\\Mdash\\Tret\\Space' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Space.php', + 'Emuravjev\\Mdash\\Tret\\Symbol' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Symbol.php', + 'Emuravjev\\Mdash\\Tret\\Text' => __DIR__ . '/..' . '/emuravjev/mdash/src/Tret/Text.php', + 'Emuravjev\\Mdash\\Typograph' => __DIR__ . '/..' . '/emuravjev/mdash/src/Typograph.php', + 'Emuravjev\\Mdash\\TypographBase' => __DIR__ . '/..' . '/emuravjev/mdash/src/TypographBase.php', + ); + + public static function getInitializer(ClassLoader $loader) + { + return \Closure::bind(function () use ($loader) { + $loader->prefixLengthsPsr4 = ComposerStaticInit371aeab417b0809125223b89ea34c67a::$prefixLengthsPsr4; + $loader->prefixDirsPsr4 = ComposerStaticInit371aeab417b0809125223b89ea34c67a::$prefixDirsPsr4; + $loader->classMap = ComposerStaticInit371aeab417b0809125223b89ea34c67a::$classMap; + + }, null, ClassLoader::class); + } +} diff --git a/lib/vendor/composer/installed.json b/lib/vendor/composer/installed.json new file mode 100644 index 0000000..2835bcb --- /dev/null +++ b/lib/vendor/composer/installed.json @@ -0,0 +1,90 @@ +[ + { + "name": "emuravjev/mdash", + "version": "0.2.1", + "version_normalized": "0.2.1.0", + "source": { + "type": "git", + "url": "https://github.com/vitalybaev/mdash-typograph-php.git", + "reference": "f6aab27bd9ed008b5c214b6f30e90bb468593cab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/vitalybaev/mdash-typograph-php/zipball/f6aab27bd9ed008b5c214b6f30e90bb468593cab", + "reference": "f6aab27bd9ed008b5c214b6f30e90bb468593cab", + "shasum": "" + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.7" + }, + "time": "2017-01-13T05:02:06+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Emuravjev\\Mdash\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Public Domain" + ], + "authors": [ + { + "name": "Vitaly Baev", + "email": "dj@vitalybaev.ru" + } + ], + "description": "PHP версия типографа Муравьева", + "keywords": [ + "russian", + "typograph", + "Муравьев", + "русский", + "типограф" + ] + }, + { + "name": "visavi/cleanup", + "version": "v1.5.2", + "version_normalized": "1.5.2.0", + "source": { + "type": "git", + "url": "https://github.com/visavi/cleanup.git", + "reference": "fc13c6376fabe61522d4a3cfeab90e8555c1fbd2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/visavi/cleanup/zipball/fc13c6376fabe61522d4a3cfeab90e8555c1fbd2", + "reference": "fc13c6376fabe61522d4a3cfeab90e8555c1fbd2", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "time": "2019-12-08T16:59:14+00:00", + "bin": [ + "cleanup" + ], + "type": "library", + "installation-source": "dist", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alexander Grigorev", + "email": "admin@visavi.net", + "homepage": "http://visavi.net" + } + ], + "description": "Cleaning vendor directory", + "homepage": "http://visavi.net", + "keywords": [ + "clean", + "composer", + "vendor" + ] + } +] diff --git a/lib/vendor/emuravjev/mdash/composer.json b/lib/vendor/emuravjev/mdash/composer.json new file mode 100644 index 0000000..5b34fdd --- /dev/null +++ b/lib/vendor/emuravjev/mdash/composer.json @@ -0,0 +1,26 @@ +{ + "name": "emuravjev/mdash", + "description": "PHP версия типографа Муравьева", + "keywords": ["типограф", "Муравьев", "typograph", "russian", "русский"], + "license": "Public Domain", + "authors": [ + { + "name": "Vitaly Baev", + "email": "dj@vitalybaev.ru" + } + ], + "require": {}, + "autoload": { + "psr-4": { + "Emuravjev\\Mdash\\": "src/" + } + }, + "autoload-dev": { + "classmap": [ + "tests/TestCase.php" + ] + }, + "require-dev": { + "phpunit/phpunit": "^4.8 || ^5.7" + } +} diff --git a/lib/vendor/emuravjev/mdash/src/Lib.php b/lib/vendor/emuravjev/mdash/src/Lib.php new file mode 100644 index 0000000..5464b37 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Lib.php @@ -0,0 +1,698 @@ + array('html' => array('«', '»', '”', '‘', '„', '“', '"', '«', '»'), + 'utf8' => array(0x201E, 0x201C, 0x201F, 0x201D, 0x00AB, 0x00BB)), + ' ' => array('html' => array(' ', ' ', ' '), + 'utf8' => array(0x00A0, 0x2002, 0x2003, 0x2008, 0x2009)), + '-' => array('html' => array(/*'—',*/ '–', '−', '—', '—', '–'), + 'utf8' => array(0x002D, /*0x2014,*/ 0x2010, 0x2012, 0x2013)), + '—' => array('html' => array('—'), + 'utf8' => array(0x2014)), + '==' => array('html' => array('≡'), + 'utf8' => array(0x2261)), + '...' => array('html' => array('…', '…'), + 'utf8' => array(0x2026)), + '!=' => array('html' => array('≠', '≠'), + 'utf8' => array(0x2260)), + '<=' => array('html' => array('≤', '≤'), + 'utf8' => array(0x2264)), + '>=' => array('html' => array('≥', '≥'), + 'utf8' => array(0x2265)), + '1/2' => array('html' => array('½', '½'), + 'utf8' => array(0x00BD)), + '1/4' => array('html' => array('¼', '¼'), + 'utf8' => array(0x00BC)), + '3/4' => array('html' => array('¾', '¾'), + 'utf8' => array(0x00BE)), + '+-' => array('html' => array('±', '±'), + 'utf8' => array(0x00B1)), + '&' => array('html' => array('&', '&')), + '(tm)' => array('html' => array('™', '™'), + 'utf8' => array(0x2122)), + //'(r)' => array('html' => array('®', '®', '®'), + '(r)' => array('html' => array('®', '®'), + 'utf8' => array(0x00AE)), + '(c)' => array('html' => array('©', '©'), + 'utf8' => array(0x00A9)), + '§' => array('html' => array('§', '§'), + 'utf8' => array(0x00A7)), + '`' => array('html' => array('́')), + '\'' => array('html' => array('’', '’')), + 'x' => array('html' => array('×', '×'), + 'utf8' => array('×') /* какой же у него может быть код? */), + + ); + + /** + * Добавление к тегам атрибута 'id', благодаря которому + * при повторном типографирование текста будут удалены теги, + * расставленные данным типографом + * + * @var array + */ + protected static $_typographSpecificTagId = false; + + + /** + * Костыли для работы с символами UTF-8 + * + * @author somebody? + * @param int $c код символа в кодировке UTF-8 (например, 0x00AB) + * @return bool|string + */ + public static function _getUnicodeChar($c) + { + if ($c <= 0x7F) { + return chr($c); + } else if ($c <= 0x7FF) { + return chr(0xC0 | $c >> 6) + . chr(0x80 | $c & 0x3F); + } else if ($c <= 0xFFFF) { + return chr(0xE0 | $c >> 12) + . chr(0x80 | $c >> 6 & 0x3F) + . chr(0x80 | $c & 0x3F); + } else if ($c <= 0x10FFFF) { + return chr(0xF0 | $c >> 18) + . chr(0x80 | $c >> 12 & 0x3F) + . chr(0x80 | $c >> 6 & 0x3F) + . chr(0x80 | $c & 0x3F); + } else { + return false; + } + } + + + /** + * Удаление кодов HTML из текста + * + * + * // Remove UTF-8 chars: + * $str = Lib::clear_special_chars('your text', 'utf8'); + * // ... or HTML codes only: + * $str = Lib::clear_special_chars('your text', 'html'); + * // ... or combo: + * $str = Lib::clear_special_chars('your text'); + * + * + * @param string $text + * @param mixed $mode + * @return string|bool + */ + public static function clear_special_chars($text, $mode = null) + { + if(is_string($mode)) $mode = array($mode); + if(is_null($mode)) $mode = array('utf8', 'html'); + if(!is_array($mode)) return false; + $moder = array(); + foreach($mode as $mod) if(in_array($mod, array('utf8','html'))) $moder[] = $mod; + if(count($moder)==0) return false; + + foreach (self::$_charsTable as $char => $vals) + { + foreach ($mode as $type) + { + if (isset($vals[$type])) + { + foreach ($vals[$type] as $v) + { + if ('utf8' === $type && is_int($v)) + { + $v = self::_getUnicodeChar($v); + } + if ('html' === $type) + { + if(preg_match("/<[a-z]+>/i",$v)) + { + $v = self::safe_tag_chars($v, true); + } + } + $text = str_replace($v, $char, $text); + } + } + } + } + + return $text; + } + + /** + * Удаление тегов HTML из текста + * Тег
будет преобразов в перенос строки \n, сочетание тегов

- + * в двойной перенос + * + * @param string $text + * @param array $allowableTag массив из тегов, которые будут проигнорированы + * @return string + */ + public static function remove_html_tags($text, $allowableTag = null) + { + $ignore = null; + + if (null !== $allowableTag) + { + if (is_string($allowableTag)) + { + $allowableTag = array($allowableTag); + } + if (is_array($allowableTag)) + { + $tags = array(); + foreach ($allowableTag as $tag) + { + if ('<' !== substr($tag, 0, 1) || '>' !== substr($tag, -1, 1)) continue; + if ('/' === substr($tag, 1, 1)) continue; + $tags [] = $tag; + } + $ignore = implode('', $tags); + } + } + $text = preg_replace(array('/\/i', '/\<\/p\>\s*\/'), array("\n","\n\n"), $text); + $text = strip_tags($text, $ignore); + return $text; + } + + /** + * Сохраняем содержимое тегов HTML + * + * Тег 'a' кодируется со специальным префиксом для дальнейшей + * возможности выносить за него кавычки. + * + * @param string $text + * @param bool $safe + * @return string + */ + public static function safe_tag_chars($text, $way) + { + if ($way) + $text = preg_replace_callback('/(\<\/?)([^<>]+?)(\>)/s', create_function('$m','return (strlen($m[1])==1 && substr(trim($m[2]), 0, 1) == \'-\' && substr(trim($m[2]), 1, 1) != \'-\')? $m[0] : $m[1].( substr(trim($m[2]), 0, 1) === "a" ? "%%___" : "" ) . Emuravjev\Mdash\Lib::encrypt_tag(trim($m[2])) . $m[3];'), $text); + else + $text = preg_replace_callback('/(\<\/?)([^<>]+?)(\>)/s', create_function('$m','return (strlen($m[1])==1 && substr(trim($m[2]), 0, 1) == \'-\' && substr(trim($m[2]), 1, 1) != \'-\')? $m[0] : $m[1].( substr(trim($m[2]), 0, 3) === "%%___" ? Emuravjev\Mdash\Lib::decrypt_tag(substr(trim($m[2]), 4)) : Emuravjev\Mdash\Lib::decrypt_tag(trim($m[2])) ) . $m[3];'), $text); + return $text; + } + + + /** + * Декодриует спец блоки + * + * @param string $text + * @return string + */ + public static function decode_internal_blocks($text) + { + $text = preg_replace_callback('/'.Lib::INTERNAL_BLOCK_OPEN.'([a-zA-Z0-9\/=]+?)'.Lib::INTERNAL_BLOCK_CLOSE.'/s', create_function('$m','return Emuravjev\Mdash\Lib::decrypt_tag($m[1]);'), $text); + return $text; + } + + /** + * Кодирует спец блок + * + * @param string $text + * @return string + */ + public static function iblock($text) + { + return Lib::INTERNAL_BLOCK_OPEN. Lib::encrypt_tag($text).Lib::INTERNAL_BLOCK_CLOSE; + } + + /** + * Создание тега с защищенным содержимым + * + * @param string $content текст, который будет обрамлен тегом + * @param string $tag тэг + * @param array $attribute список атрибутов, где ключ - имя атрибута, а значение - само значение данного атрибута + * @return string + */ + public static function build_safe_tag($content, $tag = 'span', $attribute = array(), $layout = Lib::LAYOUT_STYLE ) + { + $htmlTag = $tag; + + if (self::$_typographSpecificTagId) + { + if(!isset($attribute['id'])) + { + $attribute['id'] = 'emt-2' . mt_rand(1000,9999); + } + } + + $classname = ""; + if (count($attribute)) + { + + if($layout & Lib::LAYOUT_STYLE) + { + if(isset($attribute['__style']) && $attribute['__style']) + { + if(isset($attribute['style']) && $attribute['style']) + { + $st = trim($attribute['style']); + if(mb_substr($st, -1) != ";") $st .= ";"; + $st .= $attribute['__style']; + $attribute['style'] = $st; + } else { + $attribute['style'] = $attribute['__style']; + } + unset($attribute['__style']); + } + + } + foreach ($attribute as $attr => $value) + { + if($attr == "__style") continue; + if($attr == "class") { + $classname = "$value"; + continue; + } + $htmlTag .= " $attr=\"$value\""; + } + + } + + if( ($layout & Lib::LAYOUT_CLASS ) && $classname) { + $htmlTag .= " class=\"$classname\""; + } + + return "<" . self::encrypt_tag($htmlTag) . ">$content"; + } + + /** + * Метод, осуществляющий кодирование (сохранение) информации + * с целью невозможности типографировать ее + * + * @param string $text + * @return string + */ + public static function encrypt_tag($text) + { + return base64_encode($text)."="; + } + + /** + * Метод, осуществляющий декодирование информации + * + * @param string $text + * @return string + */ + public static function decrypt_tag($text) + { + return base64_decode(substr($text,0,-1)); + } + + + + public static function strpos_ex(&$haystack, $needle, $offset = null) + { + if(is_array($needle)) + { + $m = false; + $w = false; + foreach($needle as $n) + { + $p = strpos($haystack, $n , $offset); + if($p===false) continue; + if($m === false) + { + $m = $p; + $w = $n; + continue; + } + if($p < $m) + { + $m = $p; + $w = $n; + } + } + if($m === false) return false; + return array('pos' => $m, 'str' => $w); + } + return strpos($haystack, $needle, $offset); + } + + public static function _process_selector_pattern(&$pattern) + { + if($pattern===false) return; + $pattern = preg_quote($pattern , '/'); + $pattern = str_replace("\\*", "[a-z0-9_\-]*", $pattern); + $pattern = "/".$pattern."/i"; + } + public static function _test_pattern($pattern, $text) + { + if($pattern === false) return true; + return preg_match($pattern, $text); + } + + public static function strtolower($string) + { + $convert_to = array( + "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", + "v", "w", "x", "y", "z", "à", "á", "â", "ã", "ä", "å", "æ", "ç", "è", "é", "ê", "ë", "ì", "í", "î", "ï", + "ð", "ñ", "ò", "ó", "ô", "õ", "ö", "ø", "ù", "ú", "û", "ü", "ý", "а", "б", "в", "г", "д", "е", "ё", "ж", + "з", "и", "й", "к", "л", "м", "н", "о", "п", "р", "с", "т", "у", "ф", "х", "ц", "ч", "ш", "щ", "ъ", "ы", + "ь", "э", "ю", "я" + ); + $convert_from = array( + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", + "V", "W", "X", "Y", "Z", "À", "Á", "Â", "Ã", "Ä", "Å", "Æ", "Ç", "È", "É", "Ê", "Ë", "Ì", "Í", "Î", "Ï", + "Ð", "Ñ", "Ò", "Ó", "Ô", "Õ", "Ö", "Ø", "Ù", "Ú", "Û", "Ü", "Ý", "А", "Б", "В", "Г", "Д", "Е", "Ё", "Ж", + "З", "И", "Й", "К", "Л", "М", "Н", "О", "П", "Р", "С", "Т", "У", "Ф", "Х", "Ц", "Ч", "Ш", "Щ", "Ъ", "Ъ", + "Ь", "Э", "Ю", "Я" + ); + + return str_replace($convert_from, $convert_to, $string); + } + + // взято с http://www.w3.org/TR/html4/sgml/entities.html + protected static $html4_char_ents = array( + 'nbsp' => 160, + 'iexcl' => 161, + 'cent' => 162, + 'pound' => 163, + 'curren' => 164, + 'yen' => 165, + 'brvbar' => 166, + 'sect' => 167, + 'uml' => 168, + 'copy' => 169, + 'ordf' => 170, + 'laquo' => 171, + 'not' => 172, + 'shy' => 173, + 'reg' => 174, + 'macr' => 175, + 'deg' => 176, + 'plusmn' => 177, + 'sup2' => 178, + 'sup3' => 179, + 'acute' => 180, + 'micro' => 181, + 'para' => 182, + 'middot' => 183, + 'cedil' => 184, + 'sup1' => 185, + 'ordm' => 186, + 'raquo' => 187, + 'frac14' => 188, + 'frac12' => 189, + 'frac34' => 190, + 'iquest' => 191, + 'Agrave' => 192, + 'Aacute' => 193, + 'Acirc' => 194, + 'Atilde' => 195, + 'Auml' => 196, + 'Aring' => 197, + 'AElig' => 198, + 'Ccedil' => 199, + 'Egrave' => 200, + 'Eacute' => 201, + 'Ecirc' => 202, + 'Euml' => 203, + 'Igrave' => 204, + 'Iacute' => 205, + 'Icirc' => 206, + 'Iuml' => 207, + 'ETH' => 208, + 'Ntilde' => 209, + 'Ograve' => 210, + 'Oacute' => 211, + 'Ocirc' => 212, + 'Otilde' => 213, + 'Ouml' => 214, + 'times' => 215, + 'Oslash' => 216, + 'Ugrave' => 217, + 'Uacute' => 218, + 'Ucirc' => 219, + 'Uuml' => 220, + 'Yacute' => 221, + 'THORN' => 222, + 'szlig' => 223, + 'agrave' => 224, + 'aacute' => 225, + 'acirc' => 226, + 'atilde' => 227, + 'auml' => 228, + 'aring' => 229, + 'aelig' => 230, + 'ccedil' => 231, + 'egrave' => 232, + 'eacute' => 233, + 'ecirc' => 234, + 'euml' => 235, + 'igrave' => 236, + 'iacute' => 237, + 'icirc' => 238, + 'iuml' => 239, + 'eth' => 240, + 'ntilde' => 241, + 'ograve' => 242, + 'oacute' => 243, + 'ocirc' => 244, + 'otilde' => 245, + 'ouml' => 246, + 'divide' => 247, + 'oslash' => 248, + 'ugrave' => 249, + 'uacute' => 250, + 'ucirc' => 251, + 'uuml' => 252, + 'yacute' => 253, + 'thorn' => 254, + 'yuml' => 255, + 'fnof' => 402, + 'Alpha' => 913, + 'Beta' => 914, + 'Gamma' => 915, + 'Delta' => 916, + 'Epsilon' => 917, + 'Zeta' => 918, + 'Eta' => 919, + 'Theta' => 920, + 'Iota' => 921, + 'Kappa' => 922, + 'Lambda' => 923, + 'Mu' => 924, + 'Nu' => 925, + 'Xi' => 926, + 'Omicron' => 927, + 'Pi' => 928, + 'Rho' => 929, + 'Sigma' => 931, + 'Tau' => 932, + 'Upsilon' => 933, + 'Phi' => 934, + 'Chi' => 935, + 'Psi' => 936, + 'Omega' => 937, + 'alpha' => 945, + 'beta' => 946, + 'gamma' => 947, + 'delta' => 948, + 'epsilon' => 949, + 'zeta' => 950, + 'eta' => 951, + 'theta' => 952, + 'iota' => 953, + 'kappa' => 954, + 'lambda' => 955, + 'mu' => 956, + 'nu' => 957, + 'xi' => 958, + 'omicron' => 959, + 'pi' => 960, + 'rho' => 961, + 'sigmaf' => 962, + 'sigma' => 963, + 'tau' => 964, + 'upsilon' => 965, + 'phi' => 966, + 'chi' => 967, + 'psi' => 968, + 'omega' => 969, + 'thetasym' => 977, + 'upsih' => 978, + 'piv' => 982, + 'bull' => 8226, + 'hellip' => 8230, + 'prime' => 8242, + 'Prime' => 8243, + 'oline' => 8254, + 'frasl' => 8260, + 'weierp' => 8472, + 'image' => 8465, + 'real' => 8476, + 'trade' => 8482, + 'alefsym' => 8501, + 'larr' => 8592, + 'uarr' => 8593, + 'rarr' => 8594, + 'darr' => 8595, + 'harr' => 8596, + 'crarr' => 8629, + 'lArr' => 8656, + 'uArr' => 8657, + 'rArr' => 8658, + 'dArr' => 8659, + 'hArr' => 8660, + 'forall' => 8704, + 'part' => 8706, + 'exist' => 8707, + 'empty' => 8709, + 'nabla' => 8711, + 'isin' => 8712, + 'notin' => 8713, + 'ni' => 8715, + 'prod' => 8719, + 'sum' => 8721, + 'minus' => 8722, + 'lowast' => 8727, + 'radic' => 8730, + 'prop' => 8733, + 'infin' => 8734, + 'ang' => 8736, + 'and' => 8743, + 'or' => 8744, + 'cap' => 8745, + 'cup' => 8746, + 'int' => 8747, + 'there4' => 8756, + 'sim' => 8764, + 'cong' => 8773, + 'asymp' => 8776, + 'ne' => 8800, + 'equiv' => 8801, + 'le' => 8804, + 'ge' => 8805, + 'sub' => 8834, + 'sup' => 8835, + 'nsub' => 8836, + 'sube' => 8838, + 'supe' => 8839, + 'oplus' => 8853, + 'otimes' => 8855, + 'perp' => 8869, + 'sdot' => 8901, + 'lceil' => 8968, + 'rceil' => 8969, + 'lfloor' => 8970, + 'rfloor' => 8971, + 'lang' => 9001, + 'rang' => 9002, + 'loz' => 9674, + 'spades' => 9824, + 'clubs' => 9827, + 'hearts' => 9829, + 'diams' => 9830, + 'quot' => 34, + 'amp' => 38, + 'lt' => 60, + 'gt' => 62, + 'OElig' => 338, + 'oelig' => 339, + 'Scaron' => 352, + 'scaron' => 353, + 'Yuml' => 376, + 'circ' => 710, + 'tilde' => 732, + 'ensp' => 8194, + 'emsp' => 8195, + 'thinsp' => 8201, + 'zwnj' => 8204, + 'zwj' => 8205, + 'lrm' => 8206, + 'rlm' => 8207, + 'ndash' => 8211, + 'mdash' => 8212, + 'lsquo' => 8216, + 'rsquo' => 8217, + 'sbquo' => 8218, + 'ldquo' => 8220, + 'rdquo' => 8221, + 'bdquo' => 8222, + 'dagger' => 8224, + 'Dagger' => 8225, + 'permil' => 8240, + 'lsaquo' => 8249, + 'rsaquo' => 8250, + 'euro' => 8364, + ); + /** + * Вернуть уникод символ по html entinty + * + * @param string $entity + * @return string + */ + public static function html_char_entity_to_unicode($entity) + { + if(isset(self::$html4_char_ents[$entity])) return self::_getUnicodeChar(self::$html4_char_ents[$entity]); + return false; + } + + /** + * Сконвериторвать все html entity в соответсвующие юникод символы + * + * @param string $text + */ + public static function convert_html_entities_to_unicode(&$text) + { + $text = preg_replace_callback("/\&#([0-9]+)\;/", + create_function('$m', 'return Emuravjev\Mdash\Lib::_getUnicodeChar(intval($m[1]));') + , $text); + $text = preg_replace_callback("/\&#x([0-9A-F]+)\;/", + create_function('$m', 'return Emuravjev\Mdash\Lib::_getUnicodeChar(hexdec($m[1]));') + , $text); + $text = preg_replace_callback("/\&([a-zA-Z0-9]+)\;/", + create_function('$m', '$r = Emuravjev\Mdash\Lib::html_char_entity_to_unicode($m[1]); return $r ? $r : $m[0];') + , $text); + } + + public static function rstrpos ($haystack, $needle, $offset = 0){ + + if(trim($haystack) != "" && trim($needle) != "" && $offset <= mb_strlen($haystack)) + { + $last_pos = $offset; + $found = false; + while(($curr_pos = mb_strpos($haystack, $needle, $last_pos)) !== false) + { + $found = true; + $last_pos = $curr_pos + 1; + } + if($found) + { + return $last_pos - 1; + } + else + { + return false; + } + } + else + { + return false; + } + } + + public static function ifop($cond, $true, $false) { + return $cond ? $true : $false; + } + + public static function split_number($num) { + return number_format($num, 0, '', ' '); + } + +} diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Abbr.php b/lib/vendor/emuravjev/mdash/src/Tret/Abbr.php new file mode 100644 index 0000000..290169f --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Abbr.php @@ -0,0 +1,142 @@ + 'word-spacing:nowrap;', + ); + + public $rules = array( + 'nobr_abbreviation' => array( + 'description' => 'Расстановка пробелов перед сокращениями dpi, lpi', + 'pattern' => '/(\s+|^|\>)(\d+)(\040|\t)*(dpi|lpi)([\s\;\.\?\!\:\(]|$)/i', + 'replacement' => '\1\2 \4\5' + ), + 'nobr_acronym' => array( + 'description' => 'Расстановка пробелов перед сокращениями гл., стр., рис., илл., ст., п.', + 'pattern' => '/(\s|^|\>|\()(гл|стр|рис|илл?|ст|п|с)\.(\040|\t)*(\d+)(\ \;|\s|\.|\,|\?|\!|$)/iu', + 'replacement' => '\1\2. \4\5' + ), + 'nobr_sm_im' => array( + 'description' => 'Расстановка пробелов перед сокращениями см., им.', + 'pattern' => '/(\s|^|\>|\()(см|им)\.(\040|\t)*([а-яё0-9a-z]+)(\s|\.|\,|\?|\!|$)/iu', + 'replacement' => '\1\2. \4\5' + ), + 'nobr_locations' => array( + 'description' => 'Расстановка пробелов в сокращениях г., ул., пер., д.', + 'pattern' => array( + '/(\s|^|\>)(г|ул|пер|просп|пл|бул|наб|пр|ш|туп)\.(\040|\t)*([а-яё0-9a-z]+)(\s|\.|\,|\?|\!|$)/iu', + '/(\s|^|\>)(б\-р|пр\-кт)(\040|\t)*([а-яё0-9a-z]+)(\s|\.|\,|\?|\!|$)/iu', + '/(\s|^|\>)(д|кв|эт)\.(\040|\t)*(\d+)(\s|\.|\,|\?|\!|$)/iu', + ), + 'replacement' => array( + '\1\2. \4\5', + '\1\2 \4\5', + '\1\2. \4\5', + ) + ), + 'nbsp_before_unit' => array( + 'description' => 'Замена символов и привязка сокращений в размерных величинах: м, см, м2…', + 'pattern' => array( + '/(\s|^|\>|\ \;|\,)(\d+)( |\ \;)?(м|мм|см|дм|км|гм|km|dm|cm|mm)(\s|\.|\!|\?|\,|$|\±\;|\;|\<)/iu', + '/(\s|^|\>|\ \;|\,)(\d+)( |\ \;)?(м|мм|см|дм|км|гм|km|dm|cm|mm)([32]|³|²)(\s|\.|\!|\?|\,|$|\±\;|\;|\<)/iue' + ), + 'replacement' => array( + '\1\2 \4\5', + '$m[1].$m[2]." ".$m[4].($m[5]=="3"||$m[5]=="2"? "&sup".$m[5].";" : $m[5] ).$m[6]' + ), + ), + 'nbsp_before_weight_unit' => array( + 'description' => 'Замена символов и привязка сокращений в весовых величинах: г, кг, мг…', + 'pattern' => '/(\s|^|\>|\ \;|\,)(\d+)( |\ \;)?(г|кг|мг|т)(\s|\.|\!|\?|\,|$|\ \;|\;)/iu', + 'replacement' => '\1\2 \4\5', + ), + 'nobr_before_unit_volt' => array( + 'description' => 'Установка пробельных символов в сокращении вольт', + 'pattern' => '/(\d+)([вВ]| В)(\s|\.|\!|\?|\,|$)/u', + 'replacement' => '\1 В\3' + ), + 'ps_pps' => array( + 'description' => 'Объединение сокращений P.S., P.P.S.', + 'pattern' => '/(^|\040|\t|\>|\r|\n)(p\.\040?)(p\.\040?)?(s\.)([^\<])/ie', + 'replacement' => '$m[1] . $this->tag(trim($m[2]) . " " . ($m[3] ? trim($m[3]) . " " : ""). $m[4], "span", array("class" => "nowrap") ).$m[5] ' + ), + 'nobr_vtch_itd_itp' => array( + 'description' => 'Объединение сокращений и т.д., и т.п., в т.ч.', + 'cycled' => true, + 'pattern' => array( + '/(^|\s|\ \;)и( |\ \;)т\.?[ ]?д(\.|$|\s|\ \;)/ue', + '/(^|\s|\ \;)и( |\ \;)т\.?[ ]?п(\.|$|\s|\ \;)/ue', + '/(^|\s|\ \;)в( |\ \;)т\.?[ ]?ч(\.|$|\s|\ \;)/ue', + ), + 'replacement' => array( + '$m[1].$this->tag("и т. д.", "span", array("class" => "nowrap")).($m[3]!="."? $m[3] : "" )', + '$m[1].$this->tag("и т. п.", "span", array("class" => "nowrap")).($m[3]!="."? $m[3] : "" )', + '$m[1].$this->tag("в т. ч.", "span", array("class" => "nowrap")).($m[3]!="."? $m[3] : "" )', + ) + ), + 'nbsp_te' => array( + 'description' => 'Обработка т.е.', + 'pattern' => '/(^|\s|\ \;)([тТ])\.?[ ]?е\./ue', + 'replacement' => '$m[1].$this->tag($m[2].". е.", "span", array("class" => "nowrap"))', + ), + 'nbsp_money_abbr' => array( + 'description' => 'Форматирование денежных сокращений (расстановка пробелов и привязка названия валюты к числу)', + 'pattern' => '/(\d)((\040|\ \;)?(тыс|млн|млрд)\.?(\040|\ \;)?)?(\040|\ \;)?(руб\.|долл\.|евро|€|€|\$|у[\.]? ?е[\.]?)/ieu', + 'replacement' => '$m[1].($m[4]?" ".$m[4].($m[4]=="тыс"?".":""):"")." ".(!preg_match("#у[\\\\.]? ?е[\\\\.]?#iu",$m[7])?$m[7]:"у.е.")', + 'replacement_python' => 'm.group(1)+(u" "+m.group(4)+(u"." if m.group(4)==u"тыс" else u"") if m.group(4) else u"")+u" "+(m.group(7) if not re.match(u"у[\\\\.]? ?е[\\\\.]?",m.group(7),re.I | re.U) else u"у.е.")' + //'replacement_py' => 'm.group(1)+(\" \"+m.group(4)+(m.group(4)==\"\u0442\u044b\u0441\"?\".\" if m.group(4) else \"\"):\"\")+\" \"+(m.group(7) if !preg_match(\"#\u0443[\\\\.]? ?\u0435[\\\\.]?#iu\",m.group(7)) else \"\u0443.\u0435.\")' + ), + 'nbsp_money_abbr_rev' => array( + 'description' => 'Привязка валюты к числу спереди', + 'pattern' => '/(€|€|\$)\s?(\d)/iu', + 'replacement' => '\1 \2' + ), + 'nbsp_org_abbr' => array( + 'description' => 'Привязка сокращений форм собственности к названиям организаций', + 'pattern' => '/([^a-zA-Zа-яёА-ЯЁ]|^)(ООО|ЗАО|ОАО|НИИ|ПБОЮЛ) ([a-zA-Zа-яёА-ЯЁ]|\"|\«\;|\&bdquo\;|<)/u', + 'replacement' => '\1\2 \3' + ), + 'nobr_gost' => array( + 'description' => 'Привязка сокращения ГОСТ к номеру', + 'pattern' => array( + '/(\040|\t|\ \;|^)ГОСТ( |\ \;)?(\d+)((\-|\&minus\;|\&mdash\;)(\d+))?(( |\ \;)(\-|\&mdash\;))?/ieu', + '/(\040|\t|\ \;|^|\>)ГОСТ( |\ \;)?(\d+)(\-|\&minus\;|\&mdash\;)(\d+)/ieu', + ), + 'replacement' => array( + '$m[1].$this->tag("ГОСТ ".$m[3].(isset($m[6])?"–".$m[6]:"").(isset($m[7])?" —":""),"span", array("class"=>"nowrap"))', + '$m[1]."ГОСТ ".$m[3]."–".$m[5]', + ), + ), + /* + 'nobr_vtch_itd_itp' => array( + 'description' => 'Привязка сокращений до н.э., н.э.', + 'pattern' => array( + + //IV в до н.э, в V-VIвв до нэ., третий в. н.э. + + '/(\s|\ \;)и( |\ \;)т\.?[ ]?д\./ue', + '/(\s|\ \;)и( |\ \;)т\.?[ ]?п\./ue', + '/(\s|\ \;)в( |\ \;)т\.?[ ]?ч\./ue', + ), + 'replacement' => array( + '$m[1].$this->tag("и т. д.", "span", array("class" => "nowrap"))', + '$m[1].$this->tag("и т. п.", "span", array("class" => "nowrap"))', + '$m[1].$this->tag("в т. ч.", "span", array("class" => "nowrap"))', + ) + ), + */ + + + ); +} diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Base.php b/lib/vendor/emuravjev/mdash/src/Tret/Base.php new file mode 100644 index 0000000..36c4d4c --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Base.php @@ -0,0 +1,525 @@ +logging) return; + $this->logs[] = array('info' => $str, 'data' => $data); + } + + private function error($info, $data = null) + { + $this->errors[] = array('info' => $info, 'data' => $data); + $this->log('ERROR: '. $info , $data); + } + + public function debug($place, &$after_text) + { + if(!$this->debug_enabled) return; + $this->debug_info[] = array( + 'place' => $place, + 'text' => $after_text, + ); + } + + + /** + * Установить режим разметки для данного Трэта если не было раньше установлено, + * Lib::LAYOUT_STYLE - с помощью стилей + * Lib::LAYOUT_CLASS - с помощью классов + * + * @param int $kind + */ + public function set_tag_layout_ifnotset($layout) + { + if($this->use_layout_set) return; + $this->use_layout = $layout; + } + + /** + * Установить режим разметки для данного Трэта, + * Lib::LAYOUT_STYLE - с помощью стилей + * Lib::LAYOUT_CLASS - с помощью классов + * Lib::LAYOUT_STYLE|Lib::LAYOUT_CLASS - оба метода + * + * @param int $kind + */ + public function set_tag_layout($layout = Lib::LAYOUT_STYLE) + { + $this->use_layout = $layout; + $this->use_layout_set = true; + } + + public function set_class_layout_prefix($prefix) + { + $this->class_layout_prefix = $prefix; + } + + + public function debug_on() + { + $this->debug_enabled = true; + } + + public function log_on() + { + $this->debug_enabled = true; + } + + + private function getmethod($name) + { + if(!$name) return false; + if(!method_exists($this, $name)) return false; + return array($this, $name); + } + + private function _pre_parse() + { + $this->pre_parse(); + foreach($this->rules as $rule) + { + if(!isset($rule['init'])) continue; + $m = $this->getmethod($rule['init']); + if(!$m) continue; + call_user_func($m); + } + } + private function _post_parse() + { + foreach($this->rules as $rule) + { + if(!isset($rule['deinit'])) continue; + $m = $this->getmethod($rule['deinit']); + if(!$m) continue; + call_user_func($m); + } + $this->post_parse(); + } + + private function rule_order_sort($a, $b) + { + if($a['order'] == $b['order']) return 0; + if($a['order'] < $b['order']) return -1; + return 1; + } + + private function apply_rule($rule) + { + $name = $rule['id']; + //$this->log("Правило $name", "Применяем правило"); + $disabled = (isset($this->disabled[$rule['id']]) && $this->disabled[$rule['id']]) || ((isset($rule['disabled']) && $rule['disabled']) && !(isset($this->enabled[$rule['id']]) && $this->enabled[$rule['id']])); + if($disabled) + { + $this->log("Правило $name", "Правило отключено" . ((isset($rule['disabled']) && $rule['disabled'])? " (по умолчанию)" : "")); + return; + } + if(isset($rule['function']) && $rule['function']) + { + if(!(isset($rule['pattern']) && $rule['pattern'])) + { + if(method_exists($this, $rule['function'])) + { + $this->log("Правило $name", "Используется метод ".$rule['function']." в правиле"); + + call_user_func(array($this, $rule['function'])); + return; + } + if(function_exists($rule['function'])) + { + $this->log("Правило $name", "Используется функция ".$rule['function']." в правиле"); + + call_user_func($rule['function']); + return; + } + + $this->error('Функция '.$rule['function'].' из правила '.$rule['id']. " не найдена"); + return ; + } else { + if(preg_match("/^[a-z_0-9]+$/i", $rule['function'])) + { + if(method_exists($this, $rule['function'])) + { + $this->log("Правило $name", "Замена с использованием preg_replace_callback с методом ".$rule['function'].""); + + $this->_text = preg_replace_callback($rule['pattern'], array($this, $rule['function']), $this->_text); + return; + } + if(function_exists($rule['function'])) + { + $this->log("Правило $name", "Замена с использованием preg_replace_callback с функцией ".$rule['function'].""); + + $this->_text = preg_replace_callback($rule['pattern'], $rule['function'], $this->_text); + return; + } + $this->error('Функция '.$rule['function'].' из правила '.$rule['id']. " не найдена"); + } else { + $this->_text = preg_replace_callback($rule['pattern'], create_function('$m', $rule['function']), $this->_text); + $this->log('Замена с использованием preg_replace_callback с инлайн функцией из правила '.$rule['id']); + return; + } + return ; + } + } + + if(isset($rule['simple_replace']) && $rule['simple_replace']) + { + if(isset($rule['case_sensitive']) && $rule['case_sensitive']) + { + $this->log("Правило $name", "Простая замена с использованием str_replace"); + $this->_text = str_replace($rule['pattern'], $rule['replacement'], $this->_text); + return; + } + $this->log("Правило $name", "Простая замена с использованием str_ireplace"); + $this->_text = str_ireplace($rule['pattern'], $rule['replacement'], $this->_text); + return; + } + + $pattern = $rule['pattern']; + if(is_string($pattern)) $pattern = array($pattern); + $eval = false; + foreach($pattern as $patt) + { + $chr = substr($patt,0,1); + $preg_arr = explode($chr, $patt); + if(strpos($preg_arr[count($preg_arr)-1], "e")!==false) + { + $eval = true; + break; + } + } + if(!$eval) + { + $this->log("Правило $name", "Замена с использованием preg_replace"); + + do { + $this->_text = preg_replace($rule['pattern'], $rule['replacement'], $this->_text); + if(!(isset($rule['cycled']) && $rule['cycled'])) break; + } while(preg_match($rule['pattern'], $this->_text)); + + return; + } + + $this->log("Правило $name", "Замена с использованием preg_replace_callback вместо eval"); + $k = 0; + foreach($pattern as $patt) + { + $repl = is_string($rule['replacement']) ? $rule['replacement'] : $rule['replacement'][$k]; + + $chr = substr($patt,0,1); + $preg_arr = explode($chr, $patt); + if(strpos($preg_arr[count($preg_arr)-1], "e")!==false) // eval система + { + $preg_arr[count($preg_arr)-1] = str_replace("e","",$preg_arr[count($preg_arr)-1]); + $patt = implode($chr, $preg_arr); + $this->thereplacement = $repl; + do { + $this->_text = preg_replace_callback($patt, array($this, "thereplcallback"), $this->_text); + if(!(isset($rule['cycled']) && $rule['cycled'])) break; + } while(preg_match($patt, $this->_text)); + + } else { + do { + $this->_text = preg_replace($patt, $repl, $this->_text); + if(!(isset($rule['cycled']) && $rule['cycled'])) break; + } while(preg_match($patt, $this->_text)); + } + $k++; + } + } + + + protected function preg_replace_e($pattern, $replacement, $text) + { + $chr = substr($pattern,0,1); + $preg_arr = explode($chr, $pattern); + if(strpos($preg_arr[count($preg_arr)-1], "e")===false) return preg_replace($pattern, $replacement, $text); + $preg_arr[count($preg_arr)-1] = str_replace("e","",$preg_arr[count($preg_arr)-1]); + $patt = implode($chr, $preg_arr); + $this->thereplacement = $replacement; + return preg_replace_callback($patt, array($this, "thereplcallback"), $text); + } + + private $thereplacement = ""; + private function thereplcallback($m) + { + $x = ""; + eval('$x = '.($this->thereplacement?$this->thereplacement:'""').';'); + return $x; + } + + private function _apply($list) + { + $this->errors = array(); + $this->_pre_parse(); + + $this->log("Применяется набор правил", implode(",",$list)); + + $rulelist = array(); + foreach($list as $k) + { + $rule = $this->rules[$k]; + $rule['id'] = $k; + $rule['order'] = isset($rule['order'])? $rule['order'] : 5 ; + $rulelist[] = $rule; + } + //usort($rulelist, array($this, "rule_order_sort")); + + foreach($rulelist as $rule) + { + $this->apply_rule($rule); + $this->debug($rule['id'], $this->_text); + } + + $this->_post_parse(); + } + + + /** + * Создание защищенного тега с содержимым + * + * @see Lib::build_safe_tag + * @param string $content + * @param string $tag + * @param array $attribute + * @return string + */ + protected function tag($content, $tag = 'span', $attribute = array()) + { + if(isset($attribute['class'])) + { + $classname = $attribute['class']; + if($classname == "nowrap") + { + if(!$this->is_on('nowrap')) + { + $tag = "nobr"; + $attribute = array(); + $classname = ""; + } + } + if(isset($this->classes[$classname])) + { + $style_inline = $this->classes[$classname]; + if($style_inline) $attribute['__style'] = $style_inline; + } + $classname = (isset($this->class_names[$classname]) ? $this->class_names[$classname] :$classname); + $classname = ($this->class_layout_prefix ? $this->class_layout_prefix : "" ).$classname; + $attribute['class'] = $classname; + } + + return Lib::build_safe_tag($content, $tag, $attribute, + $this->use_layout === false? Lib::LAYOUT_STYLE : $this->use_layout ); + } + + + /** + * Добавить правило в группу + * + * @param string $name + * @param array $params + */ + public function put_rule($name, $params) + { + $this->rules[$name] = $params; + return $this; + } + + /** + * Отключить правило, в обработке + * + * @param string $name + */ + public function disable_rule($name) + { + $this->disabled[$name] = true; + unset($this->enabled[$name]); + } + + /** + * Включить правило + * + * @param string $name + */ + public function enable_rule($name) + { + $this->enabled[$name] = true; + unset($this->disabled[$name]); + } + + /** + * Добавить настройку в трет + * + * @param string $key ключ + * @param mixed $value значение + */ + public function set($key, $value) + { + $this->settings[$key] = $value; + } + + /** + * Установлена ли настройка + * + * @param string $key + */ + public function is_on($key) + { + if(!isset($this->settings[$key])) return false; + $kk = $this->settings[$key]; + return ((strtolower($kk)=="on") || ($kk === "1") || ($kk === true) || ($kk === 1)); + } + + /** + * Получить строковое значение настройки + * + * @param mixed $key + * @return mixed + */ + public function ss($key) + { + if(!isset($this->settings[$key])) return ""; + return strval($this->settings[$key]); + } + + /** + * Добавить настройку в правило + * + * @param string $rulename идентификатор правила + * @param string $key ключ + * @param mixed $value значение + */ + public function set_rule($rulename, $key, $value) + { + $this->rules[$rulename][$key] = $value; + } + + /** + * Включить правила, согласно списку + * + * @param array $list список правил + * @param bool $disable выкллючить их или включить + * @param bool $strict строго, т.е. те которые не в списку будут тоже обработаны + */ + public function activate($list,$disable =false, $strict = true) + { + if(!is_array($list)) return ; + + foreach($list as $rulename) + { + if($disable) $this->disable_rule($rulename); else $this->enable_rule($rulename); + } + + if($strict) + { + foreach($this->rules as $rulename => $v) + { + if(in_array($rulename, $list)) continue; + if(!$disable) $this->disable_rule($rulename); else $this->enable_rule($rulename); + } + } + } + + public function set_text(&$text) + { + $this->_text = &$text; + $this->debug_info = array(); + $this->logs = array(); + } + + + /** + * Применить к тексту + * + * @param string $text - текст к которому применить + * @param mixed $list - список правил, null - все правила + * @return string + */ + public function apply($list = null) + { + if(is_string($list)) $rlist = array($list); + elseif(is_array($list)) $rlist = $list; + else $rlist = array_keys($this->rules); + $this->_apply($rlist); + return $this->_text; + } + + + + + /** + * Код, выполняем до того, как применить правила + * + */ + public function pre_parse() + { + } + + /** + * После выполнения всех правил, выполняется этот метод + * + */ + public function post_parse() + { + } + + +} diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Dash.php b/lib/vendor/emuravjev/mdash/src/Tret/Dash.php new file mode 100644 index 0000000..10ba1e3 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Dash.php @@ -0,0 +1,75 @@ + array( + 'description' => 'Замена символа тире на html конструкцию', + 'pattern' => '/—/iu', + 'replacement' => '—' + ), + 'mdash' => array( + 'description' => 'Тире после кавычек, скобочек, пунктуации', + 'pattern' => array( + '/([a-zа-яё0-9]+|\,|\:|\)|\&(ra|ld)quo\;|\|\"|\>)(\040|\t)(—|\-|\&mdash\;)(\s|$|\<)/ui', + '/(\,|\:|\)|\")(—|\-|\&mdash\;)(\s|$|\<)/ui', + ), + 'replacement' => array( + '\1 —\5', + '\1 —\3', + ), + ), + 'mdash_2' => array( + 'description' => 'Тире после переноса строки', + 'pattern' => '/(\n|\r|^|\>)(\-|\&mdash\;)(\t|\040)/', + 'replacement' => '\1— ' + ), + 'mdash_3' => array( + 'description' => 'Тире после знаков восклицания, троеточия и прочее', + 'pattern' => '/(\.|\!|\?|\&hellip\;)(\040|\t|\ \;)(\-|\&mdash\;)(\040|\t|\ \;)/', + 'replacement' => '\1 — ' + ), + 'iz_za_pod' => array( + 'description' => 'Расстановка дефисов между из-за, из-под', + 'pattern' => '/(\s|\ \;|\>|^)(из)(\040|\t|\ \;)\-?(за|под)([\.\,\!\?\:\;]|\040|\ \;)/uie', + 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' + ), + 'to_libo_nibud' => array( + 'description' => 'Автоматическая простановка дефисов в обезличенных местоимениях и междометиях', + 'cycled' => true, + 'pattern' => '/(\s|^|\ \;|\>)(кто|кем|когда|зачем|почему|как|что|чем|где|чего|кого)\-?(\040|\t|\ \;)\-?(то|либо|нибудь)([\.\,\!\?\;]|\040|\ \;|$)/uie', + 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' + ), + 'koe_kak' => array( + 'description' => 'Кое-как, кой-кого, все-таки', + 'cycled' => true, + 'pattern' => array( + '/(\s|^|\ \;|\>)(кое)\-?(\040|\t|\ \;)\-?(как)([\.\,\!\?\;]|\040|\ \;|$)/uie', + '/(\s|^|\ \;|\>)(кой)\-?(\040|\t|\ \;)\-?(кого)([\.\,\!\?\;]|\040|\ \;|$)/uie', + '/(\s|^|\ \;|\>)(вс[её])\-?(\040|\t|\ \;)\-?(таки)([\.\,\!\?\;]|\040|\ \;|$)/uie', + ), + 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' + ), + 'ka_de_kas' => array( + 'description' => 'Расстановка дефисов с частицами ка, де, кась', + 'disabled' => true, + 'pattern' => array( + '/(\s|^|\ \;|\>)([а-яё]+)(\040|\t|\ \;)(ка)([\.\,\!\?\;]|\040|\ \;|$)/uie', + '/(\s|^|\ \;|\>)([а-яё]+)(\040|\t|\ \;)(де)([\.\,\!\?\;]|\040|\ \;|$)/uie', + '/(\s|^|\ \;|\>)([а-яё]+)(\040|\t|\ \;)(кась)([\.\,\!\?\;]|\040|\ \;|$)/uie', + ), + 'replacement' => '($m[1] == " " ? " " : $m[1]) . $m[2]."-".$m[4] . ($m[5] == " "? " " : $m[5])' + ), + + + + ); + +} diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Date.php b/lib/vendor/emuravjev/mdash/src/Tret/Date.php new file mode 100644 index 0000000..dc76473 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Date.php @@ -0,0 +1,60 @@ + 'word-spacing:nowrap;', + ); + + public $rules = array( + 'years' => array( + 'description' => 'Установка тире и пробельных символов в периодах дат', + 'pattern' => '/(с|по|период|середины|начала|начало|конца|конец|половины|в|между|\([cс]\)|\©\;)(\s+|\ \;)([\d]{4})(-|\&mdash\;|\&minus\;)([\d]{4})(( |\ \;)?(г\.г\.|гг\.|гг|г\.|г)([^а-яёa-z]))?/eui', + 'replacement' => '$m[1].$m[2]. (intval($m[3])>=intval($m[5])? $m[3].$m[4].$m[5] : $m[3]."—".$m[5]) . (isset($m[6])? " гг.":"").(isset($m[9])?$m[9]:"")' + ), + 'mdash_month_interval' => array( + 'description' => 'Расстановка тире и объединение в неразрывные периоды месяцев', + 'disabled' => true, + 'pattern' => '/((январ|феврал|сентябр|октябр|ноябр|декабр)([ьяюе]|[её]м)|(апрел|июн|июл)([ьяюе]|ем)|(март|август)([ауе]|ом)?|ма[йяюе]|маем)\-((январ|феврал|сентябр|октябр|ноябр|декабр)([ьяюе]|[её]м)|(апрел|июн|июл)([ьяюе]|ем)|(март|август)([ауе]|ом)?|ма[йяюе]|маем)/iu', + 'replacement' => '\1—\8' + ), + 'nbsp_and_dash_month_interval' => array( + 'description' => 'Расстановка тире и объединение в неразрывные периоды дней', + 'disabled' => true, + 'pattern' => '/([^\>]|^)(\d+)(\-|\&minus\;|\&mdash\;)(\d+)( |\ \;)(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)([^\<]|$)/ieu', + 'replacement' => '$m[1].$this->tag($m[2]."—".$m[4]." ".$m[6],"span", array("class"=>"nowrap")).$m[7]' + ), + 'nobr_year_in_date' => array( + 'description' => 'Привязка года к дате', + 'pattern' => array( + '/(\s|\ \;)([0-9]{2}\.[0-9]{2}\.([0-9]{2})?[0-9]{2})(\s|\ \;)?г(\.|\s|\ \;)/eiu', + '/(\s|\ \;)([0-9]{2}\.[0-9]{2}\.([0-9]{2})?[0-9]{2})(\s|\ \;|\.(\s|\ \;|$)|$)/eiu', + ), + 'replacement' => array( + '$m[1].$this->tag($m[2]." г.","span", array("class"=>"nowrap")).($m[5]==="."?"":" ")', + '$m[1].$this->tag($m[2],"span", array("class"=>"nowrap")).$m[4]', + ), + ), + 'space_posle_goda' => array( + 'description' => 'Пробел после года', + 'pattern' => '/(^|\040|\ \;)([0-9]{3,4})(год([ауе]|ом)?)([^a-zа-яё]|$)/ui', + 'replacement' => '\1\2 \3\5' + ), + 'nbsp_posle_goda_abbr' => array( + 'description' => 'Пробел после года', + 'pattern' => '/(^|\040|\ \;|\"|\«\;)([0-9]{3,4})[ ]?(г\.)([^a-zа-яё]|$)/ui', + 'replacement' => '\1\2 \3\4' + ), + + ); +} + +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Etc.php b/lib/vendor/emuravjev/mdash/src/Tret/Etc.php new file mode 100644 index 0000000..42b001c --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Etc.php @@ -0,0 +1,105 @@ + 'word-spacing:nowrap;', + ); + + /** + * Базовые параметры тофа + * + * @var array + */ + public $title = "Прочее"; + public $rules = array( + 'acute_accent' => array( + 'description' => 'Акцент', + 'pattern' => '/(у|е|ы|а|о|э|я|и|ю|ё)\`(\w)/i', + 'replacement' => '\1́\2' + ), + + 'word_sup' => array( + 'description' => 'Надстрочный текст после символа ^', + 'pattern' => '/((\s|\ \;|^)+)\^([a-zа-яё0-9\.\:\,\-]+)(\s|\ \;|$|\.$)/ieu', + 'replacement' => '"" . $this->tag($this->tag($m[3],"small"),"sup") . $m[4]' + ), + 'century_period' => array( + 'description' => 'Тире между диапозоном веков', + 'pattern' => '/(\040|\t|\ \;|^)([XIV]{1,5})(-|\&mdash\;)([XIV]{1,5})(( |\ \;)?(в\.в\.|вв\.|вв|в\.|в))/eu', + 'replacement' => '$m[1] .$this->tag($m[2]."—".$m[4]." вв.","span", array("class"=>"nowrap"))' + ), + 'time_interval' => array( + 'description' => 'Тире и отмена переноса между диапозоном времени', + 'pattern' => '/([^\d\>]|^)([\d]{1,2}\:[\d]{2})(-|\&mdash\;|\&minus\;)([\d]{1,2}\:[\d]{2})([^\d\<]|$)/eui', + 'replacement' => '$m[1] . $this->tag($m[2]."—".$m[4],"span", array("class"=>"nowrap")).$m[5]' + ), + 'split_number_to_triads' => array( + 'description' => 'Разбиение числа на триады', + 'pattern' => '/([^a-zA-Z0-9<\)]|^)([0-9]{5,})([^a-zA-Z>\(]|$)/eu', + 'replacement' => '$m[1].str_replace(" "," ",Emuravjev\Mdash\Lib::split_number($m[2])).$m[3] ' + //'function' => 'split_number' + ), + 'expand_no_nbsp_in_nobr' => array( + 'description' => 'Удаление nbsp в nobr/nowrap тэгах', + 'function' => 'remove_nbsp' + ), + 'nobr_to_nbsp' => array( + 'description' => 'Преобразование nobr в nbsp', + 'disabled' => true, + 'function' => 'nobr_to_nbsp' + ), + ); + + protected function remove_nbsp() + { + $thetag = $this->tag("###", 'span', array('class' => "nowrap")); + $arr = explode("###", $thetag); + $b = preg_quote($arr[0], '/'); + $e = preg_quote($arr[1], '/'); + + $match = '/(^|[^a-zа-яё])([a-zа-яё]+)\ \;('.$b.')/iu'; + do { + $this->_text = preg_replace($match, '\1\3\2 ', $this->_text); + } while(preg_match($match, $this->_text)); + + $match = '/('.$e.')\ \;([a-zа-яё]+)($|[^a-zа-яё])/iu'; + do { + $this->_text = preg_replace($match, ' \2\1\3', $this->_text); + } while(preg_match($match, $this->_text)); + + $this->_text = $this->preg_replace_e('/'.$b.'.*?'.$e.'/iue', 'str_replace(" "," ",$m[0]);' , $this->_text ); + } + + protected function nobr_to_nbsp() + { + $thetag = $this->tag("###", 'span', array('class' => "nowrap")); + $arr = explode("###", $thetag); + $b = preg_quote($arr[0], '/'); + $e = preg_quote($arr[1], '/'); + $this->_text = $this->preg_replace_e('/'.$b.'(.*?)'.$e.'/iue', 'str_replace(" "," ",$m[1]);' , $this->_text ); + } + /* + protected function split_number () { + + $this->preg_replace_e("/([^a-zA-Z<]|^)([0-9]{5,})([^a-zA-Z>]|$)/u", ) + + $match = ; + while(preg_match($match, $this->_text, $m)) { + $repl = ""; + for($i = strlen($m[2]); $i >=0 ; $i-=3) + if($i-3>=0) $repl = ($i>3?" ":"").substr($m[2], $i-3, 3) . $repl; else $repl = substr($m[2], 0, $i) . $repl; + $this->_text = str_replace($m[1], $repl, $this->_text); + } + }*/ + +} + +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Nobr.php b/lib/vendor/emuravjev/mdash/src/Tret/Nobr.php new file mode 100644 index 0000000..64de7f3 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Nobr.php @@ -0,0 +1,165 @@ + 'word-spacing:nowrap;', + ); + + public $rules = array( + + 'super_nbsp' => array( + 'description' => 'Привязка союзов и предлогов к написанным после словам', + 'pattern' => '/(\s|^|\&(la|bd)quo\;|\>|\(|\&mdash\;\ \;)([a-zа-яё]{1,2}\s+)([a-zа-яё]{1,2}\s+)?([a-zа-яё0-9\-]{2,}|[0-9])/ieu', + 'replacement' => '$m[1] . trim($m[3]) . " " . ($m[4] ? trim($m[4]) . " " : "") . $m[5]' + ), + 'nbsp_in_the_end' => array( + 'description' => 'Привязка союзов и предлогов к предыдущим словам в случае конца предложения', + 'pattern' => '/([a-zа-яё0-9\-]{3,}) ([a-zа-яё]{1,2})\.( [A-ZА-ЯЁ]|$)/u', + 'replacement' => '\1 \2.\3' + ), + 'phone_builder' => array( + 'description' => 'Объединение в неразрывные конструкции номеров телефонов', + 'pattern' => + array( + '/([^\d\+]|^)([\+]?[0-9]{1,3})( |\ \;|\&thinsp\;)([0-9]{3,4}|\([0-9]{3,4}\))( |\ \;|\&thinsp\;)([0-9]{2,3})(-|\&minus\;)([0-9]{2})(-|\&minus\;)([0-9]{2})([^\d]|$)/e', + '/([^\d\+]|^)([\+]?[0-9]{1,3})( |\ \;|\&thinsp\;)([0-9]{3,4}|[0-9]{3,4})( |\ \;|\&thinsp\;)([0-9]{2,3})(-|\&minus\;)([0-9]{2})(-|\&minus\;)([0-9]{2})([^\d]|$)/e', + ), + 'replacement' => + array( + '$m[1] .(($m[1] == ">" || $m[11] == "<") ? $m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10] :$this->tag($m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10], "span", array("class"=>"nowrap")) ).$m[11]', + '$m[1] .(($m[1] == ">" || $m[11] == "<") ? $m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10] :$this->tag($m[2]." ".$m[4]." ".$m[6]."-".$m[8]."-".$m[10], "span", array("class"=>"nowrap")) ).$m[11]', + ), + ), + 'phone_builder_v2' => array( + 'description' => 'Дополнительный формат номеров телефонов', + 'pattern' => '/([^\d]|^)\+\s?([0-9]{1})\s?\(([0-9]{3,4})\)\s?(\d{3})(\d{2})(\d{2})([^\d]|$)/ie', + 'replacement' => '$m[1].$this->tag("+".$m[2]." ".$m[3]." ".$m[4]."-".$m[5]."-".$m[6], "span", array("class" => "nowrap")).$m[7]', + ), + 'ip_address' => array( + 'description' => 'Объединение IP-адресов', + 'pattern' => '/(\s|\ \;|^)(\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3})/ie', + 'replacement' => '$m[1] . $this->nowrap_ip_address($m[2])' + ), + 'dots_for_surname_abbr' => array( + 'disabled' => true, + 'description' => 'Простановка точек к инициалам у фамилии', + 'pattern' => + array( + '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁ])\.?(\s|\ \;)?([А-ЯЁ])(\s|\ \;)([А-ЯЁ][а-яё]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁ][а-яё]+)(\s|\ \;)([А-ЯЁ])\.?(\s|\ \;)?([А-ЯЁ])\.?(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + ), + 'replacement' => + array( + '$m[1].$this->tag($m[2].". ".$m[4].". ".$m[6], "span", array("class" => "nowrap")).$m[7]', + '$m[1].$this->tag($m[2]." ".$m[4].". ".$m[6].".", "span", array("class" => "nowrap")).$m[7]', + ), + ), + 'spaces_nobr_in_surname_abbr' => array( + 'description' => 'Привязка инициалов к фамилиям', + 'pattern' => + array( + '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁ])\.(\s|\ \;)?([А-ЯЁ])\.(\s|\ \;)?([А-ЯЁ][а-яё]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁ][а-яё]+)(\s|\ \;)([А-ЯЁ])\.(\s|\ \;)?([А-ЯЁ])\.(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁ])(\s|\ \;)?([А-ЯЁ])(\s|\ \;)([А-ЯЁ][а-яё]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + '/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([А-ЯЁ][а-яё]+)(\s|\ \;)([А-ЯЁ])(\s|\ \;)?([А-ЯЁ])(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + //'/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([A-Z])\.?(\s|\ \;)?([A-Z])(\.(\s|\ \;)?|(\s|\ \;))([A-Z][a-z]+)(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + //'/(\s|^|\.|\,|\;|\:|\?|\!|\ \;)([A-Z][a-z]+)(\s|\ \;)([A-Z])\.?(\s|\ \;)?([A-Z])\.?(\s|$|\.|\,|\;|\:|\?|\!|\ \;)/ue', + ), + 'replacement' => + array( + '$m[1].$this->tag($m[2].". ".$m[4].". ".$m[6], "span", array("class" => "nowrap")).$m[7]', + '$m[1].$this->tag($m[2]." ".$m[4].". ".$m[6].".", "span", array("class" => "nowrap")).$m[7]', + '$m[1].$this->tag($m[2].(isset($m[3])? " " : "" ).$m[4].(isset($m[5])? " " : "" ).$m[6], "span", array("class" => "nowrap")).$m[7]', + '$m[1].$this->tag($m[2]." ".$m[4].(isset($m[5])? " " : "" ).$m[6], "span", array("class" => "nowrap")).$m[7]', + //'$m[1].$this->tag($m[2].". ".$m[4].". ".$m[8], "span", array("class" => "nowrap")).$m[9]', + //'$m[1].$this->tag($m[2]." ".$m[4].". ".$m[6].".", "span", array("class" => "nowrap")).$m[7]', + ), + ), + 'nbsp_before_particle' => array( + 'description' => 'Неразрывный пробел перед частицей', + 'pattern' => '/(\040|\t)+(ли|бы|б|же|ж)(\ \;|\.|\,|\:|\;|\&hellip\;|\?|\s)/iue', + 'replacement' => '" ".$m[2] . ($m[3] == " " ? " " : $m[3])' + ), + 'nbsp_v_kak_to' => array( + 'description' => 'Неразрывный пробел в как то', + 'pattern' => '/как то\:/ui', + 'replacement' => 'как то:' + ), + 'nbsp_celcius' => array( + 'description' => 'Привязка градусов к числу', + 'pattern' => '/(\s|^|\>|\ \;)(\d+)( |\ \;)?(°|\°\;)(C|С)(\s|\.|\!|\?|\,|$|\ \;|\;)/iu', + 'replacement' => '\1\2 \4C\6' + ), + 'hyphen_nowrap_in_small_words' => array( + 'description' => 'Обрамление пятисимвольных слов разделенных дефисом в неразрывные блоки', + 'disabled' => true, + 'cycled' => true, + 'pattern' => '/(\ \;|\s|\>|^)([a-zа-яё]{1}\-[a-zа-яё]{4}|[a-zа-яё]{2}\-[a-zа-яё]{3}|[a-zа-яё]{3}\-[a-zа-яё]{2}|[a-zа-яё]{4}\-[a-zа-яё]{1}|когда\-то|кое\-как|кой\-кого|вс[её]\-таки|[а-яё]+\-(кась|ка|де))(\s|\.|\,|\!|\?|\ \;|\&hellip\;|$)/uie', + 'replacement' => '$m[1] . $this->tag($m[2], "span", array("class"=>"nowrap")) . $m[4]', + ), + 'hyphen_nowrap' => array( + 'description' => 'Отмена переноса слова с дефисом', + 'disabled' => true, + 'cycled' => true, + 'pattern' => '/(\ \;|\s|\>|^)([a-zа-яё]+)((\-([a-zа-яё]+)){1,2})(\s|\.|\,|\!|\?|\ \;|\&hellip\;|$)/uie', + 'replacement' => '$m[1] . $this->tag($m[2].$m[3], "span", array("class"=>"nowrap")) . $m[6]' + ), + ); + + /** + * Объединение IP-адрессов в неразрывные конструкции (IPv4 only) + * + * @param mixed $triads + * @return mixed + */ + protected function nowrap_ip_address($triads) + { + $triad = explode('.', $triads); + $addTag = true; + + foreach ($triad as $value) { + $value = (int) $value; + if ($value > 255) { + $addTag = false; + break; + } + } + + if (true === $addTag) { + $triads = $this->tag($triads, 'span', array('class' => "nowrap")); + } + + return $triads; + } +} +/**PYTHON + # * Объединение IP-адрессов в неразрывные конструкции (IPv4 only) + # * + # * @param unknown_type $triads + # * @return unknown + def nowrap_ip_address(self, triads): + triad = triads.split('.') + addTag = True + + for value in triad: + value = int(value) + if (value > 255): + addTag = false + break + + if (addTag == True): + triads = self.tag(triads, 'span', {'class': "nowrap"}) + + return triads + +PYTHON**/ +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Number.php b/lib/vendor/emuravjev/mdash/src/Tret/Number.php new file mode 100644 index 0000000..c9eb70e --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Number.php @@ -0,0 +1,75 @@ + array( + 'description' => 'Расстановка знака минус между числами', + 'pattern' => '/(\d+)\-(\d)/i', + 'replacement' => '\1−\2' + ), + 'minus_in_numbers_range' => array( + 'description' => 'Расстановка знака минус между диапозоном чисел', + 'pattern' => '/(^|\s|\ \;)(\&minus\;|\-)(\d+)(\.\.\.|\&hellip\;)(\s|\ \;)?(\+|\-|\&minus\;)?(\d+)/ie', + 'replacement' => '$m[1] ."−".$m[3] . $m[4].$m[5].($m[6]=="+"?$m[6]:"−").$m[7]' + ), + 'auto_times_x' => array( + 'description' => 'Замена x на символ × в размерных единицах', + 'cycled' => true, + 'pattern' => '/([^a-zA-Z><]|^)(\×\;)?(\d+)(\040*)(x|х)(\040*)(\d+)([^a-zA-Z><]|$)/u', + 'replacement' => '\1\2\3×\7\8' + ), + 'numeric_sub' => array( + 'description' => 'Нижний индекс', + 'pattern' => '/([a-zа-яё0-9])\_([\d]{1,3})([^@а-яёa-z0-9]|$)/ieu', + 'replacement' => '$m[1] . $this->tag($this->tag($m[2],"small"),"sub") . $m[3]' + ), + 'numeric_sup' => array( + 'description' => 'Верхний индекс', + 'pattern' => '/([a-zа-яё0-9])\^([\d]{1,3})([^а-яёa-z0-9]|$)/ieu', + 'replacement' => '$m[1] . $this->tag($this->tag($m[2],"small"),"sup") . $m[3]' + ), + 'dimensions_sup' => array( + 'description' => 'Верхний индекс для см2, м2...', + 'pattern' => '/(м|мм|см|дм|км|гм|m|km|dm|cm|mm)([\d]{1,3})([^а-яёa-z0-9]|$)/ieu', + 'replacement' => '$m[1] . $this->tag($this->tag($m[2],"small"),"sup") . $m[3]' + ), + 'simple_fraction' => array( + 'description' => 'Замена дробей 1/2, 1/4, 3/4 на соответствующие символы', + 'pattern' => array('/(^|\D)1\/(2|4)(\D)/', '/(^|\D)3\/4(\D)/'), + 'replacement' => array('\1&frac1\2;\3', '\1¾\2') + ), + 'math_chars' => array( + 'description' => 'Математические знаки больше/меньше/плюс минус/неравно', + 'pattern' => array('/!=/', '/\<=/', '/([^=]|^)\>=/', '/~=/', '/\+-/'), + 'replacement' => array('≠', '≤', '\1≥', '≅', '±' ) + ), + + 'thinsp_between_number_triads' => array( + 'description' => 'Объединение триад чисел полупробелом', + 'pattern' => '/([0-9]{1,3}( [0-9]{3}){1,})(.|$)/ue', + 'replacement' => '($m[3]=="-"? $m[0]:str_replace(" "," ",$m[1]).$m[3])' + ), + 'thinsp_between_no_and_number' => array( + 'description' => 'Пробел между симоволом номера и числом', + 'pattern' => '/(№|\№\;)(\s| )*(\d)/iu', + 'replacement' => '№ \3' + ), + 'thinsp_between_sect_and_number' => array( + 'description' => 'Пробел между параграфом и числом', + 'pattern' => '/(§|\§\;)(\s| )*(\d+|[IVX]+|[a-zа-яё]+)/ui', + 'replacement' => '§ \3' + ), + ); +} + +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/OptAlign.php b/lib/vendor/emuravjev/mdash/src/Tret/OptAlign.php new file mode 100644 index 0000000..c575425 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/OptAlign.php @@ -0,0 +1,80 @@ + "margin-right:0.3em;", + "oa_obracket_sp_b" => "margin-left:-0.3em;", + "oa_obracket_nl_b" => "margin-left:-0.3em;", + "oa_comma_b" => "margin-right:-0.2em;", + "oa_comma_e" => "margin-left:0.2em;", + 'oa_oquote_nl' => "margin-left:-0.44em;", + 'oa_oqoute_sp_s' => "margin-right:0.44em;", + 'oa_oqoute_sp_q' => "margin-left:-0.44em;", + ); + + /** + * Базовые параметры тофа + * + * @var array + */ + public $title = "Оптическое выравнивание"; + public $rules = array( + 'oa_oquote' => array( + 'description' => 'Оптическое выравнивание открывающей кавычки', + //'disabled' => true, + 'pattern' => array( + '/([a-zа-яё\-]{3,})(\040|\ \;|\t)(\«\;)/uie', + '/(\n|\r|^)(\«\;)/ei' + ), + 'replacement' => array( + '$m[1] . $this->tag($m[2], "span", array("class"=>"oa_oqoute_sp_s")) . $this->tag($m[3], "span", array("class"=>"oa_oqoute_sp_q"))', + '$m[1] . $this->tag($m[2], "span", array("class"=>"oa_oquote_nl"))', + ), + ), + 'oa_oquote_extra' => array( + 'description' => 'Оптическое выравнивание кавычки', + //'disabled' => true, + 'function' => 'oaquote_extra' + ), + 'oa_obracket_coma' => array( + 'description' => 'Оптическое выравнивание для пунктуации (скобка)', + //'disabled' => true, + 'pattern' => array( + '/(\040|\ \;|\t)\(/ei', + '/(\n|\r|^)\(/ei', + //'/([а-яёa-z0-9]+)\,(\040+)/iue', + ), + 'replacement' => array( + '$this->tag($m[1], "span", array("class"=>"oa_obracket_sp_s")) . $this->tag("(", "span", array("class"=>"oa_obracket_sp_b"))', + '$m[1] . $this->tag("(", "span", array("class"=>"oa_obracket_nl_b"))', + //'$m[1] . $this->tag(",", "span", array("class"=>"oa_comma_b")) . $this->tag(" ", "span", array("class"=>"oa_comma_e"))', + ), + ), + + ); + + /** + * Если стоит открывающая кавычка после

надо делать её висячей + * + * @return void + */ + protected function oaquote_extra() + { + $this->_text = $this->preg_replace_e( + '/(<' .self::BASE64_PARAGRAPH_TAG . '>)([\040\t]+)?(\«\;)/e', + '$m[1] . $this->tag($m[3], "span", array("class"=>"oa_oquote_nl"))', + $this->_text); + } + + +} + +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Punctmark.php b/lib/vendor/emuravjev/mdash/src/Tret/Punctmark.php new file mode 100644 index 0000000..3d13de5 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Punctmark.php @@ -0,0 +1,72 @@ + array( + 'description' => 'Расстановка запятых перед а, но', + 'pattern' => '/([a-zа-яё])(\s| )(но|а)(\s| )/iu', + 'replacement' => '\1,\2\3\4' + ), + 'punctuation_marks_limit' => array( + 'description' => 'Лишние восклицательные, вопросительные знаки и точки', + 'pattern' => '/([\!\.\?]){4,}/', + 'replacement' => '\1\1\1' + ), + 'punctuation_marks_base_limit' => array( + 'description' => 'Лишние запятые, двоеточия, точки с запятой', + 'pattern' => '/([\,]|[\:]|[\;]]){2,}/', + 'replacement' => '\1' + ), + 'hellip' => array( + 'description' => 'Замена трех точек на знак многоточия', + 'simple_replace'=> true, + 'pattern' => '...', + 'replacement' => '…' + ), + 'fix_excl_quest_marks' => array( + 'description' => 'Замена восклицательного и вопросительного знаков местами', + 'pattern' => '/([a-zа-яё0-9])\!\?(\s|$|\<)/ui', + 'replacement' => '\1?!\2' + ), + 'fix_pmarks' => array( + 'description' => 'Замена сдвоенных знаков препинания на одинарные', + 'pattern' => array( + '/([^\!\?])\.\./', + '/([a-zа-яё0-9])(\!|\.)(\!|\.|\?)(\s|$|\<)/ui', + '/([a-zа-яё0-9])(\?)(\?)(\s|$|\<)/ui', + ), + 'replacement' => array( + '\1.', + '\1\2\4', + '\1\2\4' + ), + ), + 'fix_brackets' => array( + 'description' => 'Лишние пробелы после открывающей скобочки и перед закрывающей', + 'pattern' => array('/(\()(\040|\t)+/', '/(\040|\t)+(\))/'), + 'replacement' => array('\1', '\2') + ), + 'fix_brackets_space' => array( + 'description' => 'Пробел перед открывающей скобочкой', + 'pattern' => '/([a-zа-яё])(\()/iu', + 'replacement' => '\1 \2' + ), + 'dot_on_end' => array( + 'description' => 'Точка в конце текста, если её там нет', + 'disabled' => true, + 'pattern' => '/([a-zа-яё0-9])(\040|\t|\ \;)*$/ui', + //'pattern' => '/(([^\.\!\?])|(&(ra|ld)quo;))$/', + 'replacement' => '\1.' + ), + + ); +} diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Quote.php b/lib/vendor/emuravjev/mdash/src/Tret/Quote.php new file mode 100644 index 0000000..ea4c1ee --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Quote.php @@ -0,0 +1,190 @@ + array( + 'description' => 'Кавычки вне тэга ', + //'pattern' => '/(\<%%\_\_.+?\>)\"(.+?)\"(\<\/%%\_\_.+?\>)/s', + 'pattern' => '/(\<%%\_\_[^\>]+\>)\"(.+?)\"(\<\/%%\_\_[^\>]+\>)/s', + 'replacement' => '"\1\2\3"' + ), + + 'open_quote' => array( + 'description' => 'Открывающая кавычка', + 'pattern' => '/(^|\(|\s|\>|-)((\"|\\\")+)(\S+)/iue', + 'replacement' => '$m[1] . str_repeat(self::QUOTE_FIRS_OPEN, substr_count($m[2],"\"") ) . $m[4]' + ), + 'close_quote' => array( + 'description' => 'Закрывающая кавычка', + 'pattern' => '/([a-zа-яё0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:|\+|\%|\@|\#|\$|\*)((\"|\\\")+)(\.|\&hellip\;|\;|\:|\?|\!|\,|\s|\)|\<\/|\<|$)/uie', + 'replacement' => '$m[1] . str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[2],"\"") ) . $m[4]' + ), + 'close_quote_adv' => array( + 'description' => 'Закрывающая кавычка особые случаи', + //'pattern' => '/([a-zа-яё0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:)((\"|\\\"|\«\;)+)(\<.+?\>)(\.|\&hellip\;|\;|\:|\?|\!|\,|\s|\)|\<\/|$)/uie', + 'pattern' => + array( + '/([a-zа-яё0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:|\+|\%|\@|\#|\$|\*)((\"|\\\"|\«\;)+)(\<[^\>]+\>)(\.|\&hellip\;|\;|\:|\?|\!|\,|\)|\<\/|$| )/uie', + '/([a-zа-яё0-9]|\.|\&hellip\;|\!|\?|\>|\)|\:|\+|\%|\@|\#|\$|\*)(\s+)((\"|\\\")+)(\s+)(\.|\&hellip\;|\;|\:|\?|\!|\,|\)|\<\/|$| )/uie', + '/\>(\«\;)\.($|\s|\<)/ui', + '/\>(\«\;),($|\s|\<|\S)/ui', + '/\>(\«\;):($|\s|\<|\S)/ui', + '/\>(\«\;);($|\s|\<|\S)/ui', + '/\>(\«\;)\)($|\s|\<|\S)/ui', + '/((\"|\\\")+)$/uie', + ), + 'replacement' => + array( + '$m[1] . str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[2],"\"")+substr_count($m[2],"«") ) . $m[4]. $m[5]', + '$m[1] .$m[2]. str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[3],"\"")+substr_count($m[3],"«") ) . $m[5]. $m[6]', + '>».\2', + '>»,\2', + '>»:\2', + '>»;\2', + '>»)\2', + 'str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[1],"\"") )', + ), + ), + 'open_quote_adv' => array( + 'description' => 'Открывающая кавычка особые случаи', + 'pattern' => '/(^|\(|\s|\>)(\"|\\\")(\s)(\S+)/iue', + 'replacement' => '$m[1] . self::QUOTE_FIRS_OPEN .$m[4]' + ), + 'close_quote_adv_2' => array( + 'description' => 'Закрывающая кавычка последний шанс', + 'pattern' => '/(\S)((\"|\\\")+)(\.|\&hellip\;|\;|\:|\?|\!|\,|\s|\)|\<\/|\<|$)/uie', + 'replacement' => '$m[1] . str_repeat(self::QUOTE_FIRS_CLOSE, substr_count($m[2],"\"") ) . $m[4]' + ), + 'quotation' => array( + 'description' => 'Внутренние кавычки-лапки и дюймы', + 'function' => 'build_sub_quotations' + ), + ); + + protected function inject_in($pos, $text, &$thetext) + { + for($i=0;$i_text, "")!==false ? "" : (strpos($this->_text,"\r\n")!==false ? "\r\n\r\n" :"\n\n"); + + $texts_in = explode($exp, $this->_text); + $texts_out = array(); + + foreach($texts_in as $textx) { + + $okposstack = array('0'); + $okpos = 0; + $level = 0; + $off = 0; + while(true) + { + $p = Lib::strpos_ex($textx, array("«", "»"), $off); + if($p===false) break; + if($p['str'] == "«") + { + if($level>0) if(!$this->is_on('no_bdquotes')) $this->inject_in($p['pos'], self::QUOTE_CRAWSE_OPEN, $textx); + $level++; + } + if($p['str'] == "»") + { + $level--; + if($level>0) if(!$this->is_on('no_bdquotes')) $this->inject_in($p['pos'], self::QUOTE_CRAWSE_CLOSE, $textx); + } + $off = $p['pos']+strlen($p['str']); + if($level == 0) + { + $okpos = $off; + array_push($okposstack, $okpos); + } elseif($level<0) // уровень стал меньше нуля + { + if(!$this->is_on('no_inches')) + { + do{ + $lokpos = array_pop($okposstack); + $k = substr($textx, $lokpos, $off-$lokpos); + $k = str_replace(self::QUOTE_CRAWSE_OPEN, self::QUOTE_FIRS_OPEN, $k); + $k = str_replace(self::QUOTE_CRAWSE_CLOSE, self::QUOTE_FIRS_CLOSE, $k); + //$k = preg_replace("/(^|[^0-9])([0-9]+)\»\;/ui", '\1\2″', $k, 1, $amount); + + $amount = 0; + $__ax = preg_match_all("/(^|[^0-9])([0-9]+)\»\;/ui", $k, $m); + $__ay = 0; + if($__ax) + { + $k = preg_replace_callback("/(^|[^0-9])([0-9]+)\»\;/ui", + create_function('$m','global $__ax,$__ay; $__ay++; if($__ay==$__ax){ return $m[1].$m[2]."″";} return $m[0];'), + $k); + $amount = 1; + } + + + + } while(($amount==0) && count($okposstack)); + + // успешно сделали замену + if($amount == 1) + { + // заново просмотрим содержимое + $textx = substr($textx, 0, $lokpos). $k . substr($textx, $off); + $off = $lokpos; + $level = 0; + continue; + } + + // иначе просто заменим последнюю явно на " от отчаяния + if($amount == 0) + { + // говорим, что всё в порядке + $level = 0; + $textx = substr($textx, 0, $p['pos']). '"' . substr($textx, $off); + $off = $p['pos'] + strlen('"'); + $okposstack = array($off); + continue; + } + } + } + + + } + // не совпало количество, отменяем все подкавычки + if($level != 0 ){ + + // закрывающих меньше, чем надо + if($level>0) + { + $k = substr($textx, $okpos); + $k = str_replace(self::QUOTE_CRAWSE_OPEN, self::QUOTE_FIRS_OPEN, $k); + $k = str_replace(self::QUOTE_CRAWSE_CLOSE, self::QUOTE_FIRS_CLOSE, $k); + $textx = substr($textx, 0, $okpos). $k; + } + } + $texts_out[] = $textx; + } + $this->_text = implode($exp, $texts_out); + } + +} + +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Space.php b/lib/vendor/emuravjev/mdash/src/Tret/Space.php new file mode 100644 index 0000000..76a1ad3 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Space.php @@ -0,0 +1,103 @@ + 'word-spacing:nowrap;', + ); + + public $rules = array( + 'nobr_twosym_abbr' => array( + 'description' => 'Неразрывный перед 2х символьной аббревиатурой', + 'pattern' => '/([a-zA-Zа-яёА-ЯЁ])(\040|\t)+([A-ZА-ЯЁ]{2})([\s\;\.\?\!\:\(\"]|\&(ra|ld)quo\;|$)/u', + 'replacement' => '\1 \3\4' + ), + 'remove_space_before_punctuationmarks' => array( + 'description' => 'Удаление пробела перед точкой, запятой, двоеточием, точкой с запятой', + 'pattern' => '/((\040|\t|\ \;)+)([\,\:\.\;\?])(\s+|$)/', + 'replacement' => '\3\4' + ), + 'autospace_after_comma' => array( + 'description' => 'Пробел после запятой', + 'pattern' => array( + '/(\040|\t|\ \;)\,([а-яёa-z0-9])/iu', + '/([^0-9])\,([а-яёa-z0-9])/iu', + ), + 'replacement' => array( + ', \2', + '\1, \2' + ), + ), + 'autospace_after_pmarks' => array( + 'description' => 'Пробел после знаков пунктуации, кроме точки', + 'pattern' => '/(\040|\t|\ \;|^|\n)([a-zа-яё0-9]+)(\040|\t|\ \;)?(\:|\)|\,|\&hellip\;|(?:\!|\?)+)([а-яёa-z])/iu', + 'replacement' => '\1\2\4 \5' + ), + 'autospace_after_dot' => array( + 'description' => 'Пробел после точки', + 'pattern' => array( + '/(\040|\t|\ \;|^)([a-zа-яё0-9]+)(\040|\t|\ \;)?\.([а-яёa-z]{5,})($|[^a-zа-яё])/iue', + '/(\040|\t|\ \;|^)([a-zа-яё0-9]+)\.([а-яёa-z]{1,4})($|[^a-zа-яё])/iue', + ), + 'replacement' => array( + //'\1\2. \4', + '$m[1].$m[2]."." .( $m[5] == "." ? "" : " ").$m[4].$m[5]', + '$m[1].$m[2]."." .(in_array(Emuravjev\Mdash\Lib::strtolower($m[3]), $this->domain_zones)? "":( $m[4] == "." ? "" : " ")). $m[3].$m[4]' + ), + ), + 'autospace_after_hellips' => array( + 'description' => 'Пробел после знаков троеточий с вопросительным или восклицательными знаками', + 'pattern' => '/([\?\!]\.\.)([а-яёa-z])/iu', + 'replacement' => '\1 \2' + ), + 'many_spaces_to_one' => array( + 'description' => 'Удаление лишних пробельных символов и табуляций', + 'pattern' => '/(\040|\t)+/', + 'replacement' => ' ' + ), + 'clear_percent' => array( + 'description' => 'Удаление пробела перед символом процента', + 'pattern' => '/(\d+)([\t\040]+)\%/', + 'replacement' => '\1%' + ), + 'nbsp_before_open_quote' => array( + 'description' => 'Неразрывный пробел перед открывающей скобкой', + 'pattern' => '/(^|\040|\t|>)([a-zа-яё]{1,2})\040(\«\;|\&bdquo\;)/u', + 'replacement' => '\1\2 \3' + ), + + 'nbsp_before_month' => array( + 'description' => 'Неразрывный пробел в датах перед числом и месяцем', + 'pattern' => '/(\d)(\s)+(января|февраля|марта|апреля|мая|июня|июля|августа|сентября|октября|ноября|декабря)([^\<]|$)/iu', + 'replacement' => '\1 \3\4' + ), + 'spaces_on_end' => array( + 'description' => 'Удаление пробелов в конце текста', + 'pattern' => '/ +$/', + 'replacement' => '' + ), + 'no_space_posle_hellip' => array( + 'description' => 'Отсутстввие пробела после троеточия после открывающей кавычки', + 'pattern' => '/(\«\;|\&bdquo\;)( |\ \;)?\&hellip\;( |\ \;)?([a-zа-яё])/ui', + 'replacement' => '\1…\4' + ), + 'space_posle_goda' => array( + 'description' => 'Пробел после года', + 'pattern' => '/(^|\040|\ \;)([0-9]{3,4})(год([ауе]|ом)?)([^a-zа-яё]|$)/ui', + 'replacement' => '\1\2 \3\5' + ), + ); +} + +?> diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Symbol.php b/lib/vendor/emuravjev/mdash/src/Tret/Symbol.php new file mode 100644 index 0000000..74ac27b --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Symbol.php @@ -0,0 +1,84 @@ + 'word-spacing:nowrap;', + ); + + public $title = "Специальные символы"; + public $rules = array( + 'tm_replace' => array( + 'description' => 'Замена (tm) на символ торговой марки', + 'pattern' => '/([\040\t])?\(tm\)/i', + 'replacement' => '™' + ), + 'r_sign_replace' => array( + 'description' => 'Замена (R) на символ зарегистрированной торговой марки', + 'pattern' => array( + '/(.|^)\(r\)(.|$)/ie', + //'/([^\>]|^)\(r\)([^\<]|$)/ie', + //'/\>\(r\)\ array( + //'$m[1].$this->tag("®", "sup").$m[2]', + '$m[1]."®".$m[2]', + //'>®<' + ), + ), + 'copy_replace' => array( + 'description' => 'Замена (c) на символ копирайт', + 'pattern' => array( + '/\((c|с)\)\s+/iu', + '/\((c|с)\)($|\.|,|!|\?)/iu', + ), + 'replacement' => array( + '© ', + '©\2', + ), + ), + 'apostrophe' => array( + 'description' => 'Расстановка правильного апострофа в текстах', + 'pattern' => '/(\s|^|\>|\&rsquo\;)([a-zа-яё]{1,})\'([a-zа-яё]+)/ui', + 'replacement' => '\1\2’\3', + 'cycled' => true + ), + /* + 'ru_apostrophe' => array( + 'description' => 'Расстановка правильного апострофа в русских текстах', + 'pattern' => '/(\s|^|\>)([а-яё]+)\'([а-яё]+)/iu', + 'replacement' => '\1\2’\3' + ), + */ + 'degree_f' => array( + 'description' => 'Градусы по Фаренгейту', + 'pattern' => '/([0-9]+)F($|\s|\.|\,|\;|\:|\ \;|\?|\!)/eu', + 'replacement' => '"".$this->tag($m[1]." °F","span", array("class"=>"nowrap")) .$m[2]' + ), + 'euro_symbol' => array( + 'description' => 'Символ евро', + 'simple_replace' => true, + 'pattern' => '€', + 'replacement' => '€' + ), + 'arrows_symbols' => array( + 'description' => 'Замена стрелок вправо-влево на html коды', + //'pattern' => array('/(\s|\>|\ \;|^)\-\>($|\s|\ \;|\<)/', '/(\s|\>|\ \;|^|;)\<\-(\s|\ \;|$|\<)/', '/→/u', '/←/u'), + //'pattern' => array('/\-\>($|\s|\ \;|\<)/', '/(\s|\>|\ \;|^|;)\<\-(\s|\ \;|$|\<)/', '/→/u', '/←/u'), + 'pattern' => array('/\-\>/', '/\<\-/', '/→/u', '/←/u'), + //'replacement' => array('\1→\2', '\1←\2', '→', '←' ), + 'replacement' => array('→', '←', '→', '←' ), + ), + ); +} diff --git a/lib/vendor/emuravjev/mdash/src/Tret/Text.php b/lib/vendor/emuravjev/mdash/src/Tret/Text.php new file mode 100644 index 0000000..809d576 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Tret/Text.php @@ -0,0 +1,114 @@ + 'word-spacing:nowrap;', + ); + + /** + * Базовые параметры тофа + * + * @var array + */ + public $title = "Текст и абзацы"; + public $rules = array( + 'auto_links' => array( + 'description' => 'Выделение ссылок из текста', + 'pattern' => '/(\s|^)(http|ftp|mailto|https)(:\/\/)([^\s\,\!\<]{4,})(\s|\.|\,|\!|\?|\<|$)/ieu', + 'replacement' => '$m[1] . $this->tag((substr($m[4],-1)=="."?substr($m[4],0,-1):$m[4]), "a", array("href" => $m[2].$m[3].(substr($m[4],-1)=="."?substr($m[4],0,-1):$m[4]))) . (substr($m[4],-1)=="."?".":"") .$m[5]' + ), + 'email' => array( + 'description' => 'Выделение эл. почты из текста', + 'pattern' => '/(\s|^|\ \;|\()([a-z0-9\-\_\.]{2,})\@([a-z0-9\-\.]{2,})\.([a-z]{2,6})(\)|\s|\.|\,|\!|\?|$|\<)/e', + 'replacement' => '$m[1] . $this->tag($m[2]."@".$m[3].".".$m[4], "a", array("href" => "mailto:".$m[2]."@".$m[3].".".$m[4])) . $m[5]' + ), + 'no_repeat_words' => array( + 'description' => 'Удаление повторяющихся слов', + 'disabled' => true, + 'pattern' => array( + '/([а-яё]{3,})( |\t|\ \;)\1/iu', + '/(\s|\ \;|^|\.|\!|\?)(([А-ЯЁ])([а-яё]{2,}))( |\t|\ \;)(([а-яё])\4)/eu', + ), + 'replacement' => array( + '\1', + '$m[1].($m[7] === Emuravjev\Mdash\Lib::strtolower($m[3]) ? $m[2] : $m[2].$m[5].$m[6] )', + ) + ), + 'paragraphs' => array( + 'description' => 'Простановка параграфов', + 'function' => 'build_paragraphs' + ), + 'breakline' => array( + 'description' => 'Простановка переносов строк', + 'function' => 'build_brs' + ), + + ); + + /** + * Расстановка защищенных тегов параграфа (

...

) и переноса строки + * + * @return void + */ + protected function do_paragraphs($text) { + $text = str_replace("\r\n","\n",$text); + $text = str_replace("\r","\n",$text); + $text = '<' . self::BASE64_PARAGRAPH_TAG . '>' . trim($text) . ''; + //$text = $this->preg_replace_e('/([\040\t]+)?(\n|\r){2,}/e', '"<" .self::BASE64_PARAGRAPH_TAG . ">"', $text); + //$text = $this->preg_replace_e('/([\040\t]+)?(\n){2,}/e', '"<" .self::BASE64_PARAGRAPH_TAG . ">"', $text); + $text = $this->preg_replace_e('/([\040\t]+)?(\n)+([\040\t]*)(\n)+/e', '$m[1]."".Emuravjev\Mdash\Lib::iblock($m[2].$m[3])."<" .self::BASE64_PARAGRAPH_TAG . ">"', $text); + //$text = $this->preg_replace_e('/([\040\t]+)?(\n)+([\040\t]*)(\n)+/e', '""."<" .self::BASE64_PARAGRAPH_TAG . ">"', $text); + //может от открвающего до закрывающего ?! + $text = preg_replace('/\<' . self::BASE64_PARAGRAPH_TAG . '\>('.Lib::INTERNAL_BLOCK_OPEN.'[a-zA-Z0-9\/=]+?'.Lib::INTERNAL_BLOCK_CLOSE.')?\<\/' . self::BASE64_PARAGRAPH_TAG . '\>/s', "", $text); + return $text; + } + + /** + * Расстановка защищенных тегов параграфа (

...

) и переноса строки + * + * @return void + */ + protected function build_paragraphs() + { + $r = mb_strpos($this->_text, '<' . self::BASE64_PARAGRAPH_TAG . '>' ); + $p = Lib::rstrpos($this->_text, '' ) ; + if(($r!== false) && ($p !== false)) { + + $beg = mb_substr($this->_text,0,$r); + $end = mb_substr($this->_text,$p+mb_strlen('')); + $this->_text = + (trim($beg) ? $this->do_paragraphs($beg). "\n":"") .'<' . self::BASE64_PARAGRAPH_TAG . '>'. + mb_substr($this->_text,$r + mb_strlen('<' . self::BASE64_PARAGRAPH_TAG . '>'),$p -($r + mb_strlen('<' . self::BASE64_PARAGRAPH_TAG . '>')) ).''. + (trim($end) ? "\n".$this->do_paragraphs($end) :"") ; + } else { + $this->_text = $this->do_paragraphs($this->_text); + } + } + + /** + * Расстановка защищенных тегов параграфа (

...

) и переноса строки + * + * @return void + */ + protected function build_brs() + { + $this->_text = $this->preg_replace_e('/(\<\/' . self::BASE64_PARAGRAPH_TAG . '\>)([\r\n \t]+)(\<' . self::BASE64_PARAGRAPH_TAG . '\>)/mse', '$m[1].Emuravjev\Mdash\Lib::iblock($m[2]).$m[3]', $this->_text); + + if (!preg_match('/\<' . self::BASE64_BREAKLINE_TAG . '\>/', $this->_text)) { + $this->_text = str_replace("\r\n","\n",$this->_text); + $this->_text = str_replace("\r","\n",$this->_text); + //$this->_text = $this->preg_replace_e('/(\n|\r)/e', '"<" . self::BASE64_BREAKLINE_TAG . ">"', $this->_text); + $this->_text = $this->preg_replace_e('/(\n)/e', '"<" . self::BASE64_BREAKLINE_TAG . ">\n"', $this->_text); + } + } +} +?> diff --git a/lib/vendor/emuravjev/mdash/src/Typograph.php b/lib/vendor/emuravjev/mdash/src/Typograph.php new file mode 100644 index 0000000..d8b2036 --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/Typograph.php @@ -0,0 +1,222 @@ + true, + 'Dash' => true, + 'Nobr' => true, + 'Symbol' => true, + 'Punctmark' => true, + 'Number' => true, + 'Date' => true, + 'Space' => true, + 'Abbr' => true, + 'OptAlign' => true, + 'Text' => true, + 'Etc' => true, + ); + protected $all_options = array( + + 'Quote.quotes' => array( 'description' => 'Расстановка «кавычек-елочек» первого уровня', 'selector' => "Quote.*quote" ), + 'Quote.quotation' => array( 'description' => 'Внутренние кавычки-лапки', 'selector' => "Quote", 'setting' => 'no_bdquotes', 'reversed' => true ), + + 'Dash.to_libo_nibud' => 'direct', + 'Dash.iz_za_pod' => 'direct', + 'Dash.ka_de_kas' => 'direct', + + 'Nobr.super_nbsp' => 'direct', + 'Nobr.nbsp_in_the_end' => 'direct', + 'Nobr.phone_builder' => 'direct', + 'Nobr.phone_builder_v2' => 'direct', + 'Nobr.ip_address' => 'direct', + 'Nobr.spaces_nobr_in_surname_abbr' => 'direct', + 'Nobr.dots_for_surname_abbr' => 'direct', + 'Nobr.nbsp_celcius' => 'direct', + 'Nobr.hyphen_nowrap_in_small_words' => 'direct', + 'Nobr.hyphen_nowrap' => 'direct', + 'Nobr.nowrap' => array('description' => 'Nobr (по умолчанию) & nowrap', 'disabled' => true, 'selector' => '*', 'setting' => 'nowrap' ), + + 'Symbol.tm_replace' => 'direct', + 'Symbol.r_sign_replace' => 'direct', + 'Symbol.copy_replace' => 'direct', + 'Symbol.apostrophe' => 'direct', + 'Symbol.degree_f' => 'direct', + 'Symbol.arrows_symbols' => 'direct', + 'Symbol.no_inches' => array( 'description' => 'Расстановка дюйма после числа', 'selector' => "Quote", 'setting' => 'no_inches', 'reversed' => true ), + + 'Punctmark.auto_comma' => 'direct', + 'Punctmark.hellip' => 'direct', + 'Punctmark.fix_pmarks' => 'direct', + 'Punctmark.fix_excl_quest_marks' => 'direct', + 'Punctmark.dot_on_end' => 'direct', + + 'Number.minus_between_nums' => 'direct', + 'Number.minus_in_numbers_range' => 'direct', + 'Number.auto_times_x' => 'direct', + 'Number.simple_fraction' => 'direct', + 'Number.math_chars' => 'direct', + 'Number.thinsp_between_number_triads' => 'direct', + 'Number.thinsp_between_no_and_number' => 'direct', + 'Number.thinsp_between_sect_and_number' => 'direct', + + 'Date.years' => 'direct', + 'Date.mdash_month_interval' => 'direct', + 'Date.nbsp_and_dash_month_interval' => 'direct', + 'Date.nobr_year_in_date' => 'direct', + + 'Space.many_spaces_to_one' => 'direct', + 'Space.clear_percent' => 'direct', + 'Space.clear_before_after_punct' => array( 'description' => 'Удаление пробелов перед и после знаков препинания в предложении', 'selector' => 'Space.remove_space_before_punctuationmarks'), + 'Space.autospace_after' => array( 'description' => 'Расстановка пробелов после знаков препинания', 'selector' => 'Space.autospace_after_*'), + 'Space.bracket_fix' => array( 'description' => 'Удаление пробелов внутри скобок, а также расстановка пробела перед скобками', + 'selector' => array('Space.nbsp_before_open_quote', 'Punctmark.fix_brackets')), + + 'Abbr.nbsp_money_abbr' => array( 'description' => 'Форматирование денежных сокращений (расстановка пробелов и привязка названия валюты к числу)', + 'selector' => array('Abbr.nbsp_money_abbr', 'Abbr.nbsp_money_abbr_rev')), + 'Abbr.nobr_vtch_itd_itp' => 'direct', + 'Abbr.nobr_sm_im' => 'direct', + 'Abbr.nobr_acronym' => 'direct', + 'Abbr.nobr_locations' => 'direct', + 'Abbr.nobr_abbreviation' => 'direct', + 'Abbr.ps_pps' => 'direct', + 'Abbr.nbsp_org_abbr' => 'direct', + 'Abbr.nobr_gost' => 'direct', + 'Abbr.nobr_before_unit_volt' => 'direct', + 'Abbr.nbsp_before_unit' => 'direct', + + 'OptAlign.all' => array( 'description' => 'Все настройки оптического выравнивания', 'hide' => true, 'selector' => 'OptAlign.*'), + 'OptAlign.oa_oquote' => 'direct', + 'OptAlign.oa_obracket_coma' => 'direct', + 'OptAlign.oa_oquote_extra' => 'direct', + 'OptAlign.layout' => array( 'description' => 'Inline стили или CSS' ), + + 'Text.paragraphs' => 'direct', + 'Text.auto_links' => 'direct', + 'Text.email' => 'direct', + 'Text.breakline' => 'direct', + 'Text.no_repeat_words' => 'direct', + + + //'Etc.no_nbsp_in_nobr' => 'direct', + 'Etc.unicode_convert' => array('description' => 'Преобразовывать html-сущности в юникод', 'selector' => array('*', 'Etc.nobr_to_nbsp'), 'setting' => array('dounicode','active'), 'exact_selector' => true ,'disabled' => true), + 'Etc.nobr_to_nbsp' => 'direct', + 'Etc.split_number_to_triads' => 'direct', + + ); + + /** + * Получить список имеющихся опций + * + * @return array + * all - полный список + * group - сгруппированный по группам + */ + public function get_options_list() + { + $arr['all'] = array(); + $bygroup = array(); + foreach($this->all_options as $opt => $op) + { + $arr['all'][$opt] = $this->get_option_info($opt); + $x = explode(".",$opt); + $bygroup[$x[0]][] = $opt; + } + $arr['group'] = array(); + foreach($this->group_list as $group => $ginfo) + { + if($ginfo === true) + { + $tret = $this->get_tret($group); + if($tret) $info['title'] = $tret->title; else $info['title'] = "Не определено"; + } else { + $info = $ginfo; + } + $info['name'] = $group; + $info['options'] = array(); + if(is_array($bygroup[$group])) foreach($bygroup[$group] as $opt) $info['options'][] = $opt; + $arr['group'][] = $info; + } + return $arr; + } + + + /** + * Получить информацию о настройке + * + * @param string $key + * @return array|false + */ + protected function get_option_info($key) + { + if(!isset($this->all_options[$key])) return false; + if(is_array($this->all_options[$key])) return $this->all_options[$key]; + + if(($this->all_options[$key] == "direct") || ($this->all_options[$key] == "reverse")) + { + $pa = explode(".", $key); + $tret_pattern = $pa[0]; + $tret = $this->get_tret($tret_pattern); + if(!$tret) return false; + if(!isset($tret->rules[$pa[1]])) return false; + $array = $tret->rules[$pa[1]]; + $array['way'] = $this->all_options[$key]; + return $array; + } + return false; + } + + + /** + * Установка одной метанастройки + * + * @param string $name + * @param mixed $value + */ + public function do_setup($name, $value) + { + if(!isset($this->all_options[$name])) return; + + // эта настрока связана с правилом ядра + if(is_string($this->all_options[$name])) + { + $this->set($name, "active", $value ); + return ; + } + if(is_array($this->all_options[$name])) + { + if(isset($this->all_options[$name]['selector'])) + { + $settingname = "active"; + if(isset($this->all_options[$name]['setting'])) $settingname = $this->all_options[$name]['setting']; + $this->set($this->all_options[$name]['selector'], $settingname, $value, isset($this->all_options[$name]['exact_selector'])); + } + } + + if($name == "OptAlign.layout") + { + if($value == "style") $this->set_tag_layout(Lib::LAYOUT_STYLE); + if($value == "class") $this->set_tag_layout(Lib::LAYOUT_CLASS); + } + + } + + /** + * Запустить типограф со стандартными параметрами + * + * @param string $text + * @param array $options + * @return string + */ + public static function fast_apply($text, $options = null) + { + $obj = new self(); + if(is_array($options)) $obj->setup($options); + $obj->set_text($text); + return $obj->apply(); + } +} diff --git a/lib/vendor/emuravjev/mdash/src/TypographBase.php b/lib/vendor/emuravjev/mdash/src/TypographBase.php new file mode 100644 index 0000000..81426ef --- /dev/null +++ b/lib/vendor/emuravjev/mdash/src/TypographBase.php @@ -0,0 +1,745 @@ +logging) return; + $this->logs[] = array('class' => '', 'info' => $str, 'data' => $data); + } + + protected function tret_log($tret, $str, $data = null) + { + $this->logs[] = array('class' => $tret, 'info' => $str, 'data' => $data); + } + + protected function error($info, $data = null) + { + $this->errors[] = array('class' => '', 'info' => $info, 'data' => $data); + $this->log("ERROR $info", $data ); + } + + protected function tret_error($tret, $info, $data = null) + { + $this->errors[] = array('class' => $tret, 'info' => $info, 'data' => $data); + } + + protected function debug($class, $place, &$after_text, $after_text_raw = "") + { + if(!$this->debug_enabled) return; + $this->debug_info[] = array( + 'tret' => $class == $this ? false: true, + 'class' => is_object($class)? get_class($class) : $class, + 'place' => $place, + 'text' => $after_text, + 'text_raw' => $after_text_raw, + ); + } + + + + protected $_safe_blocks = array(); + + + /** + * Включить режим отладки, чтобы посмотреть последовательность вызовов + * третов и правил после + * + */ + public function debug_on() + { + $this->debug_enabled = true; + } + + /** + * Включить режим отладки, чтобы посмотреть последовательность вызовов + * третов и правил после + * + */ + public function log_on() + { + $this->logging = true; + } + + /** + * Добавление защищенного блока + * + * + * Jare_Typograph_Tool::addCustomBlocks('', ''); + * Jare_Typograph_Tool::addCustomBlocks('\', '\<\/span\>', true); + * + * + * @param string $id идентификатор + * @param string $open начало блока + * @param string $close конец защищенного блока + * @param string $tag тэг + * @return void + */ + private function _add_safe_block($id, $open, $close, $tag) + { + $this->_safe_blocks[] = array( + 'id' => $id, + 'tag' => $tag, + 'open' => $open, + 'close' => $close, + ); + } + + /** + * Список защищенных блоков + * + * @return array + */ + public function get_all_safe_blocks() + { + return $this->_safe_blocks; + } + + /** + * Удаленного блока по его номеру ключа + * + * @param string $id идентифиактор защищённого блока + * @return void + */ + public function remove_safe_block($id) + { + foreach($this->_safe_blocks as $k => $block) { + if($block['id']==$id) unset($this->_safe_blocks[$k]); + } + } + + + /** + * Добавление защищенного блока + * + * @param string $tag тэг, который должен быть защищён + * @return void + */ + public function add_safe_tag($tag) + { + $open = preg_quote("<", '/'). $tag."[^>]*?" . preg_quote(">", '/'); + $close = preg_quote("", '/'); + $this->_add_safe_block($tag, $open, $close, $tag); + return true; + } + + + /** + * Добавление защищенного блока + * + * @param string $open начало блока + * @param string $close конец защищенного блока + * @param bool $quoted специальные символы в начале и конце блока экранированы + * @return void + */ + public function add_safe_block($id, $open, $close, $quoted = false) + { + $open = trim($open); + $close = trim($close); + + if (empty($open) || empty($close)) + { + return false; + } + + if (false === $quoted) + { + $open = preg_quote($open, '/'); + $close = preg_quote($close, '/'); + } + + $this->_add_safe_block($id, $open, $close, ""); + return true; + } + + + /** + * Сохранение содержимого защищенных блоков + * + * @param string $text + * @param bool $safe если true, то содержимое блоков будет сохранено, иначе - раскодировано. + * @return string + */ + public function safe_blocks($text, $way, $show = true) + { + if (count($this->_safe_blocks)) + { + $safeType = true === $way ? "Lib::encrypt_tag(\$m[2])" : "stripslashes(Lib::decrypt_tag(\$m[2]))"; + $safeblocks = true === $way ? $this->_safe_blocks : array_reverse($this->_safe_blocks); + foreach ($safeblocks as $block) + { + $text = preg_replace_callback("/({$block['open']})(.+?)({$block['close']})/s", create_function('$m','return $m[1].'.$safeType . '.$m[3];') , $text); + } + } + + return $text; + } + + + /** + * Декодирование блоков, которые были скрыты в момент типографирования + * + * @param string $text + * @return string + */ + public function decode_internal_blocks($text) + { + return Lib::decode_internal_blocks($text); + } + + + private function create_object($tret) + { + $tret = "Emuravjev\\Mdash\\Tret\\" . $tret; + + if(!class_exists($tret)) + { + $this->error("Класс $tret не найден. Пожалуйста, подргузите нужный файл."); + return null; + } + + $obj = new $tret(); + $obj->EMT = $this; + $obj->logging = $this->logging; + return $obj; + } + + private function get_short_tret($tretname) + { + if(preg_match("/^EMT_Tret_([a-zA-Z0-9_]+)$/",$tretname, $m)) + { + return $m[1]; + } + return $tretname; + } + + private function _init() + { + foreach($this->trets as $tret) + { + if(isset($this->tret_objects[$tret])) continue; + $obj = $this->create_object($tret); + if($obj == null) continue; + $this->tret_objects[$tret] = $obj; + } + + if(!$this->inited) + { + $this->add_safe_tag('pre'); + $this->add_safe_tag('script'); + $this->add_safe_tag('style'); + $this->add_safe_tag('notg'); + $this->add_safe_block('span-notg', '', ''); + } + $this->inited = true; + } + + + + + + /** + * Инициализация класса, используется чтобы задать список третов или + * список защищённых блоков, которые можно использовать. + * Также здесь можно отменить защищённые блоки по умлочнаию + * + */ + public function init() + { + + } + + /** + * Добавить Трэт, + * + * @param mixed $class - имя класса трета, или сам объект + * @param string $altname - альтернативное имя, если хотим например иметь два одинаоковых терта в обработке + * @return mixed + */ + public function add_tret($class, $altname = false) + { + if(is_object($class)) + { + if(!is_a($class, "Tret\Base")) + { + $this->error("You are adding Tret that doesn't inherit base class Tret\Base", get_class($class)); + return false; + } + + $class->EMT = $this; + $class->logging = $this->logging; + $this->tret_objects[($altname ? $altname : get_class($class))] = $class; + $this->trets[] = ($altname ? $altname : get_class($class)); + return true; + } + if(is_string($class)) + { + $obj = $this->create_object($class); + if($obj === null) + return false; + $this->tret_objects[($altname ? $altname : $class)] = $obj; + $this->trets[] = ($altname ? $altname : $class); + return true; + } + $this->error("Чтобы добавить трэт необходимо передать имя или объект"); + return false; + } + + /** + * Получаем ТРЕТ по идентификатору, т.е. названию класса + * + * @param mixed $name + */ + public function get_tret($name) + { + if(isset($this->tret_objects[$name])) return $this->tret_objects[$name]; + foreach($this->trets as $tret) + { + if($tret == $name) + { + $this->_init(); + return $this->tret_objects[$name]; + } + if($this->get_short_tret($tret) == $name) + { + $this->_init(); + return $this->tret_objects[$tret]; + } + } + $this->error("Трэт с идентификатором $name не найден"); + return false; + } + + /** + * Задаём текст для применения типографа + * + * @param string $text + */ + public function set_text($text) + { + $this->_text = $text; + } + + + + /** + * Запустить типограф на выполнение + * + */ + public function apply($trets = null) + { + $this->ok = false; + + $this->init(); + $this->_init(); + + $atrets = $this->trets; + if(is_string($trets)) $atrets = array($trets); + elseif(is_array($trets)) $atrets = $trets; + + $this->debug($this, 'init', $this->_text); + + $this->_text = $this->safe_blocks($this->_text, true); + $this->debug($this, 'safe_blocks', $this->_text); + + $this->_text = Lib::safe_tag_chars($this->_text, true); + $this->debug($this, 'safe_tag_chars', $this->_text); + + $this->_text = Lib::clear_special_chars($this->_text); + $this->debug($this, 'clear_special_chars', $this->_text); + + foreach ($atrets as $tret) + { + // если установлен режим разметки тэгов то выставим его + if($this->use_layout_set) + $this->tret_objects[$tret]->set_tag_layout_ifnotset($this->use_layout); + + if($this->class_layout_prefix) + $this->tret_objects[$tret]->set_class_layout_prefix($this->class_layout_prefix); + + // влючаем, если нужно + if($this->debug_enabled) $this->tret_objects[$tret]->debug_on(); + if($this->logging) $this->tret_objects[$tret]->logging = true; + + // применяем трэт + //$this->tret_objects[$tret]->set_text(&$this->_text); + $this->tret_objects[$tret]->set_text($this->_text); + $this->tret_objects[$tret]->apply(); + + // соберём ошибки если таковые есть + if(count($this->tret_objects[$tret]->errors)>0) + foreach($this->tret_objects[$tret]->errors as $err ) + $this->tret_error($tret, $err['info'], $err['data']); + + // логгирование + if($this->logging) + if(count($this->tret_objects[$tret]->logs)>0) + foreach($this->tret_objects[$tret]->logs as $log ) + $this->tret_log($tret, $log['info'], $log['data']); + + // отладка + if($this->debug_enabled) { + foreach($this->tret_objects[$tret]->debug_info as $di) + { + $unsafetext = $di['text']; + $unsafetext = Lib::safe_tag_chars($unsafetext, false); + $unsafetext = $this->safe_blocks($unsafetext, false); + $this->debug($tret, $di['place'], $unsafetext, $di['text']); + } + } + } + + + $this->_text = $this->decode_internal_blocks($this->_text); + $this->debug($this, 'decode_internal_blocks', $this->_text); + + if($this->is_on('dounicode')) + { + Lib::convert_html_entities_to_unicode($this->_text); + } + + $this->_text = Lib::safe_tag_chars($this->_text, false); + $this->debug($this, 'unsafe_tag_chars', $this->_text); + + $this->_text = $this->safe_blocks($this->_text, false); + $this->debug($this, 'unsafe_blocks', $this->_text); + + if(!$this->disable_notg_replace) + { + $repl = array('', ''); + if($this->remove_notg) $repl = ""; + $this->_text = str_replace( array('',''), $repl , $this->_text); + } + $this->_text = trim($this->_text); + $this->ok = (count($this->errors)==0); + return $this->_text; + } + + /** + * Получить содержимое при использовании классов + * + * @param bool $list false - вернуть в виде строки для style или как массив + * @param bool $compact не выводить пустые классы + * @return string|array + */ + public function get_style($list = false, $compact = false) + { + $this->_init(); + + $res = array(); + foreach ($this->trets as $tret) + { + $arr =$this->tret_objects[$tret]->classes; + if(!is_array($arr)) continue; + foreach($arr as $classname => $str) + { + if(($compact) && (!$str)) continue; + $clsname = ($this->class_layout_prefix ? $this->class_layout_prefix : "" ).(isset($this->tret_objects[$tret]->class_names[$classname]) ? $this->tret_objects[$tret]->class_names[$classname] :$classname); + $res[$clsname] = $str; + } + } + if($list) return $res; + $str = ""; + foreach($res as $k => $v) + { + $str .= ".$k { $v }\n"; + } + return $str; + } + + + + + + /** + * Установить режим разметки, + * Lib::LAYOUT_STYLE - с помощью стилей + * Lib::LAYOUT_CLASS - с помощью классов + * Lib::LAYOUT_STYLE|Lib::LAYOUT_CLASS - оба метода + * + * @param int $layout + */ + public function set_tag_layout($layout = Lib::LAYOUT_STYLE) + { + $this->use_layout = $layout; + $this->use_layout_set = true; + } + + /** + * Установить префикс для классов + * + * @param string|bool $prefix если true то префикс 'emt_', иначе то, что передали + */ + public function set_class_layout_prefix($prefix ) + { + $this->class_layout_prefix = $prefix === true ? "emt_" : $prefix; + } + + /** + * Включить/отключить правила, согласно карте + * Формат карты: + * 'Название трэта 1' => array ( 'правило1', 'правило2' , ... ) + * 'Название трэта 2' => array ( 'правило1', 'правило2' , ... ) + * + * @param array $map + * @param bool $disable если ложно, то $map соотвествует тем правилам, которые надо включить + * иначе это список правил, которые надо выключить + * @param bool $strict строго, т.е. те которые не в списке будут тоже обработаны + */ + public function set_enable_map($map, $disable = false, $strict = true) + { + if(!is_array($map)) return; + $trets = array(); + foreach($map as $tret => $list) + { + $tretx = $this->get_tret($tret); + if(!$tretx) + { + $this->log("Трэт $tret не найден при применении карты включаемых правил"); + continue; + } + $trets[] = $tretx; + + if($list === true) // все + { + $tretx->activate(array(), !$disable , true); + } elseif(is_string($list)) { + $tretx->activate(array($list), $disable , $strict); + } elseif(is_array($list)) { + $tretx->activate($list, $disable , $strict); + } + } + if($strict) + { + foreach($this->trets as $tret) + { + if(in_array($this->tret_objects[$tret], $trets)) continue; + $this->tret_objects[$tret]->activate(array(), $disable , true); + } + } + + } + + + /** + * Установлена ли настройка + * + * @param string $key + */ + public function is_on($key) + { + if(!isset($this->settings[$key])) return false; + $kk = $this->settings[$key]; + return ((strtolower($kk)=="on") || ($kk === "1") || ($kk === true) || ($kk === 1)); + } + + + /** + * Установить настройку + * + * @param mixed $selector + * @param string $setting + * @param mixed $value + */ + protected function doset($selector, $key, $value) + { + $tret_pattern = false; + $rule_pattern = false; + //if(($selector === false) || ($selector === null) || ($selector === false) || ($selector === "*")) $type = 0; + if(is_string($selector)) + { + if(strpos($selector,".")===false) + { + $tret_pattern = $selector; + } else { + $pa = explode(".", $selector); + $tret_pattern = $pa[0]; + array_shift($pa); + $rule_pattern = implode(".", $pa); + } + } + Lib::_process_selector_pattern($tret_pattern); + Lib::_process_selector_pattern($rule_pattern); + if($selector == "*") $this->settings[$key] = $value; + + foreach ($this->trets as $tret) + { + $t1 = $this->get_short_tret($tret); + if(!Lib::_test_pattern($tret_pattern, $t1)) if(!Lib::_test_pattern($tret_pattern, $tret)) continue; + $tret_obj = $this->get_tret($tret); + if($key == "active") + { + foreach($tret_obj->rules as $rulename => $v) + { + if(!Lib::_test_pattern($rule_pattern, $rulename)) continue; + if((strtolower($value) === "on") || ($value===1) || ($value === true) || ($value=="1")) $tret_obj->enable_rule($rulename); + if((strtolower($value) === "off") || ($value===0) || ($value === false) || ($value=="0")) $tret_obj->disable_rule($rulename); + } + } else { + if($rule_pattern===false) + { + $tret_obj->set($key, $value); + } else { + foreach($tret_obj->rules as $rulename => $v) + { + if(!Lib::_test_pattern($rule_pattern, $rulename)) continue; + $tret_obj->set_rule($rulename, $key, $value); + } + } + } + } + } + + + /** + * Установить настройки для тертов и правил + * 1. если селектор является массивом, то тогда установка правил будет выполнена для каждого + * элемента этого массива, как отдельного селектора. + * 2. Если $key не является массивом, то эта настройка будет проставлена согласно селектору + * 3. Если $key массив - то будет задана группа настроек + * - если $value массив , то настройки определяются по ключам из массива $key, а значения из $value + * - иначе, $key содержит ключ-значение как массив + * 4. $exact_match - если true тогда array selector будет соответсвовать array $key, а не произведению массивов + * + * @param mixed $selector + * @param mixed $key + * @param mixed $value + * @param mixed $exact_match + */ + public function set($selector, $key , $value = false, $exact_match = false) + { + if($exact_match && is_array($selector) && is_array($key) && count($selector)==count($key)) { + $idx = 0; + foreach($key as $x => $y){ + if(is_array($value)) + { + $kk = $y; + $vv = $value[$x]; + } else { + $kk = ( $value ? $y : $x ); + $vv = ( $value ? $value : $y ); + } + $this->set($selector[$idx], $kk , $vv); + $idx++; + } + return ; + } + if(is_array($selector)) + { + foreach($selector as $val) $this->set($val, $key, $value); + return; + } + if(is_array($key)) + { + foreach($key as $x => $y) + { + if(is_array($value)) + { + $kk = $y; + $vv = $value[$x]; + } else { + $kk = ( $value ? $y : $x ); + $vv = ( $value ? $value : $y ); + } + $this->set($selector, $kk, $vv); + } + return ; + } + $this->doset($selector, $key, $value); + } + + + /** + * Возвращает список текущих третов, которые установлены + * + */ + public function get_trets_list() + { + return $this->trets; + } + + /** + * Установка одной метанастройки + * + * @param string $name + * @param mixed $value + */ + public function do_setup($name, $value) + { + + } + + + /** + * Установить настройки + * + * @param array $setupmap + */ + public function setup($setupmap) + { + if(!is_array($setupmap)) return; + + if(isset($setupmap['map']) || isset($setupmap['maps'])) + { + if(isset($setupmap['map'])) + { + $ret['map'] = $test['params']['map']; + $ret['disable'] = $test['params']['map_disable']; + $ret['strict'] = $test['params']['map_strict']; + $test['params']['maps'] = array($ret); + unset($setupmap['map']); + unset($setupmap['map_disable']); + unset($setupmap['map_strict']); + } + if(is_array($setupmap['maps'])) + { + foreach($setupmap['maps'] as $map) + { + $this->set_enable_map + ($map['map'], + isset($map['disable']) ? $map['disable'] : false, + isset($map['strict']) ? $map['strict'] : false + ); + } + } + unset($setupmap['maps']); + } + + + foreach($setupmap as $k => $v) $this->do_setup($k , $v); + } +} diff --git a/lib/vendor/visavi/cleanup/cleanup b/lib/vendor/visavi/cleanup/cleanup new file mode 100644 index 0000000..53e4398 --- /dev/null +++ b/lib/vendor/visavi/cleanup/cleanup @@ -0,0 +1,173 @@ +#!/usr/bin/env php + $value) { + $options[$key[0]] = $value; +} + +echo 'Cleanup v' . $version . PHP_EOL . PHP_EOL; + +if (isset($options['h'])) { + echo "\e[0;33mUsage:\e[0m" . PHP_EOL; + echo ' command [options] [arguments]' . PHP_EOL . PHP_EOL; + + echo "\e[0;33mOptions:\e[0m" . PHP_EOL; + echo " \e[0;32m-h, --help \e[0m Display this help message" . PHP_EOL; + echo " \e[0;32m-i, --include \e[0m Add patterns for common files, comma separated" . PHP_EOL; + echo " \e[0;32m-e, --exclude \e[0m Remove patterns for common files, comma separated" . PHP_EOL; + echo " \e[0;32m-v, --verbose \e[0m Increase the verbosity of messages" . PHP_EOL; + echo " \e[0;32m-p, --path \e[0m Find on specific path" . PHP_EOL; + echo " \e[0;32m-d, --dry \e[0m Run without actual remove" . PHP_EOL . PHP_EOL; + + echo "\e[0;33mExample:\e[0m" . PHP_EOL; + echo ' ./vendor/bin/cleanup -v --path symfony --include *.zip,*.rar --exclude doc,docs,test' . PHP_EOL; + return; +} + +// Default patterns for common files +$patterns = [ + '.git', + '.github', + 'test', + 'tests', + 'travis', + 'demo', + 'example', + 'examples', + 'doc', + 'docs', + 'license', + 'changelog*', + 'changes*', + 'faq*', + 'contributing*', + 'history*', + 'upgrading*', + 'upgrade*', + 'readme*', + '{,.}*.yml', + '*.md', + '*.xml', + '*.txt', + '*.dist', + '*.neon', + '.php_cs*', + '.scrutinizer', + '.gitignore', + '.gitattributes', + '.editorconfig', + '.phpstorm.meta.php', + 'dockerfile', + 'composer.lock', +]; + +$dirname = dirname(__DIR__, 2); + +if (isset($options['p'])) { + $dirname .= '/' . $options['p']; + + if (! file_exists($dirname)) { + echo 'Directory not found!' . PHP_EOL; + return; + } +} + +if (isset($options['i'])) { + $patterns = array_merge($patterns, explode(',', $options['i'])); +} + +if (isset($options['e'])) { + $patterns = array_diff($patterns, explode(',', $options['e'])); +} + +/** + * Recursively traverses the directory tree + * + * @param string $dirname + * @return array + */ +function expandTree($dirname) +{ + $directories = []; + $files = array_diff(scandir($dirname), ['.', '..']); + foreach($files as $file) { + $directory = $dirname . '/' . $file; + if(is_dir($directory)) { + $directories[] = $directory; + $directories = array_merge($directories, expandTree($directory)); + } + } + + return $directories; +} + +/** + * Recursively deletes the directory + * + * @param string $dirname + * @return bool + */ +function delTree($dirname) +{ + $files = array_diff(scandir($dirname), ['.', '..']); + foreach ($files as $file) { + is_dir($dirname . '/' . $file) ? delTree($dirname . '/' . $file) : unlink($dirname . '/' . $file); + } + + return rmdir($dirname); +} + +/** + * Prepare word + * + * @param string $matches + * @return string + */ +function prepareWord($matches) +{ + return '[' . strtolower($matches[1]) . strtoupper($matches[1]) . ']'; +} + +$objects = 0; +$directories = expandTree($dirname); + +foreach ($directories as $directory) { + foreach ($patterns as $pattern) { + + $casePattern = preg_replace_callback('/([a-z])/i', 'prepareWord', $pattern); + + foreach (glob($directory . '/' . $casePattern, GLOB_BRACE) as $file) { + + if (isset($options['v']) || isset($options['d'])) { + echo $file . PHP_EOL; + } else { + echo '.'; + } + + if (! isset($options['d'])) { + if (is_dir($file)) { + delTree($file); + } else { + unlink($file); + } + } + + usleep(3000); + $objects++; + } + } +} + +if ($objects) { + if (isset($options['d'])) { + echo PHP_EOL . $objects . ' object(s) will be deleted!' . PHP_EOL; + } else { + echo PHP_EOL . $objects . ' object(s) successfully deleted!' . PHP_EOL; + } +} else { + echo 'No objects found for deletion!' . PHP_EOL; +} + diff --git a/lib/vendor/visavi/cleanup/composer.json b/lib/vendor/visavi/cleanup/composer.json new file mode 100644 index 0000000..efd9dfb --- /dev/null +++ b/lib/vendor/visavi/cleanup/composer.json @@ -0,0 +1,19 @@ +{ + "name": "visavi/cleanup", + "description": "Cleaning vendor directory", + "keywords": ["composer", "vendor", "clean"], + "homepage": "http://visavi.net", + "license": "MIT", + "authors": [ + { + "name": "Alexander Grigorev", + "email": "admin@visavi.net", + "homepage": "http://visavi.net" + } + ], + "require": { + "php": ">=5.4.0" + }, + "minimum-stability": "stable", + "bin": ["cleanup"] +}