#!/usr/bin/env python # -*- encoding: utf-8 -*- ## _news_colors.py - colors that can be used in news ## ## Copyright © 2012-2014 Ben Longbons ## ## This file is part of The Mana World (Athena server) ## ## This program is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 2 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . try: # py3 from html import escape as html_escape except ImportError: # py2 from cgi import escape as html_escape __all__ = ['make_html_colors_dict', 'make_txt_colors_dict', 'make_forum_colors_dict'] class Color(object): __slots__ = ('txt', 'rgb') def __init__(self, txt, rgb): self.txt = txt self.rgb = rgb color_dict = dict( black = Color(txt='##0', rgb=0x000000), red = Color(txt='##1', rgb=0xff0000), green = Color(txt='##2', rgb=0x009000), blue = Color(txt='##3', rgb=0x0000ff), orange = Color(txt='##4', rgb=0xe0980e), yellow = Color(txt='##5', rgb=0xf1dc27), pink = Color(txt='##6', rgb=0xff00d8), purple = Color(txt='##7', rgb=0x8415e2), gray = Color(txt='##8', rgb=0x919191), brown = Color(txt='##9', rgb=0x8e4c17), ) class HtmlDate(object): __slots__ = () def __format__(self, date): return '%s' % date class HtmlLink(object): __slots__ = () def __format__(self, target): target = html_escape(target, True) return '%s' % (target, target) class HtmlSignature(object): __slots__ = () def __format__(self, author): return '-%s' % author class HtmlTitle(object): __slots__ = () def __format__(self, title): # no color here # (we really need someone to do CSS) return '%s' % title def make_html_colors_dict(): r = { 'date': HtmlDate(), 'link': HtmlLink(), 'author': HtmlSignature(), 'title': HtmlTitle(), 'ul' : '', 'li' : '
  • ', '/li': '
  • ', 'b' : '', '/b': '', } for k, v in color_dict.items(): r[k] = '' % v.rgb r['/' + k] = '' return r class ForumDate(object): __slots__ = () def __format__(self, date): return '[i]%s[/i]' % date class ForumLink(object): __slots__ = () def __format__(self, target): return '[url=%s]%s[/url]' % (target, target) class ForumSignature(object): __slots__ = () def __format__(self, author): return '-[i]%s[/i]' % author class ForumTitle(object): __slots__ = () def __format__(self, title): # no color here # (we really need someone to do CSS) return 'put this in the post title: %s' % title def make_forum_colors_dict(): r = { 'date': ForumDate(), 'link': ForumLink(), 'author': ForumSignature(), 'title': ForumTitle(), 'ul' : '[list]', '/ul': '[/list]', 'li' : '[*]', '/li': '', 'b' : '[b]', '/b': '[/b]', } for k, v in color_dict.items(): r[k] = '[color=#%06x]' % v.rgb r['/' + k] = '[/color]' return r # Here be dragons def make_txt_colors_dict(): return dict(generate_txt_colors()) class StackPusher(object): __slots__ = ('tag_stack', 'tag', 'txt_stack', 'txt') def __init__(self, tag_stack, tag, txt_stack, txt): self.tag_stack = tag_stack self.tag = tag self.txt_stack = txt_stack self.txt = txt def __format__(self, fmt): assert fmt == '' self.tag_stack.append(self.tag) if self.txt_stack is not None: self.txt_stack.append(self.txt) return self.txt class StackPopper(object): __slots__ = ('tag_stack', 'tag', 'txt_stack', 'txt') def __init__(self, tag_stack, tag, txt_stack, txt): self.tag_stack = tag_stack self.tag = tag self.txt_stack = txt_stack self.txt = txt def __format__(self, fmt): assert fmt == '' if len(self.tag_stack) <= 0: raise SyntaxError('Unmatched {/%s}' % self.tag) prev = self.tag_stack.pop() if self.tag != prev: raise SyntaxError('Mismatched {/%s} from {%s}' % (self.tag, prev)) if self.txt_stack is not None: self.txt_stack.pop() return self.txt_stack[-1] return self.txt class TxtDate(object): __slots__ = ('stack') def __init__(self, stack): self.stack = stack def __format__(self, date): return '##3' + date + self.stack[-1] class TxtLink(object): __slots__ = ('stack') def __init__(self, stack): self.stack = stack def __format__(self, target): # the field labeled 'bug' should not be necessary ... return '@@{link}|{text}@@{bug}'.format(link=target, text=target, bug=self.stack[-1]) class TxtSignature(object): __slots__ = ('stack') def __init__(self, stack): self.stack = stack def __format__(self, author): return '-##2' + author + self.stack[-1] class TxtTitle(object): __slots__ = ('stack') def __init__(self, stack): self.stack = stack def __format__(self, title): return '##7' + title + self.stack[-1] def generate_txt_colors(): tag_stack = [] color_stack = ['##0'] # don't let color stack become empty for k,v in color_dict.items(): yield k, StackPusher(tag_stack, k, color_stack, v.txt) e = '/' + k yield e, StackPopper(tag_stack, k, color_stack, v.txt) yield 'date', TxtDate(color_stack) yield 'link', TxtLink(color_stack) yield 'author', TxtSignature(color_stack) yield 'title', TxtTitle(color_stack) yield 'ul', StackPusher(tag_stack, 'ul', None, '') yield '/ul', StackPopper(tag_stack, 'ul', None, '') yield 'li', StackPusher(tag_stack, 'li', None, '* ') yield '/li', StackPopper(tag_stack, 'li', None, '') yield 'b', '##B' yield '/b', '##b'