import commands, curses, os, sys import color, method, mode from lex import Grammar, PatternRule, RegionRule from mode.text import TextInsertSpace class ArgumentGrammar(Grammar): rules = [PatternRule(r'data', r'[^}]+')] class StringGrammar1(Grammar): rules = [PatternRule(r'data', r"[^']+")] class StringGrammar2(Grammar): rules = [PatternRule(r'data', r"(?:[^']|'(?!'))+")] class LatexGrammar(Grammar): rules = [ PatternRule(r'comment', r'\%.*$'), PatternRule(r'latex_wrapper', r'\\(?:begin|end)'), PatternRule(r'latex_control', r'\\[a-zA-Z]+'), RegionRule(r'latex_argument', r'{', ArgumentGrammar, r'}'), RegionRule(r'latex_string', r"``", StringGrammar2, r"''"), RegionRule(r'latex_string', r"`", StringGrammar1, r"'"), PatternRule(r'latex_escaped', r'\\.'), PatternRule(r'latex_special', r'[{}$^_%~#&]'), PatternRule(r'data', r'[^{}$^_%~#&%\\`]+'), ] class LatexBuild(method.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 LatexCommentRegion(method.CommentRegion): commentc = '%' class LatexUncommentRegion(method.UncommentRegion): commentc = '%' class LatexInsertSquotes(method.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.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.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.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(mode.Fundamental): modename = 'Latex' extensions = ['.latex', '.tex'] 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'), 'latex_string.start': ('green', 'default', 'bold'), 'latex_string.null': ('green', 'default', 'bold'), 'latex_string.data': ('green', 'default', 'bold'), 'latex_string.end': ('green', 'default', 'bold'), 'latex_escaped': ('magenta', 'default', 'bold'), } config = { 'latex.buildcmd': 'latex', 'latex.pdfbuildcmd': 'pdflatex', 'latex.pdfviewcmd': 'evince', } actions = [LatexCommentRegion, LatexUncommentRegion, LatexInsertSquotes, LatexInsertDquotes, LatexInsertBraces, LatexBuild, LatexInsertSpace, LatexBuildPdf, LatexViewPdf, LatexCheckSpelling] def __init__(self, w): mode.Fundamental.__init__(self, w) self.add_bindings('wrap-paragraph', ('M-q',)) self.add_bindings('latex-comment-region', ('C-c #', "C-c \%")) self.add_bindings('latex-uncomment-region', ('C-u C-c #', "C-u C-c \%")) self.add_bindings('latex-insert-squotes', ("M-'",)) self.add_bindings('latex-insert-dquotes', ('M-"',)) self.add_bindings('latex-insert-braces', ('M-{',)) self.add_bindings('latex-build', ("C-c C-c", 'C-c B')) self.add_bindings('latex-insert-space', ('SPACE',)) self.add_bindings('latex-build-pdf', ("C-c C-p",)) self.add_bindings('latex-view-pdf', ('C-c C-v',)) install = Latex.install