You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.7 KiB
Python
87 lines
2.7 KiB
Python
from block_markup import *
|
|
|
|
class Parser():
|
|
def __init__(self, template):
|
|
self.template = template
|
|
|
|
def render(self, text):
|
|
paragraphs = re.split("\s*\n\s*\n", text)
|
|
self.toc_items = []
|
|
current_level = 0
|
|
current_paragraph = 0
|
|
current_elements = {0: TreeLevel(0, "root")}
|
|
|
|
for paragraph in paragraphs:
|
|
if paragraph.strip() == "":
|
|
continue
|
|
|
|
current_paragraph += 1
|
|
indentation = len(paragraph) - len(paragraph.lstrip("\t")) + 1
|
|
|
|
if indentation > current_level + 1:
|
|
raise Exception("Invalid indentation found in paragraph %d" % current_paragraph)
|
|
|
|
element_type = TreeLevel
|
|
start = indentation - 1
|
|
|
|
lines = [line[start:] for line in paragraph.splitlines()]
|
|
|
|
if lines[0].startswith("#"):
|
|
element_type = Header
|
|
depth = len(lines[0]) - len(lines[0].lstrip("#"))
|
|
lines[0] = lines[0].lstrip("# ")
|
|
data = " ".join(lines)
|
|
elif lines[0].startswith("^"):
|
|
element_type = Definition
|
|
lines[0] = lines[0].lstrip("^ ")
|
|
data = "\n".join(lines)
|
|
elif lines[0].startswith("@"):
|
|
element_type = Example
|
|
lines[0] = lines[0].lstrip("@ ")
|
|
data = " ".join(lines)
|
|
elif lines[0].startswith("$$") and current_elements[current_level].__class__.__name__ == "Code":
|
|
current_elements[current_level].data += "\n\n" + "\n".join(lines).lstrip("$ ")
|
|
continue
|
|
elif lines[0].startswith("$"):
|
|
element_type = Code
|
|
lines[0] = lines[0].lstrip("$ ")
|
|
data = "\n".join(lines)
|
|
elif lines[0].startswith(">>") and current_elements[current_level].__class__.__name__ == "Output":
|
|
current_elements[current_level].data += "\n\n" + "\n".join(lines).lstrip("> ")
|
|
continue
|
|
elif lines[0].startswith(">"):
|
|
element_type = Output
|
|
lines[0] = lines[0].lstrip("> ")
|
|
data = "\n".join(lines)
|
|
elif lines[0].startswith("!"):
|
|
element_type = Exclamation
|
|
lines[0] = lines[0].lstrip("! ")
|
|
data = " ".join(lines)
|
|
elif re.match(".*::\s*$", lines[0]):
|
|
element_type = Argument
|
|
argname = lines[0][:-2]
|
|
data = " ".join(line.lstrip() for line in lines[1:])
|
|
elif lines[0].strip() == "{TOC}":
|
|
element_type = Index
|
|
data = self
|
|
else:
|
|
element_type = Text
|
|
data = " ".join(lines)
|
|
|
|
if element_type.__name__ == "Header":
|
|
element = Header(indentation, data, depth)
|
|
elif element_type.__name__ == "Argument":
|
|
element = Argument(indentation, data, argname)
|
|
else:
|
|
element = element_type(indentation, data)
|
|
|
|
if element_type.__name__ == "Definition":
|
|
self.toc_items.append(element)
|
|
|
|
current_elements[indentation - 1].add(element)
|
|
|
|
current_level = indentation
|
|
current_elements[current_level] = element
|
|
|
|
return self.template.replace("{CONTENT}", current_elements[0].output())
|