402 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			402 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
<?php
 | 
						|
 | 
						|
    namespace WMarkDown;
 | 
						|
 | 
						|
    class ScriptsAnalyzer{
 | 
						|
 | 
						|
        private $wmarkdown = null;
 | 
						|
        private $ignore = [];
 | 
						|
        private $root = null;
 | 
						|
        private $root_l = 0;
 | 
						|
        private $original_wmd = null;
 | 
						|
        private $file_wmd = null;
 | 
						|
        private $common = [];
 | 
						|
        private $class = null;
 | 
						|
        private $object = null;
 | 
						|
        private $only = null;
 | 
						|
        private static $types = [
 | 
						|
            "__construct" => "constructor",
 | 
						|
            "__init__" => "constructor",
 | 
						|
            "__destruct" => "destructor",
 | 
						|
            "__del__" => "destructor",
 | 
						|
            "object" => "objeto",
 | 
						|
            "static" => "estático",
 | 
						|
            "classmethod" => "de clase",
 | 
						|
            "staticmethod" => "estático"
 | 
						|
        ];
 | 
						|
        private static $languages = [
 | 
						|
            "php" => "PHP",
 | 
						|
            "python" => "Python",
 | 
						|
            "js" => "JavaScript",
 | 
						|
            "ecma" => "ECMAScript",
 | 
						|
            "mariadb" => "MariaDB",
 | 
						|
            "transact_sql" => "Transact SQL",
 | 
						|
            "sql_lite" => "SQLite",
 | 
						|
            "c_sharp" => "C#"
 | 
						|
        ];
 | 
						|
        private static $classes = [
 | 
						|
            "php" => "PHP",
 | 
						|
            "js" => "JS",
 | 
						|
            "cs" => "CSharp",
 | 
						|
            "py" => "Python",
 | 
						|
            "sql" => "SQL"
 | 
						|
        ];
 | 
						|
        private static $languages_with_overloads = ["C#"];
 | 
						|
        private static $languages_typed = ["SQLite", "Transact SQL", "MariaDB", "C#"];
 | 
						|
        private static $languages_with_status = ["PHP", "Python", "SQLite", "Transact SQL", "MariaDB", "C#"];
 | 
						|
        public $php;
 | 
						|
        public $js;
 | 
						|
        public $sql;
 | 
						|
        public $py;
 | 
						|
        public $cs;
 | 
						|
 | 
						|
        public function __construct($wmarkdown, $input = []){
 | 
						|
 | 
						|
            $date = date("Ymd");
 | 
						|
 | 
						|
            $this->wmarkdown = $wmarkdown;
 | 
						|
            $this->ignore = $this->wmarkdown->get_ignore_file_paths();
 | 
						|
            $this->root_l = strlen($this->root = $this->wmarkdown->get_root());
 | 
						|
            $this->original_wmd = file_exists($path = $this->wmarkdown->settings("wmd_file")) ? file_get_contents($path) : null;
 | 
						|
            $this->file_wmd = file_exists($path = $this->wmarkdown->settings("wmd_file_empty")) ? file_get_contents($path) : null;
 | 
						|
            $this->class = $this->wmarkdown->settings("class");
 | 
						|
            $this->object = $this->wmarkdown->settings("object");
 | 
						|
            $this->common = [
 | 
						|
                "author" => $this->wmarkdown->settings("author"),
 | 
						|
                "project" => $this->wmarkdown->settings("project"),
 | 
						|
                "url" => $this->wmarkdown->settings("url"),
 | 
						|
                "project_author" => $this->wmarkdown->settings("project_author"),
 | 
						|
                "key_words" => $this->wmarkdown->settings("key_words"),
 | 
						|
                "language" => $this->wmarkdown->settings("language"),
 | 
						|
                "logo" => $this->wmarkdown->settings("logo"),
 | 
						|
                "since" => $date,
 | 
						|
                "version" => $date
 | 
						|
            ];
 | 
						|
            $this->only = $this->wmarkdown->settings("only");
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        public static function get_content($file, $path){
 | 
						|
            return file_exists($subpath = $path . "/" . $file) ? file_get_contents($subpath) : null;
 | 
						|
        }
 | 
						|
 | 
						|
        public function get_wmd_path($file, $path){
 | 
						|
            return $this->root . "/WMD/dev" . substr($path . "/" . $file, $this->root_l) . ".w.md";
 | 
						|
        }
 | 
						|
 | 
						|
        private function write($file, $path, $content){
 | 
						|
            file_put_contents($content, $this->get_wmd_path($file, $path));
 | 
						|
        }
 | 
						|
 | 
						|
        private static function get_properties($value){
 | 
						|
 | 
						|
            preg_match('/^\#([^\s\t\\\\]+)((\\\\t)+|[\s\t]+)+([^\s\t\\\\]+)((\\\\t)+|[\s\t]+)+([^\s\t\\\\]+)/', $value, $matches, PREG_OFFSET_CAPTURE);
 | 
						|
 | 
						|
            return [$matches[1][0], $matches[4][0], $matches[7][0]];
 | 
						|
        }
 | 
						|
 | 
						|
        private static function get_attributes($wdoc){
 | 
						|
 | 
						|
            $see = [];
 | 
						|
            $language = null;
 | 
						|
            $access = null;
 | 
						|
            $parameters = [];
 | 
						|
            $return = null;
 | 
						|
            $parameters_full = [];
 | 
						|
            $hash = null;
 | 
						|
 | 
						|
            preg_replace_callback('/^([\#\@])([^\s]+)\s+([^\r\n]+)/m', function($values) use(&$see, &$language, &$access, &$parameters, &$return, &$parameters_full, &$hash){
 | 
						|
                if($values[1] == "#"){
 | 
						|
                    if($values[2] == "return")
 | 
						|
                        $return = true;
 | 
						|
                    else{
 | 
						|
                        $parameters[] = $values[2];
 | 
						|
                        $parameters_full[] = $values[0];
 | 
						|
                    };
 | 
						|
                }else{
 | 
						|
                    switch($values[2]){
 | 
						|
                        case "lang":
 | 
						|
                            $language = $values[3];
 | 
						|
                        break;
 | 
						|
                        case "see":
 | 
						|
                            $see[] = $values[3];
 | 
						|
                        break;
 | 
						|
                        case "access":
 | 
						|
                            $access = $values[3];
 | 
						|
                        break;
 | 
						|
                        case "hash":
 | 
						|
                            $hash = $values[3];
 | 
						|
                        break;
 | 
						|
                    };
 | 
						|
                };
 | 
						|
            }, $wdoc);
 | 
						|
 | 
						|
            return [
 | 
						|
                "see" => $see,
 | 
						|
                "language" => $language,
 | 
						|
                "access" => $access,
 | 
						|
                "parameters" => $parameters,
 | 
						|
                "return" => $return,
 | 
						|
                "parameters_full" => $parameters_full,
 | 
						|
                "hash" => $hash
 | 
						|
            ];
 | 
						|
        }
 | 
						|
 | 
						|
        private static function set_parameter($parameter){
 | 
						|
            return "#" . (is_string($parameter) ? $parameter = ["name" => $parameter] : $parameter)["name"] . "\t" . (empty($parameter["type"]) ? "-" : $parameter["type"]) . " " . (empty($parameter["default"]) ? "optional" : "required") . " Parámetro " . $parameter["name"] . "\n";
 | 
						|
        }
 | 
						|
 | 
						|
        private static function set_return($return){
 | 
						|
            if(is_bool($return) || is_integer($return))
 | 
						|
                return $return ? "#return\t- - Retorno.\n" : "";
 | 
						|
            if(is_string($return))
 | 
						|
                return $return ? "#return\t" . $return . " - Retorno.\n" : "";
 | 
						|
            return "";
 | 
						|
        }
 | 
						|
 | 
						|
        private function update_wdoc(&$wdoc, $current, $new){
 | 
						|
 | 
						|
            $parameters = [];
 | 
						|
            $l = 0;
 | 
						|
            $last_parameter = null;
 | 
						|
            $return = null;
 | 
						|
            $parameters_final = [];
 | 
						|
            $m = count($current["parameters"]);
 | 
						|
 | 
						|
            if(preg_match('/^(\#([^\r\n]+)[\r\n]+)+/m', $wdoc, $parameters, PREG_OFFSET_CAPTURE)){
 | 
						|
                $wdoc = substr($wdoc, 0, $parameters[0][1]) . substr($wdoc, $parameters[0][1] + strlen($parameters[0][0]), -3);
 | 
						|
                $parameters = preg_split('/(\r\n|[\r\n])/', trim($parameters[0][0]));
 | 
						|
                $l = count($parameters);
 | 
						|
                $last_parameter = $parameters[$l - 1];
 | 
						|
            }else
 | 
						|
                $wdoc = substr($wdoc, 0, -3);
 | 
						|
 | 
						|
            if($last_parameter && preg_match('/^\#return[\\\\\s\t]/', $last_parameter, $matches, PREG_OFFSET_CAPTURE)){
 | 
						|
                $return = $last_parameter . "\n";
 | 
						|
                array_pop($parameters);
 | 
						|
                $l --;
 | 
						|
            }else if(isset($new["return"]))
 | 
						|
                $return = self::set_return($new["return"]);
 | 
						|
 | 
						|
            $wdoc = preg_replace('/^(@see[^\r\n]+[\r\n]+)+/m', "@see\t" . implode("\n@see\t", $new["see"]) . "\n", $wdoc);
 | 
						|
            $wdoc = preg_replace('/^@access[^\r\n]+/m', "@access\t" . $new["access"], $wdoc);
 | 
						|
            $wdoc = preg_replace('/^@version[^\r\n]+/m', "@version\t" . $this->common["version"], $wdoc);
 | 
						|
            if($new["hash"])
 | 
						|
                $wdoc = preg_match('/^@hash/m', $wdoc) ? preg_replace('/^@hash[^\r\n]+/m', "@hash\t" . $new["hash"], $wdoc) : $wdoc . "\n@hash\t" . $new["hash"];
 | 
						|
 | 
						|
            foreach($new["parameters"] as $i => $parameter)
 | 
						|
                $parameters_final[$i] = (
 | 
						|
                    $i < $m && $current["parameters"][$i] == $parameter ? $parameters[$i] : (
 | 
						|
                    ($j = array_search($parameter, $current["parameters"])) !== false ? $current["parameters"][$j] :
 | 
						|
                    $new["parameters_full"][$i]
 | 
						|
                ));
 | 
						|
 | 
						|
            $wdoc .= (substr($wdoc, -1) == "\n" ? "" : "\n") . (($parameters = implode("\n", $parameters_final)) ? $parameters . "\n" : "") . ($return ? $return : "") . "]]";
 | 
						|
 | 
						|
            return $wdoc;
 | 
						|
        }
 | 
						|
 | 
						|
        public function add_method($wmd, $last, $variables){
 | 
						|
 | 
						|
            if(isset($variables["see"])){
 | 
						|
                if(is_array($variables["see"])){
 | 
						|
 | 
						|
                    $see = "";
 | 
						|
 | 
						|
                    foreach($variables["see"] as $item)
 | 
						|
                        $see .= "@see        " . $item . "\n";
 | 
						|
                    $variables["see"] = $see;
 | 
						|
 | 
						|
                };
 | 
						|
            }else
 | 
						|
                $variables["see"] = "";
 | 
						|
 | 
						|
            if(isset($variables["parameters"])){
 | 
						|
                if(is_array($variables["parameters"])){
 | 
						|
 | 
						|
                    $parameters = "";
 | 
						|
 | 
						|
                    foreach($variables["parameters"] as $parameter)
 | 
						|
                        $parameters .= self::set_parameter($parameter);
 | 
						|
                    $variables["parameters"] = $parameters;
 | 
						|
                };
 | 
						|
            }else
 | 
						|
                $variables["parameters"] = $parameters;
 | 
						|
 | 
						|
            $variables["return"] = isset($variables["return"]) ? self::set_return($variables["return"]) : "";
 | 
						|
 | 
						|
            $method_variables = array_merge($variables, $this->common);
 | 
						|
            $new_method = \WMarkDown::string_variables("[[wdoc\n" .
 | 
						|
                "Método {type}.\n" .
 | 
						|
                "@name       {name}\n" .
 | 
						|
                "{see}" .
 | 
						|
                "@lang       {language_script}\n" .
 | 
						|
                "@author     {author}\n" .
 | 
						|
                "@since      {since}\n" .
 | 
						|
                "@version    {version}\n" .
 | 
						|
                "@access     {access}\n" .
 | 
						|
                "@hash       {hash}\n" .
 | 
						|
                "{parameters}" .
 | 
						|
                "{return}" .
 | 
						|
            "]]", $method_variables);
 | 
						|
            $pattern = preg_replace('/\\\\{8}/', "\\\\\\\\\\\\\\\\", '/[\r\n]\#\# \[\[plain ' . preg_replace('/([\.\-\:\\\\])/', "\\\\$1", $variables["name"]) . '\]\]((?!(\#\# |\[\[html_data))(.|[\n\r]))+/');
 | 
						|
            $new = self::get_attributes($new_method);
 | 
						|
            $language = $new["language"];
 | 
						|
 | 
						|
            if(preg_match($pattern, $wmd, $matches, PREG_OFFSET_CAPTURE)){
 | 
						|
 | 
						|
                $content = "";
 | 
						|
                $temporary = $matches[0][0];
 | 
						|
                $done = false;
 | 
						|
                $overload = in_array($language, self::$languages_with_overloads);
 | 
						|
 | 
						|
                while(preg_match('/([\r\n]\[\[wdoc((?!([\r\n]\]\]))(.|[\r\n]))+[\r\n]\]\])/', $temporary, $submatches, PREG_OFFSET_CAPTURE)){
 | 
						|
 | 
						|
                    $current = self::get_attributes($submatches[0][0]);
 | 
						|
 | 
						|
                    $wdoc = $submatches[0][0];
 | 
						|
                    $content .= substr($temporary, 0, $submatches[0][1]);
 | 
						|
                    $temporary = substr($temporary, $submatches[0][1] + strlen($submatches[0][0]));
 | 
						|
 | 
						|
                    if($overload){
 | 
						|
 | 
						|
                        if($done){
 | 
						|
                            $content .= $wdoc;
 | 
						|
                            continue;
 | 
						|
                        };
 | 
						|
 | 
						|
                        $ok = true;
 | 
						|
 | 
						|
                        foreach($new as $key => $value)
 | 
						|
                            if(!in_array($key, ["parameters_full", "hash"]) && !($ok = $value == $current[$key]))
 | 
						|
                                break;
 | 
						|
                        $content .= ($done = $ok) && $new["hash"] != $current["hash"] ? $this->update_wdoc($wdoc, $current, $new) : $wdoc;
 | 
						|
 | 
						|
                    }else{
 | 
						|
                        $same = true;
 | 
						|
                        foreach($new as $key => $value)
 | 
						|
                            if(!in_array($key, ["parameters_full"]) && !($same = $value == $current[$key]))
 | 
						|
                                break;
 | 
						|
                        $content .= $same ? $wdoc : $this->update_wdoc($wdoc, $current, $new);
 | 
						|
                        break;
 | 
						|
                    };
 | 
						|
 | 
						|
                };
 | 
						|
 | 
						|
                $overload && !$done && ($content .= "\n\n" . $new_method);
 | 
						|
 | 
						|
                return substr($wmd, 0, $matches[0][1]) . $content . "\n\n" . substr($wmd, $matches[0][1] + strlen($matches[0][0]));
 | 
						|
            };
 | 
						|
 | 
						|
            $fragments = $last ? explode("## " . $last . "\n", $wmd) : [$wmd];
 | 
						|
 | 
						|
            $new_method = \WmarkDown::string_variables("## [[plain {name}]]\n\n", $method_variables) . $new_method;
 | 
						|
 | 
						|
            $results = null;
 | 
						|
 | 
						|
            if(count($fragments) > 1)
 | 
						|
                $results = $fragments[0] . "## [[plain " . $last . "\n" . preg_replace('/^(\#{2} |\[{2}html_data)/m', $new_method . "]]\n\n$1", $fragments[1], 1);
 | 
						|
            else
 | 
						|
                $results = preg_replace('/^(\[{2}html_data)/m', $new_method . "\n\n$1", $fragments[0], 1);
 | 
						|
 | 
						|
            return $results;
 | 
						|
 | 
						|
            if(count($fragments) > 1)
 | 
						|
                return $fragments[0] . "## [[plain " . $last . "\n" . preg_replace('/^(\#{2} |\[{2}html_data)/m', $new_method . "]]\n\n$1", $fragments[1], 1);
 | 
						|
            return preg_replace('/^(\[{2}html_data)/m', $new_method . "\n\n$1", $fragments[0], 1);
 | 
						|
        }
 | 
						|
 | 
						|
        private function get_commons(){
 | 
						|
            return [
 | 
						|
                "common" => $this->common,
 | 
						|
                "original_wmd" => $this->original_wmd,
 | 
						|
                "root" => $this->root,
 | 
						|
                "root_l" => $this->root_l,
 | 
						|
                "class" => $this->class,
 | 
						|
                "object" => $this->object
 | 
						|
            ];
 | 
						|
        }
 | 
						|
 | 
						|
        private function analyze($class, $object, $file, $path, &$languages, $i){
 | 
						|
 | 
						|
            $class = '\WMarkDown\ScriptsAnalyzer\\' . $class;
 | 
						|
 | 
						|
            !$this->$object && class_exists($class) && ($this->$object = new $class($this->wmarkdown, $this, $this->get_commons()));
 | 
						|
            $this->$object && $this->$object->analyze($file, $path, $languages, $i);
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
        private function build($path, &$languages, $i = 0){
 | 
						|
            foreach(scandir($path) as $file){
 | 
						|
                if(preg_match('/^\.{1,2}$/', $file))
 | 
						|
                    continue;
 | 
						|
 | 
						|
                $subpath = $path . "/" . $file;
 | 
						|
 | 
						|
                if(in_array(substr($subpath, $this->root_l), $this->ignore))
 | 
						|
                    continue;
 | 
						|
                if(is_dir($subpath))
 | 
						|
                    $this->build($subpath, $languages, $i + 1);
 | 
						|
                elseif(preg_match('/\.(py|php|js|sql|cs)$/', $file, $matches, PREG_OFFSET_CAPTURE) && isset(self::$classes[$matches[1][0]]))
 | 
						|
                    $this->analyze(self::$classes[$matches[1][0]], $matches[1][0], $file, $path, $languages, $i);
 | 
						|
 | 
						|
            };
 | 
						|
        }
 | 
						|
 | 
						|
        private function write_wmd($path, $content, $variables){
 | 
						|
            \WMarkDown::save_file($path, \WMarkDown::string_variables($this->file_wmd, array_merge(["content" => $content], $this->common, $variables)));
 | 
						|
        }
 | 
						|
 | 
						|
        public function update_files(){
 | 
						|
 | 
						|
            $languages = [];
 | 
						|
            $wmd = "";
 | 
						|
 | 
						|
            if($this->original_wmd){
 | 
						|
                if($this->only){
 | 
						|
                    foreach(is_array($this->only) ? $this->only : [$this->only] as $path)
 | 
						|
                        $this->build($this->root . $path, $languages);
 | 
						|
                }else
 | 
						|
                    $this->build($this->root, $languages);
 | 
						|
            };
 | 
						|
 | 
						|
            foreach($languages as $language => $files){
 | 
						|
 | 
						|
                $index = "# " . self::$languages[$language] . "\n\n";
 | 
						|
 | 
						|
                $wmd .= "\n# " . self::$languages[$language] . "\n";
 | 
						|
                foreach($files as $file){
 | 
						|
 | 
						|
                    $path = substr($file["path"], $this->root_l + 8);
 | 
						|
 | 
						|
                    $wmd .= "\n- [" . ($link = ($sublink = "/dev/" . self::$languages[$language]) . "#" . preg_replace('/[^a-z\d]+/i', "-", preg_replace('/^(.+?\/)?([^\/]+)\.w\.md$/', "$2-2", $path))) . " " . preg_replace('/\.w\.md$/', "", $path) . "]";
 | 
						|
                    $index .= (
 | 
						|
                        "[[header_level 0]]\n" .
 | 
						|
                        "[[include /WMD/dev" . $path . "]]\n\n"
 | 
						|
                    );
 | 
						|
                    foreach($file["methods"] as $method)
 | 
						|
                        $wmd .= "\n    - [" . $sublink . "#" . preg_replace('/[^a-z\d]+/i', "-", $method) . "-2 " . preg_replace('/([_\\\\])/', "\\\\$1", $method) . "]";
 | 
						|
 | 
						|
                };
 | 
						|
                $wmd .= "\n";
 | 
						|
 | 
						|
                $this->write_wmd($this->root . "/WMD/dev/" . self::$languages[$language] . "/index.w.md", $index, [
 | 
						|
                    "title" => self::$languages[$language],
 | 
						|
                    "subpath" => "/dev/" . self::$languages[$language] . "/index",
 | 
						|
                    "languages" => strtolower(self::$languages[$language]),
 | 
						|
                    "language_name" => self::$languages[$language]
 | 
						|
                ]);
 | 
						|
 | 
						|
            };
 | 
						|
 | 
						|
            $this->write_wmd($this->root . "/WMD/dev/index.w.md", $wmd, [
 | 
						|
                "title" => "Código",
 | 
						|
                "subpath" => "/dev/index",
 | 
						|
                "languages" => "todo,all",
 | 
						|
                "language_name" => "Todo"
 | 
						|
            ]);
 | 
						|
 | 
						|
        }
 | 
						|
 | 
						|
    };
 |