source: linenomacro/trunk/lineno/LinenoMacro.py @ 11954

Last change on this file since 11954 was 11954, checked in by Ryan J Ollos, 12 years ago

Refs #10292: (1.2dev) Modified generation of anchor ids to ensure that the id associated with each line number will be unique for the resource. The ids are of the form a\d-L\d (e.g. a1-L1).

File size: 2.9 KB
Line 
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
10from genshi.builder import tag
11from trac.core import implements
12from trac.mimeview.api import IHTMLPreviewAnnotator, Mimeview
13from trac.util.translation import _
14from trac.web.chrome import ITemplateProvider, add_stylesheet
15from trac.wiki.macros import WikiMacroBase
16from trac.wiki.parser import WikiParser
17
18
19class 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        ))
Note: See TracBrowser for help on using the repository browser.