export REFPATH
for p in {8000..8100}; do
- php -S localhost:$p -t . index.php && break
+ ${PHP:-php} -S localhost:$p -t . index.php && break
done
--- /dev/null
+#!/usr/bin/env php
+<?php
+
+define("ROOT", dirname(__DIR__));
+define("REFS", getenv("REFPATH") ?: implode(PATH_SEPARATOR, glob(ROOT."/refs/*")));
+
+#ini_set("open_basedir", ROOT.":".REFS);
+
+$loader = require ROOT . "/vendor/autoload.php";
+/* @var $loader \Composer\Autoload\ClassLoader */
+$loader->add("mdref", ROOT);
+
+$g = new mdref\Generator(REFS, @$argv[1]);
+$g->run();
$pld = new \stdClass;
try {
- $pld->quick = function($string) {
- $md = \MarkdownDocument::createFromString($string);
- $md->compile(\MarkdownDocument::AUTOLINK);
- return $md->getHtml();
- };
-
- $pld->file = function($file) {
- $fd = fopen($file, "r");
- $md = \MarkdownDocument::createFromStream($fd);
- $md->compile(\MarkdownDocument::AUTOLINK | \MarkdownDocument::TOC);
- $html = $md->getHtml();
- fclose($fd);
- return $html;
- };
+ $pld->quick = [$this->reference, "formatString"];
+ $pld->file = [$this->reference, "formatFile"];
$pld->ref = implode("/", $this->baseUrl->params(
$this->baseUrl->mod($ctl->getRequest()->getRequestUrl())));
--- /dev/null
+<?php
+
+namespace mdref;
+
+/**
+ * Static mdref generator
+ */
+class Generator
+{
+ /**
+ * @var \mdref\Reference
+ */
+ private $reference;
+
+ /**
+ * @var \mdref\Generator\Renderer
+ */
+ private $renderer;
+
+ /**
+ * Create a new generator
+ * @param string $refs list of reference paths
+ * @param string $dir output directory
+ */
+ public function __construct($refs, $dir = null) {
+ $this->reference = new Reference(explode(PATH_SEPARATOR, $refs));
+ $this->renderer = new Generator\Renderer($dir ?: "public/static");
+ }
+
+ /**
+ * Run the generator
+ */
+ public function run() {
+ $this->generateRoot();
+ foreach ($this->reference as $repo) {
+ $iter = new \RecursiveIteratorIterator($repo,
+ \RecursiveIteratorIterator::SELF_FIRST);
+ foreach ($iter as $ref) {
+ $this->generateEntry($ref);
+ }
+ }
+ }
+
+ /**
+ * Generate index.html and LICENSE.html
+ */
+ private function generateRoot() {
+ printf("Generating index ...\n");
+ $data = $this->createPayload(null);
+ $data->ref = "index";
+ $this->renderer->persist($data);
+
+ printf("Generating LICENSE ...\n");
+ $data->text = file_get_contents(__DIR__."/../LICENSE");
+ $data->ref = "LICENSE";
+ $this->renderer->persist($data);
+ }
+
+ /**
+ * Generate HTML for an entry
+ * @param \mdref\Entry $ref
+ */
+ private function generateEntry(Entry $ref) {
+ printf("Generating %s ...\n", $ref->getName());
+ $data = $this->createPayload($ref);
+ $this->renderer->persist($data);
+ }
+
+ /**
+ * Create the view payload
+ * @param \mdref\Entry $ref
+ * @param \mdref\Generator\Renderer $view
+ * @return \stdClass
+ */
+ private function createPayload(Entry $ref = null) {
+ $pld = new \stdClass;
+
+ $pld->quick = [$this->reference, "formatString"];
+ $pld->file = [$this->reference, "formatFile"];
+ $pld->refs = $this->reference;
+ $pld->view = $this->renderer;
+ if ($ref) {
+ $pld->entry = $ref;
+ $pld->ref = $ref->getName();
+ }
+
+ return $pld;
+ }
+}
+
+namespace mdref\Generator;
+
+class Renderer
+{
+ /**
+ * @var string
+ */
+ private $dir;
+
+ /**
+ * @param string $dir output directory
+ */
+ public function __construct($dir = "public/static") {
+ $this->dir = $dir;
+ }
+
+ /**
+ * HTML entity encode special characters
+ * @param string $string
+ * @return string
+ */
+ public function esc($string) {
+ return htmlspecialchars($string);
+ }
+
+ /**
+ * Render mdref page
+ * @param \stdClass $pld
+ * @return string
+ */
+ public function render(\stdClass $pld) {
+ $content = "";
+ ob_start(function($data) use(&$content) {
+ $content .= $data;
+ return true;
+ });
+ static::renderFile("views/layout.phtml", (array) $pld);
+ ob_end_flush();
+ return $content;
+ }
+
+ /**
+ * Persist mdref page to output directory
+ * @param \stdClass $data
+ */
+ public function persist(\stdClass $data) {
+ $html = $this->render($data);
+ $file = sprintf("%s/%s.html", $this->dir, $data->ref);
+ $this->saveFile($file, $html);
+ $this->linkIndex(dirname($file));
+ }
+
+ /**
+ * Save data to file (write to $file.tmp and rename to $file)
+ * @param string $file
+ * @param string $data
+ * @throws \Exception
+ */
+ private function saveFile($file, $data) {
+ $dir = dirname($file);
+ if (!is_dir($dir) && !mkdir($dir, 0755, true)) {
+ throw new \Exception("Failed to create directory '$dir'");
+ }
+ if (!file_put_contents("$file.tmp", $data)) {
+ throw new \Exception("Failed to save file '$file.tmp'");
+ }
+ if (!rename("$file.tmp", $file)) {
+ throw new \Exception("Failed to rename to '$file'");
+ }
+ }
+
+ private function linkIndex($dir) {
+ $index = "$dir.html";
+ $link = "$dir/index.html";
+ if (is_file($index) && !is_file($link)) {
+ printf("Generating index for '%s'\n", substr($dir, strlen($this->dir)));
+ link($index, $link);
+ }
+ }
+
+ /**
+ * Render file
+ */
+ static private function renderFile() {
+ if (func_num_args() > 1) {
+ extract(func_get_arg(1));
+ }
+ include func_get_arg(0);
+ }
+}
public function getIterator() {
return new \ArrayIterator($this->repos);
}
+
+ public function formatString($string) {
+ $md = \MarkdownDocument::createFromString($string);
+ $md->compile(\MarkdownDocument::AUTOLINK);
+ return $md->getHtml();
+ }
+ public function formatFile($file) {
+ $fd = fopen($file, "r");
+ $md = \MarkdownDocument::createFromStream($fd);
+ $md->compile(\MarkdownDocument::AUTOLINK | \MarkdownDocument::TOC);
+ $html = $md->getHtml();
+ fclose($fd);
+ return $html;
+ }
}
+DirectorySlash Off
RewriteEngine On
+RewriteRule ^static.*\.html - [L]
+RewriteRule ^(static/.+) $1.html [L]
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d [OR]
RewriteCond %{REQUEST_FILENAME} -l
color: #eee;
}
-p, pre, table {
+p, pre, table, dl {
margin: 1em 2em;
}
th, td {
padding: .4em;
}
-
+dt {
+ font-weight: bold;
+ margin-top: 1em;
+}
+dd {
+ line-height: 1.2em;
+ margin-left: 1em;
+}
h1, footer, table, .sidebar, pre>code, li h3 {
box-shadow: 0 0 4px #708090;
}
return "<a href=\"" + s.replace(/::|\\/g, "/") + "\">";
}
}
- if (-1 !== (j = s.indexOf("\\")) && s.substr(j+1,1) !== "n") {
- return "<a href=\"" + s.replace(/\\/g, "/").replace(/::|$/, "#") + "\">";
+ if (-1 !== (j = s.lastIndexOf("\\")) && s.substr(j+1,1) !== "n") {
+ t = s.substring(j+1);
+ if (!mdref.is_constant(t)) {
+ return "<a href=\"" + s.replace(/\\/g, "/").replace(/::|$/, "#") + "\">";
+ }
+ return "<a href=\"" + s.substring(0,j).replace(/\\/g, "/") + "#" + t + "\">";
}
switch (s.toLowerCase()) {
<?php endif; ?>
mdref
</title>
- <base href="<?= $baseUrl ?>">
- <meta http-equiv="Content-Location" content="<?= $baseUrl . $ref ?>">
- <link rel="stylesheet" href="index.css">
+ <?php if (isset($baseUrl)) : ?>
+ <base href="<?= $baseUrl ?>">
+ <meta http-equiv="Content-Location" content="<?= $baseUrl . $ref ?>">
+ <link rel="stylesheet" href="index.css">
+ <?php else: ?>
+ <style type="text/css">
+ <?= file_get_contents(__DIR__."/../public/index.css"); ?>
+ </style>
+ <?php endif; ?>
+
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
</head>
<body>
<?php include __DIR__."/index.phtml" ?>
<?php endif; ?>
- <?php if ($_SERVER["SERVER_NAME"] != "localhost") : ?>
+ <?php if (@$_SERVER["SERVER_NAME"] != "localhost") : ?>
<div id="disqus_thread"></div>
<script>
var disqus_shortname = 'mdref';
<footer>
<?php include __DIR__."/footer.phtml" ?>
</footer>
- <script src="index.js"></script>
+ <?php if (isset($baseUrl)) : ?>
+ <script src="index.js"></script>
+ <?php else : ?>
+ <script type="application/javascript">
+ <?= file_get_contents(__DIR__."/../public/index.js"); ?>
+ </script>
+ <?php endif; ?>
</body>
</html>
<div class="sidebar">
+ <?php
+ if (isset($baseUrl) || !isset($entry)) {
+ $up = "";
+ } else {
+ $up = str_repeat("../", count($entry->getParents()));
+ }
+ ?>
<ul>
- <li>↰ <a href="">Home</a>
+ <li>↰ <a href="<?= $up ?>">Home</a>
<?php if (isset($entry)) : /* @var \mdref\Entry $entry */ ?>
<ul>
<li>
<?php foreach ($entry->getParents() as $parent) if ($parent->isFile()) : ?>
↑
- <a href="<?= $view->esc($parent->getName()) ?>">
+ <a href="<?= $up.$view->esc($parent->getName()) ?>">
<?= $view->esc($entry->getRepo()->getEntry($parent)) ?>
</a>
<ul>
<li>
<?php endif; ?>
- ↻ <a href="<?= $view->esc($entry->getName()) ?>"
+ ↻ <a href="<?= $up.$view->esc($entry->getName()) ?>"
><?= $view->esc($entry) ?></a>
<ul>
<?php foreach ($entry as $sub) : /* @var \mdref\Entry $sub */ ?>
<li>
- ↳ <a href="<?= $view->esc($sub->getName()) ?>"
+ ↳ <a href="<?= $up.$view->esc($sub->getName()) ?>"
><?= $view->esc($sub) ?></a>
</li>
<?php endforeach; ?>
</ul>
<?php if (isset($entry)) : ?>
<div class="edit">
- <a href="<?=$entry->getEditUrl()?>">Edit</a>
+ <a href="<?= $entry->getEditUrl() ?>">Edit</a>
</div>
<?php endif; ?>
</div>