# -*- coding: utf-8 -*- """ MoinMoin - "text/latex" Formatter Copyright 2005 Johannes Berg Copyright (c) 2003 by João Neves Copyright (c) 2000, 2001, 2002 by Jürgen Hermann All rights reserved, see COPYING for details. """ # Imports import sys, re, time from MoinMoin.formatter.base import FormatterBase from MoinMoin.Page import Page ############################################################################# ### LaTeX Formatter ############################################################################# class Formatter(FormatterBase): """ Send text data. """ hardspace = ' ' def __init__(self, request, **kw): apply(FormatterBase.__init__, (self, request), kw) self.verbatim = False self.itemized = False def text2latex(self, text): "Escape special characters if not in verbatim mode" if self.verbatim: return text text = text.replace('\\', '$\\backslash$ '); text = text.replace('$', r'\$'); text = text.replace(r'\$\backslash\$', r'$\backslash$') text = text.replace('#', '\#'); text = text.replace('%', '\%'); text = text.replace('^', '\^{}'); text = text.replace('&', '\&'); text = text.replace('_', '\_'); text = text.replace('{', '\{'); text = text.replace('}', '\}'); text = text.replace('~', '\~{}'); text = text.replace('"', '\"'); return text def write_text(self, text): if self.item is None: return text else: self.item = (self.item[0], self.item[1]+text) return '' def startDocument(self, pagename): extra_preamble = '' preamble_page = self.request.pragma.get('latex_preamble', None) if preamble_page is not None: extra_preamble = Page(self.request, preamble_page).get_raw_body() extra_preamble = re.sub(re.compile('^#'), '%', extra_preamble) import locale locale.setlocale(locale.LC_ALL,('fr_FR')) date = time.strftime("%A %d %B %Y", time.localtime()).capitalize() return """\\documentclass[a4paper,10pt]{article} \\usepackage[english,french]{babel} \\usepackage[utf8]{inputenc} \\usepackage{times} \\usepackage[T1]{fontenc} \\usepackage{helvet} \\usepackage{graphicx} \\usepackage{multicol} \\usepackage{fullpage} \\usepackage{fancyhdr} \\usepackage{hyperref} \\usepackage{multirow} \\makeatletter \\DeclareRobustCommand*\\textsubscript[1]{%% \\@textsubscript{\\selectfont#1}} \\def\\@textsubscript#1{%% {\\m@th\\ensuremath{_{\\mbox{\\fontsize\\sf@size\\z@#1}}}}} \\makeatother %% begin extra preamble inclusion %% %s %% end extra preamble inclusion %% \\title{%s} \\author{ } \\date{%s} \\renewcommand{\\theenumi}{\\arabic{enumi}} \\renewcommand{\\theenumii}{\\arabic{enumi}.\\arabic{enumii}} \\renewcommand{\\theenumiii}{\\arabic{enumi}.\\arabic{enumii}.\\arabic{enumiii}} \\renewcommand{\\theenumiv}{\\arabic{enumi}.\\arabic{enumii}.\\arabic{enumiii}.\\arabic{enumiv}} \\begin{document} \\maketitle \\tableofcontents \\newpage """ % (extra_preamble, pagename, date) def endDocument(self): return '\\end{document}\n' def sysmsg(self, text, **kw): return self.write_text('') def pagelink(self, on, pagename, page=None, **kw): if not on: apply(FormatterBase.pagelink, (self, on, pagename, page), kw) if page is None: page = Page(self.request, pagename, formatter=self); if page.exists(): return self.write_text('\\footnote{http://crans.org%s}' % self.text2latex(page.url(request=self.request))) #return self.write_text('toto:%s[%s]' % (self.request.getScriptname(),page.url(request=self.request))) return '' def url(self, on, url=None, css=None, **kw): if on: self.save_url=url.replace('&', '\\&') return '' return self.write_text('\\footnote{%s}' % self.save_url) def text(self, text): return self.write_text(self.text2latex(text)) def rule(self, size=0): size = min(size, 10) ch = "---~=*+#####"[size] return self.write_text('\\vrule \n') def strong(self, on): return self.write_text(['{\\bf ', '}'][not on]) def emphasis(self, on): return self.write_text(['{\\em ', '}'][not on]) def highlight(self, on): return self.write_text(['{\\tt ', '}'][not on]) def number_list(self, on, type=None, start=None): self.itemized = on if on: text = "\\begin{enumerate}" else: text = '\\end{enumerate}\n' return self.write_text(text) def bullet_list(self, on): self.itemized = on return self.write_text(['\\begin{itemize}\n', '\n\\end{itemize}\n'][not on]) def listitem(self, on, **kw): if not self.itemized: return '' self._in_li = on != 0 if on: return self.write_text('\\item ') else: return '' def sup(self, on): return self.write_text(['\\textsuperscript{', '}'][not on]) def sub(self, on): return self.write_text(['\\textsubscript{', '}'][not on]) def code(self, on): return self.write_text(['{\\tt ', '}'][not on]) def code_area(self, on, code_id, code_type='code', show=0, start=-1, step=-1): res = self.preformatted(on) self.verbatim = False return self.write_text(res) def code_token(self, on, tok_type): return self.write_text('') def code_line(self, on): return self.write_text('\n') def preformatted(self, on): FormatterBase.preformatted(self, on) self.verbatim = on return self.write_text(['\\begin{verbatim}\n', '\\end{verbatim}\n'][not on]) def smiley(self, text): return self.write_text(self.text2latex(text)) def paragraph(self, on): FormatterBase.paragraph(self, on) return self.write_text(['', '\n\n'][not on]) def linebreak(self, preformatted=1): if preformatted==1: return self.write_text('\n') else: return self.write_text('\\newline') def heading(self, on, depth, **kw): if depth == 1: rv = (r'\section{','}') elif depth == 2: rv = ('\\subsection{','}') elif depth == 3: rv = ('\\subsubsection{','}') else: rv = (r'\paragraph{','}',) return self.write_text(rv[not on]) rows = [] row = [] item = None def table(self, on, attrs={}): def count_cols(row): cols = 0 for cell in row: if cell[0].has_key('colspan'): cols += int(cell[0]['colspan'][1:-1]) else: cols += 1 return cols if on: self.rows = [] self.item = None self.row = [] return '' # not on: if self.rows == []: return '' cols = count_cols(self.rows[0]) rows = len(self.rows) _table = [[0 for i in xrange(0,cols)] for j in xrange(0,rows)] _rownum = -1 for _row in self.rows: _rownum += 1 _cellnum = -1 for _cell in _row: _cellnum += 1 while _table[_rownum][_cellnum] is None or type(_table[_rownum][_cellnum]) == type(()): _cellnum += 1 if _cell[0].get('rowspan') == '"1"': del _cell[0]['rowspan'] if _cell[0].get('colspan') == '"1"': del _cell[0]['colspan'] _rowspan = int(_cell[0].get('rowspan', '"1"')[1:-1]) _colspan = int(_cell[0].get('colspan', '"1"')[1:-1]) for j in xrange(0,_rowspan): for i in xrange(0,_colspan): _table[_rownum+j][_cellnum+i] = None _table[_rownum+j][_cellnum] = ({'colspan':'"%d"'%_colspan},None) _table[_rownum][_cellnum] = _cell table = '\\begin{tabular}{|%s}\n' % (cols * 'l|') for _row in _table: row = '' cellnum = 0 _lines = [] _do_line = True for _cell in _row: cellnum+=1 if _cell == 0: return 'INVALID TABLE' if _cell is None: if _do_line: _lines += [cellnum] continue _rowspan = int(_cell[0].get('rowspan', '"1"')[1:-1]) _colspan = int(_cell[0].get('colspan', '"1"')[1:-1]) format = '%s' if not (_cell[1] is None): _do_line = True _lines += [cellnum] else: _do_line = False _cell = (_cell[0], u'') if _rowspan > 1: format = r'\multirow{%d}*{%%s}' % _rowspan if _colspan > 1: format = r'\multicolumn{%d}{|l|}{ %s }' % (_colspan, format) row += (format+' & ') % _cell[1].replace('\n',' ') for l in _lines: table += r'\cline{%d-%d}' % (l,l) table += row[0:-3] + '\\\\ \n' table += '\\hline\\end{tabular}\n\n' return table def table_row(self, on, attrs={}): if not on: self.rows += [self.row] self.row = [] return '' def table_cell(self, on, attrs={}): if not on: self.row += [self.item] self.item = None else: self.item = (attrs,'') return '' def underline(self, on): return self.write_text(['\\underline{', '}'][not on]) def definition_list(self, on): return self.write_text(['\\begin{description}\n', '\\end{description}\n'][not on]) def definition_term(self, on, compact=0): return self.write_text(['\\item[', '] '][not on]) def definition_desc(self, on): return self.write_text('') def image(self, **kw): # I am using alt for caption, but how to integrate the image? text = '' #if kw.has_key('alt'): # text += '\\begin{picture}\n' # text += '\\caption{%s}\n' % kw[alt] # text += '\\end{picture}\n' return self.write_text(text) def johill_sidecall_emit_latex(self, code): # nothing else for now return code def open(self, on, **kw): return "" def close(self, on, **kw): return "" # suckers who call this. we can't do raw HTML, so we ignore it def rawHTML(self, markup): return ''