fprintf(STDERR, " Note: the basedir will also be used as <base href>\n");
exit(1);
}
-function say($fmt, ...$args) {
- return fprintf(STDERR, $fmt, ...$args);
-};
$out = $argv[1];
if (!is_dir($out) && !mkdir($out, 0775, true)) {
fprintf(STDERR, "Could not create output directory %s\n", $out);
$dst = $dir . ".html";
foreach ($xfm as $from => $dest) {
if (strpos($src, $dest) !== false) {
- say("Redirecting from %s to %s\n", $from, $dest);
+ printf("Redirecting from %s to %s\n", $from, $dest);
$red($from, $dest, $src);
break;
}
$gen($subentry);
}
}
- say("Generating %s from %s\n", $dst, $src);
+ printf("Generating %s from %s\n", $dst, $src);
$fmt($src, $dst);
};
/** @var $repo Repo */
foreach ($ref as $repo) {
- say("Entering ref %s\n", $repo->getName());
+ printf("Entering ref %s\n", $repo->getName());
if (is_file($stub = $repo->getPath($repo->getName().".stub.php"))) {
copy($stub, $out . "/" . basename($stub));
}
--- /dev/null
+#!/usr/bin/env php
+<?php
+
+namespace mdref;
+
+require_once $_composer_autoload_path ?? __DIR__."/../vendor/autoload.php";
+
+if ($argc < 2) {
+ fprintf(STDERR, "Usage: %s <stub.php> [<ns>]\n", $argv[0]);
+ exit(1);
+}
+
+if (!($stub = realpath($argv[1]))) {
+ $stat = stat($stub);
+ assert(!$stat);
+ exit(2);
+}
+if ($argc > 2) {
+ $namespace = $argv[2];
+} else {
+ $namespace = basename($stub, ".stub.php");
+}
+
+$tmplck = tempnam(sys_get_temp_dir(), "mdref.");
+$tmpdir = $tmplck . ".d";
+mkdir($tmpdir) && chdir($tmpdir) || exit(-1);
+
+$running = true;
+$shutdown = function() use($tmpdir, $tmplck, &$running) {
+ $running = false;
+ chdir(__DIR__) && rm_r($tmpdir, $tmplck);
+};
+register_shutdown_function($shutdown);
+pcntl_signal(SIGINT, $shutdown, false);
+pcntl_signal(SIGTERM, $shutdown, false);
+
+$passthru = fn($cmd) => fn() => printf("%s\n", $cmd) && !passthru("$cmd 2>&1 >/dev/null", $rc) && !$rc;
+$stub2ref = $passthru(
+ sprintf("%s/stub2ref %s %s %s",
+ __DIR__,
+ escapeshellarg($namespace),
+ escapeshellarg($stub),
+ escapeshellarg($tmpdir)
+ )
+);
+$ref2html = $passthru(
+ sprintf("%s/ref2html . .",
+ __DIR__,
+ )
+);
+$update = fn() => $stub2ref() && $ref2html();
+
+if ($update()) {
+ $ifd = inotify_init();
+ inotify_add_watch($ifd, $stub, IN_MODIFY);
+ stream_set_blocking($ifd, false);
+
+ file_put_contents("router.php", file_get_contents(__FILE__, false, null, __COMPILER_HALT_OFFSET__));
+ $php = popen(sprintf("%s -S localhost:0 -t . router.php 2>&1 | grep --line-buffered -Ev 'Accepted|Closing|GET'", PHP_BINARY), "r");
+ echo fgets($php);
+ stream_set_blocking($php, false);
+
+ while ($running) {
+ $R = [$ifd, $php]; $W = []; $E = [];
+ if (stream_select($R, $W, $E, null)) {
+ foreach ($R as $r) {
+ switch ($r) {
+ case $php:
+ while (($string = fgets($php))) echo $string;
+ break;
+ case $ifd:
+ // cooldown
+ usleep(50 * 1000);
+ while (inotify_read($ifd));
+ $update();
+ break;
+ }
+ }
+ }
+ pcntl_signal_dispatch();
+ }
+}
+
+function rm_r(string ...$args) {
+ foreach ($args as $del) {
+ if (is_dir($del)) {
+ rm_r(...array_map(fn($sub) => "$del/$sub", array_slice(scandir($del), 2)));
+ rmdir($del);
+ } else if (file_exists($del)) {
+ unlink($del);
+ }
+ }
+}
+
+__HALT_COMPILER();
+<?php
+
+$file = __DIR__ . urldecode($_SERVER["REQUEST_URI"]);
+
+if (is_file($file)) {
+ return false;
+}
+
+if (is_dir($file) && file_exists($file."/index.html")) {
+ readfile($file."/index.html");
+} else {
+ $file = rtrim($file, "/").".html";
+ if (file_exists($file)) {
+ readfile($file);
+ } else {
+ return false;
+ }
+}
mkdir($destination) || exit -1;
}
if (!file_exists("$destination/$namespace.mdref")) {
- fprintf(STDERR, "Missing $destination/$namespace.mdref; generated default.\n");
+ fprintf(STDERR, "Missing $destination/$namespace.mdref; generating default.\n");
file_put_contents("$destination/$namespace.mdref", "./%s") || exit -2;
}
+if (!file_exists("$destination/$namespace.md")) {
+ fprintf(STDERR, "Missing $destination/$namespace.mdref; generating default from README.\n");
+ $readme = dirname($argv[2]) . "/README.md";
+ if (!file_exists($readme)) {
+ fprintf(STDERR, "Missing $readme; creating empty $namespace.md");
+ touch("$destination/$namespace.md");
+ } else {
+ link(realpath($readme), "$destination/$namespace.md");
+ }
+}
$inspector = new Inspector;
$inspector->inspectNamespace($namespace);
$ns_path = $this->destination . "/" . strtr($ns, "\\", "/");
foreach ($funcs as $fn => $rf) {
$fn_file = "$ns_path/$fn.md";
- fprintf(STDERR, "Generating %s\n", $fn_file);
+ printf("Generating %s\n", $fn_file);
is_dir($ns_path) || mkdir($ns_path, 0770, true);
file_put_contents($fn_file, new Func($this, $rf));
}
foreach ($cls as $cn => $rc) {
$cn_path = "$ns_path/$cn";
$cn_file = "$cn_path.md";
- fprintf(STDERR, "Generating %s\n", $cn_file);
+ printf("Generating %s\n", $cn_file);
is_dir($ns_path) || mkdir($ns_path, 0770, true);
file_put_contents($cn_file, new Cls($this, $rc));
$this->generateMethods($rc);
$this->createDocBlock();
}
if (!$this->doc) {
- fprintf(STDERR, ... match (get_class($ref)) {
+ printf(... match (get_class($ref)) {
\ReflectionClass::class => ["Missing docs for class %s\n", $ref->name],
\ReflectionMethod::class => ["Missing docs for method %s::%s()\n", $ref->class, $ref->name],
\ReflectionProperty::class => ["Missing docs for property %s %s::\$%s\n", $ref->getType(), $ref->class, $ref->name],