summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJensDiemer <git@jensdiemer.de>2011-05-26 18:00:03 +0200
committerJensDiemer <git@jensdiemer.de>2011-05-26 18:00:03 +0200
commit5549d55cf548f3b500f677638674655117dffa72 (patch)
treebf71163a684b2e395258c1da3e91ce8320bdd7f7
parent9c8396bbeb859c4dc030a8b9848b14147b126d88 (diff)
downloadcreole-restructure.tar.gz
* remove the support for callable macros. Only dict and modules are allowed.restructure
* No macros used as default in creole2html converting. * macros gets arguments as real keyword arguments and not only the string as \"args\"
-rw-r--r--README7
-rw-r--r--creole/creole2html/emitter.py19
-rw-r--r--creole/creole2html/example_macros.py (renamed from creole/creole2html/default_macros.py)8
-rw-r--r--creole/creole2html/str2dict.py68
-rw-r--r--tests/test_creole2html.py106
-rw-r--r--tests/test_cross_compare.py5
-rw-r--r--tests/test_macros.py39
-rw-r--r--tests/utils/base_unittest.py13
8 files changed, 171 insertions, 94 deletions
diff --git a/README b/README
index 1e37ade..7d09960 100644
--- a/README
+++ b/README
@@ -63,7 +63,12 @@ Contributers should take a look at this page:
- v0.5
- - API changed: Html2CreoleEmitter optinal argument 'unknown_emit' taks now a callable for handle unknown html tags.
+ - API changed:
+
+ - Html2CreoleEmitter optinal argument 'unknown_emit' taks now a callable for handle unknown html tags.
+ - No macros used as default in creole2html converting.
+ - We remove the support for callable macros. Only dict and modules are allowed.
+
- remove unknown html tags is default behaviour in html2creole converting.
- restructure and cleanup sourcecode files.
diff --git a/creole/creole2html/emitter.py b/creole/creole2html/emitter.py
index cb5ef46..7c1b849 100644
--- a/creole/creole2html/emitter.py
+++ b/creole/creole2html/emitter.py
@@ -14,8 +14,8 @@ import sys
import traceback
-from creole.creole2html import default_macros
from creole.creole2html.parser import CreoleParser
+from creole.creole2html.str2dict import str2dict
class HtmlEmitter:
@@ -23,7 +23,7 @@ class HtmlEmitter:
Generate HTML output for the document
tree consisting of DocNodes.
"""
- def __init__(self, root, macros=default_macros, verbose=1, stderr=sys.stderr):
+ def __init__(self, root, macros=None, verbose=1, stderr=sys.stderr):
self.root = root
self.macros = macros
self.verbose = verbose
@@ -154,11 +154,18 @@ class HtmlEmitter:
def macro_emit(self, node):
#print node.debug()
macro_name = node.macro_name
+ text = node.content
macro = None
- if callable(self.macros):
- macro = lambda args, text: self.macros(macro_name, args=args, text=text)
- elif isinstance(self.macros, dict):
+ args = node.macro_args
+ macro_kwargs = str2dict(args)
+ macro_kwargs["text"] = text
+
+ if callable(self.macros) == True:
+ raise DeprecationWarning("Callable macros are not supported anymore!")
+ return
+
+ if isinstance(self.macros, dict):
try:
macro = self.macros[macro_name]
except KeyError, e:
@@ -176,7 +183,7 @@ class HtmlEmitter:
)
try:
- result = macro(args=node.macro_args, text=node.content)
+ result = macro(**macro_kwargs)
except Exception, err:
return self.error(
u"Macro '%s' error: %s" % (macro_name, err),
diff --git a/creole/creole2html/default_macros.py b/creole/creole2html/example_macros.py
index 41ea022..54249c9 100644
--- a/creole/creole2html/default_macros.py
+++ b/creole/creole2html/example_macros.py
@@ -12,16 +12,10 @@
"""
-def html(args, text):
+def html(text):
"""
Macro tag <<html>>...<</html>>
Pass-trought for html code (or other stuff)
"""
return text
-
-def test_macro(args, text):
- """
- a macro only for testing
- """
- return u"[%s text: %s]" % (args, text)
diff --git a/creole/creole2html/str2dict.py b/creole/creole2html/str2dict.py
new file mode 100644
index 0000000..025ef30
--- /dev/null
+++ b/creole/creole2html/str2dict.py
@@ -0,0 +1,68 @@
+# coding: utf-8
+
+
+"""
+ Creole Rules for parser
+ ~~~~~~~~~~~~~~~~~~~~~~~
+
+ Helper take from PyLucid CMS project
+
+ :copyleft: 2011 by python-creole team, see AUTHORS for more details.
+ :license: GNU GPL v3 or above, see LICENSE for more details.
+"""
+
+
+import shlex
+
+
+# For str2dict()
+KEYWORD_MAP = {
+ "True": True,
+ "False": False,
+ "None": None,
+}
+
+def str2dict(raw_content, encoding="utf-8"):
+ """
+ convert a string into a dictionary. e.g.:
+
+ >>> str2dict('key1="value1" key2="value2"')
+ {'key2': 'value2', 'key1': 'value1'}
+
+ >>> str2dict(u'A="B" C=1 D=1.1 E=True F=False G=None')
+ {'A': 'B', 'C': 1, 'E': True, 'D': '1.1', 'G': None, 'F': False}
+
+ >>> str2dict('''key1="'1'" key2='"2"' key3="""'3'""" ''')
+ {'key3': 3, 'key2': 2, 'key1': 1}
+
+ >>> str2dict(u'unicode=True')
+ {'unicode': True}
+ """
+ if isinstance(raw_content, unicode):
+ # shlex.split doesn't work with unicode?!?
+ raw_content = raw_content.encode(encoding)
+
+ parts = shlex.split(raw_content)
+
+ result = {}
+ for part in parts:
+ key, value = part.split("=", 1)
+
+ if value in KEYWORD_MAP:
+ # True False or None
+ value = KEYWORD_MAP[value]
+ else:
+ # A number?
+ try:
+ value = int(value.strip("'\""))
+ except ValueError:
+ pass
+
+ result[key] = value
+
+ return result
+
+
+if __name__ == "__main__":
+ import doctest
+ print doctest.testmod()
diff --git a/tests/test_creole2html.py b/tests/test_creole2html.py
index 2a93507..fc1ea5b 100644
--- a/tests/test_creole2html.py
+++ b/tests/test_creole2html.py
@@ -22,8 +22,10 @@ import unittest
import StringIO
from tests.utils.base_unittest import BaseCreoleTest
+from tests import test_macros
from creole import creole2html
+from creole.creole2html import example_macros
class TestCreole2html(unittest.TestCase):
@@ -55,74 +57,61 @@ class TestCreole2html(unittest.TestCase):
"String %r not found in:\n******\n%s******" % (part, error_msg)
)
- def test_default_macro1(self):
+ def test_example_macros1(self):
"""
Test the default "html" macro, found in ./creole/default_macros.py
"""
html = creole2html(
markup_string=u"<<html>><p>foo</p><</html>><bar?>",
verbose=1,
+ macros=example_macros
# stderr=sys.stderr, debug=False
)
self.assertEqual(html, u'<p>foo</p>\n<p>&lt;bar?&gt;</p>\n')
- def test_default_macro2(self):
+ def test_example_macros2(self):
html = creole2html(
markup_string=u"<<html>>{{{&lt;nocode&gt;}}}<</html>>",
verbose=1,
+ macros=example_macros
# stderr=sys.stderr, debug=False
)
self.assertEqual(html, u'{{{&lt;nocode&gt;}}}\n')
- def test_default_macro3(self):
+ def test_example_macros3(self):
html = creole2html(
markup_string=u"<<html>>1<</html>><<html>>2<</html>>",
verbose=1,
+ macros=example_macros,
# stderr=sys.stderr, debug=False
)
self.assertEqual(html, u'1\n2\n')
- def test_macro_class(self):
- """
- simple test for the "macro API"
- """
- class TestMacro(object):
- def test(self, args, text):
- return u"XXX%s|%sXXX" % (args, text)
-
- html = creole2html(
- markup_string=u"<<test foo=1>>bar<</test>>",
- macros=TestMacro()
- )
- self.assertEqual(html, u'XXXfoo=1|barXXX\n')
-
def test_macro_dict(self):
"""
simple test for the "macro API"
"""
- def test(args, text):
- return u"XXX%s|%sXXX" % (args, text)
+ def test(text, foo, bar):
+ return u"|".join([foo, bar, text])
html = creole2html(
- markup_string=u"<<test foo=1>>bar<</test>>",
+ markup_string=u"<<test bar='b' foo='a'>>c<</test>>",
macros={"test": test}
)
- self.assertEqual(html, u'XXXfoo=1|barXXX\n')
+ self.assertEqual(html, u'a|b|c\n')
def test_macro_callable(self):
"""
simple test for the "macro API"
"""
- def testmacro(macroname, args, text):
- if macroname == "test":
- return u"XXX%s|%sXXX" % (args, text)
- raise AssertionError("Wrong macro name?")
+ def testmacro():
+ pass
- html = creole2html(
- markup_string=u"<<test foo=1>>bar<</test>>",
+ self.failUnlessRaises(DeprecationWarning,
+ creole2html,
+ markup_string=u"<<test no=1 arg2='foo'>>bar<</test>>",
macros=testmacro
)
- self.assertEqual(html, u'XXXfoo=1|barXXX\n')
@@ -168,17 +157,13 @@ class TestCreole2htmlMarkup(BaseCreoleTest):
escape html chars like < and > ;)
So you can't insert <html> directly.
- You can use the <<html>><strong>html macro</strong><</html>> for it.
- This is a default macro.
<p>This escaped, too.</p>
""", """
<p>This is a normal Text block witch would<br />
escape html chars like &lt; and &gt; ;)</p>
- <p>So you can't insert &lt;html&gt; directly.<br />
- You can use the <strong>html macro</strong> for it.<br />
- This is a default macro.</p>
+ <p>So you can't insert &lt;html&gt; directly.</p>
<p>&lt;p&gt;This escaped, too.&lt;/p&gt;</p>
""")
@@ -248,30 +233,30 @@ class TestCreole2htmlMarkup(BaseCreoleTest):
"""
Test the three diferent macro types with a "unittest macro"
"""
-
self.assertCreole(r"""
There exist three different macro types:
- A <<test_macro args="foo1">>bar1<</test_macro>> in a line...
- ...a single <<test_macro args="foo2">> tag,
- or: <<test_macro args="foo2" />> closed...
+ A <<test_macro1 args="foo1">>bar1<</test_macro1>> in a line...
+ ...a single <<test_macro1 foo="bar">> tag,
+ or: <<test_macro1 a=1 b=2 />> closed...
a macro block:
- <<test_macro args="foo3">>
+ <<test_macro2 char="|">>
the
text
- <</test_macro>>
+ <</test_macro2>>
the end
""", r"""
<p>There exist three different macro types:<br />
- A [args="foo1" text: bar1] in a line...<br />
- ...a single [args="foo2" text: None] tag,<br />
- or: [args="foo2" text: None] closed...</p>
+ A [test macro1 - kwargs: args='foo1',text=u'bar1'] in a line...<br />
+ ...a single [test macro1 - kwargs: foo='bar',text=None] tag,<br />
+ or: [test macro1 - kwargs: a=1,b=2,text=None] closed...</p>
<p>a macro block:</p>
- [args="foo3" text: the
- text]
+ the|text
<p>the end</p>
- """)
+ """,
+ macros=test_macros,
+ )
def test_macro_html1(self):
self.assertCreole(r"""
@@ -287,6 +272,7 @@ class TestCreole2htmlMarkup(BaseCreoleTest):
<p>inline: &#x7B;...&#x7D; code</p>
""", #debug=True
+ macros=example_macros,
)
def test_macro_not_exist1(self):
@@ -377,36 +363,6 @@ class TestCreole2htmlMarkup(BaseCreoleTest):
<a href="http://de.wikipedia.org/wiki/Creole_(Markup)">Creole@wikipedia</a></p>
""")
- def test_macro_get_raw_content(self):
- """
- A macro should get the complete content without any modifications.
- """
- def testmacro(macroname, args, text):
- self.failUnlessEqual(macroname, "code")
- text = text.replace("{", "&#x7B;").replace("}", "&#x7D;")
- return text
-
- html = creole2html(
- markup_string=self._prepare_text(u"""
- intro
- <<code>>
- a {{ django }} variable, not a image ;)
- Foo {% blocktag %} bar {% endblocktag %}!
- **bold** //italics//
- <</code>>
- outro
- """),
- macros=testmacro
- )
- self.assertEqual(html, self._prepare_text(u"""
- <p>intro</p>
- a &#x7B;&#x7B; django &#x7D;&#x7D; variable, not a image ;)
- Foo &#x7B;% blocktag %&#x7D; bar &#x7B;% endblocktag %&#x7D;!
- **bold** //italics//
- <p>outro</p>
-
- """))
-
def test_wiki_style_line_breaks(self):
html = creole2html(
diff --git a/tests/test_cross_compare.py b/tests/test_cross_compare.py
index a5b54ee..5fbf06d 100644
--- a/tests/test_cross_compare.py
+++ b/tests/test_cross_compare.py
@@ -1,5 +1,6 @@
#!/usr/bin/env python
# coding: utf-8
+from creole.creole2html import example_macros
"""
@@ -482,7 +483,9 @@ class CrossCompareTests(BaseCreoleTest):
333<x foo1="bar1">foobar</x>444</p>
<p>555<x />666</p>
- """)
+ """,
+ macros=example_macros
+ )
def test_entities(self):
self.assertCreole(u"""
diff --git a/tests/test_macros.py b/tests/test_macros.py
new file mode 100644
index 0000000..68e170b
--- /dev/null
+++ b/tests/test_macros.py
@@ -0,0 +1,39 @@
+# coding: utf-8
+
+
+"""
+ Creole unittest macros
+ ~~~~~~~~~~~~~~~~~~~~~~
+
+ Note: all mecro functions must return unicode!
+
+ :copyleft: 2008-2011 by python-creole team, see AUTHORS for more details.
+ :license: GNU GPL v3 or above, see LICENSE for more details.
+"""
+
+
+def test_macro1(**kwargs):
+ """
+ >>> test_macro1(foo="bar")
+ u"[test macro1 - kwargs: foo='bar']"
+
+ >>> test_macro1()
+ u'[test macro1 - kwargs: ]'
+
+ >>> test_macro1(a=1,b=2)
+ u'[test macro1 - kwargs: a=1,b=2]'
+ """
+ kwargs = u','.join([u'%s=%r' % (k, v) for k, v in sorted(kwargs.items())])
+ return u"[test macro1 - kwargs: %s]" % kwargs
+
+def test_macro2(char, text):
+ """
+ >>> test_macro2(char=u"|", text=u"a\\nb")
+ u'a|b'
+ """
+ return char.join(text.split())
+
+
+if __name__ == "__main__":
+ import doctest
+ print doctest.testmod()
diff --git a/tests/utils/base_unittest.py b/tests/utils/base_unittest.py
index c7d6aed..2ee0bc6 100644
--- a/tests/utils/base_unittest.py
+++ b/tests/utils/base_unittest.py
@@ -36,7 +36,7 @@ class BaseCreoleTest(MarkupTest):
print "-" * 79
def assert_Creole2html(self, source_string, should_string, \
- verbose=1, stderr=sys.stderr, debug=False):
+ verbose=1, stderr=sys.stderr, debug=False, macros=None):
"""
compare the generated html code from the markup string >source_string<
with the >should_string< reference.
@@ -54,7 +54,8 @@ class BaseCreoleTest(MarkupTest):
# convert creole markup into html code
out_string = creole2html(
- markup_string, verbose=verbose, stderr=stderr, debug=debug
+ markup_string, verbose=verbose, stderr=stderr, \
+ debug=debug, macros=macros
)
if debug:
self._debug_text("assert_Creole2html() creole2html", out_string)
@@ -93,7 +94,7 @@ class BaseCreoleTest(MarkupTest):
# compare
self.assertEqual(out_string, markup)
- def assertCreole(self, source_string, should_string, debug=False):
+ def assertCreole(self, source_string, should_string, debug=False, macros=None):
"""
Cross compare with creol2html _and_ html2creole with the same given
refenrece strings.
@@ -103,7 +104,11 @@ class BaseCreoleTest(MarkupTest):
source_string = unicode(source_string)
should_string = unicode(should_string)
self.assertNotEqual(source_string, should_string)
- self.assert_Creole2html(source_string, should_string, debug)
+
+ self.assert_Creole2html(
+ source_string, should_string, debug, macros=macros
+ )
+
self.assert_html2Creole(
source_string, should_string, debug,
unknown_emit=use_html_macro