Ejemplo n.º 1
0
    def expand_macro(self, formatter, name, content):
        add_stylesheet(formatter.req, 'lineno/css/lineno.css')

        i = 1
        self._anchor = 'a1'
        while self._anchor in formatter._anchors:
            self._anchor = 'a' + str(i)
            i += 1
        formatter._anchors[self._anchor] = True

        mt = 'txt'
        match = WikiParser._processor_re.match(content)
        if match:
            try:  #Trac 0.12+
                mt = match.group(2)
                content = content[match.end(2) + 1:]
            except IndexError:  #Trac 0.11
                mt = match.group(1)
                content = content[match.end(1) + 1:]

        mimeview = Mimeview(formatter.env)
        mimetype = mimeview.get_mimetype(mt) or mimeview.get_mimetype('txt')
        return mimeview.render(formatter.context,
                               mimetype,
                               content,
                               annotations=['codeblock-lineno'])
Ejemplo n.º 2
0
 def render(self, req):
     """Render the data."""
     context = Context.from_request(req)
     mimeview = Mimeview(self.env)
     return mimeview.render(context,
                            self.mimetype,
                            self.data,
                            annotations=['lineno'])
Ejemplo n.º 3
0
    def test_plain_text_content(self):
        """Render simple plain text content."""
        mimeview = Mimeview(self.env)
        req = MockRequest(self.env)
        context = RenderingContext(Resource('wiki', 'readme.txt'))
        context.req = req
        content = io.BytesIO("""\
Some text.
""")

        rendered = mimeview.render(context, 'text/plain', content)

        self.assertEqual('<div class="code"><pre>Some text.\n</pre></div>',
                         str(rendered))
Ejemplo n.º 4
0
    def expand_macro(self, formatter, name, content):
        add_stylesheet(formatter.req, 'lineno/css/lineno.css')

        i = 1
        self._anchor = 'a1'
        while self._anchor in formatter._anchors:
            self._anchor = 'a' + str(i)
            i += 1
        formatter._anchors[self._anchor] = True

        mt = 'txt'
        match = WikiParser._processor_re.match(content)
        if match:
            try: #Trac 0.12+
                mt = match.group(2)
                content = content[match.end(2)+1:]
            except IndexError: #Trac 0.11
                mt = match.group(1)
                content = content[match.end(1)+1:]
        
        mimeview = Mimeview(formatter.env)
        mimetype = mimeview.get_mimetype(mt) or mimeview.get_mimetype('txt')        
        return mimeview.render(formatter.context, mimetype,
                               content, annotations=['codeblock-lineno'])
Ejemplo n.º 5
0
    def process_request(self, req):
        req.perm.require('WIKI_VIEW')

        action = req.args.get('action', 'view')
        version = req.args.get('version')
        root = self.config.get('docs', 'root', '')
        base = req.args.get('path')
        if base[-1] == '/':
            base = base[:-1]
        path = root + base

        title = base or 'Docs'
        if action != 'view':
            title += ' (%s)' % action
        data = {}
        data['title'] = title

        repos = self.env.get_repository(authname=req.authname)
        node = repos.get_node(path, None)

        if node.isdir:
            page = DirPage(self.env, node, root, base)
        else:
            page = FilePage(self.env, node, root, base)

        data['editable'] = not node.isdir

        if req.method == 'POST':

            if action == 'edit':
                if page.node.isdir:
                    raise TracError("Cannot edit a directory")
                latest_version = page.version
                if req.args.has_key('cancel'):
                    req.redirect(req.href.docs(page.base))
                elif int(version) != latest_version:
                    action = 'collision'
                    self._render_editor(req, page, data)
                elif req.args.has_key('preview'):
                    action = 'preview'
                    self._render_editor(req, page, data, preview=True)
                else:
                    self._do_save(req, page)

        elif action == 'edit':
            self._render_editor(req, page, data)

        else:
            req.perm.assert_permission('WIKI_VIEW')

            if node.isdir:
                data['entries'] = page.get_entries(req)
                if page.index is not None:
                    data['index'] = page.index.get_html(req)
                else:
                    mimeview = Mimeview(self.env)
                    text = []
                    text.append('=' * (len(page.name) + 6))
                    text.append('   %s' % page.name)
                    text.append('=' * (len(page.name) + 6))
                    text = '\n'.join(text)
                    mimetype = 'text/x-rst; charset=utf8'
                    result = mimeview.render(req, mimetype, text)
                    data['index'] = result

            else:
                mime_type, chunk = page.get_raw()

                # When possible, send with non-text mimetype
                # Perhaps we should embed images...? 
                if not mime_type.startswith('text') or \
                    mime_type.startswith('text/html'):
                    req.send_response(200)
                    req.send_header('Content-Type', mime_type)
                    req.end_headers()
                    req.write(chunk)
                    return

                format = req.args.get('format')
                if format:
                    Mimeview(self.env).send_converted(req, 'text/x-rst', chunk, format, page.name)

                for conversion in Mimeview(self.env).get_supported_conversions('text/x-rst'):
                    conversion_href = req.href.docs(page.base, format=conversion[0])
                    add_link(req, 'alternate', conversion_href, conversion[1],
                             conversion[3])

                # Render the content into HTML
                data['content'] = page.get_html(req)


        data['action'] = action
        data['current_href'] = req.href.docs(page.base)
        data['log_href'] = req.href.log(page.path)

        # Include trac wiki stylesheet
        add_stylesheet(req, 'common/css/wiki.css')

        # Include trac docs stylesheet
        add_stylesheet(req, 'docs/common.css')

        # Include docutils stylesheet
        add_stylesheet(req, 'docs/docutils.css')

        # Include google-code-prettify
        add_stylesheet(req, 'docs/prettify.css')
        add_script(req, 'docs/prettify.min.js')

        # Include context navigation links
        history = [('root', req.href.docs())]
        t = ''
        for s in base[1:].split('/'):
            if not s: continue
            t += '/' + s
            history.append((s, req.href.docs(t)))
        for h in reversed(history):
            add_ctxtnav(req, h[0], h[1])
        add_ctxtnav(req, 'Revision Log', req.href.log(path))

        return 'docs.html', data, None
