1 | <?php |
||
2 | /** |
||
3 | * @copyright Copyright (c) 2015 Nobuo Kihara |
||
4 | * @license https://github.com/softark/creole/blob/master/LICENSE |
||
5 | * @link https://github.com/softark/creole#readme |
||
6 | */ |
||
7 | |||
8 | namespace softark\creole; |
||
9 | |||
10 | /** |
||
11 | * Creole wiki parser for [Creole 1.0 spec](http://www.wikicreole.org/wiki/Creole1.0). |
||
12 | * |
||
13 | * @author Nobuo Kihara <[email protected]> |
||
14 | */ |
||
15 | class Creole extends \cebe\markdown\Parser |
||
16 | { |
||
17 | // include block element parsing using traits |
||
18 | use block\CodeTrait; |
||
19 | use block\HeadlineTrait; |
||
20 | use block\ListTrait; |
||
21 | use block\TableTrait; |
||
22 | use block\RuleTrait; |
||
23 | use block\RawHtmlTrait; |
||
24 | |||
25 | // include inline element parsing using traits |
||
26 | use inline\CodeTrait; |
||
27 | use inline\EmphStrongTrait; |
||
28 | use inline\LinkTrait; |
||
29 | |||
30 | /** |
||
31 | * @var boolean whether to format markup according to HTML5 spec. |
||
32 | * Defaults to `true` which means that markup is formatted as HTML5. |
||
33 | * If you want HTML4, set it to false. |
||
34 | */ |
||
35 | public $html5 = true; |
||
36 | |||
37 | /** |
||
38 | * Consume lines for a paragraph |
||
39 | * |
||
40 | * Allow block elements to break paragraphs |
||
41 | */ |
||
42 | 18 | protected function consumeParagraph($lines, $current) |
|
43 | { |
||
44 | // consume until newline |
||
45 | 18 | $content = []; |
|
46 | 18 | for ($i = $current, $count = count($lines); $i < $count; $i++) { |
|
47 | 18 | $line = $lines[$i]; |
|
48 | 18 | if ($this->isParagraphEnd($line)) { |
|
49 | 13 | break; |
|
50 | } |
||
51 | 18 | $content[] = $line; |
|
52 | } |
||
53 | $block = [ |
||
54 | 18 | 'paragraph', |
|
55 | 18 | 'content' => $this->parseInline(implode("\n", $content)), |
|
56 | ]; |
||
57 | 18 | return [$block, --$i]; |
|
58 | } |
||
59 | |||
60 | /** |
||
61 | * Checks if the paragraph ends |
||
62 | * @param $line |
||
63 | * @return bool true if end of paragraph |
||
64 | */ |
||
65 | 18 | protected function isParagraphEnd($line) |
|
66 | { |
||
67 | 18 | if (empty($line) || |
|
68 | 18 | ltrim($line) === '' || |
|
69 | 18 | $this->identifyHeadline($line) || |
|
70 | 18 | $this->identifyHr($line) || |
|
71 | 18 | $this->identifyUl($line) || |
|
72 | 18 | $this->identifyOl($line) || |
|
73 | 18 | $this->identifyTable($line) || |
|
74 | 18 | $this->identifyCode($line) || |
|
75 | 18 | $this->identifyRawHtml($line)) { |
|
76 | 13 | return true; |
|
77 | } |
||
78 | 18 | return false; |
|
79 | } |
||
80 | |||
81 | |||
82 | /** |
||
83 | * Parses escaped special characters. |
||
84 | * Creole uses tilde (~) for the escaping marker. |
||
85 | * It should escape the next character whatever it would be. |
||
86 | * @marker ~ |
||
87 | */ |
||
88 | 2 | protected function parseEscape($text) |
|
89 | { |
||
90 | 2 | if (isset($text[1])) { |
|
91 | 2 | return [['text', $text[1]], 2]; |
|
92 | } |
||
93 | 1 | return [['text', $text[0]], 1]; |
|
94 | } |
||
95 | |||
96 | /** |
||
97 | * @inheritdocs |
||
98 | * |
||
99 | * Parses a newline indicated by two backslashes, and |
||
100 | * escape '&', '<', and '>'. |
||
101 | */ |
||
102 | 22 | protected function renderText($text) |
|
103 | { |
||
104 | 22 | return str_replace( |
|
105 | 22 | ['&', '<', '>', "\\\\"], |
|
106 | 22 | ['&', '<', '>', $this->html5 ? "<br>" : "<br />"], |
|
107 | 22 | $text[1]); |
|
108 | } |
||
109 | } |
||
110 |