1
0
mirror of https://github.com/erusev/parsedown.git synced 2023-08-10 21:13:06 +03:00

Compare commits

...

14 Commits
0.9.1 ... 0.9.3

Author SHA1 Message Date
95e9878fb0 improve tests 2014-02-06 02:37:09 +02:00
611aed179d simplify reference 2014-02-06 02:36:22 +02:00
abb88d59fa fix reference 2014-02-06 02:36:11 +02:00
14ab6d46fe resolve #82 2014-02-06 00:10:18 +02:00
ebfdace4c6 reference labels should be case insensitive 2014-02-05 14:18:05 +02:00
ba7f377290 resolve #88, resolve #81 2014-02-05 14:03:43 +02:00
548a6f7945 resolve #89 2014-02-05 14:03:43 +02:00
7a4d3c0f18 Merge pull request #85 from cebe/simplify-tests
simplify testing and improved output
2014-02-04 03:46:39 -08:00
7f68a3a2e1 improve contributing guidelines 2014-02-04 01:49:55 +02:00
7193e634b2 Merge pull request #84 from wkpark/fix-em-strong
simplify em/strong routine
2014-02-03 05:28:20 -08:00
45c01d4673 simplify testing and improved output 2014-02-03 11:23:54 +01:00
59907ff757 simplify em/strong routine
retry to search em/strong markers to fix nested em/strong correctly
2014-02-03 16:48:28 +09:00
6e93b68692 outdented is shorter and probably more accurate 2014-02-02 23:41:58 +02:00
5a525be070 improve contributing guidelines 2014-02-02 23:23:50 +02:00
11 changed files with 134 additions and 82 deletions

View File

@ -1,15 +1,20 @@
Pull Requests
-------------
Do create pull requests that:
* resolve an issue
* optimise an existing feature or text
* improve an existing feature or text
Do NOT create pull requests that:
Do not create pull requests that:
* introduce a feature or text
* change the currently used coding style
* change the interface
* change the coding style
Pull requests should do only ONE thing. If a pull request contains unrelated updates, they should be submitted as separate pull requests.
If a pull request contains unrelated changes, they should be submitted as separate pull requests.
By contributing to the project, you grant to the creator of the project a perpetual, worldwide, no-charge, irrevocable license to use, reproduce and distribute your contributions and derivative works.
License
-------
You also warrant that you are the sole owner of your contributions and that they are your original works of authorship.
By contributing to the project, you grant the creator of the project a perpetual, worldwide, irrevocable license to use, reproduce and distribute your contributions and derivative works. You also warrant that you are the sole owner of your contributions and that they are your original works of authorship.

View File