Ejemplo n.º 6
0
class PygmentsRendererTestCase(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub(enable=[Chrome, PygmentsRenderer])
        self.pygments = Mimeview(self.env).renderers[0]
        self.req = Mock(base_path='', chrome={}, args={},
                        abs_href=Href('/'), href=Href('/'),
                        session={}, perm=None, authname=None, tz=None)
        self.context = web_context(self.req)
        pygments_html = open(os.path.join(os.path.split(__file__)[0],
                                       'pygments.html'))
        self.pygments_html = Stream(list(HTMLParser(pygments_html, encoding='utf-8')))

    def _expected(self, expected_id):
        return self.pygments_html.select(
            '//div[@id="%s"]/*|//div[@id="%s"]/text())' %
            (expected_id, expected_id))

    def _test(self, expected_id, result):
        expected = str(self._expected(expected_id))
        result = str(result)
        #print "\nE: " + repr(expected)
        #print "\nR: " + repr(result)
        expected, result = expected.splitlines(), result.splitlines()
        for exp, res in zip(expected, result):
            self.assertEqual(exp, res)
        self.assertEqual(len(expected), len(result))

    def test_python_hello(self):
        """
        Simple Python highlighting with Pygments (direct)
        """
        result = self.pygments.render(self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        self._test('python_hello', result)

    def test_python_hello_mimeview(self):
        """
        Simple Python highlighting with Pygments (through Mimeview.render)
        """
        result = Mimeview(self.env).render(self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        self._test('python_hello_mimeview', result)

    def test_newline_content(self):
        """
        The behavior of Pygments changed post-Pygments 0.11.1, and now
        contains all four newlines.  In Pygments 0.11.1 and prior, it only
        has three since stripnl defaults to True.

        See http://trac.edgewall.org/ticket/7705.
        """
        from pkg_resources import parse_version, get_distribution

        result = self.pygments.render(self.context, 'text/x-python', '\n\n\n\n')
        self.assertTrue(result)
        t = "".join([r[1] for r in result if r[0] is TEXT])

        if parse_version(pygments.__version__) > parse_version('0.11.1') \
           or pygments.__version__ == '0.11.1' and 'dev' in \
           get_distribution('Pygments').version:
            self.assertEqual("\n\n\n\n", t)
        else:
            self.assertEqual("\n\n\n", t)

    def test_empty_content(self):
        """
        A '\n' token is generated for an empty file, so we have to bypass
        pygments when rendering empty files.
        """
        result = self.pygments.render(self.context, 'text/x-python', '')
        self.assertIsNone(result)

    def test_extra_mimetypes(self):
        """
        The text/x-ini mimetype is normally not known by Trac, but
        Pygments supports it.
        """
        mimeview = Mimeview(self.env)
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.ini'))
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.cfg'))
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.text/x-ini'))
Ejemplo n.º 7
0
class PatchRendererTestCase(unittest.TestCase):
    def setUp(self):
        env = EnvironmentStub(enable=[Chrome, PatchRenderer])
        req = Mock(base_path='',
                   chrome={},
                   args={},
                   session={},
                   abs_href=Href('/'),
                   href=Href('/'),
                   locale='',
                   perm=MockPerm(),
                   authname=None,
                   tz=None)
        self.context = Context.from_request(req)
        self.patch = Mimeview(env).renderers[0]
        patch_html = open(
            os.path.join(os.path.split(__file__)[0], 'patch.html'))
        self.patch_html = Stream(list(HTMLParser(patch_html)))

    def _expected(self, expected_id):
        return self.patch_html.select('//div[@id="%s"]/div' % expected_id)

    def _test(self, expected_id, result):
        expected = str(self._expected(expected_id))
        result = str(XML(result))
        expected, result = expected.splitlines(), result.splitlines()
        for exp, res in zip(expected, result):
            self.assertEquals(exp, res)
        self.assertEquals(len(expected), len(result))

    def test_simple(self):
        """
        Simple patch rendering
        """
        result = self.patch.render(
            self.context, None, """
--- README.orig 2006-10-27 14:42:04.062500000 +0200
+++ README      2006-10-27 14:42:28.125000000 +0200
@@ -1,5 +1,5 @@
 ----
-base
-base
-base
+be
+the base
+base modified
 .
""")
        self.assertTrue(result)
        self._test('simple', result)

    def test_no_newline_in_base(self):
        """
        Simple regression test for #4027 ("No newline at end of file")
        """
        result = self.patch.render(
            self.context, None, """
--- nonewline   2006-10-27 08:36:48.453125000 +0200
+++ newline     2006-10-27 08:36:57.187500000 +0200
@@ -1 +1 @@
-ONELINE
\ No newline at end of file
+ONELINE        
""")
        self.assertTrue(result)
        self._test('no_newline_in_base', result)

    def test_no_newline_in_changed(self):
        """
        Another simple regression test for #4027 ("No newline at end of file")
        """
        result = self.patch.render(
            self.context, None, """
--- newline     2006-10-27 08:36:57.187500000 +0200
+++ nonewline   2006-10-27 08:36:48.453125000 +0200
@@ -1 +1 @@
-ONELINE
+ONELINE
\ No newline at end of file
""")
        self.assertTrue(result)
        self._test('no_newline_in_changed', result)

    def test_diff_to_hdf_expandtabs(self):
        """Regression test related to #4557"""
        changes = self.patch._diff_to_hdf([
            '--- hello.c 1', '+++ hello.c 2', '@@ -1 +1 @@', '-aa\tb', '+aaxb'
        ], 8)
        self.assertEquals('aa<del>&nbsp; &nbsp; &nbsp; </del>b',
                          str(changes[0]['diffs'][0][0]['base']['lines'][0]))
        self.assertEquals(
            'aa<ins>x</ins>b',
            str(changes[0]['diffs'][0][0]['changed']['lines'][0]))

    def test_diff_to_hdf_leading_ws(self):
        """Regression test related to #5795"""
        changes = self.patch._diff_to_hdf(
            ['--- hello.c 1', '+++ hello.c 2', '@@ -1 +1 @@', '-*a', '+ *a'],
            8)
        self.assertEquals('<del></del>*a',
                          str(changes[0]['diffs'][0][0]['base']['lines'][0]))
        self.assertEquals(
            '<ins>&nbsp;</ins>*a',
            str(changes[0]['diffs'][0][0]['changed']['lines'][0]))
Ejemplo n.º 8
0
 def format_wiki_text(text):
     from trac.mimeview.api import Mimeview
     mimeview = Mimeview(self.env)
     mimetype = 'text/x-trac-wiki'
     return mimeview.render(req, mimetype, text)
Ejemplo n.º 9
0
class PatchRendererTestCase(unittest.TestCase):

    def setUp(self):
        env = EnvironmentStub(enable=[Chrome, PatchRenderer])
        req = Mock(base_path='', chrome={'static_hash': None}, args={},
                   session={}, abs_href=Href('/'), href=Href('/'), locale='',
                   perm=MockPerm(), authname=None, tz=None)
        self.context = web_context(req)
        self.patch = Mimeview(env).renderers[0]
        patch_html = open(os.path.join(os.path.split(__file__)[0],
                                       'patch.html'))
        self.patch_html = Stream(list(HTMLParser(patch_html, encoding='utf-8')))

    def _expected(self, expected_id):
        return self.patch_html.select('//div[@id="%s"]/div' % expected_id)

    def _test(self, expected_id, result):
        expected = self._expected(expected_id).render(encoding='utf-8')
        result = XML(result.render(encoding='utf-8')).render(encoding='utf-8')
        expected, result = expected.splitlines(), result.splitlines()
        for exp, res in zip(expected, result):
            self.assertEquals(exp, res)
        self.assertEquals(len(expected), len(result))

    def test_simple(self):
        """
        Simple patch rendering
        """
        result = self.patch.render(self.context, None, """
--- README.orig 2006-10-27 14:42:04.062500000 +0200
+++ README      2006-10-27 14:42:28.125000000 +0200
@@ -1,5 +1,5 @@
 ----
-base
-base
-base
+be
+the base
+base modified
 .
""")
        self.assertTrue(result)
        self._test('simple', result)

    def test_no_newline_in_base(self):
        """
        Simple regression test for #4027 ("No newline at end of file")
        """
        result = self.patch.render(self.context, None, """
--- nonewline   2006-10-27 08:36:48.453125000 +0200
+++ newline     2006-10-27 08:36:57.187500000 +0200
@@ -1 +1 @@
-ONELINE
\ No newline at end of file
+ONELINE        
""")
        self.assertTrue(result)
        self._test('no_newline_in_base', result)

    def test_no_newline_in_changed(self):
        """
        Another simple regression test for #4027 ("No newline at end of file")
        """
        result = self.patch.render(self.context, None, """
--- newline     2006-10-27 08:36:57.187500000 +0200
+++ nonewline   2006-10-27 08:36:48.453125000 +0200
@@ -1 +1 @@
-ONELINE
+ONELINE
\ No newline at end of file
""")
        self.assertTrue(result)
        self._test('no_newline_in_changed', result)
    def test_diff_to_hdf_expandtabs(self):
        """Regression test related to #4557"""
        changes = self.patch._diff_to_hdf(
            ['--- hello.c 1',
             '+++ hello.c 2',
             '@@ -1 +1 @@',
             '-aa\tb',
             '+aaxb'], 8)
        self.assertEquals('aa<del>&nbsp; &nbsp; &nbsp; </del>b',
                          str(changes[0]['diffs'][0][0]['base']['lines'][0]))
        self.assertEquals('aa<ins>x</ins>b',
                          str(changes[0]['diffs'][0][0]['changed']['lines'][0]))

    def test_diff_to_hdf_leading_ws(self):
        """Regression test related to #5795"""
        changes = self.patch._diff_to_hdf(
            ['--- hello.c 1',
             '+++ hello.c 2',
             '@@ -1 +1 @@',
             '-*a',
             '+ *a'], 8)
        self.assertEquals('<del></del>*a',
                          str(changes[0]['diffs'][0][0]['base']['lines'][0]))
        self.assertEquals('<ins>&nbsp;</ins>*a',
                          str(changes[0]['diffs'][0][0]['changed']['lines'][0]))
Ejemplo n.º 10
0
    def expand_macro(self, formatter, name, content):
        self.log.info('Begin expand_macro for req: ' + repr(content))
        largs, kwargs = parse_args(content)
        
        if len(largs) == 0:
            raise TracError("File name to include is required parameter!")

        orig_file_name = file_name = largs[0]

        global multirepos
        if not multirepos:
            repos = self.env.get_repository(formatter.req.authname)
        else:
            if (orig_file_name[0] == '/'): orig_file_name = orig_file_name[1:]
            splitpath = file_name.split('/')
            if (file_name[0] == '/'):
                reponame = splitpath[1]
            else:
                reponame = splitpath[0]
            repos = self.env.get_repository(reponame)
            if (repos):
                l = len(reponame)
                if (file_name[0] == '/'):
                    file_name = file_name[1:]
                file_name = file_name[l:]
            else:
                repos = self.env.get_repository()
                
        rev = kwargs.get('rev', None)
        
        if kwargs.has_key('header'):
            header = kwargs.get('header')   # user specified header
        else:
            href = '../browser/%s%s' % (orig_file_name, make_rev_str(rev))
            header = tag.a(file_name, href=href)
        if not header:
            header = u'\xa0'    # default value from trac.mimeview.api.py
            
        # TODO - 'content' is default from mimeview.api.py, but it picks
        # up text-align: center, which probably isn't the best thing if
        # we are adding a file name in the header. There isn't an obvious
        # replacement in the delivered CSS to pick over this for now though
        header_class = kwargs.get('header_class', 'content')
            
        src = repos.get_node(file_name, rev).get_content().read()

        context = formatter.context
        # put these into context object so annotator sees them
        context.file_name = file_name
        context.rev = rev
        context.startline = 1
        
        # we generally include line numbers in the output, unless it has been
        # explicitly requested otherwise. 0, no, false, none will suppress
        line_numbers = kwargs.get('line_numbers', None)
        if line_numbers is None:
            line_numbers = True
        else:
            try:
                line_numbers = int(line_numbers)
            except:
                negatory = ('no', 'false', 'none')
                line_numbers = str(line_numbers).lower() not in negatory

        # lines added up front to "trick" renderer when rendering partial
        render_prepend = []
        
        start, end = kwargs.get('start', None), kwargs.get('end', None)
        if start or end:
            src, start, end = self._handle_partial(src, start, end)
            context.startline = start
            
            if start > 2 and file_name.endswith('.php'):
                render_prepend = [ '#!/usr/bin/php -f', '<?' ]

            if render_prepend:
                src = '\n'.join(render_prepend) + '\n' + src

                # ensure accurate start number after this gets stripped
                context.startline = start - len(render_prepend) 

        mimetype = kwargs.get('mimetype', None)
        url = None  # render method doesn't seem to use this

        mv = Mimeview(self.env)
        annotations = line_numbers and ['givenlineno'] or None
            
        src = mv.render(formatter.context, mimetype, src, file_name, url, annotations)

        if line_numbers:
            # handle the case where only one line of code was included
            # and we get back an XHTML string
            if not hasattr(src, 'generate'):
                from genshi.input import XML
                src = XML(src)
            
            # the _render_source method will always set the CSS class
            # of the annotator to it's name; there isn't an easy way
            # to override that. We could create our own CSS class for
            # givenlineno that mimics lineno, but it's cleaner to just 
            # tweak the output here by running the genshi stream from
            # src through a transformer that will make the change
            
            xpath1 = 'thead/tr/th[@class="givenlineno"]'
            xpath2 = 'thead/tr/th[2]'   # last() not supported by Genshi?
            xpath3 = 'thead/tr/th[2]/text()'
            
            # TODO - does genshi require a QName here? Seems to work w/o it
            src = src.generate() | Transformer(xpath1).attr('class', 'lineno') \
                                 | Transformer(xpath2).attr('class', header_class) \
                                 | Transformer(xpath3).replace(header)
                                 
            if render_prepend:
                # TODO - is there a better of stripping lines here?
                for i in xrange(len(render_prepend)):
                    src = src | Transformer('tbody/tr[1]').remove()

        return src
Ejemplo n.º 11
0
class PygmentsRendererTestCase(unittest.TestCase):
    def setUp(self):
        self.env = EnvironmentStub(
            enable=[Chrome, LineNumberAnnotator, PygmentsRenderer])
        self.pygments = Mimeview(self.env).renderers[0]
        self.req = Mock(base_path='',
                        chrome={},
                        args={},
                        abs_href=Href('/'),
                        href=Href('/'),
                        session={},
                        perm=None,
                        authname=None,
                        tz=None)
        self.context = web_context(self.req)
        pygments_html = open(
            os.path.join(os.path.split(__file__)[0], 'pygments.html'))
        self.pygments_html = Stream(
            list(HTMLParser(pygments_html, encoding='utf-8')))

    def _expected(self, expected_id):
        return self.pygments_html.select(
            '//div[@id="%s"]/*|//div[@id="%s"]/text())' %
            (expected_id, expected_id))

    def _test(self, expected_id, result):
        expected = unicode(self._expected(expected_id))
        result = unicode(result)
        #print("\nE: " + repr(expected))
        #print("\nR: " + repr(result))
        expected, result = expected.splitlines(), result.splitlines()
        for exp, res in zip(expected, result):
            self.assertEqual(exp, res)
        self.assertEqual(len(expected), len(result))

    def test_python_hello(self):
        """
        Simple Python highlighting with Pygments (direct)
        """
        result = self.pygments.render(
            self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        self._test('python_hello', result)

    def test_python_hello_mimeview(self):
        """
        Simple Python highlighting with Pygments (through Mimeview.render)
        """
        result = Mimeview(self.env).render(
            self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        self._test('python_hello_mimeview', result)

    def test_python_with_lineno(self):
        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        self._test('python_with_lineno_1', result)

        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=3
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        self._test('python_with_lineno_2', result)

    def test_python_with_lineno_and_markups(self):
        """Python highlighting with Pygments and lineno annotator
        """
        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=3 id=b marks=4-5
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        self._test('python_with_lineno_and_markups', result)

    def test_python_with_invalid_arguments(self):
        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=-10
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        self._test('python_with_invalid_arguments_1', result)

        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=a id=d marks=a-b
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        self._test('python_with_invalid_arguments_2', result)

    def test_pygments_lexer_options(self):
        self.env.config.set('pygments-lexer', 'php.startinline', True)
        self.env.config.set('pygments-lexer', 'php.funcnamehighlighting',
                            False)
        result = format_to_html(
            self.env, self.context, """
{{{#!php
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
}}}
""")
        self.assertTrue(result)
        self._test('pygments_lexer_options', result)

    def test_pygments_lexer_arguments(self):
        result = format_to_html(
            self.env, self.context, """
{{{#!php startinline=True funcnamehighlighting=False
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
}}}
""")
        self.assertTrue(result)
        self._test('pygments_lexer_arguments', result)

    def test_pygments_lexer_arguments_override_options(self):
        self.env.config.set('pygments-lexer', 'php.startinline', True)
        self.env.config.set('pygments-lexer', 'php.funcnamehighlighting',
                            False)
        result = format_to_html(
            self.env, self.context, """
{{{#!php funcnamehighlighting=True
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
}}}
""")
        self.assertTrue(result)
        self._test('pygments_lexer_arguments_override_options', result)

    def test_newline_content(self):
        """
        The behavior of Pygments changed post-Pygments 0.11.1, and now
        contains all four newlines.  In Pygments 0.11.1 and prior, it only
        has three since stripnl defaults to True.

        See http://trac.edgewall.org/ticket/7705.
        """
        from pkg_resources import parse_version, get_distribution

        result = self.pygments.render(self.context, 'text/x-python',
                                      '\n\n\n\n')
        self.assertTrue(result)
        t = "".join([r[1] for r in result if r[0] is TEXT])

        if parse_version(pygments.__version__) > parse_version('0.11.1') \
           or pygments.__version__ == '0.11.1' and 'dev' in \
           get_distribution('Pygments').version:
            self.assertEqual("\n\n\n\n", t)
        else:
            self.assertEqual("\n\n\n", t)

    def test_empty_content(self):
        """
        A '\n' token is generated for an empty file, so we have to bypass
        pygments when rendering empty files.
        """
        result = self.pygments.render(self.context, 'text/x-python', '')
        self.assertIsNone(result)

    def test_extra_mimetypes(self):
        """
        The text/x-ini mimetype is normally not known by Trac, but
        Pygments supports it.
        """
        mimeview = Mimeview(self.env)
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.ini'))
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.cfg'))
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.text/x-ini'))
Ejemplo n.º 12
0
class PygmentsRendererTestCase(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub(enable=[Chrome, PygmentsRenderer])
        self.pygments = Mimeview(self.env).renderers[0]
        self.req = Mock(base_path='', chrome={}, args={},
                        abs_href=Href('/'), href=Href('/'),
                        session={}, perm=None, authname=None, tz=None)
        self.context = web_context(self.req)
        pygments_html = open(os.path.join(os.path.split(__file__)[0],
                                       'pygments.html'))
        self.pygments_html = Stream(list(HTMLParser(pygments_html, encoding='utf-8')))

    def _expected(self, expected_id):
        return self.pygments_html.select(
            '//div[@id="%s"]/*|//div[@id="%s"]/text())' % 
            (expected_id, expected_id))

    def _test(self, expected_id, result):
        expected = str(self._expected(expected_id))
        result = str(result)
        #print "\nE: " + repr(expected)
        #print "\nR: " + repr(result)
        expected, result = expected.splitlines(), result.splitlines()
        for exp, res in zip(expected, result):
            self.assertEquals(exp, res)
        self.assertEquals(len(expected), len(result))

    def test_python_hello(self):
        """
        Simple Python highlighting with Pygments (direct)
        """
        result = self.pygments.render(self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        self._test('python_hello', result)

    def test_python_hello_mimeview(self):
        """
        Simple Python highlighting with Pygments (through Mimeview.render)
        """
        result = Mimeview(self.env).render(self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        self._test('python_hello_mimeview', result)

    def test_newline_content(self):
        """
        The behavior of Pygments changed post-Pygments 0.11.1, and now
        contains all four newlines.  In Pygments 0.11.1 and prior, it only
        has three since stripnl defaults to True.

        See http://trac.edgewall.org/ticket/7705.
        """
        from pkg_resources import parse_version, get_distribution

        result = self.pygments.render(self.context, 'text/x-python', '\n\n\n\n')
        self.assertTrue(result)
        t = "".join([r[1] for r in result if r[0] is TEXT])

        if parse_version(pygments.__version__) > parse_version('0.11.1') \
           or pygments.__version__ == '0.11.1' and 'dev' in \
           get_distribution('Pygments').version:
            self.assertEqual("\n\n\n\n", t)
        else:
            self.assertEqual("\n\n\n", t)

    def test_empty_content(self):
        """
        A '\n' token is generated for an empty file, so we have to bypass
        pygments when rendering empty files.
        """
        result = self.pygments.render(self.context, 'text/x-python', '')
        self.assertEqual(None, result)
Ejemplo n.º 13
0
class PygmentsRendererTestCase(unittest.TestCase):
    def setUp(self):
        self.env = EnvironmentStub(
            enable=[Chrome, LineNumberAnnotator, PygmentsRenderer])
        self.pygments = Mimeview(self.env).renderers[0]
        self.req = MockRequest(self.env)
        self.context = web_context(self.req)
        pygments_html = open(
            os.path.join(os.path.split(__file__)[0], 'pygments.html'))
        self.pygments_html = Stream(
            list(HTMLParser(pygments_html, encoding='utf-8')))

    def _expected(self, expected_id):
        return self.pygments_html.select(
            '//div[@id="%s"]/*|//div[@id="%s"]/text())' %
            (expected_id, expected_id))

    def _test(self, expected_id, result):
        expected = unicode(self._expected(expected_id))
        result = unicode(result)
        #print("\nE: " + repr(expected))
        #print("\nR: " + repr(result))
        expected, result = expected.splitlines(), result.splitlines()
        for exp, res in zip(expected, result):
            self.assertEqual(exp, res)
        self.assertEqual(len(expected), len(result))

    def test_python_hello(self):
        """
        Simple Python highlighting with Pygments (direct)
        """
        result = self.pygments.render(
            self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_hello', result)
        else:
            self._test('python_hello_pygments_2.1plus', result)

    def test_python_hello_mimeview(self):
        """
        Simple Python highlighting with Pygments (through Mimeview.render)
        """
        result = Mimeview(self.env).render(
            self.context, 'text/x-python', """
def hello():
        return "Hello World!"
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_hello_mimeview', result)
        else:
            self._test('python_hello_mimeview_pygments_2.1plus', result)

    def test_python_with_lineno(self):
        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_lineno_1', result)
        else:
            self._test('python_with_lineno_1_pygments_2.1plus', result)

        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=3
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_lineno_2', result)
        else:
            self._test('python_with_lineno_2_pygments_2.1plus', result)

    def test_python_with_lineno_and_markups(self):
        """Python highlighting with Pygments and lineno annotator
        """
        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=3 id=b marks=4-5
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_lineno_and_markups', result)
        else:
            self._test('python_with_lineno_and_markups_pygments_2.1plus',
                       result)

    def test_python_with_invalid_arguments(self):
        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=-10
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_invalid_arguments_1', result)
        else:
            self._test('python_with_invalid_arguments_1_pygments_2.1plus',
                       result)

        result = format_to_html(
            self.env, self.context, """\
{{{#!text/x-python lineno=a id=d marks=a-b
print 'this is a python sample'
a = b+3
z = "this is a string"
print 'this is the end of the python sample'
}}}
""")
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_invalid_arguments_2', result)
        else:
            self._test('python_with_invalid_arguments_2_pygments_2.1plus',
                       result)

    def test_pygments_lexer_options(self):
        self.env.config.set('pygments-lexer', 'php.startinline', True)
        self.env.config.set('pygments-lexer', 'php.funcnamehighlighting',
                            False)
        result = format_to_html(
            self.env, self.context, """
{{{#!php
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
}}}
""")
        self.assertTrue(result)
        self._test('pygments_lexer_options', result)

    def test_pygments_lexer_arguments(self):
        result = format_to_html(
            self.env, self.context, """
{{{#!php startinline=True funcnamehighlighting=False
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
}}}
""")
        self.assertTrue(result)
        self._test('pygments_lexer_arguments', result)

    def test_pygments_lexer_arguments_override_options(self):
        self.env.config.set('pygments-lexer', 'php.startinline', True)
        self.env.config.set('pygments-lexer', 'php.funcnamehighlighting',
                            False)
        result = format_to_html(
            self.env, self.context, """
{{{#!php funcnamehighlighting=True
if (class_exists('MyClass')) {
    $myclass = new MyClass();
}
}}}
""")
        self.assertTrue(result)
        self._test('pygments_lexer_arguments_override_options', result)

    def test_newline_content(self):
        """Regression test for newline-stripping behavior in Pygments.

        http://trac.edgewall.org/ticket/7705
        """
        result = self.pygments.render(self.context, 'text/x-python',
                                      '\n\n\n\n')
        self.assertTrue(result)
        t = "".join(r[1] for r in result if r[0] is TEXT)

        self.assertEqual("\n\n\n\n", t)

    def test_empty_content(self):
        """
        A '\n' token is generated for an empty file, so we have to bypass
        pygments when rendering empty files.
        """
        result = self.pygments.render(self.context, 'text/x-python', '')
        self.assertIsNone(result)

    def test_extra_mimetypes(self):
        """
        The text/x-ini mimetype is normally not known by Trac, but
        Pygments supports it.
        """
        mimeview = Mimeview(self.env)
        self.assertIn(mimeview.get_mimetype('file.ini'),
                      ('text/x-ini; charset=utf-8',
                       'text/inf; charset=utf-8'))  # Pygment 2.1+
        self.assertIn(mimeview.get_mimetype('file.cfg'),
                      ('text/x-ini; charset=utf-8',
                       'text/inf; charset=utf-8'))  # Pygment 2.1+
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.text/x-ini'))
Ejemplo n.º 14
0
 def render(self, req):
     """Render the data."""
     context = Context.from_request(req)
     mimeview = Mimeview(self.env)
     return mimeview.render(context, self.mimetype, self.data,
                            annotations=['lineno'])
Ejemplo n.º 15
0
class FilePage(Page):

    def __init__(self, env, node, root, base):
        super(FilePage, self).__init__(env, node, root, base)
        self.mimeview = Mimeview(self.env)
        self.exists = (node is not None)

        self.mime_type = None
        self.chunk = None

    def get_html(self, req):
        """
        Get the raw content from the repository and convert to html.
        """
        mime_type, chunk = self.get_raw()
        if not mime_type.startswith('text'):
            raise TracError("Invalid mime-type: %s" % mime_type)

        # Hack to support images, we change the path from relative
        # the document being requested to absolute.
        # 1: Ignore http and ftp urls to allow images to be fetched
        # 2: Assume URLS beginning with "/" are relative to top-level
        # 3: Assume URLS that do not include "http/ftp" are relative to
        #    current path.
        def fixup(m):
            text = m.group(1)
            if text.startswith('http:') or text.startswith('ftp:'):
                return m.group(0)
            if text.startswith('/'):
                text = text[1:]
            dir = self.dir
            if dir.endswith('/'):
                dir = dir[:-1] 
            return '.. image:: %s/%s' % (req.href.docs(dir), text)
        chunk = re.sub('\.\. image\:\:\s*(\S+)', fixup, chunk, re.MULTILINE)

        # Assume all wiki pages are ReStructuredText documents 
        result = self.mimeview.render(req, mime_type, chunk)

        if not isinstance(result, (str, unicode)):
            result = unicode(result)

        # Hack to pretty-print source code (assumes all literal-blocks 
        # contain source code).
        result = result.replace('<pre class="literal-block">',
                                '<pre class="literal-block prettyprint">')

        if 'prettyprint' in result:
            # FIXME: Add as an event listener instead?
            result += """
                <script type="text/javascript">
                var origOnLoad = window.onload;
                function onLoad() {
                    if (origOnLoad) {
                      if(typeof(origOnLoad) == "string") {
                        eval(origOnLoad);
                      }
                      else {
                        origOnLoad();
                      }
                    } 
                    prettyPrint();
                }
                window.onload = onLoad;
                </script>
            """

        return Markup(result)

    def get_raw(self):
        """
        Load the raw content from the repository.
        """
        if self.mime_type is not None:
            return self.mime_type, self.chunk

        node = self.node
        content_length = node.get_content_length()
        if content_length > (1024 * 1024):
            raise TracError("Docs is too large: %d" % content_length)
        content = node.get_content()
        chunk = content.read(content_length)
        mime_type = node.content_type

        # Guess the mime-type when possible to be text/plain.
        if not mime_type or mime_type == 'application/octet-stream':
            mime_type = self.mimeview.get_mimetype(node.name, chunk) or \
            mime_type or 'text/plain'

        if mime_type.startswith('text/plain'):
            mime_type = 'text/x-rst; charset=utf8' 

        self.mime_type = mime_type
        self.chunk = chunk

        return mime_type, chunk 

    def save(self, req, text, comment):
        """
        Save the specified text into this document.
        """
        if not isinstance(self.node.repos, SubversionRepository):
            raise TracError("The '%s' repository is not supported" % type(self.node.repos))

        from svn import core as _core
        from svn import fs as _fs
        from svn import repos as _repos

        repos = self.node.repos.repos #.repos
        revnum = self.node._requested_rev
        author = req.authname
        message = 'Edited %s' % self.base[1:]
        if comment:
            message += ' (%s)' % comment

        pool = _core.Pool()
        fs_txn = _repos.fs_begin_txn_for_commit(repos, revnum, author, message, pool)
        fs_root = _fs.svn_fs_txn_root(fs_txn, pool)
        if hasattr(self.node, '_scoped_svn_path'):
            fs_path = self.node._scoped_svn_path
        else:
            fs_path = self.node._scoped_path_utf8
        stream = _fs.svn_fs_apply_text(fs_root, fs_path, None, pool)
        _core.svn_stream_write(stream, text)
        _core.svn_stream_close(stream) 
        return _repos.fs_commit_txn(repos, fs_txn, pool)
Ejemplo n.º 16
0
class PygmentsRendererTestCase(unittest.TestCase):

    def setUp(self):
        self.env = EnvironmentStub(enable=[Chrome, LineNumberAnnotator,
                                           PygmentsRenderer])
        self.pygments = Mimeview(self.env).renderers[0]
        self.req = MockRequest(self.env)
        self.context = web_context(self.req)
        self.pygments_html = {}
        testcase = []
        html_file = os.path.join(os.path.dirname(__file__), 'pygments.data')
        with open(html_file, 'rb') as f:
            for line in f.readlines():
                if line.startswith('#'):
                    self.pygments_html[line[1:].strip()] = testcase = []
                else:
                    testcase.append(unicode(line.rstrip(), 'utf-8'))

    def _expected(self, expected_id):
        return self.pygments_html[expected_id]

    def _test(self, expected_id, result):
        expected = self._expected(expected_id)
        result = unicode(result).splitlines()
        # from pprint import pformat
        # print("\nE: " + expected_id + "\n" + pformat(expected))
        # print("\nR: " + expected_id + "\n" + pformat(result))
        self.maxDiff = None
        def split(s):
            sp = re.split('(>)', s)
            return [a + b for (a, b) in zip(sp[0::2], sp[1::2])]
        for exp, res in zip(expected, result):
            self.assertEqual(split(exp), split(res))
        self.assertEqual(len(expected), len(result))

    def test_python_hello(self):
        """
        Simple Python highlighting with Pygments (direct)
        """
        result = self.pygments.render(self.context, 'text/x-python',
                                      textwrap.dedent("""\
            def hello():
                    return "Hello World!"
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_hello', result)
        else:
            self._test('python_hello_pygments_2.1plus', result)

    def test_python_hello_mimeview(self):
        """
        Simple Python highlighting with Pygments (through Mimeview.render)
        """
        result = Mimeview(self.env).render(self.context, 'text/x-python',
                                           textwrap.dedent("""
            def hello():
                    return "Hello World!"
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_hello_mimeview', result)
        else:
            self._test('python_hello_mimeview_pygments_2.1plus', result)

    def test_python_with_lineno(self):
        result = format_to_html(self.env, self.context, textwrap.dedent("""\
            {{{#!text/x-python lineno
            print 'this is a python sample'
            a = b+3
            z = "this is a string"
            print 'this is the end of the python sample'
            }}}
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_lineno_1', result)
        else:
            self._test('python_with_lineno_1_pygments_2.1plus', result)

        result = format_to_html(self.env, self.context, textwrap.dedent("""\
            {{{#!text/x-python lineno=3
            print 'this is a python sample'
            a = b+3
            z = "this is a string"
            print 'this is the end of the python sample'
            }}}
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_lineno_2', result)
        else:
            self._test('python_with_lineno_2_pygments_2.1plus', result)

    def test_python_with_lineno_and_markups(self):
        """Python highlighting with Pygments and lineno annotator
        """
        result = format_to_html(self.env, self.context, textwrap.dedent("""\
            {{{#!text/x-python lineno=3 id=b marks=4-5
            print 'this is a python sample'
            a = b+3
            z = "this is a string"
            print 'this is the end of the python sample'
            }}}
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_lineno_and_markups', result)
        else:
            self._test('python_with_lineno_and_markups_pygments_2.1plus',
                       result)

    def test_python_with_invalid_arguments(self):
        result = format_to_html(self.env, self.context, textwrap.dedent("""\
            {{{#!text/x-python lineno=-10
            print 'this is a python sample'
            a = b+3
            z = "this is a string"
            print 'this is the end of the python sample'
            }}}
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_invalid_arguments_1', result)
        else:
            self._test('python_with_invalid_arguments_1_pygments_2.1plus',
                       result)

        result = format_to_html(self.env, self.context, textwrap.dedent("""\
            {{{#!text/x-python lineno=a id=d marks=a-b
            print 'this is a python sample'
            a = b+3
            z = "this is a string"
            print 'this is the end of the python sample'
            }}}
            """))
        self.assertTrue(result)
        if pygments_version < parse_version('2.1'):
            self._test('python_with_invalid_arguments_2', result)
        else:
            self._test('python_with_invalid_arguments_2_pygments_2.1plus',
                       result)

    def test_pygments_lexer_options(self):
        self.env.config.set('pygments-lexer',
                            'php.startinline', True)
        self.env.config.set('pygments-lexer',
                            'php.funcnamehighlighting', False)
        result = format_to_html(self.env, self.context, textwrap.dedent("""
            {{{#!php
            if (class_exists('MyClass')) {
                $myclass = new MyClass();
            }
            }}}
            """))
        self.assertTrue(result)
        self._test('pygments_lexer_options', result)

    def test_pygments_lexer_arguments(self):
        result = format_to_html(self.env, self.context, textwrap.dedent("""
            {{{#!php startinline=True funcnamehighlighting=False
            if (class_exists('MyClass')) {
                $myclass = new MyClass();
            }
            }}}
            """))
        self.assertTrue(result)
        self._test('pygments_lexer_arguments', result)

    def test_pygments_lexer_arguments_override_options(self):
        self.env.config.set('pygments-lexer',
                            'php.startinline', True)
        self.env.config.set('pygments-lexer',
                            'php.funcnamehighlighting', False)
        result = format_to_html(self.env, self.context, textwrap.dedent("""
            {{{#!php funcnamehighlighting=True
            if (class_exists('MyClass')) {
                $myclass = new MyClass();
            }
            }}}
            """))
        self.assertTrue(result)
        self._test('pygments_lexer_arguments_override_options', result)

    def test_newline_content(self):
        """Regression test for newline-stripping behavior in Pygments.

        http://trac.edgewall.org/ticket/7705
        """
        result = self.pygments.render(self.context, 'text/x-python',
                                      '\n\n\n\n')
        self.assertTrue(result)
        t = result

        self.assertEqual("\n\n\n\n", t)

    def test_empty_content(self):
        """
        A '\n' token is generated for an empty file, so we have to bypass
        pygments when rendering empty files.
        """
        result = self.pygments.render(self.context, 'text/x-python', '')
        self.assertIsNone(result)

    def test_extra_mimetypes(self):
        """
        The text/x-ini mimetype is normally not known by Trac, but
        Pygments supports it.
        """
        mimeview = Mimeview(self.env)
        self.assertIn(mimeview.get_mimetype('file.ini'),
                      ('text/x-ini; charset=utf-8',
                       'text/inf; charset=utf-8'))  # Pygment 2.1+
        self.assertIn(mimeview.get_mimetype('file.cfg'),
                      ('text/x-ini; charset=utf-8',
                       'text/inf; charset=utf-8'))  # Pygment 2.1+
        self.assertEqual('text/x-ini; charset=utf-8',
                         mimeview.get_mimetype('file.text/x-ini'))
Ejemplo n.º 17
0
class PatchRendererTestCase(unittest.TestCase):

    def setUp(self):
        env = EnvironmentStub(enable=[Chrome, PatchRenderer])
        req = MockRequest(env)
        self.context = web_context(req)
        self.patch = Mimeview(env).renderers[0]
        html_file = os.path.join(os.path.dirname(__file__), 'patch.data')
        self.patch_html = {}
        testcase = []
        with open(html_file, 'rb') as f:
            for line in f.readlines():
                if line.startswith('#'):
                    self.patch_html[line[1:].strip()] = testcase = []
                else:
                    testcase.append(line.rstrip())

    def _expected(self, expected_id):
        return self.patch_html[expected_id]

    def _test(self, expected_id, result):
        expected = self._expected(expected_id)
        result = result.splitlines()
        self.maxDiff = None
        for exp, res in zip(expected, result):
            self.assertEqual(exp, res)
        self.assertEqual(len(expected), len(result))

    def test_simple(self):
        """
        Simple patch rendering
        """
        result = self.patch.render(self.context, None, """
--- README.orig 2006-10-27 14:42:04.062500000 +0200
+++ README      2006-10-27 14:42:28.125000000 +0200
@@ -1,5 +1,5 @@
 ----
-base
-base
-base
+be
+the base
+base modified
 .
""")
        self.assertTrue(result)
        self._test('simple', result)

    def test_no_newline_in_base(self):
        """
        Simple regression test for #4027 ("No newline at end of file")
        """
        result = self.patch.render(self.context, None, """
--- nonewline   2006-10-27 08:36:48.453125000 +0200
+++ newline     2006-10-27 08:36:57.187500000 +0200
@@ -1 +1 @@
-ONELINE
\ No newline at end of file
+ONELINE
""")
        self.assertTrue(result)
        self._test('no_newline_in_base', result)

    def test_no_newline_in_changed(self):
        """
        Another simple regression test for #4027 ("No newline at end of file")
        """
        result = self.patch.render(self.context, None, """
--- newline     2006-10-27 08:36:57.187500000 +0200
+++ nonewline   2006-10-27 08:36:48.453125000 +0200
@@ -1 +1 @@
-ONELINE
+ONELINE
\ No newline at end of file
""")
        self.assertTrue(result)
        self._test('no_newline_in_changed', result)
    def test_diff_to_hdf_expandtabs(self):
        """Regression test related to #4557"""
        changes = self.patch._diff_to_hdf(
            ['--- hello.c 1',
             '+++ hello.c 2',
             '@@ -1 +1 @@',
             '-aa\tb',
             '+aaxb'], 8)
        self.assertEqual('aa<del>&nbsp; &nbsp; &nbsp; </del>b',
                         str(changes[0]['diffs'][0][0]['base']['lines'][0]))
        self.assertEqual('aa<ins>x</ins>b',
                         str(changes[0]['diffs'][0][0]['changed']['lines'][0]))

    def test_diff_to_hdf_leading_ws(self):
        """Regression test related to #5795"""
        changes = self.patch._diff_to_hdf(
            ['--- hello.c 1',
             '+++ hello.c 2',
             '@@ -1 +1 @@',
             '-*a',
             '+ *a'], 8)
        self.assertEqual('<del></del>*a',
                         str(changes[0]['diffs'][0][0]['base']['lines'][0]))
        self.assertEqual('<ins>&nbsp;</ins>*a',
                         str(changes[0]['diffs'][0][0]['changed']['lines'][0]))

    def test_range_information_with_no_lines(self):
        result = self.patch.render(self.context, None, """
Index: filename.txt
===================================================================
--- filename.txt
+++ filename.txt
@@ -14,7 +14,7 @@
""")
        self.assertTrue(result)
        self._test('range_information_with_no_lines', result)
Ejemplo n.º 18
0
    def expand_macro(self, formatter, name, content):
        self.log.info('Begin expand_macro for req: ' + repr(content))
        largs, kwargs = parse_args(content)

        if len(largs) == 0:
            raise TracError("File name to include is required parameter!")

        orig_file_name = file_name = largs[0]

        global multirepos
        if not multirepos:
            repos = self.env.get_repository(formatter.req.authname)
        else:
            if (orig_file_name[0] == '/'): orig_file_name = orig_file_name[1:]
            splitpath = file_name.split('/')
            if (file_name[0] == '/'):
                reponame = splitpath[1]
            else:
                reponame = splitpath[0]
            repos = self.env.get_repository(reponame)
            if (repos):
                l = len(reponame)
                if (file_name[0] == '/'):
                    file_name = file_name[1:]
                file_name = file_name[l:]
            else:
                repos = self.env.get_repository()

        rev = kwargs.get('rev', None)

        if kwargs.has_key('header'):
            header = kwargs.get('header')  # user specified header
        else:
            href = '../browser/%s%s' % (orig_file_name, make_rev_str(rev))
            header = tag.a(file_name, href=href)
        if not header:
            header = u'\xa0'  # default value from trac.mimeview.api.py

        # TODO - 'content' is default from mimeview.api.py, but it picks
        # up text-align: center, which probably isn't the best thing if
        # we are adding a file name in the header. There isn't an obvious
        # replacement in the delivered CSS to pick over this for now though
        header_class = kwargs.get('header_class', 'content')

        src = repos.get_node(file_name, rev).get_content().read()

        context = formatter.context
        # put these into context object so annotator sees them
        context.file_name = file_name
        context.rev = rev
        context.startline = 1

        # we generally include line numbers in the output, unless it has been
        # explicitly requested otherwise. 0, no, false, none will suppress
        line_numbers = kwargs.get('line_numbers', None)
        if line_numbers is None:
            line_numbers = True
        else:
            try:
                line_numbers = int(line_numbers)
            except:
                negatory = ('no', 'false', 'none')
                line_numbers = str(line_numbers).lower() not in negatory

        # lines added up front to "trick" renderer when rendering partial
        render_prepend = []

        start, end = kwargs.get('start', None), kwargs.get('end', None)
        if start or end:
            src, start, end = self._handle_partial(src, start, end)
            context.startline = start

            if start > 2 and file_name.endswith('.php'):
                render_prepend = ['#!/usr/bin/php -f', '<?']

            if render_prepend:
                src = '\n'.join(render_prepend) + '\n' + src

                # ensure accurate start number after this gets stripped
                context.startline = start - len(render_prepend)

        mimetype = kwargs.get('mimetype', None)
        url = None  # render method doesn't seem to use this

        mv = Mimeview(self.env)
        annotations = line_numbers and ['givenlineno'] or None

        src = mv.render(formatter.context, mimetype, src, file_name, url,
                        annotations)

        if line_numbers:
            # handle the case where only one line of code was included
            # and we get back an XHTML string
            if not hasattr(src, 'generate'):
                from genshi.input import XML
                src = XML(src)

            # the _render_source method will always set the CSS class
            # of the annotator to it's name; there isn't an easy way
            # to override that. We could create our own CSS class for
            # givenlineno that mimics lineno, but it's cleaner to just
            # tweak the output here by running the genshi stream from
            # src through a transformer that will make the change

            xpath1 = 'thead/tr/th[@class="givenlineno"]'
            xpath2 = 'thead/tr/th[2]'  # last() not supported by Genshi?
            xpath3 = 'thead/tr/th[2]/text()'

            # TODO - does genshi require a QName here? Seems to work w/o it
            src = src.generate() | Transformer(xpath1).attr('class', 'lineno') \
                                 | Transformer(xpath2).attr('class', header_class) \
                                 | Transformer(xpath3).replace(header)

            if render_prepend:
                # TODO - is there a better of stripping lines here?
                for i in xrange(len(render_prepend)):
                    src = src | Transformer('tbody/tr[1]').remove()

        return src