2021-06-29 13:07:22 -05:00
|
|
|
from fileinput import input as finput
|
2021-06-29 16:48:03 -05:00
|
|
|
import re
|
2021-06-29 13:07:22 -05:00
|
|
|
|
2021-06-29 16:48:03 -05:00
|
|
|
class UntitledError(BaseException): pass
|
2021-06-29 13:07:22 -05:00
|
|
|
class InternalError(UntitledError): pass
|
|
|
|
class ParsingError(UntitledError): pass
|
|
|
|
class MiscError(UntitledError): pass
|
|
|
|
|
|
|
|
class Element:
|
2021-06-30 14:27:26 -05:00
|
|
|
def __init__(self, element, data=None, data2=None):
|
2021-06-29 13:07:22 -05:00
|
|
|
if not data: self.data = ""
|
|
|
|
else: self.data = data
|
2021-06-30 14:27:26 -05:00
|
|
|
if not data2: self.data2 = ""
|
|
|
|
else: self.data2 = data2
|
2021-06-29 13:07:22 -05:00
|
|
|
self.element = element
|
|
|
|
def append(self, string, space=False):
|
2021-06-29 16:48:03 -05:00
|
|
|
if type(data) == str:
|
|
|
|
if space: self.data += " "
|
|
|
|
self.data += string
|
|
|
|
else: raise InternalError("Appending to object!")
|
|
|
|
def set(self, data):
|
|
|
|
self.data = data
|
|
|
|
def __str__(self):
|
|
|
|
return str((str(self.element), str(self.data)))
|
|
|
|
def __repl__(self): return self.__str__()
|
2021-06-30 00:14:07 -05:00
|
|
|
|
2021-06-29 16:48:03 -05:00
|
|
|
class Table:
|
|
|
|
def __init__(self, data=None):
|
|
|
|
if data == None: self.data = []
|
|
|
|
else:
|
|
|
|
self.data = []
|
|
|
|
self.addrow(data)
|
|
|
|
def addrow(self, data):
|
|
|
|
if type(data) == str:
|
|
|
|
buf = [i.rstrip().lstrip() for i in data.split("|")]
|
|
|
|
if len(self.data) > 0:
|
|
|
|
if len(self.data[-1]) == len(buf):
|
|
|
|
self.data.append(buf)
|
|
|
|
else:
|
|
|
|
raise ParsingError("tables must have uniform dimensions throughout")
|
|
|
|
else:
|
|
|
|
self.data.append(buf)
|
|
|
|
elif type(data) == list:
|
|
|
|
if len(self.data) > 0:
|
|
|
|
if len(self.data[-1]) == len(data):
|
|
|
|
self.data.append(data)
|
|
|
|
else:
|
|
|
|
raise ParsingError("tables must have uniform dimensions throughout")
|
|
|
|
else:
|
|
|
|
self.data.append(data)
|
|
|
|
def __str__(self):
|
|
|
|
return str(self.data)
|
|
|
|
def __repl__(self): return self.__str__()
|
2021-06-29 13:07:22 -05:00
|
|
|
|
|
|
|
def printchain(chain):
|
|
|
|
for i in chain:
|
|
|
|
if not i.data == None: print(i.data, i.element)
|
|
|
|
else: print(i.element)
|
|
|
|
|
2021-06-30 00:14:07 -05:00
|
|
|
def renderer(chain):
|
|
|
|
for i in chain:
|
|
|
|
rendered = False
|
|
|
|
if i.element == "h1":
|
|
|
|
rendered = True
|
|
|
|
print("+" + (len(i.data) + 2) * "-" + "+")
|
|
|
|
print("| " + i.data + " |")
|
|
|
|
print("+" + (len(i.data) + 2) * "-" + "+")
|
|
|
|
elif i.element == "h2":
|
|
|
|
rendered = True
|
|
|
|
print(" " + i.data + " ")
|
|
|
|
print("=" * (len(i.data) + 2))
|
|
|
|
elif i.element == "h3":
|
|
|
|
rendered = True
|
|
|
|
print(" " + i.data + " ")
|
|
|
|
print("-" * (len(i.data) + 2))
|
|
|
|
elif "h" in i.element:
|
|
|
|
raise ParsingError("you cannot have more than three levels of headers")
|
|
|
|
elif i.element == "p":
|
|
|
|
rendered = True
|
|
|
|
isplit = i.data.split(' ')
|
|
|
|
buf = ""
|
|
|
|
|
|
|
|
for i in isplit:
|
|
|
|
if (len(i) + len(buf) + 1) <= 63:
|
|
|
|
if not len(buf) == 0: buf += " "
|
|
|
|
buf += i
|
|
|
|
else:
|
|
|
|
print(buf)
|
|
|
|
buf = ""
|
|
|
|
buf += i
|
|
|
|
print(buf)
|
|
|
|
elif i.element == "t":
|
2021-06-30 13:47:34 -05:00
|
|
|
rendered = True
|
2021-06-30 00:14:07 -05:00
|
|
|
buf = [0] * len(i.data.data[0])
|
|
|
|
for j in i.data.data:
|
|
|
|
c = 0
|
|
|
|
for k in j:
|
|
|
|
if len(k) > buf[c]: buf[c] = len(k)
|
|
|
|
c += 1
|
|
|
|
width = 0
|
|
|
|
for j in buf:
|
|
|
|
width += j
|
|
|
|
width += 2 * len(i.data.data[0]) + 1
|
|
|
|
print("+" + "-" * width + "+")
|
|
|
|
# don't ask
|
|
|
|
for j in range(len(i.data.data)):
|
|
|
|
c = 0
|
|
|
|
for k in range(len(i.data.data[j])):
|
|
|
|
if len(i.data.data[j][k]) < buf[c]:
|
|
|
|
i.data.data[j][k] = i.data.data[j][k].ljust(buf[c], " ")
|
|
|
|
cbuf = ""
|
|
|
|
for j in i.data.data:
|
|
|
|
cbuf = "| " + ' | '.join(j) + " |"
|
|
|
|
print(cbuf)
|
|
|
|
print("+" + "-" * width + "+")
|
2021-06-30 13:47:34 -05:00
|
|
|
elif i.element == "l":
|
|
|
|
rendered = True
|
|
|
|
buf = i.data.split(' ')
|
|
|
|
cbuf = "* "
|
|
|
|
for i in buf:
|
|
|
|
if (len(cbuf) + len(i) + 1) <= 63:
|
|
|
|
if not len(cbuf) == 2: cbuf += " "
|
|
|
|
cbuf += i
|
|
|
|
else:
|
|
|
|
print(cbuf)
|
|
|
|
cbuf = " "
|
|
|
|
cbuf += i
|
|
|
|
print(cbuf)
|
2021-06-30 15:48:21 -05:00
|
|
|
elif i.element == "r":
|
|
|
|
rendered = True
|
|
|
|
print("=>", i.data, i.data2)
|
2021-06-30 15:03:21 -05:00
|
|
|
elif i.element == "x":
|
|
|
|
print(i.data)
|
2021-06-30 00:14:07 -05:00
|
|
|
if rendered: print()
|
|
|
|
|
2021-06-29 13:07:22 -05:00
|
|
|
chain = []
|
2021-06-29 16:48:03 -05:00
|
|
|
flags = {
|
|
|
|
"TABLE_PREV": False,
|
2021-06-30 13:53:02 -05:00
|
|
|
"PARA_PREV": False,
|
2021-06-30 15:03:21 -05:00
|
|
|
"IN_PREFORMATTED": False,
|
2021-06-29 16:48:03 -05:00
|
|
|
}
|
|
|
|
def main():
|
|
|
|
for i in finput():
|
|
|
|
i = i.rstrip()
|
|
|
|
|
2021-06-30 15:45:57 -05:00
|
|
|
# ignore blank lines (but not seperating paragraphs)
|
|
|
|
if len(i) == 0 and not flags["IN_PREFORMATTED"]:
|
|
|
|
if flags["PARA_PREV"]:
|
|
|
|
flags["PARA_PREV"] = False
|
|
|
|
continue
|
2021-06-29 16:48:03 -05:00
|
|
|
|
|
|
|
# lines with text
|
2021-06-30 15:03:21 -05:00
|
|
|
if i[0].isalpha() and not flags["IN_PREFORMATTED"]:
|
2021-06-30 13:53:02 -05:00
|
|
|
if not flags["PARA_PREV"]:
|
|
|
|
flags["PARA_PREV"] = True
|
|
|
|
chain.append(Element("p", i))
|
|
|
|
else:
|
|
|
|
if not chain[-1].data[-1] == " ":
|
|
|
|
chain[-1].data += " " + i
|
|
|
|
else:
|
|
|
|
chain[-1].data += i
|
|
|
|
continue
|
2021-06-29 16:48:03 -05:00
|
|
|
|
2021-06-30 15:03:21 -05:00
|
|
|
if i[0:3] == '```':
|
|
|
|
if not flags["IN_PREFORMATTED"]:
|
|
|
|
flags["IN_PREFORMATTED"] = True
|
|
|
|
params = i[3:]
|
|
|
|
chain.append(Element("x", "", params))
|
|
|
|
else:
|
|
|
|
flags["IN_PREFORMATTED"] = False
|
|
|
|
continue
|
|
|
|
|
2021-06-29 16:48:03 -05:00
|
|
|
# we have a processing command
|
2021-06-30 15:03:21 -05:00
|
|
|
if not i[0].isalpha() and not flags["IN_PREFORMATTED"]:
|
2021-06-29 16:48:03 -05:00
|
|
|
command = ""
|
|
|
|
params = ""
|
|
|
|
counter = 0
|
|
|
|
for j in i:
|
|
|
|
if not j.isalpha() \
|
|
|
|
and not j == ' ':
|
|
|
|
command += j
|
2021-06-29 13:07:22 -05:00
|
|
|
else:
|
2021-06-29 16:48:03 -05:00
|
|
|
if j == ' ':
|
|
|
|
params = i[counter + 1:]
|
|
|
|
else:
|
|
|
|
params = i[counter:]
|
|
|
|
break
|
|
|
|
counter += 1
|
|
|
|
if command[0] == "#": chain.append(Element("h" + str(len(command)), params))
|
|
|
|
elif command == "%": chain.append(Element("c", params))
|
|
|
|
elif command == "*": chain.append(Element("l", params))
|
|
|
|
elif command == "-": chain.append(Element("l", params))
|
|
|
|
elif command == ">": chain.append(Element("q", params))
|
2021-06-30 15:45:57 -05:00
|
|
|
elif command == "=":
|
|
|
|
splitted = params.split(' ')
|
|
|
|
url = splitted[0]
|
|
|
|
desc = ' '.join(splitted[1:])
|
|
|
|
chain.append(Element("r", url, desc))
|
2021-06-29 16:48:03 -05:00
|
|
|
elif command == "|":
|
|
|
|
if flags["TABLE_PREV"]:
|
|
|
|
chain[-1].data.addrow(params)
|
|
|
|
continue
|
|
|
|
else:
|
|
|
|
chain.append(Element("t", Table(params)))
|
|
|
|
flags["TABLE_PREV"] = True
|
|
|
|
continue
|
|
|
|
flags["TABLE_PREV"] = False
|
2021-06-30 13:53:02 -05:00
|
|
|
flags["PARA_PREV"] = False
|
2021-06-30 00:14:07 -05:00
|
|
|
continue
|
2021-06-30 15:03:21 -05:00
|
|
|
elif flags["IN_PREFORMATTED"]:
|
|
|
|
chain[-1].data += i + "\n"
|
2021-06-30 00:14:07 -05:00
|
|
|
renderer(chain)
|
2021-06-29 16:48:03 -05:00
|
|
|
|
|
|
|
if __name__ == "__main__": main()
|