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);
}
}