/** * Callback for: <tag attr="...">. * * @param TexyLineParser * @param array regexp matches * @param string pattern name * @return TexyHtml|string|FALSE */ public function patternTag($parser, $matches) { list(, $mEnd, $mTag, $mAttr, $mEmpty) = $matches; // [1] => / // [2] => tag // [3] => attributes // [4] => / $tx = $this->texy; $isStart = $mEnd !== '/'; $isEmpty = $mEmpty === '/'; if (!$isEmpty && substr($mAttr, -1) === '/') { // uvizlo v $mAttr? $mAttr = substr($mAttr, 0, -1); $isEmpty = TRUE; } // error - can't close empty element if ($isEmpty && !$isStart) { return FALSE; } // error - end element with atttrs $mAttr = trim(strtr($mAttr, "\n", ' ')); if ($mAttr && !$isStart) { return FALSE; } $el = TexyHtml::el($mTag); if ($isStart) { // parse attributes $matches2 = NULL; preg_match_all('#([a-z0-9:-]+)\\s*(?:=\\s*(\'[^\']*\'|"[^"]*"|[^\'"\\s]+))?()#isu', $mAttr, $matches2, PREG_SET_ORDER); foreach ($matches2 as $m) { $key = strtolower($m[1]); $value = $m[2]; if ($value == NULL) { $el->attrs[$key] = TRUE; } elseif ($value[0] === '\'' || $value[0] === '"') { $el->attrs[$key] = Texy::unescapeHtml(substr($value, 1, -1)); } else { $el->attrs[$key] = Texy::unescapeHtml($value); } } } $res = $tx->invokeAroundHandlers('htmlTag', $parser, array($el, $isStart, $isEmpty)); if ($res instanceof TexyHtml) { return $tx->protect($isStart ? $res->startTag() : $res->endTag(), $res->getContentType()); } return $res; }
public function patternPhrase($parser, $matches, $phrase) { list(, $mContent, $mMod, $mLink) = $matches; $tx = $this->texy; $mod = new TexyModifier($mMod); $link = NULL; $parser->again = $phrase !== 'phrase/code' && $phrase !== 'phrase/quicklink'; if ($phrase === 'phrase/span' || $phrase === 'phrase/span-alt') { if ($mLink == NULL) { if (!$mMod) { return FALSE; } } else { $link = $tx->linkModule->factoryLink($mLink, $mMod, $mContent); } } elseif ($phrase === 'phrase/acronym' || $phrase === 'phrase/acronym-alt') { $mod->title = trim(Texy::unescapeHtml($mLink)); } elseif ($phrase === 'phrase/quote') { $mod->cite = $tx->blockQuoteModule->citeLink($mLink); } elseif ($mLink != NULL) { $link = $tx->linkModule->factoryLink($mLink, NULL, $mContent); } return $tx->invokeAroundHandlers('phrase', $parser, array($phrase, $mContent, $mod, $link)); }
/** * Callback for: **.... .(title)[class]{style}**:LINK. * * @param TexyLineParser * @param array regexp matches * @param string pattern name * * @return TexyHtml|string|FALSE */ public function patternPhrase($parser, $matches, $phrase) { list(, $mContent, $mMod, $mLink) = $matches; // [1] => ** // [2] => ... // [3] => .(title)[class]{style} // [4] => LINK $tx = $this->texy; $mod = new TexyModifier($mMod); $link = null; $parser->again = $phrase !== 'phrase/code' && $phrase !== 'phrase/quicklink'; if ($phrase === 'phrase/span' || $phrase === 'phrase/span-alt') { if ($mLink == null) { if (!$mMod) { return false; } // means "..." } else { $link = $tx->linkModule->factoryLink($mLink, $mMod, $mContent); } } elseif ($phrase === 'phrase/acronym' || $phrase === 'phrase/acronym-alt') { $mod->title = trim(Texy::unescapeHtml($mLink)); } elseif ($phrase === 'phrase/quote') { $mod->cite = $tx->blockQuoteModule->citeLink($mLink); } elseif ($mLink != null) { $link = $tx->linkModule->factoryLink($mLink, null, $mContent); } return $tx->invokeAroundHandlers('phrase', $parser, array($phrase, $mContent, $mod, $link)); }
public function setProperties($mod) { if (!$mod) { return; } $p = 0; $len = strlen($mod); while ($p < $len) { $ch = $mod[$p]; if ($ch === '(') { // title $a = strpos($mod, ')', $p) + 1; $this->title = Texy::unescapeHtml(trim(substr($mod, $p + 1, $a - $p - 2))); $p = $a; } elseif ($ch === '{') { // style & attributes $a = strpos($mod, '}', $p) + 1; foreach (explode(';', substr($mod, $p + 1, $a - $p - 2)) as $value) { $pair = explode(':', $value, 2); $prop = strtolower(trim($pair[0])); if ($prop === '' || !isset($pair[1])) { continue; } $value = trim($pair[1]); if (isset(self::$elAttrs[$prop])) { $this->attrs[$prop] = $value; } elseif ($value !== '') { $this->styles[$prop] = $value; } } $p = $a; } elseif ($ch === '[') { // classes & ID $a = strpos($mod, ']', $p) + 1; $s = str_replace('#', ' #', substr($mod, $p + 1, $a - $p - 2)); foreach (explode(' ', $s) as $value) { if ($value === '') { continue; } if ($value[0] === '#') { $this->id = substr($value, 1); } else { $this->classes[$value] = true; } } $p = $a; } elseif ($ch === '^') { $this->vAlign = 'top'; $p++; } elseif ($ch === '-') { $this->vAlign = 'middle'; $p++; } elseif ($ch === '_') { $this->vAlign = 'bottom'; $p++; } elseif ($ch === '=') { $this->hAlign = 'justify'; $p++; } elseif ($ch === '>') { $this->hAlign = 'right'; $p++; } elseif (substr($mod, $p, 2) === '<>') { $this->hAlign = 'center'; $p += 2; } elseif ($ch === '<') { $this->hAlign = 'left'; $p++; } else { break; } } }
/** * Finish invocation. * * @param TexyHandlerInvocation handler invocation * @param string blocktype * @param string content * @param string additional parameter * @param TexyModifier * @return TexyHtml|string|FALSE */ public function solve($invocation, $blocktype, $s, $param, $mod) { $tx = $this->texy; $parser = $invocation->parser; if ($blocktype === 'block/texy') { $el = TexyHtml::el(); $el->parseBlock($tx, $s, $parser->isIndented()); return $el; } if (empty($tx->allowed[$blocktype])) { return FALSE; } if ($blocktype === 'block/texysource') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el(); if ($param === 'line') { $el->parseLine($tx, $s); } else { $el->parseBlock($tx, $s); } $s = $el->toHtml($tx); $blocktype = 'block/code'; $param = 'html'; // to be continue (as block/code) } if ($blocktype === 'block/code') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $s = Texy::escapeHtml($s); $s = $tx->protect($s, Texy::CONTENT_BLOCK); $el = TexyHtml::el('pre'); $mod->decorate($tx, $el); $el->attrs['class'][] = $param; // lang $el->create('code', $s); return $el; } if ($blocktype === 'block/default') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('pre'); $mod->decorate($tx, $el); $el->attrs['class'][] = $param; // lang $s = Texy::escapeHtml($s); $s = $tx->protect($s, Texy::CONTENT_BLOCK); $el->setText($s); return $el; } if ($blocktype === 'block/pre') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('pre'); $mod->decorate($tx, $el); $lineParser = new TexyLineParser($tx, $el); // special mode - parse only html tags $tmp = $lineParser->patterns; $lineParser->patterns = array(); if (isset($tmp['html/tag'])) { $lineParser->patterns['html/tag'] = $tmp['html/tag']; } if (isset($tmp['html/comment'])) { $lineParser->patterns['html/comment'] = $tmp['html/comment']; } unset($tmp); $lineParser->parse($s); $s = $el->getText(); $s = Texy::unescapeHtml($s); $s = Texy::escapeHtml($s); $s = $tx->unprotect($s); $s = $tx->protect($s, Texy::CONTENT_BLOCK); $el->setText($s); return $el; } if ($blocktype === 'block/html') { $s = trim($s, "\n"); if ($s === '') { return "\n"; } $el = TexyHtml::el(); $lineParser = new TexyLineParser($tx, $el); // special mode - parse only html tags $tmp = $lineParser->patterns; $lineParser->patterns = array(); if (isset($tmp['html/tag'])) { $lineParser->patterns['html/tag'] = $tmp['html/tag']; } if (isset($tmp['html/comment'])) { $lineParser->patterns['html/comment'] = $tmp['html/comment']; } unset($tmp); $lineParser->parse($s); $s = $el->getText(); $s = Texy::unescapeHtml($s); $s = Texy::escapeHtml($s); $s = $tx->unprotect($s); return $tx->protect($s, Texy::CONTENT_BLOCK) . "\n"; } if ($blocktype === 'block/text') { $s = trim($s, "\n"); if ($s === '') { return "\n"; } $s = Texy::escapeHtml($s); $s = str_replace("\n", TexyHtml::el('br')->startTag(), $s); // nl2br return $tx->protect($s, Texy::CONTENT_BLOCK) . "\n"; } if ($blocktype === 'block/comment') { return "\n"; } if ($blocktype === 'block/div') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('div'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } if ($blocktype === 'block/section') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('section'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } if ($blocktype === 'block/article') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('article'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } if ($blocktype === 'block/aside') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('aside'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } if ($blocktype === 'block/header') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('header'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } if ($blocktype === 'block/footer') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('footer'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } if ($blocktype === 'block/nav') { $s = Texy::outdent($s); if ($s === '') { return "\n"; } $el = TexyHtml::el('nav'); $mod->decorate($tx, $el); $el->parseBlock($tx, $s, $parser->isIndented()); // TODO: INDENT or NORMAL ? return $el; } return FALSE; }
/** * Callback for: **.... .(title)[class]{style}**:LINK. * * @param TexyLineParser * @param array regexp matches * @param string pattern name * @return TexyHtml|string|FALSE */ public function patternPhrase($parser, $matches, $phrase) { list(, $mContent, $mMod, $mLink) = $matches; // [1] => ** // [2] => ... // [3] => .(title)[class]{style} // [4] => LINK $tx = $this->texy; $mod = new TexyModifier($mMod); $link = NULL; $html5 = $tx->getOutputMode() === Texy::HTML5 || $tx->getOutputMode() === Texy::HTML5 | Texy::XML; if ($html5) { $this->tags['phrase/acronym'] = 'abbr'; $this->tags['phrase/acronym-alt'] = 'abbr'; } $parser->again = $phrase !== 'phrase/code' && $phrase !== 'phrase/quicklink'; if ($phrase === 'phrase/span' || $phrase === 'phrase/span-alt') { if ($mLink == NULL) { if (!$mMod) { return FALSE; } // means "..." } else { $link = $tx->linkModule->factoryLink($mLink, $mMod, $mContent); } } elseif ($phrase === 'phrase/acronym' || $phrase === 'phrase/acronym-alt') { $mod->title = trim(Texy::unescapeHtml($mLink)); } elseif ($phrase === 'phrase/quote') { $mod->cite = $tx->blockQuoteModule->citeLink($mLink); } elseif ($mLink != NULL) { $link = $tx->linkModule->factoryLink($mLink, NULL, $mContent); } return $tx->invokeAroundHandlers('phrase', $parser, array($phrase, $mContent, $mod, $link)); }