Пример #1
0
 def render_macro(self, req, name, content):
     from trac.wiki.formatter import Formatter
     formatter = Formatter(self.env, req)
     def getparm(category, target):
         return req.perm.perms
     formatter.perm = getparm
     return self.expand_macro(formatter, name, content)
Пример #2
0
    def format(self, active_page, page, text, out, min_depth, max_depth):
        self.__page = page
        # XXX Code copied straight out of OutlineFormatter
        self.outline = []

        class NullOut(object):
            def write(self, data):
                pass

        Formatter.format(self, text, NullOut())

        if min_depth > max_depth:
            min_depth, max_depth = max_depth, min_depth
        max_depth = min(6, max_depth)
        min_depth = max(1, min_depth)

        curr_depth = min_depth - 1
        for depth, link in self.outline:
            active = ''
            if '/%s' % active_page in link:
                active = ' class="active"'
            if depth < min_depth or depth > max_depth:
                continue
            if depth < curr_depth:
                out.write('</li></ol><li%s>' % active * (curr_depth - depth))
            elif depth > curr_depth:
                out.write('<ol><li%s>' % active * (depth - curr_depth))
            else:
                out.write("</li><li%s>\n" % active)
            curr_depth = depth
            out.write(link)
        out.write('</li></ol>' * curr_depth)
Пример #3
0
    def format(self, active_page, page, text, out, min_depth, max_depth):
        # XXX Code copied straight out of OutlineFormatter
        self.outline = []
        Formatter.format(self, text)

        active = ''
        if page == active_page:
            active = ' class="active"'

        if min_depth > max_depth:
            min_depth, max_depth = max_depth, min_depth
        max_depth = min(6, max_depth)
        min_depth = max(1, min_depth)

        curr_depth = min_depth - 1
        for depth, anchor, heading in self.outline:
            if depth < min_depth or depth > max_depth:
                continue
            if depth < curr_depth:
                out.write('</li></ol><li%s>' % active * (curr_depth - depth))
            elif depth > curr_depth:
                out.write('<ol><li%s>' % active * (depth - curr_depth))
            else:
                out.write("</li><li%s>\n" % active)
            curr_depth = depth
            out.write('<a href="%s#%s">%s</a>' %
                      (self.href.wiki(page), anchor, heading))
        out.write('</li></ol>' * curr_depth)
Пример #4
0
    def format(self, active_page, page, text, out, min_depth, max_depth):
        self.__page = page
        # XXX Code copied straight out of OutlineFormatter
        self.outline = []
        class NullOut(object):
            def write(self, data): pass
        Formatter.format(self, text, NullOut())

        if min_depth > max_depth:
            min_depth, max_depth = max_depth, min_depth
        max_depth = min(6, max_depth)
        min_depth = max(1, min_depth)

        curr_depth = min_depth - 1
        for depth, link in self.outline:
            active = ''
            if '/%s' % active_page in link:
                active = ' class="active"'
            if depth < min_depth or depth > max_depth:
                continue
            if depth < curr_depth:
                out.write('</li></ol><li%s>' % active * (curr_depth - depth))
            elif depth > curr_depth:
                out.write('<ol><li%s>' % active * (depth - curr_depth))
            else:
                out.write("</li><li%s>\n" % active)
            curr_depth = depth
            out.write(link)
        out.write('</li></ol>' * curr_depth)
Пример #5
0
    def format(self, active_page, page, text, out, min_depth, max_depth):
        # XXX Code copied straight out of OutlineFormatter
        self.outline = []
        Formatter.format(self, text)

        active = ''
        if page == active_page:
            active = ' class="active"'

        if min_depth > max_depth:
            min_depth, max_depth = max_depth, min_depth
        max_depth = min(6, max_depth)
        min_depth = max(1, min_depth)

        curr_depth = min_depth - 1
        for depth, anchor, heading in self.outline:
            if depth < min_depth or depth > max_depth:
                continue
            if depth < curr_depth:
                out.write('</li></ol><li%s>' % active * (curr_depth - depth))
            elif depth > curr_depth:
                out.write('<ol><li%s>' % active * (depth - curr_depth))
            else:
                out.write("</li><li%s>\n" % active)
            curr_depth = depth
            out.write('<a href="%s#%s">%s</a>' %
                      (self.href.wiki(page), anchor, heading))
        out.write('</li></ol>' * curr_depth)
Пример #6
0
 def __init__(self, env, context, wikidom, accepted_code_processors):
     self.env = env
     self.context = context
     self.accepted_code_processors = accepted_code_processors
     if isinstance(wikidom, basestring):
         wikidom = WikiParser(env).parse(wikidom)
     self.wikidom = wikidom
     Formatter.__init__(self, env, context)
