1 <?php
2 /**
3 * Smarty plugin
4 *
5 * @package Smarty
6 * @subpackage PluginsFilter
7 */
9 /**
10 * Smarty trimwhitespace outputfilter plugin
11 *
12 * Trim unnecessary whitespace from HTML markup.
13 *
14 * @author Rodney Rehm
15 * @param string $source input string
16 * @param Smarty_Internal_Template $smarty Smarty object
17 * @return string filtered output
18 */
19 function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty)
20 {
21 $store = array();
22 $_store = 0;
23 $_offset = 0;
25 // Unify Line-Breaks to \n
26 $source = preg_replace("/\015\012|\015|\012/", "\n", $source);
28 // capture Internet Explorer Conditional Comments
29 if (preg_match_all('#<!--\[[^\]]+\]>.*?<!\[[^\]]+\]-->#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
30 foreach ($matches as $match) {
31 $store[] = $match[0][0];
32 $_length = strlen($match[0][0]);
33 $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
34 $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
36 $_offset += $_length - strlen($replace);
37 $_store++;
38 }
39 }
41 // Strip all HTML-Comments
42 $source = preg_replace( '#<!--.*?-->#ms', '', $source );
44 // capture html elements not to be messed with
45 $_offset = 0;
46 if (preg_match_all('#<(script|pre|textarea)[^>]*>.*?</\\1>#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
47 foreach ($matches as $match) {
48 $store[] = $match[0][0];
49 $_length = strlen($match[0][0]);
50 $replace = '@!@SMARTY:' . $_store . ':SMARTY@!@';
51 $source = substr_replace($source, $replace, $match[0][1] - $_offset, $_length);
53 $_offset += $_length - strlen($replace);
54 $_store++;
55 }
56 }
58 $expressions = array(
59 // replace multiple spaces between tags by a single space
60 // can't remove them entirely, becaue that might break poorly implemented CSS display:inline-block elements
61 '#(:SMARTY@!@|>)\s+(?=@!@SMARTY:|<)#s' => '\1 \2',
62 // remove spaces between attributes (but not in attribute values!)
63 '#(([a-z0-9]\s*=\s*(["\'])[^\3]*?\3)|<[a-z0-9_]+)\s+([a-z/>])#is' => '\1 \4',
64 // note: for some very weird reason trim() seems to remove spaces inside attributes.
65 // maybe a \0 byte or something is interfering?
66 '#^\s+<#Ss' => '<',
67 '#>\s+$#Ss' => '>',
68 );
70 $source = preg_replace( array_keys($expressions), array_values($expressions), $source );
71 // note: for some very weird reason trim() seems to remove spaces inside attributes.
72 // maybe a \0 byte or something is interfering?
73 // $source = trim( $source );
75 // capture html elements not to be messed with
76 $_offset = 0;
77 if (preg_match_all('#@!@SMARTY:([0-9]+):SMARTY@!@#is', $source, $matches, PREG_OFFSET_CAPTURE | PREG_SET_ORDER)) {
78 foreach ($matches as $match) {
79 $store[] = $match[0][0];
80 $_length = strlen($match[0][0]);
81 $replace = array_shift($store);
82 $source = substr_replace($source, $replace, $match[0][1] + $_offset, $_length);
84 $_offset += strlen($replace) - $_length;
85 $_store++;
86 }
87 }
89 return $source;
90 }
92 ?>