| 1 | # -*- coding: iso-8859-1 -*- |
|---|
| 2 | # |
|---|
| 3 | # Copyright (C) 2011 Mikael Relbe <mikael@relbe.se> |
|---|
| 4 | # All rights reserved. |
|---|
| 5 | # |
|---|
| 6 | # This software is licensed as described in the file COPYING, which |
|---|
| 7 | # you should have received as part of this distribution. The terms |
|---|
| 8 | # are also available at http://trac.edgewall.com/license.html. |
|---|
| 9 | # |
|---|
| 10 | # Author: Mikael Relbe <mikael@relbe.se> |
|---|
| 11 | |
|---|
| 12 | """Decorate wiki text with colors. |
|---|
| 13 | """ |
|---|
| 14 | |
|---|
| 15 | from trac.util.html import Markup, html as tag |
|---|
| 16 | |
|---|
| 17 | from trac.core import implements, Component |
|---|
| 18 | from trac.util.compat import cleandoc |
|---|
| 19 | from trac.wiki import IWikiMacroProvider, format_to_html, format_to_oneliner |
|---|
| 20 | |
|---|
| 21 | from tracwikiextras.util import sanitize_attrib |
|---|
| 22 | |
|---|
| 23 | |
|---|
| 24 | class Color(Component): |
|---|
| 25 | """Macro for coloring wiki text. |
|---|
| 26 | |
|---|
| 27 | Use the `Color` macro to decorate text with colors. |
|---|
| 28 | """ |
|---|
| 29 | |
|---|
| 30 | implements(IWikiMacroProvider) |
|---|
| 31 | |
|---|
| 32 | # IWikiMacroProvider methods |
|---|
| 33 | |
|---|
| 34 | def get_macros(self): |
|---|
| 35 | yield 'Color' |
|---|
| 36 | |
|---|
| 37 | #noinspection PyUnusedLocal |
|---|
| 38 | def get_macro_description(self, name): |
|---|
| 39 | return cleandoc("""Decorate text with colors. |
|---|
| 40 | |
|---|
| 41 | Syntax: |
|---|
| 42 | {{{ |
|---|
| 43 | [[Color(text, fg/bg/size)]] |
|---|
| 44 | }}} |
|---|
| 45 | where |
|---|
| 46 | * `text` is the text to decorate. Enter a leading and/or |
|---|
| 47 | trailing space character to surround the text with a |
|---|
| 48 | decorated space. |
|---|
| 49 | * `fg/bg/size` defines the foreground and background colors, |
|---|
| 50 | and a font size. All parameters are optional and separated |
|---|
| 51 | by slash character (`/`). |
|---|
| 52 | |
|---|
| 53 | Colors may be specified as an RGB triplet in hexadecimal format |
|---|
| 54 | (a hex triplet; e.g. `#000` or `#000000` for black); they may |
|---|
| 55 | also be specified according to their common English names (e.g. |
|---|
| 56 | red, green, blue etc.). See |
|---|
| 57 | [http://en.wikipedia.org/wiki/Web_colors here] for details. |
|---|
| 58 | |
|---|
| 59 | Examples: |
|---|
| 60 | {{{ |
|---|
| 61 | [[Color(Large red on yellow, red/yellow/150%)]] |
|---|
| 62 | [[Color(Red on yellow, red/yellow)]] |
|---|
| 63 | [[Color(Yellow background, /yellow)]] |
|---|
| 64 | [[Color(Large red, #f00/2em)]] |
|---|
| 65 | [[Color(Large on yellow, /yellow/20px)]] |
|---|
| 66 | [[Color(Text, can, have, commas, /yellow)]] |
|---|
| 67 | [[Color( Surrounding space is also decorated , white/red)]] |
|---|
| 68 | }}} |
|---|
| 69 | |
|---|
| 70 | To set the foreground color for a larger block, the processor |
|---|
| 71 | variant can be used ''(background color and font size may not |
|---|
| 72 | display as expected due to the mechanisms of cascading style |
|---|
| 73 | sheets, be advised and use the ''color'' parameter only)'': |
|---|
| 74 | |
|---|
| 75 | {{{ |
|---|
| 76 | {{{#!Color color=green |
|---|
| 77 | ... |
|---|
| 78 | }}} |
|---|
| 79 | }}} |
|---|
| 80 | """) |
|---|
| 81 | |
|---|
| 82 | #noinspection PyUnusedLocal |
|---|
| 83 | def expand_macro(self, formatter, name, content, args=None): |
|---|
| 84 | style_args = {'fg': 'color', 'bg': 'background-color', |
|---|
| 85 | 'size': 'font-size'} |
|---|
| 86 | style_values = {'color': '', 'background-color': '', 'font-size': ''} |
|---|
| 87 | space_start = '' |
|---|
| 88 | space_end = '' |
|---|
| 89 | if args: |
|---|
| 90 | text = content |
|---|
| 91 | for k in args.keys(): |
|---|
| 92 | style = style_args[k] if k in style_args else k |
|---|
| 93 | style_values[style] = args.get(k) |
|---|
| 94 | html = format_to_html(self.env, formatter.context, text) |
|---|
| 95 | else: |
|---|
| 96 | args = content.split(',') |
|---|
| 97 | text = ','.join(args[:-1]) |
|---|
| 98 | args = args[-1].split('/') + ['']*3 |
|---|
| 99 | style_values['color'] = args.pop(0).strip() |
|---|
| 100 | # background color is optional |
|---|
| 101 | arg = args.pop(0).strip() |
|---|
| 102 | if len(arg) > 0 and arg[0].isdigit(): |
|---|
| 103 | style_values['font-size'] = arg |
|---|
| 104 | else: |
|---|
| 105 | style_values['background-color'] = arg |
|---|
| 106 | style_values['font-size'] = args.pop(0).strip() |
|---|
| 107 | html = format_to_oneliner(self.env, formatter.context, text) |
|---|
| 108 | if text.startswith(u' '): |
|---|
| 109 | space_start = Markup(' ') |
|---|
| 110 | if text.endswith(u' '): |
|---|
| 111 | space_end = Markup(' ') |
|---|
| 112 | if style_values['font-size'].isdigit(): |
|---|
| 113 | style_values['font-size'] = '%s%%' % style_values['font-size'] |
|---|
| 114 | style = ';'.join('%s:%s' % (k, v) for (k, v) in |
|---|
| 115 | style_values.iteritems() if v) |
|---|
| 116 | |
|---|
| 117 | span = sanitize_attrib(self.env, tag.span(style=style)) |
|---|
| 118 | span(space_start, html, space_end) |
|---|
| 119 | return span |
|---|