/** * @param TexyBlockParser * @param string text * @param array * @param TexyHtml * @return vois */ public function process($parser, $content, $el) { $tx = $this->texy; if ($parser->isIndented()) { $parts = preg_split('#(\\n(?! )|\\n{2,})#', $content, -1, PREG_SPLIT_NO_EMPTY); } else { $parts = preg_split('#(\\n{2,})#', $content, -1, PREG_SPLIT_NO_EMPTY); } foreach ($parts as $s) { $s = trim($s); if ($s === '') { continue; } // try to find modifier $mod = NULL; if ($mx = TexyRegexp::match($s, '#' . TexyPatterns::MODIFIER_H . '(?=\\n|\\z)#sUm', TexyRegexp::OFFSET_CAPTURE)) { list($mMod) = $mx[1]; $s = trim(substr_replace($s, '', $mx[0][1], strlen($mx[0][0]))); if ($s === '') { continue; } $mod = new TexyModifier(); $mod->setProperties($mMod); } $res = $tx->invokeAroundHandlers('paragraph', $parser, array($s, $mod)); if ($res) { $el->insert(NULL, $res); } } }
/** * @param TexyBlockParser * @param string text * @param array * @param TexyHtml * @return vois */ public function process($parser, $content, $el) { $tx = $this->texy; if ($parser->isIndented()) { $parts = preg_split('#(\\n(?! )|\\n{2,})#', $content, -1, PREG_SPLIT_NO_EMPTY); } else { $parts = preg_split('#(\\n{2,})#', $content, -1, PREG_SPLIT_NO_EMPTY); } foreach ($parts as $s) { $s = trim($s); if ($s === '') { continue; } // try to find modifier $mx = $mod = NULL; if (preg_match('#\\A(.*)(?<=\\A|\\S)' . TEXY_MODIFIER_H . '(\\n.*)?()\\z#sUm', $s, $mx)) { list(, $mC1, $mMod, $mC2) = $mx; $s = trim($mC1 . $mC2); if ($s === '') { continue; } $mod = new TexyModifier(); $mod->setProperties($mMod); } $res = $tx->invokeAroundHandlers('paragraph', $parser, array($s, $mod)); if ($res) { $el->insert(NULL, $res); } } }
/** * @param TexyBlockParser * @param string text * @param array * @param TexyHtml * @return vois */ public function process($parser, $content, $el) { $tx = $this->texy; if ($parser->isIndented()) { $parts = preg_split('#(\n(?! )|\n{2,})#', $content, -1, PREG_SPLIT_NO_EMPTY); } else { $parts = preg_split('#(\n{2,})#', $content, -1, PREG_SPLIT_NO_EMPTY); } foreach ($parts as $s) { $s = trim($s); if ($s === '') continue; // try to find modifier $mx = $mod = NULL; if (preg_match('#'.TEXY_MODIFIER_H.'(?=\n|\z)#sUm', $s, $mx, PREG_OFFSET_CAPTURE)) { list($mMod) = $mx[1]; $s = trim(substr_replace($s, '', $mx[0][1], strlen($mx[0][0]))); if ($s === '') continue; $mod = new TexyModifier; $mod->setProperties($mMod); } elseif (TEXY_CHECK_PCRE && preg_last_error()) { throw new TexyPcreException; } $res = $tx->invokeAroundHandlers('paragraph', $parser, array($s, $mod)); if ($res) $el->insert(NULL, $res); } }
/** * Callback for:. * * > They went in single file, running like hounds on a strong scent, * and an eager light was in their eyes. Nearly due west the broad * swath of the marching Orcs tramped its ugly slot; the sweet grass * of Rohan had been bruised and blackened as they passed. * >:http://www.mycom.com/tolkien/twotowers.html * * @param TexyBlockParser * @param array regexp matches * @param string pattern name * @return TexyHtml|string|FALSE */ public function pattern($parser, $matches) { list(, $mMod, $mPrefix, $mContent) = $matches; // [1] => .(title)[class]{style}<> // [2] => spaces | // [3] => ... / LINK $tx = $this->texy; $el = TexyHtml::el('blockquote'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $el); $content = ''; $spaces = ''; do { if ($mPrefix === ':') { $mod->cite = $tx->blockQuoteModule->citeLink($mContent); $content .= "\n"; } else { if ($spaces === '') $spaces = max(1, strlen($mPrefix)); $content .= $mContent . "\n"; } if (!$parser->next("#^>(?:|(\\ {1,$spaces}|:)(.*))()$#mA", $matches)) break; /* if ($mPrefix === '>') { $content .= $mPrefix . $mContent . "\n"; } elseif ($mPrefix === ':') { $mod->cite = $tx->blockQuoteModule->citeLink($mContent); $content .= "\n"; } else { if ($spaces === '') $spaces = max(1, strlen($mPrefix)); $content .= $mContent . "\n"; } if (!$parser->next("#^\\>(?:(\\>|\\ {1,$spaces}|:)(.*))?()$#mA", $matches)) break; */ list(, $mPrefix, $mContent) = $matches; } while (TRUE); $el->attrs['cite'] = $mod->cite; $el->parseBlock($tx, $content, $parser->isIndented()); // no content? if (!$el->count()) return FALSE; // event listener $tx->invokeHandlers('afterBlockquote', array($parser, $el, $mod)); return $el; }
/** * Pattern handler for inline syntaxes * * @param TexyLineParser * @param array reg-exp matches * @param string pattern name (myInlineSyntax1 or myInlineSyntax2) * @return TexyHtml|string */ function userInlineHandler($parser, $matches, $name) { list(, $mContent, $mMod) = $matches; $texy = $parser->getTexy(); // create element $tag = $name === 'myInlineSyntax1' ? 'b' : 'i'; $el = TexyHtml::el($tag); // apply modifier $mod = new TexyModifier($mMod); $mod->decorate($texy, $el); $el->attrs['class'] = 'myclass'; $el->setText($mContent); // parse inner content of this element $parser->again = TRUE; return $el; }
function wiki_texy_InlineHandler($parser, $matches, $name) { list(, $mContent, $mMod) = $matches; $texy = $parser->getTexy(); $tag = 'a'; $el = TexyHtml::el($tag); $mod = new TexyModifier($mMod); $mod->decorate($texy, $el); if ($name == 'wikilink') { $el->attrs['href'] = '?page=' . urlencode($mContent); } else { $el->attrs['href'] = $mContent; } $el->attrs['class'] = $name; $el->setText($mContent); $parser->again = TRUE; return $el; }
public function patternTable($parser, $matches) { list(, $mMod) = $matches; $tx = $this->texy; $el = TexyHtml::el('table'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $el); $parser->moveBackward(); if ($parser->next('#^\\|(\\#|\\=){2,}(?![|\\#=+])(.+)\\1*\\|? *' . TEXY_MODIFIER_H . '?()$#Um', $matches)) { list(, , $mContent, $mMod) = $matches; $caption = $el->create('caption'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $caption); $caption->parseLine($tx, $mContent); } $isHead = FALSE; $colModifier = array(); $prevRow = array(); $rowCounter = 0; $colCounter = 0; $elPart = NULL; $lineMode = FALSE; while (TRUE) { if ($parser->next('#^\\|([=-])[+|=-]{2,}$#Um', $matches)) { if ($lineMode) { if ($matches[1] === '=') { $isHead = !$isHead; } } else { $isHead = !$isHead; $lineMode = $matches[1] === '='; } $prevRow = array(); continue; } if ($parser->next('#^\\|(.*)(?:|\\|\\ *' . TEXY_MODIFIER_HV . '?)()$#U', $matches)) { if ($rowCounter === 0 && !$isHead && $parser->next('#^\\|[=-][+|=-]{2,}$#Um', $foo)) { $isHead = TRUE; $parser->moveBackward(); } if ($elPart === NULL) { $elPart = $el->create($isHead ? 'thead' : 'tbody'); } elseif (!$isHead && $elPart->getName() === 'thead') { $this->finishPart($elPart); $elPart = $el->create('tbody'); } list(, $mContent, $mMod) = $matches; $elRow = TexyHtml::el('tr'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $elRow); $rowClass = $rowCounter % 2 === 0 ? $this->oddClass : $this->evenClass; if ($rowClass && !isset($mod->classes[$this->oddClass]) && !isset($mod->classes[$this->evenClass])) { $elRow->attrs['class'][] = $rowClass; } $col = 0; $elCell = NULL; $mContent = str_replace('\\|', '|', $mContent); foreach (explode('|', $mContent) as $cell) { if (isset($prevRow[$col]) && ($lineMode || preg_match('#\\^\\ *$|\\*??(.*)\\ +\\^$#AU', $cell, $matches))) { $prevRow[$col]->rowSpan++; if (!$lineMode) { $cell = isset($matches[1]) ? $matches[1] : ''; } $prevRow[$col]->text .= "\n" . $cell; $col += $prevRow[$col]->colSpan; $elCell = NULL; continue; } if ($cell === '' && $elCell) { $elCell->colSpan++; unset($prevRow[$col]); $col++; continue; } if (!preg_match('#(\\*??)\\ *' . TEXY_MODIFIER_HV . '??(.*)' . TEXY_MODIFIER_HV . '?\\ *()$#AU', $cell, $matches)) { continue; } list(, $mHead, $mModCol, $mContent, $mMod) = $matches; if ($mModCol) { $colModifier[$col] = new TexyModifier($mModCol); } if (isset($colModifier[$col])) { $mod = clone $colModifier[$col]; } else { $mod = new TexyModifier(); } $mod->setProperties($mMod); $elCell = new TexyTableCellElement(); $elCell->setName($isHead || $mHead === '*' ? 'th' : 'td'); $mod->decorate($tx, $elCell); $elCell->text = $mContent; $elRow->add($elCell); $prevRow[$col] = $elCell; $col++; } while ($col < $colCounter) { if (isset($prevRow[$col]) && $lineMode) { $prevRow[$col]->rowSpan++; $prevRow[$col]->text .= "\n"; } else { $elCell = new TexyTableCellElement(); $elCell->setName($isHead ? 'th' : 'td'); if (isset($colModifier[$col])) { $colModifier[$col]->decorate($tx, $elCell); } $elRow->add($elCell); $prevRow[$col] = $elCell; } $col++; } $colCounter = $col; if ($elRow->count()) { $elPart->add($elRow); $rowCounter++; } else { foreach ($prevRow as $elCell) { $elCell->rowSpan--; } } continue; } break; } if ($elPart === NULL) { return FALSE; } if ($elPart->getName() === 'thead') { $elPart->setName('tbody'); } $this->finishPart($elPart); $tx->invokeHandlers('afterTable', array($parser, $el, $mod)); return $el; }
/** * Callback for single list item. * * @param TexyBlockParser * @param string bullet type * @param string left space * @param string html tag * @return TexyHtml|FALSE */ public function patternItem($parser, $bullet, $indented, $tag) { $tx = $this->texy; $spacesBase = $indented ? '\\ {1,}' : ''; $patternItem = "#^\n?({$spacesBase}){$bullet}\\ *(\\S.*)?" . TEXY_MODIFIER_H . "?()\$#mAUu"; // first line with bullet $matches = NULL; if (!$parser->next($patternItem, $matches)) { return FALSE; } list(, $mIndent, $mContent, $mMod) = $matches; // [1] => indent // [2] => ... // [3] => .(title)[class]{style}<> $elItem = TexyHtml::el($tag); $mod = new TexyModifier($mMod); $mod->decorate($tx, $elItem); // next lines $spaces = ''; $content = ' ' . $mContent; // trick while ($parser->next('#^(\\n*)' . $mIndent . '(\\ {1,' . $spaces . '})(.*)()$#Am', $matches)) { list(, $mBlank, $mSpaces, $mContent) = $matches; // [1] => blank line? // [2] => spaces // [3] => ... if ($spaces === '') { $spaces = strlen($mSpaces); } $content .= "\n" . $mBlank . $mContent; } // parse content $elItem->parseBlock($tx, $content, TRUE); if (isset($elItem[0]) && $elItem[0] instanceof TexyHtml) { $elItem[0]->setName(NULL); } return $elItem; }
/** * Callback for:. * * .(title)[class]{style}> * |------------------ * | xxx | xxx | xxx | .(..){..}[..] * |------------------ * | aa | bb | cc | * * @param TexyBlockParser * @param array regexp matches * @param string pattern name * @return TexyHtml|string|FALSE */ public function patternTable($parser, $matches) { list(, $mMod) = $matches; // [1] => .(title)[class]{style}<>_ $tx = $this->texy; $el = TexyHtml::el('table'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $el); $parser->moveBackward(); if ($parser->next('#^\\|(\\#|\\=){2,}(?![|\\#=+])(.+)\\1*\\|? *' . TEXY_MODIFIER_H . '?()$#Um', $matches)) { list(, , $mContent, $mMod) = $matches; // [1] => # / = // [2] => .... // [3] => .(title)[class]{style}<> $caption = $el->create('caption'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $caption); $caption->parseLine($tx, $mContent); } $isHead = FALSE; $colModifier = array(); $prevRow = array(); // rowSpan building helper $rowCounter = 0; $colCounter = 0; $elPart = NULL; $lineMode = FALSE; // rows must be separated by lines while (TRUE) { if ($parser->next('#^\\|([=-])[+|=-]{2,}$#Um', $matches)) { // line if ($lineMode) { if ($matches[1] === '=') { $isHead = !$isHead; } } else { $isHead = !$isHead; $lineMode = $matches[1] === '='; } $prevRow = array(); continue; } if ($parser->next('#^\\|(.*)(?:|\\|\\ *' . TEXY_MODIFIER_HV . '?)()$#U', $matches)) { // smarter head detection if ($rowCounter === 0 && !$isHead && $parser->next('#^\\|[=-][+|=-]{2,}$#Um', $foo)) { $isHead = TRUE; $parser->moveBackward(); } if ($elPart === NULL) { $elPart = $el->create($isHead ? 'thead' : 'tbody'); } elseif (!$isHead && $elPart->getName() === 'thead') { $this->finishPart($elPart); $elPart = $el->create('tbody'); } // PARSE ROW list(, $mContent, $mMod) = $matches; // [1] => .... // [2] => .(title)[class]{style}<>_ $elRow = TexyHtml::el('tr'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $elRow); $rowClass = $rowCounter % 2 === 0 ? $this->oddClass : $this->evenClass; if ($rowClass && !isset($mod->classes[$this->oddClass]) && !isset($mod->classes[$this->evenClass])) { $elRow->attrs['class'][] = $rowClass; } $col = 0; $elCell = NULL; // special escape sequence \| $mContent = str_replace('\\|', '|', $mContent); foreach (explode('|', $mContent) as $cell) { // rowSpan if (isset($prevRow[$col]) && ($lineMode || preg_match('#\\^\\ *$|\\*??(.*)\\ +\\^$#AU', $cell, $matches))) { $prevRow[$col]->rowSpan++; if (!$lineMode) { $cell = isset($matches[1]) ? $matches[1] : ''; } $prevRow[$col]->text .= "\n" . $cell; $col += $prevRow[$col]->colSpan; $elCell = NULL; continue; } // colSpan if ($cell === '' && $elCell) { $elCell->colSpan++; unset($prevRow[$col]); $col++; continue; } // common cell if (!preg_match('#(\\*??)\\ *' . TEXY_MODIFIER_HV . '??(.*)' . TEXY_MODIFIER_HV . '?\\ *()$#AU', $cell, $matches)) { continue; } list(, $mHead, $mModCol, $mContent, $mMod) = $matches; // [1] => * ^ // [2] => .(title)[class]{style}<>_ // [3] => .... // [4] => .(title)[class]{style}<>_ if ($mModCol) { $colModifier[$col] = new TexyModifier($mModCol); } if (isset($colModifier[$col])) { $mod = clone $colModifier[$col]; } else { $mod = new TexyModifier(); } $mod->setProperties($mMod); $elCell = new TexyTableCellElement(); $elCell->setName($isHead || $mHead === '*' ? 'th' : 'td'); $mod->decorate($tx, $elCell); $elCell->text = $mContent; $elRow->add($elCell); $prevRow[$col] = $elCell; $col++; } // even up with empty cells while ($col < $colCounter) { if (isset($prevRow[$col]) && $lineMode) { $prevRow[$col]->rowSpan++; $prevRow[$col]->text .= "\n"; } else { $elCell = new TexyTableCellElement(); $elCell->setName($isHead ? 'th' : 'td'); if (isset($colModifier[$col])) { $colModifier[$col]->decorate($tx, $elCell); } $elRow->add($elCell); $prevRow[$col] = $elCell; } $col++; } $colCounter = $col; if ($elRow->count()) { $elPart->add($elRow); $rowCounter++; } else { // redundant row foreach ($prevRow as $elCell) { $elCell->rowSpan--; } } continue; } break; } if ($elPart === NULL) { // invalid table return FALSE; } if ($elPart->getName() === 'thead') { // thead is optional, tbody is required $elPart->setName('tbody'); } $this->finishPart($elPart); // event listener $tx->invokeHandlers('afterTable', array($parser, $el, $mod)); return $el; }
/** * Callback for:. * * Term: .(title)[class]{style}> * - description 1 * - description 2 * - description 3 * * @param TexyBlockParser * @param array regexp matches * @param string pattern name * * @return TexyHtml */ public function patternDefList($parser, $matches) { list(, $mMod, , , , $mBullet) = $matches; // [1] => .(title)[class]{style}<> // [2] => ... // [3] => .(title)[class]{style}<> // [4] => space // [5] => - * + $tx = $this->texy; $bullet = null; foreach ($this->bullets as $desc) { if (preg_match('#' . $desc[0] . '#Au', $mBullet)) { $bullet = isset($desc[3]) ? $desc[3] : $desc[0]; break; } } $el = TexyHtml::el('dl'); $mod = new TexyModifier($mMod); $mod->decorate($tx, $el); $parser->moveBackward(2); $patternTerm = '#^\\n?(\\S.*)\\:\\ *' . TEXY_MODIFIER_H . '?()$#mUA'; while (true) { if ($elItem = $this->patternItem($parser, $bullet, true, 'dd')) { $el->add($elItem); continue; } if ($parser->next($patternTerm, $matches)) { list(, $mContent, $mMod) = $matches; // [1] => ... // [2] => .(title)[class]{style}<> $elItem = TexyHtml::el('dt'); $modItem = new TexyModifier($mMod); $modItem->decorate($tx, $elItem); $elItem->parseLine($tx, $mContent); $el->add($elItem); continue; } break; } // event listener $tx->invokeHandlers('afterDefinitionList', array($parser, $el, $mod)); return $el; }