Page MenuHomePhabricator

D20393.id48698.diff
No OneTemporary

D20393.id48698.diff

diff --git a/src/__phutil_library_map__.php b/src/__phutil_library_map__.php
--- a/src/__phutil_library_map__.php
+++ b/src/__phutil_library_map__.php
@@ -403,6 +403,7 @@
'PhutilRemarkupLiteralBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupLiteralBlockRule.php',
'PhutilRemarkupMonospaceRule' => 'markup/engine/remarkup/markuprule/PhutilRemarkupMonospaceRule.php',
'PhutilRemarkupNoteBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupNoteBlockRule.php',
+ 'PhutilRemarkupQuotedBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupQuotedBlockRule.php',
'PhutilRemarkupQuotesBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupQuotesBlockRule.php',
'PhutilRemarkupReplyBlockRule' => 'markup/engine/remarkup/blockrule/PhutilRemarkupReplyBlockRule.php',
'PhutilRemarkupRule' => 'markup/engine/remarkup/markuprule/PhutilRemarkupRule.php',
@@ -1063,8 +1064,9 @@
'PhutilRemarkupLiteralBlockRule' => 'PhutilRemarkupBlockRule',
'PhutilRemarkupMonospaceRule' => 'PhutilRemarkupRule',
'PhutilRemarkupNoteBlockRule' => 'PhutilRemarkupBlockRule',
- 'PhutilRemarkupQuotesBlockRule' => 'PhutilRemarkupBlockRule',
- 'PhutilRemarkupReplyBlockRule' => 'PhutilRemarkupBlockRule',
+ 'PhutilRemarkupQuotedBlockRule' => 'PhutilRemarkupBlockRule',
+ 'PhutilRemarkupQuotesBlockRule' => 'PhutilRemarkupQuotedBlockRule',
+ 'PhutilRemarkupReplyBlockRule' => 'PhutilRemarkupQuotedBlockRule',
'PhutilRemarkupRule' => 'Phobject',
'PhutilRemarkupSimpleTableBlockRule' => 'PhutilRemarkupBlockRule',
'PhutilRemarkupTableBlockRule' => 'PhutilRemarkupBlockRule',
diff --git a/src/markup/engine/__tests__/remarkup/quoted-code-block.txt b/src/markup/engine/__tests__/remarkup/quoted-code-block.txt
--- a/src/markup/engine/__tests__/remarkup/quoted-code-block.txt
+++ b/src/markup/engine/__tests__/remarkup/quoted-code-block.txt
@@ -11,6 +11,6 @@
<span class="nv">$foo</span> <span class="k">=</span> <span class="s">&#039;bar&#039;</span><span class="k">;</span></pre></div></blockquote>
~~~~~~~~~~
> This should be a code block:
->
+>
> <?php
> $foo = 'bar';
diff --git a/src/markup/engine/__tests__/remarkup/quoted-lists.txt b/src/markup/engine/__tests__/remarkup/quoted-lists.txt
--- a/src/markup/engine/__tests__/remarkup/quoted-lists.txt
+++ b/src/markup/engine/__tests__/remarkup/quoted-lists.txt
@@ -18,7 +18,7 @@
~~~~~~~~~~
> 1. X
> 2. Y
-> ~
+>
> B
-> ~
+>
> - C
diff --git a/src/markup/engine/__tests__/remarkup/quoted-quote.txt b/src/markup/engine/__tests__/remarkup/quoted-quote.txt
new file mode 100644
--- /dev/null
+++ b/src/markup/engine/__tests__/remarkup/quoted-quote.txt
@@ -0,0 +1,19 @@
+>>! In U, W wrote:
+> - Y
+>
+> Z
+~~~~~~~~~~
+<blockquote class="remarkup-reply-block">
+<div class="remarkup-reply-head">In U, W wrote:</div>
+<div class="remarkup-reply-body"><ul class="remarkup-list">
+<li class="remarkup-list-item">Y</li>
+</ul>
+
+<p>Z</p></div>
+</blockquote>
+~~~~~~~~~~
+In U, W wrote:
+
+> - Y
+>
+> Z
diff --git a/src/markup/engine/__tests__/remarkup/reply-basic.txt b/src/markup/engine/__tests__/remarkup/reply-basic.txt
--- a/src/markup/engine/__tests__/remarkup/reply-basic.txt
+++ b/src/markup/engine/__tests__/remarkup/reply-basic.txt
@@ -9,4 +9,3 @@
In comment #123, alincoln wrote:
> Four score and twenty years ago...
-
diff --git a/src/markup/engine/__tests__/remarkup/reply-nested.txt b/src/markup/engine/__tests__/remarkup/reply-nested.txt
--- a/src/markup/engine/__tests__/remarkup/reply-nested.txt
+++ b/src/markup/engine/__tests__/remarkup/reply-nested.txt
@@ -41,10 +41,8 @@
>
> More previously, vegetables:
>
-> > - Potato
-> > - Potato
-> > - Potato
->
+>> - Potato
+>> - Potato
+>> - Potato
>
> The end.
-
diff --git a/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotedBlockRule.php b/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotedBlockRule.php
new file mode 100644
--- /dev/null
+++ b/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotedBlockRule.php
@@ -0,0 +1,108 @@
+<?php
+
+abstract class PhutilRemarkupQuotedBlockRule
+ extends PhutilRemarkupBlockRule {
+
+ final public function supportsChildBlocks() {
+ return true;
+ }
+
+ final protected function normalizeQuotedBody($text) {
+ $text = phutil_split_lines($text, true);
+ foreach ($text as $key => $line) {
+ $text[$key] = substr($line, 1);
+ }
+
+ // If every line in the block is empty or begins with at least one leading
+ // space, strip the initial space off each line. When we quote text, we
+ // normally add "> " (with a space) to the beginning of each line, which
+ // can disrupt some other rules. If the block appears to have this space
+ // in front of each line, remove it.
+
+ $strip_space = true;
+ foreach ($text as $key => $line) {
+ $len = strlen($line);
+
+ if (!$len) {
+ // We'll still strip spaces if there are some completely empty
+ // lines, they may have just had trailing whitespace trimmed.
+ continue;
+ }
+
+ // If this line is part of a nested quote block, just ignore it when
+ // realigning this quote block. It's either an author attribution
+ // line with ">>!", or we'll deal with it in a subrule when processing
+ // the nested quote block.
+ if ($line[0] == '>') {
+ continue;
+ }
+
+ if ($line[0] == ' ' || $line[0] == "\n") {
+ continue;
+ }
+
+ // The first character of this line is something other than a space, so
+ // we can't strip spaces.
+ $strip_space = false;
+ break;
+ }
+
+ if ($strip_space) {
+ foreach ($text as $key => $line) {
+ $len = strlen($line);
+ if (!$len) {
+ continue;
+ }
+
+ if ($line[0] !== ' ') {
+ continue;
+ }
+
+ $text[$key] = substr($line, 1);
+ }
+ }
+
+ // Strip leading empty lines.
+ foreach ($text as $key => $line) {
+ if (!strlen(trim($line))) {
+ unset($text[$key]);
+ }
+ }
+
+ return implode('', $text);
+ }
+
+ final protected function getQuotedText($text) {
+ $text = rtrim($text, "\n");
+
+ $no_whitespace = array(
+ // For readability, we render nested quotes as ">> quack",
+ // not "> > quack".
+ '>' => true,
+
+ // If the line is empty except for a newline, do not add an
+ // unnecessary dangling space.
+ "\n" => true,
+ );
+
+ $text = phutil_split_lines($text, true);
+ foreach ($text as $key => $line) {
+ $c = null;
+ if (isset($line[0])) {
+ $c = $line[0];
+ } else {
+ $c = null;
+ }
+
+ if (isset($no_whitespace[$c])) {
+ $text[$key] = '>'.$line;
+ } else {
+ $text[$key] = '> '.$line;
+ }
+ }
+ $text = implode('', $text);
+
+ return $text;
+ }
+
+}
diff --git a/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotesBlockRule.php b/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotesBlockRule.php
--- a/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotesBlockRule.php
+++ b/src/markup/engine/remarkup/blockrule/PhutilRemarkupQuotesBlockRule.php
@@ -1,6 +1,7 @@
<?php
-final class PhutilRemarkupQuotesBlockRule extends PhutilRemarkupBlockRule {
+final class PhutilRemarkupQuotesBlockRule
+ extends PhutilRemarkupQuotedBlockRule {
public function getMatchingLineCount(array $lines, $cursor) {
$pos = $cursor;
@@ -14,73 +15,13 @@
return ($pos - $cursor);
}
- public function supportsChildBlocks() {
- return true;
- }
-
public function extractChildText($text) {
- $text = phutil_split_lines($text, true);
- foreach ($text as $key => $line) {
- $text[$key] = substr($line, 1);
- }
-
- // If every line in the block is empty or begins with at least one leading
- // space, strip the initial space off each line. When we quote text, we
- // normally add "> " (with a space) to the beginning of each line, which
- // can disrupt some other rules. If the block appears to have this space
- // in front of each line, remove it.
-
- $strip_space = true;
- foreach ($text as $key => $line) {
- $len = strlen($line);
-
- if (!$len) {
- // We'll still strip spaces if there are some completely empty
- // lines, they may have just had trailing whitespace trimmed.
- continue;
- }
-
- if ($line[0] == ' ' || $line[0] == "\n") {
- continue;
- }
-
- // The first character of this line is something other than a space, so
- // we can't strip spaces.
- $strip_space = false;
- break;
- }
-
- if ($strip_space) {
- foreach ($text as $key => $line) {
- $len = strlen($line);
- if (!$len) {
- continue;
- }
-
- if ($line[0] !== ' ') {
- continue;
- }
-
- $text[$key] = substr($line, 1);
- }
- }
-
- return array('', implode('', $text));
+ return array('', $this->normalizeQuotedBody($text));
}
public function markupText($text, $children) {
if ($this->getEngine()->isTextMode()) {
- $lines = rtrim($children, "\n");
- $lines = phutil_split_lines($lines);
- foreach ($lines as $key => $line) {
- if (isset($line[0]) && ($line[0] == '>')) {
- $line = '>'.$line;
- } else {
- $line = '> '.$line;
- }
- $lines[$key] = $line;
- }
- return implode('', $lines);
+ return $this->getQuotedText($children);
}
$attributes = array();
diff --git a/src/markup/engine/remarkup/blockrule/PhutilRemarkupReplyBlockRule.php b/src/markup/engine/remarkup/blockrule/PhutilRemarkupReplyBlockRule.php
--- a/src/markup/engine/remarkup/blockrule/PhutilRemarkupReplyBlockRule.php
+++ b/src/markup/engine/remarkup/blockrule/PhutilRemarkupReplyBlockRule.php
@@ -1,6 +1,7 @@
<?php
-final class PhutilRemarkupReplyBlockRule extends PhutilRemarkupBlockRule {
+final class PhutilRemarkupReplyBlockRule
+ extends PhutilRemarkupQuotedBlockRule {
public function getPriority() {
return 400;
@@ -18,50 +19,23 @@
return ($pos - $cursor);
}
- public function supportsChildBlocks() {
- return true;
- }
-
public function extractChildText($text) {
$text = phutil_split_lines($text, true);
- $head = array();
- $body = array();
-
$head = substr(reset($text), 3);
$body = array_slice($text, 1);
+ $body = implode('', $body);
+ $body = $this->normalizeQuotedBody($body);
- // Remove the carets.
- foreach ($body as $key => $line) {
- $body[$key] = substr($line, 1);
- }
-
- // Strip leading empty lines.
- foreach ($body as $key => $line) {
- if (strlen(trim($line))) {
- break;
- }
- unset($body[$key]);
- }
-
- return array(trim($head), implode('', $body));
+ return array(trim($head), $body);
}
public function markupText($text, $children) {
$text = $this->applyRules($text);
if ($this->getEngine()->isTextMode()) {
- $children = phutil_split_lines($children, true);
- foreach ($children as $key => $child) {
- if (strlen(trim($child))) {
- $children[$key] = '> '.$child;
- } else {
- $children[$key] = '>'.$child;
- }
- }
- $children = implode('', $children);
-
+ $children = $this->getQuotedText($children);
return $text."\n\n".$children;
}

File Metadata

Mime Type
text/plain
Expires
Mar 26 2025, 7:57 PM (4 w, 3 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
7383758
Default Alt Text
D20393.id48698.diff (11 KB)

Event Timeline