1 | <?php |
||
2 | /** |
||
3 | * @copyright Copyright (c) 2014 Carsten Brandt |
||
4 | * @license https://github.com/cebe/markdown/blob/master/LICENSE |
||
5 | * @link https://github.com/cebe/markdown#readme |
||
6 | */ |
||
7 | |||
8 | namespace cebe\markdown; |
||
9 | |||
10 | /** |
||
11 | * Markdown parser for the [initial markdown spec](http://daringfireball.net/projects/markdown/syntax). |
||
12 | * |
||
13 | * @author Carsten Brandt <[email protected]> |
||
14 | */ |
||
15 | class Markdown extends Parser |
||
16 | { |
||
17 | // include block element parsing using traits |
||
18 | use block\CodeTrait; |
||
19 | use block\HeadlineTrait; |
||
20 | use block\HtmlTrait { |
||
21 | parseInlineHtml as private; |
||
22 | } |
||
23 | use block\ListTrait { |
||
24 | // Check Ul List before headline |
||
25 | identifyUl as protected identifyBUl; |
||
26 | consumeUl as protected consumeBUl; |
||
27 | } |
||
28 | use block\QuoteTrait; |
||
29 | use block\RuleTrait { |
||
30 | // Check Hr before checking lists |
||
31 | identifyHr as protected identifyAHr; |
||
32 | consumeHr as protected consumeAHr; |
||
33 | } |
||
34 | |||
35 | // include inline element parsing using traits |
||
36 | use inline\CodeTrait; |
||
37 | use inline\EmphStrongTrait; |
||
38 | use inline\LinkTrait; |
||
39 | |||
40 | /** |
||
41 | * @var boolean whether to format markup according to HTML5 spec. |
||
42 | * Defaults to `false` which means that markup is formatted as HTML4. |
||
43 | */ |
||
44 | public $html5 = false; |
||
45 | |||
46 | /** |
||
47 | * @var array these are "escapeable" characters. When using one of these prefixed with a |
||
48 | * backslash, the character will be outputted without the backslash and is not interpreted |
||
49 | * as markdown. |
||
50 | */ |
||
51 | protected $escapeCharacters = [ |
||
52 | '\\', // backslash |
||
53 | '`', // backtick |
||
54 | '*', // asterisk |
||
55 | '_', // underscore |
||
56 | '{', '}', // curly braces |
||
57 | '[', ']', // square brackets |
||
58 | '(', ')', // parentheses |
||
59 | '#', // hash mark |
||
60 | '+', // plus sign |
||
61 | '-', // minus sign (hyphen) |
||
62 | '.', // dot |
||
63 | '!', // exclamation mark |
||
64 | '<', '>', |
||
65 | ]; |
||
66 | |||
67 | |||
68 | /** |
||
69 | * @inheritDoc |
||
70 | */ |
||
71 | 208 | protected function prepare() |
|
72 | { |
||
73 | // reset references |
||
74 | 208 | $this->references = []; |
|
75 | 208 | } |
|
76 | |||
77 | /** |
||
78 | * Consume lines for a paragraph |
||
79 | * |
||
80 | * Allow headlines and code to break paragraphs |
||
81 | */ |
||
82 | 130 | protected function consumeParagraph($lines, $current) |
|
83 | { |
||
84 | // consume until newline |
||
85 | 130 | $content = []; |
|
86 | 130 | for ($i = $current, $count = count($lines); $i < $count; $i++) { |
|
87 | 130 | $line = $lines[$i]; |
|
88 | |||
89 | // a list may break a paragraph when it is inside of a list |
||
90 | 130 | if (isset($this->context[1]) && $this->context[1] === 'list' && !ctype_alpha($line[0]) && ( |
|
91 | 130 | $this->identifyUl($line, $lines, $i) || $this->identifyOl($line, $lines, $i))) { |
|
92 | break; |
||
93 | } |
||
94 | |||
95 | 130 | if ($line === '' || ltrim($line) === '' || $this->identifyHeadline($line, $lines, $i)) { |
|
96 | 106 | break; |
|
97 | 130 | } elseif ($line[0] === "\t" || $line[0] === " " && strncmp($line, ' ', 4) === 0) { |
|
98 | // possible beginning of a code block |
||
99 | // but check for continued inline HTML |
||
100 | // e.g. <img src="file.jpg" |
||
101 | // alt="some alt aligned with src attribute" title="some text" /> |
||
102 | 4 | if (preg_match('~<\w+([^>]+)$~s', implode("\n", $content))) { |
|
103 | 2 | $content[] = $line; |
|
104 | } else { |
||
105 | 4 | break; |
|
106 | } |
||
107 | } else { |
||
108 | 130 | $content[] = $line; |
|
109 | } |
||
110 | } |
||
111 | $block = [ |
||
112 | 130 | 'paragraph', |
|
113 | 130 | 'content' => $this->parseInline(implode("\n", $content)), |
|
114 | ]; |
||
115 | 130 | return [$block, --$i]; |
|
116 | } |
||
117 | |||
118 | |||
119 | /** |
||
120 | * @inheritdocs |
||
121 | * |
||
122 | * Parses a newline indicated by two spaces on the end of a markdown line. |
||
123 | */ |
||
124 | 207 | protected function renderText($text) |
|
125 | { |
||
126 | 207 | return str_replace(" \n", $this->html5 ? "<br>\n" : "<br />\n", $text[1]); |
|
127 | } |
||
128 | } |
||
129 |