Page MenuHome GnuPG

No OneTemporary

diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupBoldRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupBoldRule.php
index 1940ee8..4640df2 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupBoldRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupBoldRule.php
@@ -1,24 +1,24 @@
<?php
final class PhutilRemarkupBoldRule extends PhutilRemarkupRule {
public function getPriority() {
return 1000.0;
}
public function apply($text) {
if ($this->getEngine()->isTextMode()) {
return $text;
}
return $this->replaceHTML(
'@\\*\\*(.+?)\\*\\*@s',
array($this, 'applyCallback'),
$text);
}
- protected function applyCallback($matches) {
+ protected function applyCallback(array $matches) {
return hsprintf('<strong>%s</strong>', $matches[1]);
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupDelRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupDelRule.php
index 623441c..82f23d2 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupDelRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupDelRule.php
@@ -1,24 +1,24 @@
<?php
final class PhutilRemarkupDelRule extends PhutilRemarkupRule {
public function getPriority() {
return 1000.0;
}
public function apply($text) {
if ($this->getEngine()->isTextMode()) {
return $text;
}
return $this->replaceHTML(
'@(?<!~)~~([^\s~].*?~*)~~@s',
array($this, 'applyCallback'),
$text);
}
- protected function applyCallback($matches) {
+ protected function applyCallback(array $matches) {
return hsprintf('<del>%s</del>', $matches[1]);
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupDocumentLinkRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupDocumentLinkRule.php
index 818ff9e..ed85d72 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupDocumentLinkRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupDocumentLinkRule.php
@@ -1,133 +1,132 @@
<?php
final class PhutilRemarkupDocumentLinkRule extends PhutilRemarkupRule {
public function getPriority() {
return 150.0;
}
public function apply($text) {
-
// Handle mediawiki-style links: [[ href | name ]]
$text = preg_replace_callback(
'@\B\\[\\[([^|\\]]+)(?:\\|([^\\]]+))?\\]\\]\B@U',
array($this, 'markupDocumentLink'),
$text);
// Handle markdown-style links: [name](href)
$text = preg_replace_callback(
'@\B\\[([^\\]]+)\\]\\(([^\\)]+)\\)\B@U',
array($this, 'markupAlternateLink'),
$text);
return $text;
}
protected function renderHyperlink($link, $name) {
if ($this->getEngine()->isTextMode()) {
$text = $link;
if (strncmp($link, '/', 1) == 0 || strncmp($link, '#', 1) == 0) {
$base = $this->getEngine()->getConfig('uri.prefix');
if (strncmp($link, '/', 1) == 0) {
$base = rtrim($base, '/');
}
$text = $base.$text;
}
// If present, strip off "mailto:" or "tel:".
$text = preg_replace('/^(?:mailto|tel):/', '', $text);
if ($link == $name) {
return $text;
}
return $name.' <'.$text.'>';
} else if ($this->getEngine()->isHTMLMailMode()) {
if (strncmp($link, '/', 1) == 0 || strncmp($link, '#', 1) == 0) {
$base = $this->getEngine()->getConfig('uri.base');
$text = $link;
if (strncmp($link, '/', 1) == 0) {
$base = rtrim($base, '/');
}
$link = $base.$text;
}
}
// By default, we open links in a new window or tab. For anchors on the same
// page, just jump normally.
$target = '_blank';
if (strncmp($link, '#', 1) == 0) {
$target = null;
}
$name = preg_replace('/^(?:mailto|tel):/', '', $name);
if ($this->getEngine()->getState('toc')) {
return $name;
} else {
return phutil_tag(
'a',
array(
'href' => $link,
'class' => 'remarkup-link',
'target' => $target,
),
$name);
}
}
- public function markupAlternateLink($matches) {
+ public function markupAlternateLink(array $matches) {
$uri = trim($matches[2]);
// NOTE: We apply some special rules to avoid false positives here. The
// major concern is that we do not want to convert `x[0][1](y)` in a
// discussion about C source code into a link. To this end, we:
//
// - Don't match at word boundaries;
// - require the URI to contain a "/" character or "@" character; and
// - reject URIs which being with a quote character.
if ($uri[0] == '"' || $uri[0] == "'" || $uri[0] == '`') {
return $matches[0];
}
if (strpos($uri, '/') === false &&
strpos($uri, '@') === false &&
strncmp($uri, 'tel:', 4)) {
return $matches[0];
}
return $this->markupDocumentLink(
array(
$matches[0],
$matches[2],
$matches[1],
));
}
- public function markupDocumentLink($matches) {
+ public function markupDocumentLink(array $matches) {
$uri = trim($matches[1]);
$name = trim(idx($matches, 2, $uri));
// If whatever is being linked to begins with "/" or "#", or has "://",
// or is "mailto:" or "tel:", treat it as a URI instead of a wiki page.
$is_uri = preg_match('@(^/)|(://)|(^#)|(^(?:mailto|tel):)@', $uri);
if ($is_uri && strncmp('/', $uri, 1) && strncmp('#', $uri, 1)) {
$protocols = $this->getEngine()->getConfig(
'uri.allowed-protocols',
array());
$protocol = id(new PhutilURI($uri))->getProtocol();
if (!idx($protocols, $protocol)) {
// Don't treat this as a URI if it's not an allowed protocol.
$is_uri = false;
}
}
if (!$is_uri) {
return $matches[0];
}
return $this->getEngine()->storeText($this->renderHyperlink($uri, $name));
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupHyperlinkRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupHyperlinkRule.php
index 2e3d87b..b9c51e5 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupHyperlinkRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupHyperlinkRule.php
@@ -1,99 +1,99 @@
<?php
final class PhutilRemarkupHyperlinkRule extends PhutilRemarkupRule {
public function getPriority() {
return 400.0;
}
public function apply($text) {
// Hyperlinks with explicit "<>" around them get linked exactly, without
// the "<>". Angle brackets are basically special and mean "this is a URL
// with weird characters". This is assumed to be reasonable because they
// don't appear in normal text or normal URLs.
$text = preg_replace_callback(
'@<(\w{3,}://[^\s'.PhutilRemarkupBlockStorage::MAGIC_BYTE.']+?)>@',
array($this, 'markupHyperlink'),
$text);
// Anything else we match "ungreedily", which means we'll look for
// stuff that's probably puncutation or otherwise not part of the URL and
// not link it. This lets someone write "QuicK! Go to
// http://www.example.com/!". We also apply some paren balancing rules.
// NOTE: We're explicitly avoiding capturing stored blocks, so text like
// `http://www.example.com/[[x | y]]` doesn't get aggressively captured.
$text = preg_replace_callback(
'@(\w{3,}://[^\s'.PhutilRemarkupBlockStorage::MAGIC_BYTE.']+)@',
array($this, 'markupHyperlinkUngreedy'),
$text);
return $text;
}
- protected function markupHyperlink($matches) {
+ protected function markupHyperlink(array $matches) {
$protocols = $this->getEngine()->getConfig(
'uri.allowed-protocols',
array());
$protocol = id(new PhutilURI($matches[1]))->getProtocol();
if (!idx($protocols, $protocol)) {
// If this URI doesn't use a whitelisted protocol, don't link it. This
// is primarily intended to prevent javascript:// silliness.
return $this->getEngine()->storeText($matches[1]);
}
return $this->storeRenderedHyperlink($matches[1]);
}
protected function storeRenderedHyperlink($link) {
return $this->getEngine()->storeText($this->renderHyperlink($link));
}
protected function renderHyperlink($link) {
if ($this->getEngine()->isTextMode()) {
return $link;
}
if ($this->getEngine()->getState('toc')) {
return $link;
} else {
return phutil_tag(
'a',
array(
'href' => $link,
'class' => 'remarkup-link',
'target' => '_blank',
),
$link);
}
}
protected function markupHyperlinkUngreedy($matches) {
$match = $matches[1];
$tail = null;
$trailing = null;
if (preg_match('/[;,.:!?]+$/', $match, $trailing)) {
$tail = $trailing[0];
$match = substr($match, 0, -strlen($tail));
}
// If there's a closing paren at the end but no balancing open paren in
// the URL, don't link the close paren. This is an attempt to gracefully
// handle the two common paren cases, Wikipedia links and English language
// parentheticals, e.g.:
//
// http://en.wikipedia.org/wiki/Noun_(disambiguation)
// (see also http://www.example.com)
//
// We could apply a craftier heuristic here which tries to actually balance
// the parens, but this is probably sufficient.
if (preg_match('/\\)$/', $match) && !preg_match('/\\(/', $match)) {
$tail = ')'.$tail;
$match = substr($match, 0, -1);
}
return hsprintf('%s%s', $this->markupHyperlink(array(null, $match)), $tail);
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupItalicRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupItalicRule.php
index f05410c..9eefe2a 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupItalicRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupItalicRule.php
@@ -1,24 +1,24 @@
<?php
final class PhutilRemarkupItalicRule extends PhutilRemarkupRule {
public function getPriority() {
return 1000.0;
}
public function apply($text) {
if ($this->getEngine()->isTextMode()) {
return $text;
}
return $this->replaceHTML(
'@(?<!:)//(.+?)//@s',
array($this, 'applyCallback'),
$text);
}
- protected function applyCallback($matches) {
+ protected function applyCallback(array $matches) {
return hsprintf('<em>%s</em>', $matches[1]);
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupMonospaceRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupMonospaceRule.php
index e63415a..cd5ab8a 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupMonospaceRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupMonospaceRule.php
@@ -1,49 +1,49 @@
<?php
final class PhutilRemarkupMonospaceRule extends PhutilRemarkupRule {
public function getPriority() {
return 100.0;
}
public function apply($text) {
// NOTE: We don't require a trailing non-boundary on the backtick syntax,
// to permit the use case of naming and pluralizing a class, like
// "Load all the `PhutilArray`s and then iterate over them." In theory, the
// required \B on the leading backtick should protect us from most
// collateral damage.
return preg_replace_callback(
'@##([\s\S]+?)##|\B`(.+?)`@',
array($this, 'markupMonospacedText'),
$text);
}
- protected function markupMonospacedText($matches) {
+ protected function markupMonospacedText(array $matches) {
if ($this->getEngine()->isTextMode()) {
$result = $matches[0];
} else
if ($this->getEngine()->isHTMLMailMode()) {
$match = isset($matches[2]) ? $matches[2] : $matches[1];
$result = phutil_tag(
'tt',
array(
'style' => 'background: #ebebeb; font-size: 13px;',
),
$match);
} else {
$match = isset($matches[2]) ? $matches[2] : $matches[1];
$result = phutil_tag(
'tt',
array(
'class' => 'remarkup-monospaced',
),
$match);
}
return $this->getEngine()->storeText($result);
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupRule.php
index 3ef5c87..292bfe6 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupRule.php
@@ -1,112 +1,112 @@
<?php
/**
* @stable
*/
abstract class PhutilRemarkupRule {
private $engine;
private $replaceCallback;
public function setEngine(PhutilRemarkupEngine $engine) {
$this->engine = $engine;
return $this;
}
public function getEngine() {
return $this->engine;
}
public function getPriority() {
return 500.0;
}
abstract public function apply($text);
public function getPostprocessKey() {
return spl_object_hash($this);
}
public function didMarkupText() {
return;
}
protected function replaceHTML($pattern, $callback, $text) {
$this->replaceCallback = $callback;
return phutil_safe_html(preg_replace_callback(
$pattern,
array($this, 'replaceHTMLCallback'),
phutil_escape_html($text)));
}
- private function replaceHTMLCallback($match) {
+ private function replaceHTMLCallback(array $match) {
return phutil_escape_html(call_user_func(
$this->replaceCallback,
array_map('phutil_safe_html', $match)));
}
/**
* Safely generate a tag.
*
* In Remarkup contexts, it's not safe to use arbitrary text in tag
* attributes: even though it will be escaped, it may contain replacement
* tokens which are then replaced with markup.
*
* This method acts as @{function:phutil_tag}, but checks attributes before
* using them.
*
* @param string Tag name.
* @param dict<string, wild> Tag attributes.
* @param wild Tag content.
* @return PhutilSafeHTML Tag object.
*/
protected function newTag($name, array $attrs, $content = null) {
foreach ($attrs as $key => $attr) {
if ($attr !== null) {
$attrs[$key] = $this->assertFlatText($attr);
}
}
return phutil_tag($name, $attrs, $content);
}
/**
* Assert that a text token is flat (it contains no replacement tokens).
*
* Because tokens can be replaced with markup, it is dangerous to use
* arbitrary input text in tag attributes. Normally, rule precedence should
* prevent this. Asserting that text is flat before using it as an attribute
* provides an extra layer of security.
*
* Normally, you can call @{method:newTag} rather than calling this method
* directly. @{method:newTag} will check attributes for you.
*
* @param wild Ostensibly flat text.
* @return string Flat text.
*/
protected function assertFlatText($text) {
$text = (string)hsprintf('%s', phutil_safe_html($text));
$rich = (strpos($text, PhutilRemarkupBlockStorage::MAGIC_BYTE) !== false);
if ($rich) {
throw new Exception(
pht(
'Remarkup rule precedence is dangerous: rendering text with tokens '.
'as flat text!'));
}
return $text;
}
/**
* Check whether text is flat (contains no replacement tokens) or not.
*
* @param wild Ostensibly flat text.
* @return bool True if the text is flat.
*/
protected function isFlatText($text) {
$text = (string)hsprintf('%s', phutil_safe_html($text));
return (strpos($text, PhutilRemarkupBlockStorage::MAGIC_BYTE) === false);
}
}
diff --git a/src/markup/engine/remarkup/markuprule/PhutilRemarkupUnderlineRule.php b/src/markup/engine/remarkup/markuprule/PhutilRemarkupUnderlineRule.php
index 0224fb7..1f15728 100644
--- a/src/markup/engine/remarkup/markuprule/PhutilRemarkupUnderlineRule.php
+++ b/src/markup/engine/remarkup/markuprule/PhutilRemarkupUnderlineRule.php
@@ -1,24 +1,24 @@
<?php
final class PhutilRemarkupUnderlineRule extends PhutilRemarkupRule {
public function getPriority() {
return 1000.0;
}
public function apply($text) {
if ($this->getEngine()->isTextMode()) {
return $text;
}
return $this->replaceHTML(
'@(?<!_|/)__([^\s_/].*?_*)__(?!/|\.\S)@s',
array($this, 'applyCallback'),
$text);
}
- protected function applyCallback($matches) {
+ protected function applyCallback(array $matches) {
return hsprintf('<u>%s</u>', $matches[1]);
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sun, Feb 23, 7:32 PM (1 d, 45 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
8c/1a/5028f98aba23caa2c5fa4481f935

Event Timeline