Пример #7
0
 def __init__(self, env, context, wikidom, accepted_code_processors):
     self.env = env
     self.context = context
     self.accepted_code_processors = accepted_code_processors
     if isinstance(wikidom, basestring):
         wikidom = WikiParser(env).parse(wikidom)
     self.wikidom = wikidom
     Formatter.__init__(self, env, context)
Пример #8
0
 def _heading_formatter(self, match, fullmatch):
     Formatter._heading_formatter(self, match, fullmatch)
     depth = min(len(fullmatch.group('hdepth')), 5)
     heading = match[depth + 1:len(match) - depth - 1]
     anchor = self._anchors[-1]
     text = wiki_to_oneliner(heading, self.env, self.db, self._absurls)
     text = re.sub(r'</?a(?: .*?)?>', '', text) # Strip out link tags
     self.outline.append((depth, '<a href="%s#%s">%s</a>' %
                         (self.env.href.wiki(self.__page), anchor, text)))
Пример #9
0
 def _heading_formatter(self, match, fullmatch):
     Formatter._heading_formatter(self, match, fullmatch)
     depth = min(len(fullmatch.group('hdepth')), 5)
     heading = match[depth + 1:len(match) - depth - 1]
     anchor = self._anchors[-1]
     text = wiki_to_oneliner(heading, self.env, self.db, self._absurls)
     text = re.sub(r'</?a(?: .*?)?>', '', text)  # Strip out link tags
     self.outline.append((depth, '<a href="%s#%s">%s</a>' %
                          (self.env.href.wiki(self.__page), anchor, text)))
Пример #10
0
    def expand_macro(self, formatter, name, content):
        db = self.env.get_db_cnx()

        txt = content or ''
        args = txt.split('|')
        url = args.pop(0).replace("'", "''")

        if ":" in url:
            base, name = url.split(":")
            if base != "wiki":
                return "Use 'wiki:' prefix in wiki page url", base, name
        else:
            name = url

        sql = "SELECT text from wiki where name = '%s' order by version desc limit 1" % name
        cs = db.cursor()
        cs.execute(sql)
        result = cs.fetchone()

        if not result:
            return '<b>Wiki Page %s not found!</b>' % url

        text = result[0]
        out = StringIO()
        codepage = self.env.config.get('trac', 'charset', 'ISO8859-15')

        Formatter(self.env, formatter.context).format(text, out, False)
        text = out.getvalue().encode(codepage)
        return text
Пример #11
0
    def expand_macro(self, formatter, name, content):
        args, kwargs = parse_args(content)
        pattern = args[0]
        if len(args) > 1 and args[1].strip().upper() == "COMPLETED":
            completed = "AND completed>0"
        else:
            completed = "AND completed=0"
        if len(args) > 2 and args[2].strip().upper() == "ASC":
            ordering = "ASC"
        else:
            ordering = "DESC"

        db = self.env.get_db_cnx()
        cursor = db.cursor()
        print """
            SELECT name FROM milestone WHERE name %s
              %s ORDER BY name %s
            """ % (db.like(), completed, ordering)
        cursor.execute(
            """
            SELECT name FROM milestone WHERE name %s
              %s ORDER BY name %s
            """ % (db.like(), completed, ordering), (pattern, ))

        out = StringIO()
        for name, in cursor.fetchall():
            wikitext = """
                == [milestone:%(milestonename)s %(milestonename)s] ==
                [[TicketQuery(milestone=%(milestonename)s,order=id,desc=0,format=table,col=summary|owner|ticket_status|type|status)]]
                """ % {
                'milestonename': name
            }
            Formatter(self.env, formatter.context).format(wikitext, out)

        return Markup(out.getvalue())
Пример #12
0
    def test_expand_macro(self):
        """ Testing the expand_macro method. """
        processor = CodeExample(self.env)
        args = 'test'
        formatter = Formatter(self.env, self.context)

        name = 'CodeExample'
        expected = '<div ' \
        'class="example">\n  <div class="title">\n\t' \
        '<span class="select_code" id="link1">' \
        'SELECT ALL</span>\n\t\n\t<span>EXAMPLE:</span>\n</div>\n    \n    ' \
        '<div class="code">' \
        '\n        <pre id="codelink1">test\n</pre>\n    </div>\n</div>'
        self.assertEqual(expected,
                         processor.expand_macro(formatter, name, args))

        args = '##type=bad\ntest'
        expected = '<div ' \
        'class="bad_example">\n  <div class="title">\n\t' \
        '<span class="select_code" id="link2">' \
        'SELECT ALL</span>\n\t\n\t<span>INCORRECT EXAMPLE:</span>\n' \
        '</div>\n    \n    <div class="code">' \
        '\n        <pre id="codelink2">test\n</pre>\n    </div>\n</div>'
        self.assertEqual(expected,
                         processor.expand_macro(formatter, name, args))

        args = '##type=good\ntest'
        expected = '<div ' \
        'class="good_example">\n  <div class="title">\n\t' \
        '<span class="select_code" id="link3">' \
        'SELECT ALL</span>\n\t\n\t<span>CORRECT EXAMPLE:</span>\n</div>' \
        '\n    \n    <div class="code">' \
        '\n        <pre id="codelink3">test\n</pre>\n    </div>\n</div>'
        self.assertEqual(expected,
                         processor.expand_macro(formatter, name, args))
