aboutsummaryrefslogtreecommitdiff
path: root/textoutpc/builtin/_Text.py
diff options
context:
space:
mode:
authorThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-07-28 19:36:43 +0200
committerThomas "Cakeisalie5" Touhey <thomas@touhey.fr>2018-07-28 19:36:43 +0200
commit8d9d4360ed9a20b3f5b6ec38c8f2e40b12ff1781 (patch)
tree550a246df7078b210c8405c94ee13c3235731c93 /textoutpc/builtin/_Text.py
parenta2fdc5d5a03422848fd2413c037d0c6668dbfe84 (diff)
Better smiley implementation.
Diffstat (limited to 'textoutpc/builtin/_Text.py')
-rwxr-xr-xtextoutpc/builtin/_Text.py221
1 files changed, 221 insertions, 0 deletions
diff --git a/textoutpc/builtin/_Text.py b/textoutpc/builtin/_Text.py
new file mode 100755
index 0000000..506ab1f
--- /dev/null
+++ b/textoutpc/builtin/_Text.py
@@ -0,0 +1,221 @@
+#!/usr/bin/env python3
+#******************************************************************************
+# Copyright (C) 2018 Thomas "Cakeisalie5" Touhey <thomas@touhey.fr>
+# This file is part of the textoutpc project, which is MIT-licensed.
+#******************************************************************************
+
+from .. import InlineTag as _TextoutInlineTag
+from ..color import get_color as _get_color
+
+__all__ = ["TextoutTextTag"]
+
+# ---
+# Data.
+# ---
+
+_big_size = 2.00
+_sml_size = 0.75
+
+_fonts = {
+ "arial": "Arial",
+ "comic": "Comic MS",
+ "tahoma": "Tahoma",
+ "courier": "Courier",
+ "haettenschweiler": "Haettenschweiler",
+ "mono": "monospace",
+ "monospace": "monospace"
+}
+
+# ---
+# Tag definition.
+# ---
+
+class TextoutTextTag(_TextoutInlineTag):
+ """ Main tag for setting text formatting.
+ Example uses:
+
+ [b]Bold text.[/b]
+ [i]Italic text.[/i]
+ [u]Underlined text.[/u]
+ [strike]Striked text.[/strike]
+ [striked]Text strikes again.[/striked]
+ [font=arial]Arial text.[/font]
+ [arial]Arial text again.[/arial]
+ [blue]This will be in blue[/blue]
+ [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]
+ """
+
+ aliases = ('[b]', '[i]', '[u]', '[s]', '[strike]',
+ '[monospace]', '[mono]', '[font]', '[color]',
+ '[size]', '[big]', '[small]',
+ '[arial]', '[comic]', '[tahoma]', '[courier]',
+ '[haettenschweiler]', '[red]', '[green]', '[blue]',
+ '[yellow]', '[maroon]', '[purple]', '[gray]',
+ '[grey]', '[brown]')
+ notempty = True
+
+ def prepare(self, name, value):
+ self._bold = False
+ self._italic = False
+ self._underline = False
+ self._strike = False
+ self._font = None
+ self._color = None
+ self._size = None
+
+ # Récupérer la partie correspondant à l'injection CSS s'il y
+ # en a une.
+
+ def get_props(value):
+ props = ''
+ if value != None:
+ index = value.find(';')
+ if index >= 0:
+ props = value[index + 1:]
+ value = value[:index]
+ return value, props
+
+ # Définir les propriétés à partir du truc principal.
+
+ name = name[1:-1]
+ props = ""
+ if name == "b":
+ self._bold = True
+ elif name == "i":
+ self._italic = True
+ elif name == "u":
+ self._underline = True
+ elif name in ("s", "strike", "striked"):
+ self._strike = True
+ elif name == "color":
+ value, props = get_props(value)
+ self._color = _get_color(value)
+ elif name == "font":
+ value, props = get_props(value)
+ assert value in _fonts
+ self._font = _fonts[value]
+ elif name in ('size', 'big', 'small'):
+ if name != 'size':
+ value = name
+ if value == 'big':
+ self._size = _big_size
+ elif value == 'small':
+ self._size = _sml_size
+ else:
+ self._size = round(int(value) / 100.0, 2)
+ assert 0 < self._size <= 3.0
+
+ if self._size == 1.0:
+ self._size = None
+ elif name in _fonts:
+ self._font = name
+ else:
+ self._color = _get_color(name)
+
+ # Gestion des injections CSS.
+
+ for prop in props.split(';'):
+ prop = prop.strip()
+ if not prop:
+ continue
+
+ name, *value = prop.split(':')
+ if not value:
+ continue
+ name = name.strip()
+ value = ':'.join(value).strip()
+
+ if name == 'size':
+ unit = 'pt'
+ if value.endswith('pt'):
+ value = value[:-2].rstrip()
+ elif value.endswith('em'):
+ unit = 'em'
+ value = value[:-2].rstrip()
+
+ if not value or \
+ any(c != '0' for c in value[:-3]) or \
+ any(not c in '0123456789' for c in value[-3:]):
+ continue
+
+ value = int(value[-3:])
+ if unit == 'pt':
+ value /= 12 # XXX: default em size
+
+ if 0 < value <= 3.0:
+ self._size = value
+
+ def _get_css(self):
+ """ Get the `style` CSS classes and properties for HTML output. """
+
+ classes, props = [], []
+
+ if not self.tweak('obsolete_tags', True):
+ if self._bold:
+ props.append('font-weight: bold')
+ if self._italic:
+ props.append('font-style: italic')
+ if self._underline or self._strike:
+ props.append('text-decoration:{}{}'.format(' underline' \
+ if self._underline else '', ' line-through' \
+ if self._strike else ''))
+
+ if self._font:
+ props.append('font-family: ' + self._font)
+
+ if self._color:
+ # `transparent` is at least considered as a special value,
+ # or at most as an alias to `rgba(0,0,0,0)`.
+
+ if self._color[3] == 0.0:
+ props.append('color: transparent')
+ else:
+ # always append the #rgb color: it will be read by older
+ # browsers if the `rgba()` function isn't supported.
+
+ props.append('color: #%02X%02X%02X' % self._color[0:3])
+ if self._color[3] < 1.0:
+ props.append('color: rgba({}, {}, {}, {})' \
+ .format(*self._color))
+
+ if self._size:
+ props.append('font-size: {}em'.format(self._size))
+
+ return classes, props
+
+ def begin_html(self):
+ obsoletetags = self.tweak('obsolete_tags', True)
+
+ cls, props = self._get_css()
+ if cls or props:
+ props = '<span{}{}>'.format(' class="{}"'.format(' '.join(cls)) \
+ if cls else '', ' style="{}"'.format('; '.join(props)) \
+ if props else '')
+ else:
+ props = ''
+
+ return '' \
+ + ('', '<b>')[obsoletetags and self._bold] \
+ + ('', '<i>')[obsoletetags and self._italic] \
+ + ('', '<u>')[obsoletetags and self._underline] \
+ + ('', '<strike>')[obsoletetags and self._strike] \
+ + props
+
+ def end_html(self):
+ obsoletetags = self.tweak('obsolete_tags', True)
+
+ return '' \
+ + ('', '</span>')[any(self._get_css())] \
+ + ('', '</strike>')[obsoletetags and self._strike] \
+ + ('', '</u>')[obsoletetags and self._underline] \
+ + ('', '</i>')[obsoletetags and self._italic] \
+ + ('', '</b>')[obsoletetags and self._bold]
+
+# End of file.