Attachment 'wiki_word.py'

Download

   1 # -*- coding: iso-8859-1 -*-
   2 
   3 """
   4     MoinMoin - MoinMoin Wiki Markup Parser (for Word Dump)
   5 
   6     Copyright (c) 2000, 2001, 2002 by Jürgen Hermann <jh@web.de>
   7     All rights reserved, see COPYING for details.
   8 
   9     $Id: wiki.py,v 1.88 2002/05/09 21:09:37 jhermann Exp $
  10     ORS modifications:
  11         08.01.04 RS inline parser fix, makes inline extensions configurable
  12         08.01.04 RS colorizer, makes colorizer extensions configurable
  13         09.01.04 RS ignore character formatting inside DT
  14         09.01.04 RS upgrade to 1.1. using wiki.py
  15         12.01.04 RS set proper encoding of this file
  16      1.3.3 re-migration of patches started 31.01.05
  17        * page variables in interwiki
  18      1.3.3 re-migration of patches started 01.09.05
  19        * cleaned some obsolete 1.1. deltas
  20 
  21 """
  22 
  23 import os, re
  24 from MoinMoin import config, wikimacro, wikiutil
  25 from MoinMoin.Page import Page
  26 from MoinMoin.util import web
  27 
  28 Dependencies = []
  29 
  30 _debug=1
  31 
  32 _max_lineno=-40 #limit number of lines in source, -1 = all
  33 
  34 class Parser:
  35     """
  36         Object that turns Wiki markup into HTML.
  37 
  38         All formatting commands can be parsed one line at a time, though
  39         some state is carried over between lines.
  40 
  41         Methods named like _*_repl() are responsible to handle the named regex
  42         patterns defined in print_html().
  43     """
  44 
  45     # allow caching
  46     caching = 1
  47     Dependencies = []
  48 
  49     # some common strings
  50     PARENT_PREFIX = wikiutil.PARENT_PREFIX
  51     attachment_schemas = ["attachment", "inline", "drawing"]
  52     punct_pattern = re.escape(u'''"\'}]|:,.)?!''')
  53     url_pattern = (u'http|https|ftp|nntp|news|mailto|telnet|wiki|file|' +
  54             u'|'.join(attachment_schemas) + 
  55             (config.url_schemas and u'|' + u'|'.join(config.url_schemas) or ''))
  56 
  57     # some common rules
  58     word_rule = ur'(?:(?<![%(l)s])|^)%(parent)s(?:%(subpages)s(?:[%(u)s][%(l)s]+){2,})+(?![%(u)s%(l)s]+)' % {
  59         'u': config.chars_upper,
  60         'l': config.chars_lower,
  61         'subpages': config.allow_subpages and (wikiutil.CHILD_PREFIX + '?') or '',
  62         'parent': config.allow_subpages and (ur'(?:%s)?' % re.escape(PARENT_PREFIX)) or '',
  63     }
  64 #RS end
  65 #RS Word version
  66     punct_pattern_red = re.escape(u',.?')
  67     textword_rule = ur'(?:[%(l)s|%(u)s][%(l)s]*)' % {
  68         'u': config.chars_upper,
  69         'l': config.chars_lower,
  70 #        'punctr': punct_pattern_red,
  71     }
  72 #RS stop
  73     url_rule = ur'%(url_guard)s(%(url)s)\:([^\s\<%(punct)s]|([%(punct)s][^\s\<%(punct)s]))+' % {
  74         'url_guard': u'(^|(?<!\w))',
  75         'url': url_pattern,
  76         'punct': punct_pattern,
  77     }
  78 
  79     ol_rule = ur"^\s+(?:[0-9]+|[aAiI])\.(?:#\d+)?\s"
  80     dl_rule = ur"^\s+.*?::\s"
  81 
  82     # the big, fat, ugly one ;)
  83 #RS word
  84 #Patterns that have been replaced inside the formatting_rules:
  85 #<textword> inserted before <ent>
  86 #(?P<textword>%(textword_rule)s)
  87 #<eoln> and <char> inserted after <ent>
  88 #(?P<eoln> $)
  89 #(?P<char>.)
  90 #RS end
  91 
  92     formatting_rules = ur"""(?:(?P<emph_ibb>'''''(?=[^']+'''))
  93 (?P<emph_ibi>'''''(?=[^']+''))
  94 (?P<emph_ib_or_bi>'{5}(?=[^']))
  95 (?P<emph>'{2,3})
  96 (?P<u>__)
  97 (?P<sup>\^.*?\^)
  98 (?P<sub>,,[^,]{1,40},,)
  99 (?P<tt>\{\{\{.*?\}\}\})
 100 (?P<processor>(\{\{\{(#!.*|\s*$)))
 101 (?P<pre>(\{\{\{ ?|\}\}\}))
 102 (?P<small>(\~- ?|-\~))
 103 (?P<big>(\~\+ ?|\+\~))
 104 (?P<rule>-{4,})
 105 (?P<comment>^\#\#.*$)
 106 (?P<macro>\[\[(%%(macronames)s)(?:\(.*?\))?\]\]))
 107 (?P<ol>%(ol_rule)s)
 108 (?P<dl>%(dl_rule)s)
 109 (?P<li>^\s+\*?)
 110 (?P<tableZ>\|\| $)
 111 (?P<table>(?:\|\|)+(?:<[^>]*?>)?(?!\|? $))
 112 (?P<heading>^\s*(?P<hmarker>=+)\s.*\s(?P=hmarker) $)
 113 (?P<interwiki>[A-Z][a-zA-Z]+\:[^\s'\"\:\<\|]([^\s%(punct)s]|([%(punct)s][^\s%(punct)s]))+)
 114 (?P<word>%(word_rule)s)
 115 (?P<url_bracket>\[\^?((%(url)s)\:|#|\:)[^\s\]]+(\s[^\]]+)?\])
 116 (?P<url>%(url_rule)s)
 117 (?P<email>[-\w._+]+\@[\w-]+(\.[\w-]+)+)
 118 (?P<smiley>(?<=\s)(%(smiley)s)(?=\s))
 119 (?P<smileyA>^(%(smiley)s)(?=\s))
 120 (?P<textword>%(textword_rule)s)
 121 (?P<ent>[<>&])
 122 (?P<eoln> $)
 123 (?P<char>[^`])"""  % {
 124         'url': url_pattern,
 125         'punct': punct_pattern,
 126 #RS 1.3?
 127 #        'macronames': '|'.join(wikimacro.names),
 128 #RS end
 129         'ol_rule': ol_rule,
 130         'dl_rule': dl_rule,
 131         'url_rule': url_rule,
 132         'word_rule': word_rule,
 133 #RS word
 134         'textword_rule': textword_rule,
 135 #RS end
 136         'smiley': u'|'.join(map(re.escape, config.smileys.keys()))}
 137 
 138     # Don't start p before these 
 139 #RS word
 140 #    no_new_p_before = ("heading rule table tableZ tr td ul ol dl dt dd li "
 141 #                       "processor macro pre")
 142     no_new_p_before = ("heading rule table tableZ tr td ul ol dl dt dd li "
 143                        "processor macro pre textword char")
 144 #RS end
 145     no_new_p_before = dict(zip(no_new_p_before.split(), [1] * len(no_new_p_before)))
 146 
 147     def __init__(self, raw, request, **kw):
 148         self.raw = raw
 149         self.request = request
 150         self.form = request.form
 151         self._ = request.getText
 152         self.cfg = request.cfg
 153 
 154         self.macro = None
 155 
 156         self.is_em = 0
 157         self.is_b = 0
 158         self.is_u = 0
 159         self.lineno = 0
 160         self.in_li = 0
 161         self.in_dd = 0
 162         self.in_pre = 0
 163         self.in_table = 0
 164         self.is_big = False
 165         self.is_small = False
 166         self.inhibit_p = 0 # if set, do not auto-create a <p>aragraph
 167         self.titles = request._page_headings
 168 # abp add for pdf
 169         self.is_sub = 0
 170         self.is_sup = 0
 171         self.is_tt = 0
 172 
 173         # holds the nesting level (in chars) of open lists
 174         self.list_indents = []
 175         self.list_types = []
 176 
 177         self.formatting_rules = self.formatting_rules % {'macronames': u'|'.join(wikimacro.getNames(self.cfg))}
 178 
 179 #RS obsolete in 1.3?
 180     def _check_p(self):
 181         pass
 182 #        if not (self.formatter.in_p or self.in_pre):
 183 #            self.request.write(self.formatter.paragraph(1))
 184 
 185 
 186     def _close_item(self, result):
 187         result.append("<!-- close item begin -->\n")
 188         if self.in_table:
 189             result.append(self.formatter.table(0))
 190             self.in_table = 0
 191         if self.in_li:
 192             self.in_li = 0
 193             if self.formatter.in_p:
 194                 result.append(self.formatter.paragraph(0))
 195             result.append(self.formatter.listitem(0))
 196         if self.in_dd:
 197             self.in_dd = 0
 198             if self.formatter.in_p:
 199                 result.append(self.formatter.paragraph(0))
 200             result.append(self.formatter.definition_desc(0))
 201         result.append("<!-- close item end -->\n")
 202 
 203 
 204     def interwiki(self, url_and_text, **kw):
 205         # TODO: maybe support [wiki:Page http://wherever/image.png] ?
 206         self._check_p()
 207 
 208         if len(url_and_text) == 1:
 209             url = url_and_text[0]
 210             text = None
 211         else:
 212             url, text = url_and_text
 213 
 214         url = url[5:] # remove "wiki:"
 215         if text is None:
 216             tag, tail = wikiutil.split_wiki(url)
 217             if tag:
 218                 text = tail
 219             else:
 220                 text = url
 221                 url = ""
 222         elif config.allow_subpages and url.startswith(wikiutil.CHILD_PREFIX):
 223             # fancy link to subpage [wiki:/SubPage text]
 224             return self._word_repl(url, text)
 225         elif Page(self.request, url).exists():
 226             # fancy link to local page [wiki:LocalPage text]
 227             return self._word_repl(url, text)
 228 
 229         wikitag, wikiurl, wikitail, wikitag_bad = wikiutil.resolve_wiki(self.request, url)
 230 #RS evaluate some keywords that can be set by pragmas
 231         for key in self.request.pagevars:
 232            value=self.request.getPragma("var_%s" % key, "")
 233            wikiurl=wikiurl.replace("$var_%s" % key, value)
 234 #RS        
 235         wikiurl = wikiutil.mapURL(self.request,wikiurl)
 236         href = wikiutil.join_wiki(wikiurl, wikitail)
 237 
 238         # check for image URL, and possibly return IMG tag
 239         if not kw.get('pretty_url', 0) and wikiutil.isPicture(wikitail):
 240             return self.formatter.image(src=href)
 241 
 242         # link to self?
 243         if wikitag is None:
 244             return self._word_repl(wikitail)
 245               
 246 ##        # return InterWiki hyperlink
 247 ##        prefix = config.url_prefix
 248 ##        badwiki = wikitag == "BadWikiTag"
 249 #RS changed for Word
 250 ##        text = self.highlight_text(text) # also wikiutil.escapes if necessary
 251 #RS stop
 252 ##        icon = ''
 253 ##        if self.request.user.show_fancy_links:
 254 #RS continue
 255 ##            self.formatter.image(width=16, height=16, hspace=2,
 256 ##                border=badwiki,
 257 ##                src=prefix+"/img/moin-inter.gif",
 258 ##                alt="[%s]" % wikitag)
 259 #RS end
 260 ##        return self.formatter.url(href, icon + text,
 261 ##            title=wikitag, unescaped=1, pretty_url=kw.get('pretty_url', 0), target=target)
 262 #RS end
 263         return (self.formatter.interwikilink(1, wikitag, wikitail) + 
 264                 self.formatter.text(text) +
 265                 self.formatter.interwikilink(0))
 266 
 267 
 268     def attachment(self, url_and_text, **kw):
 269         """ This gets called on attachment URLs.
 270         """
 271         import urllib
 272         _ = self._
 273 
 274         self._check_p()
 275 
 276         if len(url_and_text) == 1:
 277             url = url_and_text[0]
 278             text = None
 279         else:
 280             url, text = url_and_text
 281 
 282         inline = url[0] == 'i'
 283         drawing = url[0] == 'd'
 284         url = url.split(":", 1)[1]
 285         url = urllib.unquote(url)
 286         text = text or url
 287 
 288         pagename = self.formatter.page.page_name
 289         parts = url.split('/')
 290         if len(parts) > 1:
 291             # get attachment from other page
 292             pagename = '/'.join(parts[:-1])
 293             url = parts[-1]
 294 
 295         import urllib
 296         from MoinMoin.action import AttachFile
 297         fname = wikiutil.taintfilename(url)
 298         if drawing:
 299             drawing = fname
 300             fname = fname + ".png"
 301             url = url + ".png"
 302             # fallback for old gif drawings (1.1 -> 1.2)
 303             fpath = AttachFile.getFilename(self.request, pagename, fname)
 304             if not os.path.exists(fpath):
 305                 gfname = fname[:-4] + ".gif"
 306                 gurl = url[:-4] + ".gif"
 307                 gfpath = AttachFile.getFilename(self.request, pagename, gfname)
 308                 if os.path.exists(gfpath):
 309                     fname, url, fpath = gfname, gurl, gfpath
 310         else:
 311             fpath = AttachFile.getFilename(self.request, pagename, fname)
 312 
 313         # check whether attachment exists, possibly point to upload form
 314         if not os.path.exists(fpath):
 315             if drawing:
 316                 linktext = _('Create new drawing "%(filename)s"')
 317             else:
 318                 linktext = _('Upload new attachment "%(filename)s"')
 319             return wikiutil.link_tag(self.request,
 320                 self.formatter.text('%s?action=AttachFile&rename=%s%s' % (
 321                     wikiutil.quoteWikinameURL(pagename),
 322                     urllib.quote_plus(fname.encode(config.charset)),
 323                     drawing and ('&drawing=%s' % urllib.quote(drawing.encode(config.charset))) or '')),
 324                 linktext % {'filename': self.formatter.text(fname)})
 325 
 326         # check for image URL, and possibly return IMG tag
 327         # (images are always inlined, just like for other URLs)
 328         if not kw.get('pretty_url', 0) and wikiutil.isPicture(url):
 329             if drawing:
 330                 # check for map file
 331                 mappath = AttachFile.getFilename(self.request, pagename, drawing + '.map')
 332                 edit_link = self.formatter.text('%s?action=AttachFile&rename=%s&drawing=%s' % (wikiutil.quoteWikinameURL(pagename), urllib.quote_plus(fname.encode(config.charset)), urllib.quote(drawing.encode(config.charset))))
 333                 if os.path.exists(mappath):
 334                     # we have a image map. inline it and add a map ref
 335                     # to the img tag
 336                     try:
 337                         map = open(mappath,'r').read()
 338                     except IOError:
 339                         pass
 340                     except OSError:
 341                         pass
 342                     else:
 343                         mapid = 'ImageMapOf'+drawing
 344                         # replace MAPNAME
 345                         map = map.replace('%MAPNAME%', mapid)
 346                         # add alt and title tags to areas
 347                         map = re.sub('href\s*=\s*"((?!%TWIKIDRAW%).+?)"',r'href="\1" alt="\1" title="\1"',map)
 348                         # add in edit links plus alt and title attributes
 349                         map = map.replace('%TWIKIDRAW%"', edit_link + '" alt="' + _('Edit drawing %(filename)s') % {'filename': self.formatter.text(fname)} + '" title="' + _('Edit drawing %(filename)s') % {'filename': self.formatter.text(fname)} + '"')
 350                         # unxml, because 4.01 concrete will not validate />
 351                         map = map.replace('/>','>')
 352                         return map + self.formatter.image(alt=drawing,
 353                                 src=AttachFile.getAttachUrl(pagename, url, self.request, addts=1), usemap='#'+mapid, html_class="drawing")
 354                 else:
 355                     return wikiutil.link_tag(self.request,
 356                         edit_link,
 357                         self.formatter.image(alt=url,
 358                             src=AttachFile.getAttachUrl(pagename, url, self.request, addts=1), html_class="drawing"),
 359                         attrs='title="%s"' % (_('Edit drawing %(filename)s') % {'filename': self.formatter.text(fname)}))
 360             else:
 361                 return self.formatter.image(alt=url,
 362                     src=AttachFile.getAttachUrl(pagename, url, self.request, addts=1))
 363 
 364 #            print "image<P>"
 365             form = self.request.form
 366 
 367             # determine modes
 368 #RS handle attachments as path url when printmode
 369             print_mode = form.has_key('action') and form['action'].value == 'print'
 370             if print_mode:
 371 #                print "printed:"
 372                 attsrc=AttachFile.getAttachPathUrl(pagename, url, addts=1)
 373                 return self.formatter.image(border=0, alt=url,
 374                     src=attsrc)
 375             else:    
 376                 return self.formatter.image(border=0, alt=url,
 377                     src=AttachFile.getAttachUrl(pagename, url, addts=1))
 378 #RS end
 379 
 380         # try to inline the attachment (parser know what they
 381         # can handle)
 382         base, ext = os.path.splitext(url)
 383         if inline:
 384             Parser = wikiutil.getParserForExtension(self.cfg, ext)
 385             if Parser is not None:
 386                 content = file(fpath, 'r').read()
 387                 # Try to decode text. It might return junk, but we don't
 388                 # have enough information with attachments.
 389                 content = wikiutil.decodeUnknownInput(content)
 390                 colorizer = Parser(content, self.request)
 391                 colorizer.format(self.formatter)
 392 
 393         url = AttachFile.getAttachUrl(pagename, url, self.request)
 394 
 395         if not kw.get('pretty_url', 0) and wikiutil.isPicture(url):
 396             return self.formatter.image(src=url)
 397         else:
 398             return (self.formatter.url(1, url) +
 399                     self.formatter.text(text) +
 400                     self.formatter.url(0))
 401 
 402     def _u_repl(self, word):
 403         """Handle underline."""
 404         self._check_p()
 405         self.is_u = not self.is_u
 406         return self.formatter.underline(self.is_u)
 407 
 408     def _small_repl(self, word):
 409         """Handle small."""
 410         if word.strip() == '~-' and self.is_small: return word
 411         if word.strip() == '-~' and not self.is_small: return word
 412         self.is_small = not self.is_small
 413         return self.formatter.small(self.is_small)
 414 
 415     def _big_repl(self, word):
 416         """Handle big."""
 417         if word.strip() == '~+' and self.is_big: return word
 418         if word.strip() == '+~' and not self.is_big: return word
 419         self.is_big = not self.is_big
 420         return self.formatter.big(self.is_big)
 421 
 422     def _emph_repl(self, word):
 423         """Handle emphasis, i.e. '' and '''."""
 424         self._check_p()
 425         ##print "#", self.is_b, self.is_em, "#"
 426         if len(word) == 3:
 427             self.is_b = not self.is_b
 428             if self.is_em and self.is_b: self.is_b = 2
 429             return self.formatter.strong(self.is_b)
 430         else:
 431             self.is_em = not self.is_em
 432             if self.is_em and self.is_b: self.is_em = 2
 433             return self.formatter.emphasis(self.is_em)
 434 
 435     def _emph_ibb_repl(self, word):
 436         """Handle mixed emphasis, i.e. ''''' followed by '''."""
 437         self._check_p()
 438         self.is_b = not self.is_b
 439         self.is_em = not self.is_em
 440         if self.is_em and self.is_b: self.is_b = 2
 441         return self.formatter.emphasis(self.is_em) + self.formatter.strong(self.is_b)
 442 
 443     def _emph_ibi_repl(self, word):
 444         """Handle mixed emphasis, i.e. ''''' followed by ''."""
 445         self._check_p()
 446         self.is_b = not self.is_b
 447         self.is_em = not self.is_em
 448         if self.is_em and self.is_b: self.is_em = 2
 449         return self.formatter.strong(self.is_b) + self.formatter.emphasis(self.is_em)
 450 
 451     def _emph_ib_or_bi_repl(self, word):
 452         """Handle mixed emphasis, exactly five '''''."""
 453         self._check_p()
 454         ##print "*", self.is_b, self.is_em, "*"
 455         b_before_em = self.is_b > self.is_em > 0
 456         self.is_b = not self.is_b
 457         self.is_em = not self.is_em
 458         if b_before_em:
 459             return self.formatter.strong(self.is_b) + self.formatter.emphasis(self.is_em)
 460         else:
 461             return self.formatter.emphasis(self.is_em) + self.formatter.strong(self.is_b)
 462 
 463 
 464     def _sup_repl(self, word):
 465         """Handle superscript."""
 466         self._check_p()
 467         return self.formatter.sup(1) + \
 468             self.formatter.text(word[1:-1]) + \
 469             self.formatter.sup(0)
 470 
 471     def _sub_repl(self, word):
 472         """Handle subscript."""
 473         self._check_p()
 474         return self.formatter.sub(1) + \
 475             self.formatter.text(word[2:-2]) + \
 476             self.formatter.sub(0)
 477 
 478     def _rule_repl(self, word):
 479         """Handle sequences of dashes."""
 480         ##self.inhibit_p = 1
 481         result = self._undent() + self._closeP()
 482         if len(word) <= 4:
 483             result = result + self.formatter.rule()
 484         else:
 485             # Create variable rule size 1 - 6. Actual size defined in css.
 486             size = min(len(word), 10) - 4
 487             result = result + self.formatter.rule(size)
 488         return result
 489 
 490     def _word_repl(self, word, text=None):
 491 
 492         """Handle WikiNames."""
 493         self._check_p()
 494         # check for parent links
 495         # !!! should use wikiutil.AbsPageName here, but setting `text`
 496         # correctly prevents us from doing this for now
 497         if config.allow_subpages and word.startswith(wikiutil.PARENT_PREFIX):
 498             if not text: text = word
 499             word = '/'.join(filter(None, self.formatter.page.page_name.split('/')[:-1] + [word[wikiutil.PARENT_PREFIX_LEN:]]))
 500 
 501         if not text:
 502             # if a simple, self-referencing link, emit it as plain text
 503             if word == self.formatter.page.page_name:
 504                 return self.formatter.text(word)
 505             text = word
 506         if config.allow_subpages and word.startswith(wikiutil.CHILD_PREFIX):
 507             word = self.formatter.page.page_name + '/' + word[wikiutil.CHILD_PREFIX_LEN:]
 508         return (self.formatter.pagelink(1, word) +
 509                 self.formatter.text(text) +
 510                 self.formatter.pagelink(0, word))
 511 
 512 #RS word
 513     def _textword_repl(self, word):
 514         """Handle simple text word."""
 515         self._check_p()
 516         return self.formatter.pure(word)
 517 
 518     def _punct1_repl(self, word):
 519         """Handle simple text word."""
 520         self._check_p()
 521         return self.formatter.pure('*'+word)
 522 
 523     def _char_repl(self, word):
 524         """Handle single chars."""
 525         return self.formatter.pure(word)
 526 
 527     def _eoln_repl(self, word):
 528         """final space at eoln"""
 529         return self.formatter.pure('')
 530 
 531     def _punct2_repl(self, word):
 532         """Handle simple text word."""
 533         self._check_p()
 534         return self.formatter.pure('*'+word)
 535 
 536     def _punct3_repl(self, word):
 537         """Handle simple text word."""
 538         self._check_p()
 539         return self.formatter.pure('*'+word)
 540 
 541     def _punctr_repl(self, word):
 542         """Handle simple text word."""
 543         self._check_p()
 544         return self.formatter.pure('^'+word)
 545 #RS end
 546 
 547     def _notword_repl(self, word):
 548         """Handle !NotWikiNames."""
 549         self._check_p()
 550         return self.formatter.text(word[1:])
 551 
 552 
 553     def _interwiki_repl(self, word):
 554         """Handle InterWiki links."""
 555         self._check_p()
 556         return self.interwiki(["wiki:" + word])
 557 
 558 
 559     def _url_repl(self, word):
 560         """Handle literal URLs including inline images."""
 561         self._check_p()
 562         scheme = word.split(":", 1)[0]
 563 
 564         if scheme == "wiki": return self.interwiki([word])
 565         if scheme in self.attachment_schemas:
 566             return self.attachment([word])
 567 
 568 #RS word
 569 #        return self.formatter.url(word, text=word)
 570 #RS end
 571         if wikiutil.isPicture(word):
 572             word = wikiutil.mapURL(self.request, word)
 573             # Get image name http://here.com/dir/image.gif -> image
 574             name = word.split('/')[-1]
 575             name = ''.join(name.split('.')[:-1])
 576             return self.formatter.image(src=word, alt=name)
 577         else:
 578             return (self.formatter.url(1, word, type='www') +
 579                     self.formatter.text(word) +
 580                     self.formatter.url(0))
 581 
 582     def _wikiname_bracket_repl(self, word):
 583         """Handle special-char wikinames."""
 584         wikiname = word[2:-2]
 585         if wikiname:
 586             return self._word_repl(wikiname)
 587         else:
 588             return word
 589 
 590 
 591     def _url_bracket_repl(self, word):
 592         """Handle bracketed URLs."""
 593         self._check_p()
 594 
 595         # Local extended link?
 596         if word[1] == ':':
 597             words = word[2:-1].split(':', 1)
 598             if len(words) == 1:
 599                 words = words * 2
 600             words[0] = 'wiki:Self:%s' % words[0]
 601             return self.interwiki(words, pretty_url=1)
 602             #return self._word_repl(words[0], words[1])
 603 
 604         # Traditional split on space
 605         words = word[1:-1].split(None, 1)
 606         if len(words) == 1: words = words * 2
 607 
 608         if words[0][0] == '#':
 609             # anchor link
 610             return (self.formatter.url(1, words[0]) +
 611                     self.formatter.text(words[1]) +
 612                     self.formatter.url(0))
 613         scheme = words[0].split(":", 1)[0]
 614         if scheme == "wiki": return self.interwiki(words, pretty_url=1)
 615         if scheme in self.attachment_schemas:
 616             return self.attachment(words, pretty_url=1)
 617 
 618         if wikiutil.isPicture(words[1]) and re.match(self.url_rule, words[1]):
 619             return (self.formatter.url(1, words[0], 'external', unescaped=1) +
 620                     self.formatter.image(title=words[0], alt=words[0], src=words[1]) +
 621                     self.formatter.url(0))
 622         else:
 623             return (self.formatter.url(1, words[0], 'external',
 624                                        type='www', unescaped=1) +
 625                     self.formatter.text(words[1]) +
 626                     self.formatter.url(0))
 627 
 628 
 629 
 630     def _email_repl(self, word):
 631         """Handle email addresses (without a leading mailto:)."""
 632         self._check_p()
 633         return (self.formatter.url(1, "mailto:" + word, type='mailto') +
 634                 self.formatter.text(word) +
 635                 self.formatter.url(0))
 636 
 637 
 638     def _ent_repl(self, word):
 639         """Handle SGML entities."""
 640         self._check_p()
 641         return self.formatter.text(word)
 642         #return {'&': '&amp;',
 643         #        '<': '&lt;',
 644         #        '>': '&gt;'}[word]
 645 
 646 
 647     def _ent_numeric_repl(self, word):
 648         """Handle numeric SGML entities."""
 649         self._check_p()
 650         return self.formatter.rawHTML(word)
 651 
 652 
 653     def _li_repl(self, match):
 654         """Handle bullet lists."""
 655         result = []
 656         indented_only = (match == (" " * len(match)))
 657         if indented_only and self.in_li: return ''
 658             
 659         self._close_item(result)
 660         #self.inhibit_p = 1
 661         self.in_li = 1
 662         css_class = ''
 663         if self.line_was_empty and not self.first_list_item:
 664             css_class = 'gap'
 665         if indented_only:
 666             result.append(self.formatter.listitem(1, css_class=css_class,
 667                                              style="list-style-type:none"))
 668         else:
 669             result.append(self.formatter.listitem(1, css_class=css_class))
 670         # Suspected p!
 671         ## result.append(self.formatter.paragraph(1))
 672         return ''.join(result)
 673 
 674 
 675     def _ol_repl(self, match):
 676         """Handle numbered lists."""
 677         return self._li_repl(match)
 678 
 679 
 680     def _dl_repl(self, match):
 681         """Handle definition lists."""
 682         result = []
 683         self._close_item(result)
 684         #self.inhibit_p = 1
 685         self.in_dd = 1
 686         result.extend([
 687             self.formatter.definition_term(1),
 688 #RS ignore character formatting inside DT
 689 #            self.formatter.text(match[1:-3]),
 690             self.formatter.text(match[1:-3].replace("'","")),
 691 #RS end
 692             self.formatter.definition_term(0),
 693             self.formatter.definition_desc(1),
 694             ## CHANGE: no automatic paragraph
 695             ##self.formatter.paragraph(1)
 696         ])
 697         return ''.join(result)
 698 
 699 
 700     def _indent_level(self):
 701         """Return current char-wise indent level."""
 702         return len(self.list_indents) and self.list_indents[-1]
 703 
 704 
 705     def _indent_to(self, new_level, list_type, numtype, numstart):
 706         """Close and open lists."""
 707         open = []   # don't make one out of these two statements!
 708         close = []
 709 
 710 
 711         if self._indent_level() != new_level and self.in_table:
 712             tag=self.formatter.table(0)
 713             if tag:
 714                 close.append(tag)
 715             self.in_table = 0
 716         #    #self._close_item(close)
 717         #else:
 718         #    if not self.line_was_empty:
 719         #        self.inhibit_p = 1
 720     
 721         # Close lists while char-wise indent is greater than the current one
 722         while ((self._indent_level() > new_level) or
 723                ( new_level and
 724                 (self._indent_level() == new_level) and
 725                 (self.list_types[-1]) != list_type)):
 726             self._close_item(close)
 727             if self.list_types[-1] == 'ol':
 728                 tag = self.formatter.number_list(0)
 729             elif self.list_types[-1] == 'dl':
 730                 tag = self.formatter.definition_list(0)
 731             else:
 732                 tag = self.formatter.bullet_list(0)
 733             if tag:
 734                 close.append(tag)
 735 
 736             del(self.list_indents[-1])
 737             del(self.list_types[-1])
 738             
 739             #if new_level:
 740             #    self.inhibit_p = 1
 741             #else:
 742             #    self.inhibit_p = 0
 743 
 744             if self.list_types: # we are still in a list
 745                 if self.list_types[-1] == 'dl':
 746                     self.in_dd = 1
 747                 else:
 748                     self.in_li = 1
 749                 
 750         # Open new list, if necessary
 751         if self._indent_level() < new_level:
 752                     
 753             self.list_indents.append(new_level)
 754             self.list_types.append(list_type)
 755 
 756             if self.formatter.in_p:
 757                 tag=self.formatter.paragraph(0)
 758                 if tag:
 759                     close.append(tag)
 760             
 761             if list_type == 'ol':
 762                 tag = self.formatter.number_list(1, numtype, numstart)
 763             elif list_type == 'dl':
 764                 tag = self.formatter.definition_list(1)
 765             else:
 766                 tag = self.formatter.bullet_list(1)
 767             if tag:    
 768                 open.append(tag)
 769             
 770             self.first_list_item = 1
 771             ## Maybe this prevent p creation in lists?
 772             ##self.inhibit_p = 1
 773             self.in_li = 0
 774             self.in_dd = 0
 775         # If list level changes, close an open table
 776         if self.in_table and (open or close):
 777             tag=self.formatter.table(0)
 778             if tag:
 779                 close[0:0] = []
 780             self.in_table = 0
 781         
 782         ## Maybe this prevent p creation in lists?
 783         ##self.inhibit_p = bool(self.list_types)
 784 
 785         return ''.join(close) + ''.join(open)
 786 
 787 
 788     def _undent(self):
 789         """Close all open lists."""
 790         result = []
 791         #result.append("<!-- _undent start -->\n")
 792         self._close_item(result)
 793         for type in self.list_types:
 794             if type == 'ol':
 795                 result.append(self.formatter.number_list(0))
 796             elif type == 'dl':
 797                 result.append(self.formatter.definition_list(0))
 798             else:
 799                 result.append(self.formatter.bullet_list(0))
 800         #result.append("<!-- _undent end -->\n")
 801         self.list_indents = []
 802         self.list_types = []
 803         return ''.join(result)
 804 
 805 
 806     def _tt_repl(self, word):
 807         """Handle inline code."""
 808         self._check_p()
 809         
 810         return self.formatter.code(1) + \
 811             self.formatter.text(word[3:-3]) + \
 812             self.formatter.code(0)
 813 
 814 
 815     def _tt_bt_repl(self, word):
 816         """Handle backticked inline code."""
 817         if len(word) == 2: return ""
 818         self._check_p()
 819 #RS word
 820 #            self.highlight_text(word[1:-1],pure=1) + \
 821         return self.formatter.code(1) + \
 822             self.formatter.text(word[1:-1]) + \
 823             self.formatter.code(0)
 824 #RS end
 825 
 826 
 827     def _getTableAttrs(self, attrdef):
 828         # skip "|" and initial "<"
 829         while attrdef and attrdef[0] == "|":
 830             attrdef = attrdef[1:]
 831         if not attrdef or attrdef[0] != "<":
 832             return {}, ''
 833         attrdef = attrdef[1:]
 834 
 835         # extension for special table markup
 836         def table_extension(key, parser, attrs, wiki_parser=self):
 837             _ = wiki_parser._
 838             msg = ''
 839             if key[0] in "0123456789":
 840                 token = parser.get_token()
 841                 if token != '%':
 842                     wanted = '%'
 843                     msg = _('Expected "%(wanted)s" after "%(key)s", got "%(token)s"') % {
 844                         'wanted': wanted, 'key': key, 'token': token}
 845                 else:
 846                     try:
 847                         dummy = int(key)
 848                     except ValueError:
 849                         msg = _('Expected an integer "%(key)s" before "%(token)s"') % {
 850                             'key': key, 'token': token}
 851                     else:
 852                         attrs['width'] = '"%s%%"' % key
 853             elif key == '-':
 854                 arg = parser.get_token()
 855                 try:
 856                     dummy = int(arg)
 857                 except ValueError:
 858                     msg = _('Expected an integer "%(arg)s" after "%(key)s"') % {
 859                         'arg': arg, 'key': key}
 860                 else:
 861                     attrs['colspan'] = '"%s"' % arg
 862             elif key == '|':
 863                 arg = parser.get_token()
 864                 try:
 865                     dummy = int(arg)
 866                 except ValueError:
 867                     msg = _('Expected an integer "%(arg)s" after "%(key)s"') % {
 868                         'arg': arg, 'key': key}
 869                 else:
 870                     attrs['rowspan'] = '"%s"' % arg
 871             elif key == '(':
 872                 attrs['align'] = '"left"'
 873             elif key == ':':
 874                 attrs['align'] = '"center"'
 875             elif key == ')':
 876                 attrs['align'] = '"right"'
 877             elif key == '^':
 878                 attrs['valign'] = '"top"'
 879             elif key == 'v':
 880                 attrs['valign'] = '"bottom"'
 881             elif key == '#':
 882                 arg = parser.get_token()
 883                 try:
 884                     if len(arg) != 6: raise ValueError
 885                     dummy = int(arg, 16)
 886                 except ValueError:
 887                     msg = _('Expected a color value "%(arg)s" after "%(key)s"') % {
 888                         'arg': arg, 'key': key}
 889                 else:
 890                     attrs['bgcolor'] = '"#%s"' % arg
 891             else:
 892                 msg = None
 893             #print "key: %s\nattrs: %s" % (key, str(attrs))
 894             return msg
 895 
 896         # scan attributes
 897         attr, msg = wikiutil.parseAttributes(self.request, attrdef, '>', table_extension)
 898         if msg: msg = '<strong class="highlight">%s</strong>' % msg
 899         #print attr
 900         return attr, msg
 901 
 902     def _tableZ_repl(self, word):
 903         """Handle table row end."""
 904         if self.in_table:
 905             result = ''
 906             # REMOVED: check for self.in_li, p should always close
 907             if self.formatter.in_p:
 908                 result = self.formatter.paragraph(0)
 909             result += self.formatter.table_cell(0) + self.formatter.table_row(0)
 910             return result
 911         else:
 912             return word
 913 
 914 
 915     def _table_repl(self, word):
 916         """Handle table cell separator."""
 917         if self.in_table:
 918             result = []
 919             # check for attributes
 920             attrs, attrerr = self._getTableAttrs(word)
 921 
 922             # start the table row?
 923             if self.table_rowstart:
 924                 self.table_rowstart = 0
 925                 result.append(self.formatter.table_row(1, attrs))
 926             else:
 927                 # Close table cell, first closing open p
 928                 # REMOVED check for self.in_li, paragraph should close always!
 929                 if self.formatter.in_p:
 930                     result.append(self.formatter.paragraph(0))
 931                 result.append(self.formatter.table_cell(0))
 932 
 933             # check for adjacent cell markers
 934             if word.count("|") > 2:
 935                 if not attrs.has_key('align'):
 936                     attrs['align'] = '"center"'
 937                 if not attrs.has_key('colspan'):
 938                     attrs['colspan'] = '"%d"' % (word.count("|")/2)
 939 
 940             # return the complete cell markup
 941             result.append(self.formatter.table_cell(1, attrs) + attrerr)         
 942             return ''.join(result) 
 943         else:
 944             return word
 945 
 946 
 947     def _heading_repl(self, word):
 948         """Handle section headings."""
 949         import sha
 950 
 951         ##self.inhibit_p = 1
 952 
 953         h = word.strip()
 954         level = 1
 955         while h[level:level+1] == '=':
 956             level = level+1
 957         depth = min(5,level)
 958 
 959         # this is needed for Included pages
 960         # TODO but it might still result in unpredictable results
 961         # when included the same page multiple times
 962         title_text = h[level:-level].strip()
 963         pntt = self.formatter.page.page_name + title_text
 964         self.titles.setdefault(pntt, 0)
 965         self.titles[pntt] += 1
 966 
 967         unique_id = ''
 968         if self.titles[pntt] > 1:
 969             unique_id = '-%d' % self.titles[pntt]
 970         result = self._closeP()
 971         result += self.formatter.heading(1, depth, id="head-"+sha.new(pntt.encode(config.charset)).hexdigest()+unique_id)
 972                                      
 973         return (result + self.formatter.text(title_text) +
 974                 self.formatter.heading(0, depth))
 975     
 976     def _processor_repl(self, word):
 977         """Handle processed code displays."""
 978 #RS debug
 979         if _debug:
 980             print "request processor",word
 981 #RS end
 982         if word[:3] == '{{{': word = word[3:]
 983 
 984         self.processor = None
 985         self.processor_name = None
 986         self.processor_is_parser = 0
 987         s_word = word.strip()
 988         if s_word == '#!':
 989             # empty bang paths lead to a normal code display
 990             # can be used to escape real, non-empty bang paths
 991             word = ''
 992             self.in_pre = 3
 993             return self._closeP() + self.formatter.preformatted(1)
 994         elif s_word[:2] == '#!':
 995             # first try to find a processor for this (will go away in 1.4)
 996             processor_name = s_word[2:].split()[0]
 997             self.processor = wikiutil.importPlugin(
 998                 self.request.cfg, "processor", processor_name, "process")
 999             # now look for a parser with that name
