Skip to content
Snippets Groups Projects
Select Git revision
  • 9dd3d9521760f4558999868201bb74dcdcf632e7
  • master default protected
  • add_logger
  • spheric_talk
  • james_paper
  • ewass_talk
  • updated_contact_list
  • about-page-information
  • eurohack
  • updated_people_list
10 results

about.py

Blame
  • about.py 4.05 KiB
    """
    This file contains the routines used to compile the 'about' page's text.
    This text comes to us in three parts, which are stored in three markdown
    files in the data directory, along with an about_meta.yaml file describing
    how they are to be described at the top of the page.
    
    The markdown files are then compiled to two pieces of HTML, one for the
    sidebar and one for the main part of the text, as well as a small
    dictionary that describes the content of the cards at the top of the page.
    
    Created 16-08-2017 by Josh Borrow (joshua.borrow@durham.ac.uk)
    """
    
    #Disable errors associated with un-overwritten methods in HTMLParser.
    #pylint: disable=W0223
    
    from html.parser import HTMLParser
    
    from mdcomp import convert_text
    import yaml
    
    
    def open_meta(filename="about_meta.yaml", data_dir="../data"):
        """ Read the meta file and return the associated data """
        with open(f"{data_dir}/{filename}", "r") as handle:
            return yaml.load(handle)
    
    
    def compile_markdown(data, data_dir="../data"):
        """ 'data' is the dictionary provided by reading about_meta.yaml """
    
        output_text = ""
    
        for item in data["files"]:
            with open(f"{data_dir}/{item['name']}", "r") as handle:
                input_text = handle.read()
            
            compiled_text = convert_text(input_text)
    
            output_text += f"<div id=\"{item['slug']}\">{compiled_text}</div>"
        return output_text
    
    
    class Parser(HTMLParser):
        """ Custom HTML Parser that builds the headings tree """
        def __init__(self):
            super(Parser, self).__init__()
    
            self.headings = []
            self.waiting_for_data = False
    
        def handle_starttag(self, tag, attrs):
            for attr in attrs:
                if attr[0] == "id":
                    this_id = attr[1]
                    break
                else:
                    this_id = ""
                    continue
    
            if (tag == "h1") or (tag == "h2"):
                self.headings.append([tag, this_id])
                self.waiting_for_data = True
    
    
        def handle_endtag(self, tag):
            pass
    
    
        def handle_data(self, data):
            if self.waiting_for_data:
                self.headings[-1].append(data)
                self.waiting_for_data = False
    
    
    def parse_html(text):
        """ To generate the sidebar automatically we must parse the HTML and
            extract the appropriate headings. """
    
        parser = Parser()
        parser.feed(text)
    
        return parser.headings
    
    
    def parse_headings(headings):
        """ Creates the HTML for the sidebar based on the headings """
    
        sidebar_content = ""
    
        # Heading has the structure [tag, id, text]
        for heading in headings:
            if heading[0] == "h1":
                if sidebar_content != "":
                    sidebar_content += "</ul>"
    
                sidebar_content += f"<h2>{heading[2]}</h2><ul>"
    
            elif heading[0] == "h2":
                sidebar_content += f"<li><a href=\"#{heading[1]}\">{heading[2]}</a></li>"
    
            else:
                raise Exception(f"There is an issue with Parser (about.py). It picked up {heading}")
    
        return f"{sidebar_content}</ul>"
    
    
    def compile_to_yaml(in_filename="about_meta.yaml", out_filename="about.yaml", data_dir="../data"):
        """ Compiles the information in the markdown files and sends it out to an
            external yaml file. """
    
        meta_data = open_meta(in_filename, data_dir)
        # At this stage it is smart to remove the 'hidden' files.
        meta_data_clean = {
        "files" : [
                item for item in meta_data["files"] if not item["hidden"]
            ]
        }
    
        output_text = compile_markdown(meta_data_clean, data_dir)
    
        sidebar = parse_headings(parse_html(output_text))
    
        output_data = {
            "meta_data": meta_data_clean,
            "output_text": output_text,
            "sidebar": sidebar
        }
    
        with open(f"{data_dir}/{out_filename}", "w") as handle:
            yaml.dump(output_data, handle)
    
        return output_data
    
    if __name__ == "__main__":
        print("Running this script directly will only compile the markdown in data.")
        print("If you wish to continue, please enter Y, if not, please enter N.")
    
        CHOICE = input()
    
        if CHOICE in ['y', 'Y']:
            compile_to_yaml()
        else:
            exit(0)