1<?php
2// $Header: /cvsroot/html2ps/css.inc.php,v 1.28 2007/04/07 11:16:34 Konstantin Exp $
3
4class CSS {
5  var $_handlers;
6  var $_mapping;
7  var $_defaultState;
8  var $_defaultStateFlags;
9
10  function _getDefaultState() {
11    if (!isset($this->_defaultState)) {
12      $this->_defaultState = array();
13
14      $handlers = $this->getHandlers();
15      foreach ($handlers as $property => $handler) {
16        $this->_defaultState[$property] = $handler->default_value();
17      };
18    };
19
20    return $this->_defaultState;
21  }
22
23  function _getDefaultStateFlags() {
24    if (!isset($this->_defaultStateFlags)) {
25      $this->_defaultStateFlags = array();
26
27      $handlers = $this->getHandlers();
28      foreach ($handlers as $property => $handler) {
29        $this->_defaultStateFlags[$property] = true;
30      };
31    };
32
33    return $this->_defaultStateFlags;
34  }
35
36  function getHandlers() {
37    return $this->_handlers;
38  }
39
40  function getInheritableTextHandlers() {
41    if (!isset($this->_handlersInheritableText)) {
42      $this->_handlersInheritabletext = array();
43      foreach ($this->_handlers as $property => $handler) {
44        if ($handler->isInheritableText()) {
45          $this->_handlersInheritableText[$property] =& $this->_handlers[$property];
46        };
47      }
48    }
49
50    return $this->_handlersInheritableText;
51  }
52
53  function getInheritableHandlers() {
54    if (!isset($this->_handlersInheritable)) {
55      $this->_handlersInheritable = array();
56      foreach ($this->_handlers as $property => $handler) {
57        if ($handler->isInheritable()) {
58          $this->_handlersInheritable[$property] =& $this->_handlers[$property];
59        };
60      }
61    }
62
63    return $this->_handlersInheritable;
64  }
65
66  function &get() {
67    global $__g_css_handler_set;
68
69    if (!isset($__g_css_handler_set)) {
70      $__g_css_handler_set = new CSS();
71    };
72
73    return $__g_css_handler_set;
74  }
75
76  function CSS() {
77    $this->_handlers = array();
78    $this->_mapping  = array();
79  }
80
81  function getDefaultValue($property) {
82    $css =& CSS::get();
83    $handler =& $css->_get_handler($property);
84    $value = $handler->default_value();
85
86    if (is_object($value)) {
87      return $value->copy();
88    } else {
89      return $value;
90    };
91  }
92
93  function &get_handler($property) {
94    $css =& CSS::get();
95    $handler =& $css->_get_handler($property);
96    return $handler;
97  }
98
99  function &_get_handler($property) {
100    if (isset($this->_handlers[$property])) {
101      return $this->_handlers[$property];
102    } else {
103      $dumb = null;
104      return $dumb;
105    };
106  }
107
108  function _name2code($key) {
109    if (!isset($this->_mapping[$key])) {
110      return null;
111    };
112
113    return $this->_mapping[$key];
114  }
115
116  function name2code($key) {
117    $css =& CSS::get();
118    return $css->_name2code($key);
119  }
120
121  function register_css_property(&$handler) {
122    $property = $handler->get_property_code();
123    $name     = $handler->get_property_name();
124
125    $css =& CSS::get();
126    $css->_handlers[$property] =& $handler;
127    $css->_mapping[$name] = $property;
128  }
129
130  /**
131   * Refer to CSS 2.1 G.2 Lexical scanner
132   * h		[0-9a-f]
133   * nonascii	[\200-\377]
134   * unicode		\\{h}{1,6}(\r\n|[ \t\r\n\f])?
135   * escape		{unicode}|\\[^\r\n\f0-9a-f]
136   * nmstart		[_a-z]|{nonascii}|{escape}
137   * nmchar		[_a-z0-9-]|{nonascii}|{escape}
138   * ident		-?{nmstart}{nmchar}*
139   */
140  function get_identifier_regexp() {
141    return '-?(?:[_a-z]|[\200-\377]|\\[0-9a-f]{1,6}(?:\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])(?:[_a-z0-9-]|[\200-\377]|\\[0-9a-f]{1,6}(?:\r\n|[ \t\r\n\f])?|\\[^\r\n\f0-9a-f])*';
142  }
143
144  function is_identifier($string) {
145    return preg_match(sprintf('/%s/',
146                              CSS::get_identifier_regexp()),
147                      $string);
148  }
149
150  function parse_string($string) {
151    if (preg_match(sprintf('/^(%s)\s*(.*)$/s', CSS_STRING1_REGEXP), $string, $matches)) {
152      $value = $matches[1];
153      $rest = $matches[2];
154
155      $value = CSS::remove_backslash_at_newline($value);
156
157      return array($value, $rest);
158    };
159
160    if (preg_match(sprintf('/^(%s)\s*(.*)$/s', CSS_STRING2_REGEXP), $string, $matches)) {
161      $value = $matches[1];
162      $rest = $matches[2];
163
164      $value = CSS::remove_backslash_at_newline($value);
165
166      return array($value, $rest);
167    };
168
169    return array(null, $string);
170  }
171
172  function remove_backslash_at_newline($value) {
173    return preg_replace("/\\\\\n/", '', $value);
174  }
175}
176
177?>