PluginProbe
DecaLog / 4.4.0
DecaLog v4.4.0
3.0.2 3.1.0 3.10.0 3.2.0 3.3.0 3.4.0 3.4.1 3.5.0 3.5.1 3.6.0 3.6.1 3.6.2 3.6.3 3.7.0 3.7.1 3.8.0 3.9.0 3.9.1 4.0.0 4.1.0 4.2.0 4.3.0 4.3.1 4.4.0 4.5.0 All 75 releases
decalog / includes / libraries / markdown / block / HtmlTrait.php

HtmlTrait.php in DecaLog 4.4.0, at includes/libraries/markdown/block/HtmlTrait.php

169 lines 3.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
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\markdownparser\block;
9
10 /**
11 * Adds inline and block HTML support
12 */
13 trait HtmlTrait
14 {
15 /**
16 * @var array HTML elements considered as inline elements.
17 * @see http://www.w3.org/wiki/HTML/Elements#Text-level_semantics
18 */
19 protected $inlineHtmlElements = [
20 'a', 'abbr', 'acronym',
21 'b', 'basefont', 'bdo', 'big', 'br', 'button', 'blink',
22 'cite', 'code',
23 'del', 'dfn',
24 'em',
25 'font',
26 'i', 'img', 'ins', 'input', 'iframe',
27 'kbd',
28 'label', 'listing',
29 'map', 'mark',
30 'nobr',
31 'object',
32 'q',
33 'rp', 'rt', 'ruby',
34 's', 'samp', 'script', 'select', 'small', 'spacer', 'span', 'strong', 'sub', 'sup',
35 'tt', 'var',
36 'u',
37 'wbr',
38 'time',
39 ];
40 /**
41 * @var array HTML elements known to be self-closing.
42 */
43 protected $selfClosingHtmlElements = [
44 'br', 'hr', 'img', 'input', 'nobr',
45 ];
46
47 /**
48 * identify a line as the beginning of a HTML block.
49 */
50 protected function identifyHtml($line, $lines, $current)
51 {
52 if ($line[0] !== '<' || isset($line[1]) && $line[1] == ' ') {
53 return false; // no html tag
54 }
55
56 if (strncmp($line, '<!--', 4) === 0) {
57 return true; // a html comment
58 }
59
60 $gtPos = strpos($lines[$current], '>');
61 $spacePos = strpos($lines[$current], ' ');
62 if ($gtPos === false && $spacePos === false) {
63 return false; // no html tag
64 } elseif ($spacePos === false) {
65 $tag = rtrim(substr($line, 1, $gtPos - 1), '/');
66 } else {
67 $tag = rtrim(substr($line, 1, min($gtPos, $spacePos) - 1), '/');
68 }
69
70 if (!ctype_alnum($tag) || in_array(strtolower($tag), $this->inlineHtmlElements)) {
71 return false; // no html tag or inline html tag
72 }
73 return true;
74 }
75
76 /**
77 * Consume lines for an HTML block
78 */
79 protected function consumeHtml($lines, $current)
80 {
81 $content = [];
82 if (strncmp($lines[$current], '<!--', 4) === 0) { // html comment
83 for ($i = $current, $count = count($lines); $i < $count; $i++) {
84 $line = $lines[$i];
85 $content[] = $line;
86 if (strpos($line, '-->') !== false) {
87 break;
88 }
89 }
90 } else {
91 $tag = rtrim(substr($lines[$current], 1, min(strpos($lines[$current], '>'), strpos($lines[$current] . ' ', ' ')) - 1), '/');
92 $level = 0;
93 if (in_array($tag, $this->selfClosingHtmlElements)) {
94 $level--;
95 }
96 for ($i = $current, $count = count($lines); $i < $count; $i++) {
97 $line = $lines[$i];
98 $content[] = $line;
99 $level += substr_count($line, "<$tag") - substr_count($line, "</$tag>") - substr_count($line, "/>");
100 if ($level <= 0) {
101 break;
102 }
103 }
104 }
105 $block = [
106 'html',
107 'content' => implode("\n", $content),
108 ];
109 return [$block, $i];
110 }
111
112 /**
113 * Renders an HTML block
114 */
115 protected function renderHtml($block)
116 {
117 return $block['content'] . "\n";
118 }
119
120 /**
121 * Parses an & or a html entity definition.
122 * @marker &
123 */
124 protected function parseEntity($text)
125 {
126 // html entities e.g. &copy; &#169; &#x00A9;
127 if (preg_match('/^&#?[\w\d]+;/', $text, $matches)) {
128 return [['inlineHtml', $matches[0]], strlen($matches[0])];
129 } else {
130 return [['text', '&amp;'], 1];
131 }
132 }
133
134 /**
135 * renders a html entity.
136 */
137 protected function renderInlineHtml($block)
138 {
139 return $block[1];
140 }
141
142 /**
143 * Parses inline HTML.
144 * @marker <
145 */
146 protected function parseInlineHtml($text)
147 {
148 if (strpos($text, '>') !== false) {
149 if (preg_match('~^</?(\w+\d?)( .*?)?>~s', $text, $matches)) {
150 // HTML tags
151 return [['inlineHtml', $matches[0]], strlen($matches[0])];
152 } elseif (preg_match('~^<!--.*?-->~s', $text, $matches)) {
153 // HTML comments
154 return [['inlineHtml', $matches[0]], strlen($matches[0])];
155 }
156 }
157 return [['text', '&lt;'], 1];
158 }
159
160 /**
161 * Escapes `>` characters.
162 * @marker >
163 */
164 protected function parseGt($text)
165 {
166 return [['text', '&gt;'], 1];
167 }
168 }
169