UNPKG

teroshdl

Version:

Backend for terosHDL IDE

291 lines (261 loc) 9.64 kB
// Copyright 2020-2021 Teros Technology // // Ismael Perez Rojo // Carlos Alberto Ruiz Naranjo // Alfredo Saez // // This file is part of TerosHDL. // // TerosHDL is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // TerosHDL is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with TerosHDL. If not, see <https://www.gnu.org/licenses/>. /* eslint-disable no-empty */ const path_lib = require('path'); const utils = require('../utils/utils'); const fs = require('fs'); const Documenter_lib = require('./documenter'); const declaration_finder = require('../utils/utils'); const css_style_lib = require('./css_style'); async function get_md_doc_from_project(project, output_dir_doc, graph, config, cli_bar) { let result = await get_doc_from_project(project, output_dir_doc, graph, config, 'markdown', cli_bar); return result; } async function get_html_doc_from_project(project, output_dir_doc, graph, config, cli_bar) { let result = await get_doc_from_project(project, output_dir_doc, graph, config, 'html', cli_bar); return result; } async function get_doc_from_project(project, output_dir_doc, graph, config, type, cli_bar=undefined) { let ok_files = 0; let fail_files = 0; let self_contained = config.self_contained; if (self_contained === undefined){ self_contained = false; } //Internal doc folder const INTERNAL_DOC_FOLDER = 'doc_internal'; const INTERNAL_DOC_FOLDER_COMPLETE = path_lib.join(output_dir_doc,'doc_internal'); if (!fs.existsSync(INTERNAL_DOC_FOLDER_COMPLETE) && (self_contained === false || type === 'markdown')){ fs.mkdirSync(INTERNAL_DOC_FOLDER_COMPLETE, { recursive: true }); } //Main doc let files = get_sources_as_array(project.files); cli_bar.start(files.length, 0); let project_name = project.name; let main_doc = get_title_project(type, project_name); if (config.dependency_graph === true && graph !== undefined) { main_doc += get_graph_declaration(type, graph, INTERNAL_DOC_FOLDER_COMPLETE, INTERNAL_DOC_FOLDER); } main_doc += get_title_design(type); let lang = "none"; main_doc += get_separation_init(type); let doc_modules = ''; let list_modules = ''; let doc_current = new Documenter_lib.Documenter(config); for (let i = 0; i < files.length; ++i) { let file_path = files[i]; let file_path_name = path_lib.basename(file_path); let filename = path_lib.basename(file_path, path_lib.extname(file_path)); lang = utils.get_lang_from_path(file_path); if( lang === 'systemverilog'){ lang = 'verilog'; } // Only save the doc for a HDL file and exists if (lang !== 'none' && fs.existsSync(file_path) === true){ let contents = fs.readFileSync(files[i], 'utf8'); if (contents.split(/\r\n|\r|\n/).length < 8000){ cli_bar.update(i, {filename: file_path_name}); try{ config.input_path = file_path; let declaration = await declaration_finder.get_declaration_from_path(file_path); if (declaration.name !== ''){ ok_files += 1; let list_modules_inst = ''; if (declaration.type === 'entity'){ list_modules_inst = get_module_str(self_contained, INTERNAL_DOC_FOLDER, filename, declaration.name, type); } else{ list_modules_inst = get_package_str(self_contained, INTERNAL_DOC_FOLDER, filename, declaration.name, type); } let inst_doc_module = await save_doc(self_contained, type, INTERNAL_DOC_FOLDER_COMPLETE, filename, doc_current, contents, lang, config); if (self_contained === false && inst_doc_module.error === false){ main_doc += list_modules_inst; main_doc += inst_doc_module.doc; } else if(inst_doc_module.error === false){ list_modules += list_modules_inst; doc_modules += inst_doc_module.doc; } } else{ fail_files += 1; } } catch(e){ } } else{ fail_files += 1; } } } if (self_contained === true){ main_doc += list_modules; main_doc += '\n\n'; main_doc += doc_modules; main_doc = css_style_lib.html_style_save + main_doc; } main_doc += get_separation_end(type); fs.writeFileSync(output_dir_doc + path_lib.sep + get_index_name(type), main_doc); // Stop the progress bar cli_bar.update(files.length); cli_bar.stop(); return {'fail_files':fail_files, 'ok_files':ok_files}; } async function save_doc(self_contained, type, output, filename, doc_inst, code, lang, config){ let result; if (self_contained === true && type === 'html'){ result = await save_doc_self_contained(type, doc_inst, code, lang, config); } else{ result = await save_doc_separate(type, output, filename, doc_inst, code, lang, config); } return result; } async function save_doc_self_contained(type, doc_inst, code, lang, config){ config.html_style = true; let html_value = ''; if (type === 'html'){ config.html_style = 'save'; config.extra_top_space = false; html_value = await doc_inst.get_html(code, lang, config); } return {error:html_value.error, doc:html_value.html}; } async function save_doc_separate(type, output, filename, doc_inst, code, lang, config){ let output_filename = filename + get_extension(type); let output_path = path_lib.join(output, output_filename); let error; if (type === 'html'){ error = await doc_inst.save_html(code, lang, config, output_path); } else{ error = await doc_inst.save_markdown(code, lang, config, output_path); } return {error:error, doc:''}; } function get_graph_declaration(type, graph, output_dir_doc, output_dir_doc_relative){ let declaration = ''; if (type === 'html'){ declaration += graph + '\n'; } else{ declaration += `![system](./${output_dir_doc_relative}/dependency_graph.svg "System")\n`; fs.writeFileSync(output_dir_doc + path_lib.sep + "dependency_graph.svg", graph); } return declaration; } function get_date(){ let date_ob = new Date(); let date = ("0" + date_ob.getDate()).slice(-2); let month = ("0" + (date_ob.getMonth() + 1)).slice(-2); let year = date_ob.getFullYear(); let hours = date_ob.getHours().toString().padStart(2, '0'); let minutes = date_ob.getMinutes().toString().padStart(2, '0'); let seconds = date_ob.getSeconds().toString().padStart(2, '0'); let date_str = year + "-" + month + "-" + date + " " + hours + ":" + minutes + ":" + seconds; return date_str.padEnd(19); } function get_title_project(type, project_name){ let date = get_date(); let title = ''; if (type === 'html'){ title = `<h1>Documentation for: ${project_name}</h1>\n\n`; title += 'Generated by <strong>TerosHDL</strong> © 2020-2021 License GPLv3<br>'; } else{ title = `# Documentation for: ${project_name}\n\n`; title += 'Generated by **TerosHDL** © 2020-2021 License GPLv3<br>'; } title += 'Carlos Alberto Ruiz Naranjo (carlosruiznaranjo@gmail.com)<br>'; title += 'Ismael Perez Rojo (ismaelprojo@gmail.com)<br><br>'; title += `Project revision ${date}<br><br>\n`; return title; } function get_title_design(type){ let title = `## Designs\n`; if (type === 'html'){ title = "<h2>Designs\n</h2>"; } return title; } function get_module_str(self_contained, folder, filename, name, type){ let declaration = `- Module: [${name} ](./${folder}/${filename}.md)\n`; if (self_contained === false && type === 'html'){ declaration = ` <li>Module: <a href="${folder}/${filename}.html">${name}</a>\n</li>`; } else if(self_contained === true && type === 'html'){ declaration = ` <li>Module: <a href="#${name}">${name}</a>\n</li>`; } return declaration; } function get_package_str(self_contained, folder, filename, name, type){ let declaration = `- Package: [${name} ](./${folder}/${filename}.md)\n`; if (self_contained === false && type === 'html'){ declaration = ` <li>Package: <a href="${folder}/${filename}.html">${name}</a>\n</li>`; } else if(self_contained === true && type === 'html'){ declaration = ` <li>Package: <a href="#${name}">${name}</a>\n</li>`; } return declaration; } function get_separation_init(type){ let declaration = '\n'; if (type === 'html'){ declaration = '<ul>'; } return declaration; } function get_separation_end(type){ let declaration = '\n'; if (type === 'html'){ declaration = '</ul>'; } return declaration; } function get_index_name(type){ let declaration = 'README.md'; if (type === 'html'){ declaration = 'index.html'; } return declaration; } function get_extension(type){ let declaration = '.md'; if (type === 'html'){ declaration = '.html'; } return declaration; } function get_sources_as_array(files_edam){ let sources = []; for (let i = 0; i < files_edam.length; i++) { const element = files_edam[i]; sources.push(element.name); } return sources; } module.exports = { get_html_doc_from_project: get_html_doc_from_project, get_md_doc_from_project: get_md_doc_from_project };