diff --git a/Pipfile b/Pipfile index 2ac0b47..3345456 100644 --- a/Pipfile +++ b/Pipfile @@ -4,10 +4,11 @@ verify_ssl = true name = 'pypi' [requires] -python_version = '3.6' +python_version = '3.7' [packages] regex = '*' [dev-packages] sphinx = '*' +pudb = '*' diff --git a/Pipfile.lock b/Pipfile.lock index e04bd27..3111bdb 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "6e1b84fcb804088935285008b44bd4b05be953563380302b468b4bafbbd7ed97" + "sha256": "47d74a67e04adbda8d9502f7b0f14e7cf8adbb701407750d8e319a932ddc0e10" }, "pipfile-spec": 6, "requires": { @@ -109,6 +109,13 @@ ], "version": "==17.1" }, + "pudb": { + "hashes": [ + "sha256:8d8b974641b7a7a2a721af01c9dce5eac8e05a2ceebc2680725ba8eef1ca876e" + ], + "index": "pypi", + "version": "==2018.1" + }, "pygments": { "hashes": [ "sha256:78f3f434bcc5d6ee09020f92ba487f95ba50f1e3ef83ae96b9d5ffa1bab25c5d", @@ -174,6 +181,12 @@ ], "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.*'", "version": "==1.23" + }, + "urwid": { + "hashes": [ + "sha256:644d3e3900867161a2fc9287a9762753d66bd194754679adb26aede559bcccbc" + ], + "version": "==2.0.1" } } } diff --git a/setup.cfg b/setup.cfg index 9272e32..f5b8260 100644 --- a/setup.cfg +++ b/setup.cfg @@ -37,3 +37,7 @@ source-dir = docs [wheel] universal = True + +[flake8] +ignore = F401, F403, E128, E131, E241, E261, E265, E271, W191 +exclude = .git, __pycache__, build, dist, docs/conf.py, test.py, test diff --git a/test/html.py b/test/html.py index 8c7dcf4..57fc984 100755 --- a/test/html.py +++ b/test/html.py @@ -169,6 +169,10 @@ __test_cases = { 'style="padding-bottom: 75%">', + 'lol[youtube]h4WLX8hfpJw': '

lol

', # Progress bars. '[progress=lol]mdr[/progress]': '

[progress=lol]mdr[/progress]

', @@ -206,6 +210,6 @@ exec("class TextoutHTMLTest(_unittest.TestCase):\n maxDiff = None\n" + \ # If run as main script, run the test function. if __name__ == '__main__': - çunittest.main() + _unittest.main() # End of file. diff --git a/textoutpc/_translate.py b/textoutpc/_translate.py index 72f422a..4c33ce2 100755 --- a/textoutpc/_translate.py +++ b/textoutpc/_translate.py @@ -400,6 +400,9 @@ class Translator: `end` represents the full version of the ending tag marker, for displaying if the tag is invalid. """ + if not self.queue: + return + # Even if we had no beginning, no content and no end, what is # here has to be distinguished from what was right before! # So we need to flush the text group for this. diff --git a/textoutpc/builtin/_Align.py b/textoutpc/builtin/_Align.py index b23df83..800c3ca 100755 --- a/textoutpc/builtin/_Align.py +++ b/textoutpc/builtin/_Align.py @@ -8,10 +8,11 @@ from .. import BlockTag as _BlockTag __all__ = ["AlignTag"] + class AlignTag(_BlockTag): """ Main tag for aligning paragraphs. Example uses: - + [align=center]This text is centered horizontally.[/align] [justify]This text is justified.[/justify] """ @@ -31,7 +32,7 @@ class AlignTag(_BlockTag): if not name: align = None - elif name == 'align' and value != None: + elif name == 'align' and value is not None: align = _align[value] else: align = _align[name[1:-1]] diff --git a/textoutpc/builtin/_Code.py b/textoutpc/builtin/_Code.py index 2787993..37eb4d5 100755 --- a/textoutpc/builtin/_Code.py +++ b/textoutpc/builtin/_Code.py @@ -8,10 +8,11 @@ from .. import BlockTag as _BlockTag, InlineTag as _InlineTag __all__ = ["CodeTag", "InlineCodeTag", "NoEvalTag"] + class CodeTag(_BlockTag): """ The basic code tag, for displaying code. Example uses: - + [code]int main() { printf("hello, world"); @@ -34,11 +35,12 @@ class CodeTag(_BlockTag): def end_lightscript(self): return '```\n' + class InlineCodeTag(_InlineTag): """ Inline code tag, doesn't display a box, simply doesn't evaluate the content and uses monospace font. Example uses: - + `some inline code` [inlinecode][b]The tags will be shown verbatim.[/b][/inlinecode] [inlinecode][inlinecode][i]This also[/inlinecode] works![/inlinecode] @@ -60,10 +62,11 @@ class InlineCodeTag(_InlineTag): def end_lightscript(self): return '`' + class NoEvalTag(_InlineTag): """ Inline code tag, simply doesn't evaluate the content. Example uses: - + [noeval][b]wow, and no need for monospace![/b][/noeval] """ diff --git a/textoutpc/builtin/_Image.py b/textoutpc/builtin/_Image.py index 6f9eb32..2fd6a78 100755 --- a/textoutpc/builtin/_Image.py +++ b/textoutpc/builtin/_Image.py @@ -9,10 +9,11 @@ from html import escape as _htmlescape __all__ = ["ImageTag", "AdminImageTag"] + class ImageTag(_BlockTag): """ The main tag for displaying an image. Example uses: - + [img]picture_url[/img] [img=center]picture_url[/img] [img=12x24]picture_url[/img] @@ -41,7 +42,7 @@ class ImageTag(_BlockTag): self._height = None self._align = None - for arg in ("", value)[value != None].split('|'): + for arg in ("", value)[value is not None].split('|'): if not arg: pass elif arg[0] in '0123456789x': @@ -49,13 +50,17 @@ class ImageTag(_BlockTag): self._height = None dim = arg.split('x') - try: self._width = int(dim[0]) - except: pass - try: self._height = int(dim[1]) - except: pass + try: + self._width = int(dim[0]) + except ValueError: + pass + try: + self._height = int(dim[1]) + except ValueError: + pass elif arg in _align: al, fl = _align[arg] - if al != None: + if al is not None: self._align = al if fl: self._float = True @@ -95,12 +100,13 @@ class ImageTag(_BlockTag): url = self._url.replace('[', '%5B').replace(']', '%5D') return '[[image:{}]]'.format(url) + class AdminImageTag(ImageTag): """ This tag is special for Planète Casio, as it takes images from the `ad`ministration's image folder. It just adds this folder's prefix. Example uses: - + [adimg]some_picture.png[/img] [adimg=center]some_picture.png[/img] [adimg=12x24]some_picture.png[/img] diff --git a/textoutpc/builtin/_Label.py b/textoutpc/builtin/_Label.py index 587d125..3715917 100755 --- a/textoutpc/builtin/_Label.py +++ b/textoutpc/builtin/_Label.py @@ -11,10 +11,11 @@ __all__ = ["LabelTag", "TargetTag"] _labelexpr = _re.compile('^[a-z0-9-]{1,16}$', _re.I) + class LabelTag(_InlineTag): """ The label tag, defines an anchor at a point of the post. Example uses: - + [label=installation]Installation de tel logiciel... (no ending req.) [label=compilation][/label] Compilation de tel logiciel... """ @@ -33,10 +34,11 @@ class LabelTag(_InlineTag): name = self.tweak("label_prefix", "") + self._label return ''.format(name) + class TargetTag(_InlineTag): """ The goto tag, links to an anchor defined in the post. Example uses: - + [target=installation]Check out the installation manual[/target]! """ diff --git a/textoutpc/builtin/_Link.py b/textoutpc/builtin/_Link.py index 854c37c..efe4a5a 100755 --- a/textoutpc/builtin/_Link.py +++ b/textoutpc/builtin/_Link.py @@ -9,10 +9,11 @@ from html import escape as _htmlescape __all__ = ["LinkTag", "ProfileTag", "TopicTag", "TutorialTag", "ProgramTag"] + class LinkTag(_InlineTag): """ The main link tag. Example uses: - + [url=https://example.org/hi]Go to example.org[/url]! [url=/Fr/index.php][/url] [url]https://random.org/randomize.php[/url] """ @@ -33,7 +34,7 @@ class LinkTag(_InlineTag): # If there is no value, wait until we have a content to # decide if we are valid or not. - if value == None: + if value is None: self.preprocess = self._preprocess_if_no_value return @@ -63,11 +64,12 @@ class LinkTag(_InlineTag): url = self._url.replace('(', '%28').replace(')', '%29') return ']({})'.format(url) + class ProfileTag(LinkTag): """ A special link tag for Planète Casio's profiles. Adds the prefix to the content, and sets the value. Example uses: - + [profil]Cakeisalie5[/] """ aliases = ('[profil]', '[profile]') @@ -82,7 +84,7 @@ class ProfileTag(LinkTag): username = content allowed = "abcdefghijklmnopqrstuvwxyz0123456789_ -." - if any(not car in allowed for car in allowed): + if any(car not in allowed for car in allowed): raise ValueError("invalid username!") # Prepare the tag. @@ -91,11 +93,12 @@ class ProfileTag(LinkTag): '?membre={}'.format(username) self._validate() + class TopicTag(LinkTag): """ A special link tag for Planète Casio's topics. Adds the prefix to the content, and sets the value. Example uses: - + [topic]234[/] """ aliases = ('[topic]',) @@ -116,11 +119,12 @@ class TopicTag(LinkTag): f'lecture_sujet.php?id={topic}' self._validate() + class TutorialTag(LinkTag): """ A special link tag for Planète Casio's tutorial. Adds the prefix to the content, and sets the value. Example uses: - + [tutorial]71[/tutorial] [tuto]71[/tuto] """ @@ -142,11 +146,12 @@ class TutorialTag(LinkTag): f'tutoriels.php?id={topic}' self._validate() + class ProgramTag(LinkTag): """ A special link tag for a Planète Casio's program. Adds the prefix to the content, and sets the value. Example uses: - + [program]3598[/program] [prog]3598[/prog] """ diff --git a/textoutpc/builtin/_Progress.py b/textoutpc/builtin/_Progress.py index b244c24..3692dc3 100755 --- a/textoutpc/builtin/_Progress.py +++ b/textoutpc/builtin/_Progress.py @@ -8,10 +8,11 @@ from .. import BlockTag as _BlockTag __all__ = ["ProgressTag"] + class ProgressTag(_BlockTag): """ Progress tag, used to display the progress on anything. Usage: - + [progress=50]My great progress bar[/progress] [progress=100][/progress] """ @@ -28,8 +29,8 @@ class ProgressTag(_BlockTag): def end_html(self): return '' \ - '
' \ - '
   {}%' \ - '
'.format(self._val, self._val) + '
' \ + '
   {}%' \ + '
'.format(self._val, self._val) # End of file. diff --git a/textoutpc/builtin/_Quote.py b/textoutpc/builtin/_Quote.py index 9b47e54..d543042 100755 --- a/textoutpc/builtin/_Quote.py +++ b/textoutpc/builtin/_Quote.py @@ -8,10 +8,11 @@ from .. import BlockTag as _BlockTag __all__ = ["QuoteTag"] + class QuoteTag(_BlockTag): """ The main tag for quoting someone. Example uses: - + [quote]Hey, I said that![/quote] [quote=Someone important]I said something important, and it's multiline and [b]formatted[/b]! diff --git a/textoutpc/builtin/_Rot.py b/textoutpc/builtin/_Rot.py index f3df58d..f2f15ca 100755 --- a/textoutpc/builtin/_Rot.py +++ b/textoutpc/builtin/_Rot.py @@ -9,6 +9,7 @@ from .. import InlineTag as _InlineTag __all__ = ["RotTag"] + class RotTag(_InlineTag): """ Tag which un-rot13 a content. Demonstration tag for content processing. diff --git a/textoutpc/builtin/_Show.py b/textoutpc/builtin/_Show.py index a37fa24..4bcab19 100755 --- a/textoutpc/builtin/_Show.py +++ b/textoutpc/builtin/_Show.py @@ -9,10 +9,11 @@ from .. import BlockTag as _BlockTag __all__ = ["ShowTag"] + class ShowTag(_BlockTag): """ Tag which shows the HTML code that is produced by textout(). Example uses: - + [show][b]hello world![/show] """ diff --git a/textoutpc/builtin/_Smileys.py b/textoutpc/builtin/_Smileys.py index 7ba93b8..16e6be0 100755 --- a/textoutpc/builtin/_Smileys.py +++ b/textoutpc/builtin/_Smileys.py @@ -16,124 +16,154 @@ __all__ = ["TwistedSmiley", "EvilSmiley", "SmileSmiley", "WinkSmiley", _prefix = '/images/smileys/' + class TwistedSmiley(_Smiley): aliases = ('>:)',) url = _prefix + 'twisted.gif' + class EvilSmiley(_Smiley): aliases = ('>:(', ':grr:') url = _prefix + 'evil.gif' + class SmileSmiley(_Smiley): aliases = (':)',) url = _prefix + 'smile.gif' + class WinkSmiley(_Smiley): aliases = (';)',) url = _prefix + 'wink.gif' + class SadSmiley(_Smiley): aliases = (':(',) url = _prefix + 'sad.gif' + class GrinSmiley(_Smiley): aliases = (':D', ':grin:') url = _prefix + 'grin.gif' + class HeheSmiley(_Smiley): aliases = (':p',) url = _prefix + 'hehe.gif' + class CoolSmiley(_Smiley): aliases = (':cool:',) url = _prefix + 'cool.gif' + class Cool2Smiley(_Smiley): aliases = ('8-)',) url = _prefix + 'cool2.gif' + class MadSmiley(_Smiley): aliases = (':@',) url = _prefix + 'mad.gif' + class EekSmiley(_Smiley): aliases = ('0_0',) url = _prefix + 'eek.gif' + class MrGreenSmiley(_Smiley): aliases = (':E', ':mrgreen:') url = _prefix + 'mrgreen.gif' + class ShockedSmiley(_Smiley): aliases = (':O',) url = _prefix + 'shocked.gif' + class ConfusedSmiley(_Smiley): aliases = (':s', ':oops:') url = _prefix + 'confused2.gif' + class EyebrowsSmiley(_Smiley): aliases = ('^^',) url = _prefix + 'eyebrows.gif' + class CrySmiley(_Smiley): aliases = (":'(", ":cry:") url = _prefix + 'cry.gif' + # FIXME #class WhistleSmiley(_Smiley): # aliases = (":-°", ':whistle:') # url = _prefix + 'whistle.gif' # height = '15px' + class LolSmiley(_Smiley): aliases = (":lol:",) url = _prefix + 'lol.gif' + class SorrySmiley(_Smiley): aliases = (":sry:",) url = _prefix + 'redface.gif' + class RollEyesSmiley(_Smiley): aliases = (":mmm:",) url = _prefix + 'rolleyes.gif' + class WazaSmiley(_Smiley): aliases = (":waza:",) url = _prefix + 'waza.gif' + class HereSmiley(_Smiley): aliases = (":here:", ":arrow:") url = _prefix + 'pointer.gif' + class BowSmiley(_Smiley): aliases = (":bow:",) url = _prefix + 'bow.gif' + class GoodSmiley(_Smiley): aliases = (":good:",) url = _prefix + 'welldone.gif' + class LoveSmiley(_Smiley): aliases = (":love:",) url = _prefix + 'love.gif' + class OuchSmiley(_Smiley): aliases = (":aie:",) url = _prefix + 'banghead2.gif' + class FacepalmSmiley(_Smiley): aliases = (":facepalm:",) url = _prefix + 'facepalm.gif' + class InsultsSmiley(_Smiley): aliases = (":argh:",) url = _prefix + 'insults.gif' + class WhatSmiley(_Smiley): aliases = (":?:",) url = _prefix + 'what.gif' + class ExclSmiley(_Smiley): aliases = (":!:",) url = _prefix + 'excl.gif' diff --git a/textoutpc/builtin/_Spoiler.py b/textoutpc/builtin/_Spoiler.py index 4fe1277..63f3543 100755 --- a/textoutpc/builtin/_Spoiler.py +++ b/textoutpc/builtin/_Spoiler.py @@ -8,12 +8,13 @@ from .. import BlockTag as _BlockTag __all__ = ["SpoilerTag"] + class SpoilerTag(_BlockTag): """ Hide content at first glance, force people to click to read content. These elements can contain 'secret' elements such as solutions, source code, or various other things. Example uses: - + [spoiler]This is hidden![/spoiler] [spoiler=Y a quelque chose de caché !|Ah, bah en fait non :)]:E And it's multiline, [big]and formatted[/big], as usual :D[/spoiler] @@ -37,11 +38,11 @@ class SpoilerTag(_BlockTag): def begin_html(self): return '
' \ - '

{}

' \ - '

{}

' \ - '
'.format(self._closed, self._open) + '

{}

' \ + '

{}

' \ + '
'.format(self._closed, self._open) def end_html(self): return '
' diff --git a/textoutpc/builtin/_Text.py b/textoutpc/builtin/_Text.py index 11778d9..db5f289 100755 --- a/textoutpc/builtin/_Text.py +++ b/textoutpc/builtin/_Text.py @@ -30,10 +30,11 @@ _fonts = { # Tag definition. # --- + class TextTag(_InlineTag): """ Main tag for setting text formatting. Example uses: - + [b]Bold text.[/b] [i]Italic text.[/i] [u]Underlined text.[/u] @@ -45,10 +46,10 @@ class TextTag(_InlineTag): [color=blue]This as well[/color] [color=rgb(255, 255, 255, 0.4)]BLACKNESS[/color] [color=hsl(0, 100%, 0.5)]This will be red.[/color] - + Also supports a hack used on Planète Casio for a while, which is a CSS injection, e.g.: - + [color=brown; size: 16pt]Hello world![/color] """ @@ -77,7 +78,7 @@ class TextTag(_InlineTag): def get_props(value): props = '' - if value != None: + if value is not None: index = value.find(';') if index >= 0: props = value[index + 1:] @@ -153,7 +154,7 @@ class TextTag(_InlineTag): if not value or \ any(c != '0' for c in value[:-3]) or \ - any(not c in '0123456789' for c in value[-3:]): + any(c not in '0123456789' for c in value[-3:]): continue value = int(value[-3:]) @@ -182,13 +183,13 @@ class TextTag(_InlineTag): if self._italic: props.append('font-style: italic') if self._underline or self._strike or self._overline: - props.append('text-decoration:{}{}{}'.format(' underline' \ - if self._underline else '', ' line-through' \ - if self._strike else '', ' overline' \ + props.append('text-decoration:{}{}{}'.format(' underline' + if self._underline else '', ' line-through' + if self._strike else '', ' overline' if self._overline else '')) else: if self._overline: - props.append('text-decoration:{}'.format(' overline' \ + props.append('text-decoration:{}'.format(' overline' if self._overline else '')) if self._font: @@ -206,13 +207,13 @@ class TextTag(_InlineTag): props.append('color: #%02X%02X%02X' % self._color[0:3]) if self._color[3] < 1.0: - props.append('color: rgba({}, {}, {}, {})' \ + props.append('color: rgba({}, {}, {}, {})' .format(*self._color)) if self._bgcolor and self._bgcolor[3] != 0.0: props.append('background-color: #%02X%02X%02X' % self._color[0:3]) if self._bgcolor[3] < 1.0: - props.append('background-color: rgba({}, {}, {}, {})' \ + props.append('background-color: rgba({}, {}, {}, {})' .format(*self._bgcolor)) if self._size: @@ -225,8 +226,8 @@ class TextTag(_InlineTag): cls, props = self._get_css() if cls or props: - props = ''.format(' class="{}"'.format(' '.join(cls)) \ - if cls else '', ' style="{}"'.format('; '.join(props)) \ + props = ''.format(' class="{}"'.format(' '.join(cls)) + if cls else '', ' style="{}"'.format('; '.join(props)) if props else '') else: props = '' diff --git a/textoutpc/builtin/_Title.py b/textoutpc/builtin/_Title.py index c2fb5f8..05d12ff 100755 --- a/textoutpc/builtin/_Title.py +++ b/textoutpc/builtin/_Title.py @@ -8,10 +8,11 @@ from .. import BlockTag as _BlockTag __all__ = ["TitleTag"] + class TitleTag(_BlockTag): """ The title tag. Example uses: - + [title]Some title[/title] [subtitle]Some subtitle[/subtitle] """ diff --git a/textoutpc/builtin/_Video.py b/textoutpc/builtin/_Video.py index 2dbbc63..b20dc45 100755 --- a/textoutpc/builtin/_Video.py +++ b/textoutpc/builtin/_Video.py @@ -14,11 +14,12 @@ __all__ = ["VideoTag", "YoutubeTag"] _defaultratio_w = 16 _defaultratio_h = 9 + class VideoTag(_BlockTag): """ The video tag, puts a preview of the video whose URL is given. Only a few 'big' services are supported for now. Example uses: - + [video]video_url[/video] [video=4:3]video_url[/video] [video tiny]video_url[/video tiny] @@ -77,7 +78,7 @@ class VideoTag(_BlockTag): self._video = self.video(content) except: url = _urlparse.urlparse(content) - if not url.scheme in ('http', 'https'): + if url.scheme not in ('http', 'https'): raise Exception("No allowed prefix!") self._video = content @@ -117,10 +118,11 @@ class VideoTag(_BlockTag): url = self._url.replace('[', '%5B').replace(']', '%5D') return '[[image:{}]]'.format(url) + class YoutubeTag(VideoTag): """ Alias for the video tag with only the Youtube possibility. Example uses: - + [youtube]okMK1NYRySI[/youtube] """ aliases = ('[youtube]',) diff --git a/textoutpc/builtin/_Videos.py b/textoutpc/builtin/_Videos.py index 6b7cfbe..5ffb759 100755 --- a/textoutpc/builtin/_Videos.py +++ b/textoutpc/builtin/_Videos.py @@ -11,6 +11,7 @@ from .. import Video as _Video __all__ = ["YouTubeVideo", "DailymotionVideo", "VimeoVideo"] + class YouTubeVideo(_Video): """ Get a video from Youtube. """ @@ -18,7 +19,7 @@ class YouTubeVideo(_Video): def __init__(self, url): url = _urlparse.urlparse(url) - if not url.scheme in ('http', 'https'): + if url.scheme not in ('http', 'https'): raise Exception if url.netloc == "youtu.be": @@ -36,6 +37,7 @@ class YouTubeVideo(_Video): self.embed = f"https://www.youtube.com/embed/{self._id}" + class DailymotionVideo(_Video): """ Get a video from Dailymotion. """ @@ -43,7 +45,7 @@ class DailymotionVideo(_Video): def __init__(self, url): url = _urlparse.urlparse(url) - if not url.scheme in ('http', 'https'): + if url.scheme not in ('http', 'https'): raise Exception if url.netloc in ('dailymotion.com', 'www.dailymotion.com'): @@ -53,6 +55,7 @@ class DailymotionVideo(_Video): self.embed = f"https://www.dailymotion.com/embed/video/{self._code}" + class VimeoVideo(_Video): """ Get a video from Vimeo. """ @@ -60,7 +63,7 @@ class VimeoVideo(_Video): def __init__(self, url): url = _urlparse.urlparse(url) - if not url.scheme in ('http', 'https'): + if url.scheme not in ('http', 'https'): raise Exception if url.netloc in ('vimeo.com', 'www.vimeo.com'):