From: Michael Wallner Date: Fri, 13 Dec 2013 09:42:31 +0000 (+0100) Subject: convert to autocracy X-Git-Url: https://git.m6w6.name/?a=commitdiff_plain;h=e49b8a277a69f2b1e1d90a0f7607b08bbf972da2;p=mdref%2Fmdref convert to autocracy --- diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..67bbd91 --- /dev/null +++ b/AUTHORS @@ -0,0 +1 @@ +Michael Wallner diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..816ff40 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +Copyright (c) 2013, Michael Wallner . +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. + diff --git a/mdref/Action.php b/mdref/Action.php new file mode 100644 index 0000000..223e532 --- /dev/null +++ b/mdref/Action.php @@ -0,0 +1,41 @@ +getPayload(); + $request = $ctl->getRequest(); + + $finder = new Finder($this->baseUrl, REFS); + $url = new \http\Url($request->getRequestUrl()); + if (!$path = $finder->find($url)) { + $path = new Path; + } + + $payload->baseUrl = $this->baseUrl; + $payload->requestUrl = $url; + + $payload->listing = new RefListing($path, + $finder->glob($path, "/[_a-zA-Z]*.md")); + + if ($path->isFile()) { + $payload->markdown = new Markdown($path); + $payload->sublisting = new RefListing($path, + $finder->glob($path, "/[_a-z]*.md")); + } else if ($path($url)->isFile("")) { + $payload->markdown = $path->toHtml(); + } else if (strcmp($url, $this->baseUrl)) { + throw new \http\Controller\Exception(404, "Could not find '$url'"); + } + } catch (\Exception $e) { + $payload->baseUrl = $this->baseUrl; + $ctl->getPayload()->exception = $e; + } + } +} diff --git a/mdref/ExceptionHandler.php b/mdref/ExceptionHandler.php new file mode 100644 index 0000000..d184ea0 --- /dev/null +++ b/mdref/ExceptionHandler.php @@ -0,0 +1,47 @@ +getCode() ?: 500; + foreach ($e->getHeaders() as $key => $val) { + HTTP::sendResponseHeader($key, $val); + } + } else { + $code = 500; + } + HTTP::setResponseCode($code); + $name = HTTP::getResponseStatusForCode($code); + $html = sprintf("<%s>%s\n<%s>%s\n", + implode(" ", $title_tag), $name, $title_tag[0], + implode(" ", $message_tag), $e->getMessage(), $message_tag[0]); + if ($trace_tag) { + $html .= sprintf("<%s>%s\n", + implode(" ", $trace_tag), $e->getTraceAsString(), $trace_tag[0]); + } + return $html; + } +} \ No newline at end of file diff --git a/mdref/Finder.php b/mdref/Finder.php new file mode 100644 index 0000000..9d1c64c --- /dev/null +++ b/mdref/Finder.php @@ -0,0 +1,59 @@ +refs = $paths; + $this->baseUrl = $baseUrl; + } + + /** + * @param \http\Url $requestUrl + * @return Path + */ + function find(\http\Url $requestUrl) { + $file = implode(DIRECTORY_SEPARATOR, + $this->baseUrl->params($requestUrl)); + + foreach ($this->refs as $base) { + $path = new Path($base, $file); + if ($path->isFile()) { + return $path; + } + } + } + + function glob(Path $path, $pattern, $flags = GLOB_BRACE) { + if (strlen($path->getBaseDir())) { + return glob($path->getFullPath($pattern), $flags); + } + $glob = array(); + foreach ($this->refs as $ref) { + $glob = array_merge($glob, array_map(function ($fn) use ($ref) { + return substr($fn, strlen($ref)); + }, glob($ref . $pattern, $flags))); + } + return $glob; + } +} diff --git a/mdref/Markdown.php b/mdref/Markdown.php new file mode 100644 index 0000000..6d761c2 --- /dev/null +++ b/mdref/Markdown.php @@ -0,0 +1,34 @@ +path = $path; + } + + /** + * @return string + */ + function __toString() { + try { + $r = fopen($this->path->getFullPath(".md"), "r"); + $md = \MarkdownDocument::createFromStream($r); + $md->compile(\MarkdownDocument::AUTOLINK | \MarkdownDocument::TOC); + $html = $md->getHtml(); + fclose($r); + } catch (\Exception $e) { + $html = ExceptionHandler::html($e); + } + return $html; + } +} diff --git a/mdref/Path.php b/mdref/Path.php new file mode 100644 index 0000000..b9212d2 --- /dev/null +++ b/mdref/Path.php @@ -0,0 +1,61 @@ +baseDir = $baseDir; + $this->path = $path; + } + + function __invoke($path) { + $that = clone $this; + $that->path = $path; + return $that; + } + + function __toString() { + return $this->getFullPath(); + } + + function getBaseDir() { + return $this->baseDir; + } + + function getPathName() { + return $this->path; + } + + function getFullPath($ext = "") { + return $this->baseDir . DIRECTORY_SEPARATOR . $this->path . $ext; + } + + function getSubPath($path) { + return trim(substr($path, strlen($this->baseDir)), DIRECTORY_SEPARATOR); + } + + function isFile($ext = ".md") { + return is_file($this->getFullPath($ext)); + } + + function toHtml() { + if ($this->isFile()) { + return htmlspecialchars(file_get_contents($this->getFullPath())); + } elseif ($this->isFile("")) { + return htmlspecialchars(file_get_contents($this->getFullPath(""))); + } + } +} \ No newline at end of file diff --git a/mdref/RefEntry.php b/mdref/RefEntry.php new file mode 100644 index 0000000..f88b43f --- /dev/null +++ b/mdref/RefEntry.php @@ -0,0 +1,95 @@ +path = $path; + $this->entry = $entry ?: $path->getPathName(); + } + + function __destruct() { + if (is_resource($this->file)) { + fclose($this->file); + } + } + + function formatUrl() { + return htmlspecialchars($this->entry); + return implode("/", explode(DIRECTORY_SEPARATOR, trim(substr( + $this->entry, strlen($this->path->getBaseDir())), + DIRECTORY_SEPARATOR))); + } + + protected function joinLink(array $parts) { + $link = ""; + $upper = ctype_upper($parts[0][0]);; + for ($i = 0; $i < count($parts); ++$i) { + if (!strlen($parts[$i]) || $parts[$i] === ".") { + continue; + } + if (strlen($link)) { + if ($upper && !ctype_upper($parts[$i][0])) { + $link .= "::"; + } else { + $link .= "\\"; + } + } + $link .= $parts[$i]; + $upper = ctype_upper($parts[$i][0]); + } + return $link; + } + + function formatLink($basename = false) { + $link = ""; + if (strlen($entry = trim($this->entry, DIRECTORY_SEPARATOR))) { + $parts = explode(DIRECTORY_SEPARATOR, $entry); + $link = $basename ? end($parts) : $this->joinLink($parts); + } + return htmlspecialchars($link); + } + + protected function openFile() { + if (!is_resource($this->file)) { + $path = $this->path; + $file = $path($this->entry); + if (!$file->isFile()) { + throw new \Exception("Not a file: '$this->entry'"); + } + if (!$this->file = fopen($file->getFullPath(".md"), "r")) { + throw new \Exception("Could not open {$this->entry}"); + } + } + } + + function readTitle() { + $this->openFile(); + fseek($this->file, 1, SEEK_SET); + return htmlspecialchars(fgets($this->file)); + } + + function readDescription() { + $this->openFile(); + fseek($this->file, 0, SEEK_SET); + fgets($this->file); + fgets($this->file); + return htmlspecialchars(fgets($this->file)); + } +} \ No newline at end of file diff --git a/mdref/RefListing.php b/mdref/RefListing.php index 542a3ff..d718090 100644 --- a/mdref/RefListing.php +++ b/mdref/RefListing.php @@ -1,8 +1,111 @@ path = $path; + $this->entries = array_map(function($fn) { + return substr(trim($fn, DIRECTORY_SEPARATOR), 0, -3); + }, $files); + } + + /** + * Copy constructor + * @param mixed $filter callable array filter or fnmatch pattern + * @return \mdref\RefListing + */ + function __invoke($filter) { + die(__METHOD__); + $that = clone $this; + $that->entries = array_filter($that->entries, is_callable($filter) + ? $filter + : function($fn) use ($filter) { + return fnmatch($filter, $fn); + } + ); + return $that; + } + + function __toString() { + return __METHOD__; + return $this->format(substr($this->path, strlen($this->path->getBaseDir()))); + } + + function count() { + return count($this->entries); + } + + function rewind() { + reset($this->entries); + } + + function valid() { + return null !== key($this->entries); + } + + function key() { + return $this->path->getSubPath(current($this->entries)); + } + + function next() { + next($this->entries); + } + + function current() { + return new RefEntry($this->path, $this->key());//$this->format($this->key()); + } + + function getParent() { + switch ($parent = dirname($this->path->getPathName())) { + case ".": + case "": + return null; + default: + return new RefEntry($this->path, $parent); + } + } + + function getSelf() { + return new RefEntry($this->path); + } + + function format($entry) { + return __METHOD__; + $ns = ""; + if (strlen($entry = trim($entry, DIRECTORY_SEPARATOR))) { + $upper = ctype_upper($entry[0]); + $parts = explode(DIRECTORY_SEPARATOR, $entry); + + 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; } } \ No newline at end of file diff --git a/mdref/controllers/AppController.php b/mdref/controllers/AppController.php deleted file mode 100644 index cb09d8f..0000000 --- a/mdref/controllers/AppController.php +++ /dev/null @@ -1,15 +0,0 @@ -payload->title = "mdref"; - $this->payload->listing = 123; - } -} \ No newline at end of file diff --git a/mdref/controllers/IndexController.php b/mdref/controllers/IndexController.php deleted file mode 100644 index 771de9f..0000000 --- a/mdref/controllers/IndexController.php +++ /dev/null @@ -1,9 +0,0 @@ - - - - - <?= $title ?> - - - - - - - - - -
- - - - - diff --git a/public/.htaccess b/public/.htaccess new file mode 100644 index 0000000..affb2a0 --- /dev/null +++ b/public/.htaccess @@ -0,0 +1,6 @@ +RewriteEngine On +RewriteCond %{REQUEST_FILENAME} -f [OR] +RewriteCond %{REQUEST_FILENAME} -d [OR] +RewriteCond %{REQUEST_FILENAME} -l +RewriteRule ^ - [L] +RewriteRule ^ index.php [L] diff --git a/public/index.css b/public/index.css index a48ac00..754f96c 100644 --- a/public/index.css +++ b/public/index.css @@ -32,6 +32,7 @@ body>ul { } .sidebar ul { margin-left: 1em; + margin-top: .5em; padding: 0; list-style-type: none; } @@ -160,3 +161,11 @@ footer li { display: inline-block; margin: 0 1em; } + +footer a { + text-decoration: none; +} + +footer a:hover { + text-decoration: underline; +} \ No newline at end of file diff --git a/public/index.php b/public/index.php index 649bb0a..d4518cd 100644 --- a/public/index.php +++ b/public/index.php @@ -1,32 +1,25 @@ add("controllers", __DIR__ . "/../mdref"); +$loader->add("mdref", ROOT); use http\Controller; use http\Controller\Url; - -use http\Controller\Observer\Callback; -use http\Controller\Observer\Params; -use http\Controller\Observer\Action; -use http\Controller\Observer\View; use http\Controller\Observer\Layout; +use mdref\ExceptionHandler; +use mdref\Action; -$url = new Url; +new ExceptionHandler; $ctl = new Controller; -$ctl->setDependency("baseUrl", $url); - -$ctl->attach(new Params\Action); -$ctl->attach(new Action(["controllerPrefix" => "controllers\\"])); -$ctl->attach(new Callback(function(\http\Controller $ctl) use ($url) { - $ctl->getPayload()->baseUrl = $url; -})); -$ctl->attach(new View(["directory" => __DIR__ . "/../mdref/views"])); -$ctl->attach(new Layout(["directory" => __DIR__ . "/../mdref/views"])); - -$response = $ctl->notify()->getResponse(); -$response->send(); +$ctl->setDependency("baseUrl", new Url) + ->attach(new Action) + ->attach(new Layout) + ->notify() + ->getResponse() + ->send(); diff --git a/views/layout.phtml b/views/layout.phtml new file mode 100644 index 0000000..69c9727 --- /dev/null +++ b/views/layout.phtml @@ -0,0 +1,27 @@ + + + + + <?= $title ?> + + + + + + + + + +
+ + + + +