Skip to content

Commit

Permalink
fixed handling of non-separated block elements
Browse files Browse the repository at this point in the history
improved markdown handling of block elements that are not separated by a
blank line.

fixes #27
  • Loading branch information
cebe committed Feb 18, 2014
1 parent 1d18ebc commit 8d035ac
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 11 deletions.
2 changes: 1 addition & 1 deletion GithubMarkdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected function inlineMarkers()
*/
protected function identifyLine($lines, $current)
{
if (strncmp($lines[$current], '```', 3) === 0) {
if (isset($lines[$current]) && strncmp($lines[$current], '```', 3) === 0) {
return 'fencedCode';
}
return parent::identifyLine($lines, $current);
Expand Down
47 changes: 38 additions & 9 deletions Markdown.php
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ protected function prepare()
*/
protected function identifyLine($lines, $current)
{
if (empty($lines[$current]) || ltrim($lines[$current]) === '') {
if (empty($lines[$current])) {
return 'empty';
}
$line = $lines[$current];
Expand Down Expand Up @@ -205,6 +205,28 @@ protected function identifyLine($lines, $current)
return 'paragraph';
}

/**
* Consume lines for a paragraph
*/
public function consumeParagraph($lines, $current)
{
// consume until newline or intended line

$block = [
'type' => 'paragraph',
'content' => [],
];
for($i = $current, $count = count($lines); $i < $count; $i++) {
if (ltrim($lines[$i]) !== '' && $lines[$i][0] != "\t" && strncmp($lines[$i], ' ', 4) !== 0) {
$block['content'][] = $lines[$i];
} else {
break;
}
}

return [$block, --$i];
}

/**
* Consume lines for a blockquote element
*/
Expand Down Expand Up @@ -247,7 +269,14 @@ protected function consumeCode($lines, $current)
];
for($i = $current, $count = count($lines); $i < $count; $i++) {
$line = $lines[$i];
if (ltrim($line) !== '' || isset($lines[$i + 1]) && $this->identifyLine($lines, $i + 1) === 'code') {

// a line is considered to belong to this code block as long as it is intended by 4 spaces or a tab
if (isset($line[0]) && ($line[0] === "\t" || strncmp($lines[$i], ' ', 4) === 0)) {
$line = $line[0] === "\t" ? substr($line, 1) : substr($line, 4);
$block['content'][] = $line;
// but also if it is empty and the next line is intended by 4 spaces or a tab
} elseif ((empty($line) || rtrim($line) === '') && isset($lines[$i + 1][0]) &&
($lines[$i + 1][0] === "\t" || strncmp($lines[$i + 1], ' ', 4) === 0)) {
if (!empty($line)) {
$line = $line[0] === "\t" ? substr($line, 1) : substr($line, 4);
}
Expand All @@ -257,7 +286,7 @@ protected function consumeCode($lines, $current)
}
}

return [$block, $i];
return [$block, --$i];
}

/**
Expand Down Expand Up @@ -311,7 +340,7 @@ private function consumeList($lines, $current, $block, $type)
$block['items'][++$item][] = $line;
} elseif (ltrim($line) === '') {
// next line after empty one is also a list or indented -> lazy list
if (isset($lines[$i + 1]) && (
if (isset($lines[$i + 1][0]) && (
$this->identifyLine($lines, $i + 1) === $type ||
(strncmp($lines[$i + 1], $indent, $len) === 0 || !empty($lines[$i + 1]) && $lines[$i + 1][0] == "\t"))) {
$block['items'][$item][] = $line;
Expand Down Expand Up @@ -355,15 +384,15 @@ protected function consumeHeadline($lines, $current)
'content' => trim($lines[$current], "# \t"),
'level' => $level,
];
return [$block, ++$current];
return [$block, $current];
}

$block = [
'type' => 'headline',
'content' => $lines[$current],
'level' => $lines[$current + 1][0] === '=' ? 1 : 2,
];
return [$block, $current + 2];
return [$block, $current + 1];
}

/**
Expand Down Expand Up @@ -409,7 +438,7 @@ protected function consumeHr($lines, $current)
$block = [
'type' => 'hr',
];
return [$block, $current + 1];
return [$block, $current];
}

/**
Expand All @@ -434,7 +463,7 @@ protected function consumeReference($lines, $current)
}
$current++;
}
return [false, $current];
return [false, --$current];
}


Expand Down Expand Up @@ -469,7 +498,7 @@ protected function renderList($block)
$output .= '<li>';
if (!isset($block['lazyItems'][$item])) {
$firstPar = [];
while(!empty($itemLines) && $this->identifyLine($itemLines, 0) === 'paragraph') {
while(!empty($itemLines) && rtrim($itemLines[0]) !== '' && $this->identifyLine($itemLines, 0) === 'paragraph') {
$firstPar[] = array_shift($itemLines);
}
$output .= $this->parseInline(implode("\n", $firstPar));
Expand Down
2 changes: 1 addition & 1 deletion Parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ protected function parseBlocks($lines)
// convert lines to blocks

for($i = 0, $count = count($lines); $i < $count; $i++) {
if (!empty($lines[$i])) { // skip empty lines
if (!empty($lines[$i]) && rtrim($lines[$i]) !== '') { // skip empty lines
// identify a blocks beginning
$blockType = $this->identifyLine($lines, $i);

Expand Down
50 changes: 50 additions & 0 deletions tests/markdown-data/dense-block-markers.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<h1>this is to test dense blocks (no newlines between them)</h1>
<hr />
<h2>what is Markdown?</h2>
<p>see <a href="http://en.wikipedia.org/wiki/Markdown">Wikipedia</a></p>
<h2>a h2</h2>
<p>paragraph</p>
<p>this is a paragraph, not a headline or list
next line
- whoo</p>
<p>par</p>
<pre><code>code
code
</code></pre>
<p>par</p>
<h3>Tasks list</h3>
<ul>
<li>list items</li>
</ul>
<h2>headline1</h2>
<blockquote><p>quote
quote</p>
</blockquote>
<h2>headline2</h2>
<hr />
<h1>h1</h1>
<h2>h2</h2>
<hr />
<h3>h3</h3>
<ol>
<li>ol1</li>
<li>ol2</li>
</ol>
<h4>h4</h4>
<ul>
<li>listA</li>
<li>listB</li>
</ul>
<h5>h5</h5>
<h6>h6</h6>
<hr />
<hr />
<h2>changelog 1</h2>
<ul>
<li>17-Feb-2013 re-design</li>
</ul>
<hr />
<h2>changelog 2</h2>
<ul>
<li>17-Feb-2013 re-design</li>
</ul>
56 changes: 56 additions & 0 deletions tests/markdown-data/dense-block-markers.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# this is to test dense blocks (no newlines between them)

----
## what is Markdown?
see [Wikipedia][]

a h2
----
paragraph

this is a paragraph, not a headline or list
next line
- whoo

par
code
code
par

### Tasks list
- list items

headline1
---------
> quote
> quote
[Wikipedia]: http://en.wikipedia.org/wiki/Markdown
headline2
---------

----
# h1
## h2
---
### h3
1. ol1
2. ol2

#### h4
- listA
- listB

##### h5
###### h6
--------

----

## changelog 1

* 17-Feb-2013 re-design

----
## changelog 2
* 17-Feb-2013 re-design
1 change: 1 addition & 0 deletions tests/markdown-data/md1_inline_html_simple.html
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
<!-- foo -->
<p>Code:</p>
<pre><code>&lt;hr /&gt;

</code></pre>
<p>Hr's:</p>
<hr>
Expand Down
1 change: 1 addition & 0 deletions tests/markdown-data/md1_markdown_documentation_basics.html
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ <h2>Lists</h2>
&lt;p&gt;With multiple paragraphs.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Another item in the list.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

</code></pre>
<h3>Links</h3>
<p>Markdown supports two styles for creating links: <em>inline</em> and
Expand Down

0 comments on commit 8d035ac

Please sign in to comment.