public function testRewindDouble() { $stack = new ezcDocumentRstStack(); $array = array(); array_unshift($array, 1); array_unshift($array, 23); $stack->unshift(1); $stack->unshift(23); $this->assertSame(reset($array), $stack->rewind()); }
/** * Reduce link * * Uses the preceding element as the hyperlink content. This should be * either a literal markup section, or just the last word. * * As we do not get workd content out of the tokenizer (too much overhead), * we split out the previous text node up, in case we got one. * * @param ezcDocumentRstNode $node * @return void */ protected function reduceLink(ezcDocumentRstNode $node) { if (!isset($this->documentStack[0])) { // This should never happen, though. return; } // Check a special case for anonymous hyperlinks, that the beforelast // token is not a '__'. if (isset($this->documentStack[1]) && $this->documentStack[1]->token->content === '__') { return new ezcDocumentRstTextLineNode($node->token); } // Aggregate token to check for an embedded inline URL $text = false; if ($this->documentStack[0]->type === ezcDocumentRstNode::MARKUP_INTERPRETED || $this->documentStack[0]->type === ezcDocumentRstNode::MARKUP_SUBSTITUTION) { /* DEBUG echo " - Scan literal for embedded URI.\n"; // /DEBUG */ $textNode = false; $text = $this->documentStack->shift(); foreach ($text->nodes as $child) { if ($child->type !== ezcDocumentRstNode::TEXT_LINE) { /* DEBUG echo " - Invalid subnode type found: " . ezcDocumentRstNode::getTokenName( $child->type ) . ".\n"; // /DEBUG */ $textNode = false; break; } else { $textNode .= $child->token->content; } } // If we could aggregate the texts easily, because there is only // plain text included, we can check for an URL. if ($textNode !== false && preg_match('(\\s*<(?P<url>[^>]+)>)', $textNode, $match)) { // We found an URL - remove it from the text and use it as link // target. /* DEBUG echo " - Matched embedded URI: " . $match['url'] . ".\n"; // /DEBUG */ $text = new ezcDocumentRstTextLineNode($text->nodes[0]->token); $text->token->content = str_replace($match[0], '', $textNode); $node->target = $match['url']; } $text = array($text); } elseif ($this->documentStack[0]->type === ezcDocumentRstNode::TEXT_LINE && strpos($this->documentStack[0]->token->content, ' ') === false) { /* DEBUG echo " - Spaceless text found, aggregating:\n"; // /DEBUG */ $text = array(); do { $text[] = $this->documentStack->shift(); } while (isset($this->documentStack[0]) && $this->documentStack[0]->type === ezcDocumentRstNode::TEXT_LINE && ($this->documentStack[0]->token->type === ezcDocumentRstToken::TEXT_LINE || $this->documentStack[0]->token->type === ezcDocumentRstToken::SPECIAL_CHARS && preg_match('(^[_-]+$)', $this->documentStack[0]->token->content)) && strpos($this->documentStack[0]->token->content, ' ') === false); // Split away everything after the first space, and include it in // the reference target, if applicable if (isset($this->documentStack[0]) && $this->documentStack[0]->type === ezcDocumentRstNode::TEXT_LINE && preg_match('(^(?P<before>.*?)(?P<text>[A-Za-z0-9_-]+)$)s', $this->documentStack[0]->token->content, $match)) { /* DEBUG echo " - Splitting node: '{$this->documentStack[0]->token->content}' at $pos.\n"; // /DEBUG */ $token = clone $this->documentStack[0]->token; $this->documentStack[0]->token->content = rtrim($match['before']); $token->content = $match['text']; $text[] = new ezcDocumentRstTextLineNode($token); } $text = array_reverse($text); } if ($text !== false) { /* DEBUG echo " - Return created node.\n"; // /DEBUG */ $node->nodes = $text; return $node; } // If the single text node contains spaces we need to split it up here, // because the link only covers the last word in the string. if ($this->documentStack[0]->type === ezcDocumentRstNode::TEXT_LINE) { // This is bit hackish, but otherwise the tokenizer would produce // too large amounts of structs. $words = explode(' ', $this->documentStack[0]->token->content); $this->documentStack[0]->token->content = implode(' ', array_slice($words, 0, -1)) . ' '; $token = clone $this->documentStack[0]->token; $token->content = end($words); $text = new ezcDocumentRstTextLineNode($token); $node->nodes = array($text); return $node; } // We did not find a valid precedessor, so just convert to a text node. return new ezcDocumentRstTextLineNode($node->token); }