Пример #13
0
    def expand_macro(self, formatter, name, content):

        env = formatter.env
        abs = env.abs_href.base
        abs = abs[:len(abs) - len(env.href.base)]
        f = Formatter(formatter.env, formatter.context)

        def convert(m):
            pre, target, suf = filter(None, m.groups())
            out = StringIO()
            f.format(target, out)
            url = re.search(HREF, out.getvalue()).groups()[0]
            # Trac creates relative links, which Markdown won't touch inside
            # <autolinks> because they look like HTML
            if pre == '<' and url != target:
                pre += abs
            return pre + str(url) + suf

        try:
            from markdown import markdown
            return markdown(re.sub(LINK, convert, content))
        except ImportError:
            msg = 'Error importing Python Markdown, install it from '
            url = 'http://www.freewisdom.org/projects/python-markdown/'
            return system_message(tag(msg, tag.a('here', href="%s" % url),
                                      '.'))
Пример #14
0
 def _macro_formatter(self, match, fullmatch):
     name = fullmatch.group('macroname')
     if name in self.allowed_macros:
         # leapfrog the OneLinerFormatter
         return Formatter._macro_formatter(self, match, fullmatch)
     else:
         # use the OneLinerFormatter
         return OneLinerFormatter._macro_formatter(self, match, fullmatch)
Пример #15
0
    def process_request(self, req):
        req.perm.assert_permission('TICKET_VIEW')

        if 'id' in req.args.keys():
            try:
                ticket = int(req.args.get('id'))
            except ValueError:
                raise TracError('Need integer ticket id.')

            sql = ("SELECT 1 FROM ticket WHERE id=%s" % ticket)

            db = self.env.get_db_cnx()
            cursor = db.cursor()
            cursor.execute(sql)
            row = cursor.fetchone()
            if not row:
                raise TracError(
                    'Cannot build dependency graph for non-existent ticket %d.'
                    % ticket)

            depth = -1
            for key in req.args.keys():
                if key == 'depth':
                    depth = req.args[key]

            options = '%s,%s' % (ticket, depth)
            add_ctxtnav(req, 'Back to Ticket #%s' % ticket,
                        req.href.ticket(ticket))
            title = 'Ticket #%s Dependency Graph' % ticket
            headline = 'Dependency Graph for Ticket #%s' % ticket
        else:
            constraints = {}
            for key in req.args.keys():
                if isinstance(req.args[key], (list, tuple)):
                    constraints[key] = '|'.join(req.args[key])
                else:
                    constraints[key] = req.args[key]
            options = 'query:' + '&'.join(key + '=' + constraints[key]
                                          for key in constraints)

            title = 'Ticket query Dependency Graph'
            headline = 'Dependency Graph for Query'
            add_ctxtnav(req, 'Back to query', req.href('query', **req.args))

        data = {}

        context = Context.from_request(req, '')
        formatter = Formatter(self.env, context)
        graph = DepGraphMacro(self.env).expand_macro(formatter, 'DepGraph',
                                                     options)
        data['title'] = title
        data['headline'] = headline
        data['depgraph'] = Markup(graph)

        return 'depgraph.html', data, None
Пример #16
0
    def test_wiki_link_foreign(self):
        attachment = Attachment(self.env, 'ticket', 123)
        attachment.insert('foo.txt', tempfile.TemporaryFile(), 0)

        ns, func = AttachmentModule(self.env).get_link_resolvers().next()
        self.assertEqual('attachment', ns)

        req = Mock(path_info='/wiki')
        formatter = Formatter(self.env, req)
        self.assertEqual('<a class="attachment" title="Attachment #123: '
                         'foo.txt" href="/trac.cgi/attachment/ticket/123/'
                         'foo.txt">Foo</a>',
                         func(formatter, ns, 'ticket:123:foo.txt', 'Foo'))
Пример #17
0
    def test_wiki_link_subpage(self):
        attachment = Attachment(self.env, 'wiki', 'SomePage/SubPage')
        attachment.insert('foo.txt', tempfile.TemporaryFile(), 0)

        ns, func = AttachmentModule(self.env).get_link_resolvers().next()
        self.assertEqual('attachment', ns)

        req = Mock(path_info='/wiki/SomePage/SubPage')
        formatter = Formatter(self.env, req)
        self.assertEqual(
            '<a class="attachment" '
            'title="Attachment SomePage/SubPage: foo.txt" '
            'href="/trac.cgi/attachment/wiki/SomePage/SubPage/'
            'foo.txt">Foo</a>', func(formatter, ns, 'foo.txt', 'Foo'))
