Blame | Letzte Änderung | Log anzeigen | RSS feed
<?phprequire_once(HTML2PS_DIR.'css.constants.inc.php');class CSSPageSelector {var $_type;function CSSPageSelector($type) {$this->set_type($type);}function get_type() {return $this->_type;}function set_type($type) {$this->_type = $type;}}class CSSPageSelectorAll extends CSSPageSelector {function CSSPageSelectorAll() {$this->CSSPageSelector(CSS_PAGE_SELECTOR_ALL);}}class CSSPageSelectorNamed extends CSSPageSelector {var $_name;function CSSPageSelectorNamed($name) {$this->CSSPageSelector(CSS_PAGE_SELECTOR_NAMED);$this->set_name($name);}function get_name() {return $this->_name;}function set_name($name) {$this->_name = $name;}}class CSSPageSelectorFirst extends CSSPageSelector {function CSSPageSelectorFirst() {$this->CSSPageSelector(CSS_PAGE_SELECTOR_FIRST);}}class CSSPageSelectorLeft extends CSSPageSelector {function CSSPageSelectorLeft() {$this->CSSPageSelector(CSS_PAGE_SELECTOR_LEFT);}}class CSSPageSelectorRight extends CSSPageSelector {function CSSPageSelectorRight() {$this->CSSPageSelector(CSS_PAGE_SELECTOR_RIGHT);}}class CSSAtRulePage {var $selector;var $margin_boxes;var $css;function CSSAtRulePage($selector, &$pipeline) {$this->selector = $selector;$this->margin_boxes = array();$this->css =& new CSSPropertyCollection();}function &getSelector() {return $this->selector;}function getAtRuleMarginBoxes() {return $this->margin_boxes;}/*** Note that only one margin box rule could be added; subsequent adds* will overwrite existing data*/function addAtRuleMarginBox($rule) {$this->margin_boxes[$rule->getSelector()] = $rule;}function setCSSProperty($property) {$this->css->add_property($property);}}class CSSAtRuleMarginBox {var $selector;var $css;/*** TODO: CSS_TEXT_ALIGN should get top/bottom values by default for* left-top, left-bottom, right-top and right-bottom boxes*/function CSSAtRuleMarginBox($selector, &$pipeline) {$this->selector = $selector;$css = "-html2ps-html-content: ''; content: ''; width: auto; height: auto; margin: 0; border: none; padding: 0; font: auto;";$css = $css . $this->_getCSSDefaults($selector);$this->css = new CSSRule(array(array(SELECTOR_ANY),parse_css_properties($css, $null),'',null),$pipeline);}function getSelector() {return $this->selector;}function _getCSSDefaults($selector) {$text_align_handler =& CSS::get_handler(CSS_TEXT_ALIGN);$vertical_align_handler =& CSS::get_handler(CSS_VERTICAL_ALIGN);switch ($selector) {case CSS_MARGIN_BOX_SELECTOR_TOP:return 'text-align: left; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_TOP_LEFT_CORNER:return 'text-align: right; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_TOP_LEFT:return 'text-align: left; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_TOP_CENTER:return 'text-align: center; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT:return 'text-align: right; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT_CORNER:return 'text-align: left; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_BOTTOM:return 'text-align: left; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT_CORNER:return 'text-align: right; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT:return 'text-align: left; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_BOTTOM_CENTER:return 'text-align: center; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT:return 'text-align: right; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT_CORNER:return 'text-align: left; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_LEFT_TOP:return 'text-align: center; vertical-align: top';case CSS_MARGIN_BOX_SELECTOR_LEFT_MIDDLE:return 'text-align: center; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_LEFT_BOTTOM:return 'text-align: center; vertical-align: bottom';case CSS_MARGIN_BOX_SELECTOR_RIGHT_TOP:return 'text-align: center; vertical-align: top';case CSS_MARGIN_BOX_SELECTOR_RIGHT_MIDDLE:return 'text-align: center; vertical-align: middle';case CSS_MARGIN_BOX_SELECTOR_RIGHT_BOTTOM:return 'text-align: center; vertical-align: bottom';};}function setCSSProperty($property) {$this->css->add_property($property);}function &get_css_property($code) {return $this->css->get_property($code);}}/*** Handle @page rules in current CSS media As parse_css_media is* called for selected media only, we can store data to global CSS* state - no data should be ignored** at-page rules will be removed after parsing** @param $css String contains raw CSS data to be processed* @return String CSS text without at-page rules*/function parse_css_atpage_rules($css, &$css_ruleset) {while (preg_match('/^(.*?)@page(.*)/is', $css, $matches)) {$data = $matches[2];$css = $matches[1].parse_css_atpage_rule(trim($data), $css_ruleset);};return $css;}function parse_css_atpage_rule($css, &$css_ruleset) {/*** Extract selector and left bracket*/if (!preg_match('/^(.*?){(.*)$/is', $css, $matches)) {error_log('No selector and/or open bracket found in @page rule');return $css;};$raw_selector = trim($matches[1]);$css = trim($matches[2]);$selector =& parse_css_atpage_selector($raw_selector);$at_rule =& new CSSAtRulePage($selector, $css_ruleset);/*** The body of @page rule may contain declaraction (detected by ';'),* margin box at-rule (detected by @top and similar tokens) or } indicating termination of* @page rule*/while (preg_match('/^(.*?)(;|@|})(.*)$/is', $css, $matches)) {$raw_prefix = trim($matches[1]);$raw_token = trim($matches[2]);$raw_suffix = trim($matches[3]);switch ($raw_token) {case ';':/*** Normal declaration (text contained in $raw_prefix*/parse_css_atpage_declaration($raw_prefix, $at_rule, $css_ruleset);$css = $raw_suffix;break;case '@':/*** Margin box at-rule*/$css = parse_css_atpage_margin_box($raw_suffix, $at_rule, $css_ruleset);break;case '}':/*** End-of-rule*/$css_ruleset->add_at_rule_page($at_rule);return $raw_suffix;};};/*** Note that we should normally exit via '}' token handler above*/error_log('No close bracket found in @page rule');$css_ruleset->add_at_rule_page($at_rule);return $css;}/*** Parses CSS at-page rule selector; syntax of this selector can be seen in* CSS 3 specification at http://www.w3.org/TR/css3-page/#syntax-page-selector***/function &parse_css_atpage_selector($selector) {switch ($selector) {case '':$selector =& new CSSPageSelectorAll();return $selector;case ':first':$selector =& new CSSPageSelectorFirst();return $selector;case ':left':$selector =& new CSSPageSelectorLeft();return $selector;case ':right':$selector =& new CSSPageSelectorRight();return $selector;default:if (CSS::is_identifier($selector)) {$selector =& new CSSPageSelectorNamed($selector);return $selector;} else {error_log(sprintf('Unknown page selector in @page rule: \'%s\'', $selector));$selector =& new CSSPageSelectorAll();return $selector;};};}function parse_css_atpage_margin_box($css, &$at_rule, &$pipeline) {if (!preg_match("/^([-\w]*)\s*{(.*)/is",$css,$matches)) {error_log("Invalid margin box at-rule format");return $css;};$raw_margin_box_selector = trim($matches[1]);$css = trim($matches[2]);$margin_box_selector = parse_css_atpage_margin_box_selector($raw_margin_box_selector);$at_rule_margin_box = new CSSAtRuleMarginBox($margin_box_selector, $pipeline);/*** The body of margin box at-rule may contain declaraction (detected* by ';'), or } indicating termination of at-rule*/while (preg_match('/^(.*?)(;|})(.*)$/is', $css, $matches)) {$raw_prefix = trim($matches[1]);$raw_token = trim($matches[2]);$raw_suffix = trim($matches[3]);switch ($raw_token) {case ';':/*** Normal declaration (text contained in $raw_prefix*/parse_css_atpage_margin_box_declaration($raw_prefix, $at_rule_margin_box, $pipeline);$css = $raw_suffix;break;case '}':/*** End-of-rule*/$at_rule->addAtRuleMarginBox($at_rule_margin_box);return $raw_suffix;};};/*** Note that we should normally exit via '}' token handler above*/error_log('No close bracket found in margin box at-rule');$at_rule->addAtRuleMarginBox($at_rule_margin_box);return $css;}function parse_css_atpage_margin_box_selector($css) {switch ($css) {case 'top':return CSS_MARGIN_BOX_SELECTOR_TOP;case 'top-left-corner':return CSS_MARGIN_BOX_SELECTOR_TOP_LEFT_CORNER;case 'top-left':return CSS_MARGIN_BOX_SELECTOR_TOP_LEFT;case 'top-center':return CSS_MARGIN_BOX_SELECTOR_TOP_CENTER;case 'top-right':return CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT;case 'top-right-corner':return CSS_MARGIN_BOX_SELECTOR_TOP_RIGHT_CORNER;case 'bottom':return CSS_MARGIN_BOX_SELECTOR_BOTTOM;case 'bottom-left-corner':return CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT_CORNER;case 'bottom-left':return CSS_MARGIN_BOX_SELECTOR_BOTTOM_LEFT;case 'bottom-center':return CSS_MARGIN_BOX_SELECTOR_BOTTOM_CENTER;case 'bottom-right':return CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT;case 'bottom-right-corner':return CSS_MARGIN_BOX_SELECTOR_BOTTOM_RIGHT_CORNER;case 'left-top':return CSS_MARGIN_BOX_SELECTOR_LEFT_TOP;case 'left-middle':return CSS_MARGIN_BOX_SELECTOR_LEFT_MIDDLE;case 'left-bottom':return CSS_MARGIN_BOX_SELECTOR_LEFT_BOTTOM;case 'right-top':return CSS_MARGIN_BOX_SELECTOR_RIGHT_TOP;case 'right-middle':return CSS_MARGIN_BOX_SELECTOR_RIGHT_MIDDLE;case 'right-bottom':return CSS_MARGIN_BOX_SELECTOR_RIGHT_BOTTOM;default:error_log(sprintf('Unrecognized margin box selector: \'%s\'', $css));return CSS_MARGIN_BOX_SELECTOR_TOP;}};function parse_css_atpage_declaration($css, &$at_rule, &$pipeline) {$parsed =& parse_css_property($css, $pipeline);if (!is_null($parsed)) {$properties = $parsed->getPropertiesSortedByPriority();foreach ($properties as $property) {$at_rule->setCSSProperty($property);};};}function parse_css_atpage_margin_box_declaration($css, &$at_rule, &$pipeline) {$parsed =& parse_css_property($css, $pipeline);if (!is_null($parsed)) {$properties = $parsed->getPropertiesSortedByPriority();foreach ($properties as $property) {$at_rule->setCSSProperty($property);};};}?>