Attachment 'linuxmagazin.py'

Download

   1 """
   2     MoinMoin - Linux-Magazin Artikel Parser
   3 
   4     Copyright (c) 2002 by Jürgen Hermann <jh@web.de>
   5 
   6     Siehe http://www.linux-magazin.de/Info/Hinweise/Format.html
   7     für Details zum hier unterstützten Format.
   8 """
   9 
  10 import re
  11 
  12 
  13 class Parser:
  14     """ Parser für das "Autoren-Format" des Linux-Magazins.
  15     """
  16 
  17     PARA_SECTIONS = ('L', 'KL', 'IL')
  18 
  19     def __init__(self, raw, request, **kw):
  20         self.raw = raw
  21         self.request = request
  22         self.metadata = {}
  23 
  24         self.request.setPragma('section-numbers', 'off')
  25 
  26     def format(self, formatter):
  27         """ Den Text formatiert ausgeben.
  28         """
  29         self.formatter = formatter
  30         self.formatter._base_depth = 1
  31 
  32         # Text in Zeilen aufbereiten
  33         text = self.raw
  34         text = text.expandtabs()
  35         text = [line.rstrip() for line in text.splitlines()]
  36 
  37         # Zeilen zu Abschnitten verarbeiten
  38         sections = []
  39         collecting = 0
  40         for line in text:
  41             if not line:
  42                 if collecting and sections[-1][0] in ('LI',):
  43                     # Leerzeilen in Listings sammeln
  44                     sections[-1][1].append(line)
  45                 else:    
  46                     # Ende des Abschnitts
  47                     collecting = 0
  48             elif line[0] == "@":
  49                 # Kennung verarbeiten
  50                 try:
  51                     sect, line = line[1:].split(':', 1)
  52                 except ValueError:
  53                     sect = 'L'
  54                 if sect == '#': continue
  55                 sections.append((sect, [line]))
  56                 collecting = 1
  57             else:
  58                 # Fließtext
  59                 if not sections:
  60                     sections.append(('L', []))
  61                 elif not collecting:
  62                     sections.append((sections[-1][0], []))
  63                 collecting = 1
  64                 sections[-1][1].append(line)
  65 
  66         # Listen erkennen, Kasten einsammeln
  67         idx = 0
  68         while idx < len(sections):
  69             if sections[idx][0] in self.PARA_SECTIONS and sections[idx][1][0].startswith('* '):
  70                 base = idx
  71                 sections[base] = ('_UL', [' '.join(sections[base][1])[2:]])
  72                 idx += 1
  73                 while idx < len(sections) and sections[idx][0] in self.PARA_SECTIONS and sections[idx][1][0].startswith('* '):
  74                     sections[base][1].append(' '.join(sections[idx][1])[2:])
  75                     idx += 1
  76                 sections[base+1:idx] = []
  77                 idx = base+1
  78             else:
  79                 idx += 1                
  80         idx = 0
  81         while idx < len(sections):
  82             if sections[idx][0] == 'KT':
  83                 base = idx
  84                 while idx < len(sections) and sections[idx][0] not in ('L', 'KE'):
  85                     idx += 1
  86                 sections[base:idx] = [('_Kasten', sections[base:idx])]
  87             else:
  88                 idx += 1                
  89 
  90         # Abschnitte ausgeben
  91         self.output = []
  92         self.renderSections(sections)
  93 
  94         self.output[0:0] = ([
  95             self.formatter.heading(1, self.metadata['T']),
  96             self.formatter.heading(2, '%(D)s [%(R)s/%(SW)s]' % self.metadata),
  97             self.formatter.text('von '),
  98             self.formatter.strong(1),
  99             self.formatter.text(self.metadata['A']),
 100             self.formatter.strong(0),
 101         ])            
 102 
 103         self.request.write(''.join(self.output))
 104 
 105     def renderSections(self, sections):
 106         for section in sections:
 107             handler = getattr(self, '_render' + section[0], self._unknown)
 108             handler(section)
 109 
 110     def _inline(self, lines):
 111         "Inline-Markup verarbeiten"
 112         result = []
 113         flags = {'I': 0, 'B': 0, 'C': 0, '+': 0, '-': 0, 'U': 0}
 114         calls = {
 115             'I': self.formatter.emphasis,
 116             'B': self.formatter.strong,
 117             'C': self.formatter.code,
 118             '+': self.formatter.sup,
 119             '-': self.formatter.sub,
 120         }
 121         markup = filter(None, re.split(r'(<[IBC+-U]>)', ' '.join(lines)))
 122         for part in markup:
 123             if part.startswith('<'):
 124                 flags[part[1]] ^= 1
 125                 if part == '<U>':
 126                     if not flags['U']:
 127                         result.append(self.formatter.url(result[-1]))
 128                         result[-2] = self.formatter.text('[')
 129                         result.append(self.formatter.text(']'))
 130                 else:
 131                     result.append(calls[part[1]](flags[part[1]]))
 132             else:
 133                 result.append(self.formatter.text(part))
 134         return result
 135 
 136     def _paragraph(self, lines):
 137         return ['\n', self.formatter.paragraph(1)] + \
 138             self._inline(lines) + [self.formatter.paragraph(0), '\n']
 139 
 140     def _unknown(self, section):
 141         self.output.append(self.formatter.sysmsg('Unbekannter Absatztyp "%s"' % section[0]))
 142         self.output.extend(self._paragraph(section[1]))
 143 
 144     def _meta(self, section):
 145         self.metadata[section[0]] = '\n'.join(section[1])
 146 
 147     _renderR = _meta # Rubrik
 148     _renderSW = _meta # Schlagwort
 149     _renderD = _meta # Dachzeile
 150     _renderT = _meta # Titel
 151     _renderA = _meta # Autor
 152 
 153     def _renderV(self, section):
 154         "Vorspann"
 155         para = self._paragraph(section[1])
 156         para.insert(2, self.formatter.emphasis(1))
 157         para.insert(len(para)-2, self.formatter.emphasis(0))
 158         para.append(self.formatter.rule())
 159         self.output.extend(para)
 160 
 161     def _render_UL(self, section):
 162         self.output.append(self.formatter.bullet_list(1))
 163         for item in section[1]:
 164             self.output.append(self.formatter.listitem(1))
 165             self.output.extend(self._inline([item]))
 166             self.output.append(self.formatter.listitem(0))
 167         self.output.append(self.formatter.bullet_list(0))
 168 
 169     def _renderL(self, section):
 170         "Lauftext"
 171         self.output.extend(self._paragraph(section[1]))
 172 
 173     def _render_Kasten(self, section):
 174         self.output.extend([
 175             self.formatter.paragraph(1),
 176             self.formatter.table(1),
 177             self.formatter.table_row(1),
 178             self.formatter.table_cell(1, attrs={'bgcolor': '#E8E8E8'}),
 179         ])
 180         self.renderSections(section[1])
 181         self.output.extend([
 182             self.formatter.table_cell(0),
 183             self.formatter.table_row(0),
 184             self.formatter.table(0),
 185             self.formatter.paragraph(0),
 186         ])
 187 
 188     def _renderKT(self, section):
 189         "Kastentitel"
 190         self.output.extend([
 191             self.formatter.strong(1),
 192             self.formatter.text('\n'.join(section[1])),
 193             self.formatter.strong(0),
 194             self.formatter.linebreak(0),
 195         ])
 196 
 197     _renderKL = _renderL
 198 
 199     def _renderKE(self, section):
 200         "Kastenende"
 201 
 202     def _renderZT(self, section):
 203         "Zwischentitel"
 204         self.output.append(self.formatter.heading(2, ' '.join(section[1])))
 205 
 206     def _renderLI(self, section):
 207         "Listing"
 208         self.output.extend([
 209             self.formatter.preformatted(1),
 210             self.formatter.text('\n'.join(section[1])),
 211             self.formatter.preformatted(0),
 212         ])
 213 
 214     def _renderBi(self, section):
 215         "Bild"
 216         from MoinMoin.action.AttachFile import getAttachUrl
 217 
 218         self.output.extend([
 219             self.formatter.paragraph(1),
 220             self.formatter.table(1),
 221             self.formatter.table_row(1),
 222             self.formatter.table_cell(1, attrs={'bgcolor': '#E8E8E8'}),
 223         ])
 224         ##self.output.append(self.formatter.rule())
 225         self.output.append(self.formatter.url(getAttachUrl(self.formatter.page.page_name, section[1][0])))
 226         
 227     def _renderB(self, section):
 228         "Bildunterschrift"
 229         self.output.extend([
 230             ##self.formatter.rule(),
 231             self.formatter.linebreak(0),
 232             self.formatter.strong(1),
 233             self.formatter.text('\n'.join(section[1])),
 234             self.formatter.strong(0),
 235             self.formatter.table_cell(0),
 236             self.formatter.table_row(0),
 237             self.formatter.table(0),
 238             self.formatter.paragraph(0),
 239         ])
 240 
 241     def _renderIT(self, section):
 242         "Infotitel"
 243         self.output.append(self.formatter.heading(2, ' '.join(section[1])))
 244 
 245     _renderIL = _renderL
 246     _renderIE = _renderKE

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] (2003-12-07 18:15:55, 1.8 KB) [[attachment:diff2.py]]
  • [get | view] (2003-12-07 18:15:55, 8.2 KB) [[attachment:linuxmagazin.py]]
 All files | Selected Files: delete move to page copy to page

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