Пример #18
0
    def test_expand_macro_with_unicode(self):
        """ Testing the expand_macro method with unicode symbols. """
        processor = CodeExample(self.env)
        args = 'ТЕСТ'
        formatter = Formatter(self.env, self.context)

        name = 'CodeExample'
        expected = '<div ' \
        'class="example">\n  <div class="title">\n\t' \
        '<span class="select_code" id="link1">' \
        'SELECT ALL</span>\n\t\n\t<span>EXAMPLE:</span>\n</div>\n    \n    ' \
        '<div class="code">' \
        '\n        <pre id="codelink1">ТЕСТ\n</pre>\n    </div>\n</div>'
        self.assertEqual(expected,
                         processor.expand_macro(formatter, name, args))
Пример #19
0
    def expand_macro(self, formatter, name, content):

        env = formatter.env
        abs = env.abs_href.base
        abs = abs[:len(abs) - len(env.href.base)]
        f = Formatter(formatter.env, formatter.context)

        def convert_links(m):
            pre, target, suf = filter(None, m.groups())
            out = StringIO()
            f.format(target, out)
            url = re.search(HREF, out.getvalue()).groups()[0]
            # Trac creates relative links, which Markdown won't touch inside
            # <autolinks> because they look like HTML
            if pre == '<' and url != target:
                pre += abs
            return pre + str(url) + suf

        def emojify(html):
            pattern = ":([a-z0-9\\+\\-_]+):"
            link = "<img\
                alt=\"\\1\"\
                title=\":\\1:\"\
                height=\"20\"\
                style=\"vertical-align:middle\"\
                width=\"20\"\
                src=\"/chrome/markdown/emoji/\\1.png\" />"

            emojify_html = re.sub(pattern, link, html)
            return emojify_html

        try:
            # Import & convert
            import markdown2
            # autolink http:// n stuff
            autolinked_content = re.sub(LINK, convert_links, content)
            # convert to markdown
            html = markdown2.markdown(autolinked_content, extras=MD_EXTRAS)
            # substitute emojis
            emojified_html = emojify(html)

            return emojified_html
        except ImportError:
            # no markdown2 package found?
            msg = 'Error importing python-markdown2, install it from '
            url = 'https://github.com/trentm/python-markdown2'
            return system_message(tag(msg, tag.a('here', href="%s" % url),
                                      '.'))
Пример #20
0
    def process_request(self, req):
        """Process the request. For ClearSilver, return a (template_name,
        content_type) tuple, where `template` is the ClearSilver template to use
        (either a `neo_cs.CS` object, or the file name of the template), and
        `content_type` is the MIME type of the content. For Genshi, return a
        (template_name, data, content_type) tuple, where `data` is a dictionary
        of substitutions for the template.

        For both templating systems, "text/html" is assumed if `content_type` is
        `None`.

        Note that if template processing should not occur, this method can
        simply send the response itself and not return anything.
        """
        formatter = Formatter(self.env, Context.from_request(req))
        intertrac = InterTracDispatcher(self.env)
        macro = intertrac.expand_macro(formatter, 'InterTrac', '')
        data = {'macro': macro}
        return ("intertracinfo.html", data, 'text/html')
Пример #21
0
    def test(self):
        """Testing WikiFormatter"""

        # Environment stub
        from trac.core import ComponentManager
        from trac.config import Configuration
        from trac.log import logger_factory
        from trac.test import InMemoryDatabase
        from trac.web.href import Href

        db = InMemoryDatabase()

        class DummyEnvironment(ComponentManager):
            def __init__(self):
                ComponentManager.__init__(self)
                self.log = logger_factory('null')
                self.config = Configuration(None)
                self.href = Href('/')
                self.abs_href = Href('http://www.example.com/')
                self._wiki_pages = {}
                self.path = ''
            def component_activated(self, component):
                component.env = self
                component.config = self.config
                component.log = self.log
            def get_db_cnx(self):
                return db

        # Load all the components that provide IWikiSyntaxProvider
        # implementations that are tested. Ideally those should be tested
        # in separate unit tests.
        import trac.versioncontrol.web_ui.browser
        import trac.versioncontrol.web_ui.changeset
        import trac.Milestone
        import trac.ticket.query
        import trac.ticket.report
        import trac.Search

        env = DummyEnvironment()
        out = StringIO.StringIO()
        Formatter(env).format(self.input, out)
        v = out.getvalue().replace('\r','')
        self.assertEquals(self.correct, v)
