# This Python 3 script reads a single documentation.html file generated by Sigasi # Studio, and rewrites it into separate files per entity or module. Multiple # libraries are not supported. # # This script reads its input from a file named documentation.html, which is assumed # to be in the current directory. # The generated index document is index.html, the separate files with a single # design unit are named after the design unit. # # # Note that the structure of the generated documentation is not fixed like an API. # Sigasi may change the way it generates documentation, and this may break the # functionality of this script (and your adaptations). This script was made for # Sigasi Studio 4.12. # # Copyright (c) 2021, Sigasi. All rights reserved. # # This script is provided under the BSD license: # # Redistribution and use in source and binary forms, with or without modification, # are permitted provided that the following conditions are met: # # Redistributions of source code must retain the above copyright notice, this # list of conditions and the following disclaimer. # # Redistributions in binary form must reproduce the above copyright notice, this # list of conditions and the following disclaimer in the documentation and/or # other materials provided with the distribution. # # Neither the name of the Sigasi nor the names of its # contributors may be used to endorse or promote products derived from # this software without specific prior written permission. # # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE # DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON # ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. from htmldom import htmldom def bare_design_unit_name(text): result = text.replace("​", "") # Zero width space if "." in result: return result.split(".")[1].strip() return result.strip() def rewrite_documentation(): # Read and parse the documentation generated by Sigasi Studio, and save the header for later dom = htmldom.HtmlDom("file:documentation.html").createDom() head = dom.find("head") # Create a list of entities and modules. VHDL architectures are appended to their respective architectures design_units = {} entity_length = len("entity ") for entity in dom.find("div.entity"): design_units[bare_design_unit_name(entity.find("h2").text()[entity_length:])] = entity architecture_length = len("architecture ") for architecture in dom.find("div.architecture"): arch_name = bare_design_unit_name(architecture.find("h2").text()[architecture_length:]) entity_name = arch_name.split("(")[0] if entity_name in design_units: design_units[entity_name].append(architecture) else: print("*Warning* unmatched architecture " + arch_name + " of " + entity_name) module_length = len("module ") for module in dom.find("div.module"): design_units[bare_design_unit_name(module.find("h2").text()[module_length:])] = module # Look up which design units are instantiated i.e. which are not top levels non_top_level = [] for design_unit_name, design_unit in design_units.items(): for h3 in design_unit.find('h3'): if h3.text() == "Instantiations": for insta in h3.nextUntil('h3'): insta_li = insta.find('li').first() insta_li_textbits = insta_li.text().split(" : ") insta_name = bare_design_unit_name(insta_li_textbits[1]) non_top_level.append(insta_name) # While we're here, add a link to instantiations text_with_link = insta_li_textbits[0] + " : " + '' + \ insta_li_textbits[1] + '' insta_li.text(text_with_link) # Create a new index document and set up some headers and titles. index_document = htmldom.HtmlDom().createDom("").find('html') index_document.prepend(head) index_body = index_document.find('body') # Copy the H1 title from the original document to the index document. index_body.prepend(dom.find('h1')) # One may want to append some high-level information on the project at this point. index_body.append("

Top level modules and entities:

") index_body.append("

Other modules and entities:

") # Generate an HTML file for each design unit, and add a link in the index document for design_unit_name, design_unit in design_units.items(): print('Design unit: ' + design_unit_name) new_document = htmldom.HtmlDom().createDom("").find('html') new_document.prepend(head) # Copy the full HTML describing the design unit from the original document into the single design unit document new_document.find('body').append(design_unit) # Add the link to the index document link = '
  • ' + design_unit_name + '
  • ' if design_unit_name not in non_top_level: design_unit.find('p').first().after("

    This is a top level module/entity

    ") index_body.find('ul').first().append(link) else: index_body.find('ul').last().append(link) # Save the single design unit document with open(design_unit_name + ".html", 'w') as f: f.write(new_document.html()) # Save the index document with open('index.html', 'w') as f: f.write(index_document.html()) if __name__ == '__main__': rewrite_documentation()