#!/usr/bin/python # -*- coding: utf-8 -*- # Copyright (C) 2015 Sergey Poznyakoff # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3, or (at your option) # any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . from wikimarkup import * from types import TupleType from wikins import wiki_ns_re, wiki_ns import re import urllib class TexiWikiMarkup (WikiMarkup): sectcomm = { 'numbered': [ '@top', '@chapter', '@section', '@subsection', '@subsubsection' ], 'unnumbered': [ '@top', '@unnumbered', '@unnumberedsec', '@unnumberedsubsec', '@unnumberedsubsubsec' ], 'appendix': [ '@top', '@appendix', '@appendixsec', '@appendixsubsec', '@appendixsubsubsec' ], 'heading': [ '@majorheading' '@chapheading', '@heading', '@subheading', '@subsubheading' ] } sectioning_model = 'numbered' sectioning_start = 0 def __init__(self, *args, **keywords): super(TexiWikiMarkup, self).__init__(*args, **keywords) if keywords.has_key("sectioning-model"): val = keywords["sectioning-model"] if self.sectcomm.has_key(val): self.sectioning_model = val else: raise ValueError("Invalid value for sectioning model: %s" % val) if keywords.has_key("sectioning-start"): val = keywords["sectioning-start"] if val < 0 or val > 4: raise ValueError("Invalid value for sectioning start: %s" % val) else: self.sectioning_start = val def __str__(self): str = "" for elt in self.tree: str += self.format(elt) return str def format(self, elt): if elt['type'] == 'TEXT': if isinstance(elt['content'],list): string = "" for s in elt['content']: string += s else: string = elt['content'] return string elif elt['type'] == 'TAG': return self.str_tag(elt) elif elt['type'] == 'PARA': return self.str_para(elt) elif elt['type'] == 'PRE': return self.str_pre(elt) elif elt['type'] == 'IT': return self.str_it(elt) elif elt['type'] == 'BOLD': return self.str_bold(elt) elif elt['type'] == 'LINK': return self.str_link(elt) elif elt['type'] == 'TMPL': return self.str_tmpl(elt) elif elt['type'] == 'BAR': return self.str_bar() elif elt['type'] == 'HDR': return self.str_hdr(elt) elif elt['type'] == 'REF': return self.str_ref(elt) elif elt['type'] == 'ENV': return self.str_env(elt) elif elt['type'] == 'IND': return self.str_ind(elt) elif elt['type'] == 'SEQ': string = "" for x in elt['content']: string += self.format(x) return string else: return str(elt) def str_tag(self, elt): if elt['tag'] == 'code': self.nested += 1 s = self.format(elt['content']) self.nested -= 1 if not s.endswith("\n"): s += "\n" return '@example\n' + s + '@end example\n' elif elt['tag'] == 'tt': self.nested += 1 s = self.format(elt['content']) self.nested -= 1 return "@code{%s}" % s elif elt['tag'] == 'div': s = '' if 'args' in elt and 'id' in elt['args']: s += "\n@anchor{%s}\n" % elt['args']['id'] s += self.format(elt['content']) return s else: s = '<' + elt['tag'] if elt['args']: s += ' ' + elt['args'] s += '>' + self.format(elt['content']) + '' return s def str_para(self, elt): string = ""; for x in elt['content']: string += self.format(x) return "\n" + string + "\n" def str_pre(self, elt): string = ""; for x in elt['content']: string += self.format(x) if self.nested: return string if not string.endswith("\n"): string += "\n"; return '\n@example\n' + string + '@end example\n' def concat(self, eltlist): string = "" for x in eltlist: string += self.format(x) return string def str_it(self, elt): return "@i{" + self.concat(elt['content']) + "}" def str_bold(self, elt): return "@b{" + self.concat(elt['content']) + "}" def nodename(self, elt): return self.format(elt) # FIXME def str_hdr(self, elt): level = elt['level'] if level > len(self.sectcomm[self.sectioning_model]) - 1 - self.sectioning_start: s ="\n@* %s" % (self.format(elt['content'])) else: s = self.sectcomm[self.sectioning_model][level - self.sectioning_start] + " " + self.format(elt['content']) + "\n" if self.sectcomm[self.sectioning_model][0] == '@top': s += "@node %s\n" % (self.nodename(elt['content'])) return s + "\n" def str_bar(self): return "\n-----\n" # FIXME def str_ind(self, elt): return ("@w{ }" * elt['level']) + self.format(elt['content']) + '\n' def str_env(self, elt): if elt['envtype'] == 'unnumbered': string = '\n@itemize @bullet\n' for s in elt['content']: string += '@item ' + self.format(s['content']) + '\n\n' string += '@end itemize\n' elif elt['envtype'] == 'numbered': string = '\n@enumerate\n' for s in elt['content']: string += '@item ' + self.format(s['content']) + '\n\n' string += '@end enumerate\n' elif elt['envtype'] == 'defn': string = "\n@table @asis\n" for s in elt['content']: if s['subtype'] == 0: string += "@item " + self.format(s['content']) + '\n' else: string += self.format(s['content']) + '\n' string += '@end table\n' return string def str_link(self, elt): # FIXME: A very crude version arg = self.format(elt['content'][0]) if len(elt['content']) > 1: s = map(self.format, elt['content']) text = s[1] else: s = None text = None if s: if s[0] == 'disambigR' or s[0] == 'wikiquote': return "" if len(s) > 1 and s[1] == 'thumb': return "" (qual,sep,tgt) = arg.partition(':') if text: return "@ref{%s,%s}" % (qual, text) else: return "@ref{%s}" % qual def str_tmpl(self, elt): return "FIXME: str_tmpl not implemented\n" def str_ref(self, elt): target = elt['ref'] text = self.format(elt['content']) if text and text != '': return "@uref{%s,%s}" % (target, text) else: return "@uref{%s}" % target