{ "info": { "author": "Lovely Systems GmbH", "author_email": "office@lovelysystems.com", "bugtrack_url": null, "classifiers": [ "Development Status :: 4 - Beta", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "==========\nlovely.tal\n==========\n\nthe lovely tal package is meant to contain new tal:expressions\n\nTextFormatter\n=============\n\noption replace:\n takes a list of tuples, which characters or strings should be replaced by \n what, e.g. ``replace python:[(origChar, repChar), (origChar2, repChar2), \n ...]``\n\noption allow:\n takes a list of html-tags which shall be allowed in the string e.g. ``allow \n python:['a', 'br', 'ul', 'li']`` if this option is not set, the string is \n restricted to contain no html-tags, therefor the ``< `` and ``>`` are \n beeing replaced with ``< ``, ``>``\n\noption allow-all:\n allow all html-tags in the string e.g. ``allow-all: 'True'``\n\noption break-string:\n force the string to break after a given number of characters e.g. \n ``break-string python:25`` breaks the string after a sequence of 25 \n characters not containing a linebreak\n \t\t\t\t\t\t\noption cut: \n cuts a string to the given length\n\noption attach: \n works only together with option ``cut``, attaches the given string to the \n expression, if this is longer than number of characters given in option \n ``cut``\n\noption urlparse:\n parsing of http:// or www. strings to hyperlinks, got a dictonary of parameters \n e.g. urlparse python:{'rel':'nofollow','target':'_blank', allready existing\n anchor tags are extended with the parameters in the dictionary, image tags\n stay untouched in this whole parsing process\n\nExample::\n\t\t\t\n ')];\n allow python:['a', 'br'];\n break-string python:25;\n urlparse python:{'rel':'nofollow','target':'_blank'};\n cut python 25;\n attach '...'\"\n tal:content=\"structure textFormatter: view/description\">Description\n\nLets see if the TextFormatter does what we want him to.\n\nWe have to fake a context object to call the textformatter::\n\n >>> class Context(object):\n ... vars = {}\n ... def __init__(self, vars):\n ... self.vars = vars\n >>> from lovely.tal.textformatter import TextFormatter\n >>> from zope.tales.expressions import simpleTraverse\n >>> from zope.app.pagetemplate.engine import TrustedZopeEngine\n >>> tf = TextFormatter('textFormatter', 'view/title', TrustedZopeEngine(), \n ... simpleTraverse)\n >>> context = Context({})\n >>> tf._doFormat('foolink', context)\n '<a href=\"#\" name=\"foolink\">foolink</a>'\n >>> tf._doFormat('foolink
'\n ... '
', context)\n '<a href=\"#\" name=\"foolink\">foolink</a><br /><form action=\".\"><input type=\"text\" /></form>'\n \nif we provide an empty context, the textformatter translates all html-tags to \n``< >``\n\nOption 'allow'\n==============\n\nWe can allow certain html-tags in the text::\n\n >>> context = Context({'allow':['a']})\n >>> tf._doFormat('foolink
', context)\n 'foolink<br /><form action=\".\"><input type=\"text\" /></form>'\n >>> context = Context({'allow':['a', 'br']})\n >>> tf._doFormat('foolink
', context)\n 'foolink
<form action=\".\"><input type=\"text\" /></form>'\n >>> context = Context({'allow':['a', 'br', 'form']})\n >>> tf._doFormat('foolink
', context)\n 'foolink
<input type=\"text\" />
'\n\nIn the above example, still the content of the form tag is translated \n \nLets try to write dirty html::\n\n >>> context = Context({'allow':['a', 'br', 'form']})\n >>> tf._doFormat('< a href=\"#\" name=\"foolink\">foolink
< form action=\".\">', context)\n '< a href=\"#\" name=\"foolink\">foolink</ a>
< form action=\".\"><input type=\"text\" /></form >'\n\nSince the a-tag and the form-tag are not valid html, they are translated, although we declared them to be allowed \nWe get the same result if we do not allow them::\n\n >>> context = Context({'allow':['br']})\n >>> tf._doFormat('< a href=\"#\" name=\"foolink\">foolink
< form action=\".\">', context)\n '< a href=\"#\" name=\"foolink\">foolink</ a>
< form action=\".\"><input type=\"text\" /></form >'\n\nOption 'allow-all'\n==================\n \nWe can allow all html-tags::\n\n >>> context = Context({'allow-all':True})\n >>> tf._doFormat('foolink
', context)\n 'foolink
'\n\nOption 'replace'\n================\n\nWe can replace characters or strings, e.g. we would like to replace the '\\n' character by '
'\nto display the text properly::\n\n >>> context = Context({'replace':[('\\n', '
')]})\n >>> tf._doFormat('das Schwein, \\n das aus der Wueste kam', context)\n 'das Schwein,
das aus der Wueste kam'\n \nwe can also replace strings::\n\n >>> context = Context({'replace':[('\\n', '
'), ('Schwein', 'Kamel')]})\n >>> tf._doFormat('das Schwein, \\n das aus der Wueste kam', context)\n 'das Kamel,
das aus der Wueste kam'\n \nOption 'break-string'\n=====================\n\nAnother option is to break strings after a given number of characters n, in case there\nwas no break or '\\s' in the last n characters::\n\n >>> context = Context({'break-string':8})\n >>> tf._doFormat('das Schwein, das aus der Wueste kam', context)\n 'das
Schwein,
das aus
der
Wueste
kam'\n >>> context = Context({'break-string':8})\n >>> tf._doFormat('ein superlangerstring mit ein paar kurzen strings', context)\n 'ein
superlan
gerstrin
g mit
ein paar
kurzen
strings'\n\nAlso multi line text works::\n\n >>> context = Context({'break-string':40})\n >>> res = tf._doFormat(\"\"\"\n ... ein superlangerstring mit ein paar kurzen strings.\n ... \n ... - another line\n ... \n ... - another long string which needs to break\n ... and this needs to break twice because it is longer than 80 characters, hopefully it works\n ... \"\"\", context)\n >>> print res.replace('
', '\\n')\n \n ein superlangerstring mit ein paar\n kurzen strings.\n \n - another line\n \n - another long string which needs to\n break\n and this needs to break twice because it\n is longer than 80 characters, hopefully\n it works\n \n >>> context = Context({'break-string':20, 'allow':['br']})\n >>> text = u'eins zwei drei vier fuenf sechs sieben,
'\n >>> text += u'in der Schule wird geschrieben,
'\n >>> text += u'in der Schule wird gelacht,
'\n >>> text += u'bis der Lehrer pitschpatsch macht!'\n >>> res = tf._doFormat(text, context)\n >>> print res.replace('
', '\\n')\n eins zwei drei vier\n fuenf sechs sieben,\n in der Schule wird\n geschrieben,\n in der Schule wird\n gelacht,\n bis der Lehrer\n pitschpatsch macht!\n\nthe formatter considers tags as not to be part of the text, that means that\nbreaks aren't made inside tags (<...>)::\n\n >>> context = Context({'break-string':8, 'allow':['a']})\n >>> tf._doFormat('working at lovelysystems is great!', context)\n 'working
at
lovelysy
stems
is
great!'\n\nOption 'cut'\n============ \n\nWe can also cut strings to a given length::\n\nWarning: cut will not check for HTML tags and will therefore cut in the middle\n of a tag which will make HTML unusable. Only use for plain text.\n\n >>> context = Context({'cut':20})\n >>> rendered = tf._doFormat('ein superlangerstring mit ein paar kurzen strings', context)\n >>> len(rendered)\n 20\n\ncut is done as the first operation. If it is combined with replace the\nresulting string can be longer.\n\n >>> context = Context({'cut':20, 'replace':(('ein', 'Wrong case : ein'),)})\n >>> rendered = tf._doFormat('ein superlangerstring mit ein paar kurzen strings', context)\n >>> len(rendered)\n 33\n\n\nOption 'clear-html'\n===================\n\n >>> context = Context({'clear-html':True})\n >>> tf._doFormat('Text containing HTML', context)\n 'Text containing HTML'\n\nThis is done before \"cut\".\n\n >>> context = Context({'clear-html':True, 'cut':10})\n >>> tf._doFormat('Text containing HTML', context)\n 'Text conta'\n\nOption 'attach'\n===============\n\nand attach a string to the expression::\n\n >>> context = Context({'cut':20, 'attach':'...'})\n >>> tf._doFormat('ein superlangerstring mit ein paar kurzen strings', context)\n 'ein superlangerstrin...'\n\n\nOption 'softcut'\n===============\n\nthe option softcut works together with cut and prevents cutting words::\n\n >>> context = Context({'cut':20, 'attach':'…', 'softcut':True})\n >>> tf._doFormat('ein superlangerstring mit ein paar kurzen strings', context)\n 'ein…'\n\n >>> context = Context({'cut':25, 'attach':'…', 'softcut':True})\n >>> tf._doFormat('ein superlangerstring mit ein paar kurzen strings', context)\n 'ein superlangerstring…'\n\n\n\nOption 'allow-scripts'\n======================\n\nthe option 'allow-scripts' has to be set explicitly if you want to include scripts.\n\n >>> context = Context({'allow-all':True, 'allow-scripts':True})\n >>> html = \"\"\"

this is html containing a \n ... script.\n ...

\"\"\"\n >>> print tf._doFormat(html, context)\n

this is html containing a \n script.\n

\n\n\nif not, all scripts will be stripped out although allow-all is enabled::\n\n >>> context = Context({'allow-all':True})\n >>> html = \"\"\"

this is html containing a \n ... script.\n ...

\"\"\"\n >>> print tf._doFormat(html, context)\n

this is html containing a \n script.\n

\n\ntest uppercase and whitespaces::\n\n >>> html = \"\"\"

this is html containing a \n ... < SCRIPT\n ... type=\"text/javascript\">\n ... alert(\"i'm not allowed');\n ... < /SCRIPT > script.\n ...

\"\"\"\n >>> print tf._doFormat(html, context)\n

this is html containing a \n script.\n

\n\nescaped scripttags::\n\n >>> html = \"\"\"

this is html containing a \n ... <script type=\"text/javascript\">\n ... alert(\"i'm not allowed');\n ... </SCRIPT> script.\n ...

\"\"\"\n >>> print tf._doFormat(html, context)\n

this is html containing a \n script.\n

\n\n\nescaped scripts including whitespace and different case::\n\n >>> html = \"\"\"

this is html containing a \n ... <SCRIPT \n ... type=\"text/javascript\">\n ... alert(\"i'm not allowed');\n ... < /SCRIPT > script.\n ...

\"\"\"\n >>> print tf._doFormat(html, context)\n

this is html containing a \n script.\n

\n\nOption 'urlparse'\n=================\n\nparse the urls in the expression:\n\n >>> context = Context({})\n >>> context = Context({'urlparse':{'rel':'nofollow','target':'_blank'},'allow':['a', 'br']})\n >>> tf._doFormat('lovelysystems rocks your zope', context)\n 'lovelysystems rocks your zope'\n\n >>> tf._doFormat('ha ha hell yeah http://www.lovelysystems.com/ rocks your zope', context)\n '...http://www.lovelysystems.com/...'\n\n >>> tf._doFormat('ha ha hell yeah www.lovelysystems.com/ rocks your zope', context)\n '...www.lovelysystems.com/...'\n\n >>> tf._doFormat('ha ha hell yeah rocks your zope', context)\n '...<img src=\"http://www.lovelysystems.com/image.jpg\" />...'", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://launchpad.net/lovely.tal", "keywords": "tal zope zope3", "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "lovely.tal", "package_url": "https://pypi.org/project/lovely.tal/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/lovely.tal/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://launchpad.net/lovely.tal" }, "release_url": "https://pypi.org/project/lovely.tal/0.6.0/", "requires_dist": null, "requires_python": null, "summary": "the lovely tal enables new tal expressions", "version": "0.6.0" }, "last_serial": 794373, "releases": { "0.2.1": [ { "comment_text": "", "digests": { "md5": "dd5d26678bced83363451d153b2bf531", "sha256": "042ecc240cc59fa2659edbc0510824f2b7491eb43440228e8c2436e3e283c006" }, "downloads": -1, "filename": "lovely.tal-0.2.1-py2.4.egg", "has_sig": false, "md5_digest": "dd5d26678bced83363451d153b2bf531", "packagetype": "bdist_egg", "python_version": "2.4", "requires_python": null, "size": 15355, "upload_time": "2007-12-10T11:38:49", "url": "https://files.pythonhosted.org/packages/ea/08/34166190d018f88d8b0170c8e50beb381aaf58e4a5e6f2cccc0ebfede5ec/lovely.tal-0.2.1-py2.4.egg" }, { "comment_text": "", "digests": { "md5": "bf034caa9b938615ce66f895c2b26ce2", "sha256": "78e42c6add2811a6f6291ee62d755bc440f01aa94e553b1f45e463b12689b3d1" }, "downloads": -1, "filename": "lovely.tal-0.2.1.tar.gz", "has_sig": false, "md5_digest": "bf034caa9b938615ce66f895c2b26ce2", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9083, "upload_time": "2007-12-10T11:38:49", "url": "https://files.pythonhosted.org/packages/05/bf/c3950965994db3617ced692324253f45137ef382dd5e13bc71e6b6dfd0a7/lovely.tal-0.2.1.tar.gz" } ], "0.5.0a1": [ { "comment_text": "", "digests": { "md5": "6f63c716b2fbcd9995a722ac3e427a40", "sha256": "1b04feeaa03dce7c5365376d5fe70a8c82789b73d97a8618981507e20662495e" }, "downloads": -1, "filename": "lovely.tal-0.5.0a1.tar.gz", "has_sig": false, "md5_digest": "6f63c716b2fbcd9995a722ac3e427a40", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10651, "upload_time": "2008-11-12T12:51:35", "url": "https://files.pythonhosted.org/packages/bf/2c/7f0a8c4e74251659f7fe959e9c904c701c478a12c0e143c5672af645feb8/lovely.tal-0.5.0a1.tar.gz" } ], "0.6.0": [ { "comment_text": "", "digests": { "md5": "e979e3149dd3648c40681dab36c02f4f", "sha256": "61bfd74deff4fab5413a41706bb60609ef567c6bf46e38c95c546d17e355e033" }, "downloads": -1, "filename": "lovely.tal-0.6.0.tar.gz", "has_sig": false, "md5_digest": "e979e3149dd3648c40681dab36c02f4f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12487, "upload_time": "2009-02-03T08:33:55", "url": "https://files.pythonhosted.org/packages/06/da/6eab30b504d0ffe6c2ae42e3175975ce9788a3a5f2a5fed7f2856b72b043/lovely.tal-0.6.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "e979e3149dd3648c40681dab36c02f4f", "sha256": "61bfd74deff4fab5413a41706bb60609ef567c6bf46e38c95c546d17e355e033" }, "downloads": -1, "filename": "lovely.tal-0.6.0.tar.gz", "has_sig": false, "md5_digest": "e979e3149dd3648c40681dab36c02f4f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 12487, "upload_time": "2009-02-03T08:33:55", "url": "https://files.pythonhosted.org/packages/06/da/6eab30b504d0ffe6c2ae42e3175975ce9788a3a5f2a5fed7f2856b72b043/lovely.tal-0.6.0.tar.gz" } ] }