improve parsing of list item and code block by measuring line indentation

This commit is contained in:
Emanuil Rusev 2014-01-31 02:19:18 +02:00
parent 72f4a375ef
commit e9098aebfa
1 changed files with 44 additions and 47 deletions

View File

@ -157,7 +157,14 @@ class Parsedown
# ~ # ~
$deindented_line = ltrim($line); $indentation = 0;
while(isset($line[$indentation]) and $line[$indentation] === ' ')
{
$indentation++;
}
$deindented_line = $indentation > 0 ? ltrim($line) : $line;
# blank # blank
@ -187,46 +194,23 @@ class Parsedown
case 'li': case 'li':
if (preg_match('/^([ ]{0,3})(\d+[.]|[*+-])[ ](.*)/', $line, $matches)) if ($block['indentation'] === $indentation and preg_match('/^'.$block['marker'].'[ ](.*)/', $deindented_line, $matches))
{ {
if ($block['indentation'] !== $matches[1]) unset($block['last']);
{
$block['lines'] []= $line;
}
else
{
unset($block['last']);
$blocks []= $block; $blocks []= $block;
unset($block['first']); unset($block['first']);
$block['last'] = true; $block['last'] = true;
$block['lines'] = array();
$block['lines'] = array( $block['lines'] []= preg_replace('/^[ ]{0,4}/', '', $matches[1]);
preg_replace('/^[ ]{0,4}/', '', $matches[3]),
);
}
continue 2; continue 2;
} }
if (isset($block['interrupted'])) if ( ! isset($block['interrupted']))
{
if ($line[0] === ' ')
{
$block['lines'] []= '';
$line = preg_replace('/^[ ]{0,4}/', '', $line);
$block['lines'] []= $line;
unset($block['interrupted']);
continue 2;
}
}
else
{ {
$line = preg_replace('/^[ ]{0,4}/', '', $line); $line = preg_replace('/^[ ]{0,4}/', '', $line);
@ -234,6 +218,18 @@ class Parsedown
continue 2; continue 2;
} }
elseif ($line[0] === ' ')
{
$block['lines'] []= '';
$line = preg_replace('/^[ ]{0,4}/', '', $line);
$block['lines'] []= $line;
unset($block['interrupted']);
continue 2;
}
break; break;
} }
@ -246,7 +242,7 @@ class Parsedown
# code # code
if (isset($line[3]) and $line[3] === ' ' and $line[2] === ' ' and $line[1] === ' ') if ($indentation >= 4)
{ {
$code_line = substr($line, 4); $code_line = substr($line, 4);
@ -494,42 +490,43 @@ class Parsedown
# li # li
if (preg_match('/^([ ]*)[*+-][ ](.*)/', $line, $matches)) if (preg_match('/^[*+-][ ](.*)/', $deindented_line, $matches))
{ {
$blocks []= $block; $blocks []= $block;
$block = array( $block = array(
'type' => 'li', 'type' => 'li',
'ordered' => false, 'indentation' => $indentation,
'indentation' => $matches[1], 'marker' => '[*+-]',
'first' => true, 'first' => true,
'last' => true, 'last' => true,
'lines' => array( 'lines' => array(),
preg_replace('/^[ ]{0,4}/', '', $matches[2]),
),
); );
$block['lines'] []= preg_replace('/^[ ]{0,4}/', '', $matches[1]);
continue 2; continue 2;
} }
} }
# list item # list item
if ($deindented_line[0] <= '9' and $deindented_line[0] >= '0' and preg_match('/^([ ]*)\d+[.][ ](.*)/', $line, $matches)) if ($deindented_line[0] <= '9' and preg_match('/^\d+[.][ ](.*)/', $deindented_line, $matches))
{ {
$blocks []= $block; $blocks []= $block;
$block = array( $block = array(
'type' => 'li', 'type' => 'li',
'ordered' => true, 'indentation' => $indentation,
'indentation' => $matches[1], 'marker' => '\d+[.]',
'first' => true, 'first' => true,
'last' => true, 'last' => true,
'lines' => array( 'ordered' => true,
preg_replace('/^[ ]{0,4}/', '', $matches[2]), 'lines' => array(),
),
); );
$block['lines'] []= preg_replace('/^[ ]{0,4}/', '', $matches[1]);
continue; continue;
} }
@ -654,7 +651,7 @@ class Parsedown
if (isset($block['first'])) if (isset($block['first']))
{ {
$type = $block['ordered'] ? 'ol' : 'ul'; $type = isset($block['ordered']) ? 'ol' : 'ul';
$markup .= '<'.$type.'>'."\n"; $markup .= '<'.$type.'>'."\n";
} }
@ -670,7 +667,7 @@ class Parsedown
if (isset($block['last'])) if (isset($block['last']))
{ {
$type = $block['ordered'] ? 'ol' : 'ul'; $type = isset($block['ordered']) ? 'ol' : 'ul';
$markup .= '</'.$type.'>'."\n"; $markup .= '</'.$type.'>'."\n";
} }