Skip to content

Commit f8fb8e9

Browse files
committed
Add rendering of bbcode tags
1 parent f1ec843 commit f8fb8e9

37 files changed

+513
-87
lines changed

BbCode/Helper.php

Lines changed: 0 additions & 69 deletions
This file was deleted.

BbCode/TagRenderer.php

Lines changed: 229 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,229 @@
1+
<?php
2+
3+
namespace Inforge\PostTOC\BbCode;
4+
5+
class TagRenderer
6+
{
7+
private static int $chNum = 0;
8+
private static int $secNum = 0;
9+
private static int $subsecNum = 0;
10+
private static int $subsubsecNum = 0;
11+
private static int $parNum = 0;
12+
13+
private static function getContent($tagChildren, $removeNewLines = true)
14+
{
15+
if (is_string($tagChildren))
16+
return $removeNewLines ?
17+
str_replace(["\r\n", "\n", "\r"], ' ',
18+
$tagChildren) : $tagChildren;
19+
$content = '';
20+
foreach ($tagChildren as $child)
21+
if (is_string($child))
22+
$content .= $removeNewLines ?
23+
str_replace(["\r\n", "\n", "\r"], ' ',
24+
$child) : $child;
25+
else if (is_array($child))
26+
$content .= self::getContent($child['children'],
27+
$removeNewLines);
28+
return $content;
29+
}
30+
31+
private static function getAnchorId($uniqueId, $tagChildren)
32+
{
33+
$text = self::getContent($tagChildren);
34+
$text = preg_replace('/[\s+]/', '-', $text);
35+
$text = preg_replace('/[^A-Za-z0-9\-]/', '', $text);
36+
$text = substr($text, 0, 30);
37+
return $uniqueId . '-' . $text;
38+
}
39+
40+
private static function getEntityId($entity)
41+
{
42+
if (!isset($entity)) {
43+
\XF::logError('Can not get post/resource id: $entity is not defined.');
44+
return 0;
45+
}
46+
if ($entity instanceof \XF\Entity\Post)
47+
return $entity->post_id;
48+
if (class_exists('\XFRM\Entity\ResourceUpdate')
49+
&& $entity instanceof \XFRM\Entity\ResourceUpdate)
50+
return $entity->resource_id;
51+
\XF::logError('Can not get post/resource id: unsupported entity type.');
52+
return 0;
53+
}
54+
55+
private static function getNumByDepth($depth, $override = -1)
56+
{
57+
// TODO: write better
58+
$nums = [];
59+
switch ($depth) {
60+
case 4:
61+
if ($override > -1)
62+
self::$parNum = $override;
63+
else
64+
self::$parNum++;
65+
$nums[] = self::$parNum;
66+
case 3:
67+
if ($depth == 3)
68+
if ($override > -1)
69+
self::$subsubsecNum = $override;
70+
else
71+
self::$subsubsecNum++;
72+
$nums[] = self::$subsubsecNum;
73+
case 2:
74+
if ($depth == 2)
75+
if ($override > -1)
76+
self::$subsecNum = $override;
77+
else
78+
self::$subsecNum++;
79+
$nums[] = self::$subsecNum;
80+
case 1:
81+
if ($depth == 1)
82+
if ($override > -1)
83+
self::$secNum = $override;
84+
else
85+
self::$secNum++;
86+
$nums[] = self::$secNum;
87+
case 0:
88+
if ($depth == 0)
89+
if ($override > -1)
90+
self::$chNum = $override;
91+
else
92+
self::$chNum++;
93+
$nums[] = self::$chNum;
94+
break;
95+
default:
96+
return '';
97+
}
98+
self::resetCounters($depth + 1);
99+
$nums = array_reverse($nums);
100+
$idxString = '';
101+
foreach ($nums as $num)
102+
$idxString .= ".$num";
103+
return ltrim($idxString, '.');
104+
105+
}
106+
107+
private static function renderTag($depth, $tagChildren, $tagOption, $entity)
108+
{
109+
$content = self::getContent($tagChildren);
110+
$depth = max($depth, 0);
111+
$depth = min($depth, 4);
112+
$options = self::buildOptions($tagOption, [
113+
'enumerate' => $depth < 3,
114+
'index' => $depth < 4,
115+
'overrideNum' => null,
116+
]);
117+
$tag = 'h' . ($depth + 2);
118+
$htmlClass = 'posttoc';
119+
if (!empty($options['index']))
120+
$htmlClass .= '-index';
121+
$num = '';
122+
if (!empty($options['enumerate']))
123+
$num .= self::getNumByDepth($depth, $options['overrideNum'] ?? -1);
124+
$uniqueId = self::getEntityId($entity) . '-' . str_replace('.', '-', $num);
125+
$anchorId = self::getAnchorId($uniqueId, $tagChildren);
126+
if (strlen($num) > 0)
127+
$num .= ' | ';
128+
return "<$tag class=\"$htmlClass\" id=\"$anchorId\">$num$content</$tag>";
129+
}
130+
131+
private static function buildOptions($tagOption, $options = [])
132+
{
133+
$strOptions = explode(',', trim($tagOption));
134+
foreach ($strOptions as $opt) {
135+
$opt = strtolower(trim($opt));
136+
if (strlen($opt) == 0)
137+
continue;
138+
if ($opt == 'num')
139+
$options['enumerate'] = true;
140+
else if ($opt == 'toc')
141+
$options['index'] = true;
142+
else if ($opt == 'nonum')
143+
$options['enumerate'] = false;
144+
else if ($opt == 'notoc')
145+
$options['index'] = false;
146+
else
147+
$options['overrideNum'] = filter_var($opt,
148+
FILTER_VALIDATE_INT, [
149+
'options' => [
150+
'min_range' => 0,
151+
],
152+
'flags' => FILTER_NULL_ON_FAILURE,
153+
]);
154+
}
155+
if (isset($options['overrideNum']))
156+
$options['enumerate'] = true;
157+
return $options;
158+
}
159+
160+
public static function renderChapterTag($tagChildren, $tagOption, $tag,
161+
array $options, \XF\BbCode\Renderer\AbstractRenderer $renderer)
162+
{
163+
return self::renderTag(0, $tagChildren, $tagOption,
164+
$options['entity']);
165+
}
166+
167+
public static function renderSectionTag($tagChildren, $tagOption, $tag,
168+
array $options, \XF\BbCode\Renderer\AbstractRenderer $renderer)
169+
{
170+
return self::renderTag(1, $tagChildren, $tagOption,
171+
$options['entity']);
172+
}
173+
174+
public static function renderSubsectionTag($tagChildren, $tagOption,
175+
$tag, array $options,
176+
\XF\BbCode\Renderer\AbstractRenderer $renderer)
177+
{
178+
return self::renderTag(2, $tagChildren, $tagOption,
179+
$options['entity']);
180+
}
181+
182+
public static function renderSubsubsectionTag($tagChildren, $tagOption,
183+
$tag, array $options,
184+
\XF\BbCode\Renderer\AbstractRenderer $renderer)
185+
{
186+
return self::renderTag(3, $tagChildren, $tagOption,
187+
$options['entity']);
188+
}
189+
190+
public static function renderParagraphTag($tagChildren, $tagOption, $tag,
191+
array $options, \XF\BbCode\Renderer\AbstractRenderer $renderer)
192+
{
193+
return self::renderTag(4, $tagChildren, $tagOption,
194+
$options['entity']);
195+
}
196+
197+
public static function renderTocTag($tagChildren, $tagOption, $tag,
198+
array $options, \XF\BbCode\Renderer\AbstractRenderer $renderer)
199+
{
200+
//$renderer->getTemplater()->includeJs([
201+
// 'src' => 'inforge/posttoc/toc-renderer.js',
202+
// 'addon' => 'Inforge/PostTOC',
203+
// 'min' => true,
204+
// ]);
205+
self::resetCounters();
206+
$hideTitle = !empty($tagOption) &&
207+
(strtolower(trim($tagOption)) == 'notitle');
208+
return $renderer->getTemplater()->renderTemplate(
209+
'public:if_toc_bb_code_tag_toc', [
210+
'showTitle' => !$hideTitle,
211+
]);
212+
}
213+
214+
private static function resetCounters($depth = 0)
215+
{
216+
switch ($depth) {
217+
case 0:
218+
self::$chNum = 0;
219+
case 1:
220+
self::$secNum = 0;
221+
case 2:
222+
self::$subsecNum = 0;
223+
case 3:
224+
self::$subsubsecNum = 0;
225+
case 4:
226+
self::$parNum = 0;
227+
}
228+
}
229+
}