Пример #22
0
    def test_path_recognition(self):
        """ Testing correct path requirements. """
        processor = CodeExample(self.env)
        args = '##path=test\nТЕСТ'
        formatter = Formatter(self.env, self.context)

        name = 'CodeExample'
        expected = '<div ' \
        'class="example">\n  <div class="title">\n\t' \
        '<span class="select_code" id="link1">' \
        'SELECT ALL</span>\n\t\n\t<span>EXAMPLE:</span>\n</div>\n    \n    ' \
        '<div class="system-message">\n    <strong>' \
        'During the example analyzing the following problems' \
        ' appear:</strong>\n    <ul>\n        ' \
        '<li>Path element is not found.</li>\n    '\
        '</ul>\n    </div>' \
        '\n    \n    <div class="code">' \
        '\n        <pre id="codelink1">ТЕСТ\n</pre>\n    </div>\n</div>'
        self.assertEqual(expected,
                         processor.expand_macro(formatter, name, args))
Пример #23
0
    def test_macro_with_invalid_lang(self):
        """ Testing the expand_macro method with invalid language. """
        processor = CodeExample(self.env)
        args = '#!python1\ntest'
        formatter = Formatter(self.env, self.context)

        name = 'CodeExample'
        expected = '<div ' \
        'class="example">\n  <div class="title">\n\t' \
        '<span class="select_code" id="link1">' \
        'SELECT ALL</span>\n\t\n\t<span>EXAMPLE:</span>\n</div>\n    \n    ' \
        '<div class="system-message">\n    <strong>' \
        'During the example analyzing the following problems appear:' \
        '</strong>\n    ' \
        '<ul>\n        <li>no lexer for alias \'python1\' found</li>' \
        '\n    </ul>\n    </div>\n    \n    ' \
        '<div class="code">' \
        '\n        <pre id="codelink1">test\n</pre>\n    </div>\n</div>'
        self.assertEqual(expected,
                         processor.expand_macro(formatter, name, args))
Пример #24
0
    def expand_macro(self, formatter, name, content):
        (args, kwargs) = parse_args(content, False)

        page_name = self.MACRO_PAGES + name
        page = WikiPage(self.env, page_name)
        if not page.exists:
            raise RuntimeError(u'Can\'t find page', page_name)

        for i, arg in enumerate(args):
            kwargs[unicode(i+1)] = arg

        text = RelaxedIdTemplate(page.text).safe_substitute(kwargs)

        out = StringIO()
        Formatter(self.env, formatter.context).format(text, out)

        out = out.getvalue().strip()
        if out.startswith(u'<p>'): out = out[3:]
        if out.endswith(u'</p>'): out = out[:-4]
        return out
Пример #25
0
    def pre_process_request(self, req, handler):
        if req.path_info.startswith('/wiki'):
            if req.method == 'POST' and req.args.get('action',
                                                     'view') == 'view':
                post_handler = None
                for poster in self.macro_posters:
                    if not hasattr(poster, 'match_macro_post'): continue
                    rv = poster.match_macro_post(req)
                    if isinstance(rv, (str, unicode)):
                        rv = rv in req.args.keys()
                    if rv:
                        post_handler = poster
                        break
                if post_handler:
                    post_handler.process_macro_post(req)
                else:
                    # Silly stuff here
                    self.log.debug(
                        'MacroPostModule: Unclaimed POST, scanning page %s',
                        req.path_info[6:])
                    page = WikiPage(self.env, req.path_info[6:])
                    matches = self.macro_re.findall(
                        page.text) + self.proc_re.findall(page.text)
                    for name in matches:
                        self.log.debug('MacroPostModule: Found macro "%s"',
                                       name)
                        resource = Resource('wiki', name)
                        context = Context.from_request(req, resource)
                        wp = WikiProcessor(Formatter(self.env, context), name)
                        if wp.macro_provider is None:
                            self.log.debug(
                                'MacroPostModule: Invalid name!!! How did that happen'
                            )
                            continue
                        if hasattr(wp.macro_provider, 'process_macro_post') and \
                           not hasattr(wp.macro_provider, 'match_macro_post'):
                            wp.macro_provider.process_macro_post(req)
                req.environ['REQUEST_METHOD'] = 'GET'  # Revert back to a GET

        return handler
