git-subtree-dir: ziglue git-subtree-mainline:d955ccf17d
git-subtree-split:3238162627
113 lines
2.6 KiB
Python
113 lines
2.6 KiB
Python
import sys
|
|
from enum import Enum, auto
|
|
from idlelib.configdialog import is_int
|
|
from pathlib import Path
|
|
from pprint import pprint
|
|
from typing import Optional
|
|
|
|
|
|
class Block:
|
|
def __init__(self, *parts):
|
|
self.tag = type(self).__name__
|
|
self.data = list(parts)
|
|
|
|
def extend(self, *parts):
|
|
self.data.extend(parts)
|
|
|
|
def __repr__(self):
|
|
return f'{self.tag}:: {''.join(self.data)!r}'
|
|
|
|
|
|
class Break(Block): pass
|
|
|
|
|
|
class ATXHeading(Block): pass
|
|
|
|
|
|
class SetextHeading(Block): pass
|
|
|
|
|
|
class IndentedChunk(Block): pass
|
|
|
|
|
|
class Fence(Block):
|
|
def __init__(self, meta, *data):
|
|
super().__init__(*data)
|
|
self.meta = meta
|
|
self.complete = False
|
|
|
|
def __repr__(self):
|
|
return f'{self.tag}:{self.meta}:: {''.join(self.data)!r}'
|
|
|
|
|
|
class HTML(Block): pass
|
|
|
|
|
|
class Definition(Block): pass
|
|
|
|
|
|
class Paragraph(Block): pass
|
|
|
|
|
|
class Blank(Block): pass
|
|
|
|
|
|
def convert(md: str):
|
|
blocks: list[Block] = []
|
|
|
|
cur_fence: Optional[Fence] = None
|
|
|
|
def get(idx):
|
|
try:
|
|
return blocks[idx]
|
|
except IndexError:
|
|
return None
|
|
|
|
for line in md.splitlines(keepends=True):
|
|
if cur_fence:
|
|
if line.lstrip(' ').startswith('```'):
|
|
blocks.append(cur_fence)
|
|
cur_fence = None
|
|
else:
|
|
cur_fence.extend(line)
|
|
else:
|
|
if line.isspace():
|
|
if len(blocks) >= 1 and isinstance(blocks[-1], Blank):
|
|
blocks[-1].extend(line)
|
|
else:
|
|
blocks.append(Blank(line))
|
|
|
|
elif line.startswith(' ') or line.startswith('\t'):
|
|
if len(blocks) >= 1 and isinstance(blocks[-1], IndentedChunk):
|
|
blocks[-1].extend(line)
|
|
elif len(blocks) >= 2 and isinstance(blocks[-1], Blank) and isinstance(blocks[-2], IndentedChunk):
|
|
blocks[-2].extend(*blocks[-1].data, line)
|
|
blocks.pop(-1)
|
|
else:
|
|
blocks.append(IndentedChunk(line))
|
|
|
|
elif line.lstrip(' ').startswith('```'):
|
|
meta = line.strip().removeprefix('```')
|
|
cur_fence = Fence(meta)
|
|
else:
|
|
if len(blocks) >= 1 and isinstance(blocks[-1], Paragraph):
|
|
blocks[-1].extend(line)
|
|
else:
|
|
blocks.append(Paragraph(line))
|
|
|
|
pprint(blocks)
|
|
|
|
|
|
def main():
|
|
for arg in sys.argv[1:]:
|
|
md = Path(arg).read_text()
|
|
html = convert(md)
|
|
|
|
print('=' * 80)
|
|
print(html)
|
|
print('=' * 80)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|