From 33d1f049c4cdd3fa2bf4437875685d819e35fff4 Mon Sep 17 00:00:00 2001 From: Michael Wallner Date: Thu, 9 Sep 2021 15:18:46 +0200 Subject: [PATCH] generate static pages with league/commonmark --- bin/ref2html | 125 +++++++++++++++++++++++++++++++++++ composer.json | 19 +++--- mdref/Formatter.php | 20 ++++++ mdref/Formatter/Discount.php | 32 +++++++++ mdref/Formatter/League.php | 59 +++++++++++++++++ mdref/Reference.php | 37 +++-------- public/index.php | 9 +-- views/stub.phtml | 5 +- 8 files changed, 263 insertions(+), 43 deletions(-) create mode 100755 bin/ref2html create mode 100644 mdref/Formatter.php create mode 100644 mdref/Formatter/Discount.php create mode 100644 mdref/Formatter/League.php diff --git a/bin/ref2html b/bin/ref2html new file mode 100755 index 0000000..0ccc331 --- /dev/null +++ b/bin/ref2html @@ -0,0 +1,125 @@ +#!/usr/bin/env php + [ ...]\n", $argv[0]); + fprintf(STDERR, " Note: the basedir will also be used as \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); + exit(1); +} +$nul = fopen("/dev/null", "w"); +$url = new BaseUrl("/" . $out . "/"); +$url->scheme = null; +$url->host = null; +$ref = new Reference(array_slice($argv, 2)); +$fmt = function(string $src, string $dst) use($ref, $out, $nul, $url) { + $req = new Request; + $req->setRequestMethod("GET"); + $req->setRequestUrl($url . "./" . $src); + $res = new Response; + $res->setBody(new Body(fopen($dst, "w+"))); + $act = new Action($ref, $req, $res, $url, $nul); + $act->handle(); +}; +$xfm = [ + "php/PropertyProxy" => "propro/php/PropertyProxy", + "pq/Gateway" => "pq-gateway/pq/Gateway", + "pq/Query" => "pq-gateway/pq/Query", +]; +$red = function($from, $dest, $name) use($out, $url) { + $from = $out . "/" . str_replace($dest, $from, $name); + if (!is_dir(dirname($from))) { + mkdir(dirname($from), 0775, true); + } + file_put_contents($from . ".html", << + + + +EOF +); +}; +$gen = function(Entry $entry) use($fmt, $out, $xfm, $red, &$gen) { + $src = $entry->getName(); + $dir = $out . "/" . $src; + $dst = $dir . ".html"; + foreach ($xfm as $from => $dest) { + if (strpos($src, $dest) !== false) { + say("Redirecting from %s to %s\n", $from, $dest); + $red($from, $dest, $src); + break; + } + } + if ($entry->hasIterator()) { + if (!is_dir($dir)) { + mkdir($dir, 0755, true); + } + foreach ($entry as $subentry) { + $gen($subentry); + } + } + say("Generating %s from %s\n", $dst, $src); + $fmt($src, $dst); +}; +/** @var $repo Repo */ +foreach ($ref as $repo) { + say("Entering ref %s\n", $repo->getName()); + if (is_file($stub = $repo->getPath($repo->getName().".stub.php"))) { + copy($stub, $out . "/" . basename($stub)); + } + foreach ($repo as $root) { + $gen($root); + } +} +$fmt("", $out . "/" . "index.html"); + +$presets = [ + "AUTHORS", + "LICENSE", + "VERSION", + "public/index.css" => "index.css", + "public/index.js" => "index.js", + "public/favicon.ico" => "favicon.ico", +]; +foreach ($presets as $src => $dst) { + if (!is_string($src)) { + $src = $dst; + } + copy(ROOT . "/" . $src, $out . "/" . $dst); +} +// no jekyll +touch($out . "/.nojekyll"); +// htacess for apache +file_put_contents($out . "/.htaccess", << + ForceType text/x-php + SetHandler default-handler + + +EOF +); diff --git a/composer.json b/composer.json index b017f41..01de530 100644 --- a/composer.json +++ b/composer.json @@ -8,21 +8,24 @@ "email": "mike@php.net" } ], - "bin": ["bin/ref2stub"], + "bin": [ + "bin/ref2stub", + "bin/ref2html" + ], "autoload": { "psr-4": { "mdref\\": "mdref/" } }, "require": { - "php": "^7.3", - "ext-ctype": "^7.3", - "ext-http": "^3.2", - "ext-filter": "^7.3", - "ext-pcre": "^7.3" + "php": "^7.3 || ^8.0", + "ext-ctype": "*", + "ext-filter": "*", + "ext-pcre": "*", + "ext-http": "^3.2 || ^4.2", + "league/commonmark": "^2.0" }, "suggests": { - "ext-discount": "A Markdown renderer is needed, this is the preferred one.", - "ext-cmark": "A Markdown renderer is needed, this is the fallback one." + "ext-discount": "A Markdown renderer is needed, this is the preferred one." } } diff --git a/mdref/Formatter.php b/mdref/Formatter.php new file mode 100644 index 0000000..ecde240 --- /dev/null +++ b/mdref/Formatter.php @@ -0,0 +1,20 @@ +compile(\MarkdownDocument::AUTOLINK); + return $md->getHtml(); + } + + function formatFile(string $file) : string { + $fd = fopen($file, "r"); + if (!$fd) { + throw Exception::fromLastError(); + } + + $md = \MarkdownDocument::createFromStream($fd); + $md->compile(\MarkdownDocument::AUTOLINK | \MarkdownDocument::TOC); + $html = $md->getHtml(); + + fclose($fd); + + return $html; + } +} diff --git a/mdref/Formatter/League.php b/mdref/Formatter/League.php new file mode 100644 index 0000000..60ff7d4 --- /dev/null +++ b/mdref/Formatter/League.php @@ -0,0 +1,59 @@ +md = new GithubFlavoredMarkdownConverter([ + "slug_normalizer" => [ + "instance" => new class implements Normalizer\TextNormalizerInterface { + function normalize(string $text, $context = null) : string { + return preg_replace("/[^[:alnum:]:._-]/", ".", $text); + } + } + ], + "heading_permalink" => [ + "html_class" => "permalink", + "id_prefix" => "", + "fragment_prefix" => "", + "title" => "", + "symbol" => "#", + "insert" => "after", + "min_heading_level" => 2, + ] + ]); + $this->md->getEnvironment()->addExtension( + new Extension\DescriptionList\DescriptionListExtension + ); + $this->md->getEnvironment()->addExtension( + new Extension\HeadingPermalink\HeadingPermalinkExtension + ); + $this->md->getEnvironment()->addExtension( + new Extension\Attributes\AttributesExtension + ); + } + + function formatString(string $string) : string { + return $this->md->convertToHtml($string); + } + + function formatFile(string $file) : string { + $string = file_get_contents($file); + if ($string === false) { + throw Exception::fromLastError(); + } + return $this->md->convertToHtml($string); + } +} diff --git a/mdref/Reference.php b/mdref/Reference.php index 561bd1e..6e3b27e 100644 --- a/mdref/Reference.php +++ b/mdref/Reference.php @@ -18,14 +18,20 @@ class Reference implements IteratorAggregate { */ private $repos = array(); + /** + * @var Formatter + */ + private $fmt; + /** * @param array $refs list of mdref repository paths */ - public function __construct(array $refs) { + public function __construct(array $refs, Formatter $fmt = null) { foreach ($refs as $path) { $repo = new Repo($path); $this->repos[$repo->getName()] = $repo; } + $this->fmt = $fmt ?: Formatter::factory(); } /** @@ -66,39 +72,18 @@ class Reference implements IteratorAggregate { /** * @param string $string * @return string - * @throws \Exception + * @throws \Exception, Exception */ public function formatString(string $string) : string { - if (extension_loaded("discount")) { - $md = \MarkdownDocument::createFromString($string); - $md->compile(\MarkdownDocument::AUTOLINK); - return $md->getHtml(); - } - if (extension_loaded("cmark")) { - $node = \CommonMark\Parse($string); - return \CommonMark\Render\HTML($node); - } - throw new \Exception("No Markdown implementation found"); + return $this->fmt->formatString($string); } /** * @param string $file * @return string - * @throws \Exception + * @throws \Exception, Exception */ public function formatFile(string $file) : string { - if (extension_loaded("discount")) { - $fd = fopen($file, "r"); - $md = \MarkdownDocument::createFromStream($fd); - $md->compile(\MarkdownDocument::AUTOLINK | \MarkdownDocument::TOC); - $html = $md->getHtml(); - fclose($fd); - return $html; - } - if (extension_loaded("cmark")) { - $node = \CommonMark\Parse(file_get_contents($file)); - return \CommonMark\Render\HTML($node); - } - throw new \Exception("No Markdown implementation found"); + return $this->fmt->formatFile($file); } } diff --git a/public/index.php b/public/index.php index 2e43a16..65ad2d2 100644 --- a/public/index.php +++ b/public/index.php @@ -6,9 +6,6 @@ use http\Env\Request; use http\Env\Response; use function ini_get; use function ini_set; -use function spl_autoload_register; -use function strncmp; -use function strtr; use const GLOB_ONLYDIR; use const PATH_SEPARATOR; use const REFS; @@ -23,11 +20,7 @@ if (!ini_get("date.timezone")) { date_default_timezone_set("UTC"); } -spl_autoload_register(function($c) { - if (!strncmp($c, "mdref\\", 6)) { - return require ROOT . "/" . strtr($c, "\\", "/") . ".php"; - } -}); +require_once __DIR__ . "/../vendor/autoload.php"; $response = new Response; $ehandler = new ExceptionHandler($response); diff --git a/views/stub.phtml b/views/stub.phtml index 05679ab..140cd06 100644 --- a/views/stub.phtml +++ b/views/stub.phtml @@ -2,7 +2,11 @@

Download the Stub file:

- -- 2.30.2