/** * Test whether we should shorten this tag's text * * Will test whether the tag either does not use any markup or uses a single * [url] BBCode * * @param \s9e\TextFormatter\Parser\Tag $tag URL tag * @param string $text Original text * @return bool */ protected function should_shorten(\s9e\TextFormatter\Parser\Tag $tag, $text) { return $tag->getLen() === 0 || strtolower(substr($text, $tag->getPos(), $tag->getLen())) === '[url]'; }
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; }
/** * @testdox getPos() returns the tag's length (amount of text consumed) */ public function testGetLen() { $tag = new Tag(Tag::START_TAG, 'X', 12, 34); $this->assertSame(34, $tag->getLen()); }
/** * 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; }