1 | # -*- coding: utf-8 -*- |
---|
2 | # |
---|
3 | # Copyright (C) 2008-2009 Adamansky Anton <anton@adamansky.com> |
---|
4 | # Copyright (C) 2012 Ryan J Ollos <ryan.j.ollos@gmail.com> |
---|
5 | # All rights reserved. |
---|
6 | # |
---|
7 | # This software is licensed as described in the file COPYING, which |
---|
8 | # you should have received as part of this distribution. |
---|
9 | |
---|
10 | from genshi.builder import tag |
---|
11 | from trac.core import implements |
---|
12 | from trac.mimeview.api import IHTMLPreviewAnnotator, Mimeview |
---|
13 | from trac.util.translation import _ |
---|
14 | from trac.web.chrome import ITemplateProvider, add_stylesheet |
---|
15 | from trac.wiki.macros import WikiMacroBase |
---|
16 | from trac.wiki.parser import WikiParser |
---|
17 | |
---|
18 | |
---|
19 | class LinenoMacro(WikiMacroBase): |
---|
20 | """Wiki processor that prints line numbers for code blocks. |
---|
21 | |
---|
22 | Example: |
---|
23 | |
---|
24 | {{{ |
---|
25 | {{{ |
---|
26 | #!Lineno |
---|
27 | #!java |
---|
28 | class A { |
---|
29 | public static void main(String[] args) { |
---|
30 | } |
---|
31 | } |
---|
32 | }}} |
---|
33 | }}} |
---|
34 | |
---|
35 | {{{ |
---|
36 | #!Lineno |
---|
37 | #!java |
---|
38 | class A { |
---|
39 | public static void main(String[] args) { |
---|
40 | } |
---|
41 | } |
---|
42 | }}} |
---|
43 | """ |
---|
44 | |
---|
45 | implements(IHTMLPreviewAnnotator, ITemplateProvider) |
---|
46 | |
---|
47 | def __init__(self): |
---|
48 | self._anchor = None |
---|
49 | |
---|
50 | def expand_macro(self, formatter, name, content): |
---|
51 | add_stylesheet(formatter.req, 'lineno/css/lineno.css') |
---|
52 | |
---|
53 | i = 1 |
---|
54 | self._anchor = 'a1' |
---|
55 | while self._anchor in formatter._anchors: |
---|
56 | self._anchor = 'a' + str(i) |
---|
57 | i += 1 |
---|
58 | formatter._anchors[self._anchor] = True |
---|
59 | |
---|
60 | mt = 'txt' |
---|
61 | match = WikiParser._processor_re.match(content) |
---|
62 | if match: |
---|
63 | try: #Trac 0.12+ |
---|
64 | mt = match.group(2) |
---|
65 | content = content[match.end(2)+1:] |
---|
66 | except IndexError: #Trac 0.11 |
---|
67 | mt = match.group(1) |
---|
68 | content = content[match.end(1)+1:] |
---|
69 | |
---|
70 | mimeview = Mimeview(formatter.env) |
---|
71 | mimetype = mimeview.get_mimetype(mt) or mimeview.get_mimetype('txt') |
---|
72 | return mimeview.render(formatter.context, mimetype, |
---|
73 | content, annotations=['codeblock-lineno']) |
---|
74 | |
---|
75 | |
---|
76 | ### ITemplateProvider methods |
---|
77 | |
---|
78 | def get_templates_dirs(self): |
---|
79 | return [] |
---|
80 | |
---|
81 | def get_htdocs_dirs(self): |
---|
82 | from pkg_resources import resource_filename |
---|
83 | return [('lineno', resource_filename(__name__, 'htdocs'))] |
---|
84 | |
---|
85 | |
---|
86 | ### ITextAnnotator methods |
---|
87 | |
---|
88 | # This implementation is almost identical to LineNumberAnnotator |
---|
89 | # in trac.mimeview.api, except we take care to ensure that the id |
---|
90 | # for each line number anchor is unique. |
---|
91 | |
---|
92 | def get_annotation_type(self): |
---|
93 | return 'codeblock-lineno', _('Line'), _('Line numbers') |
---|
94 | |
---|
95 | def get_annotation_data(self, context): |
---|
96 | return None |
---|
97 | |
---|
98 | def annotate_row(self, context, row, lineno, line, data): |
---|
99 | id = self._anchor + '-L%s' % lineno |
---|
100 | row.append(tag.th(id=id)( |
---|
101 | tag.a(lineno, href='#'+id) |
---|
102 | )) |
---|