fix wrapper->fmt calls
[mdref/mdref] / mdref / Generator.php
index 7a58387e122ae371a9f3f7022eea63354cd4ae55..8cd96bd96215e0f54e4e61c865ac44a980c2f1a8 100644 (file)
 
 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");
+use mdref\Generator\{Cls, Func};
+
+class Generator {
+       protected string $destination;
+
+       public function __construct(string $destination = ".") {
+               $this->destination = $destination;
        }
-       
+
        /**
-        * 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);
+        * @param array<string, array<string, \ReflectionFunctionAbstract>> $functions
+        * @return void
+        */
+       public function generateFunctions(array $functions) : void {
+               foreach ($functions as $ns => $funcs) {
+                       $ns_path = $this->destination . "/" . strtr($ns, "\\", "/");
+                       foreach ($funcs as $fn => $rf) {
+                               $fn_file = "$ns_path/$fn.md";
+                               fprintf(STDERR, "Generating %s\n", $fn_file);
+                               is_dir($ns_path) || mkdir($ns_path, 0770, true);
+                               file_put_contents($fn_file, new Func($this, $rf));
                        }
                }
        }
-       
-       /**
-        * 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();
+        * @param array<string, array<string, \ReflectionClass>> $classes
+        * @return void
+        */
+       public function generateClasses(array $classes) : void {
+               foreach ($classes as $ns => $cls) {
+                       $ns_path = $this->destination . "/" . strtr($ns, "\\", "/");
+                       foreach ($cls as $cn => $rc) {
+                               $cn_path = "$ns_path/$cn";
+                               $cn_file = "$cn_path.md";
+                               fprintf(STDERR, "Generating %s\n", $cn_file);
+                               is_dir($ns_path) || mkdir($ns_path, 0770, true);
+                               file_put_contents($cn_file, new Cls($this, $rc));
+                               $this->generateMethods($rc);
+                       }
                }
-               
-               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));
+       private function generateMethods(\ReflectionClass $rc) : void {
+               $funcs = [];
+               foreach ($rc->getMethods(\ReflectionMethod::IS_PUBLIC) as $rm) {
+                       if ($rm->getDeclaringClass()->getName() === $rc->getName()) {
+                               foreach ($rc->getInterfaces() as $ri) {
+                                       if ($ri->hasMethod($rm->getName())) {
+                                               continue 2;
+                                       }
+                               }
+                               $funcs[$rc->getName()][$rm->getName()] = $rm;
+                       }
                }
-               include func_get_arg(0);
+               $this->generateFunctions($funcs);
        }
 }