Setup.php

Lines changed: 0 additions & 15 deletions
This file was deleted.

_files/js/inforge/posttoc/toc-renderer.js

Whitespace-only changes.

_output/bb_codes/_metadata.json

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
{
22
"chapter.json": {
3-
"hash": "7352f649ef5a0ac40764fa4304eeac72"
3+
"hash": "5c2ec57c2423499514d9c96296c0d3a0"
4+
},
5+
"paragraph.json": {
6+
"hash": "a4437679487267d2dd9da8a67622eef4"
7+
},
8+
"section.json": {
9+
"hash": "806032dc7b6d33fe9f69aaecb9bcd437"
10+
},
11+
"subsection.json": {
12+
"hash": "c655333b22283384eab3f650d9157641"
13+
},
14+
"subsubsection.json": {
15+
"hash": "3055cded7ae3c55aee7c4e22b4e78981"
16+
},
17+
"toc.json": {
18+
"hash": "5b1517c235663912f30644bb8b89f0f2"
419
}
520
}

_output/bb_codes/chapter.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,11 @@
44
"replace_html": "",
55
"replace_html_email": "",
66
"replace_text": "",
7-
"callback_class": "Inforge\\PostTOC\\BbCode\\Helper",
7+
"callback_class": "Inforge\\PostTOC\\BbCode\\TagRenderer",
88
"callback_method": "renderChapterTag",
99
"option_regex": "",
1010
"trim_lines_after": 0,
11-
"plain_children": false,
11+
"plain_children": true,
1212
"disable_smilies": false,
1313
"disable_nl2br": false,
1414
"disable_autolink": true,

