HtmlAssembler.class.php

Go to the documentation of this file.
00001 <?php
00002 /***************************************************************************
00003  *   Copyright (C) 2007 by Ivan Y. Khvostishkov                            *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU Lesser General Public License as        *
00007  *   published by the Free Software Foundation; either version 3 of the    *
00008  *   License, or (at your option) any later version.                       *
00009  *                                                                         *
00010  ***************************************************************************/
00011 
00015     final class HtmlAssembler
00016     {
00017         private $tags   = null;
00018         
00019         public function __construct($tags)
00020         {
00021             Assert::isTrue(current($tags) instanceof SgmlToken);
00022             
00023             $this->tags = $tags;
00024         }
00025         
00026         public static function makeTag(SgmlToken $tag)
00027         {
00028             if ($tag instanceof Cdata)
00029                 $result = $tag->getData();
00030             elseif ($tag instanceof SgmlIgnoredTag) {
00031                 Assert::isNotNull($tag->getId());
00032                 
00033                 $result = '<'.$tag->getId()
00034                     .$tag->getCdata()->getData()
00035                     .$tag->getEndMark().'>';
00036                 
00037             } elseif ($tag instanceof SgmlOpenTag) {
00038                 Assert::isNotNull($tag->getId());
00039                 
00040                 $attributes = self::getAttributes($tag);
00041                 
00042                 $result = '<'.$tag->getId()
00043                     .($attributes ? ' '.$attributes : null)
00044                     .($tag->isEmpty() ? '/' : null).'>';
00045                 
00046             } elseif ($tag instanceof SgmlEndTag) {
00047                 $result = '</'.$tag->getId().'>';
00048                 
00049             } else
00050                 throw new WrongArgumentException(
00051                     "don't know how to assemble tag class '"
00052                     .get_class($tag)."'"
00053                 );
00054             
00055             return $result;
00056         }
00057         
00058         public static function makeDomNode(DOMNode $node)
00059         {
00060                 $result = null;
00061                 
00062                 if ($node instanceof DOMElement) {
00063                         
00064                         $result = '<'.$node->nodeName;
00065                         
00066                         $attributes = self::getDomAttributes($node);
00067                         
00068                         if ($attributes)
00069                                 $result .= ' '.$attributes;
00070                         
00071                         if (!$node->firstChild) {
00072                                 $result .= ' />';
00073                         } else {
00074                                 $result .= '>';
00075                         }
00076                         
00077                         $childNode = $node->firstChild;
00078                         
00079                         while ($childNode) {
00080                                 $result .= self::makeDomNode($childNode);
00081                                 $childNode = $childNode->nextSibling;
00082                         }
00083                         
00084                         if ($node->firstChild)
00085                                 $result .= '</'.$node->nodeName.'>';
00086                         
00087                 } elseif ($node instanceof DOMCharacterData) {
00088                         
00089                         $result = $node->data;
00090                         
00091                 } else {
00092                         throw new UnimplementedFeatureException(
00093                                 'assembling of '.get_class($node).' is not implemented yet'
00094                         );
00095                 }
00096                 
00097                 return $result;
00098         }
00099         
00100         public function getHtml()
00101         {
00102             $result = null;
00103             
00104             foreach ($this->tags as $tag) {
00105                 $result .= self::makeTag($tag);
00106             }
00107             
00108             return $result;
00109         }
00110         
00111         private static function getAttributes(SgmlOpenTag $tag)
00112         {
00113             $attributes = array();
00114             
00115             foreach ($tag->getAttributesList() as $name => $value) {
00116                 if ($value === null)
00117                     $quotedValue = null;
00118                 else
00119                     // FIXME: is multibyte safe?
00120                     $quotedValue = '="'.str_replace('"', '&quot;', $value).'"';
00121                 
00122                 $attributes[] = $name.$quotedValue;
00123             }
00124             
00125             return implode(' ', $attributes);
00126         }
00127         
00128         private static function getDomAttributes(DOMNode $node)
00129         {
00130             $result = null;
00131             
00132             $attributes = array();
00133             
00134             if ($node->attributes) {
00135                 $i = 0;
00136                 
00137                 while ($item = $node->attributes->item($i)) {
00138                     $attributes[] = $item->name.'="'.$item->value.'"';
00139                     
00140                     ++$i;
00141                 }
00142             }
00143             
00144             if ($attributes)
00145                 $result = implode(' ', $attributes);
00146             
00147             return $result;
00148         }
00149     }
00150 ?>