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