diff options
author | JensDiemer <git@jensdiemer.de> | 2011-05-26 18:00:03 +0200 |
---|---|---|
committer | JensDiemer <git@jensdiemer.de> | 2011-05-26 18:00:03 +0200 |
commit | 5549d55cf548f3b500f677638674655117dffa72 (patch) | |
tree | bf71163a684b2e395258c1da3e91ce8320bdd7f7 | |
parent | 9c8396bbeb859c4dc030a8b9848b14147b126d88 (diff) | |
download | creole-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-- | README | 7 | ||||
-rw-r--r-- | creole/creole2html/emitter.py | 19 | ||||
-rw-r--r-- | creole/creole2html/example_macros.py (renamed from creole/creole2html/default_macros.py) | 8 | ||||
-rw-r--r-- | creole/creole2html/str2dict.py | 68 | ||||
-rw-r--r-- | tests/test_creole2html.py | 106 | ||||
-rw-r--r-- | tests/test_cross_compare.py | 5 | ||||
-rw-r--r-- | tests/test_macros.py | 39 | ||||
-rw-r--r-- | tests/utils/base_unittest.py | 13 |
8 files changed, 171 insertions, 94 deletions
@@ -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><bar?></p>\n') - def test_default_macro2(self): + def test_example_macros2(self): html = creole2html( markup_string=u"<<html>>{{{<nocode>}}}<</html>>", verbose=1, + macros=example_macros # stderr=sys.stderr, debug=False ) self.assertEqual(html, u'{{{<nocode>}}}\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 < and > ;)</p> - <p>So you can't insert <html> 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 <html> directly.</p> <p><p>This escaped, too.</p></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: {...} 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("{", "{").replace("}", "}") - 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 {{ django }} variable, not a image ;) - Foo {% blocktag %} bar {% endblocktag %}! - **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 |