Пример #26
0
    def process_request(self, req):
        req.perm.require('TAGS_VIEW')
        add_ctxtnav(req, 'Cloud', req.href.tags())
        match = re.match(r'/tags/?(.*)', req.path_info)
        if match.group(1):
            req.redirect(req.href('tags', q=match.group(1)))
        add_stylesheet(req, 'tags/css/tractags.css')
        query = req.args.get('q', '')
        data = {'title': 'Tags'}
        formatter = Formatter(self.env,
                              Context.from_request(req, Resource('tag')))

        realms = [p.get_taggable_realm() for p in self.tag_providers]
        checked_realms = [r for r in realms if r in req.args] or realms
        data['tag_realms'] = [{
            'name': realm,
            'checked': realm in checked_realms
        } for realm in realms]

        if query:
            data['tag_title'] = 'Showing objects matching "%s"' % query
        data['tag_query'] = query

        from tractags.macros import TagCloudMacro, ListTaggedMacro
        if not query:
            macro = TagCloudMacro(self.env)
        else:
            macro = ListTaggedMacro(self.env)
        query = '(%s) (%s)' % (' or '.join(
            ['realm:' + r for r in realms if r in checked_realms]), query)
        self.env.log.debug('Tag query: %s', query)
        try:
            data['tag_body'] = macro.expand_macro(formatter, None, query)
        except InvalidQuery, e:
            data['tag_query_error'] = to_unicode(e)
            data['tag_body'] = TagCloudMacro(self.env) \
                .expand_macro(formatter, None, '')
Пример #27
0
    def filter_stream(self, req, method, filename, stream, data):
        """Return a filtered Genshi event stream, or the original unfiltered
        stream if no match.

        `req` is the current request object, `method` is the Genshi render
        method (xml, xhtml or text), `filename` is the filename of the template
        to be rendered, `stream` is the event stream and `data` is the data for
        the current template.

        See the Genshi documentation for more information.
        """

        if filename in ('ticket.html', 'agilo_ticket_new.html',):

            add_stylesheet(req, 'tags/css/tractags.css')
            add_stylesheet(req, 'loomingclouds/css/tagcloud.css')
            add_script(req, 'loomingclouds/js/tag_filler.js')
            formatter = Formatter(self.env, Context.from_request(req))
            macro = TagCloudMacro(self.env)
            cloud = macro.expand_macro(formatter, 'TagCloud', '')

            stream |= Transformer("//input[@id='field-keywords']").after(cloud).after(tag.a('More...',href='#',class_='tag-cloud-filler'))

        return stream
Пример #28
0
    def process_request(self, req):
        req.perm.require('TAGS_VIEW')

        match = re.match(r'/tags/?(.*)', req.path_info)
        tag_id = match.group(1) and match.group(1) or None
        query = req.args.get('q', '')

        # Consider only providers, that are permitted for display.
        tag_system = TagSystem(self.env)
        all_realms = tag_system.get_taggable_realms(req.perm)
        if not (tag_id or query) or [r for r in all_realms if r in req.args
                                     ] == []:
            for realm in all_realms:
                if not realm in self.exclude_realms:
                    req.args[realm] = 'on'
        checked_realms = [r for r in all_realms if r in req.args]
        if query:
            # Add permitted realms from query expression.
            checked_realms.extend(query_realms(query, all_realms))
        realm_args = dict(
            zip([r for r in checked_realms], ['on' for r in checked_realms]))
        # Switch between single tag and tag query expression mode.
        if tag_id and not re.match(r"""(['"]?)(\S+)\1$""", tag_id, re.UNICODE):
            # Convert complex, invalid tag ID's --> query expression.
            req.redirect(req.href.tags(realm_args, q=tag_id))
        elif query:
            single_page = re.match(r"""(['"]?)(\S+)\1$""", query, re.UNICODE)
            if single_page:
                # Convert simple query --> single tag.
                req.redirect(req.href.tags(single_page.group(2), realm_args))

        data = dict(page_title=_("Tags"), checked_realms=checked_realms)
        # Populate the TagsQuery form field.
        data['tag_query'] = tag_id and tag_id or query
        data['tag_realms'] = list(
            dict(name=realm, checked=realm in checked_realms)
            for realm in all_realms)
        if tag_id:
            data['tag_page'] = WikiPage(self.env,
                                        tag_system.wiki_page_prefix + tag_id)
        if query or tag_id:
            macro = 'ListTagged'
            # TRANSLATOR: The meta-nav link label.
            add_ctxtnav(req, _("Back to Cloud"), req.href.tags())
            args = "%s,format=%s,cols=%s" % \
                   (tag_id and tag_id or query, self.default_format,
                    self.default_cols)
            data['mincount'] = None
        else:
            macro = 'TagCloud'
            mincount = as_int(req.args.get('mincount', None),
                              self.cloud_mincount)
            args = mincount and "mincount=%s" % mincount or None
            data['mincount'] = mincount
        formatter = Formatter(self.env,
                              Context.from_request(req, Resource('tag')))
        self.env.log.debug("%s macro arguments: %s" %
                           (macro, args and args or '(none)'))
        macros = TagWikiMacros(self.env)
        try:
            # Query string without realm throws 'NotImplementedError'.
            data['tag_body'] = checked_realms and \
                               macros.expand_macro(formatter, macro, args,
                                                   realms=checked_realms) \
                               or ''
        except InvalidQuery, e:
            data['tag_query_error'] = to_unicode(e)
            data['tag_body'] = macros.expand_macro(formatter, 'TagCloud', '')
