Edgewall Software

Ticket #2048: div_span_macros.diff

File div_span_macros.diff, 7.8 KB (added by cboos, 4 years ago)

Add builtin div and span wiki processors - suggested fix for 0.11

  • trac/htdocs/css/trac.css

    diff -r 9dd23e6b13fc -r c78a885f46fa trac/htdocs/css/trac.css
    a b span.closed { text-decoration: line-thro 
    310310span.closed { text-decoration: line-through } 
    311311span.forbidden, a.forbidden { background: #fafaf0; color: #998; } 
    312312 
     313/* User-selectable styles for blocks */ 
     314.important { 
     315 background: #fcb; 
     316 border: 1px dotted #d00; 
     317 color: #500; 
     318 padding: 0 .5em 0 .5em; 
     319 margin: .5em; 
     320} 
     321 
    313322dl.wiki dt { font-weight: bold } 
    314323dl.compact dt { float: left; padding-right: .5em } 
    315324dl.compact dd { margin: 0; padding: 0 } 
  • trac/wiki/formatter.py

    diff -r 9dd23e6b13fc -r c78a885f46fa trac/wiki/formatter.py
    a b import urllib 
    2424 
    2525from StringIO import StringIO 
    2626 
    27 from genshi.builder import tag 
    28 from genshi.core import Stream 
     27from genshi.builder import tag, Element 
     28from genshi.core import Stream, Markup, escape 
     29from genshi.util import plaintext 
    2930 
    3031from trac.context import get_relative_url 
    3132from trac.core import * 
    3233from trac.mimeview import * 
    3334from trac.util.compat import set 
    34 from trac.wiki.api import WikiSystem 
     35from trac.wiki.api import WikiSystem, parse_args 
    3536from trac.wiki.parser import WikiParser 
    36 from trac.util.html import escape, plaintext, Markup, Element, html 
    3737from trac.util.text import shorten_line, to_unicode 
     38from trac.util.translation import _ 
    3839 
    3940__all__ = ['wiki_to_html', 'wiki_to_oneliner', 'wiki_to_outline', 
    4041           'wiki_to_link', 'Formatter', 
    4142           'format_to', 'format_to_html', 'format_to_oneliner', 'extract_link'] 
    4243 
    4344def system_message(msg, text=None): 
    44     return html.DIV(html.STRONG(msg), text and html.PRE(text), 
    45                     class_="system-message") 
     45    return tag.div(tag.strong(msg), text and tag.pre(text), 
     46                   class_="system-message") 
    4647 
    4748 
    4849def _markup_to_unicode(markup): 
    class WikiProcessor(object): 
    6061 
    6162    _code_block_re = re.compile('^<div(?:\s+class="([^"]+)")?>(.*)</div>$') 
    6263 
    63     def __init__(self, formatter, name): 
    64         """Since 0.11: first argument is a Formatter instead of an Environment. 
     64    def __init__(self, formatter, name, args={}): 
     65        """Find the processor by name 
     66         
     67        :param formatter: the formatter embedding a call for this processor  
     68        :param name: the name of the processor  
     69        :param args: extra parameters for the processor 
     70 
     71        (since 0.11) 
    6572        """ 
    6673        self.formatter = formatter 
    6774        self.env = formatter.env 
    6875        self.name = name 
     76        self.args = args 
    6977        self.error = None 
    7078        self.macro_provider = None 
    7179 
    7280        builtin_processors = {'html': self._html_processor, 
    7381                              'default': self._default_processor, 
    74                               'comment': self._comment_processor} 
     82                              'comment': self._comment_processor, 
     83                              'div': self._div_processor, 
     84                              'span': self._span_processor} 
    7585         
    7686        self.processor = builtin_processors.get(name) 
    7787        if not self.processor: 
    class WikiProcessor(object): 
    117127            return (stream | sanitizer).render('xhtml', encoding=None) 
    118128        except ParseError, e: 
    119129            self.env.log.warn(e) 
    120             return system_message('HTML parsing error: %s' % escape(e.msg), 
    121                                   text.splitlines()[e.lineno - 1].strip()) 
     130            line = unicode(text).splitlines()[e.lineno - 1].strip() 
     131            return system_message(_('HTML parsing error: %(message)s', 
     132                                    message=escape(e.msg)), line) 
     133         
     134    def _div_processor(self, text): 
     135        if 'class' in self.args: 
     136            self.args['class_'] = self.args['class'] 
     137            del self.args['class'] 
     138        return self._html_processor( 
     139            tag.div(format_to_html(self.formatter.context, text), **self.args)) 
     140 
     141    def _span_processor(self, text): 
     142        args, kwargs = parse_args(text) 
     143        if 'class' in kwargs: 
     144            kwargs['class_'] = kwargs['class'] 
     145            del kwargs['class'] 
     146        return self._html_processor( 
     147            tag.span(format_to_oneliner(self.formatter.context, 
     148                                        ', '.join(args)), **kwargs)) 
    122149 
    123150    # generic processors 
    124151 
    class WikiProcessor(object): 
    172199                elif text.startswith('<table'): 
    173200                    interrupt_paragraph = True 
    174201            if content_for_span: 
    175                 text = html.SPAN(class_='code-block')(*content_for_span) 
     202                text = tag.span(class_='code-block')(*content_for_span) 
    176203            elif interrupt_paragraph: 
    177204                text = "</p>%s<p>" % to_unicode(text) 
    178205        return text 
    class Formatter(object): 
    278305        return self.simple_tag_handler(match, '<sup>', '</sup>') 
    279306 
    280307    def _inlinecode_formatter(self, match, fullmatch): 
    281         return html.TT(fullmatch.group('inline')) 
     308        return tag.tt(fullmatch.group('inline')) 
    282309 
    283310    def _inlinecode2_formatter(self, match, fullmatch): 
    284         return html.TT(fullmatch.group('inline2')) 
     311        return tag.tt(fullmatch.group('inline2')) 
    285312 
    286313    # -- Post- IWikiSyntaxProvider rules 
    287314 
    class Formatter(object): 
    329356                                        path) 
    330357                if '?' in path: 
    331358                    query = '&' + query.lstrip('?') 
    332             return html.A(label or rel, href=path + query + fragment) 
     359            return tag.a(label or rel, href=path + query + fragment) 
    333360        else: 
    334361            return self._make_link(ns, target, match, label) 
    335362 
    class Formatter(object): 
    392419        local_url = self.env.config.get('project', 'url') or \ 
    393420                    (self.req or self.env).abs_href.base 
    394421        if not url.startswith(local_url): 
    395             return html.A(html.SPAN(text, class_="icon"), 
     422            return tag.a(tag.span(text, class_="icon"), 
    396423                          class_="ext-link", href=url, title=title or None) 
    397424        else: 
    398             return html.A(text, href=url, title=title or None) 
     425            return tag.a(text, href=url, title=title or None) 
    399426 
    400427    def _make_mail_link(self, url, text, title=''): 
    401         return html.A(html.SPAN(text, class_="icon"), 
     428        return tag.a(tag.span(text, class_="icon"), 
    402429                      class_="mail-link", href=url, title=title or None) 
    403430 
    404431    # WikiMacros 
    class Formatter(object): 
    706733            else: 
    707734                self.code_text += line + os.linesep 
    708735        elif not self.code_processor: 
    709             match = WikiParser._processor_re.search(line) 
     736            match = WikiParser._processor_re.match(line) 
    710737            if match: 
    711738                name = match.group(1) 
    712                 self.code_processor = WikiProcessor(self, name) 
     739                args = WikiParser._processor_param_re.split(line[len(name):]) 
     740                del args[::3] 
     741                keys = [str(k) for k in args[::2]] # used as keyword parameters 
     742                values = [v and v[0] in '"\'' and v[1:-1] or v 
     743                          for v in args[1::2]] 
     744                args = dict(zip(keys, values)) 
     745                self.code_processor = WikiProcessor(self, name, args) 
    713746            else: 
    714747                self.code_text += line + os.linesep  
    715748                self.code_processor = WikiProcessor(self, 'default') 
  • trac/wiki/parser.py

    diff -r 9dd23e6b13fc -r c78a885f46fa trac/wiki/parser.py
    a b class WikiParser(Component): 
    105105        r"(?P<table_cell>\|\|)"] 
    106106 
    107107    _processor_re = re.compile('#\!([\w+-][\w+-/]*)') 
     108    _processor_param_re = re.compile(r'''[\s;]*(\w+)=(".*?"|'.*?'|\w+)''') 
    108109    _anchor_re = re.compile('[^\w:.-]+', re.UNICODE) 
    109110 
    110111    def __init__(self):