|
TYPO3 API
SVNRelease
|
00001 <?php 00002 00003 /* * 00004 * This script belongs to the FLOW3 package "Fluid". * 00005 * * 00006 * It is free software; you can redistribute it and/or modify it under * 00007 * the terms of the GNU Lesser General Public License as published by the * 00008 * Free Software Foundation, either version 3 of the License, or (at your * 00009 * option) any later version. * 00010 * * 00011 * This script is distributed in the hope that it will be useful, but * 00012 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHAN- * 00013 * TABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser * 00014 * General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU Lesser General Public * 00017 * License along with the script. * 00018 * If not, see http://www.gnu.org/licenses/lgpl.html * 00019 * * 00020 * The TYPO3 project - inspiring people to share! * 00021 * */ 00022 00023 /** 00024 * XML Schema (XSD) Generator. Will generate an XML schema which can be used for autocompletion 00025 * in schema-aware editors like Eclipse XML editor. 00026 * 00027 * @license http://www.gnu.org/licenses/lgpl.html GNU Lesser General Public License, version 3 or later 00028 */ 00029 class Tx_Fluid_Service_DocbookGenerator extends Tx_Fluid_Service_AbstractGenerator { 00030 00031 /** 00032 * Generate the XML Schema definition for a given namespace. 00033 * 00034 * @param string $namespace Namespace identifier to generate the XSD for, without leading Backslash. 00035 * @return string XML Schema definition 00036 * @author Sebastian Kurfürst <sebastian@typo3.org> 00037 */ 00038 public function generateDocbook($namespace) { 00039 if (substr($namespace, -1) !== Tx_Fluid_Fluid::NAMESPACE_SEPARATOR) { 00040 $namespace .= Tx_Fluid_Fluid::NAMESPACE_SEPARATOR; 00041 } 00042 00043 $classNames = $this->getClassNamesInNamespace($namespace); 00044 00045 $xmlRootNode = new SimpleXMLElement('<?xml version="1.0" encoding="UTF-8"?> 00046 <section version="5.0" xmlns="http://docbook.org/ns/docbook" 00047 xml:id="fluid.usermanual.standardviewhelpers" 00048 xmlns:xl="http://www.w3.org/1999/xlink" 00049 xmlns:xi="http://www.w3.org/2001/XInclude" 00050 xmlns:xhtml="http://www.w3.org/1999/xhtml" 00051 xmlns:svg="http://www.w3.org/2000/svg" 00052 xmlns:ns="http://docbook.org/ns/docbook" 00053 xmlns:mathml="http://www.w3.org/1998/Math/MathML"> 00054 <title>Standard View Helper Library</title> 00055 00056 <para>Should be autogenerated from the tags.</para> 00057 </section>'); 00058 00059 foreach ($classNames as $className) { 00060 $this->generateXmlForClassName($className, $namespace, $xmlRootNode); 00061 } 00062 00063 return $xmlRootNode->asXML(); 00064 } 00065 00066 /** 00067 * Generate the XML Schema for a given class name. 00068 * 00069 * @param string $className Class name to generate the schema for. 00070 * @param string $namespace Namespace prefix. Used to split off the first parts of the class name. 00071 * @param SimpleXMLElement $xmlRootNode XML root node where the xsd:element is appended. 00072 * @return void 00073 * @author Sebastian Kurfürst <sebastian@typo3.org> 00074 */ 00075 protected function generateXmlForClassName($className, $namespace, SimpleXMLElement $xmlRootNode) { 00076 $reflectionClass = new Tx_Extbase_Reflection_ClassReflection($className); 00077 if (!$reflectionClass->isSubclassOf($this->abstractViewHelperReflectionClass)) { 00078 return; 00079 } 00080 00081 $tagName = $this->getTagNameForClass($className, $namespace); 00082 00083 $docbookSection = $xmlRootNode->addChild('section'); 00084 00085 $docbookSection->addChild('title', $tagName); 00086 $this->docCommentParser->parseDocComment($reflectionClass->getDocComment()); 00087 $this->addDocumentation($this->docCommentParser->getDescription(), $docbookSection); 00088 00089 $argumentsSection = $docbookSection->addChild('section'); 00090 $argumentsSection->addChild('title', 'Arguments'); 00091 $this->addArguments($className, $argumentsSection); 00092 00093 return $docbookSection; 00094 } 00095 00096 /** 00097 * Add attribute descriptions to a given tag. 00098 * Initializes the view helper and its arguments, and then reads out the list of arguments. 00099 * 00100 * @param string $className Class name where to add the attribute descriptions 00101 * @param SimpleXMLElement $docbookSection DocBook section to add the attributes to. 00102 * @return void 00103 * @author Sebastian Kurfürst <sebastian@typo3.org> 00104 */ 00105 protected function addArguments($className, SimpleXMLElement $docbookSection) { 00106 $viewHelper = $this->instanciateViewHelper($className); 00107 $argumentDefinitions = $viewHelper->prepareArguments(); 00108 00109 if (count($argumentDefinitions) === 0) { 00110 $docbookSection->addChild('para', 'No arguments defined.'); 00111 return; 00112 } 00113 $argumentsTable = $docbookSection->addChild('table'); 00114 $argumentsTable->addChild('title', 'Arguments'); 00115 $tgroup = $argumentsTable->addChild('tgroup'); 00116 $tgroup['cols'] = 4; 00117 $this->addArgumentTableRow($tgroup->addChild('thead'), 'Name', 'Type', 'Required', 'Description', 'Default'); 00118 00119 $tbody = $tgroup->addChild('tbody'); 00120 00121 foreach ($argumentDefinitions as $argumentDefinition) { 00122 $this->addArgumentTableRow($tbody, $argumentDefinition->getName(), $argumentDefinition->getType(), ($argumentDefinition->isRequired()?'yes':'no'), $argumentDefinition->getDescription(), $argumentDefinition->getDefaultValue()); 00123 } 00124 } 00125 00126 /** 00127 * Instantiate a view helper. 00128 * 00129 * @param string $className 00130 * @return object 00131 */ 00132 protected function instanciateViewHelper($className) { 00133 return $this->objectManager->get($className); 00134 } 00135 00136 /** 00137 * @param SimpleXMLElement $parent 00138 * @param string $name 00139 * @param string $type 00140 * @param boolean $required 00141 * @param string $description 00142 * @param string $default 00143 * @return void 00144 */ 00145 private function addArgumentTableRow(SimpleXMLElement $parent, $name, $type, $required, $description, $default) { 00146 $row = $parent->addChild('row'); 00147 00148 $row->addChild('entry', $name); 00149 $row->addChild('entry', $type); 00150 $row->addChild('entry', $required); 00151 $row->addChild('entry', $description); 00152 $row->addChild('entry', (string)$default); 00153 } 00154 00155 /** 00156 * Add documentation XSD to a given XML node 00157 * 00158 * As Eclipse renders newlines only on new <xsd:documentation> tags, we wrap every line in a new 00159 * <xsd:documentation> tag. 00160 * Furthermore, eclipse strips out tags - the only way to prevent this is to have every line wrapped in a 00161 * CDATA block AND to replace the < and > with their XML entities. (This is IMHO not XML conformant). 00162 * 00163 * @param string $documentation Documentation string to add. 00164 * @param SimpleXMLElement $docbookSection Node to add the documentation to 00165 * @return void 00166 * @author Sebastian Kurfürst <sebastian@typo3.org> 00167 */ 00168 protected function addDocumentation($documentation, SimpleXMLElement $docbookSection) { 00169 $splitRegex = '/^\s*(=[^=]+=)$/m'; 00170 $regex = '/^\s*(=([^=]+)=)$/m'; 00171 00172 $matches = preg_split($splitRegex, $documentation, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); 00173 00174 $currentSection = $docbookSection; 00175 foreach ($matches as $singleMatch) { 00176 if (preg_match($regex, $singleMatch, $tmp)) { 00177 $currentSection = $docbookSection->addChild('section'); 00178 $currentSection->addChild('title', trim($tmp[2])); 00179 } else { 00180 $this->addText(trim($singleMatch), $currentSection); 00181 } 00182 } 00183 } 00184 00185 /** 00186 * @param string $text 00187 * @param SimpleXMLElement $parentElement 00188 */ 00189 protected function addText($text, SimpleXMLElement $parentElement) { 00190 $splitRegex = '/ 00191 (<code(?:.*?)> 00192 (?:.*?) 00193 <\/code>)/xs'; 00194 00195 $regex = '/ 00196 <code(.*?)> 00197 (.*?) 00198 <\/code>/xs'; 00199 $matches = preg_split($splitRegex, $text, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE ); 00200 foreach ($matches as $singleMatch) { 00201 00202 if (preg_match($regex, $singleMatch, $tmp)) { 00203 preg_match('/title="([^"]+)"/', $tmp[1], $titleMatch); 00204 00205 $example = $parentElement->addChild('example'); 00206 if (count($titleMatch)) { 00207 $example->addChild('title', trim($titleMatch[1])); 00208 } else { 00209 $example->addChild('title', 'Example'); 00210 } 00211 $this->addChildWithCData($example, 'programlisting', trim($tmp[2])); 00212 } else { 00213 $textParts = explode("\n", $singleMatch); 00214 foreach ($textParts as $text) { 00215 if (trim($text) === '') continue; 00216 $this->addChildWithCData($parentElement, 'para', trim($text)); 00217 } 00218 } 00219 } 00220 } 00221 } 00222 ?>
1.8.0