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

Compare commits

..

5 Commits

Author SHA1 Message Date
6d89393817 New release due to mislabeled previous tag 2019-03-17 18:48:37 +00:00
d60bcdc469 Bump version 2019-03-17 17:19:46 +00:00
c390a9e406 Merge pull request #700 from aidantwoods/fix/spaces-in-class-names-1.7.x
[1.7.x] Fix spaces in class names
2019-03-17 17:14:45 +00:00
0f1e9da8f4 Fix test platforms 2019-03-17 17:05:15 +00:00
bc003952fc [1.7.x] Fix spaces in class names 2019-03-17 16:49:45 +00:00
48 changed files with 511 additions and 1260 deletions

1
.gitattributes vendored
View File

@ -1,6 +1,5 @@
# Ignore all tests for archive
/test export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
/phpunit.xml.dist export-ignore

2
.gitignore vendored
View File

@ -1,2 +0,0 @@
composer.lock
vendor/

View File

@ -1,25 +1,23 @@
language: php
dist: trusty
sudo: false
matrix:
include:
- php: 5.3
dist: precise
- php: 5.4
dist: trusty
- php: 5.5
dist: trusty
- php: 5.6
dist: xenial
- php: 7.0
dist: xenial
- php: 7.1
dist: bionic
- php: 7.2
dist: bionic
- php: 7.3
dist: bionic
- php: 7.4
dist: bionic
- php: nightly
fast_finish: true
allow_failures:
- php: nightly
install:
- composer install --prefer-dist --no-interaction --no-progress

File diff suppressed because it is too large Load Diff

View File

