From dd19f7cf208e83e76998d7d2f5bb9e792f165766 Mon Sep 17 00:00:00 2001 From: "Thomas \"Cakeisalie5\" Touhey" Date: Sat, 25 Aug 2018 20:28:05 +0200 Subject: [PATCH] Continued, not good for 0.3 yet. --- Pipfile.lock | 53 +++++++++--------- README.rst | 6 ++- docs/tags.rst | 4 ++ setup.cfg | 2 +- test/html.py | 6 ++- test/htmli.py | 2 +- test/ls.py | 3 +- textoutpc/__init__.py | 5 +- textoutpc/_options.py | 5 -- textoutpc/builtin/_List.py | 108 +++++++++++++++++++++++++++++++++++++ 10 files changed, 154 insertions(+), 40 deletions(-) create mode 100644 textoutpc/builtin/_List.py diff --git a/Pipfile.lock b/Pipfile.lock index 3111bdb..bd27a94 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "47d74a67e04adbda8d9502f7b0f14e7cf8adbb701407750d8e319a932ddc0e10" + "sha256": "17b85803e45d9bc70fd06c90eab447ef90a4b951c78b414c60a3c21e24ddfd39" }, "pipfile-spec": 6, "requires": { - "python_version": "3.6" + "python_version": "3.7" }, "sources": [ { @@ -18,24 +18,24 @@ "default": { "regex": { "hashes": [ - "sha256:116a15f36ea1acd705765f40c6ff5384fc20cbeb28f2a167a2a6a2517d592941", - "sha256:1e90c3456fcec72a3a7d70b6152db2d8399e9561d95ec9f3c04470ae985186bf", - "sha256:3c30e63fd0da414d1aa45524fcd342719636e2501716b55f5ee958d4e9751e32", - "sha256:413098e01cfb07f1060234f01203f660a5cd8f30eade16db881ae3f4f7d0886f", - "sha256:4d4582ab3664af721d16cc6b66181eb4bfcfed6ad32002094e7019607d05051a", - "sha256:4d5cd5434c05dbb52cc6d368e47f83a012ad4074197b529adbba39d4cda90219", - "sha256:5b58d9476166baf51eba6a686cff22668c764ae14a13566568afb9460506a2f4", - "sha256:72a79b6bc599d628cd40cb948b6924b8070ef54af41135a03e8fe916d4a7f455", - "sha256:749e164d836b9d2298f6ae7e7f0922f6ed0e507fd1cdce95586b827c19c0fe61", - "sha256:753befa998d9f466b45ae5f695c83846ba17d6d4b832dea108a0747d4bce613b", - "sha256:83a1877ff6972b94ba07cc33c994522aeba647e448e0cbed7ad128561fe15bfd", - "sha256:9308dbce8e5ff4ee06b172a777f6c7f650a5835a5ad41a6080eb501639c27a2f", - "sha256:9ad64244e980cec9adfd1b73da8d894dfc70552867f42171690b0a65ce665216", - "sha256:b82e9d4d80614c2250a7c2aa1905a4b0f2671a01fce506bf85a0908987ee95c5", - "sha256:f587a55aef1c6a8b4e527980049606278b32b826fb05386472d4e3994f538b28" + "sha256:060bf5f9c0311794bde90294b858830684861aee9c1f22ef5ce20d8fabf05a4e", + "sha256:0f7cbe57eed5429b8f4295b338ab6492338ec9793e363216bdfba905ae82c7c0", + "sha256:19a76b228cbf13024bbe098da8563fc5f4831271531d5e4d9d289c68c1b01233", + "sha256:22cdfa574fa85bf536ed9197a9796962e1c131c736fc0aa9dd24045f3e333304", + "sha256:4d3323f434782185d0b89f34ba6c125f19e3bfe5e099a72c1e33e7cfd43013d2", + "sha256:56494baf1ed525deea426d3676b1ae3fdcc906b55eccfcb4ea928453e11f2a43", + "sha256:5c896c51b06c96d9d5e1c41495fd0fbe92f711225b889e2faef534f0a697f0db", + "sha256:5f1838807ced5c5fa011e3f935568ff59e0b2e6c83119668b961e3bb383e12f6", + "sha256:5f3ab6220d9c191392563c9727552fd3c1f3a3566180a64717d37554ad7414b7", + "sha256:7c90d56daeb64371670e528bd08a6e722a025a508effa84842d6c66727e7e422", + "sha256:98179516aa75ef0e9ecbda8cd4b14f6e4186e32da3fc21466edd25c917fd8110", + "sha256:c7a5613e903937c73d02f9b3b4b4dce0275fd6909295939a9f3ea50dbf6a2d4e", + "sha256:d8945dba30c1070c398ad2e0356aa0dd55d87129fa9bac2cd885ca95ff92a555", + "sha256:e45c34102da4621eee9fc25df1651129ab3adcc1f754bb77ea329aea39c2288c", + "sha256:eb5a96f142f0bb4ac37b8e8a334c234c48b571324b385cf2d66a84522d5ec075" ], "index": "pypi", - "version": "==2018.7.11" + "version": "==2018.8.17" } }, "develop": { @@ -55,10 +55,10 @@ }, "certifi": { "hashes": [ - "sha256:13e698f54293db9f89122b0581843a782ad0934a4fe0172d2a980ba77fc61bb7", - "sha256:9fa520c1bacfb634fa7af20a76bcbd3d5fb390481724c597da32c719a7dca4b0" + "sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638", + "sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a" ], - "version": "==2018.4.16" + "version": "==2018.8.24" }, "chardet": { "hashes": [ @@ -142,6 +142,7 @@ "sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1", "sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a" ], + "markers": "python_version >= '2.6' and python_version != '3.1.*' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version < '4'", "version": "==2.19.1" }, "six": { @@ -160,18 +161,18 @@ }, "sphinx": { "hashes": [ - "sha256:217ad9ece2156ed9f8af12b5d2c82a499ddf2c70a33c5f81864a08d8c67b9efc", - "sha256:a765c6db1e5b62aae857697cd4402a5c1a315a7b0854bbcd0fc8cdc524da5896" + "sha256:71531900af3f68625a29c4e00381bee8f85255219a3d500a3e255076a45b735e", + "sha256:a3defde5e17b5bc2aa21820674409287acc4d56bf8d009213d275e4b9d0d490d" ], "index": "pypi", - "version": "==1.7.6" + "version": "==1.7.7" }, "sphinxcontrib-websupport": { "hashes": [ "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd", "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9" ], - "markers": "python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.2.*' and python_version >= '2.7' and python_version != '3.1.*'", + "markers": "python_version != '3.1.*' and python_version >= '2.7' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*'", "version": "==1.1.0" }, "urllib3": { @@ -179,7 +180,7 @@ "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" ], - "markers": "python_version != '3.3.*' and python_version != '3.0.*' and python_version != '3.2.*' and python_version >= '2.6' and python_version < '4' and python_version != '3.1.*'", + "markers": "python_version >= '2.6' and python_version != '3.1.*' and python_version != '3.0.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version < '4'", "version": "==1.23" }, "urwid": { diff --git a/README.rst b/README.rst index 04552af..708db4a 100644 --- a/README.rst +++ b/README.rst @@ -14,9 +14,10 @@ documentation accessible on `the official website`_. What is left to do ------------------ +- Implement the ``not_within_itself`` attribute (for ``[*]``). +- Implement the ``expect_child`` attribute (for `[list] blah [*]`` to ignore + ``blah`` and anything before the first ``[*]``). - Add an ``[imgurl]`` tag. -- Manage blocks superseeding each other; -- Implement BBcode lists using ``[*]``, ``[**]``, …; - Manage lightscript (or even markdown?) as output languages; - Check where the errors are to display them to the user: @@ -26,6 +27,7 @@ What is left to do - Check why exceptions on raw tags effectively escape the content, as it shouldn't…? - Look for security flaws (we really don't want stored XSS flaws!). +- Implement match names (such as ``\[\*+\]`` for lists). - Manage keywords with tags such as ``[tag key=value other="something else"]``. .. _Planète Casio:: https://www.planet-casio.com/ diff --git a/docs/tags.rst b/docs/tags.rst index ea3775b..c0a68df 100644 --- a/docs/tags.rst +++ b/docs/tags.rst @@ -29,6 +29,10 @@ There are a few public members you can define as a tag: - ``inlined``: if is a block, transforms automatically the surrounding block into a superblock while it's there. - ``procvalue`` : process the value as normal text before passing it. +- ``not_within_itself`` : make that if a tag is opened within itself (depth + included), the tag above and all tags below are closed first. +- ``expect_child`` : make that all content below (without depth) that isn't + within the specified tags is ignored. So for example, if I want to make the inline tag ``[hello]`` as an example, with the alternate name ``[hai]``, I'd start off by writing: diff --git a/setup.cfg b/setup.cfg index f5b8260..1902302 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,7 +21,7 @@ classifiers = [options] zip_safe = False include_package_data = True -packages = find: +packages = textoutpc, textoutpc.color, textoutpc.builtin test_suite = test scripts = scripts/textout2html diff --git a/test/html.py b/test/html.py index 57fc984..fc159e2 100755 --- a/test/html.py +++ b/test/html.py @@ -8,7 +8,6 @@ """ import unittest as _unittest -import textoutpc as _textoutpc __all__ = ["TextoutHTMLTest"] @@ -180,6 +179,10 @@ __test_cases = { # Text rotation obfuscation. '[rot13]obawbhe[/rot13]': '

bonjour

', + # Lists. + '[list]haha[b][*]wow[*]incredible[/b][/*]wow[*]yuy[/list]': \ + '', + # Smileys. ':)': '

', ':):)': '

:):)

', @@ -193,6 +196,7 @@ _cnt = 0 _len = len(str(len(__test_cases))) _templ = """\ def test_html{n:0>{l}}(self): + import textoutpc as _textoutpc self.assertEqual(_textoutpc.tohtml({i}), {r}, \\ "for the following text: " + {i}) """ diff --git a/test/htmli.py b/test/htmli.py index 08754e8..f308f01 100755 --- a/test/htmli.py +++ b/test/htmli.py @@ -8,7 +8,6 @@ """ import unittest as _unittest -import textoutpc as _textoutpc __all__ = ["TextoutHTMLiTest"] @@ -33,6 +32,7 @@ _cnt = 0 _len = len(str(len(__test_cases))) _templ = """\ def test_htmli{n:0>{l}}(self): + import textoutpc as _textoutpc self.assertEqual(_textoutpc.tohtml({i}, inline = True), {r}, \\ "for the following text: " + {i}) """ diff --git a/test/ls.py b/test/ls.py index e6bf883..e4186de 100755 --- a/test/ls.py +++ b/test/ls.py @@ -8,7 +8,6 @@ """ import unittest as _unittest -import textoutpc as _textoutpc __all__ = ["TextoutLSTest"] @@ -16,6 +15,7 @@ __all__ = ["TextoutLSTest"] __test_cases = { # Basic text. + '': '', } @@ -25,6 +25,7 @@ _cnt = 0 _len = len(str(len(__test_cases))) _templ = """\ def test_lgsp{n:0>{l}}(self): + import textoutpc as _textoutpc self.assertEqual(_textoutpc.tolightscript({i}), {r}, {i}) """ diff --git a/textoutpc/__init__.py b/textoutpc/__init__.py index 7f9515d..f54b16b 100755 --- a/textoutpc/__init__.py +++ b/textoutpc/__init__.py @@ -11,14 +11,13 @@ from io import StringIO as _StringIO from ._options import TextoutOptions as Options, \ TextoutBlockTag as BlockTag, TextoutInlineTag as InlineTag, \ - TextoutParagraphTag as ParagraphTag, TextoutListTag as _TextoutListTag, \ - TextoutListElementTag as _TextoutListElementTag, TextoutSmiley as Smiley, \ + TextoutParagraphTag as ParagraphTag, TextoutSmiley as Smiley, \ TextoutVideo as Video from ._translate import Translator as _Translator __all__ = ["version", "tohtml", "tolightscript", "Options", "BlockTag", "ParagraphTag", "InlineTag", - "ListTag", "ListElementTag", "Smiley", "Video"] + "Smiley", "Video"] version = "0.2" diff --git a/textoutpc/_options.py b/textoutpc/_options.py index c777e2c..230d978 100755 --- a/textoutpc/_options.py +++ b/textoutpc/_options.py @@ -166,11 +166,6 @@ class TextoutBlockTag(TextoutTag): class TextoutInlineTag(TextoutTag): pass -class TextoutListTag(TextoutBlockTag): - superblock = True -class TextoutListElementTag(TextoutBlockTag): - superblock = True - # Default tag: paragraph. class TextoutParagraphTag(TextoutBlockTag): diff --git a/textoutpc/builtin/_List.py b/textoutpc/builtin/_List.py new file mode 100644 index 0000000..da1fa0e --- /dev/null +++ b/textoutpc/builtin/_List.py @@ -0,0 +1,108 @@ +#!/usr/bin/env python3 +#****************************************************************************** +# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey +# This file is part of the textoutpc project, which is MIT-licensed. +#****************************************************************************** + +from .. import BlockTag as _BlockTag + +__all__ = ["ListTag", "ListElementTag"] + + +# Bullet style names. + +_ol_list_style_types = { + 'disc': 'disc', + 'circle': 'circle', + 'square': 'square', +} +_ul_list_style_types = { + '1': 'decimal', + 'a': 'lower-alpha', + 'A': 'upper-alpha', + 'i': 'lower-roman', + 'I': 'upper-roman', +} + +_list_style_types = _ol_list_style_types.copy() +_list_style_types.update(_ul_list_style_types) + +_ul_lst_names = set(_ul_list_style_types.keys()) +_ol_lst_names = set(_ol_list_style_types.keys()) + +# Tag definitions. + +class ListElementTag(_BlockTag): + """ List element for basic lists (see `ListTag`). """ + + aliases = ('[*]',) + notempty = True + superblock = True + not_within_itself = True + + def begin_html(self): + return '
  • ' + + def end_html(self): + return '
  • ' + +class ListTag(_BlockTag): + """ Main tag for making basic lists. + Example use: + + [ul] + [*] Item number one. + [*] Item number [b]two[/b]. + [/ul] + """ + + aliases = ('[list]', '[ul]', '[ol]') + notempty = True + superblock = True + expect_child = (_ListElement,) + + def prepare(self, name, value): + us = _ul_lst_names + os = _ol_lst_names + + if name == '[list]' and value == None: + self._tag = 'ul' + self._style = None + elif name == '[list]' and value in us: + self._tag = 'ul' + self._style = value + elif name == '[list]' and value in os: + self._tag = 'ol' + self._style = value + elif name == '[ul]' and value == None: + self._tag = 'ul' + self._style = None + elif name == '[ul]' and value in us: + self._tag = 'ul' + self._style = value + elif name == '[ol]' and value == None: + self._tag = 'ol' + self._style = None + elif name == '[ol]' and value in os: + self._tag = 'ol' + self._style = value + else: + raise ValueError("invalid bullet style") + + # Find out the HTML style name. + + if self._style != None: + self._style = _list_style_types[self._style] + + def begin_html(self): + tag = f'<{self._tag}' + if self._style != None: + tag += f' style="list-style-type: {self._style}"' + tag += '>' + + return tag + + def end_html(self): + return '' + +# End of file.