diff --git a/src/__init__.py b/src/__init__.py
new file mode 100644
index 0000000..bda6776
--- /dev/null
+++ b/src/__init__.py
@@ -0,0 +1,2 @@
+# this initializes the submodule __init__
+from src.markdown import *
diff --git a/src/markdown/__init__.py b/src/markdown/__init__.py
new file mode 100644
index 0000000..e187b3d
--- /dev/null
+++ b/src/markdown/__init__.py
@@ -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__))
\ No newline at end of file
diff --git a/src/markdown/code.py b/src/markdown/code.py
index 6b0c5e6..38bd66c 100644
--- a/src/markdown/code.py
+++ b/src/markdown/code.py
@@ -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')
diff --git a/src/markdown/headers.py b/src/markdown/headers.py
index 5f51a5f..5eb8f55 100644
--- a/src/markdown/headers.py
+++ b/src/markdown/headers.py
@@ -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 = {
diff --git a/src/markdown/links.py b/src/markdown/links.py
index e2dfb06..2310950 100644
--- a/src/markdown/links.py
+++ b/src/markdown/links.py
@@ -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('(\[\[)(.*?)(\]\])')
diff --git a/src/markdown/lists.py b/src/markdown/lists.py
index d0fc87f..edae4fe 100644
--- a/src/markdown/lists.py
+++ b/src/markdown/lists.py
@@ -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):
diff --git a/src/markdown/simplestyle.py b/src/markdown/simplestyle.py
index 503433d..17215c6 100644
--- a/src/markdown/simplestyle.py
+++ b/src/markdown/simplestyle.py
@@ -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__('
', '\\')
# inline html is supported with Hugo, don't need the tags.
-class MarkdownInlineHtml:
+@MarkdownConverter.Register
+class MarkdownInlineHtml():
def convert(self, text):
return text.replace('', '').replace('', '')
# 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__('~~', '', '')
+@MarkdownConverter.Register
class MarkdownInlineCode(SimpleStyleBetweenTags):
def __init__(self):
super().__init__('`', "''", "''")
\ No newline at end of file
diff --git a/src/markdown_converter.py b/src/markdown_converter.py
index e40b30d..2ec3a25 100644
--- a/src/markdown_converter.py
+++ b/src/markdown_converter.py
@@ -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
\ No newline at end of file
diff --git a/test/expected_markdown_output.txt b/test/expected_markdown_output.txt
index de57dd9..d2dcb86 100644
--- a/test/expected_markdown_output.txt
+++ b/test/expected_markdown_output.txt
@@ -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.