error_reporting(E_ALL &~ E_DEPRECATED);
-define("OUTPUT", fopen("php://memory", "w+"));
-
function cut(array $lines, array $specs) {
$delim = "[[:space:]]+";
$bytes = [];
function head($file, $lines = 1) {
$ld = [];
- if (($fd = fopen($file, "r"))) {
+ if (is_resource($file) || ($file = fopen($file, "r"))) {
while ($lines--) {
- $ld[] = fgets($fd);
+ $ld[] = fgets($file);
}
}
return $ld;
}
-function ns($file) {
+function ns($path) {
+ $ns = "";
+ $parts = explode("/", $path);
+ $upper = ctype_upper($path[0]);
+ for ($i = 0; $i < count($parts); ++$i) {
+ if (!strlen($parts[$i]) || $parts[$i] === ".") {
+ continue;
+ }
+ if (strlen($ns)) {
+ if ($upper && !ctype_upper($parts[$i][0])) {
+ $ns .= "::";
+ } else {
+ $ns .= "\\";
+ }
+ }
+ $ns .= $parts[$i];
+ $upper = ctype_upper($parts[$i][0]);
+ }
+ return $ns;
return str_replace("/", "\\", str_replace("//", "/", trim($file, "/.")));
}
function urlpath($dir, $file) {
- return (strlen($dir) ? $dir . "/" : "") . urlencode($file);
+ return (strlen($dir) ? $dir . "/" : "") . basename($file, ".md");
}
-function ls($dir, $invert = false) {
- fprintf(OUTPUT, "<ul>\n");
- foreach (scandir($dir) as $file) {
- $dir = trim($dir, "./");
- $html = "";
- if ($file === ".") {
- continue;
- } elseif ($file === "..") {
- if ($dir === "" || $invert) {
+function ls($dir) {
+ $dir = rtrim(is_dir($dir) ? $dir : dirname($dir) ."/". basename($dir, ".md"), "/");
+ printf("<ul>\n");
+ printf("<li>⇐ <a href=/>Home</a></li>\n");
+ if ($dir !== "." && ($dn = dirname($dir)) !== ".") {
+ printf("<li>⇑ <a href=/%s>%s</a></li>\n",
+ urlpath($dir, ".."),
+ ns($dn));
+ }
+ if (is_dir($dir)) {
+ if ($dir !== ".") {
+ printf("<ul>\n<li> %s</li>\n", ns($dir));
+ }
+ printf("<ul>\n");
+ foreach (scandir($dir) as $file) {
+ /* ignore dot-files */
+ if ($file{0} === ".") {
continue;
}
- $name = sprintf("namespace %s", ns(dirname($dir)));
- } elseif (!$invert && is_dir("./$dir/$file")) {
- $name = sprintf("namespace %s", ns("./$dir/$file"));
- } elseif (!$invert && ctype_upper($file{0})) {
- $name = join(" ", cut(head("./$dir/$file"), ["f"=>"1-2"]));
- } elseif (!$invert || ctype_upper($file{0})) {
- continue;
- } else {
- $name = ns($dir)."::".basename($file, ".md");
- $html = "<p>".join(" ", cut(head("./$dir/$file"), ["f"=>"1-"]))."</p>";
+
+ $path = "$dir/$file";
+
+ if (is_file($path)) {
+ $pi = pathinfo($path);
+ /* ignore files not ending in .md */
+ if (!isset($pi["extension"]) || $pi["extension"] != "md") {
+ continue;
+ }
+ /* ignore files where an accompanying directory exists */
+ if (is_dir("$dir/".$pi["filename"])) {
+ continue;
+ }
+ } else {
+ /* ignore directories where no accompanying file exists */
+ if (!is_file("$path.md")) {
+ continue;
+ }
+ }
+
+ printf("<li>⇒ <a href=\"/%s\">%s</a></li>\n",
+ urlpath($dir, $file),
+ ns("$dir/".basename($file, ".md")));
+ }
+ printf("</ul>\n");
+ if ($dir !== ".") {
+ printf("</ul>\n");
}
-
- fprintf(OUTPUT, "<li><a href=\"/%s\">%s</a>%s</li>\n",
- urlpath($dir, $file),
- htmlspecialchars($name),
- $html);
}
- fprintf(OUTPUT, "</ul>\n");
+
+ printf("</ul>\n");
}
function ml($file) {
$pi = pathinfo($file);
- if (ctype_upper($pi["filename"][0])) {
- fprintf(OUTPUT, "<h2>Methods:</h2>\n");
- $el = $pi["dirname"] . "/" . $pi["filename"];
- ls($el, true);
+ if (!isset($pi["extension"])) {
+ return;
+ }
+ if ($pi["extension"] !== "md") {
+ return;
+ }
+ if (!ctype_upper($pi["filename"][0])) {
+ // namespaced functions
+ $dir = $pi["dirname"] . "/" . $pi["filename"];
+ if (is_dir($dir)) {
+ printf("<h2>Functions:</h2>\n");
+ printf("<ul>\n");
+ foreach (scandir($dir) as $file) {
+ if ($file{0} === "." || !is_file("$dir/$file") || ctype_upper($file{0})) {
+ continue;
+ }
+ printf("<li><h3><a href=\"/%s\">%s</a></h3><p>%s</p><p>%s</p></li>\n",
+ urlpath($dir, $file),
+ basename($file, ".md"),
+ @end(head("$dir/$file", 3)),
+ join(" ", cut(head("$dir/$file"), ["f"=>"1-"]))
+ );
+ }
+ printf("</ul>\n");
+ }
+ } else {
+ // methods
+ $dir = $pi["dirname"] . "/" . $pi["filename"];
+ if (is_dir($dir)) {
+ printf("<h2>Methods:</h2>\n");
+ printf("<ul>\n");
+ foreach (scandir($dir) as $file) {
+ if ($file{0} === "." || !is_file("$dir/$file") || ctype_upper($file{0})) {
+ continue;
+ }
+ printf("<li><h3><a href=\"/%s\">%s</a></h3><p>%s</p><p>%s</p></li>\n",
+ urlpath($dir, $file),
+ basename($file, ".md"),
+ @end(head("$dir/$file", 3)),
+ join(" ", cut(head("$dir/$file"), ["f"=>"1-"]))
+ );
+ }
+ printf("</ul>\n");
+ }
}
}
-function md($file) {
- $r = fopen($file, "r");
- $md = MarkdownDocument::createFromStream($r);
- $md->compile();
- $md->writeHtml(OUTPUT);
- unset($md);
- fclose($r);
-
- // BS Markdown seeks around...
- fseek(OUTPUT, 0, SEEK_END);
-
- ml($file);
+function md($file, $res) {
+ $file = rtrim($file, "/");
+ if (is_file($file) || is_file($file .= ".md")) {
+ $pi = pathinfo($file);
+
+ switch (@$pi["extension"]) {
+ case "md":
+ $r = fopen($file, "r");
+ $md = MarkdownDocument::createFromStream($r);
+ $md->compile(MarkdownDocument::AUTOLINK|MarkdownDocument::TOC);
+ print str_replace("<br/>","<br />",$md->getHtml());
+ fclose($r);
+ ml($file);
+ break;
+ case null:
+ printf("<h1>%s</h1>", basename($file));
+ printf("<pre>%s</pre>\n", htmlspecialchars(file_get_contents($file)));
+ break;
+ }
+ } else {
+ $res->setResponseCode(404);
+ printf("<h1>Not Found</h1>\n");
+ printf("<blockquote><p>Sorry, I could not find <code>%s/%s</code>.</p></blockquote>", dirname($file), basename($file, ".md"));
+ }
}
+chdir($_SERVER["DOCUMENT_ROOT"]);
+$t = ["css"=>"text/css", "js"=>"application/javascript"];
$r = new http\Env\Request;
$u = new http\Url($r->getRequestUrl());
-$t = ["css"=>"text/css", "js"=>"application/javascript"];
+$s = new http\Env\Response;
+$p = ".". $u->path;
-switch($u->path) {
-case "/index.js":
-case "/index.css":
- $s = new http\Env\Response;
- $s->setHeader("Content-type", $t[pathinfo($u->path, PATHINFO_EXTENSION)]);
- $s->setBody(new http\Message\Body(fopen(basename($u->path), "r")));
+switch($p) {
+case "./index.php":
+ exit;
+case "./index.js":
+case "./index.css":
+ $s->setHeader("Content-type", $t[pathinfo($p, PATHINFO_EXTENSION)]);
+ $s->setBody(new http\Message\Body(fopen($p, "r")));
$s->send();
exit;
}
-if (is_dir(".".$u->path)) {
- ls(".".$u->path);
-} else {
- md(".".$u->path);
-}
+ob_start($s);
?>
<!doctype html>
<html>
<head>
-<meta charset="utf-8">
-<title><?=$u->path?></title>
-<link rel="stylesheet" href="/index.css">
+ <meta charset="utf-8">
+ <title><?=ns($p)?></title>
+ <link rel="stylesheet" href="/index.css">
+ <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
+ <?php if (!extension_loaded("discount") || !getenv("DISCOUNT")) : ?>
+ <script src="/markdown.js"></script>
+ <?php endif; ?>
</head>
<body>
-<?php
-rewind(OUTPUT);
-fpassthru(OUTPUT);
-fclose(OUTPUT);
-?>
-<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
-<script src="/index.js"></script>
+ <div class="sidebar">
+ <?php ls($p); ?>
+ </div>
+ <?php if ($p === "./") : ?>
+ <h1>Quick Markdown Documentation Browser</h1>
+ <p>v<?php readfile("VERSION")?></p>
+ <pre><?php
+ ob_start(function($s) {
+ return htmlspecialchars($s);
+ });
+ readfile("LICENSE");
+ ob_end_flush();
+ ?></pre>
+ <?php else: ?>
+ <?php if (!md($p, $s)): ?>
+ <?php endif; ?>
+ <?php endif; ?>
+ <footer>
+ <a href="/VERSION">Version</a>
+ <a href="/AUTHORS">Authors</a>
+ <a href="/LICENSE">License</a>
+ </footer>
+ <script src="/index.js"></script>
</body>
</html>
+<?php
+
+ob_end_flush();
+$s->send();