_output/bb_codes/paragraph.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"bb_code_mode": "callback",
3+
"has_option": "optional",
4+
"replace_html": "",
5+
"replace_html_email": "",
6+
"replace_text": "",
7+
"callback_class": "Inforge\\PostTOC\\BbCode\\TagRenderer",
8+
"callback_method": "renderParagraphTag",
9+
"option_regex": "",
10+
"trim_lines_after": 0,
11+
"plain_children": true,
12+
"disable_smilies": false,
13+
"disable_nl2br": false,
14+
"disable_autolink": true,
15+
"allow_empty": false,
16+
"allow_signature": false,
17+
"editor_icon_type": "",
18+
"editor_icon_value": "",
19+
"active": true
20+
}

_output/bb_codes/section.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
{
2+
"bb_code_mode": "callback",
3+
"has_option": "optional",
4+
"replace_html": "",
5+
"replace_html_email": "",
6+
"replace_text": "",
7+
"callback_class": "Inforge\\PostTOC\\BbCode\\TagRenderer",
8+
"callback_method": "renderSectionTag",
9+
"option_regex": "",
10+
"trim_lines_after": 0,
11+
"plain_children": true,
12+
"disable_smilies": false,
13+
"disable_nl2br": false,
14+
"disable_autolink": true,
15+
"allow_empty": false,
16+
"allow_signature": false,
17+
"editor_icon_type": "",
18+
"editor_icon_value": "",
19+
"active": true
20+
}

0 commit comments

Comments
 (0)