if not available. define('PARSEDOWN_PATH', '/usr/local/emhttp/plugins/varaverk/lib/Parsedown.php'); function vv_docs_tree(): array { $base = SCRIPTS_DIR; $tree = []; $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($base, FilesystemIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ); foreach ($files as $f) { if ($f->isFile() && strtolower($f->getExtension()) === 'md') { $rel = ltrim(str_replace($base, '', $f->getPathname()), '/'); $tree[] = $rel; } } sort($tree); return $tree; } function vv_docs_render(string $rel, array $vars): string { $path = SCRIPTS_DIR . '/' . $rel; if (!file_exists($path)) return '

File not found.

'; $md = file_get_contents($path); // Substitute `$VAR_NAME` markers with live conf values $md = preg_replace_callback('/`\$([A-Z0-9_]+)`/', function($m) use ($vars) { $key = $m[1]; return isset($vars[$key]) ? '' . htmlspecialchars($vars[$key]) . '' : '$' . htmlspecialchars($key) . ''; }, $md); // Render markdown if (file_exists(PARSEDOWN_PATH)) { require_once PARSEDOWN_PATH; $pd = new Parsedown(); $pd->setSafeMode(true); return $pd->text($md); } // Fallback: plain preformatted text return '
' . htmlspecialchars($md) . '
'; }