1
0
mirror of https://github.com/erusev/parsedown.git synced 2025-09-04 12:15:27 +02:00

Compare commits

..

49 Commits
1.4.2 ... 1.5.2

Author SHA1 Message Date
Emanuil Rusev
468d1e3da8 improve readme 2015-03-18 20:44:57 +02:00
Emanuil Rusev
7aa1d97bba improve readme 2015-03-18 20:43:30 +02:00
Emanuil Rusev
f768f9c63f improve readme 2015-03-18 20:42:44 +02:00
Emanuil Rusev
aa83968534 improve readme 2015-03-18 20:41:23 +02:00
Emanuil Rusev
85eadccc05 Merge pull request #297 from hkdobrev/patch-1
Remove "tested in PHP 5.2"
2015-03-18 20:39:40 +02:00
Haralan Dobrev
c94fa12d67 Remove "tested on PHP 5.2"
It is no longer tested on PHP 5.2 in Travis CI.

See https://github.com/erusev/parsedown/pull/286
2015-03-18 17:15:00 +02:00
Emanuil Rusev
11e02d45fa improve readme 2015-03-18 16:20:28 +02:00
Emanuil Rusev
ecd53f9add improve readme 2015-03-18 16:16:51 +02:00
Emanuil Rusev
844b2f49ea Merge pull request #249 from HelpingHand1/patch-1
Updated readme to display travis-ci.org build test
2015-03-18 16:08:13 +02:00
Emanuil Rusev
65116c3cb0 Merge pull request #286 from henriquemoody/travis
Remove PHP version 5.2 from Travis builds
2015-02-09 01:04:08 +02:00
Henrique Moody
147003107a Remove PHP version 5.2 from Travis builds 2015-02-08 21:00:50 -02:00
Emanuil Rusev
618b26056c Merge pull request #284 from jstanden/master
Fixes #283
2015-02-04 00:39:05 +02:00
Jeff Standen
b828fe7c8d Fixes #283 2015-02-03 13:58:47 -08:00
Emanuil Rusev
6c9df528aa Merge pull request #280 from kelunik/master
Fixes PHP 7 compatibility
2015-02-02 02:33:38 +02:00
Niklas Keller
cb8cc57742 Fixes #279 2015-02-02 00:58:24 +01:00
Emanuil Rusev
9da19c1108 version 1.5.1 2015-01-24 15:01:47 +02:00
Emanuil Rusev
ffd9d3b407 improve tests 2015-01-24 14:37:40 +02:00
Emanuil Rusev
e94ecf4adc resolve #277 2015-01-24 14:21:55 +02:00
Emanuil Rusev
4d3079b908 resolve #274 2015-01-24 14:03:05 +02:00
Emanuil Rusev
70e7a17380 update readme 2015-01-24 04:54:01 +02:00
Emanuil Rusev
9518c8e384 improve readme 2015-01-24 04:51:13 +02:00
Emanuil Rusev
c581284231 improve readme 2015-01-24 02:33:41 +02:00
Emanuil Rusev
cb1940255a improve readme 2015-01-24 01:31:49 +02:00
Emanuil Rusev
93d0ec9397 improve readme 2015-01-24 01:27:48 +02:00
Emanuil Rusev
9c6e7e880a improve readme 2015-01-24 01:26:59 +02:00
Emanuil Rusev
2d62e29625 improve readme 2015-01-24 01:21:16 +02:00
Emanuil Rusev
595f33871e improve readme 2015-01-24 01:18:49 +02:00
Emanuil Rusev
97e1e0efaa improve readme 2015-01-24 01:15:08 +02:00
Emanuil Rusev
648419467a clean up 2015-01-21 01:32:20 +02:00
Emanuil Rusev
6ddb6b2b33 resolve #90 2015-01-19 17:11:13 +02:00
Emanuil Rusev
0008e69a83 clean up 2015-01-19 17:09:51 +02:00
Emanuil Rusev
c664785485 inline methods should be able to handle unmarked inline elements 2015-01-19 17:05:10 +02:00
Emanuil Rusev
bdf0ef024e setter variables should not be private 2015-01-18 19:38:57 +02:00
Emanuil Rusev
21a3e8790a no need for a separate method for every special character 2015-01-16 03:57:47 +02:00
Emanuil Rusev
e5e8d02934 improve order of methods 2015-01-16 03:18:07 +02:00
Emanuil Rusev
7ff0f97811 improve performance 2015-01-16 02:59:51 +02:00
Emanuil Rusev
596350d1f5 improve names of elements 2015-01-16 02:49:55 +02:00
Emanuil Rusev
2cbd3010e4 url elements should not be restricted to http 2015-01-16 02:31:58 +02:00
Emanuil Rusev
3b4aa6bff7 change the parsing order of tag elements to improve performance 2015-01-16 01:46:43 +02:00
Emanuil Rusev
05a8f16e95 improve CommonMark compliance 2015-01-16 01:44:35 +02:00
Emanuil Rusev
79d924040a improve CommonMark compliance 2015-01-16 01:24:02 +02:00
Emanuil Rusev
b4a8eb3315 resolve #156 2015-01-16 00:04:18 +02:00
Emanuil Rusev
4383cce85b resolve #143 2015-01-15 22:31:31 +02:00
Emanuil Rusev
ada39109e4 resolve #189 2015-01-15 22:04:02 +02:00
Emanuil Rusev
a06cdfb814 improve fix for #184 2015-01-15 21:32:18 +02:00
Emanuil Rusev
6bee326c92 resolve #184 2015-01-15 21:10:09 +02:00
Emanuil Rusev
3fe867d294 update readme 2015-01-15 18:28:11 +02:00
HelpingHand1
4b7d7cdef2 updated readme.md per comment by cebe 2014-12-13 13:01:40 -05:00
HelpingHand1
97e667ab30 Updated readme to display travis-ci.org build test 2014-12-10 18:13:48 -05:00
15 changed files with 337 additions and 335 deletions

