/** * Finish invocation. * @return Texy\HtmlElement|FALSE */ public function solve(Texy\HandlerInvocation $invocation, $content, Texy\Modifier $mod = NULL) { $texy = $this->texy; // find hard linebreaks if ($texy->mergeLines) { // .... // ... => \r means break line $content = Regexp::replace($content, '#\\n +(?=\\S)#', "\r"); } else { $content = Regexp::replace($content, '#\\n#', "\r"); } $el = new Texy\HtmlElement('p'); $el->parseLine($texy, $content); $content = $el->getText(); // string // check content type // block contains block tag if (strpos($content, $texy::CONTENT_BLOCK) !== FALSE) { $el->setName(NULL); // ignores modifier! // block contains text (protected) } elseif (strpos($content, $texy::CONTENT_TEXTUAL) !== FALSE) { // leave element p // block contains text } elseif (preg_match('#[^\\s' . Texy\Patterns::MARK . ']#u', $content)) { // leave element p // block contains only replaced element } elseif (strpos($content, $texy::CONTENT_REPLACED) !== FALSE) { $el->setName($texy->nontextParagraph); // block contains only markup tags or spaces or nothing } else { // if {ignoreEmptyStuff} return FALSE; if (!$mod) { $el->setName(NULL); } } if ($el->getName()) { // apply modifier if ($mod) { $mod->decorate($texy, $el); } // add <br /> if (strpos($content, "\r") !== FALSE) { $key = $texy->protect('<br />', $texy::CONTENT_REPLACED); $content = str_replace("\r", $key, $content); } } $content = strtr($content, "\r\n", ' '); $el->setText($content); return $el; }
/** * Finish invocation. * @return HtmlElement|string|FALSE */ public function solveTag(Texy\HandlerInvocation $invocation, HtmlElement $el, $isStart, $forceEmpty = NULL) { $texy = $this->texy; // tag & attibutes $allowedTags = $texy->allowedTags; // speed-up if (!$allowedTags) { return FALSE; // all tags are disabled } // convert case $name = $el->getName(); $lower = strtolower($name); if (isset($texy->dtd[$lower]) || $name === strtoupper($name)) { // complete UPPER convert to lower $name = $lower; $el->setName($name); } if (is_array($allowedTags)) { if (!isset($allowedTags[$name])) { return FALSE; } $allowedAttrs = $allowedTags[$name]; // allowed attrs } else { // allowedTags === Texy\Texy::ALL if ($forceEmpty) { $el->setName($name, TRUE); } $allowedAttrs = $texy::ALL; // all attrs are allowed } // end tag? we are finished if (!$isStart) { return $el; } $elAttrs =& $el->attrs; // process attributes if (!$allowedAttrs) { $elAttrs = []; } elseif (is_array($allowedAttrs)) { // skip disabled $allowedAttrs = array_flip($allowedAttrs); foreach ($elAttrs as $key => $foo) { if (!isset($allowedAttrs[$key])) { unset($elAttrs[$key]); } } } // apply allowedClasses $tmp = $texy->_classes; // speed-up if (isset($elAttrs['class'])) { if (is_array($tmp)) { $elAttrs['class'] = explode(' ', $elAttrs['class']); foreach ($elAttrs['class'] as $key => $value) { if (!isset($tmp[$value])) { unset($elAttrs['class'][$key]); // id & class are case-sensitive } } } elseif ($tmp !== $texy::ALL) { $elAttrs['class'] = NULL; } } // apply allowedClasses for ID if (isset($elAttrs['id'])) { if (is_array($tmp)) { if (!isset($tmp['#' . $elAttrs['id']])) { $elAttrs['id'] = NULL; } } elseif ($tmp !== $texy::ALL) { $elAttrs['id'] = NULL; } } // apply allowedStyles if (isset($elAttrs['style'])) { $tmp = $texy->_styles; // speed-up if (is_array($tmp)) { $styles = explode(';', $elAttrs['style']); $elAttrs['style'] = NULL; foreach ($styles as $value) { $pair = explode(':', $value, 2); $prop = trim($pair[0]); if (isset($pair[1]) && isset($tmp[strtolower($prop)])) { // CSS is case-insensitive $elAttrs['style'][$prop] = $pair[1]; } } } elseif ($tmp !== $texy::ALL) { $elAttrs['style'] = NULL; } } foreach (['src', 'href', 'name', 'id'] as $attr) { if (isset($elAttrs[$attr])) { $elAttrs[$attr] = is_string($elAttrs[$attr]) ? trim($elAttrs[$attr]) : ''; if ($elAttrs[$attr] === '') { unset($elAttrs[$attr]); } } } if ($name === 'img') { if (!isset($elAttrs['src']) || !$texy->checkURL($elAttrs['src'], $texy::FILTER_IMAGE)) { return FALSE; } $texy->summary['images'][] = $elAttrs['src']; } elseif ($name === 'a') { if (!isset($elAttrs['href']) && !isset($elAttrs['name']) && !isset($elAttrs['id'])) { return FALSE; } if (isset($elAttrs['href'])) { if ($texy->linkModule->forceNoFollow && strpos($elAttrs['href'], '//') !== FALSE) { if (isset($elAttrs['rel'])) { $elAttrs['rel'] = (array) $elAttrs['rel']; } $elAttrs['rel'][] = 'nofollow'; } if (!$texy->checkURL($elAttrs['href'], $texy::FILTER_ANCHOR)) { return FALSE; } $texy->summary['links'][] = $elAttrs['href']; } } elseif (preg_match('#^h[1-6]#i', $name)) { $texy->headingModule->TOC[] = ['el' => $el, 'level' => (int) substr($name, 1), 'type' => 'html']; } $el->validateAttrs($texy->dtd); return $el; }