Show the reference tables collapsed and the task guide on expand, from one file
This commit is contained in:
@@ -532,6 +532,9 @@ body.vv-fullscreen #displaybox { padding-left: 1rem !important; padding-top: .5r
|
|||||||
padding: 4px 6px 4px 0; vertical-align: top; }
|
padding: 4px 6px 4px 0; vertical-align: top; }
|
||||||
.vv-doc-code { background: #0d0d0d; border: 1px solid #222; border-radius: 3px; padding: 7px 9px;
|
.vv-doc-code { background: #0d0d0d; border: 1px solid #222; border-radius: 3px; padding: 7px 9px;
|
||||||
font-size: 11px; color: #9ab; overflow-x: auto; break-inside: avoid; }
|
font-size: 11px; color: #9ab; overflow-x: auto; break-inside: avoid; }
|
||||||
|
/* The always-visible reference tier. Sits below the collapsible guide, so the rule reads as a
|
||||||
|
separator when the guide is open and as a header underline when it is shut. */
|
||||||
|
.vv-doc-quick { border-top: 1px solid #1c1c1c; padding-top: 9px; }
|
||||||
|
|
||||||
.vv-info-divider { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: #444;
|
.vv-info-divider { font-size: 10px; text-transform: uppercase; letter-spacing: 0.1em; color: #444;
|
||||||
padding: 10px 12px 4px; border-top: 1px solid #2a2a2a; margin-top: 2px; }
|
padding: 10px 12px 4px; border-top: 1px solid #2a2a2a; margin-top: 2px; }
|
||||||
|
|||||||
@@ -72,7 +72,11 @@ function vv_docs_tree(): array {
|
|||||||
return $tree;
|
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
|
// 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
|
// 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.
|
// 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 (strtolower(pathinfo($path, PATHINFO_EXTENSION)) !== 'md') return '<p>File not found.</p>';
|
||||||
if (!is_file($path)) 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
|
// 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
|
// 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
|
// 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.
|
// 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)) {
|
if (file_exists(PARSEDOWN_PATH)) {
|
||||||
require_once PARSEDOWN_PATH;
|
require_once PARSEDOWN_PATH;
|
||||||
$pd = new Parsedown();
|
$pd = new Parsedown();
|
||||||
@@ -161,17 +165,39 @@ function vv_docs_markdown(string $md, array $vars): string {
|
|||||||
if ($inTable) { $out .= "</tbody></table>\n"; $inTable = false; }
|
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) {
|
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)) {
|
if (preg_match('/^```/', $line)) {
|
||||||
|
if (!$skip) {
|
||||||
$flushPara(); $closeList(); $closeTable();
|
$flushPara(); $closeList(); $closeTable();
|
||||||
$out .= $inCode ? "</code></pre>\n" : '<pre class="vv-doc-code"><code>';
|
$out .= $inCode ? "</code></pre>\n" : '<pre class="vv-doc-code"><code>';
|
||||||
|
}
|
||||||
$inCode = !$inCode;
|
$inCode = !$inCode;
|
||||||
continue;
|
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);
|
$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
|
// 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.
|
// not a quote line, whatever that next line turns out to be.
|
||||||
if ($quote && !str_starts_with($t, '>')) $flushQuote();
|
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 ($t === '') { $flushPara(); $closeList(); $closeTable(); continue; }
|
||||||
if (preg_match('/^(---+|\*\*\*+)$/', $t)) { $flushPara(); $closeList(); $closeTable(); $out .= "<hr>\n"; 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
|
// Consecutive > lines are one quote, not one per line — same wrapping convention as
|
||||||
// paragraphs, which is how they are written.
|
// paragraphs, which is how they are written.
|
||||||
if (preg_match('/^>\s?(.*)$/', $t, $m)) {
|
if (preg_match('/^>\s?(.*)$/', $t, $m)) {
|
||||||
|
|||||||
@@ -507,12 +507,24 @@ $runningScripts = array_unique($runningScripts);
|
|||||||
<!-- Rendered from pages/readme/scheduler-readme.md, not maintained here. That file is
|
<!-- Rendered from pages/readme/scheduler-readme.md, not maintained here. That file is
|
||||||
also what the AI tab retrieves, so the panel you read and the answer the
|
also what the AI tab retrieves, so the panel you read and the answer the
|
||||||
assistant gives are the same text and cannot drift — the same argument that
|
assistant gives are the same text and cannot drift — the same argument that
|
||||||
makes this page parse script PURPOSE blocks instead of restating them. -->
|
makes this page parse script PURPOSE blocks instead of restating them.
|
||||||
|
Two tiers, one file. Collapsed leaves the reference tables visible: that is the
|
||||||
|
terse per-control lookup this panel has always been, and it is what you want
|
||||||
|
open while actually working. Expanding adds the task guide above it — the
|
||||||
|
walkthroughs you need once and then stop reading. The split is taken from the
|
||||||
|
section titles, so neither tier is a second copy of anything.
|
||||||
|
vvToggleSug() toggles the header's immediate next sibling, so the guide must
|
||||||
|
stay directly after the header and the quick tier must sit outside it. -->
|
||||||
<div class="vv-sug-body vv-info-body">
|
<div class="vv-sug-body vv-info-body">
|
||||||
<div class="vv-doc">
|
<div class="vv-doc">
|
||||||
<?= vv_docs_render('Plugin/unraid/pages/readme/scheduler-readme.md', $_vv_doc_vars) ?>
|
<?= vv_docs_render('Plugin/unraid/pages/readme/scheduler-readme.md', $_vv_doc_vars,
|
||||||
|
fn($h) => !is_string($h) || !str_starts_with($h, 'Reference —')) ?>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="vv-info-body vv-doc vv-doc-quick">
|
||||||
|
<?= vv_docs_render('Plugin/unraid/pages/readme/scheduler-readme.md', $_vv_doc_vars,
|
||||||
|
fn($h) => is_string($h) && str_starts_with($h, 'Reference —')) ?>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ── Next Runs ── -->
|
<!-- ── Next Runs ── -->
|
||||||
|
|||||||
Reference in New Issue
Block a user