Differential D19111 Diff 45797 src/markup/engine/remarkup/markuprule/PhutilRemarkupDocumentLinkRule.php
Changeset View
Changeset View
Standalone View
Standalone View
src/markup/engine/remarkup/markuprule/PhutilRemarkupDocumentLinkRule.php
Show All 9 Lines | public function apply($text) { | ||||
// Handle mediawiki-style links: [[ href | name ]] | // Handle mediawiki-style links: [[ href | name ]] | ||||
$text = preg_replace_callback( | $text = preg_replace_callback( | ||||
'@\B\\[\\[([^|\\]]+)(?:\\|([^\\]]+))?\\]\\]\B@U', | '@\B\\[\\[([^|\\]]+)(?:\\|([^\\]]+))?\\]\\]\B@U', | ||||
array($this, 'markupDocumentLink'), | array($this, 'markupDocumentLink'), | ||||
$text); | $text); | ||||
// Handle markdown-style links: [name](href) | // Handle markdown-style links: [name](href) | ||||
$text = preg_replace_callback( | $text = preg_replace_callback( | ||||
'@\B\\[([^\\]]+)\\]\\(([^\\)]+)\\)\B@U', | '@'. | ||||
'\B'. | |||||
'\\[([^\\]]+)\\]'. | |||||
'\\('. | |||||
'(\s*'. | |||||
// See T12343. This is making some kind of effort to implement | |||||
// parenthesis balancing rules. It won't get nested parentheses | |||||
// right, but should do OK for Wikipedia pages, which seem to be | |||||
// the most important use case. | |||||
// Match zero or more non-parenthesis, non-space characters. | |||||
'[^\s()]*'. | |||||
// Match zero or more sequences of "(...)", where two balanced | |||||
// parentheses enclose zero or more normal characters. If we | |||||
// match some, optionally match more stuff at the end. | |||||
'(?:(?:\\([^ ()]*\\))+[^\s()]*)?'. | |||||
'\s*)'. | |||||
'\\)'. | |||||
'\B'. | |||||
'@U', | |||||
array($this, 'markupAlternateLink'), | array($this, 'markupAlternateLink'), | ||||
$text); | $text); | ||||
return $text; | return $text; | ||||
} | } | ||||
protected function renderHyperlink($link, $name) { | protected function renderHyperlink($link, $name) { | ||||
$engine = $this->getEngine(); | $engine = $this->getEngine(); | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | public function markupAlternateLink(array $matches) { | ||||
// - Don't match at word boundaries; | // - Don't match at word boundaries; | ||||
// - require the URI to contain a "/" character or "@" character; and | // - require the URI to contain a "/" character or "@" character; and | ||||
// - reject URIs which being with a quote character. | // - reject URIs which being with a quote character. | ||||
if ($uri[0] == '"' || $uri[0] == "'" || $uri[0] == '`') { | if ($uri[0] == '"' || $uri[0] == "'" || $uri[0] == '`') { | ||||
return $matches[0]; | return $matches[0]; | ||||
} | } | ||||
if (!strlen($uri[0])) { | |||||
return $matches[0]; | |||||
} | |||||
if (strpos($uri, '/') === false && | if (strpos($uri, '/') === false && | ||||
strpos($uri, '@') === false && | strpos($uri, '@') === false && | ||||
strncmp($uri, 'tel:', 4)) { | strncmp($uri, 'tel:', 4)) { | ||||
return $matches[0]; | return $matches[0]; | ||||
} | } | ||||
return $this->markupDocumentLink( | return $this->markupDocumentLink( | ||||
array( | array( | ||||
Show All 24 Lines | if ($is_uri && strncmp('/', $uri, 1) && strncmp('#', $uri, 1)) { | ||||
} | } | ||||
} catch (Exception $ex) { | } catch (Exception $ex) { | ||||
// We can end up here if we try to parse an ambiguous URI, see | // We can end up here if we try to parse an ambiguous URI, see | ||||
// T12796. | // T12796. | ||||
$is_uri = false; | $is_uri = false; | ||||
} | } | ||||
} | } | ||||
// As a special case, skip "[[ / ]]" so that Phriction picks it up as a | |||||
// link to the Phriction root. It is more useful to be able to use this | |||||
// syntax to link to the root document than the home page of the install. | |||||
if ($uri == '/') { | |||||
$is_uri = false; | |||||
} | |||||
if (!$is_uri) { | if (!$is_uri) { | ||||
return $matches[0]; | return $matches[0]; | ||||
} | } | ||||
return $this->getEngine()->storeText($this->renderHyperlink($uri, $name)); | return $this->getEngine()->storeText($this->renderHyperlink($uri, $name)); | ||||
} | } | ||||
} | } |