Skip to content

Commit

Permalink
rearrange block types to optimize performance
Browse files Browse the repository at this point in the history
  • Loading branch information
erusev committed Nov 4, 2013
1 parent d4d3612 commit 6d113f4
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 91 deletions.
141 changes: 75 additions & 66 deletions Parsedown.php
Original file line number Diff line number Diff line change
Expand Up @@ -217,56 +217,14 @@ private function parse_block_elements(array $lines, $context = '')

# Quick Paragraph

if ($line[0] >= 'A' and $line['0'] !== '_')
if ($line[0] >= 'A' and $line[0] !== '_')
{
goto paragraph; # trust me
}

# Setext Header (---)

if ($element['type'] === 'p' and ! isset($element['interrupted']) and preg_match('/^[-]+[ ]*$/', $line))
{
$element['type'] = 'h.';
$element['level'] = 2;

continue;
}

# Horizontal Rule

if (preg_match('/^[ ]{0,3}([-*_])([ ]{0,2}\1){2,}[ ]*$/', $line))
{
$elements []= $element;

$element = array(
'type' => 'hr',
);

continue;
}

# List Item

if (preg_match('/^([ ]{0,3})(\d+[.]|[*+-])[ ](.*)/', $line, $matches))
{
$elements []= $element;

$element = array(
'type' => 'li',
'ordered' => isset($matches[2][1]),
'indentation' => $matches[1],
'last' => true,
'lines' => array(
preg_replace('/^[ ]{0,4}/', '', $matches[3]),
),
);

continue;
}

# Code

if (preg_match('/^[ ]{4}(.*)/', $line, $matches))
if ($line[0] === ' ' and preg_match('/^[ ]{4}(.*)/', $line, $matches))
{
if ($element['type'] === 'code')
{
Expand All @@ -279,10 +237,20 @@ private function parse_block_elements(array $lines, $context = '')
$elements []= $element;

$element = array(
'type' => 'code',
'type' => 'code',
'text' => $matches[1],
);
}

continue;
}

# Setext Header (---)

if ($line[0] === '-' and $element['type'] === 'p' and ! isset($element['interrupted']) and preg_match('/^[-]+[ ]*$/', $line))
{
$element['type'] = 'h.';
$element['level'] = 2;

continue;
}
Expand All @@ -296,17 +264,31 @@ private function parse_block_elements(array $lines, $context = '')
$level = strlen($matches[1]);

$element = array(
'type' => 'h.',
'text' => $matches[2],
'type' => 'h.',
'text' => $matches[2],
'level' => $level,
);

continue;
}

# Setext Header (===)

if ($line[0] === '=' and $element['type'] === 'p' and ! isset($element['interrupted']) and preg_match('/^[=]+[ ]*$/', $line))
{
$element['type'] = 'h.';
$element['level'] = 1;

continue;
}

# ~

$pure_line = ltrim($line);

# Blockquote

if (preg_match('/^[ ]*>[ ]?(.*)/', $line, $matches))
if ($pure_line[0] === '>' and preg_match('/^>[ ]?(.*)/', $pure_line, $matches))
{
if ($element['type'] === 'blockquote')
{
Expand Down Expand Up @@ -334,45 +316,72 @@ private function parse_block_elements(array $lines, $context = '')
continue;
}

# Setext Header (===)
# HTML

if ($element['type'] === 'p' and ! isset($element['interrupted']) and preg_match('/^[=]+[ ]*$/', $line))
if ($pure_line[0] === '<')
{
$element['type'] = 'h.';
$element['level'] = 1;
# Block-Level HTML <self-closing/>

if (preg_match('{^<.+?/>$}', $pure_line))
{
$elements []= $element;

$element = array(
'type' => '',
'text' => $pure_line,
);

continue;
}

continue;
}
# Block-Level HTML <open>

# Block-Level HTML <self-closing/>
if (preg_match('{^<(\w+)(?:[ ].*?)?>}', $pure_line, $matches))
{
$elements []= $element;

$element = array(
'type' => 'block',
'subtype' => strtolower($matches[1]),
'text' => $pure_line,
'depth' => 0,
);

preg_match('{</'.$matches[1].'>\s*$}', $pure_line) and $element['closed'] = true;

continue;
}
}

# Horizontal Rule

if (preg_match('{^<.+?/>$}', $line))
if (preg_match('/^([-*_])([ ]{0,2}\1){2,}[ ]*$/', $pure_line))
{
$elements []= $element;

$element = array(
'type' => '',
'text' => $line,
'type' => 'hr',
);

continue;
}

# Block-Level HTML <open>
# List Item

if (preg_match('{^<(\w+)(?:[ ].*?)?>}', $line, $matches))
if (preg_match('/^([ ]*)(\d+[.]|[*+-])[ ](.*)/', $line, $matches))
{
$elements []= $element;

$element = array(
'type' => 'block',
'subtype' => strtolower($matches[1]),
'text' => $line,
'depth' => 0,
'type' => 'li',
'ordered' => isset($matches[2][1]),
'indentation' => $matches[1],
'last' => true,
'lines' => array(
preg_replace('/^[ ]{0,4}/', '', $matches[3]),
),
);

preg_match('{</'.$matches[1].'>\s*$}', $line) and $element['closed'] = true;

continue;
}

Expand Down
30 changes: 16 additions & 14 deletions tests/data/sparse_list.html
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
<p>Here's a list where items are separated by empty lines:</p>
<ul>
<li>
<p>list item</p>
</li>
<li>another list item</li>
</ul>
<p>Here's an ordered one:</p>
<ol>
<li>
<p>item one</p>
</li>
<li>item two</li>
</ol>
<p>Here's a sparse list:</p>
<ul>
<li>
<p>list item</p>
</li>
<li>another list item</li>
</ul>
<p>Here's one with an indented list item:</p>
<ul>
<li>
<p>li</p>
<ul>
<li>li</li>
</ul>
</li>
</ul>
22 changes: 11 additions & 11 deletions tests/data/sparse_list.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
Here's a list where items are separated by empty lines:

- list item

- another list item

Here's an ordered one:

1. item one

2. item two
Here's a sparse list:

- list item

- another list item

Here's one with an indented list item:

- li

- li

0 comments on commit 6d113f4

Please sign in to comment.