2022-01-22 09:26:09 +00:00
|
|
|
from html5tagger import Document, E, HTML
|
2022-02-01 16:36:30 +00:00
|
|
|
import shutil
|
2022-01-24 10:09:04 +00:00
|
|
|
import markdown
|
2022-01-24 12:43:28 +00:00
|
|
|
import html
|
2022-01-26 10:03:25 +00:00
|
|
|
from pathlib import Path
|
2022-01-21 10:16:26 +00:00
|
|
|
|
2022-01-27 10:11:33 +00:00
|
|
|
#TODO re-think navigation bar. Think of way to add option to display navigation bar entry differently if you're currently on that page.
|
2022-01-22 09:54:31 +00:00
|
|
|
def generateNavigationBar(lines):
|
|
|
|
global navbar
|
|
|
|
navbar = E
|
2022-01-25 14:05:07 +00:00
|
|
|
rawhtml = False
|
|
|
|
htmlstring = ""
|
2022-01-24 13:20:08 +00:00
|
|
|
for id, line in enumerate(lines):
|
2022-01-24 10:35:29 +00:00
|
|
|
|
2022-01-25 14:05:07 +00:00
|
|
|
#parse raw HTML
|
|
|
|
rawhtml, navbar, htmlstring = parseRawHTML(navbar, line, htmlstring, rawhtml, id, len(lines))
|
|
|
|
|
|
|
|
#parse markdown
|
|
|
|
if not rawhtml:
|
2022-02-02 14:51:46 +00:00
|
|
|
if ";" in line:
|
|
|
|
title, link = line.split(";", 1)
|
|
|
|
|
|
|
|
#div class for styling
|
|
|
|
navbar = navbar(HTML("<div class='" + title.replace(" ", "-").lower() + "'>"))
|
|
|
|
|
|
|
|
#link and end of div
|
|
|
|
navbar = navbar.li(HTML("<a href='" + link.strip() + "'>" + title + "</a></div>"))
|
2022-01-22 09:54:31 +00:00
|
|
|
|
2022-01-31 10:11:51 +00:00
|
|
|
def generateFooter(lines):
|
|
|
|
global footer
|
|
|
|
footer = E
|
|
|
|
rawhtml = False
|
|
|
|
htmlstring = ""
|
|
|
|
for id, line in enumerate(lines):
|
|
|
|
|
|
|
|
#parse raw HTML
|
|
|
|
rawhtml, footer, htmlstring = parseRawHTML(footer, line, htmlstring, rawhtml, id, len(lines))
|
|
|
|
|
|
|
|
#parse markdown
|
|
|
|
if not rawhtml:
|
|
|
|
footer = footer.li(HTML(parseMarkdown(footer, line)))
|
|
|
|
|
2022-01-24 13:20:08 +00:00
|
|
|
def parseRawHTML(doc, line, htmlstring, rawhtml, id, maxlines):
|
2022-01-26 10:36:59 +00:00
|
|
|
|
2022-01-24 12:43:28 +00:00
|
|
|
#raw html start
|
|
|
|
if line.strip() == ">":
|
|
|
|
rawhtml = True
|
|
|
|
htmlstring = ""
|
|
|
|
|
|
|
|
#parse indented raw html
|
|
|
|
elif rawhtml:
|
|
|
|
if line.startswith(" "):
|
2022-01-24 14:23:07 +00:00
|
|
|
|
|
|
|
#experimental markdown inside HTML support
|
|
|
|
htmlstring = htmlstring + html.unescape(markdown.markdown(html.escape(line.strip())))
|
2022-01-24 13:20:08 +00:00
|
|
|
|
|
|
|
#if indented html was the last line, this is needed for it to not be ignored
|
2022-01-24 14:06:16 +00:00
|
|
|
#since this is the end of the file, we will not set rawhtml to False.
|
2022-01-24 13:20:08 +00:00
|
|
|
if maxlines - id == 1:
|
|
|
|
doc.div(HTML(htmlstring))
|
2022-01-24 12:43:28 +00:00
|
|
|
else:
|
|
|
|
rawhtml = False
|
2022-01-24 13:20:08 +00:00
|
|
|
doc.div(HTML(htmlstring))
|
2022-01-24 12:43:28 +00:00
|
|
|
htmlstring = ""
|
2022-02-02 14:51:46 +00:00
|
|
|
|
2022-01-24 12:43:28 +00:00
|
|
|
return rawhtml, doc, htmlstring
|
|
|
|
|
|
|
|
def parseMarkdown(doc, line):
|
2022-01-26 10:36:59 +00:00
|
|
|
|
2022-01-26 10:03:25 +00:00
|
|
|
#do not allow HTML in markdown
|
2022-01-24 12:43:28 +00:00
|
|
|
line = html.escape(line.strip())
|
2022-01-25 14:45:27 +00:00
|
|
|
return markdown.markdown(line)
|
2022-01-24 12:43:28 +00:00
|
|
|
|
2022-01-22 14:06:25 +00:00
|
|
|
def generateLines(title, lines):
|
|
|
|
title = title.replace(".page", "")
|
2022-01-24 10:25:29 +00:00
|
|
|
doc = Document(title, lang="en")
|
2022-01-24 10:09:04 +00:00
|
|
|
rawhtml = False
|
2022-01-24 12:43:28 +00:00
|
|
|
htmlstring = ""
|
2022-01-24 13:20:08 +00:00
|
|
|
for id, line in enumerate(lines):
|
2022-01-24 10:09:04 +00:00
|
|
|
|
2022-01-24 12:43:28 +00:00
|
|
|
#parse raw HTML
|
2022-01-24 13:20:08 +00:00
|
|
|
rawhtml, doc, htmlstring = parseRawHTML(doc, line, htmlstring, rawhtml, id, len(lines))
|
2022-01-24 10:09:04 +00:00
|
|
|
|
|
|
|
#parse markdown
|
2022-01-24 12:43:28 +00:00
|
|
|
if not rawhtml:
|
2022-01-25 14:45:27 +00:00
|
|
|
doc = doc(HTML(parseMarkdown(doc, line)))
|
2022-01-24 10:09:04 +00:00
|
|
|
|
2022-01-24 10:25:29 +00:00
|
|
|
generatePage(title, doc)
|
2022-01-22 14:06:25 +00:00
|
|
|
|
2022-01-24 10:25:29 +00:00
|
|
|
def generatePage(title, doc):
|
2022-01-26 10:03:25 +00:00
|
|
|
global pages
|
|
|
|
global titles
|
|
|
|
if 'pages' not in globals():
|
|
|
|
pages = []
|
|
|
|
if 'titles' not in globals():
|
|
|
|
titles = []
|
2022-01-26 10:08:19 +00:00
|
|
|
|
2022-01-26 10:03:25 +00:00
|
|
|
if 'navbar' in globals():
|
2022-01-31 10:11:51 +00:00
|
|
|
if 'footer' in globals():
|
|
|
|
pages.append(str(E.ul(navbar)) + str(doc) + str(E.ul(footer)))
|
|
|
|
else:
|
|
|
|
pages.append(str(E.ul(navbar)) + str(doc))
|
2022-01-26 10:03:25 +00:00
|
|
|
else:
|
2022-01-31 10:11:51 +00:00
|
|
|
if 'footer' in globals():
|
|
|
|
pages.append(str(doc) + str(E.ul(footer)))
|
|
|
|
else:
|
|
|
|
pages.append(str(doc))
|
2022-01-26 10:36:59 +00:00
|
|
|
titles.append(title)
|
2022-01-26 10:03:25 +00:00
|
|
|
|
|
|
|
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 = ""
|
2022-01-26 10:36:59 +00:00
|
|
|
|
2022-01-26 10:03:25 +00:00
|
|
|
#creates ./website-output/pagetitle/index.html file if it is not homepage
|
|
|
|
if titles[id] != homepage:
|
2022-02-01 16:36:30 +00:00
|
|
|
foldername = titles[id].replace(" ", "-").lower()
|
|
|
|
|
|
|
|
outputpath = Path(__file__).parent.joinpath("website-output")
|
|
|
|
|
|
|
|
dirpath = outputpath.joinpath(foldername)
|
2022-01-26 10:03:25 +00:00
|
|
|
|
2022-01-27 11:02:35 +00:00
|
|
|
dirpath.mkdir(parents=True, exist_ok=True)
|
2022-01-26 10:03:25 +00:00
|
|
|
|
2022-01-27 11:02:35 +00:00
|
|
|
filepath = dirpath.joinpath("index.html")
|
2022-01-27 10:11:33 +00:00
|
|
|
|
2022-01-27 10:29:24 +00:00
|
|
|
if filepath.exists():
|
|
|
|
with filepath.open('r') as newpage:
|
2022-01-26 10:08:19 +00:00
|
|
|
if newpage.read() == page:
|
2022-01-26 10:36:59 +00:00
|
|
|
print("Page not changed: " + titles[id])
|
|
|
|
continue
|
2022-01-27 10:11:33 +00:00
|
|
|
|
2022-01-27 10:29:24 +00:00
|
|
|
with filepath.open('w') as newpage:
|
2022-01-26 10:36:59 +00:00
|
|
|
newpage.write(page)
|
|
|
|
print("Written changed page: " + titles[id])
|
2022-01-24 16:49:02 +00:00
|
|
|
|
2022-01-31 10:56:41 +00:00
|
|
|
#resources
|
|
|
|
respath = Path(__file__).parent.joinpath("resources")
|
|
|
|
if respath.exists():
|
2022-02-01 16:36:30 +00:00
|
|
|
|
|
|
|
#shutil.copytree copies timestamp too
|
|
|
|
shutil.copytree(respath, outputpath, dirs_exist_ok=True)
|
|
|
|
|
|
|
|
#check if folders are named correctly
|
|
|
|
for folder in outputpath.iterdir():
|
|
|
|
if folder.is_dir():
|
|
|
|
|
|
|
|
#rename folder name format from "About Page" to "about-page"
|
|
|
|
bettername = folder.name.replace(" ", "-").lower()
|
|
|
|
|
|
|
|
if folder.name != bettername:
|
|
|
|
newpath = outputpath.joinpath(bettername)
|
|
|
|
|
|
|
|
#example: resources folder is "About", page got auto-created earlier as "about" (from About.page), let's copy "About" resources to "about" and delete "About"
|
|
|
|
if newpath.exists():
|
|
|
|
shutil.copytree(folder, newpath, dirs_exist_ok=True)
|
|
|
|
shutil.rmtree(folder)
|
|
|
|
else:
|
|
|
|
shutil.move(str(folder), newpath)
|
|
|
|
|
2022-01-24 16:49:02 +00:00
|
|
|
def main():
|
2022-01-26 10:36:59 +00:00
|
|
|
|
2022-01-24 16:49:02 +00:00
|
|
|
#if homepage is at Home.page, set homepage to "Home"
|
|
|
|
homepage = "Home"
|
|
|
|
|
2022-01-27 11:02:35 +00:00
|
|
|
navbarfile = Path(__file__).parent.joinpath('navbar')
|
2022-01-27 10:29:24 +00:00
|
|
|
|
|
|
|
if navbarfile.exists():
|
|
|
|
with navbarfile.open('r') as navbarfile:
|
2022-01-24 16:49:02 +00:00
|
|
|
generateNavigationBar(navbarfile.readlines())
|
|
|
|
else:
|
|
|
|
print("No 'navbar' file found, there will be no navigation bar.")
|
|
|
|
|
2022-01-31 10:11:51 +00:00
|
|
|
footerfile = Path(__file__).parent.joinpath('footer')
|
|
|
|
|
|
|
|
if footerfile.exists():
|
|
|
|
with footerfile.open('r') as footerfile:
|
|
|
|
generateFooter(footerfile.readlines())
|
|
|
|
else:
|
|
|
|
print("No 'footer' file found, there will be no footer.")
|
|
|
|
|
2022-01-24 16:49:02 +00:00
|
|
|
pagescount = 0
|
2022-01-27 10:29:24 +00:00
|
|
|
|
|
|
|
for file in Path(__file__).parent.iterdir():
|
|
|
|
if file.is_file():
|
2022-01-27 11:02:35 +00:00
|
|
|
if file.suffix == ".page":
|
2022-01-27 10:29:24 +00:00
|
|
|
pagescount += 1
|
|
|
|
with file.open('r') as page:
|
2022-01-27 11:03:53 +00:00
|
|
|
generateLines(file.stem, page.readlines())
|
2022-01-26 10:03:25 +00:00
|
|
|
print("Found " + str(pagescount) + " pages")
|
|
|
|
|
2022-01-26 10:36:59 +00:00
|
|
|
#write all pages to files
|
2022-01-26 10:03:25 +00:00
|
|
|
writePages(homepage)
|
2022-01-24 16:49:02 +00:00
|
|
|
|
|
|
|
if __name__ == "__main__":
|
2022-01-26 10:03:25 +00:00
|
|
|
main()
|