import os import sys from mode import Fundamental from method import Method from lex import Grammar, PatternRule, RegionRule from mode.text import TextInsertSpace class ArgumentGrammar(Grammar): rules = [PatternRule('data', '[^}]+')] class StringGrammar1(Grammar): rules = [PatternRule('data', "[^']+")] class StringGrammar2(Grammar): rules = [PatternRule('data', "(?:[^']|'(?!'))+")] class FalseGrammar(Grammar): rules = [ PatternRule('data', r'[^\\]+'), RegionRule('comment', r'\\if', None, r'\\fi'), ] class LatexGrammar(Grammar): rules = [ PatternRule('comment', r'\%.*$'), RegionRule('comment', r'\\iffalse', FalseGrammar, r'\\fi'), PatternRule('latex.wrapper', r'\\(?:begin|end)'), PatternRule('latex.control', r'\\[a-zA-Z]+'), RegionRule('latex.argument', r'{', ArgumentGrammar, r'}'), RegionRule('latex.string', r"``", StringGrammar2, r"''"), RegionRule('latex.string', r"`", StringGrammar1, r"'"), PatternRule('latex.escaped', r'\\.'), PatternRule('latex.special', r'[{}$^_%~#&]'), PatternRule('latex.data', r'[^{}$^_%~#&%\\`]+'), ] class LatexBuild(Method): '''Insert a pair of LaTeX-style single-quotes into the buffer''' def _getcmd(self, w): return w.application.config.get('latex.buildcmd') def _build(self, w): if w.buffer.changed(): return (True, 'Build Cancelled: unsaved buffer') app = w.application buildcmd = self._getcmd(w) cmd = "%s '\\batchmode\\input %s' >/dev/null 2>&1" % (buildcmd, w.buffer.path) status = os.system(cmd) if status == 0: return (True, 'Build OK') else: return (False, 'Build Error') def _modpath(self, w, ext): return os.path.splitext(w.buffer.path)[0] + ext def _readlog(self, w): logpath = self._modpath(w, '.log') f = open(logpath, 'r') output = f.read() f.close() return output def _execute(self, w, **vargs): (ok, mesg) = self._build(w) w.set_error(mesg) if not ok: output = self._readlog(w) bufname = '*%s*' % self.name w.application.data_buffer(bufname, output, switch_to=not ok) return ok class LatexBuildPdf(LatexBuild): '''Insert a pair of LaTeX-style single-quotes into the buffer''' def _getcmd(self, w): return w.application.config.get('latex.pdfbuildcmd') class LatexViewPdf(LatexBuildPdf): '''Insert a pair of LaTeX-style single-quotes into the buffer''' def _execute(self, w, **vargs): ok = LatexBuildPdf._execute(self, w, **vargs) if ok: viewcmd = w.application.config.get('latex.pdfviewcmd') pid = os.fork() if pid == 0: # redirect stdout/stderr to a log file f = open('.pmacs-latex-pdf.err', 'a') sys.stderr.flush() os.dup2(f.fileno(), sys.stderr.fileno()) sys.stdout.flush() os.dup2(f.fileno(), sys.stdout.fileno()) # ok, now do the exec pdfpath = self._modpath(w, '.pdf') os.execvp(viewcmd, (viewcmd, pdfpath)) class LatexInsertSquotes(Method): '''Insert a pair of LaTeX-style single-quotes into the buffer''' def _execute(self, w, **vargs): w.insert_string_at_cursor("`'") w.backward() class LatexInsertDquotes(Method): '''Insert a pair of LaTeX-style double-quotes into the buffer''' def _execute(self, w, **vargs): w.insert_string_at_cursor("``''") w.backward() w.backward() class LatexInsertBraces(Method): '''Insert a pair of curly braces into the buffer''' def _execute(self, w, **vargs): w.insert_string_at_cursor("{}") w.backward() class LatexInsertSpace(TextInsertSpace): pass class LatexCheckSpelling(Method): """Check the spelling of the document via ispell -t""" def _execute(self, w, **vargs): # -x no backup file # -M show context menu # -t treat input document as TeX w.application.run_external('ispell', '-x', '-M', '-t', w.buffer.path) if w.buffer.changed_on_disk(): w.buffer.reload() class Latex(Fundamental): name = 'Latex' extensions = ['.latex', '.tex'] commentc = '%' grammar = LatexGrammar colors = { 'latex.wrapper': ('magenta', 'default', 'bold'), 'latex.control': ('blue', 'default', 'bold'), 'latex.argument.null': ('cyan', 'default', 'bold'), 'latex.argument.data': ('cyan', 'default', 'bold'), } config = { 'latex.buildcmd': 'latex', 'latex.pdfbuildcmd': 'pdflatex', 'latex.pdfviewcmd': 'evince', } actions = [LatexInsertSquotes, LatexInsertDquotes, LatexInsertBraces, LatexBuild, LatexInsertSpace, LatexBuildPdf, LatexViewPdf, LatexCheckSpelling] _bindings = { 'wrap-paragraph': ('M-q',), 'latex-insert-squotes': ("M-'",), 'latex-insert-dquotes': ('M-"',), 'latex-insert-braces': ('M-{',), 'latex-build': ("C-c C-c", 'C-c B'), 'latex-insert-space': ('SPACE',), 'latex-build-pdf': ("C-c C-p",), 'latex-view-pdf': ('C-c C-v',), } install = Latex.install