diff --git a/Plugin/unraid/css/varaverk.css b/Plugin/unraid/css/varaverk.css index 3681a7e..a02dbf9 100644 --- a/Plugin/unraid/css/varaverk.css +++ b/Plugin/unraid/css/varaverk.css @@ -532,6 +532,9 @@ body.vv-fullscreen #displaybox { padding-left: 1rem !important; padding-top: .5r padding: 4px 6px 4px 0; vertical-align: top; } .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; } +/* 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; padding: 10px 12px 4px; border-top: 1px solid #2a2a2a; margin-top: 2px; } diff --git a/Plugin/unraid/include/docs.php b/Plugin/unraid/include/docs.php index a85e633..26822c9 100644 --- a/Plugin/unraid/include/docs.php +++ b/Plugin/unraid/include/docs.php @@ -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 '
File not found.
'; if (!is_file($path)) return 'File not found.
'; - 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 into the markdown before rendering, as this file used to
// do, meant both Parsedown's safe mode and the 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 .= "\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 ? "\n" : '';
+ if (!$skip) {
+ $flushPara(); $closeList(); $closeTable();
+ $out .= $inCode ? "\n" : '';
+ }
$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 .= "" . $inline($m[2]) . " \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 .= "
\n"; continue; }
- if (preg_match('/^(#{1,6})\s+(.*)$/', $t, $m)) {
- $flushPara(); $closeList(); $closeTable();
- $n = strlen($m[1]);
- $out .= "" . $inline($m[2]) . " \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)) {
diff --git a/Plugin/unraid/pages/scheduler.php b/Plugin/unraid/pages/scheduler.php
index 216e3e9..38866dc 100644
--- a/Plugin/unraid/pages/scheduler.php
+++ b/Plugin/unraid/pages/scheduler.php
@@ -507,12 +507,24 @@ $runningScripts = array_unique($runningScripts);
+ 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. -->
- = 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 —')) ?>
+
+ = vv_docs_render('Plugin/unraid/pages/readme/scheduler-readme.md', $_vv_doc_vars,
+ fn($h) => is_string($h) && str_starts_with($h, 'Reference —')) ?>
+