@ -1,61 +1,49 @@
<!-- ![Parsedown](https://i.imgur.com/yE8afYV.png) -->
> I also make [Caret](https://caret.io?ref=parsedown) - a Markdown editor for Mac and PC.
<p align="center"><img alt="Parsedown" src="https://i.imgur.com/fKVY6Kz.png" width="240" /></p>
## Parsedown
<h1>Parsedown</h1>
[![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)-->
[![Build Status](https://travis-ci.org/erusev/parsedown.svg)](https://travis-ci.org/erusev/parsedown)
[![Total Downloads](https://poser.pugx.org/erusev/parsedown/d/total.svg)](https://packagist.org/packages/erusev/parsedown)
[![Version](https://poser.pugx.org/erusev/parsedown/v/stable.svg)](https://packagist.org/packages/erusev/parsedown)
[![License](https://poser.pugx.org/erusev/parsedown/license.svg)](https://packagist.org/packages/erusev/parsedown)
Better Markdown Parser in PHP
Better Markdown Parser in PHP - <a href="http://parsedown.org/demo">Demo</a>.
[Demo](http://parsedown.org/demo) |
[Benchmarks](http://parsedown.org/speed) |
[Tests](http://parsedown.org/tests/) |
[Documentation](https://github.com/erusev/parsedown/wiki/)
## Features
### Features
* One File
* No Dependencies
* [Super Fast](http://parsedown.org/speed)
* Super Fast
* Extensible
* [GitHub flavored](https://github.github.com/gfm)
* [Tested](http://parsedown.org/tests/) in 5.3 to 7.3
* [GitHub flavored](https://help.github.com/articles/github-flavored-markdown)
* Tested in 5.3 to 7.1 and in HHVM
* [Markdown Extra extension](https://github.com/erusev/parsedown-extra)
## Installation
### Installation
Install the [composer package]:
Include `Parsedown.php` or install [the composer package](https://packagist.org/packages/erusev/parsedown).
composer require erusev/parsedown
### Example
Or download the [latest release] and include `Parsedown.php`
[composer package]: https://packagist.org/packages/erusev/parsedown "The Parsedown package on packagist.org"
[latest release]: https://github.com/erusev/parsedown/releases/latest "The latest release of Parsedown"
## Example
```php
``` php
$Parsedown = new Parsedown();
echo $Parsedown->text('Hello _Parsedown_!'); # prints: <p>Hello <em>Parsedown</em>!</p>
```
You can also parse inline markdown only:
```php
echo $Parsedown->line('Hello _Parsedown_!'); # prints: Hello <em>Parsedown</em>!
```
More examples in [the wiki](https://github.com/erusev/parsedown/wiki/) and in [this video tutorial](http://youtu.be/wYZBY8DEikI).
## Security
### Security
Parsedown is capable of escaping user-input within the HTML that it generates. Additionally Parsedown will apply sanitisation to additional scripting vectors (such as scripting link destinations) that are introduced by the markdown syntax itself.
To tell Parsedown that it is processing untrusted user-input, use the following:
```php
$Parsedown->setSafeMode(true);
$parsedown = new Parsedown;
$parsedown->setSafeMode(true);
```
If instead, you wish to allow HTML within untrusted user-input, but still want output to be free from XSS it is recommended that you make use of a HTML sanitiser that allows HTML tags to be whitelisted, like [HTML Purifier](http://htmlpurifier.org/).
@ -66,19 +54,18 @@ In both cases you should strongly consider employing defence-in-depth measures,
Safe mode does not necessarily yield safe results when using extensions to Parsedown. Extensions should be evaluated on their own to determine their specific safety against XSS.
## Escaping HTML
> **WARNING:** This method isn't safe from XSS!
### Escaping HTML
> ⚠️  **WARNING:** This method isn't safe from XSS!
If you wish to escape HTML **in trusted input**, you can use the following:
```php
$Parsedown->setMarkupEscaped(true);
$parsedown = new Parsedown;
$parsedown->setMarkupEscaped(true);
```
Beware that this still allows users to insert unsafe scripting vectors, such as links like `[xss](javascript:alert%281%29)`.
## Questions
### Questions
**How does Parsedown work?**
@ -92,12 +79,8 @@ It passes most of the CommonMark tests. Most of the tests that don't pass deal w
**Who uses it?**
[Laravel Framework](https://laravel.com/), [Bolt CMS](http://bolt.cm/), [Grav CMS](http://getgrav.org/), [Herbie CMS](http://www.getherbie.org/), [Kirby CMS](http://getkirby.com/), [October CMS](http://octobercms.com/), [Pico CMS](http://picocms.org), [Statamic CMS](http://www.statamic.com/), [phpDocumentor](http://www.phpdoc.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony Demo](https://github.com/symfony/demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents).
[Laravel Framework](https://laravel.com/), [Bolt CMS](http://bolt.cm/), [Grav CMS](http://getgrav.org/), [Herbie CMS](http://www.getherbie.org/), [Kirby CMS](http://getkirby.com/), [October CMS](http://octobercms.com/), [Pico CMS](http://picocms.org), [Statamic CMS](http://www.statamic.com/), [phpDocumentor](http://www.phpdoc.org/), [RaspberryPi.org](http://www.raspberrypi.org/), [Symfony demo](https://github.com/symfony/symfony-demo) and [more](https://packagist.org/packages/erusev/parsedown/dependents).
**How can I help?**
Use it, star it, share it and if you feel generous, [donate](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=528P3NZQMP8N2).
**What else should I know?**
I also make [Nota](https://nota.md/) — a writing app designed for Markdown files :)

43
test/ParsedownTest.php Executable file → Normal file
View File

@ -1,5 +1,4 @@
<?php
require 'SampleExtensions.php';
use PHPUnit\Framework\TestCase;
@ -13,8 +12,7 @@ class ParsedownTest extends TestCase
parent::__construct($name, $data, $dataName);
}
private $dirs;
protected $Parsedown;
private $dirs, $Parsedown;
/**
* @return array
@ -51,47 +49,12 @@ class ParsedownTest extends TestCase
$expectedMarkup = str_replace("\r", "\n", $expectedMarkup);
$this->Parsedown->setSafeMode(substr($test, 0, 3) === 'xss');
$this->Parsedown->setStrictMode(substr($test, 0, 6) === 'strict');
$actualMarkup = $this->Parsedown->text($markdown);
$this->assertEquals($expectedMarkup, $actualMarkup);
}
function testRawHtml()
{
$markdown = "```php\nfoobar\n```";
$expectedMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
$expectedSafeMarkup = '<pre><code class="language-php">&lt;p&gt;foobar&lt;/p&gt;</code></pre>';
$unsafeExtension = new UnsafeExtension;
$actualMarkup = $unsafeExtension->text($markdown);
$this->assertEquals($expectedMarkup, $actualMarkup);
$unsafeExtension->setSafeMode(true);
$actualSafeMarkup = $unsafeExtension->text($markdown);
$this->assertEquals($expectedSafeMarkup, $actualSafeMarkup);
}
function testTrustDelegatedRawHtml()
{
$markdown = "```php\nfoobar\n```";
$expectedMarkup = '<pre><code class="language-php"><p>foobar</p></code></pre>';
$expectedSafeMarkup = $expectedMarkup;
$unsafeExtension = new TrustDelegatedExtension;
$actualMarkup = $unsafeExtension->text($markdown);
$this->assertEquals($expectedMarkup, $actualMarkup);
$unsafeExtension->setSafeMode(true);
$actualSafeMarkup = $unsafeExtension->text($markdown);
$this->assertEquals($expectedSafeMarkup, $actualSafeMarkup);
}
function data()
{
$data = array();
@ -160,12 +123,12 @@ MARKDOWN_WITH_MARKUP;
<p>&lt;div&gt;<em>content</em>&lt;/div&gt;</p>
<p>sparse:</p>
<p>&lt;div&gt;
&lt;div class="inner"&gt;
&lt;div class=&quot;inner&quot;&gt;
<em>content</em>
&lt;/div&gt;
&lt;/div&gt;</p>
<p>paragraph</p>
<p>&lt;style type="text/css"&gt;
<p>&lt;style type=&quot;text/css&quot;&gt;
p {
color: red;
}

View File

@ -1,40 +0,0 @@
<?php
class UnsafeExtension extends Parsedown
{
protected function blockFencedCodeComplete($Block)
{
$text = $Block['element']['element']['text'];
unset($Block['element']['element']['text']);
// WARNING: There is almost always a better way of doing things!
//
// This example is one of them, unsafe behaviour is NOT needed here.
// Only use this if you trust the input and have no idea what
// the output HTML will look like (e.g. using an external parser).
$Block['element']['element']['rawHtml'] = "<p>$text</p>";
return $Block;
}
}
class TrustDelegatedExtension extends Parsedown
{
protected function blockFencedCodeComplete($Block)
{
$text = $Block['element']['element']['text'];
unset($Block['element']['element']['text']);
// WARNING: There is almost always a better way of doing things!
//
// This behaviour is NOT needed in the demonstrated case.
// Only use this if you are sure that the result being added into
// rawHtml is safe.
// (e.g. using an external parser with escaping capabilities).
$Block['element']['element']['rawHtml'] = "<p>$text</p>";
$Block['element']['element']['allowRawHtmlInSafeMode'] = true;
return $Block;
}
}

View File

@ -6,8 +6,4 @@
<h6>h6</h6>
<p>####### not a heading</p>
<h1>closed h1</h1>
<h1></h1>
<h2></h2>
<h1># of levels</h1>
<h1># of levels #</h1>
<h1>heading</h1>
<p>#</p>

View File

@ -14,12 +14,4 @@
# closed h1 #
#
##
# # of levels
# # of levels # #
#heading
#

View File

@ -5,9 +5,4 @@ echo $message;</code></pre>
<hr />
<pre><code>&gt; not a quote
- not a list item
[not a reference]: http://foo.com</code></pre>
<hr />
<pre><code>foo
bar</code></pre>
[not a reference]: http://foo.com</code></pre>

View File

@ -7,11 +7,4 @@
> not a quote
- not a list item
[not a reference]: http://foo.com
---
foo
bar
[not a reference]: http://foo.com

View File

@ -1,40 +1,12 @@
<ul>
<li>li<ul>
<li>li<ul>
<li>li</li>
<li>li</li>
</ul>
</li>
<li>li</li>
</ul>
</li>
<li>li</li>
</ul>
<hr />
<li>li
<ul>
<li>level 1<ul>
<li>level 2<ul>
<li>level 3<ul>
<li>level 4<ul>
<li>level 5</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
</ul>
<hr />
<li>li
<ul>
<li>a</li>
<li>b</li>
<li>c</li>
<li>d</li>
<li>e</li>
<li>f</li>
<li>g</li>
<li>h</li>
<li>i</li>
<li>li</li>
<li>li</li>
</ul></li>
<li>li</li>
</ul></li>
<li>li</li>
</ul>

View File

@ -3,24 +3,4 @@
- li
- li
- li
- li
---
- level 1
- level 2
- level 3
- level 4
- level 5
---
- a
- b
- c
- d
- e
- f
- g
- h
- i
- li

View File

@ -1,2 +1 @@
<p>my email is <a href="mailto:me@example.com">me@example.com</a></p>
<p>html tags shouldn't start an email autolink <strong>first.last@example.com</strong></p>
<p>my email is <a href="mailto:me@example.com">me@example.com</a></p>

View File

@ -1,3 +1 @@
my email is <me@example.com>
html tags shouldn't start an email autolink <strong>first.last@example.com</strong>
my email is <me@example.com>

View File

@ -8,11 +8,4 @@ echo $message;</code></pre>
<pre><code class="language-html+php">&lt;?php
echo "Hello World";
?&gt;
&lt;a href="http://auraphp.com" &gt;Aura Project&lt;/a&gt;</code></pre>
<pre><code>the following isn't quite enough to close
```
still a fenced code block</code></pre>
<pre><code>foo
bar</code></pre>
&lt;a href="http://auraphp.com" &gt;Aura Project&lt;/a&gt;</code></pre>

View File

@ -22,17 +22,4 @@ echo 'language identifier with non words';
echo "Hello World";
?>
<a href="http://auraphp.com" >Aura Project</a>
```
````
the following isn't quite enough to close
```
still a fenced code block
````
```
foo
bar
```

View File

@ -2,10 +2,4 @@
<p>paragraph</p>
<!--
multiline -->
<p>paragraph</p>
<!-- sss -->abc
<ul>
<li>abcd</li>
<li>bbbb</li>
<li>cccc</li>
</ul>
<p>paragraph</p>

View File

@ -5,10 +5,4 @@ paragraph
<!--
multiline -->
paragraph
<!-- sss -->abc
* abcd
* bbbb
* cccc
paragraph

View File

@ -1,8 +1,6 @@
<blockquote>
<p>quote
the rest of it</p>
</blockquote>
<blockquote>
<p>another paragraph
the rest of it</p>
</blockquote>

View File

@ -1,3 +0,0 @@
<div>Markup</div>
_No markdown_ without blank line for **strict** compliance with CommonMark.
<p><strong>Markdown</strong></p>

View File

@ -1,4 +0,0 @@
<div>Markup</div>
_No markdown_ without blank line for **strict** compliance with CommonMark.
**Markdown**

View File

@ -1,4 +0,0 @@
<div>One markup on
two lines</div>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -1,5 +0,0 @@
<div>One markup on
two lines</div>
_No markdown_
**Markdown**

View File

@ -1,3 +0,0 @@
<div><p>Stripped markup</p></div>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -1,4 +0,0 @@
<div><p>Stripped markup</p></div>
_No markdown_
**Markdown**

View File

@ -1,3 +0,0 @@
<div>First markup</div><p>and second markup on the same line.</p>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -1,4 +0,0 @@
<div>First markup</div><p>and second markup on the same line.</p>
_No markdown_
**Markdown**

View File

@ -1,4 +0,0 @@
<div>First markup</div><p>and partial markup
on two lines.</p>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -1,5 +0,0 @@
<div>First markup</div><p>and partial markup
on two lines.</p>
_No markdown_
**Markdown**

View File

@ -1,4 +0,0 @@
<div><p>Stripped markup
on two lines</p></div>
_No markdown_
<p><strong>Markdown</strong></p>

View File

@ -1,5 +0,0 @@
<div><p>Stripped markup
on two lines</p></div>
_No markdown_
**Markdown**

View File

@ -10,7 +10,4 @@
<p>large numbers:</p>
<ol start="123">
<li>one</li>
</ol>
<p>foo 1. the following should not start a list
100.<br />
200. </p>
</ol>

View File

@ -8,8 +8,4 @@ repeating numbers:
large numbers:
123. one
foo 1. the following should not start a list
100.
200.
123. one

View File

@ -1,18 +1,12 @@
<hr>
paragraph
<hr/>
paragraph
<hr />
paragraph
<hr class="foo" id="bar" />
paragraph
<hr class="foo" id="bar"/>
paragraph
<hr class="foo" id="bar" >
paragraph

View File

@ -1,12 +0,0 @@
<h1>trailing space</h1>
<h2>trailing space</h2>
<h1>leading and trailing space</h1>
<h2>leading and trailing space</h2>
<h1>1 leading space</h1>
<h2>1 leading space</h2>
<h1>3 leading spaces</h1>
<h2>3 leading spaces</h2>
<p>too many leading spaces
==</p>
<p>too many leading spaces
--</p>

View File

@ -1,29 +0,0 @@
trailing space
==
trailing space
--
leading and trailing space
==
leading and trailing space
--
1 leading space
==
1 leading space
--
3 leading spaces
==
3 leading spaces
--
too many leading spaces
==
too many leading spaces
--

View File

@ -8,19 +8,4 @@
<p>no space after <code>&gt;</code>:</p>
<blockquote>
<p>quote</p>
</blockquote>
<hr />
<blockquote>
<blockquote>
<blockquote>
<p>Info 1 text</p>
</blockquote>
</blockquote>
</blockquote>
<blockquote>
<blockquote>
<blockquote>
<p>Info 2 text</p>
</blockquote>
</blockquote>
</blockquote>

View File

@ -4,10 +4,4 @@ indented:
> quote
no space after `>`:
>quote
---
>>> Info 1 text
>>> Info 2 text
>quote

View File

@ -34,42 +34,4 @@
<td>cell 2.2</td>
</tr>
</tbody>
</table>
<hr />
<table>
<thead>
<tr>
<th style="text-align: left;">header 1</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left;">cell 1.1</td>
</tr>
<tr>
<td style="text-align: left;">cell 2.1</td>
</tr>
</tbody>
</table>
<hr />
<table>
<thead>
<tr>
<th>header 1</th>
</tr>
</thead>
<tbody>
<tr>
<td>cell 1.1</td>
</tr>
<tr>
<td>cell 2.1</td>
</tr>
</tbody>
</table>
<hr />
<p>Not a table, we haven't ended the paragraph:
header 1 | header 2
-------- | --------
cell 1.1 | cell 1.2
cell 2.1 | cell 2.2</p>
</table>

View File

@ -8,26 +8,4 @@ cell 2.1 | cell 2.2
header 1 | header 2
:------- | --------
cell 1.1 | cell 1.2
cell 2.1 | cell 2.2
---
header 1
:-------
cell 1.1
cell 2.1
---
header 1
-------|
cell 1.1
cell 2.1
---
Not a table, we haven't ended the paragraph:
header 1 | header 2
-------- | --------
cell 1.1 | cell 1.2
cell 2.1 | cell 2.2

View File

@ -1,6 +1,8 @@
<div>
line 1
<p>line 2
line 3</p>
<p>line 4</p>
line 2
line 3
line 4
</div>

View File

@ -1,13 +0,0 @@
<h1>h1</h1>
<h2>h2</h2>
<h3>h3</h3>
<h4>h4</h4>
<h5>h5</h5>
<h6>h6</h6>
<p>####### not a heading</p>
<p>#not a heading</p>
<h1>closed h1</h1>
<h1></h1>
<h2></h2>
<h1># of levels</h1>
<h1># of levels #</h1>

View File

@ -1,25 +0,0 @@
# h1
## h2
### h3
#### h4
##### h5
###### h6
####### not a heading
#not a heading
# closed h1 #
#
##
# # of levels
# # of levels # #

View File

@ -1,4 +1,3 @@
<p><del>strikethrough</del></p>
<p>here's <del>one</del> followed by <del>another one</del></p>
<p>~~ this ~~ is not one neither is ~this~</p>
<p>escaped ~~this~~</p>
<p>~~ this ~~ is not one neither is ~this~</p>

View File

@ -2,6 +2,4 @@
here's ~~one~~ followed by ~~another one~~
~~ this ~~ is not one neither is ~this~
escaped \~\~this\~\~
~~ this ~~ is not one neither is ~this~

View File

@ -2,21 +2,9 @@
<li>li</li>
<li>li</li>
</ul>
<p>mixed unordered markers:</p>
<p>mixed markers:</p>
<ul>
<li>li</li>
</ul>
<ul>
<li>li</li>
</ul>
<ul>
<li>li</li>
</ul>
<p>mixed ordered markers:</p>
<ol>
<li>starting at 1, list one</li>
<li>number 2, list one</li>
</ol>
<ol start="3">
<li>starting at 3, list two</li>
</ol>
</ul>

View File

@ -1,14 +1,8 @@
- li
- li
mixed unordered markers:
mixed markers:
* li
+ li
- li
mixed ordered markers:
1. starting at 1, list one
2. number 2, list one
3) starting at 3, list two
- li