from html5tagger import Document, E, HTML from shutil import rmtree import markdown import html from pathlib import Path #TODO re-think navigation bar. Think of way to add option to display navigation bar entry differently if you're currently on that page. def generateNavigationBar(lines): global navbar navbar = E rawhtml = False htmlstring = "" for id, line in enumerate(lines): #parse raw HTML rawhtml, navbar, htmlstring = parseRawHTML(navbar, line, htmlstring, rawhtml, id, len(lines)) #parse markdown if not rawhtml: navbar = navbar.li(HTML(parseMarkdown(navbar, line))) def parseRawHTML(doc, line, htmlstring, rawhtml, id, maxlines): #raw html start if line.strip() == ">": rawhtml = True htmlstring = "" #parse indented raw html elif rawhtml: if line.startswith(" "): #experimental markdown inside HTML support htmlstring = htmlstring + html.unescape(markdown.markdown(html.escape(line.strip()))) #if indented html was the last line, this is needed for it to not be ignored #since this is the end of the file, we will not set rawhtml to False. if maxlines - id == 1: doc.div(HTML(htmlstring)) else: rawhtml = False doc.div(HTML(htmlstring)) htmlstring = "" return rawhtml, doc, htmlstring def parseMarkdown(doc, line): #do not allow HTML in markdown line = html.escape(line.strip()) return markdown.markdown(line) def generateLines(title, lines): title = title.replace(".page", "") doc = Document(title, lang="en") rawhtml = False htmlstring = "" for id, line in enumerate(lines): #parse raw HTML rawhtml, doc, htmlstring = parseRawHTML(doc, line, htmlstring, rawhtml, id, len(lines)) #parse markdown if not rawhtml: doc = doc(HTML(parseMarkdown(doc, line))) generatePage(title, doc) def generatePage(title, doc): global pages global titles if 'pages' not in globals(): pages = [] if 'titles' not in globals(): titles = [] if 'navbar' in globals(): pages.append(str(E.ul(navbar)) + str(doc)) else: pages.append(str(doc)) titles.append(title) def writePages(homepage): global pages global titles #TODO only delete files that aren't present in newest site generation #deleting contents of folder without deleting the folder, to increase compatibility with various systems #for root, dirs, files in os.walk('./website-output'): # for f in files: # os.unlink(os.path.join(root, f)) # for d in dirs: # rmtree(os.path.join(root, d)) for id, page in enumerate(pages): foldername = "" #creates ./website-output/pagetitle/index.html file if it is not homepage if titles[id] != homepage: foldername = "/" + titles[id].replace(" ", "-").lower() dirpath = Path(__file__).parent.joinpath("website-output" + foldername) dirpath.mkdir(parents=True, exist_ok=True) filepath = dirpath.joinpath("index.html") if filepath.exists(): with filepath.open('r') as newpage: if newpage.read() == page: print("Page not changed: " + titles[id]) continue with filepath.open('w') as newpage: newpage.write(page) print("Written changed page: " + titles[id]) def main(): #if homepage is at Home.page, set homepage to "Home" homepage = "Home" navbarfile = Path(__file__).parent.joinpath('navbar') if navbarfile.exists(): with navbarfile.open('r') as navbarfile: generateNavigationBar(navbarfile.readlines()) else: print("No 'navbar' file found, there will be no navigation bar.") pagescount = 0 for file in Path(__file__).parent.iterdir(): if file.is_file(): if file.suffix == ".page": pagescount += 1 with file.open('r') as page: generateLines(file.stem, page.readlines()) print("Found " + str(pagescount) + " pages") #write all pages to files writePages(homepage) if __name__ == "__main__": main()