wiring everything together using a class decorator
parent
635e746756
commit
aa00a107f0
|
@ -0,0 +1,2 @@
|
|||
# this initializes the submodule __init__
|
||||
from src.markdown import *
|
|
@ -0,0 +1,11 @@
|
|||
# https://docs.python.org/3/tutorial/modules.html
|
||||
# you need to define __all__ to be able to let from x import * work...
|
||||
# there is no out-of-the-box dynamic solution
|
||||
# see http://stackoverflow.com/questions/1057431/loading-all-modules-in-a-folder-in-python
|
||||
|
||||
from os.path import dirname, basename, isfile
|
||||
import glob
|
||||
|
||||
modules = glob.glob(dirname(__file__)+"/*.py")
|
||||
__all__ = [ basename(f)[:-3] for f in modules if isfile(f) and not f.endswith('__init__.py')]
|
||||
print('loaded markdown converters: ' + ', '.join(__all__))
|
|
@ -1,6 +1,8 @@
|
|||
from abc import ABC
|
||||
from re import compile
|
||||
|
||||
from src.markdown_converter import MarkdownConverter
|
||||
|
||||
class BaseMarkdownCode(ABC):
|
||||
markdown = "```"
|
||||
|
||||
|
@ -24,10 +26,12 @@ class BaseMarkdownCode(ABC):
|
|||
result = result.replace(match[0], BaseMarkdownCode.markdown + language)
|
||||
return result.replace('</' + self.tag + '>', BaseMarkdownCode.markdown)
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownFile(BaseMarkdownCode):
|
||||
def __init__(self):
|
||||
super().__init__('file')
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownCode(BaseMarkdownCode):
|
||||
def __init__(self):
|
||||
super().__init__('code')
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
from collections import OrderedDict
|
||||
from re import compile
|
||||
|
||||
class MarkdownHeader:
|
||||
from src.markdown_converter import MarkdownConverter
|
||||
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownHeader():
|
||||
pattern = compile('(=+)(.*?)(=+)')
|
||||
head = "="
|
||||
config = {
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import os
|
||||
from os import walk
|
||||
import re
|
||||
from os import walk
|
||||
|
||||
class MarkdownLinks:
|
||||
from src.markdown_converter import MarkdownConverter
|
||||
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownLinks():
|
||||
# see http://pythex.org/
|
||||
pattern = re.compile('(\[\[)(.*?)(\]\])')
|
||||
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
import re
|
||||
|
||||
class MarkdownOrderedList:
|
||||
from src.markdown_converter import MarkdownConverter
|
||||
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownOrderedList():
|
||||
pattern = re.compile('(^-\s)(.*)', re.MULTILINE)
|
||||
|
||||
def convert(self, text):
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
from abc import ABC
|
||||
from re import compile
|
||||
|
||||
from src.markdown_converter import MarkdownConverter
|
||||
|
||||
|
||||
class NopStyle(ABC):
|
||||
def convert(self, text):
|
||||
return text
|
||||
|
@ -29,27 +32,33 @@ class SimpleStyleBetweenTags(ABC):
|
|||
result = result.replace(orig_header, new_header)
|
||||
return result
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownLineBreak(SimpleReplacementStyle):
|
||||
def __init__(self):
|
||||
super().__init__('<br/>', '\\')
|
||||
|
||||
# inline html is supported with Hugo, don't need the tags.
|
||||
class MarkdownInlineHtml:
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownInlineHtml():
|
||||
def convert(self, text):
|
||||
return text.replace('<html>', '').replace('</html>', '')
|
||||
|
||||
# bold in Doku is bold in MD
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownBold(NopStyle):
|
||||
pass
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownItalic(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__('*', '//')
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownStrikeThrough(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__('~~', '<del>', '</del>')
|
||||
|
||||
@MarkdownConverter.Register
|
||||
class MarkdownInlineCode(SimpleStyleBetweenTags):
|
||||
def __init__(self):
|
||||
super().__init__('`', "''", "''")
|
|
@ -1,33 +1,19 @@
|
|||
from functools import reduce
|
||||
|
||||
from src.markdown.links import MarkdownLinks
|
||||
|
||||
from src.markdown.headers import MarkdownHeader
|
||||
from src.markdown.simplestyle import MarkdownItalic, MarkdownBold, MarkdownStrikeThrough
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
class MarkdownConverter:
|
||||
converters = []
|
||||
|
||||
@classmethod
|
||||
def Register(cls, converter_class):
|
||||
cls.converters.append(converter_class())
|
||||
return converter_class
|
||||
|
||||
def __init__(self, file):
|
||||
self.file = file
|
||||
self.converters = (
|
||||
# TODO auto-discover these. How do I do that, without interfaces?
|
||||
MarkdownHeader(),
|
||||
MarkdownLinks(),
|
||||
MarkdownItalic(),
|
||||
MarkdownBold(),
|
||||
MarkdownStrikeThrough()
|
||||
)
|
||||
|
||||
def convert(self):
|
||||
converted = []
|
||||
with open(self.file, 'r') as file:
|
||||
for line in file:
|
||||
converted.append(self.convert_line(line))
|
||||
|
||||
return "\n".join(converted)
|
||||
|
||||
def convert_line(self, line):
|
||||
convertfns = map(lambda converter: converter.convert, self.converters)
|
||||
massconvert = reduce(lambda red1, red2: lambda text: red1(red2(line)), convertfns, lambda text: text)
|
||||
return massconvert(line)
|
||||
text = Path(self.file).read_text()
|
||||
# TODO solve this functional-style instead of mutating text
|
||||
for converter in MarkdownConverter.converters:
|
||||
text = converter.convert(text)
|
||||
return text
|
|
@ -1,7 +1,7 @@
|
|||
# header 1
|
||||
# header 1
|
||||
|
||||
##### header 5
|
||||
##### header 5
|
||||
|
||||
[hi]({{< relref "hello world" >}}) this is a test!
|
||||
|
||||
{{< wp Dogs >}} are cool, look it up. [sublink]({{< relref "link/sub" >}} example.
|
||||
{{< wp Dogs >}} are cool, look it up. [sublink]({{< relref "link/sub" >}}) example.
|
||||
|
|
Loading…
Reference in New Issue