1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202: 203: 204: 205: 206: 207: 208: 209: 210: 211: 212: 213: 214: 215: 216: 217: 218: 219: 220: 221: 222: 223: 224: 225: 226: 227: 228: 229: 230: 231: 232: 233: 234: 235: 236: 237: 238: 239: 240: 241: 242: 243: 244: 245: 246: 247: 248: 249: 250: 251: 252: 253: 254: 255: 256: 257: 258: 259: 260: 261: 262: 263: 264: 265: 266: 267: 268: 269: 270: 271: 272: 273: 274: 275: 276: 277: 278: 279: 280: 281:
<?php
/**
* MvcCore
*
* This source file is subject to the BSD 3 License
* For the full copyright and license information, please view
* the LICENSE.md file that are distributed with this source code.
*
* @copyright Copyright (c) 2016 Tom Flídr (https://github.com/mvccore/mvccore)
* @license https://mvccore.github.io/docs/mvccore/4.0.0/LICENCE.md
*/
namespace MvcCore\Ext\View\Helpers;
class LineBreaks
{
/**
* MvcCore Extension - View Helper - Line Breaks - version:
* Comparation by PHP function version_compare();
* @see http://php.net/manual/en/function.version-compare.php
*/
const VERSION = '4.2.0';
/**
* Weak words by international language code as array key.
* Weak words are words, where you dont't want to have a line break after.
* Weak words have to be configured as string with all weak words separated
* by comma character without any spaces.
* @var array
*/
public $WeekWords = array(
'en' => 'a,an,the,and,but,or,when,of,in,to,with',
// single syllable conjunctions for Czech/Slovak
"cs" => "a,ač,aj,ak,ať,ba,co,či,do,i,k,ke,ku,o,pro,při,s,sa,se,si,sú,v,ve,z,za,ze,že",
);
/**
* Special shortcuts to not have any line break inside, keyed by language.
* @var array
*/
public $Shortcuts = array(
"cs" => array('př. kr.', 'př. n. l.', 's. r. o.', 'a. s.', 'v. o. s.', 'o. s. ř.',),
);
/**
* Units are very short words, where you dont't want to have a line break before,
* where is any digit before catched unit word and space before catched unit word.
* Units have to be configured as string with all units separated
* by comma character without any spaces.
* @var string
*/
public $Units = "%,‰,mm,cm,dm,m,km,g,dkg,kg,t,ar,ha,ml,dcl,l,cm²,m²,km²,cm³,m³,°C,°F,K";
/**
* Singleton instance.
* @var \MvcCore\Ext\View\Helpers\LineBreaks
*/
protected static $instance;
/**
* Language used for text processing as default.
* All text processing shoud be called with custom language value.
* @var string
*/
protected $lang = "";
/**
* Source text currently processed.
* @var string
*/
protected $text = "";
/**
* Store with weak words exploded into single strings, keyed by language.
* @var array
*/
protected $weekWords = array();
/**
* Exploded units as array of string to be processed in source text.
* @var string[]
*/
protected $units = array();
/**
* Prepared shortcuts with no-line breaking spaces, keyed by language.
* @var string[]
*/
protected $shortcuts = array();
/**
* Create view helper instance.
* To configure view helper instance, create it by this method
* in your $baseController->preDispatch(); method, after view
* instance inside controller is created, then you can configure
* anything you want. If Controller contains static property 'Lang',
* language for this view helper will be loaded from this property.
* @param \MvcCore\View $view
*/
public function GetInstance (\MvcCore\View & $view = NULL) {
if (!self::$instance) new self($view);
return self::$instance;
}
/**
* Create view helper instance.
* To configure view helper instance, create it by this method
* in your $baseController->preDispatch(); method, after view
* instance inside controller is created, then you can configure
* anything you want. If Controller contains static property 'Lang',
* language for this view helper will be loaded from this property.
* @param \MvcCore\View $view
*/
public function __construct (\MvcCore\View & $view = NULL) {
$ctrl = $view ? $view->Controller : \MvcCore::GetInstance()->GetController();
// If controller class has public static property named
// 'Controller::$Lang', set current context lang automaticly ($this->lang).
if (property_exists(get_class($ctrl), 'Lang')) {
$this->lang = $ctrl::$Lang;
}
self::$instance = $this;
}
/**
* Set weak words, where you need to place a HTML space entity,
* to not break line after each configured weak word in processing text.
* All words has to be configured as single string with all weak words
* separated by comma character without any space.
* @param string $weekWords all weak words as string separated by comma character
* @param string $lang optional, international language code
* @return \MvcCore\Ext\View\Helpers\LineBreaks
*/
public function SetWeekWords ($weekWords, $lang = '') {
if (!$lang) $lang = $this->lang;
$this->WeekWords[$lang] = $weekWords;
return $this;
}
/**
* Set special shortcuts for specific language to not have any line break inside.
* If language is not specified, there is used default language from controller instance.
* @param string[] $shortcuts shortcuts as array of strings
* @param string $lang optional, international language code
* @return \MvcCore\Ext\View\Helpers\LineBreaks
*/
public function SetShortcuts ($shortcuts, $lang = '') {
if (!$lang) $lang = $this->lang;
$this->Shortcuts[$lang] = $shortcuts;
return $this;
}
/**
* Set units, where you need to place a HTML space entity,
* to not break line before each configured unit where is founded digit
* character before unit and whitespace before in source text.
* All units has to be configured as single string with all units
* separated by comma character without any space.
* @param string $units all units as string separated by comma character
* @return \MvcCore\Ext\View\Helpers\LineBreaks
*/
public function SetUnits ($units) {
$this->Units = $units;
return $this;
}
/**
* Get weak words as array of strings, units and shortcuts.
* as array of string for currently processed language.
* @param string $lang international language code
* @return array
*/
protected function getWeekWordsUnitsAndShortcuts ($lang) {
if (!isset($this->weekWords[$lang]) && isset($this->WeekWords[$lang])) {
$this->weekWords[$lang] = explode(',', $this->WeekWords[$lang]);
} else {
$this->weekWords[$lang] = array();
}
if (!$this->units) {
$this->units = explode(',', $this->Units);
}
if (!isset($this->shortcuts[$lang]) && isset($this->Shortcuts[$lang])) {
$shortcuts = array();
foreach ($this->Shortcuts[$lang] as $shortcut) $shortcuts[$shortcut] = str_replace(' ', ' ', $shortcut);
$this->shortcuts[$lang] = & $shortcuts;
} else {
$this->shortcuts[$lang] = array();
}
return array($this->weekWords[$lang], $this->units, $this->shortcuts[$lang]);
}
/**
* Process configured weak words and units and place HTML space entity
* where is necessary to not line break source text where it's not wanted.
* @param string $text source text
* @param string $lang optional, international language code
* @return string
*/
public function LineBreaks ($text, $lang = "") {
$this->text = $text;
$word = "";
$lang = $lang ? $lang : $this->lang;
list($weekWords, $units, $shortcuts) = $this->getWeekWordsUnitsAndShortcuts($lang);
// if there are one or more tab chars in source text, convert them into single space
$this->text = preg_replace("#\t+#mu", " ", $this->text);
// if there are one or more space chars in source text, convert them into single space
$this->text = preg_replace("#[ ]{2,}#mu", " ", $this->text);
// for each week word
for ($i = 0, $l = count($weekWords); $i < $l; $i += 1) {
// load current week word into $word variable
$word = $weekWords[$i];
// process source text with current week word
$this->processWeakWord($word);
// convert first week word character into upper case (first word in sentence)
$word = mb_strtoupper(mb_substr($word, 0, 1)) + mb_substr($word, 1);
// process source text with current week word with first uppercased char
$this->processWeakWord($word);
}
// for each unit(s), where is whitespace char before and any number before that whitespace char:
for ($i = 0, $l = count($units); $i < $l; $i += 1) {
// load current unit into $word variable
$word = $units[$i];
// create regular expression pattern to search for unit(s), where is whitespace char before
// and any number before that whitespace char
$regExp = "#([0-9])\\s(" . $word . ")#mu";
// process replacement for all founded whitespaces into fixed space html entity in source text
$this->text = preg_replace(
$regExp,
"$1 $2",
$this->text
);
}
// for all special shortcuts - remove all line breaking whitespaces
foreach ($shortcuts as $sourceShortcut => $targetShortcut) {
$this->text = str_replace($sourceShortcut, $targetShortcut, $this->text);
}
// for all decimals, where is space between them:
// example: 9 999 999 -> 9 999 999
$this->text = preg_replace("#([0-9])\s([0-9])#", "$1 $2", $this->text);
return $this->text;
}
/**
* Process single weak word - place HTML space entity
* where is necessary to not line break source text where it's not wanted.
* @param string $word
* @return void
*/
protected function processWeakWord ($word) {
$index = 0;
$text = ' ' . $this->text . ' ';
// go through infinite loop and process given week word word with html fixed spaces replacement
while (TRUE) {
$index = mb_strpos($text, ' ' . $word . ' ');
if ($index !== FALSE) {
// If there is any week word and basic whitespace
// before and after the week word in source text:
// - take all surce text before week word including whitespace before week word,
// - take week word
// - add fixed space html entity
// - and add all rest source text after week word word
// and whitespace char after week word
$text = mb_substr($text, 0, $index + 1) . $word . ' ' . mb_substr($text, $index + 1 + mb_strlen($word) + 1);
// move $index variable after position, where is source text allready processed
$index += 1 + mb_strlen($word) + 6; // (6 - means length of space html entity: ' '
} else {
// there is no other occurance of week word in source text
break;
}
}
$this->text = mb_substr($text, 1, mb_strlen($text) - 2);
}
}