* @license PHP License * @package wb * @subpackage Markup */ WBClass::load('WBMarkup_Handler'); /** * Markup Handler: I18nExtractor * * Extract to-be-translated strings from markup files like templates * and XML config files. * * @version 0.1.0 * @package wb * @subpackage Markup */ class WBMarkup_Handler_I18nExtractor implements WBMarkup_Handler { /** * Text importer * @var patI18n_Importer */ protected $imp; /** * current depth * @var int */ protected $depth = 0; /** * document nodes * @var array */ protected $doc = array(); /** * set text importer * * @param patI18n_Importer $imp */ public function setImporter($imp) { $this->imp = $imp; } /** * handler on start beginning of scan * * * * @param string $content * @return bool usually true, false to stop the scanner */ public function onScanStart(&$content) { $this->con = array(); $this->depth = 0; $this->doc = array(); $this->doc[0] = array( 'ns' => '', 'tag' => '', 'attributes' => array(), 'isEmpty' => false, 'cData' => array(), ); return true; } /** * handler on start element * * @param string $ns The used namespace, if set. otherwise null * @param string $tag the tag itself * @param array $attributes the attributes of the found element * @param bool $isEmpty true if it is a start- and closing-Element (e.g.
) * @return bool usually true, false to stop the scanner */ public function onStartElement($ns, $tag, $attributes, $isEmpty) { ++$this->depth; $this->doc[$this->depth] = array( 'ns' => $ns, 'tag' => $tag, 'attributes' => $attributes, 'isEmpty' => $isEmpty, 'cData' => array() ); return true; } /** * handler fo cData * * Simply add cDate to document * * @uses replaceUrlString() * @param string $cData character data * @return bool usually true, false to stop the scanner */ public function onCharacterData($cData) { $this->doc[$this->depth]['cData'][] = $cData; return true; } /** * handler for entities * * Add entities to document's cData * * @param string $entity the entity element, e.g. nbsp for   * @param boolean $isUnicode true = the element is a unicode string */ public function onEntityElement($entity, $isUnicode) { $cData = '&'; if( $isUnicode ) { $cData .= '#'; } $cData .= $entity . ';'; $this->doc[$this->depth]['cData'][] = $cData; return true; } /** * test handler on end element * * @param string $ns The used namespace, if set. otherwise null * @param string $tag the tag itself * @param bool $empty defines if the tag is empty * @return bool usually true, false to stop the scanner */ public function onEndElement($ns, $tag, $empty) { // serialize node if( !$this->depth ) { return true; } $node = array_pop($this->doc); $this->extract($node); --$this->depth; if( $this->depth < 0 ) { $this->depth = 0; } $this->doc[$this->depth]['cData'][] = $this->node2String($node); return true; } /** * called right after scan is complete * * @return bool usually true, false to stop the scanner */ public function onScanComplete() { return true; } /** * receive translated content string * * @return string */ public function getParsedContent() { return $this->node2String($this->doc[0]); } /** * serialize document node * * @param array $node * @return string serialized attributes */ protected function node2String($node) { $cData = implode('', $node['cData']); if (!$node['tag']) { return $cData; } $tag = ''; if ($node['ns']) { $tag .= $node['ns'] . ':'; } $tag .= $node['tag']; $element = '<' . $tag . $this->attributes2String($node['attributes']); if ($node['isEmpty']) { $element .= ' />'; return $element; } $element .= '>' . $cData . ''; return $element; } /** * serialize attribute list to HTML attribute string * * @param array $att attribute list * @return string serialized attributes */ protected function attributes2String($att) { if (empty($att)) { return ''; } $str = ''; foreach ($att as $k => $v) { $str .= ' ' . $k . '="' . $v . '"'; } return $str; } /** * extract translatable strings from node * * Do the magic thing * * @param array $node */ protected function extract($node) { } } ?>