1 """
   2     MoinMoin - "text/latex" Formatter
   3 
   4     Copyright 2005-2007 Johannes Berg <johannes@sipsolutions.net>
   5     Copyright (c) 2003 by João Neves <moin@silvaneves.org>
   6     Copyright (c) 2000, 2001, 2002 by Jürgen Hermann <jh@web.de>
   7 
   8     If you want to have the latex formatter easily accessible from
   9     the actions menu, add add this code to a file called LatexOutput.py
  10     in your actions plugin directory:
  11 ---->%---->%----
  12 # -*- coding: iso-8859-1 -*-
  13 
  14 from MoinMoin.Page import Page
  15 from MoinMoin.request import MoinMoinFinish
  16 from MoinMoin import wikiutil
  17 
  18 def execute(pagename, request):
  19     url = Page(request, pagename).url(request,
  20                                       {'action': 'format',
  21                                        'mimetype': 'text_latex'},
  22                                       relative=False)
  23     request.http_redirect(url)
  24 ----%<----%<----
  25 
  26     @copyright: GPL v2
  27 """
  28 
  29 # Imports
  30 
  31 import sys, re
  32 
  33 # get an exception? see below
  34 from MoinMoin.formatter.base import FormatterBase
  35 # for 1.6:
  36 # from MoinMoin.formatter import FormatterBase
  37 
  38 from MoinMoin.Page import Page
  39 
  40 #############################################################################
  41 ### LaTeX Formatter
  42 #############################################################################
  43 
  44 class Formatter(FormatterBase):
  45     """
  46         Send text data.
  47     """
  48 
  49     hardspace = ' '
  50 
  51     def __init__(self, request, **kw):
  52         apply(FormatterBase.__init__, (self, request), kw)
  53         self.verbatim = False
  54         self.itemized = False
  55 
  56     def text2latex(self, text):
  57         "Escape special characters if not in verbatim mode"
  58         if self.verbatim: return text
  59         text = text.replace('\\', '$\\backslash$ ');
  60         text = text.replace('$', r'\$');
  61         text = text.replace(r'\$\backslash\$', r'$\backslash$')
  62         text = text.replace('#', '\#');
  63         text = text.replace('%', '\%');
  64         text = text.replace('^', '\^{}');
  65         text = text.replace('&', '\&');
  66         text = text.replace('_', '\_');
  67         text = text.replace('{', '\{');
  68         text = text.replace('}', '\}');
  69         text = text.replace('~', '\~{}');
  70         text = text.replace('"', '\"');
  71         return text
  72 
  73     def write_text(self, text):
  74       if self.item is None:
  75         return text
  76       else:
  77         self.item = (self.item[0], self.item[1]+text)
  78         return ''
  79 
  80     def startDocument(self, pagename):
  81         extra_preamble = ''
  82         preamble_page = self.request.pragma.get('latex_preamble', None)
  83         if preamble_page is not None:
  84           extra_preamble = Page(self.request, preamble_page).get_raw_body()
  85         extra_preamble = re.sub(re.compile('^#'), '%', extra_preamble)
  86         return """
  87 \\documentclass[a4paper,12pt]{article}
  88 
  89 \\usepackage[utf8]{inputenc}
  90 \\usepackage{helvet}
  91 \\usepackage{graphicx}
  92 \\usepackage{multicol}
  93 \\usepackage{fullpage}
  94 \\usepackage{fancyhdr}
  95 \\usepackage{hyperref}
  96 \\usepackage{multirow}
  97 \\makeatletter
  98 \\DeclareRobustCommand*\\textsubscript[1]{%%
  99   \\@textsubscript{\\selectfont#1}}
 100 \\def\\@textsubscript#1{%%
 101   {\\m@th\\ensuremath{_{\\mbox{\\fontsize\\sf@size\\z@#1}}}}}
 102 \\makeatother
 103 
 104 %% begin extra preamble inclusion %%
 105 %s
 106 
 107 %% end extra preamble inclusion %%
 108 
 109 \\title{%s}
 110 
 111 \\author{ }
 112 
 113 \\date{ }
 114 
 115 \\renewcommand{\\theenumi}{\\arabic{enumi}}
 116 \\renewcommand{\\theenumii}{\\arabic{enumi}.\\arabic{enumii}}
 117 \\renewcommand{\\theenumiii}{\\arabic{enumi}.\\arabic{enumii}.\\arabic{enumiii}}
 118 \\renewcommand{\\theenumiv}{\\arabic{enumi}.\\arabic{enumii}.\\arabic{enumiii}.\\arabic{enumiv}}
 119 
 120 \\begin{document}
 121 """ % (extra_preamble, pagename)
 122 
 123     def endDocument(self):
 124         return '\\end{document}\n'
 125 
 126     def sysmsg(self, text, **kw):
 127         return self.write_text('')
 128 
 129     def pagelink(self, on, pagename, text=None, **kw):
 130         return self.write_text('')
 131 
 132     def url(self, on, url=None, css=None, **kw):
 133         if not on:
 134             return self.write_text('}')
 135         url = url.replace('&', '\\&')
 136         return self.write_text('\\href{%s}{' % url)
 137 
 138     def text(self, text):
 139         return self.write_text(self.text2latex(text))
 140 
 141     def rule(self, size=0):
 142         size = min(size, 10)
 143         ch = "---~=*+#####"[size]
 144         return self.write_text('\\vrule \n')
 145 
 146     def strong(self, on):
 147         return self.write_text(['{\\bf ', '}'][not on])
 148 
 149     def emphasis(self, on):
 150         return self.write_text(['{\\em ', '}'][not on])
 151 
 152     def highlight(self, on):
 153         return self.write_text(['{\\tt ', '}'][not on])
 154 
 155     def number_list(self, on, type=None, start=None):
 156         self.itemized = on
 157         if on:
 158             text = "\\begin{enumerate}"
 159         else:
 160             text = '\\end{enumerate}\n'
 161         return self.write_text(text)
 162 
 163     def bullet_list(self, on):
 164         self.itemized = on
 165         return self.write_text(['\\begin{itemize}\n', '\n\\end{itemize}\n'][not on])
 166 
 167     def listitem(self, on, **kw):
 168         if not self.itemized: return ''
 169         self._in_li = on != 0
 170         if on:
 171             return self.write_text('\\item ')
 172         else:
 173             return ''
 174 
 175     def sup(self, on):
 176         return self.write_text(['\\textsuperscript{', '}'][not on])
 177 
 178     def sub(self, on):
 179         return self.write_text(['\\textsubscript{', '}'][not on])
 180 
 181     def code(self, on, **kw):
 182         return self.write_text(['{\\tt ', '}'][not on])
 183 
 184     def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1):
 185         res = self.preformatted(on)
 186         self.verbatim = False
 187         return self.write_text(res)
 188 
 189     def code_token(self, on, tok_type):
 190         return self.write_text('')
 191 
 192     def code_line(self, on):
 193         return self.write_text('\n')
 194 
 195     def preformatted(self, on):
 196         FormatterBase.preformatted(self, on)
 197         self.verbatim = on
 198         return self.write_text(['\\begin{verbatim}\n', '\\end{verbatim}\n'][not on])
 199 
 200     def smiley(self, text):
 201         return self.write_text(self.text2latex(text))
 202 
 203     def paragraph(self, on, **kw):
 204         FormatterBase.paragraph(self, on)
 205         return self.write_text(['', '\n\n'][not on])
 206 
 207     def linebreak(self, preformatted=1):
 208         if preformatted==1:
 209             return self.write_text('\n')
 210         else:
 211             return self.write_text('\\newline')
 212 
 213     def heading(self, on, depth, **kw):
 214         if depth == 1:
 215             rv = (r'\section{','}')
 216         elif depth == 2:
 217             rv = ('\\subsection{','}')
 218         elif depth == 3:
 219             rv = ('\\subsubsection{','}')
 220         else:
 221             rv = (r'\paragraph{','}',)
 222         return self.write_text(rv[not on])
 223 
 224     rows = []
 225     row = []
 226     item = None
 227 
 228     def table(self, on, attrs={}):
 229         def count_cols(row):
 230           cols = 0
 231           for cell in row:
 232             if cell[0].has_key('colspan'):
 233               cols += int(cell[0]['colspan'][1:-1])
 234             else:
 235               cols += 1
 236           return cols
 237 
 238         if on:
 239           self.rows = []
 240           self.item = None
 241           self.row = []
 242           return ''
 243         # not on:
 244         if self.rows == []: return ''
 245         cols = count_cols(self.rows[0])
 246         rows = len(self.rows)
 247         _table = [[0 for i in xrange(0,cols)] for j in xrange(0,rows)]
 248         _rownum = -1
 249         for _row in self.rows:
 250           _rownum += 1
 251           _cellnum = -1
 252           for _cell in _row:
 253             _cellnum += 1
 254 
 255             while _table[_rownum][_cellnum] is None or type(_table[_rownum][_cellnum]) == type(()):
 256               _cellnum += 1
 257 
 258             if _cell[0].get('rowspan') == '"1"':
 259               del _cell[0]['rowspan']
 260             if _cell[0].get('colspan') == '"1"':
 261               del _cell[0]['colspan']
 262 
 263             _rowspan = int(_cell[0].get('rowspan', '"1"')[1:-1])
 264             _colspan = int(_cell[0].get('colspan', '"1"')[1:-1])
 265 
 266             for j in xrange(0,_rowspan):
 267               for i in xrange(0,_colspan):
 268                 _table[_rownum+j][_cellnum+i] = None
 269               _table[_rownum+j][_cellnum] = ({'colspan':'"%d"'%_colspan},None)
 270             _table[_rownum][_cellnum] = _cell
 271 
 272 
 273         table = '\\begin{tabular}{|%s}\n' % (cols * 'l|')
 274         for _row in _table:
 275           row = ''
 276           cellnum = 0
 277           _lines = []
 278           _do_line = True
 279           for _cell in _row:
 280             cellnum+=1
 281             if _cell == 0:
 282               return 'INVALID TABLE'
 283             if _cell is None:
 284               if _do_line:
 285                 _lines += [cellnum]
 286               continue
 287             _rowspan = int(_cell[0].get('rowspan', '"1"')[1:-1])
 288             _colspan = int(_cell[0].get('colspan', '"1"')[1:-1])
 289             format = '%s'
 290             if not (_cell[1] is None):
 291               _do_line = True
 292               _lines += [cellnum]
 293             else:
 294               _do_line = False
 295               _cell = (_cell[0], u'')
 296             if _rowspan > 1:
 297               format = r'\multirow{%d}*{%%s}' % _rowspan
 298             if _colspan > 1:
 299               format = r'\multicolumn{%d}{|l|}{ %s }' % (_colspan, format)
 300             row += (format+' & ') % _cell[1].replace('\n',' ')
 301           for l in _lines:
 302             table += r'\cline{%d-%d}' % (l,l)
 303           table += row[0:-3] + '\\\\ \n'
 304         table += '\\hline\\end{tabular}\n\n'
 305         return table
 306 
 307 
 308     def table_row(self, on, attrs={}):
 309         if not on:
 310           self.rows += [self.row]
 311           self.row = []
 312         return ''
 313 
 314     def table_cell(self, on, attrs={}):
 315         if not on:
 316           self.row += [self.item]
 317           self.item = None
 318         else:
 319           self.item = (attrs,'')
 320         return ''
 321 
 322     def underline(self, on):
 323         return self.write_text(['\\underline{', '}'][not on])
 324 
 325     def definition_list(self, on):
 326         return self.write_text(['\\begin{description}\n', '\\end{description}\n'][not on])
 327 
 328     def definition_term(self, on, compact=0):
 329         return self.write_text(['\\item[', '] '][not on])
 330 
 331     def definition_desc(self, on):
 332         return self.write_text('')
 333 
 334     def attachment_image(self, fname):
 335         return self.image(src=fname)
 336     def image(self, **kw):
 337         # I am using alt for caption, but how to integrate the image?
 338         text = ''
 339         #if kw.has_key('alt'):
 340         #    text += '\\begin{picture}\n'
 341         #    text += '\\caption{%s}\n' % kw[alt]
 342         #    text += '\\end{picture}\n'
 343         return self.write_text(text)
 344 
 345     def johill_sidecall_emit_latex(self, code):
 346         # nothing else for now
 347         return code
 348     
 349     def open(self, on, **kw):
 350         return ""
 351     def close(self, on, **kw):
 352         return ""
 353 
 354     # suckers who call this. we can't do raw HTML, so we ignore it
 355     def rawHTML(self, markup):
 356         return ''

MoinMoin: FormatterMarket/text_latex.py (last edited 2007-10-29 19:08:48 by localhost)