|
@@ -1449,9 +1449,24 @@ class HyperDown
|
|
|
$rows = [];
|
|
|
$suffix = '';
|
|
|
$last = 0;
|
|
|
-
|
|
|
foreach ($lines as $key => $line) {
|
|
|
if (preg_match("/^(\s{" . $space . "})((?:[0-9]+\.?)|\-|\+|\*)(\s+)(.*)$/i", $line, $matches)) {
|
|
|
+ // 检测任务列表语法 [ ] 或 [x]
|
|
|
+ $content = $matches[4];
|
|
|
+ $isTask = false;
|
|
|
+ $checked = false;
|
|
|
+
|
|
|
+ if (substr($content, 0, 4) === '[ ] ') {
|
|
|
+ $isTask = true;
|
|
|
+ $checked = ($taskMatches === 'x');
|
|
|
+ $content = substr($content, 4);
|
|
|
+ }else if (substr($content, 0, 4) === '[x] ' || substr($content, 0, 4) === '[X] '){
|
|
|
+ $isTask = true;
|
|
|
+ $checked = true;
|
|
|
+ $content = substr($content, 4);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
if ($type == 'ol' && $key == 0) {
|
|
|
$olStart = intval($matches[2]);
|
|
|
|
|
@@ -1459,19 +1474,27 @@ class HyperDown
|
|
|
$suffix = ' start="' . $olStart . '"';
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- $rows[] = [$matches[4]];
|
|
|
+ $rows[] = [
|
|
|
+ 'content' => "$content",
|
|
|
+ 'isTask' => $isTask,
|
|
|
+ 'checked' => $checked
|
|
|
+ ];
|
|
|
$last = count($rows) - 1;
|
|
|
} else {
|
|
|
- $rows[$last][] = preg_replace("/^\s{" . ($tab + $space) . "}/", '', $line);
|
|
|
+ $rows[$last]['content'] .="\n" . preg_replace("/^\s{" . ($tab + $space) . "}/", '', $line);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
foreach ($rows as $row) {
|
|
|
- $html .= "<li>" . $this->parse(implode("\n", $row), true, $start) . "</li>";
|
|
|
- $start += count($row);
|
|
|
+ $parsedContent = $this->parse(implode("\n", [$row['content']]), true, $start);
|
|
|
+ if ($row['isTask']) {
|
|
|
+ $checkedAttr = $row['checked'] ? ' checked' : '';
|
|
|
+ $html .= "<li><input type=\"checkbox\" onclick='this.checked=!this.checked' {$checkedAttr}> {$parsedContent}</li>";
|
|
|
+ } else {
|
|
|
+ $html .= "<li>{$parsedContent}</li>";
|
|
|
+ }
|
|
|
+
|
|
|
+ $start += count([$row['content']]);
|
|
|
}
|
|
|
-
|
|
|
return "<{$type}{$suffix}>{$html}</{$type}>";
|
|
|
}
|
|
|
|