wiring everything together using a class decorator
This commit is contained in:
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 abc import ABC
|
||||||
from re import compile
|
from re import compile
|
||||||
|
|
||||||
|
from src.markdown_converter import MarkdownConverter
|
||||||
|
|
||||||
class BaseMarkdownCode(ABC):
|
class BaseMarkdownCode(ABC):
|
||||||
markdown = "```"
|
markdown = "```"
|
||||||
|
|
||||||
|
@ -24,10 +26,12 @@ class BaseMarkdownCode(ABC):
|
||||||
result = result.replace(match[0], BaseMarkdownCode.markdown + language)
|
result = result.replace(match[0], BaseMarkdownCode.markdown + language)
|
||||||
return result.replace('</' + self.tag + '>', BaseMarkdownCode.markdown)
|
return result.replace('</' + self.tag + '>', BaseMarkdownCode.markdown)
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownFile(BaseMarkdownCode):
|
class MarkdownFile(BaseMarkdownCode):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__('file')
|
super().__init__('file')
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownCode(BaseMarkdownCode):
|
class MarkdownCode(BaseMarkdownCode):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__('code')
|
super().__init__('code')
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
from collections import OrderedDict
|
|
||||||
from re import compile
|
from re import compile
|
||||||
|
|
||||||
class MarkdownHeader:
|
from src.markdown_converter import MarkdownConverter
|
||||||
|
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
|
class MarkdownHeader():
|
||||||
pattern = compile('(=+)(.*?)(=+)')
|
pattern = compile('(=+)(.*?)(=+)')
|
||||||
head = "="
|
head = "="
|
||||||
config = {
|
config = {
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
import os
|
|
||||||
from os import walk
|
|
||||||
import re
|
import re
|
||||||
|
from os import walk
|
||||||
|
|
||||||
class MarkdownLinks:
|
from src.markdown_converter import MarkdownConverter
|
||||||
|
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
|
class MarkdownLinks():
|
||||||
# see http://pythex.org/
|
# see http://pythex.org/
|
||||||
pattern = re.compile('(\[\[)(.*?)(\]\])')
|
pattern = re.compile('(\[\[)(.*?)(\]\])')
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
import re
|
import re
|
||||||
|
|
||||||
class MarkdownOrderedList:
|
from src.markdown_converter import MarkdownConverter
|
||||||
|
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
|
class MarkdownOrderedList():
|
||||||
pattern = re.compile('(^-\s)(.*)', re.MULTILINE)
|
pattern = re.compile('(^-\s)(.*)', re.MULTILINE)
|
||||||
|
|
||||||
def convert(self, text):
|
def convert(self, text):
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
from abc import ABC
|
from abc import ABC
|
||||||
from re import compile
|
from re import compile
|
||||||
|
|
||||||
|
from src.markdown_converter import MarkdownConverter
|
||||||
|
|
||||||
|
|
||||||
class NopStyle(ABC):
|
class NopStyle(ABC):
|
||||||
def convert(self, text):
|
def convert(self, text):
|
||||||
return text
|
return text
|
||||||
|
@ -29,27 +32,33 @@ class SimpleStyleBetweenTags(ABC):
|
||||||
result = result.replace(orig_header, new_header)
|
result = result.replace(orig_header, new_header)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownLineBreak(SimpleReplacementStyle):
|
class MarkdownLineBreak(SimpleReplacementStyle):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__('<br/>', '\\')
|
super().__init__('<br/>', '\\')
|
||||||
|
|
||||||
# inline html is supported with Hugo, don't need the tags.
|
# inline html is supported with Hugo, don't need the tags.
|
||||||
class MarkdownInlineHtml:
|
@MarkdownConverter.Register
|
||||||
|
class MarkdownInlineHtml():
|
||||||
def convert(self, text):
|
def convert(self, text):
|
||||||
return text.replace('<html>', '').replace('</html>', '')
|
return text.replace('<html>', '').replace('</html>', '')
|
||||||
|
|
||||||
# bold in Doku is bold in MD
|
# bold in Doku is bold in MD
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownBold(NopStyle):
|
class MarkdownBold(NopStyle):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownItalic(SimpleStyleBetweenTags):
|
class MarkdownItalic(SimpleStyleBetweenTags):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__('*', '//')
|
super().__init__('*', '//')
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownStrikeThrough(SimpleStyleBetweenTags):
|
class MarkdownStrikeThrough(SimpleStyleBetweenTags):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__('~~', '<del>', '</del>')
|
super().__init__('~~', '<del>', '</del>')
|
||||||
|
|
||||||
|
@MarkdownConverter.Register
|
||||||
class MarkdownInlineCode(SimpleStyleBetweenTags):
|
class MarkdownInlineCode(SimpleStyleBetweenTags):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__('`', "''", "''")
|
super().__init__('`', "''", "''")
|
|
@ -1,33 +1,19 @@
|
||||||
from functools import reduce
|
from pathlib import Path
|
||||||
|
|
||||||
from src.markdown.links import MarkdownLinks
|
|
||||||
|
|
||||||
from src.markdown.headers import MarkdownHeader
|
|
||||||
from src.markdown.simplestyle import MarkdownItalic, MarkdownBold, MarkdownStrikeThrough
|
|
||||||
|
|
||||||
|
|
||||||
class MarkdownConverter:
|
class MarkdownConverter:
|
||||||
|
converters = []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def Register(cls, converter_class):
|
||||||
|
cls.converters.append(converter_class())
|
||||||
|
return converter_class
|
||||||
|
|
||||||
def __init__(self, file):
|
def __init__(self, file):
|
||||||
self.file = 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):
|
def convert(self):
|
||||||
converted = []
|
text = Path(self.file).read_text()
|
||||||
with open(self.file, 'r') as file:
|
# TODO solve this functional-style instead of mutating text
|
||||||
for line in file:
|
for converter in MarkdownConverter.converters:
|
||||||
converted.append(self.convert_line(line))
|
text = converter.convert(text)
|
||||||
|
return text
|
||||||
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)
|
|
|
@ -4,4 +4,4 @@
|
||||||
|
|
||||||
[hi]({{< relref "hello world" >}}) this is a test!
|
[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