X-Git-Url: https://git.m6w6.name/?a=blobdiff_plain;f=mdref%2FTree.php;h=fc12a1c4233713fcc2535d3a30b63ce261a216a4;hb=5573dd409e834ec676570cbb4b00a217cb4464b9;hp=dd27d6fd0f94ca8616031f1127a3d14a38f0ac59;hpb=d2f3d65b1f3b75da3c182f835883681dd6eef918;p=mdref%2Fmdref diff --git a/mdref/Tree.php b/mdref/Tree.php index dd27d6f..fc12a1c 100644 --- a/mdref/Tree.php +++ b/mdref/Tree.php @@ -2,114 +2,175 @@ namespace mdref; -class Tree implements \RecursiveIterator { +use Iterator; +use RecursiveIterator; +use function array_filter; +use function array_search; +use function basename; +use function current; +use function dirname; +use function glob; +use function is_dir; +use function key; +use function next; +use function pathinfo; +use function preg_match; +use function reset; +use function strcmp; +use function usort; + +class Tree implements RecursiveIterator { /** * The repository * @var \mdref\Repo */ private $repo; - + /** * List of first level entries * @var array */ private $list = array(); - + /** * The list iterator * @var array */ private $iter; - + /** * @param string $path * @param \mdref\Repo $repo */ - public function __construct($path, Repo $repo) { - if (!($list = glob("$path/*.md"))) { + public function __construct(string $path, Repo $repo) { + if (realpath($path)."/" === $repo->getPath()) { + $list = [$path ."/". $repo->getName() .".md"]; + } elseif (!($list = glob("$path/*.md"))) { $list = glob("$path/*/*.md"); } if ($list) { $this->list = array_filter($list, $this->generateFilter($list)); - sort($this->list, SORT_STRING); + usort($this->list, $this->generateSorter()); } $this->repo = $repo; } - + /** * @param array $list * @return callable */ - private function generateFilter(array $list) { + private function generateFilter(array $list) : \Closure { return function($v) use($list) { - if ($v{0} === ".") { + if ($v[0] === ".") { return false; } if (false !== array_search("$v.md", $list, true)) { return false; } - + $pi = pathinfo($v); if (isset($pi["extension"]) && "md" !== $pi["extension"]) { return false; } - + return true; }; } + /** + * @return callable + */ + private function generateSorter() : \Closure { + return function($a, $b) { + $ab = basename($a, ".md"); + $bb = basename($b, ".md"); + + if ($ab[0] === ":" && $bb[0] === ":") { + return strcmp($ab, $bb); + } elseif ($ab[0] === ":") { + return -1; + } elseif ($bb[0] === ":") { + return 1; + } + + $ad = is_dir(dirname($a)."/$ab"); + $bd = is_dir(dirname($b)."/$bb"); + + if ($ad && $bd) { + return strcmp($ab, $bb); + } elseif ($ad) { + return -1; + } elseif ($bd) { + return 1; + } + + $au = preg_match("/^\p{Lu}/", $ab); + $bu = preg_match("/^\p{Lu}/", $bb); + + if ($au && $bu) { + return strcmp($ab, $bb); + } elseif ($au) { + return -1; + } elseif ($bu) { + return 1; + } + + return strcmp($ab, $bb); + }; + } + /** * Implements \Iterator * @return \mdref\Entry */ - public function current() { + public function current() : Entry { return $this->repo->getEntry($this->repo->hasFile(current($this->iter))); } - + /** * Implements \Iterator */ - public function next() { + public function next() : void { next($this->iter); } - + /** * Implements \Iterator * @return int */ - public function key() { + public function key() : int { return key($this->iter); } - + /** * Implements \Iterator */ - public function rewind() { + public function rewind() : void { $this->iter = $this->list; reset($this->iter); } - + /** * Implements \Iterator * @return bool */ - public function valid() { + public function valid() : bool { return null !== key($this->iter); } - + /** * Implements \RecursiveIterator * @return bool */ - public function hasChildren() { + public function hasChildren() : bool { return $this->current()->hasIterator(); } - + /** * Implements \RecursiveIterator * @return \mdref\Tree */ - public function getChildren() { + public function getChildren() : Iterator { return $this->current()->getIterator(); } }