diff --git a/Plugin/unraid/include/docs.php b/Plugin/unraid/include/docs.php
index 3be6eb6..a85e633 100644
--- a/Plugin/unraid/include/docs.php
+++ b/Plugin/unraid/include/docs.php
@@ -134,6 +134,7 @@ function vv_docs_markdown(string $md, array $vars): string {
$inCode = false;
$para = [];
$quote = [];
+ $li = [];
$flushPara = function () use (&$para, &$out, $inline) {
if (!$para) return;
@@ -145,7 +146,15 @@ function vv_docs_markdown(string $md, array $vars): string {
$out .= '
' . $inline(implode(' ', $quote)) . "
\n";
$quote = [];
};
- $closeList = function () use (&$list, &$out) {
+ // A list item is buffered rather than emitted on sight, because markdown wraps: a bullet
+ // whose text runs onto the next line is one item, not an item followed by a paragraph.
+ $flushLi = function () use (&$li, &$out, $inline) {
+ if (!$li) return;
+ $out .= '' . $inline(implode(' ', $li)) . "\n";
+ $li = [];
+ };
+ $closeList = function () use (&$list, &$out, &$flushLi) {
+ $flushLi();
if ($list) { $out .= "$list>\n"; $list = null; }
};
$closeTable = function () use (&$inTable, &$out) {
@@ -211,16 +220,23 @@ function vv_docs_markdown(string $md, array $vars): string {
if (preg_match('/^[-*]\s+(.*)$/', $t, $m)) {
$flushPara();
if ($list !== 'ul') { $closeList(); $out .= "\n"; $list = 'ul'; }
- $out .= '- ' . $inline($m[1]) . "
\n";
+ else { $flushLi(); }
+ $li[] = $m[1];
continue;
}
if (preg_match('/^\d+\.\s+(.*)$/', $t, $m)) {
$flushPara();
if ($list !== 'ol') { $closeList(); $out .= "\n"; $list = 'ol'; }
- $out .= '- ' . $inline($m[1]) . "
\n";
+ else { $flushLi(); }
+ $li[] = $m[1];
continue;
}
+ // Lazy continuation: plain text directly under an open list item belongs to that item.
+ // Without this a wrapped bullet renders as a bullet plus an orphan paragraph, which is
+ // how the first version of this shipped.
+ if ($list && $li) { $li[] = $t; continue; }
+
$para[] = $t;
}