changeset 2672:9bbe70281718

Merge main.
author Karol Nowak <grzywacz@sul.uni.lodz.pl>
date Mon, 13 Aug 2007 23:52:55 +0200
parents 9bc7d2c14e1f (current diff) b25faa72dd5b (diff)
children 536e0505c071
files
diffstat 5 files changed, 105 insertions(+), 202 deletions(-) [+]
line wrap: on
line diff
--- a/MoinMoin/parser/_tests/test_text_moin_wiki.py	Mon Aug 13 23:51:26 2007 +0200
+++ b/MoinMoin/parser/_tests/test_text_moin_wiki.py	Mon Aug 13 23:52:55 2007 +0200
@@ -9,17 +9,17 @@
     @license: GNU GPL, see COPYING for details.
 """
 
-import unittest # LEGACY UNITTEST, PLEASE DO NOT IMPORT unittest IN NEW TESTS, PLEASE CONSULT THE py.test DOCS
 import re
 from StringIO import StringIO
 
 import py
 
 from MoinMoin.Page import Page
-from MoinMoin.parser.text_moin_wiki import Parser
+from MoinMoin.parser.text_moin_wiki import Parser as WikiParser
+from MoinMoin.formatter.text_html import Formatter as HtmlFormatter
 
 
-class ParserTestCase(unittest.TestCase):
+class ParserTestCase(object):
     """ Helper class that provide a parsing method """
 
     def parse(self, body):
@@ -27,81 +27,69 @@
 
         Create a page with body, then parse it and format using html formatter
         """
+        request = self.request
         assert body is not None
-        self.request.reset()
-        page = Page(self.request, 'ThisPageDoesNotExistsAndWillNeverBeReally')
-        page.set_raw_body(body)
-        from MoinMoin.formatter.text_html import Formatter
-        page.formatter = Formatter(self.request)
-        self.request.formatter = page.formatter
-        page.formatter.setPage(page)
+        request.reset()
+        page = Page(request, 'ThisPageDoesNotExistsAndWillNeverBeReally')
         page.hilite_re = None
-
-        output = StringIO()
-        saved_write = self.request.write
-        self.request.write = output.write
-        self.request.page = page
-        try:
-            page.send_page(content_only=True, do_cache=False)
-        finally:
-            self.request.write = saved_write
-        return output.getvalue()
+        page.set_raw_body(body)
+        formatter = HtmlFormatter(request)
+        formatter.setPage(page)
+        page.formatter = formatter
+        request.formatter = formatter
+        parser = WikiParser(body, request, line_anchors=False)
+        formatter.startContent('') # needed for _include_stack init
+        output = request.redirectedOutput(parser.format, formatter)
+        formatter.endContent('')
+        return output
 
 
 class TestParagraphs(ParserTestCase):
     """ Test paragraphs creating
 
-    All tests ignoring white space in output
+    All tests ignoring white space in output.
+    We do not test for </p> as it is not there currently.
     """
 
     def testFirstParagraph(self):
         """ parser.wiki: first paragraph should be in <p> """
-        py.test.skip("Broken because of line numbers")
         result = self.parse('First')
-        expected = re.compile(r'<p>\s*First\s*</p>')
-        self.assert_(expected.search(result),
-                      '"%s" not in "%s"' % (expected.pattern, result))
+        assert re.search(r'<p.*?>\s*First\s*', result)
 
     def testEmptyLineBetweenParagraphs(self):
         """ parser.wiki: empty line separates paragraphs """
-        py.test.skip("Broken because of line numbers")
         result = self.parse('First\n\nSecond')
-        expected = re.compile(r'<p>\s*Second\s*</p>')
-        self.assert_(expected.search(result),
-                     '"%s" not in "%s"' % (expected.pattern, result))
+        assert re.search(r'<p.*?>\s*Second\s*', result)
 
     def testParagraphAfterBlockMarkup(self):
         """ parser.wiki: create paragraph after block markup """
-        py.test.skip("Broken because of line numbers")
 
         markup = (
             '----\n',
-            '[[en]]\n',
             '|| table ||\n',
             '= heading 1 =\n',
             '== heading 2 ==\n',
             '=== heading 3 ===\n',
             '==== heading 4 ====\n',
             '===== heading 5 =====\n',
+            # '[[en]]\n', XXX crashes
             )
         for item in markup:
             text = item + 'Paragraph'
             result = self.parse(text)
