flush
authorMichael Wallner <mike@php.net>
Wed, 30 Oct 2013 17:47:50 +0000 (18:47 +0100)
committerMichael Wallner <mike@php.net>
Wed, 30 Oct 2013 17:47:50 +0000 (18:47 +0100)
LICENSE [new file with mode: 0644]
index.css
index.js
index.php

diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..816ff40
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,23 @@
+Copyright (c) 2013, Michael Wallner <mike@php.net>.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without 
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, 
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright 
+      notice, this list of conditions and the following disclaimer in the 
+      documentation and/or other materials provided with the distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
+DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE 
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
+SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 
+CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 
+OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
index b61f51524d4aab89e33dbcc172c0471168c094c4..949bcbc94b753c9270b3d6681a3d44168875c42d 100644 (file)
--- a/index.css
+++ b/index.css
@@ -6,12 +6,25 @@ body {
        font-family: monospace;
        font-size: 1.5em;
        margin: 0;
-       padding: 4em 0 0 0;
+       padding: 0;
 }
 
 body>* {
+       margin-left: 1em;
+}
+
+.sidebar {
+       float: right;
+       width: 400px;
+       background: #f0f0f0;
+       border-bottom-left-radius: 10px;
+       padding: 0;
+       margin-bottom: 1em;
        margin-left: 2em;
-       margin-right: 2em;
+}
+.sidebar>ul {
+       paddinng: 1em;
+       margin-left: 1em;
 }
 
 code { 
@@ -24,22 +37,17 @@ code {
 }
 
 h1 {
-       position: fixed;
-       top: 0;
-       left: 0;
-       width: 100%;
        margin: 0;
        padding: 1em;
 }
 p {
        color: #3f3f3f;
-       margin: 1em;
+       margin: 1em 2em;
 }
 
 blockquote {
        padding: 1em;
        border-radius: 4px;
-       max-width: 1000px;
 }
 blockquote, blockquote p {
        color: #f0f0f0;
@@ -57,10 +65,17 @@ a {
 .var {
        color: #800000;
 }
+.constant {
+       color: #2e8b57;
+}
 
 .invert, h1, blockquote, blockquote p {
-       background: #030303;
-       color: #f0f0f0;
+       background: #708090;
+       color: #f5f5dc;
+}
+
+.invert .constant, h1 .constant, blockquote .constant {
+       color: #98fb98;
 }
 
 .invert .var, h1 .var, blockquote .var {
@@ -70,4 +85,3 @@ a {
 .invert a, h1 a, blockquote a {
        color: #b0e0e6;
 }
-
index 6334108c3888036c669315abd09891b4f0fb512c..2f6577266773498967a13dae88b859d087342a1d 100644 (file)
--- a/index.js
+++ b/index.js
@@ -1,4 +1,13 @@
+function is_constant(s) {
+       return s.length > 3 &&  s.toUpperCase(s) === s;
+}
+
+function is_variable(s) {
+       return s.substring(0,1) === "$";
+}
+
 function type(s) {
+       var i, j, t;
        
        // nothing
        if (!s.match(/[a-zA-Z]/)) {
@@ -15,6 +24,7 @@ function type(s) {
        case "array":
        case "object":
        case "callable":
+       case "mixed":
                return "<code>";
                
        // keywords
@@ -35,16 +45,22 @@ function type(s) {
                return "<em>";
        }
        
-       var is_namespace, is_method;
-       
-       if ((is_method = (s.indexOf("::") !== -1)) || (is_namespace = (s.indexOf("\\") !== -1))) {
-               return "<a href=\"/" + s.replace(/::|\\/g, "/") + (is_method ? ".md":"") + "\">";
+       // class members
+       if (-1 !== (i = s.indexOf("::"))) {
+               t = s.substring(i+2);
+               if (!is_constant(t) && !is_variable(t)) {
+                       // methods
+                       return "<a href=\"/" + s.replace(/::|\\/g, "/") + "\">";
+               }
+       }
+       if (-1 !== (j = s.indexOf("\\"))) {
+               return "<a href=\"/" + s.replace(/\\/g, "/").replace(/::|$/, "#") + "\">";
        }
        
        switch (s.toLowerCase()) {
        // variables
        default:
-               if (s.substring(0,1) !== "$") {
+               if (!is_variable(s)) {
                        break;
                }
        // special constants
@@ -55,8 +71,8 @@ function type(s) {
        }
        
        // constants
-       if (s.toUpperCase() === s) {
-               return "<code>";
+       if (is_constant(s)) {
+               return "<span class=\"constant\">";
        }
 }
 function node(s) {
@@ -94,8 +110,32 @@ function walk(i, e) {
                }
        });
 }
-$(document).ready(function() {
-       //console.log("ready");
 
+function hashchange() {
+       if (location.hash.length > 1) {
+               var hash = location.hash.substring(1);
+               
+               $(is_variable(hash) ? ".var" : ".constant").each(function(i, c) {
+                       
+                       if (c.textContent === hash) {
+                               var $c = $(c);
+                               
+                               $(window).scrollTop($c.offset().top - 100);
+                               $c.fadeOut("slow").queue(function(next) {
+                                       this.style.color = "red";
+                                       next();
+                               }).fadeIn("fast").fadeOut("fast").queue(function(next) {
+                                       this.style.color = "";
+                                       next();
+                               }).fadeIn("slow");
+                               return false;
+                       }
+               });
+       }
+}
+
+$(function() {
        $("h1,h2,h3,h4,h5,h6,p,li,code").each(walk);
+       $(window).on("hashchange", hashchange);
+       hashchange();
 });
index 160fed53b3418e5a0a30fb4f80e4e594c5fbf86d..b2109846572cbf8c414f5117b29a4a39ddc5c8ba 100644 (file)
--- a/index.php
+++ b/index.php
@@ -2,8 +2,6 @@
 
 error_reporting(E_ALL &~ E_DEPRECATED);
 
-define("OUTPUT", fopen("php://memory", "w+"));
-
 function cut(array $lines, array $specs) {
        $delim = "[[:space:]]+";
        $bytes = [];
@@ -69,98 +67,139 @@ function ns($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("<li>%s</li>\n", ns($dir));
+               }
+               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;
+                               }
+                               if (!ctype_upper($file{0}) && !is_dir("$dir/".$pi["filename"])) {
+                                       continue;
+                               }
+                       } else {
+                               /* ignore directories where an companying 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")));
                }
-
-               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);
+               printf("<h2>Methods:</h2>\n");
+               $dir = $pi["dirname"] . "/" . $pi["filename"];
+               if (is_dir($dir)) {
+                       printf("<ul>\n");
+                       foreach (scandir($dir) as $file) {
+                               if (!is_file("$dir/$file") || ctype_upper($file{0})) {
+                                       continue;
+                               }
+                               printf("<li><h3>%s</h3><p>%s</p></li>\n",
+                                       basename($file, ".md"),
+                                       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);
+       $file = rtrim($file, "/");
+       if (is_file($file) || is_file($file .= ".md")) {
+               $r = fopen($file, "r");
+               $md = MarkdownDocument::createFromStream($r);
+               $md->compile();
+               echo $md->getHtml();
+               fclose($r);
+               ml($file);
+       } else {
+               printf("<h1>Quick Markdown Doc Browser</h1>\n");
+               printf("<p>v0.1.0</p>\n");
+               printf("<p>");
+               ob_start(function($s) {
+                       return nl2br(htmlspecialchars($s));
+               });
+               readfile("LICENSE");
+               ob_end_flush();
+               printf("</p>\n");
+       }
+}
 
-       // BS Markdown seeks around...
-       fseek(OUTPUT, 0, SEEK_END);
-       
-       ml($file);
+
+function index($pn) {
+       ?>
+       <!doctype html>
+       <html>
+       <head>
+               <meta charset="utf-8">
+               <title><?=ns($pn)?></title>
+               <link rel="stylesheet" href="/index.css">
+       </head>
+       <body>
+               <div class="sidebar">
+                       <?php ls($pn); ?>
+               </div>
+               <?php md($pn); ?>
+               <script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script> 
+               <script src="/index.js"></script>
+       </body>
+       </html>
+       <?php
 }
 
+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;
 
 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")));
        $s->send();
        exit;
+default:
+       ob_start($s);
+       index(".".$u->path);
+       ob_end_flush();
+       $s->send();
+       break;
 }
 
-if (is_dir(".".$u->path)) {
-       ls(".".$u->path);
-} else {
-       md(".".$u->path);
-}
-
-?>
-<!doctype html>
-<html>
-<head>
-<meta charset="utf-8">
-<title><?=$u->path?></title>
-<link rel="stylesheet" href="/index.css">
-</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>
-</body>
-</html>