From 00e2cbeef8ec00d74dfb2654e49efd35b7e5d59d Mon Sep 17 00:00:00 2001 From: Jukka Svahn Date: Fri, 25 Oct 2013 19:11:36 +0300 Subject: [PATCH] Preserve whitespace as it was first specified. Prevents Textile from collapsing white-space inside code blocks and removes added extra hard-coded newlines that only work because they are inside inline HTML elements, e.g. code. White-space is trimmed from the end of the text, because otherwise the last extended block will include the last stranded empty line. This then removes the need for the trim + hard-coded LF, and allows us to actually join the blocks with the original separating whitespace. This fixes the formatting inside bc, notextile, bq and pre tags, and/or any other extended blocks. Closes #111, fixes #109 --- src/Netcarver/Textile/Parser.php | 40 ++++++++++++++++++++++---------- test/fixtures/basic.yaml | 36 +++++++++++++++++++++------- 2 files changed, 56 insertions(+), 20 deletions(-) diff --git a/src/Netcarver/Textile/Parser.php b/src/Netcarver/Textile/Parser.php index b2e5725c..8a45488e 100644 --- a/src/Netcarver/Textile/Parser.php +++ b/src/Netcarver/Textile/Parser.php @@ -1843,7 +1843,7 @@ protected function blocks($text) { $blocktags = join('|', $this->blocktag_whitelist); - $text = explode("\n\n", $text); + $text = preg_split('/(\n{2,})/', $text, null, PREG_SPLIT_DELIM_CAPTURE); $tag = 'p'; $atts = ''; @@ -1851,10 +1851,22 @@ protected function blocks($text) $graf = ''; $ext = ''; $eat = false; + $whitespace = ''; + $eatWhitespace = false; $out = array(); - foreach ($text as $line) { + foreach ($text as $key => $line) { + + // Line is just whitespace, keep it for the next block. + if (trim($line) === '') { + if ($eatWhitespace === false) { + $whitespace .= $line; + } + continue; + } + + $eatWhitespace = false; $anon = 0; if (preg_match("/^($blocktags)($this->a$this->c)\.(\.?)(?::(\S+))? (.*)$/Ss", $line, $m)) { // Last block was extended, so close it @@ -1889,14 +1901,20 @@ protected function blocks($text) } $line = $this->doPBr($line); - $line = preg_replace('/
/', '
', $line); + $line = $whitespace . preg_replace('/
/', '
', $line); if ($ext && $anon) { - $out[count($out)-1] .= "\n".$line; + $out[count($out)-1] .= $line; } elseif (!$eat) { $out[] = $line; } + if ($eat) { + $eatWhitespace = true; + } else { + $whitespace = ''; + } + if (!$ext) { $tag = 'p'; $atts = ''; @@ -1910,7 +1928,7 @@ protected function blocks($text) $out[count($out)-1] .= $c1; } - return join("\n\n", $out); + return join('', $out); } /** @@ -1985,7 +2003,7 @@ protected function fBlock($m) $o2 = ""; $c2 = ""; $c1 = ""; - $content = $this->shelve($this->rEncodeHTML(rtrim($content, "\n")."\n")); + $content = $this->shelve($this->rEncodeHTML($content)); } elseif ($tag == 'notextile') { $content = $this->shelve($content); $o1 = ''; @@ -1993,7 +2011,7 @@ protected function fBlock($m) $c1 = ''; $c2 = ''; } elseif ($tag == 'pre') { - $content = $this->shelve($this->rEncodeHTML(rtrim($content, "\n")."\n")); + $content = $this->shelve($this->rEncodeHTML($content)); $o1 = ""; $o2 = ''; $c2 = ''; @@ -2857,12 +2875,10 @@ protected function cleanWhiteSpace($text) $out = preg_replace("/^\xEF\xBB\xBF|\x1A/", '', $text); // Replaces CRLF and CR with single LF. $out = preg_replace("/\r\n?/", "\n", $out); - // Replaces line endings containing only whitespace with single LF. + // Removes leading tabs and spaces, if the line is otherwise empty. $out = preg_replace("/^[ \t]*\n/m", "\n", $out); - // Trim three or more LFs down to 2. - $out = preg_replace("/\n{3,}/", "\n\n", $out); - // Removes leading blank lines. - $out = preg_replace("/^\n*/", "", $out); + // Removes leading and ending blank lines. + $out = trim($out, "\n"); return $out; } diff --git a/test/fixtures/basic.yaml b/test/fixtures/basic.yaml index 445c0696..f54a6b9b 100644 --- a/test/fixtures/basic.yaml +++ b/test/fixtures/basic.yaml @@ -726,8 +726,7 @@ HTML Comments : Comment -->

-
<!-- Here is a comment block in a code block. -->
-    
+
<!-- Here is a comment block in a code block. -->
URLs as non-links : notes : Straight URL text sequences should not be converted to a hyperlink. @@ -1329,10 +1328,21 @@ Code blocks, pre and exclusions : + bc.. Code block + + + + with three empty lines + p(regular#somestuff). _Aaaand_, *__relax__*. + + bc.. Paragraph 1 + + Paragraph 2 + + Paragraph 3 expect : | -
You can't _*touch*_ *_this_*... Hammer time.
-    
+
You can't _*touch*_ *_this_*... Hammer time.

And keep your (expect)mitts _*off*_ *_me_* as well. About the <hr /> tag.

@@ -1342,11 +1352,22 @@ Code blocks, pre and exclusions : <txp:image class="prawns" something="summat else" /> <br /> <txp:image_info type="caption" /> - </txp:category> - + </txp:category> + +
Code block
+
+
+
+    with three empty lines

Aaaand, relax.

+
Paragraph 1
+
+    Paragraph 2
+
+    Paragraph 3
+ Basic span modifiers & glyphs: input: | This is the "start" and 'end'; and I'm stuck in '88!: With smd_g4llery's attributes where hëll_won't__fr33ze_over if I use apostrophes inside odd words and_underscores (Pah). @@ -1438,8 +1459,7 @@ Make sure these don't get turned into lists... : ; Cache-Control: no-store, no-cache, must-revalidate, pre-check=0, post-check=0, max-age=0 ; Expires: Sat, 24 Jul 2003 05:00:00 GMT ; Last-Modified: Wed, 1 Jan 2025 05:00:00 GMT - ; Pragma: no-cache - + ; Pragma: no-cache

123 test