csstidy_print

CSS Printing class.

Defined (1)

The class is defined in the following location(s).

/modules/custom-css/csstidy/class.csstidy_print.php  
  1. class csstidy_print { 
  2.  
  3. /** 
  4. * Saves the input CSS string 
  5. * @var string 
  6. * @access private 
  7. */ 
  8. public $input_css = ''; 
  9. /** 
  10. * Saves the formatted CSS string 
  11. * @var string 
  12. * @access public 
  13. */ 
  14. public $output_css = ''; 
  15. /** 
  16. * Saves the formatted CSS string (plain text) 
  17. * @var string 
  18. * @access public 
  19. */ 
  20. public $output_css_plain = ''; 
  21.  
  22. /** 
  23. * Constructor 
  24. * @param array $css contains the class csstidy 
  25. * @access private 
  26. * @version 1.0 
  27. */ 
  28. function csstidy_print(&$css) { 
  29. $this->parser = & $css; 
  30. $this->css = & $css->css; 
  31. $this->template = & $css->template; 
  32. $this->tokens = & $css->tokens; 
  33. $this->charset = & $css->charset; 
  34. $this->import = & $css->import; 
  35. $this->namespace = & $css->namespace; 
  36.  
  37. /** 
  38. * Resets output_css and output_css_plain (new css code) 
  39. * @access private 
  40. * @version 1.0 
  41. */ 
  42. function _reset() { 
  43. $this->output_css = ''; 
  44. $this->output_css_plain = ''; 
  45.  
  46. /** 
  47. * Returns the CSS code as plain text 
  48. * @param string $default_media default @media to add to selectors without any @media 
  49. * @return string 
  50. * @access public 
  51. * @version 1.0 
  52. */ 
  53. function plain($default_media='') { 
  54. $this->_print(true, $default_media); 
  55. return $this->output_css_plain; 
  56.  
  57. /** 
  58. * Returns the formatted CSS code 
  59. * @param string $default_media default @media to add to selectors without any @media 
  60. * @return string 
  61. * @access public 
  62. * @version 1.0 
  63. */ 
  64. function formatted($default_media='') { 
  65. $this->_print(false, $default_media); 
  66. return $this->output_css; 
  67.  
  68. /** 
  69. * Returns the formatted CSS code to make a complete webpage 
  70. * @param string $doctype shorthand for the document type 
  71. * @param bool $externalcss indicates whether styles to be attached internally or as an external stylesheet 
  72. * @param string $title title to be added in the head of the document 
  73. * @param string $lang two-letter language code to be added to the output 
  74. * @return string 
  75. * @access public 
  76. * @version 1.4 
  77. */ 
  78. function formatted_page($doctype='xhtml1.1', $externalcss=true, $title='', $lang='en') { 
  79. switch ($doctype) { 
  80. case 'xhtml1.0strict': 
  81. $doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
  82. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'; 
  83. break; 
  84. case 'xhtml1.1': 
  85. default: 
  86. $doctype_output = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" 
  87. "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'; 
  88. break; 
  89.  
  90. $output = $cssparsed = ''; 
  91. $this->output_css_plain = & $output; 
  92.  
  93. $output .= $doctype_output . "\n" . '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="' . $lang . '"'; 
  94. $output .= ( $doctype === 'xhtml1.1') ? '>' : ' lang="' . $lang . '">'; 
  95. $output .= "\n<head>\n <title>$title</title>"; 
  96.  
  97. if ($externalcss) { 
  98. $output .= "\n <style type=\"text/css\">\n"; 
  99. $cssparsed = file_get_contents('cssparsed.css'); 
  100. $output .= $cssparsed; // Adds an invisible BOM or something, but not in css_optimised.php 
  101. $output .= "\n</style>"; 
  102. } else { 
  103. $output .= "\n" . ' <link rel="stylesheet" type="text/css" href="cssparsed.css" />'; 
  104. // } 
  105. $output .= "\n</head>\n<body><code id=\"copytext\">"; 
  106. $output .= $this->formatted(); 
  107. $output .= '</code>' . "\n" . '</body></html>'; 
  108. return $this->output_css_plain; 
  109.  
  110. /** 
  111. * Returns the formatted CSS Code and saves it into $this->output_css and $this->output_css_plain 
  112. * @param bool $plain plain text or not 
  113. * @param string $default_media default @media to add to selectors without any @media 
  114. * @access private 
  115. * @version 2.0 
  116. */ 
  117. function _print($plain = false, $default_media='') { 
  118. if ($this->output_css && $this->output_css_plain) { 
  119. return; 
  120.  
  121. $output = ''; 
  122. if (!$this->parser->get_cfg('preserve_css')) { 
  123. $this->_convert_raw_css($default_media); 
  124.  
  125. $template = & $this->template; 
  126.  
  127. if ($plain) { 
  128. $template = array_map('strip_tags', $template); 
  129.  
  130. if ($this->parser->get_cfg('timestamp')) { 
  131. array_unshift($this->tokens, array(COMMENT, ' CSSTidy ' . $this->parser->version . ': ' . date('r') . ' ')); 
  132.  
  133. if (!empty($this->charset)) { 
  134. $output .= $template[0] . '@charset ' . $template[5] . $this->charset . $template[6]; 
  135.  
  136. if (!empty($this->import)) { 
  137. for ($i = 0, $size = count($this->import); $i < $size; $i++) { 
  138. $import_components = explode(' ', $this->import[$i]); 
  139. if (substr($import_components[0], 0, 4) === 'url(' && substr($import_components[0], -1, 1) === ')') { 
  140. $import_components[0] = '\'' . trim(substr($import_components[0], 4, -1), "'\"") . '\''; 
  141. $this->import[$i] = implode(' ', $import_components); 
  142. $this->parser->log('Optimised @import : Removed "url("', 'Information'); 
  143. $output .= $template[0] . '@import ' . $template[5] . $this->import[$i] . $template[6]; 
  144.  
  145. if (!empty($this->namespace)) { 
  146. if (substr($this->namespace, 0, 4) === 'url(' && substr($this->namespace, -1, 1) === ')') { 
  147. $this->namespace = '\'' . substr($this->namespace, 4, -1) . '\''; 
  148. $this->parser->log('Optimised @namespace : Removed "url("', 'Information'); 
  149. $output .= $template[0] . '@namespace ' . $template[5] . $this->namespace . $template[6]; 
  150.  
  151. $output .= $template[13]; 
  152. $in_at_out = ''; 
  153. $out = & $output; 
  154.  
  155. foreach ($this->tokens as $key => $token) { 
  156. switch ($token[0]) { 
  157. case AT_START: 
  158. $out .= $template[0] . $this->_htmlsp($token[1], $plain) . $template[1]; 
  159. $out = & $in_at_out; 
  160. break; 
  161.  
  162. case SEL_START: 
  163. if ($this->parser->get_cfg('lowercase_s')) 
  164. $token[1] = strtolower($token[1]); 
  165. $out .= ( $token[1]{0} !== '@') ? $template[2] . $this->_htmlsp($token[1], $plain) : $template[0] . $this->_htmlsp($token[1], $plain); 
  166. $out .= $template[3]; 
  167. break; 
  168.  
  169. case PROPERTY: 
  170. if ($this->parser->get_cfg('case_properties') === 2) { 
  171. $token[1] = strtoupper($token[1]); 
  172. } elseif ($this->parser->get_cfg('case_properties') === 1) { 
  173. $token[1] = strtolower($token[1]); 
  174. $out .= $template[4] . $this->_htmlsp($token[1], $plain) . ':' . $template[5]; 
  175. break; 
  176.  
  177. case VALUE: 
  178. $out .= $this->_htmlsp($token[1], $plain); 
  179. if ($this->_seeknocomment($key, 1) == SEL_END && $this->parser->get_cfg('remove_last_;')) { 
  180. $out .= str_replace(';', '', $template[6]); 
  181. } else { 
  182. $out .= $template[6]; 
  183. break; 
  184.  
  185. case SEL_END: 
  186. $out .= $template[7]; 
  187. if ($this->_seeknocomment($key, 1) != AT_END) 
  188. $out .= $template[8]; 
  189. break; 
  190.  
  191. case AT_END: 
  192. $out = & $output; 
  193. $out .= $template[10] . str_replace("\n", "\n" . $template[10], $in_at_out); 
  194. $in_at_out = ''; 
  195. $out .= $template[9]; 
  196. break; 
  197.  
  198. case COMMENT: 
  199. $out .= $template[11] . '/*' . $this->_htmlsp($token[1], $plain) . '*/' . $template[12]; 
  200. break; 
  201.  
  202. $output = trim($output); 
  203.  
  204. if (!$plain) { 
  205. $this->output_css = $output; 
  206. $this->_print(true); 
  207. } else { 
  208. // If using spaces in the template, don't want these to appear in the plain output 
  209. $this->output_css_plain = str_replace(' ', '', $output); 
  210.  
  211. /** 
  212. * Gets the next token type which is $move away from $key, excluding comments 
  213. * @param integer $key current position 
  214. * @param integer $move move this far 
  215. * @return mixed a token type 
  216. * @access private 
  217. * @version 1.0 
  218. */ 
  219. function _seeknocomment($key, $move) { 
  220. $go = ($move > 0) ? 1 : -1; 
  221. for ($i = $key + 1; abs($key - $i) - 1 < abs($move); $i += $go) { 
  222. if (!isset($this->tokens[$i])) { 
  223. return; 
  224. if ($this->tokens[$i][0] == COMMENT) { 
  225. $move += 1; 
  226. continue; 
  227. return $this->tokens[$i][0]; 
  228.  
  229. /** 
  230. * Converts $this->css array to a raw array ($this->tokens) 
  231. * @param string $default_media default @media to add to selectors without any @media 
  232. * @access private 
  233. * @version 1.0 
  234. */ 
  235. function _convert_raw_css($default_media='') { 
  236. $this->tokens = array(); 
  237.  
  238. foreach ($this->css as $medium => $val) { 
  239. if ($this->parser->get_cfg('sort_selectors')) 
  240. ksort($val); 
  241. if (intval($medium) < DEFAULT_AT) { 
  242. $this->parser->_add_token(AT_START, $medium, true); 
  243. elseif ($default_media) { 
  244. $this->parser->_add_token(AT_START, $default_media, true); 
  245.  
  246. foreach ($val as $selector => $vali) { 
  247. if ($this->parser->get_cfg('sort_properties')) 
  248. ksort($vali); 
  249. $this->parser->_add_token(SEL_START, $selector, true); 
  250.  
  251. foreach ($vali as $property => $valj) { 
  252. $this->parser->_add_token(PROPERTY, $property, true); 
  253. $this->parser->_add_token(VALUE, $valj, true); 
  254.  
  255. $this->parser->_add_token(SEL_END, $selector, true); 
  256.  
  257. if (intval($medium) < DEFAULT_AT) { 
  258. $this->parser->_add_token(AT_END, $medium, true); 
  259. elseif ($default_media) { 
  260. $this->parser->_add_token(AT_END, $default_media, true); 
  261.  
  262. /** 
  263. * Same as htmlspecialchars, only that chars are not replaced if $plain !== true. This makes print_code() cleaner. 
  264. * @param string $string 
  265. * @param bool $plain 
  266. * @return string 
  267. * @see csstidy_print::_print() 
  268. * @access private 
  269. * @version 1.0 
  270. */ 
  271. function _htmlsp($string, $plain) { 
  272. if (!$plain) { 
  273. return htmlspecialchars($string, ENT_QUOTES, 'utf-8'); 
  274. return $string; 
  275.  
  276. /** 
  277. * Get compression ratio 
  278. * @access public 
  279. * @return float 
  280. * @version 1.2 
  281. */ 
  282. function get_ratio() { 
  283. if (!$this->output_css_plain) { 
  284. $this->formatted(); 
  285. return round((strlen($this->input_css) - strlen($this->output_css_plain)) / strlen($this->input_css), 3) * 100; 
  286.  
  287. /** 
  288. * Get difference between the old and new code in bytes and prints the code if necessary. 
  289. * @access public 
  290. * @return string 
  291. * @version 1.1 
  292. */ 
  293. function get_diff() { 
  294. if (!$this->output_css_plain) { 
  295. $this->formatted(); 
  296.  
  297. $diff = strlen($this->output_css_plain) - strlen($this->input_css); 
  298.  
  299. if ($diff > 0) { 
  300. return '+' . $diff; 
  301. } elseif ($diff == 0) { 
  302. return '+-' . $diff; 
  303.  
  304. return $diff; 
  305.  
  306. /** 
  307. * Get the size of either input or output CSS in KB 
  308. * @param string $loc default is "output" 
  309. * @access public 
  310. * @return integer 
  311. * @version 1.0 
  312. */ 
  313. function size($loc = 'output') { 
  314. if ($loc === 'output' && !$this->output_css) { 
  315. $this->formatted(); 
  316.  
  317. if ($loc === 'input') { 
  318. return (strlen($this->input_css) / 1000); 
  319. } else { 
  320. return (strlen($this->output_css_plain) / 1000); 
  321.