@ -164,11 +164,11 @@ class Parsedown
$indentation++;
}
$deindented_line = $indentation > 0 ? ltrim($line) : $line;
$outdented_line = $indentation > 0 ? ltrim($line) : $line;
# blank
if ($deindented_line === '')
if ($outdented_line === '')
{
$block['interrupted'] = true;
@ -194,7 +194,7 @@ class Parsedown
case 'li':
if ($block['indentation'] === $indentation and preg_match('/^'.$block['marker'].'[ ]+(.*)/', $deindented_line, $matches))
if ($block['indentation'] === $indentation and preg_match('/^'.$block['marker'].'[ ]+(.*)/', $outdented_line, $matches))
{
unset($block['last']);
@ -330,15 +330,15 @@ class Parsedown
# indentation insensitive types
switch ($deindented_line[0])
switch ($outdented_line[0])
{
case '<':
$position = strpos($deindented_line, '>');
$position = strpos($outdented_line, '>');
if ($position > 1)
{
$substring = substr($deindented_line, 1, $position - 1);
$substring = substr($outdented_line, 1, $position - 1);
$substring = chop($substring);
@ -376,7 +376,7 @@ class Parsedown
{
$block = array(
'type' => 'self-closing tag',
'text' => $deindented_line,
'text' => $outdented_line,
);
unset($is_self_closing);
@ -386,13 +386,13 @@ class Parsedown
$block = array(
'type' => 'markup',
'text' => $deindented_line,
'text' => $outdented_line,
'start' => '<'.$name.'>',
'end' => '</'.$name.'>',
'depth' => 0,
);
if (strpos($deindented_line, $block['end']))
if (strpos($outdented_line, $block['end']))
{
$block['closed'] = true;
}
@ -406,7 +406,7 @@ class Parsedown
# quote
if (preg_match('/^>[ ]?(.*)/', $deindented_line, $matches))
if (preg_match('/^>[ ]?(.*)/', $outdented_line, $matches))
{
$blocks []= $block;
@ -426,19 +426,73 @@ class Parsedown
# reference
if (preg_match('/^\[(.+?)\]:[ ]*(.+?)(?:[ ]+[\'"](.+?)[\'"])?[ ]*$/', $deindented_line, $matches))
$position = strpos($outdented_line, ']:');
if ($position)
{
$label = strtolower($matches[1]);
$reference = array();
$this->reference_map[$label] = array(
'»' => trim($matches[2], '<>'),
);
$label = substr($outdented_line, 1, $position - 1);
$label = strtolower($label);
if (isset($matches[3]))
$substring = substr($outdented_line, $position + 2);
$substring = trim($substring);
if ($substring === '')
{
$this->reference_map[$label]['#'] = $matches[3];
break;
}
if ($substring[0] === '<')
{
$position = strpos($substring, '>');
if ($position === false)
{
break;
}
$reference['»'] = substr($substring, 1, $position - 1);
$substring = substr($substring, $position + 1);
}
else
{
$position = strpos($substring, ' ');
if ($position === false)
{
$reference['»'] = $substring;
$substring = false;
}
else
{
$reference['»'] = substr($substring, 0, $position);
$substring = substr($substring, $position + 1);
}
}
if ($substring !== false)
{
if ($substring[0] !== '"' and $substring[0] !== "'" and $substring[0] !== '(')
{
break;
}
$last_char = substr($substring, -1);
if ($last_char !== '"' and $last_char !== "'" and $last_char !== ')')
{
break;
}
$reference['#'] = substr($substring, 1, -1);
}
$this->reference_map[$label] = $reference;
continue 2;
}
@ -449,7 +503,7 @@ class Parsedown
# fenced code block
if (preg_match('/^([`]{3,}|[~]{3,})[ ]*(\S+)?[ ]*$/', $deindented_line, $matches))
if (preg_match('/^([`]{3,}|[~]{3,})[ ]*(\S+)?[ ]*$/', $outdented_line, $matches))
{
$blocks []= $block;
@ -476,7 +530,7 @@ class Parsedown
# hr
if (preg_match('/^([-*_])([ ]{0,2}\1){2,}[ ]*$/', $deindented_line))
if (preg_match('/^([-*_])([ ]{0,2}\1){2,}[ ]*$/', $outdented_line))
{
$blocks []= $block;
@ -489,7 +543,7 @@ class Parsedown
# li
if (preg_match('/^([*+-][ ]+)(.*)/', $deindented_line, $matches))
if (preg_match('/^([*+-][ ]+)(.*)/', $outdented_line, $matches))
{
$blocks []= $block;
@ -513,7 +567,7 @@ class Parsedown
# li
if ($deindented_line[0] <= '9' and preg_match('/^(\d+[.][ ]+)(.*)/', $deindented_line, $matches))
if ($outdented_line[0] <= '9' and preg_match('/^(\d+[.][ ]+)(.*)/', $outdented_line, $matches))
{
$blocks []= $block;
@ -887,34 +941,18 @@ class Parsedown
if ($text[1] === $closest_marker and preg_match(self::$strong_regex[$closest_marker], $text, $matches))
{
$markers[] = $closest_marker;
$matches[1] = $this->parse_span_elements($matches[1], $markers);
$markup .= '<strong>'.$matches[1].'</strong>';
}
elseif (preg_match(self::$em_regex[$closest_marker], $text, $matches))
{
$markers[] = $closest_marker;
$matches[1] = $this->parse_span_elements($matches[1], $markers);
$markup .= '<em>'.$matches[1].'</em>';
}
elseif ($text[1] === $closest_marker and preg_match(self::$strong_em_regex[$closest_marker], $text, $matches))
{
$matches[2] = $this->parse_span_elements($matches[2], $markers);
$matches[1] and $matches[1] = $this->parse_span_elements($matches[1], $markers);
$matches[3] and $matches[3] = $this->parse_span_elements($matches[3], $markers);
$markup .= '<strong>'.$matches[1].'<em>'.$matches[2].'</em>'.$matches[3].'</strong>';
}
elseif (preg_match(self::$em_strong_regex[$closest_marker], $text, $matches))
{
$matches[2] = $this->parse_span_elements($matches[2], $markers);
$matches[1] and $matches[1] = $this->parse_span_elements($matches[1], $markers);
$matches[3] and $matches[3] = $this->parse_span_elements($matches[3], $markers);
$markup .= '<em>'.$matches[1].'<strong>'.$matches[2].'</strong>'.$matches[3].'</em>';
}
if (isset($matches) and $matches)
{
@ -990,7 +1028,7 @@ class Parsedown
case '`':
if (preg_match('/^(`+)(.+?)\1(?!`)/', $text, $matches))
if (preg_match('/^(`+)[ ]*(.+?)[ ]*\1(?!`)/', $text, $matches))
{
$element_text = $matches[2];
$element_text = htmlspecialchars($element_text, ENT_NOQUOTES, 'UTF-8');
@ -1010,7 +1048,7 @@ class Parsedown
case 'http':
if (preg_match('/^https?:[\/]{2}[^\s]+\b/ui', $text, $matches))
if (preg_match('/^https?:[\/]{2}[^\s]+\b\/*/ui', $text, $matches))
{
$element_url = $matches[0];
$element_url = str_replace('&', '&amp;', $element_url);
@ -1070,23 +1108,13 @@ class Parsedown
# Read-only
private static $strong_regex = array(
'*' => '/^[*]{2}([^*]+?)[*]{2}(?![*])/s',
'_' => '/^__([^_]+?)__(?!_)/us',
'*' => '/^[*]{2}((?:[^*]|[*][^*]*[*])+?)[*]{2}(?![*])/s',
'_' => '/^__((?:[^_]|_[^_]*_)+?)__(?!_)/us',
);
private static $em_regex = array(
'*' => '/^[*]([^*]+?)[*](?![*])/s',
'_' => '/^_([^_]+?)[_](?![_])\b/us',
);
private static $strong_em_regex = array(
'*' => '/^[*]{2}(.*?)[*](.+?)[*](.*?)[*]{2}/s',
'_' => '/^__(.*?)_(.+?)_(.*?)__/us',
);
private static $em_strong_regex = array(
'*' => '/^[*](.*?)[*]{2}(.+?)[*]{2}(.*?)[*]/s',
'_' => '/^_(.*?)__(.+?)__(.*?)_/us',
'*' => '/^[*]((?:[^*]|[*][*][^*]+?[*][*])+?)[*](?![*])/s',
'_' => '/^_((?:[^_]|__[^_]*__)+?)_(?!_)\b/us',
);
private static $special_characters = array(

View File

@ -9,8 +9,14 @@ class Test extends PHPUnit_Framework_TestCase
/**
* @dataProvider provider
*/
function test_($markdown, $expected_markup)
function test_($filename)
{
$path = $this->get_data_path();
$markdown = file_get_contents($path . $filename . '.md');
$expected_markup = file_get_contents($path . $filename . '.html');
$expected_markup = str_replace("\r\n", "\n", $expected_markup);
$expected_markup = str_replace("\r", "\n", $expected_markup);
$actual_markup = Parsedown::instance()->parse($markdown);
$this->assertEquals($expected_markup, $actual_markup);
@ -20,9 +26,8 @@ class Test extends PHPUnit_Framework_TestCase
{
$provider = array();
$path = dirname(__FILE__).'/';
$DirectoryIterator = new DirectoryIterator($path . '/' . self::provider_dir);
$path = $this->get_data_path();
$DirectoryIterator = new DirectoryIterator($path);
foreach ($DirectoryIterator as $Item)
{
@ -36,20 +41,17 @@ class Test extends PHPUnit_Framework_TestCase
continue;
$basename = $Item->getBasename('.md');
$markdown = file_get_contents($path . '/' . self::provider_dir . $basename . '.md');
if (!$markdown)
continue;
$expected_markup = file_get_contents($path . '/' . self::provider_dir . $basename . '.html');
$expected_markup = str_replace("\r\n", "\n", $expected_markup);
$expected_markup = str_replace("\r", "\n", $expected_markup);
$provider [] = array($markdown, $expected_markup);
if (file_exists($path.$basename.'.html')) {
$provider [] = array($basename);
}
}
}
return $provider;
}
function get_data_path()
{
return dirname(__FILE__).'/'.self::provider_dir;
}
}

View File

@ -1,3 +1,5 @@
<p>a <code>code span</code></p>
<p><code>this is also a codespan</code> trailing text</p>
<p><code>and look at this one!</code></p>
<p><code>and look at this one!</code></p>
<p>single backtick in a code span: <code>`</code></p>
<p>backtick-delimited string in a code span: <code>`foo`</code></p>

View File

@ -2,4 +2,8 @@ a `code span`
`this is also a codespan` trailing text
`and look at this one!`
`and look at this one!`
single backtick in a code span: `` ` ``
backtick-delimited string in a code span: `` `foo` ``

View File

@ -0,0 +1 @@
<p><a href="http://example.com" title="Title">single quotes</a> and <a href="http://example.com" title="Title">double quotes</a></p>

View File

@ -0,0 +1 @@
[single quotes](http://example.com 'Title') and [double quotes](http://example.com "Title")

View File

@ -1 +1,2 @@
<p><a href="http://example.com" title="Title">single quotes</a> and <a href="http://example.com" title="Title">double quotes</a></p>
<p><a href="http://example.com" title="example title">double quotes</a> and <a href="http://example.com" title="example title">single quotes</a> and <a href="http://example.com" title="example title">parentheses</a></p>
<p>[invalid title]: <a href="http://example.com">http://example.com</a> example title</p>

View File

@ -1 +1,6 @@
[single quotes](http://example.com 'Title') and [double quotes](http://example.com "Title")
[double quotes] and [single quotes] and [parentheses]
[double quotes]: http://example.com "example title"
[single quotes]: http://example.com 'example title'
[parentheses]: http://example.com (example title)
[invalid title]: http://example.com example title

View File

@ -1,2 +1,3 @@
<p>an autolink <a href="http://example.com">http://example.com</a></p>
<p>inside of brackets [<a href="http://example.com">http://example.com</a>], inside of braces {<a href="http://example.com">http://example.com</a>}, inside of parentheses (<a href="http://example.com">http://example.com</a>)</p>
<p>inside of brackets [<a href="http://example.com">http://example.com</a>], inside of braces {<a href="http://example.com">http://example.com</a>}, inside of parentheses (<a href="http://example.com">http://example.com</a>)</p>
<p>trailing slash <a href="http://example.com/">http://example.com/</a> and <a href="http://example.com/path/">http://example.com/path/</a></p>

View File

@ -1,3 +1,5 @@
an autolink http://example.com
inside of brackets [http://example.com], inside of braces {http://example.com}, inside of parentheses (http://example.com)
inside of brackets [http://example.com], inside of braces {http://example.com}, inside of parentheses (http://example.com)
trailing slash http://example.com/ and http://example.com/path/