wmarkdown->settings(["modules_overwrite", "module_overwrite", "overwrite"]);
            foreach(is_string($modules) || (is_array($modules) && !isset($modules[0])) ? [$modules] : $modules as $items){
                if(!$items)
                    continue;
                if(is_string($items)){
                    $json = null;
                    try{
                        $json = @json_decode($items, true);
                    }catch(\Exception $exception){};
                    if(!$json && !($json = @json_decode(file_get_contents($this->wmarkdown->get_root() . $items))))
                        continue;
                    $items = $json;
                };
                if(is_array($items)){
                    if(isset($items[0]))
                        $this->add($items);
                    else
                        foreach($items as $name => $module)
                            if(!in_array($name, $this->excludes) && class_exists($module) && ($overwrite || !$this->modules[$name]))
                                $this->modules[$name] = new $module($this->wmarkdown);
                };
            };
        }
        private function __construct($wmarkdown, $excludes){
            $this->wmarkdown = $wmarkdown;
            $this->excludes = is_array($excludes) ? $excludes : [];
            foreach(["default_modules", "modules"] as $modules)
                $this->add($this->wmarkdown->settings($modules), true);
        }
        public function create_menu_item($level, $id, $content){
            return ('
                
                    
                    ' . $content . '
                
            ');
        }
        private static function create_file_item($url, $title, $file){
            return ('
                
                    
                    ' . $title . '
                
            ');
        }
        private function prepare($string, $master, $level){
            $results = '';
            $menu = '';
            $files = '';
            $title = $this->wmarkdown->settings("default_title");
            $title_root = $this->wmarkdown->settings("title");
            if($master === null)
                $master = $this;
            if(preg_match('/^#+ ?([^\r\n]+)/m', $string, $matches))
                $title = $matches[1];
            if($title_root)
                $title = $title_root . " - " . $title;
            while(true && $string){
                $first = null;
                foreach($this->modules as $name => $module)
                    if(($position = $module->get_position($string)) !== null && $position >= 0 && ($first === null || $first["position"] > $position))
                        $first = [
                            "position" => $position,
                            "module" => $name
                        ];
                if(!$first)
                    break;
                $module = $this->modules[$first["module"]];
                $module->process($string, $master, $level);
                if($first["module"] == "headers")
                    $menu .= $this->create_menu_item($this->menu_level = $module->get_level(), $module->get_id(), $module->get_content());
                elseif($first["module"] == "includes"){
                    $menu .= $module->get_menu();
                    if(!$this->documentation_root_length)
                        $this->documentation_root_length = strlen($this->wmarkdown->get_documentation_path());
                    $files .= self::create_file_item(preg_replace('/(\.w)?\.md/', ".html", substr($module->get_content(), $this->documentation_root_length)), trim(preg_replace('/^([^\-]+\-)?(.+)$/', "$2", $module->get_title())), $module->get_content());
                };
                $results .= substr($string, 0, $module->get_from()) . $module->get_html();
                $string = substr($string, $to = $module->get_to());
                foreach($this->modules as $name => $block)
                    if($block->has_more())
                        $block->set_position($to);
            };
            $results .= $string;
            return array_merge([
                "menu" => $menu,
                "content" => $results,
                "files" => $files,
                "title" => $title
            ], is_array($this->html_data) ? $this->html_data : []);
        }
        public static function format($wmarkdown, $string, $excludes = [], $master = null, $level = 0){
            return (new \WMarkDown\Modules($wmarkdown, $excludes))->prepare($string, $master, $level);
        }
    };