-            expected = re.compile(r'<p.*?>\s*Paragraph\s*</p>')
-            self.assert_(expected.search(result),
-                         '"%s" not in "%s"' % (expected.pattern, result))
+            assert re.search(r'<p.*?>\s*Paragraph\s*', result)
 
 
 class TestHeadings(ParserTestCase):
     """ Test various heading problems """
 
-    def setUp(self):
+    def class_setup(self):
         """ Require show_section_numbers = 0 to workaround counter
         global state saved in request.
         """
         self.config = self.TestConfig(show_section_numbers=0)
 
-    def tearDown(self):
+    def class_teardown(self):
         del self.config
 
     def testIgnoreWhiteSpaceAroundHeadingText(self):
@@ -111,7 +99,6 @@
 
         Does not test mapping of '=' to h number, or valid html markup.
         """
-        py.test.skip("Broken because of line numbers")
         tests = (
             '=  head =\n', # leading
             '= head  =\n', # trailing
@@ -120,19 +107,18 @@
         expected = self.parse('= head =')
         for test in tests:
             result = self.parse(test)
-            self.assertEqual(result, expected,
-                'Expected "%(expected)s" but got "%(result)s"' % locals())
+            assert result == expected
 
 
 class TestTOC(ParserTestCase):
 
-    def setUp(self):
+    def class_setup(self):
         """ Require show_section_numbers = 0 to workaround counter
         global state saved in request.
         """
         self.config = self.TestConfig(show_section_numbers=0)
 
-    def tearDown(self):
+    def class_teardown(self):
         del self.config
 
     def testHeadingWithWhiteSpace(self):
@@ -155,8 +141,7 @@
 """
         expected = self.parse(standard)
         result = self.parse(withWhitespace)
-        self.assertEqual(result, expected,
-            'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert  result == expected
 
 
 class TestDateTimeMacro(ParserTestCase):
@@ -188,11 +173,11 @@
         (u'[[DateTime(1970-01-06T00:00:00)]]',   '1970-01-06 00:00:00'), # fails e.g. for Europe/Vilnius
         )
 
-    def setUp(self):
+    def class_setup(self):
         """ Require default date and time format config values """
         self.config = self.TestConfig(defaults=('date_fmt', 'datetime_fmt'))
 
-    def tearDown(self):
+    def class_teardown(self):
         del self.config
 
     def testDateTimeMacro(self):
@@ -208,8 +193,7 @@
         for test, expected in self._tests:
             html = self.parse(self.text % test)
             result = self.needle.search(html).group(1)
-            self.assertEqual(result, expected,
-                'Expected "%(expected)s" but got "%(result)s"; %(note)s' % locals())
+            assert result == expected
 
 
 class TestTextFormatingTestCase(ParserTestCase):
@@ -234,15 +218,14 @@
         for test, expected in self._tests:
             html = self.parse(self.text % test)
             result = self.needle.search(html).group(1)
-            self.assertEqual(result, expected,
-                             'Expected "%(expected)s" but got "%(result)s"' % locals())
+            assert result == expected
 
 
 class TestCloseInlineTestCase(ParserTestCase):
 
     def testCloseOneInline(self):
         """ parser.wiki: close open inline tag when block close """
-        py.test.skip("Broken because of line numbers")
+        py.test.skip("Broken")
         cases = (
             # test, expected
             ("text'''text\n", r"<p>text<strong>text\s*</strong></p>"),
@@ -253,10 +236,8 @@
              r"\s*</span></strong></em></p>"),
             )
         for test, expected in cases:
-            needle = re.compile(expected)
             result = self.parse(test)
-            self.assert_(needle.search(result),
-                         'Expected "%(expected)s" but got "%(result)s"' % locals())
+            assert re.search(expected, result)
 
 
 class TestInlineCrossing(ParserTestCase):
@@ -269,10 +250,8 @@
 
         expected = (r"<p><em>a<strong>ab</strong></em><strong>b</strong>\s*</p>")
         test = "''a'''ab''b'''\n"
-        needle = re.compile(expected)
         result = self.parse(test)
