/** * Created by Aleksey Chichenkov on 12/6/18. */ var fs = require("fs"); var path = require('jsdoc/path'); var rx_class_declarator_std = /var *(.*?)(?:| )=(?:| ) std.class\(\[(.*?)\]/im; var rx_requires = /var {1,}?(.*?) {1,}?= {1,}?require\("(.*?)"\)/i; var __tree_list = Object.create(null); var __root; var map = {}; var destination; var output; var helper; var logger; var generate; var find = function (_conf, _helper, _logger, _generate) { helper = _helper; logger = _logger; generate = _generate; __root = new Node(); destination = path.normalize(_conf.source.include_2[0]); output = path.normalize(_conf.opts.destination); recursive(destination); generate_tree(); generate_files(); var struct = __root.get_struct(); return struct; }; var recursive = function(_path){ if(fs.lstatSync(_path).isDirectory()) { var arr = fs.readdirSync(_path); for (var a = 0; a < arr.length; a++) { var name = arr[a]; recursive(_path + "/" + name); } } else { parse_file(_path); } }; var parse_file = function(_path){ let info = Object.create(null); info.requires = Object.create(null); info.classes = Object.create(null); var file = fs.readFileSync(_path, "utf8"); var requires = exec_all(rx_requires, file); if(requires.length > 0) { for(var a = 0; a < requires.length; a++){ info.requires[requires[a].subs[0]] = update_link_file(requires[a].subs[1]) } } var classes = exec_all(rx_class_declarator_std, file); if(classes.length > 0) { for(var a = 0; a < classes.length; a++){ info.classes[classes[a].subs[0]] = classes[a].subs[1] } } map[_path] = info; }; var exec_all = function(_rx, _string){ var out = []; var result; while(result = _string.match(_rx)){ result = convert_result(result); // console.log("result", result); _string = _string.substring(result.index + result.match.length, _string.length); out.push(result); } return out }; var convert_result = function(_exec_result) { var info = Object.create(null); info.index = _exec_result.index; info.match = _exec_result[0]; info.subs = []; for (var a = 1; a < _exec_result.length; a++) { info.subs.push(_exec_result[a]); } return info; }; var update_link_file = function (_path) { var arr = destination.split("/"); arr.pop(); return arr.join("/") + "/" + _path + ".js" }; var generate_tree = function() { __root.name = "std.class"; __root.path = destination + "/std/class"; for (var path in map) { var file_info = map[path]; recursive_tree(path, file_info); } for(var name in __tree_list){ var n = __tree_list[name]; if(n.inherit === "base_class"){ __root.children.push(n); } } }; var recursive_tree = function (_file_name, _file_info, _child) { if(!_file_info){ // console.log("ERROR: ", _file_name); return; } var classes = _file_info.classes; var requires = _file_info.requires; for(var name in classes){ var path = _file_name + ":" + name; var node = __tree_list[path]; if(!node){ node = new Node(); if(name == "data"){ // console.log(_file_name); } node.name = name; node.path = _file_name; __tree_list[path] = node; } var inheritance = classes[name]; var req = requires[inheritance]; if(req){ if(_child && node.children.indexOf(_child) === -1){ _child.inherit = name; node.children.push(_child); } var fi = map[req]; recursive_tree(req, fi, node); } } }; var Node = function(){ this.children = []; this.name = ""; this.path = "no_path"; this.link = "#no_link"; this.inherit = "base_class"; }; Node.prototype = { get_struct: function () { var children = []; for(var a = 0; a < this.children.length; a++){ children.push(this.children[a].get_struct()); } // console.log(this.path); return { name: this.name, path: this.path, link: this.link, children: children } } }; var generate_files = function(){ if(!fs.existsSync(output)){ fs.mkdirSync(output); } for(var key in __tree_list){ var node = __tree_list[key]; var name = node.path.split("/").splice(6).join("_"); // console.log("out_name:", name) var out_path = output + "/" + name + ".html"; node.link = name + ".html"; // console.log(node.link, node.name, node.path); try { var source = { kind: 'source', code: helper.htmlsafe( fs.readFileSync(node.path, 'utf8') ) }; } catch (e) { logger.error('Error while generating source file %s: %s', name, e.message); } // out_path = out_path.replace("//", "/"); // console.log("out_path:", out_path); generate('Source: ' + node.name, [source], node.link, false); } }; module.exports.find = find;