diff --git a/html-preprocessor b/html-preprocessor
index 94dda41..b376783 100755
--- a/html-preprocessor
+++ b/html-preprocessor
@@ -24,7 +24,13 @@ sidenav_format = """\
"""
sidenav_content_link = "
#name"
-sidenav_content_section = "#name"
+sidenav_content_section = """\
+#name
+
+
+"""
exit_on_include_failure = False
@@ -236,11 +242,40 @@ class Sitemap:
"""
************************************************************ SIDENAV ************************************************************
"""
+def replace_and_respect_indent(string, replace, replacement):
+ """
+ replace all occurences of 'replace' with 'replacement', add the whitespaces in front of 'replace' to every line of 'replacement'
+ """
+ i = string.find(replace)
+ while i >= 0:
+ line_begin = string.rfind("\n", 0, i) + 1
+ indent = string[line_begin:i]
+ string = string[:line_begin] + replacement.replace("\n", "\n" + indent) + string[i+len(replace):]
+ i = string.find(replace)
+ return string
+
class Sidenav:
- LINK = 0
- SECTION = 1
- # 0: link, 1: section
- entries: list[tuple[int, str, str]] = []
+ class Link:
+ def __init__(self, name: str, link: str):
+ self.link = link
+ self.name = name
+ def __repr__(self):
+ return f"Link: name={self.name}, link={self.link}"
+
+ def get(self):
+ return sidenav_content_link.replace("#name", self.name).replace("#link", self.link)
+ class Section:
+ def __init__(self, name: str):
+ self.name = name
+ self.links = []
+ def add_link(self, link):
+ self.links.append(link)
+ def __repr__(self):
+ return f"Section: name={self.name}"
+ def get(self):
+ links = "".join([ link.get() + "\n" for link in self.links ])
+ return replace_and_respect_indent(sidenav_content_section.replace("#name", self.name), "#links", links)
+ entries: list[Link|Section] = []
skip_next = False
custom_name = None
@staticmethod
@@ -251,10 +286,13 @@ class Sidenav:
if Sidenav.custom_name:
name = Sidenav.custom_name
Sidenav.custom_name = None
- Sidenav.entries.append((Sidenav.LINK, name, link))
+ if len(Sidenav.entries) > 0 and type(Sidenav.entries[-1]) == Sidenav.Section:
+ Sidenav.entries[-1].add_link(Sidenav.Link(name, link))
+ else:
+ Sidenav.entries.append(Sidenav.Link(name, link))
@staticmethod
def addSection(name):
- Sidenav.entries.append((Sidenav.SECTION, name, ""))
+ Sidenav.entries.append(Sidenav.Section(name))
@staticmethod
def setCustomName(name: str):
Sidenav.custom_name = name
@@ -264,26 +302,8 @@ class Sidenav:
@staticmethod
def generate() -> str:
pdebug("Sidenav.generate", f"found the following entries: {Sidenav.entries}")
- sidenav:list[str] = sidenav_format.split('\n')
- content_i = -1
- for i in range(len(sidenav)): # find in which line the entries need to be placed
- if "#sidenav-content" in sidenav[i]:
- content_i = i
- break
- if content_i >= 0:
- indent = sidenav.pop(content_i).replace("#sidenav-content", "")
- added_links = []
- for i in reversed(range(len(Sidenav.entries))):
- entry = Sidenav.entries[i]
- if entry[0] == Sidenav.LINK:
- if entry[2] in added_links: continue # no duplicates
- added_links.append(entry[2])
- sidenav.insert(content_i, indent + sidenav_content_link.replace("#name", entry[1]).replace("#link", entry[2]))
- else:
- sidenav.insert(content_i, indent + sidenav_content_section.replace("#name", entry[1]))
- sidenav_s = ""
- for line in sidenav: sidenav_s += line + "\n" # cant use "".join because of newlines
- return sidenav_s
+ entries = "".join([entry.get() + "\n" for entry in Sidenav.entries])
+ return replace_and_respect_indent(sidenav_format, "#sidenav-content", entries)
@staticmethod
def cmd_sidenav(args:str, variables:dict[str,str]) -> str:
space = args.find(" ")