1000             if self.processor is None:
1001                 self.processor = wikiutil.importPlugin(
1002                     self.request.cfg, "parser", processor_name, "Parser")
1003                 if self.processor:
1004                     self.processor_is_parser = 1
1005 
1006         if self.processor:
1007             self.processor_name = processor_name
1008             self.in_pre = 2
1009             self.colorize_lines = [word]
1010             return ''
1011         elif s_word:
1012             self.in_pre = 3
1013             return self._closeP() + self.formatter.preformatted(1) + \
1014                    self.formatter.text(s_word + ' (-)')
1015         else:
1016             self._check_p()
1017 #RS 1.1
1018             self.in_pre = 1
1019 #            self.in_pre = word and 1 or 3
1020             return ''
1021 #RS end
1022 
1023     def _pre_repl(self, word):
1024         """Handle code displays."""
1025         word = word.strip()
1026         if word == '{{{' and not self.in_pre:
1027             self.in_pre = 3
1028             ##self.inhibit_p = 1
1029             return self._closeP() + self.formatter.preformatted(self.in_pre)
1030         elif word == '}}}' and self.in_pre:
1031             self.in_pre = 0
1032             self.inhibit_p = 0
1033             return self.formatter.preformatted(self.in_pre)
1034 
1035 #RS word
1036 ##        return word
1037         return self.formatter.pure(word)
1038 #RS end
1039 
1040 
1041     def _smiley_repl(self, word):
1042         """Handle smileys."""
1043         self._check_p()
1044         return self.formatter.smiley(word)
1045 
1046     _smileyA_repl = _smiley_repl
1047 
1048 
1049     def _comment_repl(self, word):
1050         return ''
1051 
1052     def _closeP(self):
1053         if self.formatter.in_p:
1054             return self.formatter.paragraph(0)
1055         return ''
1056         
1057     def _macro_repl(self, word):
1058         """Handle macros ([[macroname]])."""
1059         self._check_p()
1060         macro_name = word[2:-2]
1061         #self.inhibit_p = 1 # fixes UserPreferences, but makes new trouble!
1062 
1063         # check for arguments
1064         args = None
1065         if macro_name.count("("):
1066             macro_name, args = macro_name.split('(', 1)
1067             args = args[:-1]
1068 
1069         # create macro instance
1070         if self.macro is None:
1071             self.macro = wikimacro.Macro(self)
1072 
1073         # call the macro
1074 #RS word
1075         self.oldformatter=self.formatter
1076 #        print "Before Macro: %s" % (str(vars(self)))
1077 
1078 ##        return self.formatter.macro(self.macro, macro_name, args)
1079         try:
1080             result=self.formatter.macro(self.macro, macro_name, args)
1081         except:
1082             result='<error executing macro %s>' % macro_name
1083             raise
1084 #        print "After Macro: %s" % (str(vars(self)))
1085         self.formatter=self.oldformatter
1086         return result
1087 
1088         return self.formatter.macro(self.macro, macro_name, args)
1089 #RS end
1090 
1091     def scan(self, scan_re, line):
1092         """ Scans one line
1093         
1094         Append text before match, invoke replace() with match, and 
1095         add text after match.
1096         """
1097         result = []
1098         lastpos = 0
1099 
1100         ###result.append(u'<span class="info">[scan: <tt>"%s"</tt>]</span>' % line)
1101         if _debug:
1102             try:
1103                 print "\n  SCAN BEGIN :%s:" % line
1104             except UnicodeEncodeError,e:
1105                 print "\n  SCAN BEGIN, line has unicode problem: %s" % e
1106         old_lastpos=lastpos-1
1107         for match in scan_re.finditer(line):
1108             if old_lastpos==lastpos:
1109                 #emergency break?
1110                 break
1111             # Add text before the match
1112             if lastpos < match.start():
1113                 
1114                 ###result.append(u'<span class="info">[add text before match: <tt>"%s"</tt>]</span>' % line[lastpos:match.start()])
1115                 
1116                 if not (self.inhibit_p or self.in_pre or self.formatter.in_p):
1117                     result.append(self.formatter.paragraph(1))
1118                 result.append(self.formatter.text(line[lastpos:match.start()]))
1119             
1120             # Replace match with markup
1121             result.append(self.replace(match))
1122             old_lastpos=lastpos
1123             lastpos = match.end()
1124         if _debug:
1125             try:
1126                 print "\n  SCAN END :%s:" % line
1127             except UnicodeEncodeError,e:
1128                 print "\n  SCAN END, line has unicode problem: %s" % e
1129         
1130         ###result.append('<span class="info">[no match, add rest: <tt>"%s"<tt>]</span>' % line[lastpos:])
1131         
1132         # No match: Add paragraph with the text of the line
1133         if not (self.in_pre or self.inhibit_p or
1134                 self.formatter.in_p) and lastpos < len(line):
1135             result.append(self.formatter.paragraph(1))
1136         result.append(self.formatter.text(line[lastpos:]))
1137         if _debug:
1138                 print "\n  SCAN result :%s:" % result
1139         
1140         return u''.join(result)
1141 
1142     def highlight_text(self, text, **kw):
1143 #RS obsolete
1144         return ''
1145         if kw.get('flow', 1): self._check_p()
1146 #RS word
1147 ##        if not self.hilite_re: return self.formatter.text(text)
1148         if not self.hilite_re:
1149             if kw.get('pure', 0):
1150                 return self.formatter.pure(text)
1151             else:
1152                 return self.formatter.text(text)
1153         return "$HI"+text+"$"
1154 #RS end
1155         result = []
1156         lastpos = 0
1157         match = self.hilite_re.search(text)
1158         while match and lastpos < len(text):
1159             # add the match we found
1160             result.append(self.formatter.text(text[lastpos:match.start()]))
1161             result.append(self.formatter.highlight(1))
1162             result.append(self.formatter.text(match.group(0)))
1163             result.append(self.formatter.highlight(0))
1164 
1165             # search for the next one
1166             lastpos = match.end() + (match.end() == lastpos)
1167             match = self.hilite_re.search(text, lastpos)
1168 
1169         result.append(self.formatter.text(text[lastpos:]))
1170         return string.join(result, '')
1171 
1172     def highlight_scan(self, scan_re, line):
1173 #RS obsolete
1174         return ''
1175         result = []
1176         lastpos = 0
1177         match = scan_re.search(line)
1178         while match and lastpos < len(line):
1179             # add the match we found
1180 #RS word
1181 ##            result.append(self.highlight_text(line[lastpos:match.start()]))
1182             result.append(self.highlight_text(line[lastpos:match.start()],pure=0))
1183 #RS end
1184             result.append(self.replace(match))
1185 
1186             # search for the next one
1187             lastpos = match.end() + (match.end() == lastpos)
1188             match = scan_re.search(line, lastpos)
1189 
1190         result.append(self.highlight_text(line[lastpos:]))
1191         return string.join(result, '')
1192 
1193 
1194     def replace(self, match):
1195         """ Replace match using type name """
1196         result = []
1197 #RS debug
1198 #        if _debug:
1199 #            print "\n REPLACE: match groups Xx%sxX\n" % (str(match.groupdict()))
1200 #RS end
1201         for type, hit in match.groupdict().items():
1202             if hit is not None and type != "hmarker":
1203 #RS debug
1204                 if _debug:
1205                         print "\n  ###", wikiutil.escape(`type`)," # ", wikiutil.escape(`hit`), "###"
1206 #RS end
1207                 if self.in_pre and type not in ['pre', 'ent']:
1208                     return self.formatter.text(hit) 
1209 #RS end
1210                 else:
1211                     # Open p for certain types
1212                     if not (self.inhibit_p or self.formatter.in_p
1213                             or self.in_pre or (type in self.no_new_p_before)):
1214                         result.append(self.formatter.paragraph(1))
1215                     # Get replace method and replece hit
1216                     replace = getattr(self, '_' + type + '_repl')
1217                     result.append(replace(hit))
1218                     return ''.join(result)
1219 
1220         else:
1221             # We should never get here
1222             import pprint
1223             raise Exception("Can't handle match " + `match`
1224                 + "\n" + pprint.pformat(match.groupdict())
1225                 + "\n" + pprint.pformat(match.groups()) )
1226 #RS word
1227 ##        return ""
1228         return u"§NOREP§"
1229 #RS end
1230 
1231 
1232     def format(self, formatter):
1233         """ For each line, scan through looking for magic
1234             strings, outputting verbatim any intervening text.
1235         """
1236         self.formatter = formatter
1237         self.hilite_re = self.formatter.page.hilite_re
1238 
1239         # prepare regex patterns
1240         rules = self.formatting_rules.replace('\n', '|')
1241         if self.cfg.allow_extended_names:
1242 #RS word
1243 #            rules = rules + ur'|(?P<wikiname_bracket>\[".*?"\])'
1244             rules = ur'(?P<wikiname_bracket>\[".*?"\])|' + rules
1245 #RS stop
1246         if self.cfg.bang_meta:
1247             rules = ur'(?P<notword>!%(word_rule)s)|%(rules)s' % {
1248                 'word_rule': self.word_rule,
1249                 'rules': rules,
1250             }
1251         if self.cfg.backtick_meta:
1252             rules = rules + ur'|(?P<tt_bt>`.*?`)'
1253         if self.cfg.allow_numeric_entities:
1254             rules = ur'(?P<ent_numeric>&#\d{1,5};)|' + rules
1255 
1256 #RS debug
1257 #        if _debug:
1258 #            print u"\nRULE:%s:" % str(rules)
1259 #RS end
1260 
1261         self.request.clock.start('compile_huge_and_ugly')        
1262         scan_re = re.compile(rules, re.UNICODE)
1263         number_re = re.compile(self.ol_rule, re.UNICODE)
1264         term_re = re.compile(self.dl_rule, re.UNICODE)
1265         indent_re = re.compile("^\s*", re.UNICODE)
1266         eol_re = re.compile(r'\r?\n', re.UNICODE)
1267         self.request.clock.stop('compile_huge_and_ugly')        
1268 
1269         # get text and replace TABs
1270         rawtext = self.raw.expandtabs()
1271 
1272         # go through the lines
1273         self.lineno = 0
1274         self.lines = eol_re.split(rawtext)
1275         self.line_is_empty = 0
1276 
1277         # Main loop
1278         for line in self.lines:
1279             self.lineno = self.lineno + 1
1280             if _max_lineno>=0 and self.lineno>_max_lineno:
1281                 break
1282             self.table_rowstart = 1
1283             self.line_was_empty = self.line_is_empty
1284             self.line_is_empty = 0
1285             self.first_list_item = 0
1286             self.inhibit_p = 0
1287 
1288             if self.in_pre:
1289                 # TODO: move this into function
1290                 # still looking for processing instructions
1291                 # TODO: use strings for pre state, not numbers
1292                 if self.in_pre == 1:
1293                     self.processor = None
1294                     self.processor_is_parser = 0
1295                     processor_name = ''
1296                     if (line.strip()[:2] == "#!"):
1297                         processor_name = line.strip()[2:].split()[0]
1298                         self.processor = wikiutil.importPlugin(
1299                             self.request.cfg, "processor", processor_name, "process")
1300                                                                
1301                         # now look for a parser with that name
1302                         if self.processor is None:
1303                             self.processor = wikiutil.importPlugin(
1304                                 self.request.cfg, "parser", processor_name, "Parser") 
1305                             if self.processor:
1306                                 self.processor_is_parser = 1
1307                     if self.processor:
1308                         self.in_pre = 2
1309                         self.colorize_lines = [line]
1310                         self.processor_name = processor_name
1311                         continue
1312                     else:
1313                         self.request.write(self._closeP() +
1314                                            self.formatter.preformatted(1))
1315                         self.in_pre = 3
1316                 if self.in_pre == 2:
1317                     # processing mode
1318                     endpos = line.find("}}}")
1319                     if endpos == -1:
1320                         self.colorize_lines.append(line)
1321                         continue
1322                     if line[:endpos]:
1323                         self.colorize_lines.append(line[:endpos])
1324                     
1325                     # Close p before calling processor
1326                     # TODO: do we really need this?
1327                     self.request.write(self._closeP())
1328 #RS debug
1329                     if _debug:
1330                         print "\n   PROCESSOR :%s:\n" % self.processor_name
1331 #RS end
1332                     res = self.formatter.processor(self.processor_name,
1333                                                    self.colorize_lines, 
1334                                                    self.processor_is_parser)
1335                     self.request.write(res)
1336                     del self.colorize_lines
1337                     self.in_pre = 0
1338                     self.processor = None
1339 
1340                     # send rest of line through regex machinery
1341                     line = line[endpos+3:]                    
1342             else:
1343                 # we don't have \n as whitespace any more
1344                 # This is the space between lines we join to one paragraph
1345                 line = line + ' '
1346                 
1347                 # Paragraph break on empty lines
1348                 if not line.strip():
1349                     if self.in_table:
1350 #RS debug
1351                         if _debug:
1352                             print "\n   TABLE OFF\n"
1353 #RS end
1354                         self.request.write(self.formatter.table(0))
1355                         self.in_table = 0
1356                     # CHANGE: removed check for not self.list_types
1357                     # p should close on every empty line
1358                     if (self.formatter.in_p):
1359 #RS debug
1360                         if _debug:
1361                             print "\n   PARAGRAPH OFF (A)\n"
1362 #RS end
1363                         self.request.write(self.formatter.paragraph(0))
1364                     self.line_is_empty = 1
1365                     continue
1366 
1367                 # Check indent level
1368                 indent = indent_re.match(line)
1369                 indlen = len(indent.group(0))
1370                 indtype = "ul"
1371                 numtype = None
1372                 numstart = None
1373 #RS debug
1374 #                if _debug:
1375 #                    print "\n INDENT:%s:" % (str(indent))
1376 #RS end
1377                 if indlen:
1378                     match = number_re.match(line)
1379                     if match:
1380                         numtype, numstart = match.group(0).strip().split('.')
1381                         numtype = numtype[0]
1382 
1383                         if numstart and numstart[0] == "#":
1384                             numstart = int(numstart[1:])
1385                         else:
1386                             numstart = None
1387 
1388                         indtype = "ol"
1389                     else:
1390                         match = term_re.match(line)
1391                         if match:
1392                             indtype = "dl"
1393 
1394                 # output proper indentation tags
1395                 self.request.write(self._indent_to(indlen, indtype, numtype,
1396                                                    numstart))
1397 
1398                 # Table mode
1399                 # TODO: move into function?                
1400                 if (not self.in_table and line[indlen:indlen + 2] == "||"
1401                     and line[-3:] == "|| " and len(line) >= 5 + indlen):
1402                     # Start table
1403                     if self.list_types and not self.in_li:
1404 #RS debug
1405                         if _debug:
1406                             print "\n   LISTITEM ON\n"
1407 #RS end
1408                         self.request.write(self.formatter.listitem
1409                                            (1, style="list-style-type:none"))
1410                         ## CHANGE: no automatic p on li
1411                         ##self.request.write(self.formatter.paragraph(1))
1412                         self.in_li = 1
1413                         
1414                     # CHANGE: removed check for self.in_li
1415                     # paragraph should end before table, always!
1416                     if self.formatter.in_p:
1417 #RS debug
1418                         if _debug:
1419                             print "\n   PARAGRAPH OFF (B)\n"
1420 #RS end
1421                         self.request.write(self.formatter.paragraph(0))
1422                     attrs, attrerr = self._getTableAttrs(line[indlen+2:])
1423 #RS debug
1424                     if _debug:
1425                         print "\n   TABLE ON (B)\n"
1426 #RS end
1427                     self.request.write(self.formatter.table(1, attrs) + attrerr)
1428                     self.in_table = True # self.lineno
1429                 elif (self.in_table and not
1430                       # intra-table comments should not break a table
1431                       (line[:2]=="##" or  
1432                        line[indlen:indlen + 2] == "||" and
1433                        line[-3:] == "|| " and
1434                        len(line) >= 5 + indlen)):
1435                     
1436                     # Close table
1437 #RS debug
1438                     if _debug:
1439                         print "\n   TABLE OFF (B)\n"
1440 #RS end
1441                     self.request.write(self.formatter.table(0))
1442                     self.in_table = 0
1443                                             
1444             # Scan line, format and write
1445             formatted_line = self.scan(scan_re, line)
1446             self.request.write(formatted_line)
1447 
1448             if self.in_pre:
1449 #RS debug
1450                 if _debug:
1451                     print "\n   LINEBREAK in_pre\n"
1452 #RS end
1453                 self.request.write(self.formatter.linebreak())
1454 
1455         # Close code displays, paragraphs, tables and open lists
1456         self.request.write(self._undent())
1457         if self.in_pre:
1458 #RS debug
1459             if _debug:
1460                 print "\n   PRE OFF (C)\n"
1461 #RS end
1462             self.request.write(self.formatter.preformatted(0))
1463         if self.formatter.in_p:
1464 #RS debug
1465             if _debug:
1466                 print "\n   PARAGRAPH OFF (C)\n"
1467 #RS end
1468             self.request.write(self.formatter.paragraph(0))
1469         if self.in_table:
1470 #RS debug
1471             if _debug:
1472                 print "\n   TABLE OFF (C)\n"
1473 #RS end
1474             self.request.write(self.formatter.table(0))

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.
  • [get | view] (2005-10-24 16:41:36, 3.6 KB) [[attachment:FrontPage.pdf]]
  • [get | view] (2005-10-20 23:45:56, 124.5 KB) [[attachment:SyntaxReference.doc]]
  • [get | view] (2005-10-20 23:27:53, 19.0 KB) [[attachment:moin_export.py]]
  • [get | view] (2005-10-24 14:06:32, 3.9 KB) [[attachment:request_ors.py]]
  • [get | view] (2005-10-27 14:27:18, 81.6 KB) [[attachment:text_pdf.py]]
  • [get | view] (2005-10-20 23:29:45, 66.2 KB) [[attachment:text_word.py]]
  • [get | view] (2005-11-03 17:30:17, 53.9 KB) [[attachment:wiki_word.py]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.