-        self.assert_(needle.search(result),
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert re.search(expected, result)
 
 
 class TestEscapeHTML(ParserTestCase):
@@ -334,8 +313,7 @@
     def _test(self, test):
         expected = r'&lt;escape-me&gt;'
         result = self.parse(test)
-        self.assert_(re.search(expected, result),
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert re.search(expected, result)
 
 
 class TestEscapeWikiTableMarkup(ParserTestCase):
@@ -377,8 +355,7 @@
     def do(self, test):
         expected = r'&lt;tablewidth="80"&gt;'
         result = self.parse(test)
-        self.assert_(re.search(expected, result),
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert re.search(expected, result)
 
 
 class TestRule(ParserTestCase):
@@ -386,46 +363,35 @@
 
     def testNotRule(self):
         """ parser.wiki: --- is no rule """
-        py.test.skip("Broken because of line numbers")
         result = self.parse('---')
         expected = '---' # inside <p>
-        self.assert_(expected in result,
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert expected in result
 
     def testStandardRule(self):
         """ parser.wiki: ---- is standard rule """
-        py.test.skip("Broken because of line numbers")
         result = self.parse('----')
-        expected = '<hr>'
-        self.assert_(expected in result,
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert re.search(r'<hr.*?>', result)
 
     def testVariableRule(self):
         """ parser.wiki: ----- rules with size """
-        py.test.skip("Broken because of line numbers")
 
         for size in range(5, 11):
             test = '-' * size
             result = self.parse(test)
-            expected = '<hr class="hr%d">' % (size - 4)
-            self.assert_(expected in result,
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+            assert re.search(r'<hr class="hr%d".*?>' % (size - 4), result)
 
     def testLongRule(self):
         """ parser.wiki: ------------ long rule shortened to hr6 """
-        py.test.skip("Broken because of line numbers")
         test = '-' * 254
         result = self.parse(test)
-        expected = '<hr class="hr6">'
-        self.assert_(expected in result,
-                     'Expected "%(expected)s" but got "%(result)s"' % locals())
+        assert re.search(r'<hr class="hr6".*?>', result)
 
 
 class TestBlock(ParserTestCase):
     cases = (
         # test, block start
         ('----\n', '<hr'),
-        ('= Heading =\n', '<h2'),
+        ('= Heading =\n', '<h1'),
         ('{{{\nPre\n}}}\n', '<pre'),
         ('{{{\n#!python\nPre\n}}}\n', '<div'),
         ('|| Table ||', '<div'),
@@ -436,18 +402,15 @@
 
     def testParagraphBeforeBlock(self):
         """ parser.wiki: paragraph closed before block element """
-        py.test.skip("Broken because of line numbers")
         text = """AAA
 %s
 """
         for test, blockstart in self.cases:
             # We dont test here formatter white space generation
-            expected = r'<p>AAA\s*</p>\n+%s' % blockstart
+            expected = r'<p.*?>AAA\s*\n*%s' % blockstart
             needle = re.compile(expected, re.MULTILINE)
             result = self.parse(text % test)
-            match = needle.search(result)
-            self.assert_(match is not None,
-                         'Expected "%(expected)s" but got "%(result)s"' % locals())
+            assert needle.search(result)
 
     def testEmptyLineBeforeBlock(self):
         """ parser.wiki: empty lines before block element ignored
@@ -458,18 +421,15 @@
         Currently an empty paragraph is created, which make no sense but
         no real harm.
         """
-        py.test.skip("Broken because of line numbers")
         text = """AAA
 
 %s
 """
         for test, blockstart in self.cases:
-            expected = r'<p>AAA\s*</p>\n+%s' % blockstart
+            expected = r'<p.*?>AAA.*?(<p.*?>\s*)*%s' % blockstart # XXX ignores addtl. <p>
             needle = re.compile(expected, re.MULTILINE)
             result = self.parse(text % test)
-            match = needle.search(result)
-            self.assert_(match is not None,
-                         'Expected "%(expected)s" but got "%(result)s"' % locals())
+            assert needle.search(result)
 
     def testUrlAfterBlock(self):
         """ parser.wiki: tests url after block element """
@@ -537,37 +497,33 @@
     def testTextBeforeNestingPreBrackets(self):
         """ tests text before nested {{{ }}} for the wiki parser
         """
-
         raw = """Example
         {{{
 You can use {{{brackets}}}}}}"""
         output = self.parse(raw)
         output = ''.join(output)
-        assert 'Example <span class="anchor" id="line-0-1"></span><ul><li style="list-style-type:none"><span class="anchor" id="line-0-2"></span><pre>You can use {{{brackets}}}</pre>' in output
+        assert 'Example <ul><li style="list-style-type:none"><pre>You can use {{{brackets}}}</pre>' in output
 
     def testManyNestingPreBrackets(self):
         """ tests two nestings  ({{{ }}} and {{{ }}}) in one line for the wiki parser
         """
-        py.test.skip("Broken because not implemented yet")
+        py.test.skip("Broken")
 
         raw = """{{{
 Test {{{brackets}}} and test {{{brackets}}}
 }}}"""
         output = self.parse(raw)
         output = ''.join(output)
-        result = '</span><p><pre>Test {{{brackets}}} and test {{{brackets}}}' in output
-        expected = True
-
-        assert expected == result
+        expected = '<pre>Test {{{brackets}}} and test {{{brackets}}}'
+        assert expected in output
 
     def testMultipleShortPreSections(self):
         """
         tests two single {{{ }}} in one line
         """
-        raw = 'def {{{ghi}}} jkl {{{mno}}} pqr'
+        raw = 'def {{{ghi}}} jkl {{{mno}}}'
         output = ''.join(self.parse(raw))
-        # expected output copied from 1.5
-        expected = 'def <tt>ghi</tt> jkl <tt>mno</tt><span class="anchor" id="line-0-1"></span>pqr'
+        expected = 'def <tt>ghi</tt> jkl <tt>mno</tt>'
         assert expected in output
 
 class TestLinkingMarkup(ParserTestCase):
@@ -609,3 +565,4 @@
 
 
 coverage_modules = ['MoinMoin.parser.text_moin_wiki']
+
--- a/MoinMoin/parser/text_creole.py	Mon Aug 13 23:51:26 2007 +0200
+++ b/MoinMoin/parser/text_creole.py	Mon Aug 13 23:52:55 2007 +0200
@@ -4,60 +4,16 @@
 
     See http://wikicreole.org/ for latest specs.
 
-    TODO:
-     * table headers render borderless:
-    |=a|=b|
-    |c|d|
-
-    Changes:
-    2007-08-08:
-     * PEP8 cleanup
-     * creole 1.0 support
-     * checked interwiki links, they are already compliant to creole 1.0
-     * use three angle brackets <<<>>> instead of two chars for placeholder
-      * unclear: do we need to do anything with that? macros are still with <<...>>!
-     * whitespace allowed before all elements except nowiki blocks
-      * (./) headings
-      * (./) lists (checked, was already compliant)
-      * (./) hor. rule (plus fix for being exactly 4 ----)
-      * (./) tables (checked, was already compliant)
-     * (./) added escape character ~ to core
-     * (./) changed escape character so it only escapes following character
-     * (./) removed escaping closing nowiki triple curly brackets because this is now covered by the escape character
-     * (./) a tilde in front of a URL should prevent it from becoming a link (checked, already compliant)
-
-    2007-03-23
-     * Implemented table headings, as in Creole 0.5
-     * No markup allowed in table headings
-
-    2007-02-10
-     * Images inside link descriptions
-     * Lists parsed and rendered properly
-
-    2007-02-05
-     * Tables rendered properly
-     * Links, images and nowiki in tables handled properly
-
-    2007-02-04
-     * {{...}} can now be used both for attachments and images
-     * No space required after bullets anymore
-     * Implemented escaping with space in <pre>
-     * Implemented greedy "}" parsing in nowiki
-     * Added <h1> header available with =...=
-     * Added <br> available with \\
-     * Added tables (temporarily rendered as <pre>)
-    TODO: "smart" resolving of bold/list ambiguity, table rendering
-
-
-    2006-11-29
-     * Fixed the bug causing newlines to be ignored inside //emphasis//
-       and **strong**.
-
-    2006-09-11
-     * Changed the bullet character for unordered lists to '*' according to spec.
-     * Requiring a space or tab after the bullet in lists (to avoid collisions).
-     * Moved the regula expression initialization to class initialization, for
-       faster parser object creation.
+    Notes:
+    * No markup allowed in headings.
+      Creole 1.0 does not require us to support this.
+    * No markup allowed in table headings.
+      Creole 1.0 does not require us to support this.
+    * No (non-bracketed) generic url recognition: this is "mission impossible"
+      except if you want to risk lots of false positives.
+    * We do not allow : before // italic markup to avoid urls with unrecognized
+      schemes (like wtf://server/path) triggering italic rendering for the rest
+      of the paragraph.
 
     @copyright: 2007 MoinMoin:RadomirDopieralski (creole 0.5 implementation),
                 2007 MoinMoin:ThomasWaldmann (updates)
@@ -105,7 +61,7 @@
 
     # The parsing rules
 
-    # whether the parser should convert \n into <br>
+    # Whether the parser should convert \n into <br>.
     bloglike_lines = False
 
     # For pre escaping, in creole 1.0 done with ~:
@@ -113,12 +69,13 @@
 
     # For the inline elements:
     inline_tab = {
-        'url': r'''(^|(?<=\s|[.,:;!?()/=]))(?P<url_target>(?P<url_proto>http|ftp|mailto|irc|https|ftps|news|gopher|file|telnet|nntp):\S+?)($|(?=\s|[,.:;!?()](\s|$)))''',
+        'url': r'''(^|(?<=\s|[.,:;!?()/=]))(?P<escaped_url>~)?(?P<url_target>(?P<url_proto>http|ftp|mailto|irc|https|ftps|news|gopher|file|telnet|nntp):\S+?)($|(?=\s|[,.:;!?()](\s|$)))''',
         'link': r'\[\[(?P<link_target>.+?)\s*(\|\s*(?P<link_text>.+?)\s*)?]]',
         'image': r'{{(?P<image_target>.+?)\s*(\|\s*(?P<image_text>.+?)\s*)?}}',
         'macro': r'<<(?P<macro_target>.+?)\s*(\|\s*(?P<macro_text>.+?)\s*)?>>',
         'code': r'{{{(?P<code_text>.*?)}}}',
-        'emph': r'//',
+        'emph': r'(?<!:)//', # there must be no : in front of the // - avoids
+                             # italic rendering in urls with unknown protocols
         'strong': r'\*\*',
         'break': r'\\\\',
         'escape': r'~(?P<escaped_char>[^\s])', # tilde is the escape char
@@ -142,12 +99,12 @@
     attach_rule = r'(?P<attach_scheme>attachment|inline|drawing|figure):(?P<attach_addr>.*)'
     inter_rule = r'(?P<inter_wiki>[A-Z][a-zA-Z]+):(?P<inter_page>.*)'
     #u'|'.join(wikimacro.getNames(config))
-    macro_rule = r'(?P<macro_name>%s)\((-|(?P<macro_param>.*))\)' % '\w+'
+    macro_rule = r'(?P<macro_name>%s)\((-|(?P<macro_param>.*))\)' % r'\w+'
     page_rule = r'(?P<page_name>.*)'
 
     # For splitting table cells:
     cell_rule = r'\|\s* ( (?P<head> [=][^|]+) | (?P<cell> ((%(link)s) |(%(macro)s) |(%(image)s) |(%(code)s) | [^|] )+)  )\s*' % inline_tab
-    cell_re = re.compile(cell_rule, re.X|re.I|re.U)
+    cell_re = re.compile(cell_rule, re.X|re.U)
 
     # For link descriptions:
     link_rules = r'|'.join([
@@ -155,11 +112,11 @@
             _get_rule('break', inline_tab),
             _get_rule('char', inline_tab),
     ])
-    link_re = re.compile(link_rules, re.X|re.I|re.U)
+    link_re = re.compile(link_rules, re.X|re.U)
 
     # For lists:
     item_rule = r'(?P<item> ^\s* (?P<item_head> [\#*]+ ) \s* (?P<item_text>.*?) $)'
-    item_re = re.compile(item_rule, re.X|re.I|re.U|re.M)
+    item_re = re.compile(item_rule, re.X|re.U|re.M)
 
     # For block elements:
     block_rules = '|'.join([
@@ -218,12 +175,19 @@
 
     def _url_repl(self, groups):
         """Handle raw urls in text."""
-        target = groups.get('url_target', '')
-        node = DocNode('external_link', self.cur)
-        node.content = target
-        node.proto = groups.get('url_proto', 'http')
-        DocNode('text', node, node.content)
-        self.text = None
+        if not groups.get('escaped_url'):
+            # this url is NOT escaped
+            target = groups.get('url_target', '')
+            node = DocNode('external_link', self.cur)
+            node.content = target
+            node.proto = groups.get('url_proto', 'http')
+            DocNode('text', node, node.content)
+            self.text = None
+        else:
+            # this url is escaped, we render it as text
+            if self.text is None:
+                self.text = DocNode('text', self.cur, u'')
+            self.text.content += groups.get('url_target')
     _url_target_repl = _url_repl
     _url_proto_repl = _url_repl
 
@@ -457,9 +421,7 @@
 
 
 class DocEmitter:
-    """
-    Generate the output for the document tree consisting of DocNodes.
-    """
+    """Generate the output for the document tree consisting of DocNodes."""
 
     def __init__(self, root, formatter, request):
         self.root = root
@@ -729,27 +691,21 @@
 
     def preformatted_emit(self, node):
         content = node.content
-        self.processor_name = getattr(node, 'sect', '')
-        self.processor = None
-        if self.processor_name:
-            self._setProcessor(self.processor_name)
-        if self.processor is None:
+        self.parser = None
+        parser_name = getattr(node, 'sect', '')
+        if parser_name:
+            self.setParser(parser_name)
+        if self.parser is None:
+            self.parser_name = None
             return ''.join([
                 self.formatter.preformatted(1),
                 self.formatter.text(content),
                 self.formatter.preformatted(0),
             ])
         else:
-            buff = StringIO.StringIO()
-            self.request.redirect(buff)
-            try:
-                self.formatter.processor(
-                    self.processor_name,
-                    content.split('\n'),
-                    self.processor_is_parser)
-            finally:
-                self.request.redirect()
-            return buff.getvalue()
+            self.parser_name = parser_name
+            return self.request.redirectedOutput(
+                self.formatter.parser, self.parser_name, content.split('\n'))
 
     def default_emit(self, node):
         return ''.join([
@@ -780,24 +736,14 @@
         self.formatter.no_magic = magic_save
         return output
 
-    def _setProcessor(self, name): # From the wiki.py parser
-        """ Set processer to either processor or parser named 'name' """
-        cfg = self.request.cfg
+
+    # Private helpers ------------------------------------------------------------
+
+    def setParser(self, name):
+        """ Set parser to parser named 'name' """
+        # XXX this is done by the formatter as well
         try:
-            self.processor = wikiutil.importPlugin(
-                cfg,
-                "processor",
-                name,
-                "process")
-            self.processor_is_parser = 0
+            self.parser = wikiutil.searchAndImportPlugin(self.request.cfg, "parser", name)
         except wikiutil.PluginMissingError:
-            try:
-                self.processor = wikiutil.importPlugin(
-                    cfg,
-                    "parser",
-                    name,
-                    "Parser")
-                self.processor_is_parser = 1
-            except wikiutil.PluginMissingError:
-                self.processor = None
+            self.parser = None
 
--- a/wiki/htdocs/classic/css/common.css	Mon Aug 13 23:51:26 2007 +0200
+++ b/wiki/htdocs/classic/css/common.css	Mon Aug 13 23:52:55 2007 +0200
@@ -92,7 +92,7 @@
 	border-collapse: collapse;
 }
 
-td
+th, td
 {
 	padding: 0.25em 0.5em 0.25em 0.5em;
 	border: 1px solid #c0c0c0;
--- a/wiki/htdocs/modern/css/common.css	Mon Aug 13 23:51:26 2007 +0200
+++ b/wiki/htdocs/modern/css/common.css	Mon Aug 13 23:52:55 2007 +0200
@@ -109,7 +109,7 @@
 	border-collapse: collapse;
 }
 
-td
+th, td
 {
 	padding: 0.25em 0.5em 0.25em 0.5em;
 	border: 1pt solid #ADB9CC;
--- a/wiki/htdocs/rightsidebar/css/common.css	Mon Aug 13 23:51:26 2007 +0200
+++ b/wiki/htdocs/rightsidebar/css/common.css	Mon Aug 13 23:52:55 2007 +0200
@@ -104,7 +104,7 @@
 	border-collapse: collapse;
 }
 
-td
+th, td
 {
 	padding: 0.25em 0.5em 0.25em 0.5em;
 	border: 1px solid tan;