Пример #29
0
 def wiki(self, text):
     out = StringIO.StringIO()
     Formatter(self.formatter.env, self.formatter.context).format(text, out)
     return out.getvalue()
Пример #30
0
 def formatter(self, env):
     return Formatter(env)
Пример #31
0
 def __init__(self, env, context, name):
     Formatter.__init__(self, env, context)
     self.__name = name
     self.__marks = []
     self.__super = super(DefaultWikiChecker, self)
Пример #32
0
 def code_formatter(env, context, language, text):
     processor = WikiProcessor(Formatter(env, context), language)
     html = processor.process(text)
     raw = nodes.raw('', html, format='html')
     return raw
Пример #33
0
 def __init__(self, env, context, name):
     Formatter.__init__(self, env, context)
     self.__name = name
     self.__marks = []
     self.__super = super()
Пример #34
0
 def __init__(self, env, req=None, absurls=False, db=None, styles=None):
     Formatter.__init__(self, env, req=None, absurls=False, db=None)
     self.styles = styles
     self._in_list_item = False
Пример #35
0
    def convert_content(self, req, input_type, source, output_type):

        # get parameters from trac ini file
        self.img_max_x = self.env.config.get('pagetodoc', 'img_max_x', self.img_max_x)
        self.img_max_y = self.env.config.get('pagetodoc', 'img_max_y', self.img_max_y)
        self.img_max_y = self.env.config.get('pagetodoc', 'dpi', self.dpi)

        # XSL-Transformation        
        xsltfilepath = self.env.config.get('pagetodoc', 'xsltfile', '')
        # TBD: Fehler ausgeben, wenn xsltfile nicht gelesen werden kann
        # TBD: Parameter aus der trac.ini an zentraler Stelle auslesen
        if xsltfilepath == '':
            message = "You have to set the 'xsltfile' option in the " \
                "[pagetodoc] section in trac.ini"
            raise_dependency_issue(message, req, self.env)
        if not os.path.exists(xsltfilepath):
            message = ("Value for 'xsltfile' in the [pagetodoc] section in " \
                "trac.ini does not exist: '%s'.")% xsltfilepath
            raise_dependency_issue(message, req, self.env)

        # maybe for later use
        #codepage = self.env.config.get('trac', 'charset', 'iso-8859-1')
        codepage = 'iso-8859-1'

        # Convert Wiki markup to HTML, new style
        out = StringIO()
        context = Context.from_request(req, 'wiki', req.path_info[6:])
        Formatter(self.env, context).format(source, out)
        html = Markup(out.getvalue()).encode(codepage, 'replace')

        # remove the bad HTML produced by the breadcrumbs plugin
        # RFE: find a universal way to do this
        html = re.compile('(<lh[^>]*>)').sub('', html)

        # temporary files and folders
        self.tempdir = mkdtemp(prefix="page2doc")
        htmlfilehandle, htmlfilepath = mkstemp(prefix='trac_', dir=self.tempdir, suffix = ".html")
        wordfilehandle, wordfilepath = mkstemp(prefix='word_', dir=self.tempdir, suffix = ".doc")
        os.close(wordfilehandle)

        # for debug: set all rights
        #self.chmod_tmp_dir(self.tempdir)

        # images
        # replace href with absolute path and if existing, base auth login
        try:
            # this will work if the authentication type is basic (and not over SSL?)
            login = base64.b64decode(req.environ['HTTP_AUTHORIZATION'][6:]) + '@'                  
        except (KeyError, TypeError):
            login = ''
                   
        html = re.sub('<img src="(?!\w+://)', '<img src="%s://%s%s:%d' % (req.scheme, login, req.server_name, req.server_port), html)

        # save images to disk
        html = re.sub('<img src="([^"]*)"', self.download_image, html)

        # write HTML page to disk
        os.write(htmlfilehandle, '<html><body>' + html + '</body></html>')
        os.close(htmlfilehandle)

        # clean up the HTML page using HTML Tidy
        args = '-m -asxhtml -latin1 --doctype omit'
        tidypath = self.env.config.get('pagetodoc', 'tidypath', 'tidy')

        # verify that Tidy exists and is setup correctly
        tidy_error = dependency_failure("tidy", tidypath, "-v")

        if tidy_error:
            raise_dependency_issue(tidy_error, req, self.env)

        cmd = '"%s" %s %s' % (tidypath, args, htmlfilepath)
        self.execute_external_program(cmd)

        # workaround namespace
        self.perform_workarounds(htmlfilepath, 'html')

        if self.verbose:
            verb = '-v'
        else:
            verb = ''
        xsltprocpath = self.env.config.get('pagetodoc', 'xsltprocpath', 'xsltproc')

        # verify that Tidy exists and is setup correctly
        xsltproc_error = dependency_failure("xsltproc", xsltprocpath, "-V")

        if xsltproc_error:
            raise_dependency_issue(xsltproc_error, req, self.env)

        cmd = '%s %s --html -o %s %s %s' % (
            xsltprocpath, verb, wordfilepath, xsltfilepath, htmlfilepath)
        self.execute_external_program(cmd)

        # workaround pre-tags
        self.perform_workarounds(wordfilepath, 'pre')

        zipfilepath = os.path.join(
            self.tempdir, os.path.basename(str(req.path_info) + '.zip'))
            
        # create a zip file and store all files into it      
        zipfilehandle = zipfile.ZipFile(zipfilepath, "w")
        zipfilehandle.write(wordfilepath, os.path.basename(str(req.path_info) + '.htm'))       
        for image in self.images:
            zipfilehandle.write(image, self.imagesubdir + os.path.basename(image))     
        zipfilehandle.close()
        zip_file = open(zipfilepath, "rb")
        zip = zip_file.read()
        zip_file.close()

        # delete temporary folders and files
        self.remove_dir(os.path.join(self.tempdir, self.logsubdir))
        self.remove_dir(os.path.join(self.tempdir, self.imagesubdir))
        self.remove_dir(self.tempdir)

        # reset image list
        self.images = []

        return (zip, 'application/zip')
