Skip to content
Snippets Groups Projects
Verified Commit 7592830b authored by Jake's avatar Jake
Browse files

Merge branch 'master' into documentation

parents c9647b16 5139ec5c
No related branches found
No related tags found
No related merge requests found
Pipeline #319950 passed
...@@ -37,15 +37,18 @@ def run_pandoc(source, factories, lang, base="markdown", extensions=[], extra_ar ...@@ -37,15 +37,18 @@ def run_pandoc(source, factories, lang, base="markdown", extensions=[], extra_ar
if json.dumps(out_dict["pandoc-api-version"]) != "[1, 22, 2]": if json.dumps(out_dict["pandoc-api-version"]) != "[1, 22, 2]":
raise Exception("Unsupported pandoc-api version", out_dict["pandoc-api-version"]) raise Exception("Unsupported pandoc-api version", out_dict["pandoc-api-version"])
custom_syntax_handler = CustomSyntaxHandler(factories, lang, custom_syntax_register)
# parse blocks # parse blocks
raw_blocks = out_dict['blocks'] raw_blocks = out_dict['blocks']
blocks = [] blocks = []
for raw_block in raw_blocks: for raw_block in raw_blocks:
#print('raw_block: ', type(raw_block), raw_block) #print('raw_block: ', type(raw_block), raw_block)
block = parse_from_register(factories, lang, block_parsing_register, raw_block) block = parse_from_register(factories, lang, block_parsing_register, raw_block, custom_syntax_handler)
if block != None: if block != None:
blocks.append(block) blocks.append(block)
contentmetadata = {} contentmetadata = {}
contentmetadata["toc_list"] = [] contentmetadata["toc_list"] = []
contentmetadata["toc_count"] = 0 contentmetadata["toc_count"] = 0
...@@ -57,7 +60,7 @@ def run_pandoc(source, factories, lang, base="markdown", extensions=[], extra_ar ...@@ -57,7 +60,7 @@ def run_pandoc(source, factories, lang, base="markdown", extensions=[], extra_ar
return (blocks, contentmetadata) return (blocks, contentmetadata)
def parse_from_register(factories, lang, reg: dict, h: dict): def parse_from_register(factories, lang, reg: dict, h: dict, custom_syntax_handler):
t = h['t'] # pandoc type t = h['t'] # pandoc type
if t not in reg: if t not in reg:
raise Exception("pandoc type not in register", t, h) raise Exception("pandoc type not in register", t, h)
...@@ -75,13 +78,16 @@ def parse_from_register(factories, lang, reg: dict, h: dict): ...@@ -75,13 +78,16 @@ def parse_from_register(factories, lang, reg: dict, h: dict):
return None return None
handler = entry['handler'] handler = entry['handler']
res = handler(factories, lang, entry['etype']) res = handler(factories, lang, custom_syntax_handler, entry['etype'])
else: else:
handler = entry handler = entry
res = handler(factories, lang) res = handler(factories, lang, custom_syntax_handler)
res.parse(c) res.parse(c)
# Handle custom syntax
res = custom_syntax_handler.handle(res)
return res return res
...@@ -95,9 +101,10 @@ def parse_from_register(factories, lang, reg: dict, h: dict): ...@@ -95,9 +101,10 @@ def parse_from_register(factories, lang, reg: dict, h: dict):
# return super().default(obj) # return super().default(obj)
class Element(): class Element():
def __init__(self, factories, lang, etype = None): def __init__(self, factories, lang, custom_syntax_handler, etype = None):
self.factories = factories self.factories = factories
self.lang = lang self.lang = lang
self.custom_syntax_handler = custom_syntax_handler
if etype != None: if etype != None:
self.etype = etype self.etype = etype
self.children = [] self.children = []
...@@ -146,11 +153,11 @@ class Element(): ...@@ -146,11 +153,11 @@ class Element():
return res return res
def parse_block(self, raw_block): def parse_block(self, raw_block):
res = parse_from_register(self.factories, self.lang, block_parsing_register, raw_block) res = parse_from_register(self.factories, self.lang, block_parsing_register, raw_block, self.custom_syntax_handler)
self.addChild(res) self.addChild(res)
return res return res
def parse_inline(self, raw_inline): def parse_inline(self, raw_inline):
res = parse_from_register(self.factories, self.lang, inline_parsing_register, raw_inline) res = parse_from_register(self.factories, self.lang, inline_parsing_register, raw_inline, self.custom_syntax_handler)
self.addChild(res) self.addChild(res)
return res return res
...@@ -539,6 +546,120 @@ class InlineRaw(Inline): # Format Text ...@@ -539,6 +546,120 @@ class InlineRaw(Inline): # Format Text
self.format = self.parse_text(pandocraw[0]) self.format = self.parse_text(pandocraw[0])
self.raw = self.parse_text(pandocraw[1]) self.raw = self.parse_text(pandocraw[1])
############################# CUSTOM SYNTAX ####################################
class CustomSyntaxHandler:
def __init__(self, factories, lang, custom_syntax_register):
self.factories = factories
self.lang = lang
self.register = custom_syntax_register
# Executed after the parsing of every element.
# Returns either origelement or the new one to replace it.
def handle(self, origelement):
for curreg in self.register:
if self.run_tests(curreg, origelement):
#raise Exception("Found replacement!!!", curreg, origelement)
print("DEBUG: Found custom syntax!!!", curreg, origelement)
res = curreg["replace_with"](self.factories, self.lang, self) # create new replacement element
res.replace(origelement, curreg) # tell it what it is replacing
return res # return new replacement element
return origelement # no custom syntax detected
def run_test(self, test, origelement):
if "key" not in test:
# This is just another test container.
return self.run_tests(test, origelement)
tkey = test["key"]
if not hasattr(origelement, tkey):
raise Exception("Key not in Element:", tkey, origelement, test)
obj = getattr(origelement, tkey)
ttype = test["type"]
#print("DEBUG: Running test: ", ttype, "tkey:", tkey, "test:", test, "obj:", obj, "origelement:",origelement)
if ttype == "str": # Test: str
if not isinstance(obj, str):
raise Exception("Object is not a string:", obj, type(obj), origelement, test)
if "is" in test:
return test["is"] == obj
elif "contains" in test:
return test["contains"] in obj
else:
raise Exception("Don't know what to do with this test:", ttype, test, obj, origelement)
if ttype == "list": # Test: list
if not isinstance(obj, list):
raise Exception("Object is not a list:", obj, type(obj), origelement, test)
olen = len(obj)
if "len" in test and test["len"] != olen:
return False
if "len_min" in test and test["len_min"] > olen:
return False
if "len_max" in test and test["len_max"] < olen:
return False
if olen == 0:
return False
if "for_each" in test:
if olen == 0:
return False
tfor = test["for_each"]
for element in obj:
if not self.run_tests(tfor, element):
return False
if "first" in test:
if not self.run_tests(test["first"], obj[0]):
return False
if "last" in test:
if not self.run_tests(test["last"], obj[-1]):
return False
return True
else: # unknown Test
raise Exception("Unknown Test Type:", ttype, test)
def run_tests(self, testcontainer, origelement):
res = False
if "tests_all" in testcontainer:
res = self.run_tests_all(testcontainer["tests_all"], origelement)
elif "tests_any" in testcontainer:
res = self.run_tests_any(testcontainer["tests_any"], origelement)
else:
raise Exception("No tests found:", testcontainer, origelement)
#print("DEBUG: run_tests returned ",res," with ", testcontainer, " on ", origelement)
return res
def run_tests_all(self, tests, origelement):
for test in tests:
if not self.run_test(test, origelement):
return False
return True
def run_tests_any(self, tests, origelement):
for test in tests:
if self.run_test(test, origelement):
return True
return False
class CustomBlockTOC(Block):
etype = "toc"
def replace(self, origelement, custom_sytax_register_entry):
pass # TODO continue
############################## REGISTER #######################################
inline_parsing_register = { inline_parsing_register = {
"Space" : InlineSpace, "Space" : InlineSpace,
...@@ -579,3 +700,29 @@ block_parsing_register = { ...@@ -579,3 +700,29 @@ block_parsing_register = {
#"Null" :{"type":"nothing" }, # TODO find file that triggers Null #"Null" :{"type":"nothing" }, # TODO find file that triggers Null
} }
# Define custom syntax
custom_syntax_register = [
# Jeder Eintrag in dieser Liste beschreibt eine custom syntax. Die gesamte Liste wird nach jedem parsen eines Elementes getestet. Falls die Tests erfolgreich sind, wird das Element mit 'replace_with' ersetzt.
{
# Table of Contents via a Paragraph containing '[TOC]' as its only content.
"replace_with": CustomBlockTOC,
# "tests_any": []
"tests_all": [
{ "key": "eclass", "type": "str", "is": "block" },
{ "key": "etype", "type": "str", "is": "paragraph" },
{ "key": "content","type": "list",
"len": 1,
#"len_min": 1,
#"len_max": 1,
#"for_each": { "tests_all": [ ] },
"first": { "tests_all": [
{ "key": "eclass", "type": "str", "is": "inline" },
{ "key": "etype", "type": "str", "is": "string" },
{ "key": "text", "type": "str", "is": "[TOC]" }
]}
#"last": { "tests_all": [ ] },
}
]
}
]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment