--- /dev/null
+<?php
+
+namespace BookStack\Entities\Tools\Markdown;
+
+use League\CommonMark\Block\Element\AbstractBlock;
+use League\CommonMark\Block\Element\ListItem;
+use League\CommonMark\Block\Element\Paragraph;
+use League\CommonMark\Block\Renderer\BlockRendererInterface;
+use League\CommonMark\Block\Renderer\ListItemRenderer;
+use League\CommonMark\ElementRendererInterface;
+use League\CommonMark\Extension\TaskList\TaskListItemMarker;
+use League\CommonMark\HtmlElement;
+
+class CustomListItemRenderer implements BlockRendererInterface
+{
+ protected $baseRenderer;
+
+ public function __construct()
+ {
+ $this->baseRenderer = new ListItemRenderer();
+ }
+
+ /**
+ * @return HtmlElement|string|null
+ */
+ public function render(AbstractBlock $block, ElementRendererInterface $htmlRenderer, bool $inTightList = false)
+ {
+ $listItem = $this->baseRenderer->render($block, $htmlRenderer, $inTightList);
+
+ if ($this->startsTaskListItem($block)) {
+ $listItem->setAttribute('class', 'task-list-item');
+ }
+
+ return $listItem;
+ }
+
+ private function startsTaskListItem(ListItem $block): bool
+ {
+ $firstChild = $block->firstChild();
+
+ return $firstChild instanceof Paragraph && $firstChild->firstChild() instanceof TaskListItemMarker;
+ }
+}
\ No newline at end of file
namespace BookStack\Entities\Tools;
use BookStack\Entities\Models\Page;
+use BookStack\Entities\Tools\Markdown\CustomListItemRenderer;
use BookStack\Entities\Tools\Markdown\CustomStrikeThroughExtension;
+use BookStack\Entities\Tools\Markdown\CustomTaskListMarkerRenderer;
use BookStack\Exceptions\ImageUploadException;
use BookStack\Facades\Theme;
use BookStack\Theming\ThemeEvents;
use DOMNodeList;
use DOMXPath;
use Illuminate\Support\Str;
+use League\CommonMark\Block\Element\ListItem;
use League\CommonMark\CommonMarkConverter;
use League\CommonMark\Environment;
use League\CommonMark\Extension\Table\TableExtension;
use League\CommonMark\Extension\TaskList\TaskListExtension;
+use League\CommonMark\Extension\TaskList\TaskListItemMarker;
+use League\CommonMark\Extension\TaskList\TaskListItemMarkerParser;
+use League\CommonMark\Extension\TaskList\TaskListItemMarkerRenderer;
class PageContent
{
$environment = Theme::dispatch(ThemeEvents::COMMONMARK_ENVIRONMENT_CONFIGURE, $environment) ?? $environment;
$converter = new CommonMarkConverter([], $environment);
+ $environment->addBlockRenderer(ListItem::class, new CustomListItemRenderer(), 10);
+
return $converter->convertToHtml($markdown);
}
}
}
ul {
- padding-left: $-m * 1.3;
- padding-right: $-m * 1.3;
list-style: disc;
ul {
list-style: circle;
- margin-top: 0;
- margin-bottom: 0;
}
label {
margin: 0;
ol {
list-style: decimal;
- padding-left: $-m * 2;
- padding-right: $-m * 2;
+}
+
+ol, ul {
+ padding-left: $-m * 2.0;
+ padding-right: $-m * 2.0;
+}
+
+li > ol, li > ul {
+ margin-top: 0;
+ margin-bottom: 0;
+ margin-block-end: 0;
+ margin-block-start: 0;
+ padding-block-end: 0;
+ padding-block-start: 0;
+ padding-left: $-m * 1.2;
+ padding-right: $-m * 1.2;
}
li.checkbox-item, li.task-list-item {
list-style: none;
- margin-left: - ($-m * 1.3);
+ margin-left: -($-m * 1.2);
input[type="checkbox"] {
margin-right: $-xs;
}
-}
-
-li > ol, li > ul {
- margin-block-end: 0px;
- margin-block-start: 0px;
- padding-block-end: 0px;
- padding-block-start: 0px;
+ li.checkbox-item, li.task-list-item {
+ margin-left: $-xs;
+ }
}
/*