Пример #36
0
 def __init__(self, env, context, name):
     Formatter.__init__(self, env, context)
     self.__name = name
     self.__marks = []
     self.__super = super(DefaultWikiChecker, self)
Пример #37
0
class CKEditorFormatter(Formatter):
    """Extends base wiki formatter by setting code processor's name 
for code blocks. Thus CKEditor can save it, so it could be processed 
later by format processor like Pygments (see TracSyntaxColoring). 
"""
    
    data_code_style = None
    
    def __init__(self, env, context, wikidom, accepted_code_processors):
        self.env = env
        self.context = context
        self.accepted_code_processors = accepted_code_processors
        if isinstance(wikidom, basestring):
            wikidom = WikiParser(env).parse(wikidom)
        self.wikidom = wikidom
        Formatter.__init__(self, env, context)

    # copied from HtmlFormatter
    def generate(self, escape_newlines=False):
        """Generate HTML elements.

        newlines in the wikidom will be preserved if `escape_newlines` is set.
        """
        # FIXME: compatibility code only for now
        out = StringIO()
        self.format(self.wikidom, out, escape_newlines)
#        self.env.log.debug('generated html: %s' % out.getvalue())
        return Markup(out.getvalue())
    
    def handle_code_block(self, line, startmatch=None):
        """Overrides Formatter.handle_code_block, so it 
adds an additional `pre`-tag with attribute `data-code-style`,  
in which the code-format is saved.

Furthermore the code block is converted into HTML, because otherwise CKEditor 
ignores empty lines. In this method linebreaks `\n` are replaced by `<br/>`.
"""
        handle_code_style = False
        if line.strip() == WikiParser.ENDBLOCK and self.code_processor: 
            clean_processor_name = self.code_processor.name
            self.env.log.debug('clean_processor_name: %s' %  clean_processor_name) 
            
            idx = clean_processor_name.find('; ')
            if idx >= 0:
                clean_processor_name = clean_processor_name[:idx]
            
            if clean_processor_name == 'default':
                handle_code_style = True
                self.data_code_style = ''
            elif clean_processor_name not in ['diff', 'td']:
                try:
                    from pygments.lexers import get_lexer_for_mimetype
                    
                    lexer = get_lexer_for_mimetype(clean_processor_name)
                    proc_aliases = lexer.aliases
                    if proc_aliases and len(proc_aliases) > 0:
                        clean_processor_name = proc_aliases[0]
                    else:
                        clean_processor_name = lexer.name
                    
                    if clean_processor_name in self.accepted_code_processors:
                        self.data_code_style = ' data-code-style="%s"' % clean_processor_name
                        handle_code_style = True
                except Exception, e:
                    self.env.log.warn( "Error when retrieving lexer by mimetype: %s" % e )
                    self.data_code_style = ''
                
        if handle_code_style:
            self.env.log.debug('processing self.data_code_style: %s' %  self.data_code_style) 
            code_text = os.linesep.join(self.code_buf)
            html_text = WikiProcessor(self, 'default').process(code_text)
            html_text = _markup_to_unicode( html_text )
            html_text = html_text.replace('\n', '<br/>')
            
            html = HTML( html_text )
            html |= Transformer('//pre').unwrap()
            buffer = StringIO()
            html.render(out=buffer, encoding='utf-8')
            
            self.out.write( '<pre%s>' % self.data_code_style )
            self.out.write( _markup_to_unicode( buffer.getvalue() ) )
            self.out.write('</pre>')
            
            self.in_code_block = 0
        else:
            Formatter.handle_code_block(self, line, startmatch)