protected static function addSiteTag(Tag $tag, TagStack $tagStack, $siteId) { $endTag = $tag->getEndTag() ?: $tag; $lpos = $tag->getPos(); $rpos = $endTag->getPos() + $endTag->getLen(); $newTag = $tagStack->addSelfClosingTag(\strtoupper($siteId), $lpos, $rpos - $lpos); $newTag->setAttributes($tag->getAttributes()); $newTag->setSortPriority($tag->getSortPriority()); }
public static function filterTag(Tag $tag, TagStack $tagStack, array $sites) { if ($tag->hasAttribute('media')) { $tagName = $tag->getAttribute('media'); if (!$tag->hasAttribute('id') && $tag->hasAttribute('url') && \strpos($tag->getAttribute('url'), '://') === \false) { $tag->setAttribute('id', $tag->getAttribute('url')); } } elseif ($tag->hasAttribute('url')) { $p = \parse_url($tag->getAttribute('url')); if (isset($p['scheme']) && isset($sites[$p['scheme'] . ':'])) { $tagName = $sites[$p['scheme'] . ':']; } elseif (isset($p['host'])) { $host = $p['host']; do { if (isset($sites[$host])) { $tagName = $sites[$host]; break; } $pos = \strpos($host, '.'); if ($pos === \false) { break; } $host = \substr($host, 1 + $pos); } while ($host > ''); } } if (isset($tagName)) { $endTag = $tag->getEndTag() ?: $tag; $lpos = $tag->getPos(); $rpos = $endTag->getPos() + $endTag->getLen(); $newTag = $tagStack->addSelfClosingTag(\strtoupper($tagName), $lpos, $rpos - $lpos); $newTag->setAttributes($tag->getAttributes()); $newTag->setSortPriority($tag->getSortPriority()); } return \false; }
/** * Add a site tag * * @param Tag $tag The original tag * @param TagStack $tagStack Parser instance, so that we can add the new tag to the stack * @param string $siteId Site ID * @return void */ protected static function addSiteTag(Tag $tag, TagStack $tagStack, $siteId) { $endTag = $tag->getEndTag() ?: $tag; // Compute the boundaries of our new tag $lpos = $tag->getPos(); $rpos = $endTag->getPos() + $endTag->getLen(); // Create a new tag and copy this tag's attributes and priority $newTag = $tagStack->addSelfClosingTag(strtoupper($siteId), $lpos, $rpos - $lpos); $newTag->setAttributes($tag->getAttributes()); $newTag->setSortPriority($tag->getSortPriority()); }
/** * @testdox setSortPriority() sets the tag's sortPriority */ public function testSetSortPriority() { $tag = new Tag(Tag::START_TAG, 'X', 12, 34); $tag->setSortPriority(-10); $this->assertSame(-10, $tag->getSortPriority()); }
protected static function compareTags(Tag $a, Tag $b) { $aPos = $a->getPos(); $bPos = $b->getPos(); if ($aPos !== $bPos) { return $bPos - $aPos; } if ($a->getSortPriority() !== $b->getSortPriority()) { return $b->getSortPriority() - $a->getSortPriority(); } $aLen = $a->getLen(); $bLen = $b->getLen(); if (!$aLen || !$bLen) { if (!$aLen && !$bLen) { $order = array(Tag::END_TAG => 0, Tag::SELF_CLOSING_TAG => 1, Tag::START_TAG => 2); return $order[$b->getType()] - $order[$a->getType()]; } return $aLen ? -1 : 1; } return $aLen - $bLen; }
/** * sortTags() callback * * Tags are stored as a stack, in LIFO order. We sort tags by position _descending_ so that they * are processed in the order they appear in the text. * * @param Tag $a First tag to compare * @param Tag $b Second tag to compare * @return integer */ protected static function compareTags(Tag $a, Tag $b) { $aPos = $a->getPos(); $bPos = $b->getPos(); // First we order by pos descending if ($aPos !== $bPos) { return $bPos - $aPos; } // If the tags start at the same position, we'll use their sortPriority if applicable. Tags // with a lower value get sorted last, which means they'll be processed first. IOW, -10 is // processed before 10 if ($a->getSortPriority() !== $b->getSortPriority()) { return $b->getSortPriority() - $a->getSortPriority(); } // If the tags start at the same position and have the same priority, we'll sort them // according to their length, with special considerations for zero-width tags $aLen = $a->getLen(); $bLen = $b->getLen(); if (!$aLen || !$bLen) { // Zero-width end tags are ordered after zero-width start tags so that a pair that ends // with a zero-width tag has the opportunity to be closed before another pair starts // with a zero-width tag. For example, the pairs that would enclose each of the letters // in the string "XY". Self-closing tags are ordered between end tags and start tags in // an attempt to keep them out of tag pairs if (!$aLen && !$bLen) { $order = [Tag::END_TAG => 0, Tag::SELF_CLOSING_TAG => 1, Tag::START_TAG => 2]; return $order[$b->getType()] - $order[$a->getType()]; } // Here, we know that only one of $a or $b is a zero-width tags. Zero-width tags are // ordered after wider tags so that they have a chance to be processed before the next // character is consumed, which would force them to be skipped return $aLen ? -1 : 1; } // Here we know that both tags start at the same position and have a length greater than 0. // We sort tags by length ascending, so that the longest matches are processed first. If // their length is identical, the order is undefined as PHP's sort isn't stable return $aLen - $bLen; }