@@ -94,6 +94,10 @@ class TemplateProcessor
94
94
*/
95
95
protected $ tempDocumentNewImages = [];
96
96
97
+ protected static $ macroOpeningChars = '${ ' ;
98
+
99
+ protected static $ macroClosingChars = '} ' ;
100
+
97
101
/**
98
102
* @since 0.12.0 Throws CreateTemporaryFileException and CopyFileException instead of Exception
99
103
*
@@ -238,8 +242,8 @@ public function applyXslStyleSheet($xslDomDocument, $xslOptions = [], $xslOption
238
242
*/
239
243
protected static function ensureMacroCompleted ($ macro )
240
244
{
241
- if (substr ($ macro , 0 , 2 ) !== ' ${ ' && substr ($ macro , -1 ) !== ' } ' ) {
242
- $ macro = ' ${ ' . $ macro . ' } ' ;
245
+ if (substr ($ macro , 0 , 2 ) !== self :: $ macroOpeningChars && substr ($ macro , -1 ) !== self :: $ macroClosingChars ) {
246
+ $ macro = self :: $ macroOpeningChars . $ macro . self :: $ macroClosingChars ;
243
247
}
244
248
245
249
return $ macro ;
@@ -856,8 +860,12 @@ public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVaria
856
860
{
857
861
$ xmlBlock = null ;
858
862
$ matches = [];
863
+ $ escapedMacroOpeningChars = self ::$ macroOpeningChars ;
864
+ $ escapedMacroClosingChars = self ::$ macroClosingChars ;
859
865
preg_match (
860
- '/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\${ ' . $ blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\${\/ ' . $ blockname . '}<\/w:.*?p>)/is ' ,
866
+ //'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\{{' . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\{{\/' . $blockname . '}<\/w:.*?p>)/is',
867
+ '/(.*((?s)<w:p\b(?:(?!<w:p\b).)*? \\' . $ escapedMacroOpeningChars . $ blockname . $ escapedMacroClosingChars . '<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*? \\' . $ escapedMacroOpeningChars . '\/ ' . $ blockname . $ escapedMacroClosingChars . '<\/w:.*?p>)/is ' ,
868
+ //'/(.*((?s)<w:p\b(?:(?!<w:p\b).)*?\\'. $escapedMacroOpeningChars . $blockname . '}<\/w:.*?p>))(.*)((?s)<w:p\b(?:(?!<w:p\b).)[^$]*?\\'.$escapedMacroOpeningChars.'\/' . $blockname . '}<\/w:.*?p>)/is',
861
869
$ this ->tempDocumentMainPart ,
862
870
$ matches
863
871
);
@@ -896,8 +904,10 @@ public function cloneBlock($blockname, $clones = 1, $replace = true, $indexVaria
896
904
public function replaceBlock ($ blockname , $ replacement ): void
897
905
{
898
906
$ matches = [];
907
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
908
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
899
909
preg_match (
900
- '/(<\?xml.*)(<w:p.*>\${ ' . $ blockname . ' } <\/w:.*?p>)(.*)(<w:p.*\${ \/ ' . $ blockname . ' } <\/w:.*?p>)/is ' ,
910
+ '/(<\?xml.*)(<w:p.*> ' . $ escapedMacroOpeningChars . $ blockname . $ escapedMacroClosingChars . ' <\/w:.*?p>)(.*)(<w:p.* ' . $ escapedMacroOpeningChars . ' \/ ' . $ blockname . $ escapedMacroClosingChars . ' <\/w:.*?p>)/is ' ,
901
911
$ this ->tempDocumentMainPart ,
902
912
$ matches
903
913
);
@@ -1013,8 +1023,12 @@ public function saveAs($fileName): void
1013
1023
*/
1014
1024
protected function fixBrokenMacros ($ documentPart )
1015
1025
{
1026
+ $ brokenMacroOpeningChars = substr (self ::$ macroOpeningChars , 0 , 1 );
1027
+ $ endMacroOpeningChars = substr (self ::$ macroOpeningChars , 1 );
1028
+ $ macroClosingChars = self ::$ macroClosingChars ;
1029
+
1016
1030
return preg_replace_callback (
1017
- '/\$ (?:\{ |[^{$]*\>\{)[^} $]*\}/U ' ,
1031
+ '/ \\' . $ brokenMacroOpeningChars . ' (?: \\' . $ endMacroOpeningChars . ' |[^{$]*\>\{)[^ ' . $ macroClosingChars . ' $]*\}/U ' ,
1018
1032
function ($ match ) {
1019
1033
return strip_tags ($ match [0 ]);
1020
1034
},
@@ -1053,7 +1067,10 @@ protected function setValueForPart($search, $replace, $documentPartXML, $limit)
1053
1067
protected function getVariablesForPart ($ documentPartXML )
1054
1068
{
1055
1069
$ matches = [];
1056
- preg_match_all ('/\$\{(.*?)}/i ' , $ documentPartXML , $ matches );
1070
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
1071
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
1072
+
1073
+ preg_match_all ("/ $ escapedMacroOpeningChars(.*?) $ escapedMacroClosingChars/i " , $ documentPartXML , $ matches );
1057
1074
1058
1075
return $ matches [1 ];
1059
1076
}
@@ -1238,8 +1255,11 @@ protected function getSlice($startPosition, $endPosition = 0)
1238
1255
protected function indexClonedVariables ($ count , $ xmlBlock )
1239
1256
{
1240
1257
$ results = [];
1258
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
1259
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
1260
+
1241
1261
for ($ i = 1 ; $ i <= $ count ; ++$ i ) {
1242
- $ results [] = preg_replace (' /\$\{ ([^:]*?)(:.*?)?\}/ ' , ' \${\ 1# ' . $ i . '\2} ' , $ xmlBlock );
1262
+ $ results [] = preg_replace (" / $ escapedMacroOpeningChars ([^:]*?)(:.*?)? $ escapedMacroClosingChars / " , self :: $ macroOpeningChars . ' \ 1# ' . $ i . '\2 ' . self :: $ macroClosingChars , $ xmlBlock );
1243
1263
}
1244
1264
1245
1265
return $ results ;
@@ -1394,7 +1414,7 @@ protected function splitTextIntoTexts($text)
1394
1414
}
1395
1415
1396
1416
$ unformattedText = preg_replace ('/>\s+</ ' , '>< ' , $ text );
1397
- $ result = str_replace ([' ${ ' , ' } ' ], ['</w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve">${ ' , ' } </w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"> ' ], $ unformattedText );
1417
+ $ result = str_replace ([self :: $ macroOpeningChars , self :: $ macroClosingChars ], ['</w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"> ' . self :: $ macroOpeningChars , self :: $ macroClosingChars . ' </w:t></w:r><w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"> ' ], $ unformattedText );
1398
1418
1399
1419
return str_replace (['<w:r> ' . $ extractedStyle . '<w:t xml:space="preserve"></w:t></w:r> ' , '<w:r><w:t xml:space="preserve"></w:t></w:r> ' , '<w:t> ' ], ['' , '' , '<w:t xml:space="preserve"> ' ], $ result );
1400
1420
}
@@ -1408,6 +1428,25 @@ protected function splitTextIntoTexts($text)
1408
1428
*/
1409
1429
protected function textNeedsSplitting ($ text )
1410
1430
{
1411
- return preg_match ('/[^>]\${|}[^<]/i ' , $ text ) == 1 ;
1431
+ $ escapedMacroOpeningChars = preg_quote (self ::$ macroOpeningChars );
1432
+ $ escapedMacroClosingChars = preg_quote (self ::$ macroClosingChars );
1433
+
1434
+ return 1 === preg_match ('/[^>] ' . $ escapedMacroOpeningChars . '| ' . $ escapedMacroClosingChars . '[^<]/i ' , $ text );
1435
+ }
1436
+
1437
+ public function setMacroOpeningChars (string $ macroOpeningChars ): void
1438
+ {
1439
+ self ::$ macroOpeningChars = $ macroOpeningChars ;
1440
+ }
1441
+
1442
+ public function setMacroClosingChars (string $ macroClosingChars ): void
1443
+ {
1444
+ self ::$ macroClosingChars = $ macroClosingChars ;
1445
+ }
1446
+
1447
+ public function setMacroChars (string $ macroOpeningChars , string $ macroClosingChars ): void
1448
+ {
1449
+ self ::$ macroOpeningChars = $ macroOpeningChars ;
1450
+ self ::$ macroClosingChars = $ macroClosingChars ;
1412
1451
}
1413
1452
}
0 commit comments