View File

@@ -5,6 +5,4 @@ php:
- 5.5
- 5.4
- 5.3
- 5.2
- hhvm

View File

@@ -15,15 +15,10 @@
class Parsedown
{
#
# Philosophy
# ~
# Parsedown recognises that the Markdown syntax is optimised for humans so
# it tries to read like one. It goes through text line by line. It looks at
# how lines start to identify blocks. It looks for special characters to
# identify inline elements.
const version = '1.5.1';
#
# ~
function text($text)
@@ -53,8 +48,6 @@ class Parsedown
# Setters
#
private $breaksEnabled;
function setBreaksEnabled($breaksEnabled)
{
$this->breaksEnabled = $breaksEnabled;
@@ -62,7 +55,7 @@ class Parsedown
return $this;
}
private $markupEscaped;
protected $breaksEnabled;
function setMarkupEscaped($markupEscaped)
{
@@ -71,7 +64,7 @@ class Parsedown
return $this;
}
private $urlsLinked = true;
protected $markupEscaped;
function setUrlsLinked($urlsLinked)
{
@@ -80,6 +73,8 @@ class Parsedown
return $this;
}
protected $urlsLinked = true;
#
# Lines
#
@@ -534,7 +529,7 @@ class Parsedown
protected function blockListContinue($Line, array $Block)
{
if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'[ ]+(.*)/', $Line['text'], $matches))
if ($Block['indent'] === $Line['indent'] and preg_match('/^'.$Block['pattern'].'(?:[ ]+(.*)|$)/', $Line['text'], $matches))
{
if (isset($Block['interrupted']))
{
@@ -545,11 +540,13 @@ class Parsedown
unset($Block['li']);
$text = isset($matches[1]) ? $matches[1] : '';
$Block['li'] = array(
'name' => 'li',
'handler' => 'li',
'text' => array(
$matches[1],
$text,
),
);
@@ -558,6 +555,11 @@ class Parsedown
return $Block;
}
if ($Line['text'][0] === '[' and $this->blockReference($Line))
{
return $Block;
}
if ( ! isset($Block['interrupted']))
{
$text = preg_replace('/^[ ]{0,4}/', '', $Line['body']);
@@ -734,8 +736,6 @@ class Parsedown
{
$Block['closed'] = true;
}
$Block['markup'] .= $matches[1];
}
if (isset($Block['interrupted']))
@@ -850,7 +850,7 @@ class Parsedown
$alignment = $alignments[$index];
$HeaderElement['attributes'] = array(
'align' => $alignment,
'style' => 'text-align: '.$alignment.';',
);
}
@@ -905,9 +905,9 @@ class Parsedown
$row = trim($row);
$row = trim($row, '|');
$cells = explode('|', $row);
preg_match_all('/(?:(\\\\[|])|[^|`]|`[^`]+`|`)+/', $row, $matches);
foreach ($cells as $index => $cell)
foreach ($matches[0] as $index => $cell)
{
$cell = trim($cell);
@@ -920,7 +920,7 @@ class Parsedown
if (isset($Block['alignments'][$index]))
{
$Element['attributes'] = array(
'align' => $Block['alignments'][$index],
'style' => 'text-align: '.$Block['alignments'][$index].';',
);
}
@@ -956,75 +956,18 @@ class Parsedown
return $Block;
}
#
# ~
#
protected function element(array $Element)
{
$markup = '<'.$Element['name'];
if (isset($Element['attributes']))
{
foreach ($Element['attributes'] as $name => $value)
{
if ($value === null)
{
continue;
}
$markup .= ' '.$name.'="'.$value.'"';
}
}
if (isset($Element['text']))
{
$markup .= '>';
if (isset($Element['handler']))
{
$markup .= $this->$Element['handler']($Element['text']);
}
else
{
$markup .= $Element['text'];
}
$markup .= '</'.$Element['name'].'>';
}
else
{
$markup .= ' />';
}
return $markup;
}
protected function elements(array $Elements)
{
$markup = '';
foreach ($Elements as $Element)
{
$markup .= "\n" . $this->element($Element);
}
$markup .= "\n";
return $markup;
}
#
# Inline Elements
#
protected $InlineTypes = array(
'"' => array('QuotationMark'),
'"' => array('SpecialCharacter'),
'!' => array('Image'),
'&' => array('Ampersand'),
'&' => array('SpecialCharacter'),
'*' => array('Emphasis'),
'<' => array('UrlTag', 'EmailTag', 'Tag', 'LessThan'),
'>' => array('GreaterThan'),
':' => array('Url'),
'<' => array('UrlTag', 'EmailTag', 'Markup', 'SpecialCharacter'),
'>' => array('SpecialCharacter'),
'[' => array('Link'),
'_' => array('Emphasis'),
'`' => array('Code'),
@@ -1034,7 +977,7 @@ class Parsedown
# ~
protected $inlineMarkerList = '!"*_&[<>`~\\';
protected $inlineMarkerList = '!"*_&[:<>`~\\';
#
# ~
@@ -1044,43 +987,53 @@ class Parsedown
{
$markup = '';
$remainder = $text;
$unexaminedText = $text;
$markerPosition = 0;
while ($excerpt = strpbrk($remainder, $this->inlineMarkerList))
while ($excerpt = strpbrk($unexaminedText, $this->inlineMarkerList))
{
$marker = $excerpt[0];
$markerPosition += strpos($remainder, $marker);
$markerPosition += strpos($unexaminedText, $marker);
$Excerpt = array('text' => $excerpt, 'context' => $text);
foreach ($this->InlineTypes[$marker] as $inlineType)
{
$handler = 'inline'.$inlineType;
$Inline = $this->$handler($excerpt);
$Inline = $this->{'inline'.$inlineType}($Excerpt);
if ( ! isset($Inline))
{
continue;
}
$plainText = substr($text, 0, $markerPosition);
if (isset($Inline['position']) and $Inline['position'] > $markerPosition) # position is ahead of marker
{
continue;
}
$markup .= $this->unmarkedText($plainText);
if ( ! isset($Inline['position']))
{
$Inline['position'] = $markerPosition;
}
$unmarkedText = substr($text, 0, $Inline['position']);
$markup .= $this->unmarkedText($unmarkedText);
$markup .= isset($Inline['markup']) ? $Inline['markup'] : $this->element($Inline['element']);
$text = substr($text, $markerPosition + $Inline['extent']);
$text = substr($text, $Inline['position'] + $Inline['extent']);
$remainder = $text;
$unexaminedText = $text;
$markerPosition = 0;
continue 2;
}
$remainder = substr($excerpt, 1);
$unexaminedText = substr($excerpt, 1);
$markerPosition ++;
}
@@ -1094,94 +1047,29 @@ class Parsedown
# ~
#
protected function inlineAmpersand($excerpt)
protected function inlineCode($Excerpt)
{
if ( ! preg_match('/^&#?\w+;/', $excerpt))
{
return array(
'markup' => '&amp;',
'extent' => 1,
);
}
}
$marker = $Excerpt['text'][0];
protected function inlineStrikethrough($excerpt)
{
if ( ! isset($excerpt[1]))
if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $Excerpt['text'], $matches))
{
return;
}
$text = $matches[2];
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
$text = preg_replace("/[ ]*\n/", ' ', $text);
if ($excerpt[1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $excerpt, $matches))
{
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => 'del',
'text' => $matches[1],
'handler' => 'line',
'name' => 'code',
'text' => $text,
),
);
}
}
protected function inlineEscapeSequence($excerpt)
protected function inlineEmailTag($Excerpt)
{
if (isset($excerpt[1]) and in_array($excerpt[1], $this->specialCharacters))
{
return array(
'markup' => $excerpt[1],
'extent' => 2,
);
}
}
protected function inlineLessThan()
{
return array(
'markup' => '&lt;',
'extent' => 1,
);
}
protected function inlineGreaterThan()
{
return array(
'markup' => '&gt;',
'extent' => 1,
);
}
protected function inlineQuotationMark()
{
return array(
'markup' => '&quot;',
'extent' => 1,
);
}
protected function inlineUrlTag($excerpt)
{
if (strpos($excerpt, '>') !== false and preg_match('/^<(https?:[\/]{2}[^\s]+?)>/i', $excerpt, $matches))
{
$url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]);
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => 'a',
'text' => $url,
'attributes' => array(
'href' => $url,
),
),
);
}
}
protected function inlineEmailTag($excerpt)
{
if (strpos($excerpt, '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $excerpt, $matches))
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<((mailto:)?\S+?@\S+?)>/i', $Excerpt['text'], $matches))
{
$url = $matches[1];
@@ -1203,77 +1091,84 @@ class Parsedown
}
}
protected function inlineTag($excerpt)
protected function inlineEmphasis($Excerpt)
{
if ($this->markupEscaped)
if ( ! isset($Excerpt['text'][1]))
{
return;
}
if (strpos($excerpt, '>') !== false and preg_match('/^<\/?\w.*?>/s', $excerpt, $matches))
$marker = $Excerpt['text'][0];
if ($Excerpt['text'][1] === $marker and preg_match($this->StrongRegex[$marker], $Excerpt['text'], $matches))
{
return array(
'markup' => $matches[0],
'extent' => strlen($matches[0]),
);
$emphasis = 'strong';
}
}
protected function inlineCode($excerpt)
{
$marker = $excerpt[0];
if (preg_match('/^('.$marker.'+)[ ]*(.+?)[ ]*(?<!'.$marker.')\1(?!'.$marker.')/s', $excerpt, $matches))
elseif (preg_match($this->EmRegex[$marker], $Excerpt['text'], $matches))
{
$text = $matches[2];
$text = htmlspecialchars($text, ENT_NOQUOTES, 'UTF-8');
$text = preg_replace("/[ ]*\n/", ' ', $text);
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => 'code',
'text' => $text,
),
);
$emphasis = 'em';
}
}
protected function inlineImage($excerpt)
{
if ( ! isset($excerpt[1]) or $excerpt[1] !== '[')
else
{
return;
}
$excerpt = substr($excerpt, 1);
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => $emphasis,
'handler' => 'line',
'text' => $matches[1],
),
);
}
$InlineLink = $this->inlineLink($excerpt);
protected function inlineEscapeSequence($Excerpt)
{
if (isset($Excerpt['text'][1]) and in_array($Excerpt['text'][1], $this->specialCharacters))
{
return array(
'markup' => $Excerpt['text'][1],
'extent' => 2,
);
}
}
if ($InlineLink === null)
protected function inlineImage($Excerpt)
{
if ( ! isset($Excerpt['text'][1]) or $Excerpt['text'][1] !== '[')
{
return;
}
$Excerpt['text']= substr($Excerpt['text'], 1);
$Link = $this->inlineLink($Excerpt);
if ($Link === null)
{
return;
}
$Inline = array(
'extent' => $InlineLink['extent'] + 1,
'extent' => $Link['extent'] + 1,
'element' => array(
'name' => 'img',
'attributes' => array(
'src' => $InlineLink['element']['attributes']['href'],
'alt' => $InlineLink['element']['text'],
'src' => $Link['element']['attributes']['href'],
'alt' => $Link['element']['text'],
),
),
);
$Inline['element']['attributes'] += $InlineLink['element']['attributes'];
$Inline['element']['attributes'] += $Link['element']['attributes'];
unset($Inline['element']['attributes']['href']);
return $Inline;
}
protected function inlineLink($excerpt)
protected function inlineLink($Excerpt)
{
$Element = array(
'name' => 'a',
@@ -1287,7 +1182,7 @@ class Parsedown
$extent = 0;
$remainder = $excerpt;
$remainder = $Excerpt['text'];
if (preg_match('/\[((?:[^][]|(?R))*)\]/', $remainder, $matches))
{
@@ -1302,7 +1197,7 @@ class Parsedown
return;
}
if (preg_match('/^[(]((?:[^ (]|[(][^ )]+[)])+)(?:[ ]+("[^"]+"|\'[^\']+\'))?[)]/', $remainder, $matches))
if (preg_match('/^[(]((?:[^ ()]|[(][^ )]+[)])+)(?:[ ]+("[^"]*"|\'[^\']*\'))?[)]/', $remainder, $matches))
{
$Element['attributes']['href'] = $matches[1];
@@ -1346,59 +1241,126 @@ class Parsedown
);
}
protected function inlineEmphasis($excerpt)
protected function inlineMarkup($Excerpt)
{
if ( ! isset($excerpt[1]))
if ($this->markupEscaped or strpos($Excerpt['text'], '>') === false)
{
return;
}
$marker = $excerpt[0];
if ($excerpt[1] === $marker and preg_match($this->StrongRegex[$marker], $excerpt, $matches))
if ($Excerpt['text'][1] === '/' and preg_match('/^<\/\w*[ ]*>/s', $Excerpt['text'], $matches))
{
$emphasis = 'strong';
}
elseif (preg_match($this->EmRegex[$marker], $excerpt, $matches))
{
$emphasis = 'em';
}
else
{
return;
return array(
'markup' => $matches[0],
'extent' => strlen($matches[0]),
);
}
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => $emphasis,
'handler' => 'line',
'text' => $matches[1],
),
);
if ($Excerpt['text'][1] === '!' and preg_match('/^<!---?[^>-](?:-?[^-])*-->/s', $Excerpt['text'], $matches))
{
return array(
'markup' => $matches[0],
'extent' => strlen($matches[0]),
);
}
if ($Excerpt['text'][1] !== ' ' and preg_match('/^<\w*(?:[ ]*'.$this->regexHtmlAttribute.')*[ ]*\/?>/s', $Excerpt['text'], $matches))
{
return array(
'markup' => $matches[0],
'extent' => strlen($matches[0]),
);
}
}
#
# ~
protected function inlineSpecialCharacter($Excerpt)
{
if ($Excerpt['text'][0] === '&' and ! preg_match('/^&#?\w+;/', $Excerpt['text']))
{
return array(
'markup' => '&amp;',
'extent' => 1,
);
}
protected $unmarkedInlineTypes = array("\n" => 'Break', '://' => 'Url');
$SpecialCharacter = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
if (isset($SpecialCharacter[$Excerpt['text'][0]]))
{
return array(
'markup' => '&'.$SpecialCharacter[$Excerpt['text'][0]].';',
'extent' => 1,
);
}
}
protected function inlineStrikethrough($Excerpt)
{
if ( ! isset($Excerpt['text'][1]))
{
return;
}
if ($Excerpt['text'][1] === '~' and preg_match('/^~~(?=\S)(.+?)(?<=\S)~~/', $Excerpt['text'], $matches))
{
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => 'del',
'text' => $matches[1],
'handler' => 'line',
),
);
}
}
protected function inlineUrl($Excerpt)
{
if ($this->urlsLinked !== true or ! isset($Excerpt['text'][2]) or $Excerpt['text'][2] !== '/')
{
return;
}
if (preg_match('/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui', $Excerpt['context'], $matches, PREG_OFFSET_CAPTURE))
{
$Inline = array(
'extent' => strlen($matches[0][0]),
'position' => $matches[0][1],
'element' => array(
'name' => 'a',
'text' => $matches[0][0],
'attributes' => array(
'href' => $matches[0][0],
),
),
);
return $Inline;
}
}
protected function inlineUrlTag($Excerpt)
{
if (strpos($Excerpt['text'], '>') !== false and preg_match('/^<(\w+:\/{2}[^ >]+)>/i', $Excerpt['text'], $matches))
{
$url = str_replace(array('&', '<'), array('&amp;', '&lt;'), $matches[1]);
return array(
'extent' => strlen($matches[0]),
'element' => array(
'name' => 'a',
'text' => $url,
'attributes' => array(
'href' => $url,
),
),
);
}
}
# ~
protected function unmarkedText($text)
{
foreach ($this->unmarkedInlineTypes as $snippet => $inlineType)
{
if (strpos($text, $snippet) !== false)
{
$text = $this->{'unmarkedInline'.$inlineType}($text);
}
}
return $text;
}
protected function unmarkedInlineBreak($text)
{
if ($this->breaksEnabled)
{
@@ -1413,38 +1375,65 @@ class Parsedown
return $text;
}
protected function unmarkedInlineUrl($text)
#
# Handlers
#
protected function element(array $Element)
{
if ($this->urlsLinked !== true)
$markup = '<'.$Element['name'];
if (isset($Element['attributes']))
{
return $text;
foreach ($Element['attributes'] as $name => $value)
{
if ($value === null)
{
continue;
}
$markup .= ' '.$name.'="'.$value.'"';
}
}
$re = '/\bhttps?:[\/]{2}[^\s<]+\b\/*/ui';
$offset = 0;
while (strpos($text, '://', $offset) and preg_match($re, $text, $matches, PREG_OFFSET_CAPTURE, $offset))
if (isset($Element['text']))
{
$url = $matches[0][0];
$markup .= '>';
$urlLength = strlen($url);
$urlPosition = $matches[0][1];
if (isset($Element['handler']))
{
$markup .= $this->{$Element['handler']}($Element['text']);
}
else
{
$markup .= $Element['text'];
}
$markup = '<a href="'.$url.'">'.$url.'</a>';
$markupLength = strlen($markup);
$text = substr_replace($text, $markup, $urlPosition, $urlLength);
$offset = $urlPosition + $markupLength;
$markup .= '</'.$Element['name'].'>';
}
else
{
$markup .= ' />';
}
return $text;
return $markup;
}
protected function elements(array $Elements)
{
$markup = '';
foreach ($Elements as $Element)
{
$markup .= "\n" . $this->element($Element);
}
$markup .= "\n";
return $markup;
}
#
# ~
#
protected function li($lines)
{
@@ -1466,7 +1455,18 @@ class Parsedown
}
#
# Multiton
# Deprecated Methods
#
function parse($text)
{
$markup = $this->text($text);
return $markup;
}
#
# Static Methods
#
static function instance($name = 'default')
@@ -1485,22 +1485,6 @@ class Parsedown
private static $instances = array();
#
# Deprecated Methods
#
/**
* @deprecated in favor of "text"
* @param $text
* @return string
*/
function parse($text)
{
$markup = $this->text($text);
return $markup;
}
#
# Fields
#
@@ -1508,10 +1492,10 @@ class Parsedown
protected $DefinitionData;
#
# Read-only
# Read-Only
protected $specialCharacters = array(
'\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!',
'\\', '`', '*', '_', '{', '}', '[', ']', '(', ')', '>', '#', '+', '-', '.', '!', '|',
);
protected $StrongRegex = array(

View File

@@ -1,18 +1,20 @@
## Parsedown
[![Build Status](https://img.shields.io/travis/erusev/parsedown/master.svg?style=flat-square)](https://travis-ci.org/erusev/parsedown)
<!--[![Total Downloads](http://img.shields.io/packagist/dt/erusev/parsedown.svg?style=flat-square)](https://packagist.org/packages/erusev/parsedown)-->
Better Markdown Parser in PHP
[[ demo ]](http://parsedown.org/demo)
[See Demo](http://parsedown.org/demo)
### Features
* [Fast](http://parsedown.org/speed)
* [Consistent](http://parsedown.org/consistency)
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* [Tested](http://parsedown.org/tests/) in PHP 5.2, 5.3, 5.4, 5.5, 5.6 and [hhvm](http://www.hhvm.com/)
* Extensible
* [Tested](http://parsedown.org/tests/) in PHP 5.3, 5.4, 5.5, 5.6 and [HHVM](http://www.hhvm.com/)
* [Extensible](https://github.com/erusev/parsedown/wiki/Writing-Extensions)
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
* [JavaScript port](https://github.com/hkdobrev/parsedown.js) under development
### Installation
@@ -36,14 +38,14 @@ It tries to read Markdown like a human. First, it looks at the lines. Its int
We call this approach "line based". We believe that Parsedown is the first Markdown parser to use it. Since the release of Parsedown, other developers have used the same approach to develop other Markdown parsers in PHP and in other languages.
**Is Parsedown compliant with CommonMark?**
**Is it compliant with CommonMark?**
The majority of the CommonMark tests pass. Most of the tests that don't pass deal with cases that are quite extreme. Yet, we are working on them. As CommonMark matures, compliance should improve.
It passes most of the CommonMark tests. Most of the tests that don't pass deal with cases that are quite uncommon. Still, as CommonMark matures, compliance should improve.
**Who uses Parsedown?**
**Who uses it?**
[phpDocumentor](http://www.phpdoc.org/), [October CMS](http://octobercms.com/), [Bolt CMS](http://bolt.cm/), [Kirby CMS](http://getkirby.com/), [Grav CMS](http://getgrav.org/), [Statamic CMS](http://www.statamic.com/), [RaspberryPi.org](http://www.raspberrypi.org/) and [more](https://www.versioneye.com/php/erusev:parsedown/references).
**How can I help?**
Use the project, tell friends about it and if you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
Use it, star it, share it and if you feel generous, [donate some money](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).

View File

@@ -1,21 +1,21 @@
<table>
<thead>
<tr>
<th align="left">header 1</th>
<th align="center">header 2</th>
<th align="right">header 2</th>
<th style="text-align: left;">header 1</th>
<th style="text-align: center;">header 2</th>
<th style="text-align: right;">header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">cell 1.1</td>
<td align="center">cell 1.2</td>
<td align="right">cell 1.3</td>
<td style="text-align: left;">cell 1.1</td>
<td style="text-align: center;">cell 1.2</td>
<td style="text-align: right;">cell 1.3</td>
</tr>
<tr>
<td align="left">cell 2.1</td>
<td align="center">cell 2.2</td>
<td align="right">cell 2.3</td>
<td style="text-align: left;">cell 2.1</td>
<td style="text-align: center;">cell 2.2</td>
<td style="text-align: right;">cell 2.3</td>
</tr>
</tbody>
</table>

View File

@@ -1,13 +1,12 @@
<div>_content_</div>
<p>sparse:</p>
<div>
<div class="inner">
_content_
</div>
</div>
<p>paragraph</p>
<div>
<div class="inner">
_content_
</div>
</div>
<style type="text/css">
p {
color: red;
}
</style>
p {color: #789;}
</style>
<div>
<a href="/">home</a></div>

View File

@@ -1,17 +1,16 @@
<div>_content_</div>
sparse:
<div>
<div class="inner">
_content_
</div>
</div>
paragraph
<div>
<div class="inner">
_content_
</div>
</div>
<style type="text/css">
p {
color: red;
}
p {color: #789;}
</style>
<div>
<a href="/">home</a></div>

View File

@@ -1 +1,2 @@
<p><img src="/md.png" alt="alt" title="title" /></p>
<p><img src="/md.png" alt="alt" title="title" /></p>
<p><img src="/md.png" alt="blank title" title="" /></p>

View File

@@ -1 +1,3 @@
![alt](/md.png "title")
![alt](/md.png "title")
![blank title](/md.png "")

View File

@@ -1,4 +1,6 @@
<p><a href="http://example.com">link</a> and <a href="/url-with-(parentheses)">another link</a></p>
<p><a href="http://example.com">link</a></p>
<p><a href="/url-(parentheses)">link</a> with parentheses in URL </p>
<p>(<a href="/index.php">link</a>) in parentheses</p>
<p><a href="http://example.com"><code>link</code></a></p>
<p><a href="http://example.com"><img src="http://parsedown.org/md.png" alt="MD Logo" /></a></p>
<p><a href="http://example.com"><img src="http://parsedown.org/md.png" alt="MD Logo" /> and text</a></p>

View File

@@ -1,4 +1,8 @@
[link](http://example.com) and [another link](/url-with-(parentheses))
[link](http://example.com)
[link](/url-(parentheses)) with parentheses in URL
([link](/index.php)) in parentheses
[`link`](http://example.com)

View File

@@ -1,4 +1,6 @@
<p><a href="http://example.com" title="Title">single quotes</a></p>
<p><a href="http://example.com" title="Title">double quotes</a></p>
<p><a href="http://example.com" title="">single quotes blank</a></p>
<p><a href="http://example.com" title="">double quotes blank</a></p>
<p><a href="http://example.com" title="2 Words">space</a></p>
<p><a href="http://example.com/url-(parentheses)" title="Title">parentheses</a></p>

View File

@@ -2,6 +2,10 @@
[double quotes](http://example.com "Title")
[single quotes blank](http://example.com '')
[double quotes blank](http://example.com "")
[space](http://example.com "2 Words")
[parentheses](http://example.com/url-(parentheses) "Title")

View File

@@ -20,17 +20,17 @@
<table>
<thead>
<tr>
<th align="left">header 1</th>
<th style="text-align: left;">header 1</th>
<th>header 2</th>
</tr>
</thead>
<tbody>
<tr>
<td align="left">cell 1.1</td>
<td style="text-align: left;">cell 1.1</td>
<td>cell 1.2</td>
</tr>
<tr>
<td align="left">cell 2.1</td>
<td style="text-align: left;">cell 2.1</td>
<td>cell 2.2</td>
</tr>
</tbody>

View File

@@ -11,8 +11,12 @@
<td><del>cell</del> 1.2</td>
</tr>
<tr>
<td><code>cell</code> 2.1</td>
<td>cell 2.2</td>
<td><code>|</code> 2.1</td>
<td>| 2.2</td>
</tr>
<tr>
<td><code>\|</code> 2.1</td>
<td><a href="/">link</a></td>
</tr>
</tbody>
</table>

View File

@@ -1,4 +1,5 @@
| _header_ 1 | header 2 |
| ------------ | ------------ |
| _cell_ 1.1 | ~~cell~~ 1.2 |
| `cell` 2.1 | cell 2.2 |
| `|` 2.1 | \| 2.2 |
| `\|` 2.1 | [link](/) |