Show the reference tables collapsed and the task guide on expand, from one file
This commit is contained in:
@@ -72,7 +72,11 @@ function vv_docs_tree(): array {
|
||||
return $tree;
|
||||
}
|
||||
|
||||
function vv_docs_render(string $rel, array $vars): string {
|
||||
// $keep, when given, selects which `##` sections are rendered. It receives the section heading —
|
||||
// or null for the title and any preamble before the first one — and returns whether to include
|
||||
// it. That is what lets one file drive both tiers of a disclosure without a second copy, and
|
||||
// without inventing markdown syntax to mark the split: the section titles already carry it.
|
||||
function vv_docs_render(string $rel, array $vars, ?callable $keep = null): string {
|
||||
// Containment check — $rel is expected to come from a request parameter once this is
|
||||
// wired to a page. Resolve it and require the result to stay inside SCRIPTS_DIR and to
|
||||
// still be a .md file, so a traversal sequence cannot reach arbitrary files.
|
||||
@@ -83,7 +87,7 @@ function vv_docs_render(string $rel, array $vars): string {
|
||||
if (strtolower(pathinfo($path, PATHINFO_EXTENSION)) !== 'md') return '<p>File not found.</p>';
|
||||
if (!is_file($path)) return '<p>File not found.</p>';
|
||||
|
||||
return vv_docs_markdown(file_get_contents($path), $vars);
|
||||
return vv_docs_markdown(file_get_contents($path), $vars, $keep);
|
||||
}
|
||||
|
||||
// Markdown → HTML for the subset these docs actually use: headings, paragraphs, bullet and
|
||||
@@ -102,7 +106,7 @@ function vv_docs_render(string $rel, array $vars): string {
|
||||
// here, after escaping. Injecting <code> into the markdown before rendering, as this file used to
|
||||
// do, meant both Parsedown's safe mode and the <pre> fallback escaped the tags and printed them
|
||||
// as literal text. The feature never worked; nothing called it, so nothing reported it.
|
||||
function vv_docs_markdown(string $md, array $vars): string {
|
||||
function vv_docs_markdown(string $md, array $vars, ?callable $keep = null): string {
|
||||
if (file_exists(PARSEDOWN_PATH)) {
|
||||
require_once PARSEDOWN_PATH;
|
||||
$pd = new Parsedown();
|
||||
@@ -161,17 +165,39 @@ function vv_docs_markdown(string $md, array $vars): string {
|
||||
if ($inTable) { $out .= "</tbody></table>\n"; $inTable = false; }
|
||||
};
|
||||
|
||||
// Content before the first heading belongs to the same null-headed group as the title.
|
||||
$skip = $keep !== null && !$keep(null);
|
||||
|
||||
foreach (explode("\n", str_replace("\r\n", "\n", $md)) as $line) {
|
||||
// Fence state is tracked even inside a skipped section, or a ``` that is being dropped
|
||||
// would leave the parser convinced every following line is code.
|
||||
if (preg_match('/^```/', $line)) {
|
||||
$flushPara(); $closeList(); $closeTable();
|
||||
$out .= $inCode ? "</code></pre>\n" : '<pre class="vv-doc-code"><code>';
|
||||
if (!$skip) {
|
||||
$flushPara(); $closeList(); $closeTable();
|
||||
$out .= $inCode ? "</code></pre>\n" : '<pre class="vv-doc-code"><code>';
|
||||
}
|
||||
$inCode = !$inCode;
|
||||
continue;
|
||||
}
|
||||
if ($inCode) { $out .= htmlspecialchars($line, ENT_QUOTES, 'UTF-8') . "\n"; continue; }
|
||||
if ($inCode) {
|
||||
if (!$skip) $out .= htmlspecialchars($line, ENT_QUOTES, 'UTF-8') . "\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
$t = trim($line);
|
||||
|
||||
// Headings are resolved before the skip test, because a heading is what changes it.
|
||||
if (preg_match('/^(#{1,6})\s+(.*)$/', $t, $m)) {
|
||||
$flushQuote(); $flushPara(); $closeList(); $closeTable();
|
||||
$n = strlen($m[1]);
|
||||
// A level-1 heading is the document title, not a section — it and the preamble that
|
||||
// follows are offered to $keep as null so a caller can take or leave them as a unit.
|
||||
$skip = $keep !== null && !$keep($n === 1 ? null : $m[2]);
|
||||
if (!$skip) $out .= "<h$n>" . $inline($m[2]) . "</h$n>\n";
|
||||
continue;
|
||||
}
|
||||
if ($skip) continue;
|
||||
|
||||
// One guard rather than a flush in every branch: the quote ends the moment a line is
|
||||
// not a quote line, whatever that next line turns out to be.
|
||||
if ($quote && !str_starts_with($t, '>')) $flushQuote();
|
||||
@@ -179,13 +205,6 @@ function vv_docs_markdown(string $md, array $vars): string {
|
||||
if ($t === '') { $flushPara(); $closeList(); $closeTable(); continue; }
|
||||
if (preg_match('/^(---+|\*\*\*+)$/', $t)) { $flushPara(); $closeList(); $closeTable(); $out .= "<hr>\n"; continue; }
|
||||
|
||||
if (preg_match('/^(#{1,6})\s+(.*)$/', $t, $m)) {
|
||||
$flushPara(); $closeList(); $closeTable();
|
||||
$n = strlen($m[1]);
|
||||
$out .= "<h$n>" . $inline($m[2]) . "</h$n>\n";
|
||||
continue;
|
||||
}
|
||||
|
||||
// Consecutive > lines are one quote, not one per line — same wrapping convention as
|
||||
// paragraphs, which is how they are written.
|
||||
if (preg_match('/^>\s?(.*)$/', $t, $m)) {
|
||||
|
||||
Reference in New Issue
Block a user