diff --git a/Pipfile.lock b/Pipfile.lock index 486b353..f56474b 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -41,10 +41,10 @@ "develop": { "alabaster": { "hashes": [ - "sha256:674bb3bab080f598371f4443c5008cbfeb1a5e622dd312395d2d82af2c54c456", - "sha256:b63b1f4dc77c074d386752ec4a8a7517600f6c0db8cd42980cae17ab7b3275d7" + "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359", + "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02" ], - "version": "==0.7.11" + "version": "==0.7.12" }, "babel": { "hashes": [ @@ -55,10 +55,10 @@ }, "certifi": { "hashes": [ - "sha256:376690d6f16d32f9d1fe8932551d80b23e9d393a8578c5633a2ed39a64861638", - "sha256:456048c7e371c089d0a77a5212fb37a2c2dce1e24146e3b7e0261736aaeaa22a" + "sha256:339dc09518b07e2fa7eda5450740925974815557727d6bd35d319c1524a04a4c", + "sha256:6d58c986d22b038c8c0df30d639f23a3e6d172a05c3583e766f4c0b785c0986a" ], - "version": "==2018.8.24" + "version": "==2018.10.15" }, "chardet": { "hashes": [ @@ -94,7 +94,6 @@ "sha256:3f349de3eb99145973fefb7dbe38554414e5c30abd0c8e4b970a7c9d09f3a1d8", "sha256:f3832918bc3c66617f92e35f5d70729187676313caa60c187eb0f28b8fe5e3b5" ], - "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", "version": "==1.1.0" }, "jinja2": { @@ -112,10 +111,10 @@ }, "packaging": { "hashes": [ - "sha256:e9215d2d2535d3ae866c3d6efc77d5b24a0192cce0ff20e42896cc0664f889c0", - "sha256:f019b770dd64e585a99714f1fd5e01c7a8f11b45635aa953fd41c689a657375b" + "sha256:0886227f54515e592aaa2e5a553332c73962917f2831f1b0f9b9f4380a4b9807", + "sha256:f95a1e147590f204328170981833854229bb2912ac3d5f89e2a8ccd2834800c9" ], - "version": "==17.1" + "version": "==18.0" }, "pudb": { "hashes": [ @@ -133,24 +132,24 @@ }, "pyparsing": { "hashes": [ - "sha256:0832bcf47acd283788593e7a0f542407bd9550a55a8a8435214a1960e04bcb04", - "sha256:fee43f17a9c4087e7ed1605bd6df994c6173c1e977d7ade7b651292fab2bd010" + "sha256:40856e74d4987de5d01761a22d1621ae1c7f8774585acae358aa5c5936c6c90b", + "sha256:f353aab21fd474459d97b709e527b5571314ee5f067441dc9f88e33eecd96592" ], - "version": "==2.2.0" + "version": "==2.3.0" }, "pytz": { "hashes": [ - "sha256:a061aa0a9e06881eb8b3b2b43f05b9439d6583c206d0a6c340ff72a7b6669053", - "sha256:ffb9ef1de172603304d9d2819af6f5ece76f2e85ec10692a524dd876e72bf277" + "sha256:31cb35c89bd7d333cd32c5f278fca91b523b0834369e757f4c5641ea252236ca", + "sha256:8e0f8568c118d3077b46be7d654cc8167fa916092e28320cde048e54bfc9f1e6" ], - "version": "==2018.5" + "version": "==2018.7" }, "requests": { "hashes": [ - "sha256:63b52e3c866428a224f97cab011de738c36aec0185aa91cfacd418b5d58911d1", - "sha256:ec22d826a36ed72a7358ff3fe56cbd4ba69dd7a6718ffd450ff0e9df7a47ce6a" + "sha256:99dcfdaaeb17caf6e526f32b6a7b780461512ab3f1d992187801694cba42770c", + "sha256:a84b8c9ab6239b578f22d1c21d51b696dcfe004032bb80ea832398d6909d7279" ], - "version": "==2.19.1" + "version": "==2.20.0" }, "six": { "hashes": [ @@ -168,27 +167,25 @@ }, "sphinx": { "hashes": [ - "sha256:217a7705adcb573da5bbe1e0f5cab4fa0bd89fd9342c9159121746f593c2d5a4", - "sha256:a602513f385f1d5785ff1ca420d9c7eb1a1b63381733b2f0ea8188a391314a86" + "sha256:652eb8c566f18823a022bb4b6dbc868d366df332a11a0226b5bc3a798a479f17", + "sha256:d222626d8356de702431e813a05c68a35967e3d66c6cd1c2c89539bb179a7464" ], "index": "pypi", - "version": "==1.7.9" + "version": "==1.8.1" }, "sphinxcontrib-websupport": { "hashes": [ "sha256:68ca7ff70785cbe1e7bccc71a48b5b6d965d79ca50629606c7861a21b206d9dd", "sha256:9de47f375baf1ea07cdb3436ff39d7a9c76042c10a769c52353ec46e4e8fc3b9" ], - "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version != '3.2.*' and python_version != '3.0.*' and python_version >= '2.7'", "version": "==1.1.0" }, "urllib3": { "hashes": [ - "sha256:a68ac5e15e76e7e5dd2b8f94007233e01effe3e50e8daddf69acfd81cb686baf", - "sha256:b5725a0bd4ba422ab0e66e89e030c806576753ea3ee08554382c14e685d117b5" + "sha256:41c3db2fc01e5b907288010dec72f9d0a74e37d6994e6eb56849f59fea2265ae", + "sha256:8819bba37a02d143296a4d032373c4dd4aca11f6d4c9973335ca75f9c8475f59" ], - "markers": "python_version != '3.1.*' and python_version != '3.3.*' and python_version >= '2.6' and python_version < '4' and python_version != '3.2.*' and python_version != '3.0.*'", - "version": "==1.23" + "version": "==1.24" }, "urwid": { "hashes": [ diff --git a/docs/tags.rst b/docs/tags.rst index d009cb7..dd6d0f9 100644 --- a/docs/tags.rst +++ b/docs/tags.rst @@ -31,6 +31,7 @@ There are a few public members you can define as a tag: - ``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. +- ``only_in``: allow the tag to only be beneath certain tags. - ``allowed_tags``: allowed tags right beneath the current one. - ``no_text``: disable raw text within the tag. - ``expect_child``: make that all content below (without depth) that isn't diff --git a/test/html.py b/test/html.py index fc159e2..9250608 100755 --- a/test/html.py +++ b/test/html.py @@ -181,7 +181,8 @@ __test_cases = { # Lists. '[list]haha[b][*]wow[*]incredible[/b][/*]wow[*]yuy[/list]': \ - '', + '', # Smileys. ':)': '

', diff --git a/textoutpc/_translate.py b/textoutpc/_translate.py index b25300c..5c6151e 100755 --- a/textoutpc/_translate.py +++ b/textoutpc/_translate.py @@ -65,10 +65,14 @@ class _TagData: # Tag stack behaviour. # `nwi` is whether the tag can be in itself directly or not (see # the `not_within_itself` property in the docs). + # `onlyin` is the list of tags that are allowed as a parent tag + # to this one. # `allowed` is the tags that are allowed amongst the children tags. self.nwi = bool(tag.not_within_itself) \ if hasattr(tag, 'not_within_itself') else False + self.onlyin = list(tag.only_in) \ + if hasattr(tag, 'only_in') else None self.allowed = list(tag.allowed_tags) \ if hasattr(tag, 'allowed_tags') else None @@ -805,16 +809,27 @@ class Translator: else: alw = pr.allowed - if alw is not None and not type(dat.base) in alw: + if alw is not None and not any(cls for cls in alw \ + if isinstance(dat.base, cls)): self.put_text(tagdata.full) continue # Check if it is within itself and it can't. - if dat.nwi and self.queue \ - and type(dat.base) is type(self.queue[0].base): + if dat.nwi and any(d for d in self.queue \ + if isinstance(d.base, type(dat.base))): + while not isinstance(self.queue[0].base, type(dat.base)): + self.pop_tag() self.pop_tag() + # Check if it is allowed in this parent. + + if dat.onlyin is not None and self.queue \ + and not any(cls for cls in dat.onlyin \ + if isinstance(self.queue[0].base, cls)): + self.put_text(tagdata.full) + continue + # And don't forget to push the tag (through its data). self.push_tag(dat) @@ -822,7 +837,8 @@ class Translator: # Push a paragraph tag if the block is a superblock. if dat.type == dat.BLOCK and dat.super and not dat.raw \ - and not dat.inlined: + and not dat.inlined and (dat.allowed is None \ + or _TextoutParagraphTag in dat.allowed): self.push_tag(_TagData(_TextoutParagraphTag(None, None, self.output_type, self.tweaks, self.options), None, '')) diff --git a/textoutpc/builtin/_List.py b/textoutpc/builtin/_List.py index e49d6b9..af926d8 100644 --- a/textoutpc/builtin/_List.py +++ b/textoutpc/builtin/_List.py @@ -32,10 +32,14 @@ _ol_lst_names = set(_ol_list_style_types.keys()) # Tag definitions. +class _ListTagBase(_BlockTag): + pass + class ListElementTag(_BlockTag): """ List element for basic lists (see `ListTag`). """ aliases = ('[*]', '[li]') + only_in = (_ListTagBase,) notempty = True superblock = True not_within_itself = True @@ -46,7 +50,7 @@ class ListElementTag(_BlockTag): def end_html(self): return '' -class ListTag(_BlockTag): +class ListTag(_ListTagBase): """ Main tag for making basic lists. Example use: