diff -r 9dd23e6b13fc -r c78a885f46fa trac/htdocs/css/trac.css
|
a
|
b
|
span.closed { text-decoration: line-thro |
| 310 | 310 | span.closed { text-decoration: line-through } |
| 311 | 311 | span.forbidden, a.forbidden { background: #fafaf0; color: #998; } |
| 312 | 312 | |
| | 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 | |
| 313 | 322 | dl.wiki dt { font-weight: bold } |
| 314 | 323 | dl.compact dt { float: left; padding-right: .5em } |
| 315 | 324 | dl.compact dd { margin: 0; padding: 0 } |
diff -r 9dd23e6b13fc -r c78a885f46fa trac/wiki/formatter.py
|
a
|
b
|
import urllib |
| 24 | 24 | |
| 25 | 25 | from StringIO import StringIO |
| 26 | 26 | |
| 27 | | from genshi.builder import tag |
| 28 | | from genshi.core import Stream |
| | 27 | from genshi.builder import tag, Element |
| | 28 | from genshi.core import Stream, Markup, escape |
| | 29 | from genshi.util import plaintext |
| 29 | 30 | |
| 30 | 31 | from trac.context import get_relative_url |
| 31 | 32 | from trac.core import * |
| 32 | 33 | from trac.mimeview import * |
| 33 | 34 | from trac.util.compat import set |
| 34 | | from trac.wiki.api import WikiSystem |
| | 35 | from trac.wiki.api import WikiSystem, parse_args |
| 35 | 36 | from trac.wiki.parser import WikiParser |
| 36 | | from trac.util.html import escape, plaintext, Markup, Element, html |
| 37 | 37 | from trac.util.text import shorten_line, to_unicode |
| | 38 | from trac.util.translation import _ |
| 38 | 39 | |
| 39 | 40 | __all__ = ['wiki_to_html', 'wiki_to_oneliner', 'wiki_to_outline', |
| 40 | 41 | 'wiki_to_link', 'Formatter', |
| 41 | 42 | 'format_to', 'format_to_html', 'format_to_oneliner', 'extract_link'] |
| 42 | 43 | |
| 43 | 44 | def 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") |
| 46 | 47 | |
| 47 | 48 | |
| 48 | 49 | def _markup_to_unicode(markup): |
| … |
… |
class WikiProcessor(object): |
| 60 | 61 | |
| 61 | 62 | _code_block_re = re.compile('^<div(?:\s+class="([^"]+)")?>(.*)</div>$') |
| 62 | 63 | |
| 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) |
| 65 | 72 | """ |
| 66 | 73 | self.formatter = formatter |
| 67 | 74 | self.env = formatter.env |
| 68 | 75 | self.name = name |
| | 76 | self.args = args |
| 69 | 77 | self.error = None |
| 70 | 78 | self.macro_provider = None |
| 71 | 79 | |
| 72 | 80 | builtin_processors = {'html': self._html_processor, |
| 73 | 81 | 'default': self._default_processor, |
| 74 | | 'comment': self._comment_processor} |
| | 82 | 'comment': self._comment_processor, |
| | 83 | 'div': self._div_processor, |
| | 84 | 'span': self._span_processor} |
| 75 | 85 | |
| 76 | 86 | self.processor = builtin_processors.get(name) |
| 77 | 87 | if not self.processor: |
| … |
… |
class WikiProcessor(object): |
| 117 | 127 | return (stream | sanitizer).render('xhtml', encoding=None) |
| 118 | 128 | except ParseError, e: |
| 119 | 129 | 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)) |
| 122 | 149 | |
| 123 | 150 | # generic processors |
| 124 | 151 | |
| … |
… |
class WikiProcessor(object): |
| 172 | 199 | elif text.startswith('<table'): |
| 173 | 200 | interrupt_paragraph = True |
| 174 | 201 | if content_for_span: |
| 175 | | text = html.SPAN(class_='code-block')(*content_for_span) |
| | 202 | text = tag.span(class_='code-block')(*content_for_span) |
| 176 | 203 | elif interrupt_paragraph: |
| 177 | 204 | text = "</p>%s<p>" % to_unicode(text) |
| 178 | 205 | return text |
| … |
… |
class Formatter(object): |
| 278 | 305 | return self.simple_tag_handler(match, '<sup>', '</sup>') |
| 279 | 306 | |
| 280 | 307 | def _inlinecode_formatter(self, match, fullmatch): |
| 281 | | return html.TT(fullmatch.group('inline')) |
| | 308 | return tag.tt(fullmatch.group('inline')) |
| 282 | 309 | |
| 283 | 310 | def _inlinecode2_formatter(self, match, fullmatch): |
| 284 | | return html.TT(fullmatch.group('inline2')) |
| | 311 | return tag.tt(fullmatch.group('inline2')) |
| 285 | 312 | |
| 286 | 313 | # -- Post- IWikiSyntaxProvider rules |
| 287 | 314 | |
| … |
… |
class Formatter(object): |
| 329 | 356 | path) |
| 330 | 357 | if '?' in path: |
| 331 | 358 | 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) |
| 333 | 360 | else: |
| 334 | 361 | return self._make_link(ns, target, match, label) |
| 335 | 362 | |
| … |
… |
class Formatter(object): |
| 392 | 419 | local_url = self.env.config.get('project', 'url') or \ |
| 393 | 420 | (self.req or self.env).abs_href.base |
| 394 | 421 | if not url.startswith(local_url): |
| 395 | | return html.A(html.SPAN(text, class_="icon"), |
| | 422 | return tag.a(tag.span(text, class_="icon"), |
| 396 | 423 | class_="ext-link", href=url, title=title or None) |
| 397 | 424 | else: |
| 398 | | return html.A(text, href=url, title=title or None) |
| | 425 | return tag.a(text, href=url, title=title or None) |
| 399 | 426 | |
| 400 | 427 | 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"), |
| 402 | 429 | class_="mail-link", href=url, title=title or None) |
| 403 | 430 | |
| 404 | 431 | # WikiMacros |
| … |
… |
class Formatter(object): |
| 706 | 733 | else: |
| 707 | 734 | self.code_text += line + os.linesep |
| 708 | 735 | elif not self.code_processor: |
| 709 | | match = WikiParser._processor_re.search(line) |
| | 736 | match = WikiParser._processor_re.match(line) |
| 710 | 737 | if match: |
| 711 | 738 | 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) |
| 713 | 746 | else: |
| 714 | 747 | self.code_text += line + os.linesep |
| 715 | 748 | self.code_processor = WikiProcessor(self, 'default') |
diff -r 9dd23e6b13fc -r c78a885f46fa trac/wiki/parser.py
|
a
|
b
|
class WikiParser(Component): |
| 105 | 105 | r"(?P<table_cell>\|\|)"] |
| 106 | 106 | |
| 107 | 107 | _processor_re = re.compile('#\!([\w+-][\w+-/]*)') |
| | 108 | _processor_param_re = re.compile(r'''[\s;]*(\w+)=(".*?"|'.*?'|\w+)''') |
| 108 | 109 | _anchor_re = re.compile('[^\w:.-]+', re.UNICODE) |
| 109 | 110 | |
| 110 | 111 | def __init__(self): |