def apply(self, handler, gen): map = { "authors": handler.gen_authors, "content": handler.gen_content, "header": handler.gen_header, "title": handler.gen_title, "toc": handler.gen_menu } global template_re try: tpl = open(self.path, "r") n = 0 for line in tpl.readlines(): n = n + 1 f = 0 for m in template_re.finditer(line): gen.out.write(line[f:m.start()]) f = m.end() try: kw = m.group(1) map[kw](gen) except KeyError as e: common.onError("unknown element %s at %d" % (kw, n)) gen.out.write(line[f:]) except IOError as e: common.onError(str(e))
def parse(self, file, name='<unknown>'): try: self.parseInternal(file, name) self.send(doc.Event(doc.L_DOC, doc.ID_END)) self.doc.clean() except common.ParseException as e: common.onError(self.message(e))
def handleInclude(man, match): path = match.group(1).strip() if not os.path.isabs(path): path = os.path.join(os.path.dirname(man.file_name), path) try: file = open(path) man.parseInternal(file, path) except IOError as e: common.onError('%s:%d: cannot include "%s": %s' % (man.file_name, man.line_num, path, e))
def copy_friend(self, spath, tpath): """Load a friend file in the generation location. path -- relative path to write to. base -- absolute file to the file to copy.""" tpath = self.prepare_friend(tpath) try: shutil.copyfile(spath, tpath) return tpath except shutil.Error as e: common.onError('can not copy "%s" to "%s": %s' % (spath, tpath, str(e))) except IOError as e: common.onError('can not copy "%s" to "%s": %s' % (spath, tpath, str(e)))
def handleTerm(man, match): # record the term id = match.group("termid") de = match.group("termdef") if man.lexicon.exists(id): common.onError(man.message("term \"%s\" already defined!" % id)) return term = LexPar(id) man.lexicon.add(id, term) # finalize the parsing man.doc.addLabel(label(id), term) man.send(doc.ObjectEvent(doc.L_PAR, doc.ID_NEW, term)) man.reparse(de)
def __init__(self, doc): back.Generator.__init__(self, doc) self.output = self.doc.getVar('OUTPUT') if self.output: if self.output == 'pdf': self.backend = self.doc.getVar('DOCBOOK_BACKEND') if not self.backend: self.backend = 'dblatex' if self.backend == 'openjade': self.sgml = True elif self.backend == 'dblatex': self.sgml = False else: common.onError('DocBook back-end %s not supported' % self.backend) else: common.onError('DocBook output %s not supported' % self.output)
def use(self, name): """Use a module in the current parser.""" if name in self.used_mods: return path = self.doc.getVar("THOT_USE_PATH") mod = common.loadModule(name, path) if mod: self.used_mods.append(mod) if "init" in mod.__dict__: mod.init(self) # new syntax? if "__syntax__" in mod.__dict__: lines = [] words = [] if "__lines__" in mod.__dict__: lines = mod.__lines__ if "__words__" in mod.__dict__: words = mod.__words__ if "__syntaxes__" in mod.__dict__: for s in mod.__syntaxes__: lines = lines + s.get_lines() words = words + s.get_words() self.setSyntax([(l[0], re.compile(l[1])) for l in lines], [(w[0], w[1]) for w in words]) # simple extension else: if "__lines__" in mod.__dict__: for line in mod.__lines__: self.addLine((line[0], re.compile(line[1]))) if "__words__" in mod.__dict__: for word in mod.__words__: self.addWord((word[0], word[1])) if "__syntaxes__" in mod.__dict__: for s in mod.__syntaxes__: for (f, r) in s.get_lines(): self.addLine((f, re.compile(r))) for w in s.get_words(): self.addWord(w) else: common.onError('cannot load module %s' % name)
def prepare_friend(self, path): """Prepare friend file to be created (ensuring uniqueness) and existence of directories (maintain the same path suffix). Return the actual path.""" # create directories dpath = os.path.dirname(path) if not os.path.exists(dpath): try: os.makedirs(dpath) except os.error as e: common.onError('cannot create directory "%s": %s' % (dpath, e)) # ensure uniqueness file, ext = os.path.splitext(path) cnt = 0 while path in self.to_files: path = "%s-%d%s" % (file, cnt, ext) cnt = cnt + 1 return path
def include_graphics(self, url, node, align=None): # It should download the image if the URL is external # !!TODO!! # handle unsupported image format root, ext = os.path.splitext(url) if ext.lower() not in UNSUPPORTED_IMAGE: link = self.use_friend(url) else: root, ext = os.path.splitext(url) link = self.new_friend(os.path.abspath(root + ".png")) res = subprocess.call(['convert %s %s' % (url, link)], shell=True) if res != 0: common.onError('cannot convert image "%s" to "%s"' % (url, link)) # build the command args = '' if node.get_width(): if args: args += ',' args += 'width=%dpx' % node.get_width() if node.get_height(): if args: args += ',' args += 'height=%dpx' % node.get_height() if align != None: if args: args += ',' if align == doc.ALIGN_LEFT: args += "left" elif align == doc.ALIGN_RIGHT: args += "right" else: args += "center" if args: args = "[%s]" % args self.out.write('\includegraphics%s{%s}' % (args, link))
def run(self): # select the page self.template = self.doc.getVar('HTML_TEMPLATE') if self.template: page = TemplatePage(self.template) else: page = PlainPage() # select the policy self.struct = self.doc.getVar('HTML_ONE_FILE_PER') if self.struct == 'document' or self.struct == '': policy = AllInOne(self, page) elif self.struct == 'chapter': policy = PerChapter(self, page) elif self.struct == 'section': policy = PerSection(self, page) else: common.onError('one_file_per %s structure is not supported' % self.struct) # generate the document policy.run() print("SUCCESS: result in %s" % self.path)
def error(self, msg): """Display an error with file and line.""" common.onError(self.message(msg))
def onError(self, msg): """Called to display an error.""" common.onError('%s:%d: %s' % (self.file, self.line, msg))
def run(self): self.openMain('.tex') self.doc.pregen(self) # get class cls = self.doc.getVar('LATEX_CLASS') if not cls: cls = 'book' preamble = self.doc.getVar('LATEX_PREAMBLE') # look for internationalization lang = self.doc.getVar('LANG').lower().replace('-', '_') if lang: if lang in LANGUAGES: lang = LANGUAGES[lang] else: pos = lang.find('_') if pos < 0: common.onError('cannot not support "%s"' % lang) else: lang = lang[:pos] if lang in LANGUAGES: lang = LANGUAGES[lang] else: common.onError('cannot not support "%s"' % lang) # look for encoding self.encoding = self.doc.getVar('ENCODING').lower().replace('-', '_') if self.encoding: if self.encoding == 'utf_8': preamble += '\\usepackage{ucs}\n' preamble += '\\usepackage[utf8x]{inputenc}\n' self.encoder = UTF8Encoder() elif self.encoding == 'iso_8859_1': preamble += '\\usepackage[latin1]{inputenc}\n' self.encoder = NonUnicodeEncoder(self.encoding) else: common.onWarning('%s encoding is just ignored for latex' % self.encoding) # look paper size paper = self.doc.getVar('LATEX_PAPER') if not paper: paper = 'a4paper' # preamble self.out.write('\\documentclass[oneside,%s,%s]{%s}\n' % (paper, lang, cls)) self.out.write('\\usepackage[T1]{fontenc}\n') self.out.write('\\usepackage[pdftex]{graphicx}\n') self.out.write('\\usepackage{hyperref}\n') self.out.write('\\usepackage{verbatim}\n') #self.out.write('\\usepackage{fancyhdr}\n') self.out.write('\\usepackage[export]{adjustbox}\n') self.out.write(preamble) if lang: self.out.write('\\usepackage[%s]{babel}\n' % lang) is_koma = cls in KOMA_STYLES # add custom definitions self.out.write( '\\newcommand{\\superscript}[1]{\\ensuremath{^{\\textrm{#1}}}}\n') self.out.write( '\\newcommand{\\subscript}[1]{\\ensuremath{_{\\textrm{#1}}}}\n') self.out.write('\\headheight=20pt\n') self.out.write('\\headsep=10pt\n') self.out.write('\\begin{document}\n') # write title latex_title = self.doc.getVar("LATEX_TITLE") if not latex_title: self.out.write('\\title{%s}\n' % self.escape(self.doc.getVar('TITLE'))) subtitle = self.doc.getVar("SUBTITLE") if is_koma and subtitle: self.out.write("\\subtitle{%s}\n" % self.escape(subtitle)) # NOTE: \thanks{...} allows to give the owner organization of an author self.out.write('\\author{%s}\n' % self.escape( self.doc.getVar('AUTHORS')).replace(",", " \\and ")) organization = self.doc.getVar("ORGANIZATION") if is_koma and organization: self.out.write("\\publishers{%s}\n" % self.escape(organization)) self.out.write('\\maketitle\n\n') else: self.out.write("\\begin{titlepage}\n") self.out.write("\\newcommand{\\thotorganization}{%s}\n" % self.escape(self.doc.getVar("ORGANIZATION"))) self.out.write("\\newcommand{\\thottitle}{%s}\n" % self.escape(self.doc.getVar("TITLE"))) self.out.write("\\newcommand{\\thotsubtitle}{%s}\n" % self.escape(self.doc.getVar("SUBTITLE"))) self.out.write( "\\newcommand{\\thotauthors}{%s}\n" % ("{" + self.escape( self.doc.getVar("AUTHORS")).replace(",", "} {") + "}")) logos = self.doc.getVar("LOGO") text = "" fst = True for logo in logos.split(","): if not fst: text = text + " \\hfill " else: fst = False text = text + "\includegraphics{%s}" % logo.strip() self.out.write("\\newcommand{\\thotlogos}{%s}\n" % text) file = open(latex_title) for l in file: self.out.write(l) self.out.write("\\end{titlepage}\n") # generate the content self.out.write('\\tableofcontents\n\n') self.out.write('\\pagebreak\n\n') # write body self.doc.gen(self) # write footer self.out.write('\\end{document}\n') self.out.close() # generate final format output = self.doc.getVar('OUTPUT') if not output or output == 'latex': print("SUCCESS: result in %s" % self.path) elif output == 'pdf': # perform compilation for i in xrange(0, 2): # two times for TOC (sorry) dir, file = os.path.split(self.path) cmd = 'pdflatex -halt-on-error %s' % file if dir == "": dir = "." process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, cwd=dir) out, err = process.communicate('') if process.returncode != 0: sys.stdout.write(out) sys.stderr.write(err) return # display result file, ext = os.path.splitext(self.path) if ext == ".tex": path = file else: path = self.path path = path + ".pdf" print("SUCCESS: result in %s" % path) else: common.onError('unknown output: %s' % output)
def unsupported(self, feature): common.onError('%s unsupported for Latex back-end')