1<?php 2 3/** 4* @package s9e\TextFormatter 5* @copyright Copyright (c) 2010-2021 The s9e authors 6* @license http://www.opensource.org/licenses/mit-license.php The MIT License 7*/ 8namespace s9e\TextFormatter\Configurator\TemplateNormalizations; 9 10use DOMNode; 11 12/** 13* Convert simple expressions in curly brackets in text into xsl:value-of elements 14* 15* Will replace 16* <span>{$FOO}{@bar}</span> 17* with 18* <span><xsl:value-of value="$FOO"/><xsl:value-of value="@bar"/></span> 19*/ 20class ConvertCurlyExpressionsInText extends AbstractNormalization 21{ 22 /** 23 * {@inheritdoc} 24 */ 25 protected $queries = ['//*[namespace-uri() != $XSL]/text()[contains(., "{@") or contains(., "{$")]']; 26 27 /** 28 * Insert a text node before given node 29 * 30 * @param string $text 31 * @param DOMNode $node 32 * @return void 33 */ 34 protected function insertTextBefore($text, $node) 35 { 36 if ($text > '') 37 { 38 $node->parentNode->insertBefore($this->createText($text), $node); 39 } 40 } 41 42 /** 43 * {@inheritdoc} 44 */ 45 protected function normalizeNode(DOMNode $node) 46 { 47 $parentNode = $node->parentNode; 48 49 preg_match_all( 50 '#\\{([$@][-\\w]+)\\}#', 51 $node->textContent, 52 $matches, 53 PREG_SET_ORDER | PREG_OFFSET_CAPTURE 54 ); 55 56 $lastPos = 0; 57 foreach ($matches as $m) 58 { 59 $pos = $m[0][1]; 60 61 // Catch up to current position 62 if ($pos > $lastPos) 63 { 64 $text = substr($node->textContent, $lastPos, $pos - $lastPos); 65 $this->insertTextBefore($text, $node); 66 } 67 $lastPos = $pos + strlen($m[0][0]); 68 69 // Add the xsl:value-of element 70 $parentNode 71 ->insertBefore($this->createElement('xsl:value-of'), $node) 72 ->setAttribute('select', $m[1][0]); 73 } 74 75 // Append the rest of the text 76 $text = substr($node->textContent, $lastPos); 77 $this->insertTextBefore($text, $node); 78 79 // Now remove the old text node 80 $parentNode->removeChild($node); 81 } 82}