PKW4=M(Matrix.sublime-snippet mat text.tex.latex Matrix PKW4=~УTeX.tmLanguage fileTypes sty cls foldingStartMarker /\*\*|\{\s*$ foldingStopMarker \*\*/|^\s*\} name TeX patterns captures 1 name punctuation.definition.keyword.tex match (\\)(backmatter|else|fi|frontmatter|ftrue|mainmatter|if(case|cat|dim|eof|false|hbox|hmode|inner|mmode|num|odd|undefined|vbox|vmode|void|x)?)\b name keyword.control.tex captures 1 name keyword.control.catcode.tex 2 name punctuation.definition.keyword.tex 3 name punctuation.separator.key-value.tex 4 name constant.numeric.category.tex match ((\\)catcode)`(?:\\)?.(=)(\d+) name meta.catcode.tex captures 1 name punctuation.definition.comment.tex match (%:).*$\n? name comment.line.percentage.semicolon.texshop.tex match ^%!TEX (\S*) =\s*(.*)\s*$ name comment.line.percentage.directive.texshop.tex captures 1 name punctuation.definition.comment.tex match (%).*$\n? name comment.line.percentage.tex begin \{ captures 0 name punctuation.section.group.tex end \} name meta.group.braces.tex patterns include $base match [\[\]] name punctuation.definition.brackets.tex begin \$\$ beginCaptures 0 name punctuation.definition.string.begin.tex end \$\$ endCaptures 0 name punctuation.definition.string.end.tex name string.other.math.block.tex patterns include text.tex.math include $self match \\\\ name constant.character.newline.tex begin \$ beginCaptures 0 name punctuation.definition.string.begin.tex end \$ endCaptures 0 name punctuation.definition.string.end.tex name string.other.math.tex patterns match \\\$ name constant.character.escape.tex include text.tex.math include $self captures 1 name punctuation.definition.function.tex match (\\)[A-Za-z@]+ name support.function.general.tex captures 1 name punctuation.definition.keyword.tex match (\\)[^a-zA-Z@] name constant.character.escape.tex match «press a-z and space for greek letter»[a-zA-Z]* name meta.placeholder.greek.tex scopeName text.tex uuid 6BC8DE6F-9360-4C7E-AC3C-971385945346 PKW4=$Itemize.sublime-snippet item text.tex.latex Itemize PKW4=5]latexEnvCloser.pyimport sublime, sublimeplugin # Insert environment closer # this only looks at the LAST \begin{...} # need to extend to allow for nested \begin's class LatexEnvCloserCommand(sublimeplugin.TextCommand): def run(self, view, args): pattern = r'\\(begin|end)\{[^\}]+\}' b = [] currpoint = view.sel()[0].b point = 0 r = view.find(pattern, point) while r and r.end() <= currpoint: be = view.substr(r) point = r.end() if "\\begin" == be[0:6]: b.append(be[6:]) else: if be[4:] == b[-1]: b.pop() else: sublime.errorMessage("\\begin%s closed with %s on line %d" % (b[-1], be, view.rowcol(point)[0])) return r = view.find(pattern, point) # now either b = [] or b[-1] is unmatched if b == []: sublime.errorMessage("Every environment is closed") else: # note the double escaping of \end view.runCommand("insertCharacters \"\\\\end" + b[-1] + "\\n\"") PKW4=NŒbegin{}-end{}.sublime-snippet begin text.tex.latex \begin{}…\end{} PKW4={Listing.sublime-snippet listing text.tex.latex Listing PKW4=kD\qlatexEnvironment.pyimport sublime, sublimeplugin # Insert LaTeX environment based on current word # Position cursor inside environment # TODO: snippet-like jumping out with TAB class latexEnvironmentCommand(sublimeplugin.TextCommand): def run(self, view, args): currword = view.word(view.sel()[0]) command = view.substr(currword) view.erase(currword) snippet = "\\\\begin{" + command + "}\n$1\n\\\\end{" + command + "}$0" view.runCommand("insertInlineSnippet", [snippet]) PKW4=A# viewPDF.pyimport sublime, sublimeplugin, os, os.path from subprocess import Popen # View PDF file corresonding to TEX file in current buffer # Assumes that the SumatraPDF viewer is used (great for inverse search!) # and its executable is on the %PATH% # Warning: we do not do "deep" safety checks (e.g. see if PDF file is old) class ViewPDFCommand(sublimeplugin.WindowCommand): def run(self, window, args): view = window.activeView() texFile, texExt = os.path.splitext(view.fileName()) if texExt.upper() != ".TEX": sublime.errorMessage("%s is not a TeX source file: cannot view." % (os.path.basename(view.fileName()),)) return quotes = "\"" pdfFile = quotes + texFile + u'.pdf' + quotes sumatra = u'SumatraPDF -reuse-instance -inverse-search \"sublimetext \\\"%f\\\":%l\" ' print sumatra + pdfFile try: Popen(sumatra + pdfFile) except WindowsError: sublime.errorMessage("Cannot launch SumatraPDF. Make sure it is on your PATH.") PKW4=UColor.sublime-snippet color text.tex.latex Color (xcolor) PKW4=bUJBeamer boxes.sublime-snippet box text.tex.latex Beamer boxes PKW4=CtexSections.pyimport sublime, sublimeplugin, os, os.path, re # References and citations spaces = {'part' : '', 'chapter' : ' ', 'section' : ' ', 'subsection' : ' ', 'subsubsection' : ' ', 'subsubsubsection' : ' '} class TexSectionsCommand(sublimeplugin.TextCommand): def run(self, view, args): # First get raw \section{xxx} lines # Capture the entire line beginning with our pattern, do processing later secRegions = view.findAll(r'^\\(begin\{frame\}|part|chapter|(?:sub)*section).*$') # Remove \section, etc and only leave spaces and titles # Handle frames separately # For sections, match \ followed by type followed by * or {, then # match everything. This captures the last }, which we'll remove secRe = re.compile(r'\\([^{*]+)\*?\{(.*)') # \, then anything up to a * or a { # Also, we need to remove \label{} statements labelRe = re.compile(r'\\label\{.*\}') # And also remove comments at the end of the line commentRe = re.compile(r'%.*$') # This is to match frames # Here we match the \begin{frame} command, with the optional [...] # and capture the rest of the line for further processing # TODO: find a way to capture \frametitle's on a different line frameRe = re.compile(r'\\begin\{frame\}(?:\[[^\]]\])?(.*$)') frameTitleRe = re.compile(r'\{(.*)\}') def prettify(s): s = commentRe.sub('',s).strip() # kill comments at the end of the line, blanks s = labelRe.sub('',s).strip() # kill label statements frameMatch = frameRe.match(s) if frameMatch: frame = frameMatch.group(1) frameTitleMatch = frameTitleRe.search(frame) if frameTitleMatch: return "frame: " + frameTitleMatch.group(1) else: return "frame: (untitled)" else: m = secRe.match(s) #print m.group(1,2) secTitle = m.group(2) if secTitle[-1]=='}': secTitle = secTitle[:-1] return spaces[m.group(1)]+secTitle prettySecs = [prettify(view.substr(reg)) for reg in secRegions] def onSelect(i): #print view.substr(secRegions[i]) view.show(secRegions[i]) s = view.sel() # RegionSet s.clear() s.add(secRegions[i]) view.runCommand("moveTo bol") view.window().showSelectPanel(prettySecs, onSelect, None, 0) PKW4=Z; texify.pyimport sublime, sublimeplugin, os, os.path, re from subprocess import Popen, PIPE, STDOUT import threading, functools, ctypes # Compile TEX file in current buffer using MikTeX's "texify" command # Does not start the previewer # If the buffer has been modified, it saves it # Also create SyncTeX file (for inverse/forward search); # the viewPDF command implements inverse search (i.e. tells SumatraPDF to call # back Sublime Text when the user double-clicks on the page) # Only a minimal sanity check is implemented. DEBUG = 0 quotes = "\"" # From guillermoo's PowerShell utils def getOEMCP(): # Windows OEM/Ansi codepage mismatch issue. # We need the OEM cp, because texify and friends are console programs codepage = ctypes.windll.kernel32.GetOEMCP() return str(codepage) # Actually parse tex log # Input: tex log file (decoded), split into lines # Output: content to be displayed in quick panel, split into lines # # We do very simple matching: # "!" denotes an error, so we catch it # "Warning:" catches LaTeX warnings, as well as missing citations, and more def parseTeXlog(log): print "Parsing log file" errors = [] warnings = [] errors = [line for line in log if line[0:2] in ['! ','l.']] warnings = [line for line in log if "Warning: " in line] panelContent = [] if errors: print "There were errors.\n" skip = 0 for error in errors: print error[:-1] # skip a line? if skip: print "" skip = 1-skip panelContent.append("There were errors in your LaTeX source") panelContent.append("Click on any message below that shows a line number") panelContent.append("") panelContent.extend(errors) else: print "No errors.\n" panelContent.append("Texification succeeded: no errors!\n") panelContent.append("") if warnings: print "There were no warnings.\n" skip = 0 for warning in warnings: print warning if skip: print "" skip = 1-skip if errors: panelContent.append("") panelContent.append("There were also warnings.") panelContent.append("You can click on these, too.") else: panelContent.append("However, there were warnings in your LaTeX source") panelContent.append("Click on any message below that shows a line number") panelContent.append("") panelContent.extend(warnings) else: print "No warnings.\n" return panelContent class TexifyCommand(sublimeplugin.WindowCommand): def run(self, window, args): # Save file if necessary view = window.activeView() texFile, texExt = os.path.splitext(view.fileName()) if texExt.upper() != ".TEX": sublime.errorMessage("%s is not a TeX source file: cannot compile." % (os.path.basename(view.fileName()),)) return if view.isDirty(): print "saving..." window.runCommand('save') # --max-print-line makes sure that no line is truncated, or we would not catch # line numbers in some warnings texify = u'texify -b -p --tex-option=\"--synctex=1\" --tex-option=\"--max-print-line=200\" ' cmd = texify + quotes + texFile + texExt + quotes print "\n\nTexify executing command:" pContents = ["Texify executing command:", cmd] window.showQuickPanel("texify", "", pContents) # Execute command in a thread # First, define class class CmdThread ( threading.Thread ): # Use __init__ to pass things we need, including window # so we can get window.showQuickPanel def __init__ (self, cmd, pContent, texFile, window): self.cmd = cmd self.pContent = pContent self.texFile = texFile self.qp = window.showQuickPanel threading.Thread.__init__ ( self ) def run ( self ): print "Welcome to the thread!" #print self.cmd #print self.pContent p = Popen(cmd, stdout=PIPE, stderr=STDOUT, shell=True) stdoutdata, stderrdata = p.communicate() # display errors and warnings from last generated log file, # followed by the full output of the texify command # (if we only use the texify output, we get multiple errors/warnings, and also # warnings about e.g. references that are corrected in subsequent runs) texifyLog = stdoutdata.decode(getOEMCP()).splitlines() try: # Read it in as binary, as there may be NULLs # No need to close as we do not create a file object log = open(texFile + ".log", 'rb').read().decode(getOEMCP()).splitlines() except IOError: # if we cannot read the log file for any reason, # just use the texify output log = texifyLog pContent = self.pContent + ["",] + parseTeXlog(log) + \ ["","********************", "", "Full texify output follows", \ "Remember: texify may run latex & friends many times; missing refs. etc. may get automatically fixed in later runs",\ "", "********************", "", ""] + texifyLog sublime.setTimeout(functools.partial(self.qp,"texify","gotoTeXError", pContent), 0) print "returned from qp in thread" # if stderrdata and not("see log file" in str(stderrdata)): # sublime.errorMessage("Could not invoke texify. Got the following error:\n%s" % (str(stderrdata),) ) # print "texify invocation error:" + str(stderrdata) # print len(stdoutdata),len(stderrdata) # else: # window.runCommand('showTeXError') CmdThread(cmd, pContents, texFile, window).start() class ShowTeXErrorCommand(sublimeplugin.WindowCommand): def run(self, window, args): print "Show tex errors" pname = "texify" if args else "" # just as extra precaution print "Panel name: " + pname texFile = os.path.splitext(window.activeView().fileName())[0] try: # Read it in as binary, as there may be NULLs # No need to close as we do not create a file object log = open(texFile + ".log", 'rb').read().decode(getOEMCP()).splitlines() except IOError: sublime.errorMessage("Cannot open log file %s!" % (texFile + ".log",)) return panelContent = parseTeXlog(log) + \ ["","********************", "", "Last generated log file follows", \ "", "********************","",""] + log window.showQuickPanel(pname, "gotoTeXError", panelContent, panelContent, sublime.QUICK_PANEL_MONOSPACE_FONT) class GotoTeXErrorCommand(sublimeplugin.WindowCommand): def run(self, window, args): message = args[0] # print error # this catches both references and citations (and perhaps more!) if "Warning:" in message: p = re.compile('input line (\d+)') else: p = re.compile('[^\d]*(\d+)') linenoSearchResult = p.search(message) print linenoSearchResult if linenoSearchResult: lineno = linenoSearchResult.group(1) else: return v = window.activeView() linept = v.textPoint(int(lineno)-1,0) # lineno is 1-based here s = v.sel() # RegionSet s.clear() s.add(sublime.Region(linept,linept)) v.show(linept)PKW4=xll jumpToPDF.pyimport sublime, sublimeplugin, os.path # Jump to current line in PDF file class JumpToPDFCommand(sublimeplugin.TextCommand): def run(self, view, args): texFile, texExt = os.path.splitext(view.fileName()) if texExt.upper() != ".TEX": sublime.errorMessage("%s is not a TeX source file: cannot jump." % (os.path.basename(view.fileName()),)) return quotes = "\"" srcfile = texFile + u'.tex' pdffile = texFile + u'.pdf' (line, col) = view.rowcol(view.sel()[0].end()) print "Jump to: ", line,col # column is actually ignored up to 0.94 # HACK? It seems we get better results incrementing line line += 1 # the last params are flags. In part. the last is 0 if no focus, 1 to focus command = "[ForwardSearch(\"%s\",\"%s\",%d,%d,0,0)]" % (pdffile, srcfile, line, col) view.runCommand("sendDDEExecute",["SUMATRA","control",command])PKW4=uɬFigure.sublime-snippet figure text.tex.latex Figure PKW4=RG LaTeX Log.tmLanguage firstLineMatch This is (pdf|pdfe)?TeXk?, Version foldingStartMarker /\*\*|\(\s*$ foldingStopMarker \*\*/|^\s*\) name LaTeX Log patterns match .*Warning: name invalid.deprecated match [^:]*:\d*:.* name invalid.deprecated match .*Error|^!.* name invalid.illegal match .*\.sty name entity.name.function match .*\.cls name entity.name.type.class match .*\.cfg name entity.name.tag.configuration match .*\.def name entity.name.tag.definition match .*Info.* name comment.block.documentation match .*FiXme: name meta.log.latex.fixme begin (Overfull|Underfull) captures 1 name keyword.control.hyphenation.latex end (\[\]\n) name meta.log.latex.hyphenation patterns match [0-9]+\-\-[0-9]+ name variable.parameter.hyphenation.latex2 begin (<) beginCaptures 0 name punctuation.definition.string.begin.log.latex end (>) endCaptures 0 name punctuation.definition.string.end.log.latex name string.unquoted.other.filename.log.latex patterns captures 1 name entity.name.function.filename.latex match (.*/.*\.pdf) name support.function.with-arg.latex scopeName text.log.latex uuid F68ACE95-7DB3-4DFB-AA8A-89988B116B5C PKW4=K,Description.sublime-snippet desc text.tex.latex Description PKW4="̒lookupRefCite.pyimport sublime, sublimeplugin, re, textwrap # Lookup label (cross-reference) or bibliography entry (citation) # Position cursor right after closing } # Params: # How many chars before AROUND = 200 # Column width for Quick Panel WIDTH = 80 class LookupRefCiteCommand(sublimeplugin.TextCommand): def run(self, view, args): # We need a slightly more sophisticated def of "current word" currsel = view.sel()[0] currline = view.line(currsel) text = view.substr(sublime.Region(currline.begin(),currsel.end())) print text # now we search for either \ref, \eqref, etc. or \cite, \citet... m = re.search(r'.*\\(.+)\{(.+)\}$', text) if m: (typ, lab) = m.groups() if "ref" in typ: # it's a reference, show text around it cmd = "\\\\label\{%s\}" % (lab,) print cmd r = view.find(cmd,0) around = sublime.Region(max(r.begin()-AROUND,0), min(r.end()+AROUND,view.size())) textaround = ("..."+view.substr(around)+"...").split('\n') textjust = [] for line in textaround: textjust.extend(textwrap.wrap(line, WIDTH)) view.window().showQuickPanel("", "move words 0", textjust) # dummy command elif "cite" in typ: # it's some kind of citation, get it from BibTeX pass # to be implemented PKW4=r3CjlatexCommand.pyimport sublime, sublimeplugin # Insert LaTeX command based on current word # Position cursor inside braces class latexCommandCommand(sublimeplugin.TextCommand): def run(self, view, args): currword = view.word(view.sel()[0]) command = view.substr(currword) view.erase(currword) snippet = "\\\\" + command + "{$1} $0" view.runCommand("insertInlineSnippet", [snippet]) PKW4=JoEnumerate.sublime-snippet enum text.tex.latex Enumerate PKW4=viHLaTeX.sublime-options# Settings in here override the defaults in: # Packages/Default/Options/Default File Type.sublime-options # See there for the available options and their description. PKW4=:uTable.sublime-snippet table text.tex.latex Table PKW4=Zw{vv texMacro.pyimport sublime, sublimeplugin macros = { 'a' : '\\alpha', 'b' : '\\beta', 'c' : '\\chi', 'd' : '\\delta', 'e' : '\\epsilon', 'f' : '\\phi', 'g' : '\\gamma', 'h' : '\\eta', 'i' : '\\iota', 'j' : '\\phi', 'k' : '\\kappa', 'l' : '\\lambda', 'm' : '\\mu', 'n' : '\\nu', 'o' : '\\omicron', 'p' : '\\pi', 'q' : '\\theta', 'r' : '\\rho', 's' : '\\sigma', 't' : '\\tau', 'u' : '\\upsilon', 'v' : '\\psi', 'w' : '\\omega', 'x' : '\\xi', 'y' : '\\vartheta', 'z' : '\\zeta', 'A' : '\\forall', 'B' : 'FREE', 'C' : '\\Chi', 'D' : '\\Delta', 'E' : '\\exists', 'F' : '\\Phi', 'G' : '\\Gamma', 'H' : 'FREE', 'I' : '\\bigcap', 'J' : '\\Phi', 'K' : 'FREE', 'L' : '\\Lambda', 'M' : '\\int', 'N' : '\\sum', 'O' : '\\emptyset', 'P' : '\\Pi', 'Q' : '\\Theta', 'R' : 'FREE', 'S' : '\\Sigma', 'T' : '\\times', 'U' : '\\bigcup', 'V' : '\\Psi', 'W' : '\\Omega', 'X' : '\\Xi', 'Y' : '\\Upsilon', 'Z' : '\\sum', 'ge' : '\\geq', 'le' : '\\leq', 'la' : '\\leftarrow', 'ra' : '\\rightarrow', 'La' : '\\Leftarrow', 'Ra' : '\\Rightarrow', 'lra' : '\\leftrightarrow', 'up' : '\\uparrow', 'dn' : '\\downarrow', 'iff' : '\\Leftrightarrow', 'raa' : '\\rangle', 'laa' : '\\langle', 'lp' : '\\left(', 'rp' : '\\right)', 'lbk' : '\\left[', 'rbk' : '\\right]', 'lbr' : '\\left\{', 'rbr' : '\\right\}' } class texMacroCommand(sublimeplugin.TextCommand): def run(self, view, args): currsel = view.sel()[0] currword = view.word(currsel) k = view.substr(currword) if macros.has_key(k): view.replace(currword, macros[k]) else: sublime.errorMessage("%s is not a valid TeX symbol shortcut" % (k,)) PKW4=D LaTeX.package-menu PKW4=^!Item[description].sublime-snippet itd text.tex.latex meta.function.environment.list \item[description] PKW4=YllLaTeX.sublime-buildbuild pdflatex --interaction=nonstopmode --synctex=1 --max-print-line=200 $File lineNumberRegex ^()l\.(\d+) PKW4=gh]]'subsubsection-..-(ssub).sublime-snippet subs text.tex.latex Sub Sub Section PKW4=; ; LaTeX Beamer.tmLanguage fileTypes firstLineMatch ^\\documentclass(\[.*\])?\{beamer\} foldingStartMarker \\begin\{.*\}|%.*\(fold\)\s*$ foldingStopMarker \\end\{.*\}|%.*\(end\)\s*$ keyEquivalent ^~B name LaTeX Beamer patterns begin (?:\s*)((\\)begin)(\{)(frame)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex end ((\\)end)(\{)(frame)(\}) name meta.function.environment.frame.latex patterns include $self captures 1 name support.function.frametitle.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name entity.name.function.frame.latex 5 name punctuation.definition.arguments.end.latex match ((\\)frametitle)(\{)(.*)(\}) name meta.function.frametitle.latex include text.tex.latex scopeName text.tex.latex.beamer uuid 2ACA20AA-B008-469B-A04A-6DE232973ED8 PKW4=c*}NN#subsection-..-(sub).sublime-snippet sub text.tex.latex Sub Section PKW4=.cAA$section-..-(section).sublime-snippet sec text.tex.latex Section PKW4=ՠSection.sublime-snippet section text.tex.latex Section PKW4=F~IIParagraph.sublime-snippet par text.tex.latex Paragraph PKW4= texRef.pyimport sublime, sublimeplugin, os, os.path, re # References and citations done = False class TexRefCommand(sublimeplugin.TextCommand): def run(self, view, args): # get current point # assume no selection, or a singe selection (for now) currsel = view.sel()[0] point = currsel.b prefix = view.substr(view.word(point)).strip() print currsel, point, prefix,len(prefix) completions = [] view.findAll('\\label\{([^\{]*)\}',0,'\\1',completions) # print completions # print "%d labels" % (len(completions),) # no prefix, or braces if not prefix in ["", "{}", "{", "}"]: fcompletions = [comp for comp in completions if prefix in comp] else: prefix = "" # in case it's {} or { or } fcompletions = completions # The drop-down completion menu contains at most 16 items, so # show selection panel if we have more. print prefix, len(fcompletions) if len(fcompletions) == 0: sublime.errorMessage("No references starting with %s!" % (prefix,)) return if len(fcompletions) <= 16: view.showCompletions(point, prefix, fcompletions) else: def onSelect(i): # if we had an actual prefix, replace it with the label, # otherwise insert the label. # FIXME like TextMate, if you give e.g. thm:so as prefix # you may get thm:thm:something if prefix not in ["", "{}", "{", "}"]: view.replace(currword, fcompletions[i]) else: view.insert(point, fcompletions[i]) view.window().showSelectPanel(fcompletions, onSelect, None, 0) print "done" PKW4=*S{Part.sublime-snippet part text.tex.latex Part PKW4=f(Beamer frame.sublime-snippet frame text.tex.latex Beamer frame PKW4=P??Comments.tmPreferences name Comments scope text.tex.latex settings shellVariables name TM_COMMENT_START value % uuid 678850E6-C630-4EEF-B307-14ADEE2B2994 PKW4=?_Page.sublime-snippet page text.tex.latex Page PKW4=@f texCite.pyimport sublime, sublimeplugin, os, os.path, re # References and citations class TexCiteCommand(sublimeplugin.TextCommand): def run(self, view, args): print "entering texCite" # test only for now # get current point # assume no selection, or a singe selection (for now) currsel = view.sel()[0] point = currsel.b prefix = view.substr(view.word(point)).strip() print currsel, point, prefix,len(prefix) completions = [] # For now we only get completions from bibtex file bibcmd = view.substr(view.find(r'\\bibliography\{(.+)\}',0)) print bibcmd bibp = re.compile(r'\{(.+)\}') bibmatch = bibp.search(bibcmd) if not bibmatch: print "Cannot parse bibliography command: " + bibcmd return bibfname = bibmatch.group(1) print bibfname if bibfname[-4:] != ".bib": bibfname = bibfname + ".bib" texfiledir = os.path.dirname(view.fileName()) bibfname = os.path.normpath(texfiledir + os.path.sep + bibfname) print bibfname try: bibf = open(bibfname) except IOError: sublime.errorMessage("Cannot open bibliography file %s !" % (bibfname,)) return else: bib = bibf.readlines() bibf.close() kp = re.compile(r'@[^\{]+\{(.+),') tp = re.compile(r'\btitle\s*=\s*(.+)', re.IGNORECASE) kp2 = re.compile(r'([^\t]+)\t*') keywords = [kp.search(line).group(1) for line in bib if line[0] == '@'] titles = [tp.search(line).group(1) for line in bib if tp.search(line)] if len(keywords) != len(titles): print "Bibliography " + bibfname + " is broken!" completions = ["%s\t\t%s" % kt for kt in zip(keywords, titles)] # need ",}" for multiple citations # support is limited: this only OK if there is no prefix after the # comma. multicites = False if not prefix in ["", "{}", ",}"]: fcompletions = [comp for comp in completions if prefix in comp] else: if prefix == ",}": multicites = True prefix = "" # in case it's {} fcompletions = completions # are there any completions? if len(fcompletions) == 0: sublime.errorMessage("No bibliography keys start with %s!" % (prefix,)) return def onSelect(i): key = kp2.search(fcompletions[i]).group(1) # if no selection, and current character is not space, # extend to word # Note: we crash if currsel.a=0, but that means that we are trying # to enter a reference as the very first character of the file! if currsel.a == currsel.b and view.substr(currsel.a-1) != ' ': newsel = view.word(point) else: newsel = currsel view.erase(newsel) # Use all-powerful insertInlineSnippet! woot! # Note: must escape '\' twice if not multicites: snippet = "\\\\${1:cite}{" + key + "} $0" else: snippet = "," + key + "}" view.runCommand('insertInlineSnippet', [snippet]) if len(fcompletions) == 1: onSelect(0) else: view.window().showSelectPanel(fcompletions, onSelect, None, 0) print "done"PKW4=E2TeX Math.tmLanguage fileTypes foldingStartMarker /\*\*|\{\s*$ foldingStopMarker \*\*/|^\s*\} name TeX Math patterns captures 1 name punctuation.definition.constant.math.tex match (\\)(s(s(earrow|warrow|lash)|h(ort(downarrow|uparrow|parallel|leftarrow|rightarrow|mid)|arp)|tar|i(gma|m(eq)?)|u(cc(sim|n(sim|approx)|curlyeq|eq|approx)?|pset(neq(q)?|plus(eq)?|eq(q)?)?|rd|m|bset(neq(q)?|plus(eq)?|eq(q)?)?)|p(hericalangle|adesuit)|e(tminus|arrow)|q(su(pset(eq)?|bset(eq)?)|c(up|ap)|uare)|warrow|m(ile|all(s(etminus|mile)|frown)))|h(slash|ook(leftarrow|rightarrow)|eartsuit|bar)|R(sh|ightarrow|e|bag)|Gam(e|ma)|n(s(hort(parallel|mid)|im|u(cc(eq)?|pseteq(q)?|bseteq))|Rightarrow|n(earrow|warrow)|cong|triangle(left(eq(slant)?)?|right(eq(slant)?)?)|i(plus)?|u|p(lus|arallel|rec(eq)?)|e(q|arrow|g|xists)|v(dash|Dash)|warrow|le(ss|q(slant|q)?|ft(arrow|rightarrow))|a(tural|bla)|VDash|rightarrow|g(tr|eq(slant|q)?)|mid|Left(arrow|rightarrow))|c(hi|irc(eq|le(d(circ|S|dash|ast)|arrow(left|right)))?|o(ng|prod|lon|mplement)|dot(s|p)?|u(p|r(vearrow(left|right)|ly(eq(succ|prec)|vee(downarrow|uparrow)?|wedge(downarrow|uparrow)?)))|enterdot|lubsuit|ap)|Xi|Maps(to(char)?|from(char)?)|B(ox|umpeq|bbk)|t(h(ick(sim|approx)|e(ta|refore))|imes|op|wohead(leftarrow|rightarrow)|a(u|lloblong)|riangle(down|q|left(eq(slant)?)?|right(eq(slant)?)?)?)|i(n(t(er(cal|leave))?|plus|fty)?|ota|math)|S(igma|u(pset|bset))|zeta|o(slash|times|int|dot|plus|vee|wedge|lessthan|greaterthan|m(inus|ega)|b(slash|long|ar))|d(i(v(ideontimes)?|a(g(down|up)|mond(suit)?)|gamma)|o(t(plus|eq(dot)?)|ublebarwedge|wn(harpoon(left|right)|downarrows|arrow))|d(ots|agger)|elta|a(sh(v|leftarrow|rightarrow)|leth|gger))|Y(down|up|left|right)|C(up|ap)|u(n(lhd|rhd)|p(silon|harpoon(left|right)|downarrow|uparrows|lus|arrow)|lcorner|rcorner)|jmath|Theta|Im|p(si|hi|i(tchfork)?|erp|ar(tial|allel)|r(ime|o(d|pto)|ec(sim|n(sim|approx)|curlyeq|eq|approx)?)|m)|e(t(h|a)|psilon|q(slant(less|gtr)|circ|uiv)|ll|xists|mptyset)|Omega|D(iamond|ownarrow|elta)|v(d(ots|ash)|ee(bar)?|Dash|ar(s(igma|u(psetneq(q)?|bsetneq(q)?))|nothing|curly(vee|wedge)|t(heta|imes|riangle(left|right)?)|o(slash|circle|times|dot|plus|vee|wedge|lessthan|ast|greaterthan|minus|b(slash|ar))|p(hi|i|ropto)|epsilon|kappa|rho|bigcirc))|kappa|Up(silon|downarrow|arrow)|Join|f(orall|lat|a(t(s(emi|lash)|bslash)|llingdotseq)|rown)|P(si|hi|i)|w(p|edge|r)|l(hd|n(sim|eq(q)?|approx)|ceil|times|ightning|o(ng(left(arrow|rightarrow)|rightarrow|maps(to|from))|zenge|oparrow(left|right))|dot(s|p)|e(ss(sim|dot|eq(qgtr|gtr)|approx|gtr)|q(slant|q)?|ft(slice|harpoon(down|up)|threetimes|leftarrows|arrow(t(ail|riangle))?|right(squigarrow|harpoons|arrow(s|triangle|eq)?))|adsto)|vertneqq|floor|l(c(orner|eil)|floor|l|bracket)?|a(ngle|mbda)|rcorner|bag)|a(s(ymp|t)|ngle|pprox(eq)?|l(pha|eph)|rrownot|malg)|V(dash|vdash)|r(h(o|d)|ceil|times|i(singdotseq|ght(s(quigarrow|lice)|harpoon(down|up)|threetimes|left(harpoons|arrows)|arrow(t(ail|riangle))?|rightarrows))|floor|angle|r(ceil|parenthesis|floor|bracket)|bag)|g(n(sim|eq(q)?|approx)|tr(sim|dot|eq(qless|less)|less|approx)|imel|eq(slant|q)?|vertneqq|amma|g(g)?)|Finv|xi|m(ho|i(nuso|d)|o(o|dels)|u(ltimap)?|p|e(asuredangle|rge)|aps(to|from(char)?))|b(i(n(dnasrepma|ampersand)|g(s(tar|qc(up|ap))|nplus|c(irc|u(p|rly(vee|wedge))|ap)|triangle(down|up)|interleave|o(times|dot|plus)|uplus|parallel|vee|wedge|box))|o(t|wtie|x(slash|circle|times|dot|plus|empty|ast|minus|b(slash|ox|ar)))|u(llet|mpeq)|e(cause|t(h|ween|a))|lack(square|triangle(down|left|right)?|lozenge)|a(ck(s(im(eq)?|lash)|prime|epsilon)|r(o|wedge))|bslash)|L(sh|ong(left(arrow|rightarrow)|rightarrow|maps(to|from))|eft(arrow|rightarrow)|leftarrow|ambda|bag)|Arrownot)\b name constant.character.math.tex captures 1 name punctuation.definition.constant.math.tex match (\\)(sum|prod|coprod|int|oint|bigcap|bigcup|bigsqcup|bigvee|bigwedge|bigodot|bigotimes|bogoplus|biguplus)\b name constant.character.math.tex captures 1 name punctuation.definition.constant.math.tex match (\\)(arccos|arcsin|arctan|arg|cos|cosh|cot|coth|csc|deg|det|dim|exp|gcd|hom|inf|ker|lg|lim|liminf|limsup|ln|log|max|min|pr|sec|sin|sinh|sup|tan|tanh)\b name constant.other.math.tex begin ((\\)Sexpr)(\{) beginCaptures 1 name support.function.sexpr.math.tex 2 name punctuation.definition.function.math.tex 3 name punctuation.section.embedded.begin.math.tex contentName source.r.embedded.math.tex end (\}) endCaptures 1 name punctuation.section.embedded.end.math.tex name meta.function.sexpr.math.tex patterns include source.r captures 1 name punctuation.definition.constant.math.tex match (\\)([^a-zA-Z]|[A-Za-z]+)(?=\b|\}|\]|\^|\_) name constant.other.general.math.tex match (([0-9]*[\.][0-9]+)|[0-9]+) name constant.numeric.math.tex match «press a-z and space for greek letter»[a-zA-Z]* name meta.placeholder.greek.math.tex scopeName text.tex.math uuid 027D6AF4-E9D3-4250-82A1-8A42EEFE4F76 PKW4=8W3 $ $Bibtex.tmLanguage comment Grammar based on description from http://artis.imag.fr/~Xavier.Decoret/resources/xdkbibtex/bibtex_summary.html#comment TODO: Does not support @preamble fileTypes bib foldingStartMarker \@[a-zA-Z]+\s*[{(].+, foldingStopMarker ^\s*[)}]\s*$ name BibTeX patterns begin @Comment beginCaptures 0 name punctuation.definition.comment.bibtex end $\n? name comment.line.at-sign.bibtex begin ((@)String)\s*(\{)\s*([a-zA-Z]*) beginCaptures 1 name keyword.other.string-constant.bibtex 2 name punctuation.definition.keyword.bibtex 3 name punctuation.section.string-constant.begin.bibtex 4 name variable.other.bibtex end \} endCaptures 0 name punctuation.section.string-constant.end.bibtex name meta.string-constant.braces.bibtex patterns include #string_content begin ((@)String)\s*(\()\s*([a-zA-Z]*) beginCaptures 1 name keyword.other.string-constant.bibtex 2 name punctuation.definition.keyword.bibtex 3 name punctuation.section.string-constant.begin.bibtex 4 name variable.other.bibtex end \) endCaptures 0 name punctuation.section.string-constant.end.bibtex name meta.string-constant.parenthesis.bibtex patterns include #string_content begin ((@)[a-zA-Z]+)\s*(\{)\s*([^\s,]*) beginCaptures 1 name keyword.other.entry-type.bibtex 2 name punctuation.definition.keyword.bibtex 3 name punctuation.section.entry.begin.bibtex 4 name entity.name.type.entry-key.bibtex end \} endCaptures 0 name punctuation.section.entry.end.bibtex name meta.entry.braces.bibtex patterns begin ([a-zA-Z]+)\s*(\=) beginCaptures 1 name string.unquoted.key.bibtex 2 name punctuation.separator.key-value.bibtex end (?=[,}]) name meta.key-assignment.bibtex patterns include #string_content include #integer begin ((@)[a-zA-Z]+)\s*(\()\s*([^\s,]*) beginCaptures 1 name keyword.other.entry-type.bibtex 2 name punctuation.definition.keyword.bibtex 3 name punctuation.section.entry.begin.bibtex 4 name entity.name.type.entry-key.bibtex end \) endCaptures 0 name punctuation.section.entry.end.bibtex name meta.entry.parenthesis.bibtex patterns begin ([a-zA-Z]+)\s*(\=) beginCaptures 1 name string.unquoted.key.bibtex 2 name punctuation.separator.key-value.bibtex end (?=[,)]) name meta.key-assignment.bibtex patterns include #string_content include #integer begin [^@\n] end (?=@) name comment.block.bibtex repository integer match \d+ name constant.numeric.bibtex nested_braces begin \{ beginCaptures 0 name punctuation.definition.group.begin.bibtex end \} endCaptures 0 name punctuation.definition.group.end.bibtex patterns include #nested_braces string_content patterns begin " beginCaptures 0 name punctuation.definition.string.begin.bibtex end " endCaptures 0 name punctuation.definition.string.end.bibtex name string.quoted.double.bibtex patterns include #nested_braces begin \{ beginCaptures 0 name punctuation.definition.string.begin.bibtex end \} endCaptures 0 name punctuation.definition.string.end.bibtex name string.quoted.other.braces.bibtex patterns match @ name invalid.illegal.at-sign.bibtex include #nested_braces scopeName text.bibtex uuid 47F30BA1-6B1D-11D9-9A60-000D93589AF6 PKW4=7VLaTeX.tmLanguage fileTypes tex firstLineMatch ^\\documentclass(?!.*\{beamer\}) foldingStartMarker \\begin\{.*\}|%.*\(fold\)\s*$ foldingStopMarker \\end\{.*\}|%.*\(end\)\s*$ keyEquivalent ^~L name LaTeX patterns match (?=\s)(?<=\\[\w@]|\\[\w@]{2}|\\[\w@]{3}|\\[\w@]{4}|\\[\w@]{5}|\\[\w@]{6})\s name meta.space-after-command.latex begin ((\\)(?:usepackage|documentclass))(?:(\[)([^\]]*)(\]))?(\{) beginCaptures 1 name keyword.control.preamble.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.latex 5 name punctuation.definition.arguments.end.latex 6 name punctuation.definition.arguments.begin.latex contentName support.class.latex end \} endCaptures 0 name punctuation.definition.arguments.end.latex name meta.preamble.latex patterns include $self begin ((\\)(?:include|input))(\{) beginCaptures 1 name keyword.control.include.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex contentName support.class.latex end \} endCaptures 0 name punctuation.definition.arguments.end.latex name meta.include.latex patterns include $self begin (?x) ( # Capture 1 (\\) # Marker (?: (?:sub){0,2}section # Functions | (?:sub)?paragraph | chapter|part|addpart | addchap|addsec|minisec ) (?:\*)? # Optional Unnumbered ) (?: (\[)([^\[]*?)(\]) # Optional Title )?? (\{) # Opening Bracket beginCaptures 1 name support.function.section.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.optional.begin.latex 4 name entity.name.section.latex 5 name punctuation.definition.arguments.optional.end.latex 6 name punctuation.definition.arguments.begin.latex comment this works OK with all kinds of crazy stuff as long as section is one line contentName entity.name.section.latex end \} endCaptures 0 name punctuation.definition.arguments.end.latex name meta.function.section.latex patterns include $self begin (?:\s*)((\\)begin)(\{)(lstlisting)(\})(?:(\[).*(\]))?(\s*%\s*(?i:Java)\n?) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex 6 name punctuation.definition.arguments.optional.begin.latex 7 name punctuation.definition.arguments.optional.end.latex 8 name comment.line.percentage.latex contentName source.java.embedded end ((\\)end)(\{)(lstlisting)(\}) name meta.function.embedded.java.latex patterns include source.java begin (?:\s*)((\\)begin)(\{)(lstlisting)(\})(?:(\[).*(\]))?(\s*%\s*(?i:Python)\n?) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex 6 name punctuation.definition.arguments.optional.begin.latex 7 name punctuation.definition.arguments.optional.end.latex 8 name comment.line.percentage.latex comment Put the lstlisting match before the more general environment listing. Someday it would be nice to make this rule general enough to figure out which language is inside the lstlisting environment rather than my own personal use for python. --Brad contentName source.python.embedded end ((\\)end)(\{)(lstlisting)(\}) name meta.function.embedded.python.latex patterns include source.python begin (?:\s*)((\\)begin)(\{)(lstlisting)(\})(?:(\[).*(\]))?(\s*%.*\n?)? captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex 6 name punctuation.definition.arguments.optional.begin.latex 7 name punctuation.definition.arguments.optional.end.latex 8 name comment.line.percentage.latex comment Put the lstlisting match before the more general environment listing. Someday it would be nice to make this rule general enough to figure out which language is inside the lstlisting environment rather than my own personal use for python. --Brad contentName source.generic.embedded end ((\\)end)(\{)(lstlisting)(\}) name meta.function.embedded.generic.latex begin (?:\s*)((\\)begin)(\{)((?:V|v)erbatim|alltt)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex contentName markup.raw.verbatim.latex end ((\\)end)(\{)(\4)(\}) name meta.function.verbatim.latex captures 1 name support.function.url.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name markup.underline.link.latex 5 name punctuation.definition.arguments.end.latex match (?:\s*)((\\)(?:url|href))(\{)([^}]*)(\}) name meta.function.link.url.latex captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex comment These two patterns match the \begin{document} and \end{document} commands, so that the environment matching pattern following them will ignore those commands. match (?:\s*)((\\)begin)(\{)(document)(\}) name meta.function.begin-document.latex captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex match (?:\s*)((\\)end)(\{)(document)(\}) name meta.function.end-document.latex begin (?x) (?:\s*) # Optional whitespace ((\\)begin) # Marker - Function (\{) # Open Bracket ( (?: align|equation|eqnarray # Argument | multline|aligned|alignat | split|gather|gathered ) (?:\*)? # Optional Unnumbered ) (\}) # Close Bracket (\s*\n)? # Match to end of line absent of content captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex contentName string.other.math.block.environment.latex end (?x) (?:\s*) # Optional whitespace ((\\)end) # Marker - Function (\{) # Open Bracket (\4) # Previous capture from begin (\}) # Close Bracket (?:\s*\n)? # Match to end of line absent of content name meta.function.environment.math.latex patterns include $base begin (?x) (?:\s*) # Optional whitespace ((\\)begin) # Marker - Function (\{) # Open Bracket (array|tabular[xy*]?) (\}) # Close Bracket (\s*\n)? # Match to end of line absent of content captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex contentName meta.data.environment.tabular.latex end (?x) (?:\s*) # Optional whitespace ((\\)end) # Marker - Function (\{) # Open Bracket (\4) # Previous capture from begin (\}) # Close Bracket (?:\s*\n)? # Match to end of line absent of content name meta.function.environment.tabular.latex patterns match \\ name punctuation.definition.table.row.latex begin (?:^|(?<=\\\\))(?!\\\\|\s*\\end\{(?:tabular|array)) end (?=\\\\|\s*\\end\{(?:tabular|array)) name meta.row.environment.tabular.latex patterns match & name punctuation.definition.table.cell.latex begin (?:^|(?<=&))((?!&|\\\\|$)) end (?=&|\\\\|\s*\\end\{(?:tabular|array)) name meta.cell.environment.tabular.latex patterns include $base include $base include $base begin (?:\s*)((\\)begin)(\{)(itemize|enumerate|description|list)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.latex end ((\\)end)(\{)(\4)(\})(?:\s*\n)? name meta.function.environment.list.latex patterns include $base begin (?:\s*)((\\)begin)(\{)(\w+[*]?)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.latex end ((\\)end)(\{)(\4)(\})(?:\s*\n)? name meta.function.environment.general.latex patterns include $base captures 1 name punctuation.definition.function.latex match (\\)(newcommand|renewcommand)\b name storage.type.function.latex begin ((\\)marginpar)(\{) beginCaptures 1 name support.function.marginpar.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.marginpar.begin.latex contentName meta.paragraph.margin.latex end \} endCaptures 0 name punctuation.definition.marginpar.end.latex patterns include $base begin ((\\)footnote)(\{) beginCaptures 1 name support.function.footnote.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.footnote.begin.latex contentName meta.footnote.latex end \} endCaptures 0 name punctuation.definition.footnote.end.latex patterns include $base begin ((\\)emph)(\{) beginCaptures 1 name support.function.emph.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.emph.begin.latex contentName markup.italic.emph.latex end \} endCaptures 0 name punctuation.definition.emph.end.latex name meta.function.emph.latex patterns include $base begin ((\\)textit)(\{) captures 1 name support.function.textit.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.textit.begin.latex comment We put the keyword in a capture and name this capture, so that disabling spell checking for “keyword” won't be inherited by the argument to \textit{...}. Put specific matches for particular LaTeX keyword.functions before the last two more general functions contentName markup.italic.textit.latex end \} endCaptures 0 name punctuation.definition.textit.end.latex name meta.function.textit.latex patterns include $base begin ((\\)textbf)(\{) captures 1 name support.function.textbf.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.textbf.begin.latex contentName markup.bold.textbf.latex end \} endCaptures 0 name punctuation.definition.textbf.end.latex name meta.function.textbf.latex patterns include $base begin ((\\)texttt)(\{) captures 1 name support.function.texttt.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.texttt.begin.latex contentName markup.raw.texttt.latex end \} endCaptures 0 name punctuation.definition.texttt.end.latex name meta.function.texttt.latex patterns include $base captures 0 name keyword.other.item.latex 1 name punctuation.definition.keyword.latex match (\\)item\b name meta.scope.item.latex begin (?x) ( (\\) # Marker (?:foot)?(?:full)?(?:no)?(?:short)? # Function Name [cC]ite (?:al)?(?:t|p|author|year(?:par)?|title)?[ANP]* \*? # Optional Unabreviated ) (?:(\[)[^\]]*(\]))? # Optional (?:(\[)[^\]]*(\]))? # Arguments (\{) # Opening Bracket captures 1 name keyword.control.cite.latex 2 name punctuation.definition.keyword.latex 3 name punctuation.definition.arguments.optional.begin.latex 4 name punctuation.definition.arguments.optional.end.latex 5 name punctuation.definition.arguments.optional.begin.latex 6 name punctuation.definition.arguments.optional.end.latex 7 name punctuation.definition.arguments.latex end \} endCaptures 0 name punctuation.definition.arguments.latex name meta.citation.latex patterns match [\w:.]+ name constant.other.reference.citation.latex begin ((\\)(?:\w*[r|R]ef\*?))(\{) beginCaptures 1 name keyword.control.ref.latex 2 name punctuation.definition.keyword.latex 3 name punctuation.definition.arguments.begin.latex end \} endCaptures 0 name punctuation.definition.arguments.begin.latex name meta.reference.label.latex patterns match [a-zA-Z0-9\.,:/*!^_-] name constant.other.reference.label.latex begin ((\\)label)(\{) beginCaptures 1 name keyword.control.label.latex 2 name punctuation.definition.keyword.latex 3 name punctuation.definition.arguments.begin.latex end \} endCaptures 0 name punctuation.definition.arguments.end.latex name meta.definition.label.latex patterns match [a-zA-Z0-9\.,:/*!^_-] name variable.parameter.definition.label.latex begin ((\\)verb[\*]?)\s*((\\)scantokens)(\{) beginCaptures 1 name support.function.verb.latex 2 name punctuation.definition.function.latex 3 name support.function.verb.latex 4 name punctuation.definition.verb.latex 5 name punctuation.definition.begin.latex contentName markup.raw.verb.latex end (\}) endCaptures 1 name punctuation.definition.end.latex name meta.function.verb.latex patterns include $self captures 1 name support.function.verb.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.verb.latex 4 name markup.raw.verb.latex 5 name punctuation.definition.verb.latex match ((\\)verb[\*]?)\s*((?<=\s)\S|[^a-zA-Z])(.*?)(\3|$) name meta.function.verb.latex begin "` beginCaptures 0 name punctuation.definition.string.begin.latex end "' endCaptures 0 name punctuation.definition.string.end.latex name string.quoted.double.european.latex patterns include $base begin `` beginCaptures 0 name punctuation.definition.string.begin.latex end ''|" endCaptures 0 name punctuation.definition.string.end.latex name string.quoted.double.latex patterns include $base begin "> beginCaptures 0 name punctuation.definition.string.begin.latex end "< endCaptures 0 name punctuation.definition.string.end.latex name string.quoted.double.guillemot.latex patterns include $base begin "< beginCaptures 0 name punctuation.definition.string.begin.latex end "> endCaptures 0 name punctuation.definition.string.end.latex name string.quoted.double.guillemot.latex patterns include $base begin \\\( beginCaptures 0 name punctuation.definition.string.begin.latex end \\\) endCaptures 0 name punctuation.definition.string.end.latex name string.other.math.latex patterns include $base begin \\\[ beginCaptures 0 name punctuation.definition.string.begin.latex end \\\] endCaptures 0 name punctuation.definition.string.end.latex name string.other.math.latex patterns include $base match (?<!\S)'.*?' name invalid.illegal.string.quoted.single.latex match (?<!\S)".*?" name invalid.illegal.string.quoted.double.latex captures 1 name punctuation.definition.constant.latex match (\\)(text(s(terling|ixoldstyle|urd|e(ction|venoldstyle|rvicemark))|yen|n(ineoldstyle|umero|aira)|c(ircledP|o(py(left|right)|lonmonetary)|urrency|e(nt(oldstyle)?|lsius))|t(hree(superior|oldstyle|quarters(emdash)?)|i(ldelow|mes)|w(o(superior|oldstyle)|elveudash)|rademark)|interrobang(down)?|zerooldstyle|o(hm|ne(superior|half|oldstyle|quarter)|penbullet|rd(feminine|masculine))|d(i(scount|ed|v(orced)?)|o(ng|wnarrow|llar(oldstyle)?)|egree|agger(dbl)?|blhyphen(char)?)|uparrow|p(ilcrow|e(so|r(t(housand|enthousand)|iodcentered))|aragraph|m)|e(stimated|ightoldstyle|uro)|quotes(traight(dblbase|base)|ingle)|f(iveoldstyle|ouroldstyle|lorin|ractionsolidus)|won|l(not|ira|e(ftarrow|af)|quill|angle|brackdbl)|a(s(cii(caron|dieresis|acute|grave|macron|breve)|teriskcentered)|cutedbl)|r(ightarrow|e(cipe|ferencemark|gistered)|quill|angle|brackdbl)|g(uarani|ravedbl)|m(ho|inus|u(sicalnote)?|arried)|b(igcircle|orn|ullet|lank|a(ht|rdbl)|rokenbar)))\b name constant.character.latex captures 1 name punctuation.definition.column-specials.begin.latex 2 name punctuation.definition.column-specials.end.latex match (?:<|>)(\{)\$(\}) name meta.column-specials.latex include text.tex scopeName text.tex.latex uuid 3BEEA00C-6B1D-11D9-B8AD-000D93589AF6 PKW4=B=Emphasize.sublime-snippet em text.tex.latex Emphasize PKW4=Dd_ Displaymath-($$).sublime-snippet $$ text.tex.latex Display Math — \[ … \] PKW4=/?Equation.sublime-snippet eq text.tex.latex Equation PKW4=5AAChapter.sublime-snippet cha text.tex.latex Chapter PKW4=-A A DDEExecute.pyimport sublime, sublimeplugin from ctypes import * # Send DDE Execute command to running program class SendDDEExecuteCommand(sublimeplugin.TextCommand): def run(self, view, args): # define win32 api functions DdeInitialize = windll.user32.DdeInitializeW DdeUninitialize = windll.user32.DdeUninitialize DdeConnect = windll.user32.DdeConnect DdeDisconnect = windll.user32.DdeDisconnect DdeClientTransaction = windll.user32.DdeClientTransaction DdeCreateStringHandle = windll.user32.DdeCreateStringHandleW DdeFreeStringHandle = windll.user32.DdeFreeStringHandle DdeFreeDataHandle = windll.user32.DdeFreeDataHandle # Dde callback definition DDECALLBACK = WINFUNCTYPE(c_void_p, c_uint, c_uint, c_void_p, c_void_p, c_void_p, c_void_p, c_ulong, c_ulong) def py_mycallback(uType, uFmt, hconv, hsz1, hsz2, hdata, dwData1, dwData2): return 0 mycallback = DDECALLBACK(py_mycallback) # Instance ID (filled out by DdeInitialize) idInst = c_uint(0) # Conversation handle hConv = 0 # server and topic names, as LPTSTR = wchar * service = c_wchar_p(args[0]) topic = c_wchar_p(args[1]) command = args[2] pData = c_char_p(command) cbData = len(command) # initialize ret = DdeInitialize(byref(idInst), pointer(mycallback), 0, 0) # for the next two calls, the last param is the codepage: # 1004 = CP_Winansi, 1200 = CP_WINUNICODE hszService = DdeCreateStringHandle(idInst, service, 1200) hszTopic = DdeCreateStringHandle(idInst, topic, 1200) hConv = DdeConnect(idInst, hszService, hszTopic, 0) if hConv: # zero means we could not connect for some reason #print "start!" XTYP_EXECUTE = int("4050",16) # transaction type; note -1 for timeout_async hDdeData = DdeClientTransaction(pData, cbData, hConv, 0, 0, XTYP_EXECUTE, 10000, 0) print "DDE Execute returned: ", hex(windll.user32.DdeGetLastError(idInst)) DdeFreeDataHandle(hDdeData) #print ret, idInst, hszService, hszTopic, hConv # test of string handles #buf = create_string_buffer(200) #print windll.user32.DdeQueryStringW(idInst, hszService, buf, 100, 1200) #print repr(buf.raw) # OK, this works! DdeFreeStringHandle(idInst, hszTopic) DdeFreeStringHandle(idInst, hszService) DdeDisconnect(hConv) DdeUninitialize(idInst) PKW4=df  Default.sublime-keymap PKW4=<<<Tabular.sublime-snippet tab text.tex.latex Tabular PKW4=eLaTeX Memoir.tmLanguage fileTypes firstLineMatch ^\\documentclass(\[.*\])?\{memoir\} foldingStartMarker \\begin\{.*\}|%.*\(fold\)\s*$ foldingStopMarker \\end\{.*\}|%.*\(end\)\s*$ keyEquivalent ^~M name LaTeX Memoir patterns begin (?:\s*)((\\)begin)(\{)(framed|shaded|leftbar)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex end ((\\)end)(\{)(\4)(\}) name meta.function.memoir-fbox.latex patterns include $self begin (?:\s*)((\\)begin)(\{)((?:fboxv|boxedv|V)erbatim)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex contentName markup.raw.verbatim.latex end ((\\)end)(\{)(\4)(\}) name meta.function.memoir-verbatim.latex begin (?:\s*)((\\)begin)(\{)(alltt)(\}) captures 1 name support.function.be.latex 2 name punctuation.definition.function.latex 3 name punctuation.definition.arguments.begin.latex 4 name variable.parameter.function.latex 5 name punctuation.definition.arguments.end.latex contentName markup.raw.verbatim.latex end ((\\)end)(\{)(alltt)(\}) name meta.function.memoir-alltt.latex patterns captures 1 name punctuation.definition.function.tex match (\\)[A-Za-z]+ name support.function.general.tex include text.tex.latex scopeName text.tex.latex.memoir uuid D0853B20-ABFF-48AB-8AB9-3D8BA0755C05 PKW4=HSplit.sublime-snippet spl text.tex.latex Split PKW4=,f@,, README.txtLaTeX Package for Sublime Text ============================== First draft "release" September 21, 2009 Current revision May 29, 2010 Contributors: Marciano Siniscalchi (more to come I hope!) For more information, see Introduction ------------ This package provides support for editing TeX / LaTeX files, emulating functionality in TextMate's well-known LaTeX bundle. Like its TextMate counterpart, it is designed with the creation of *PDF* rather than *DVI* output in mind. While it is not(yet!) as powerful as its TextMate counterpart, it does offer a number of convenient features: * A command to run tex & friends, and then show the user any errors that might have occurred * A command to view the PDF file, setting things up so that **PDF forward and inverse search** work (see below for details) * Quick insertion of Greek letters and other LaTeX macros, e.c. `\sum`, `\bigcup` etc. * Insertion of references (`\ref{xxx}`) and citations (`\cite{xxx}`), listing the available labels or, respectively, keys in a pop-up menu or quick-panel * Closing the current environment * Inserting emphasize / boldface commands (more in the future) The most useful feature is probably PDF forward/inverse search. The TeX/LaTeX world has moved beyond DVI; on the Mac, PDF output is the default for LaTeX documents, thanks to excellent built-in support for PDF rendering, and several great PDF previewers. The "SyncTeX" technology has finally brought reliable forward- and inverse-search to PDF documents. Luckily, SyncTeX is built into MikTeX from version 2.7 up, and the [SumatraPDF][] previewer. The same technology is also used by TextMate and the Skim previewer on the Mac, and makes for a much more efficient and enjoyable texing experience. *Inverse search* means that you can double-click anywhere in the PDF window, and you jump right back to the corresponding point in the source tex file. *Forward search* is the opposite: by invoking the appropriate command or shortcut ("jumpToPDF" and `ctrl+alt+j` in this package), the PDF file scrolls to the line corresponding to the current position of the cursor in the source tex file. These are *huge* time savers! Sublime Text has a very sane command-line syntax, which makes it relatively easy to implement this feature. [SumatraPDF]: http://blog.kowalczyk.info/software/sumatrapdf/ "SumatraPDF" All commands are available both via keyboard shortcuts and from the `Tools|Packages|LaTeX Package` menu. (Invoking snippets from the menu does not seem to work right now: use the tab trigger) This document is divided into sections, each describing a different aspect of LaTeX editing and processing that this package aids or enhances. Each section begins with a list of *commands* and the corresponding *default shortcuts*, followed by an explanation of the features provided, and in some cases a list of requirements. The latter explanation always refers to *commands* rather than shortcuts. This way, if you choose to change one or more shortcuts, the text will still be accurate. Compiling and viewing your document ----------------------------------- ###Commands and Shortcuts texify : `ctrl+alt+t` showTeXErrors : `ctrl+alt+e` viewPDF : `ctrl+alt+v` jumpToPDF: `ctrl+alt+j` ###Explanation The "texify" command compiles the file in the current buffer, invoking `texify` (which in turn takes care of invoking e.g. `bibtex`, `makeindex`, etc. as needed). Furthermore, it sets up forward and inverse search with the SumatraPDF previewer, using the SyncTeX technology. The previewer is *not* automatically started; use the viewPDF command. When the "texify" command is invoked, it brings up a quick panel, which initially indicates the actual `texify` command issued. Then, if errors or warnings are detected, the quick panel is populated with a list of corresponding "helpful" one-line messages taken from the *last* log file generated by tex and friends, followed by the full output of the `texify` command. In most cases, the one-line error/warning messages suffice to identify the problem; when this is not the case, the full texify output can be useful. The full search / filtering capabilities of the quick panel may come in handy in this case. Wherever an error/warning message indicating a line number appears in the quick panel, you can click on it and you will be taken to the offending line in the source file. The quick panel is closed upon clicking one line, but you can reopen it via the "showTeXErrors" command Two small caveats. First, remember that `texify` runs tex and friends multiple times; the plugin captures its entire output (sent to either STDOUT or STDERR), which may reflect multiple runs. In particular, undefined references may be resolved in later runs, so the output from `texify` may show warnings that are not present in the last log file. Second, the "showTeXErrors" command displays the one-line messages, followed by the contents of the last log file---not the output from the texify command. If the `texify` command cannot be invoked (typically because it is not on the path), an error dialog is shown. A "build system" profile is also provided; you can run pdflatex by hitting the standard F7 key (or whatever you use to build stuff) as well, but error detection is very flaky. Consider this experimental for the time being, and use the "texify" command instead. ###Requirements * MiKTeX distribution at ; I have ver. 2.7; ver. 2.8 also works * SumatraPDF previewer, ver. 0.93, 0.94 or recent preview release at * Make sure that both SumatraPDF and Sublime Text are on the `%PATH%` Show document structure ----------------------- ###Shortcut texSections : `ctrl+shift+s` ###Explanation Displays parts, chapters, sections, subsections, etc. in a quick panel, indented to emphasize the overall structure of the document. The command also finds Beamer `frame`s, and will display the frame title as long as it is provided *on the same line* as the `\begin{frame}` statement, either as part of the latter or in an explicit `\frametitle{...}` command. Click on any line and you will be taken to the corresponding point in the source tex file. Easy insertion of tex math macros --------------------------------- ###Shortcuts texMacro : `ctrl+shift+\` ###Explanation This feature is also inspired by TextMate's LaTeX bundle, and implemented stealing ideas from the html snippets. I used the Textmate keybindings, but that can (and perhaps should) be changed. Basic idea, using Sublime Text notation `key1, key2+key3` to mean "press `key1`, then press `key2` and `key3` simultaneously": `a, ctrl+backslash` gives `\alpha` `b, ctrl+backslash` gives `\beta` ... `A, ctrl+backslash` gives `\forall` etc. Look at the `texMacro.py` file for a complete list of available shortcuts. You can also add your own shortcuts to the `macros` Python dictionary. Your shortcut can consists of letters or numbers, without spaces or other symbols. Remember to escape the leading backslash. References and citations ------------------------ ###Shortcuts texRef : `ctrl+alt+r` texCite : `ctrl+alt+c` lookupRefCite : `ctrl+alt+l` ###Explanation This is functionality that might perhaps be achieved with ctags. Suppose you have something like: \begin{lemma} \label{lem:result} ... \end{lemma} in your file. You then need to reference this lemma later on. Invoke the texRef command and pick from the list. In particular, if you begin writing `lem` and then hit `ctrl+alt+r`, only labels beginning with "lem" are shown. The `\ref{...}` command is NOT automatically inserted for you. So, the typical use case is to enter `\ref{` (which generates a matching `}` and places the cursor in between the braces), hit `ctrl+alt+r`, and choose the label. If there are no more than 16 matches, then a pop-up completion menu is shown; otherwise, the quick panel will list all matches. Similarly for citations: entries, however, are drawn from a bibtex file (specified by the `\bibliography` command in your tex file). This pops up a quick panel that shows both the key and the title of the article or book. The `\cite{...}` command is automatically inserted, and the word `cite` is highlighted so you can change it to, e.g. `citep` or `citet` if you use natbib. Hitting Tab moves you after the closing brace. There is an attempt to handle multiple cites; if you start a cite command, then type a comma, as in \cite{mycite1,} and invoke texCite again, the quick panel is shown with a list of all citations. But if you try to provide a prefix, it won't work. Finally, I often forget what a given label is associated with. If you are like me, no worries: that's what the "lookupRefCite" command is for! Position the cursor immediately after the brace in a `\ref{mystery_label}` command (or similar), invoke the "lookupRefCite" command, and a quick panel will pop up, displaying some text before and after the corresponding `\label{mystery_label}` command. This will be extended to `\cite{}` commands as well, but right now this functionality is not implemented. Environment closer ------------------ ###Shortcuts: latexEnvCloser : `ctrl+alt+.` ###Explanation Looks for the last `\begin{...}` that is not matched by the corresponding `\end{...}`, and inserts the `\end{...}` statement automatically. It also checks for mismatched `begin/end` pairs, just in case. Insert command or environment based on current word --------------------------------------------------- ###Shortcuts: latexEnvironment : `ctrl+shift+[` latexCommand : `ctrl+shift+]` ###Explanation Type `test`, invoke latexCommand, get `\test{}` with the cursor between braces; type something, then hit Tab to exit the braces. Similarly, type `test`, invoke latexEnvironment, get \begin{test} \end{test} with the cursor inside the environment. Again, Tab exits the environment. Miscellaneous commands/snippets ------------------------------- "Emphasize" (`e,m,tab`) enters `\emph{}` and drops the cursor between the braces. Hit tab to exit the braces. "Boldface" does the same, but enters `\textbf{}`. "Color" (`c,o,l,o,r,tab`) is intended to work in conjunction with the `xcolor` package. It enters `{\color{} }` and drops the cursor between the inner pair of braces; you can enter a color specification, then hit tab to move immediately before the last closing brace, where you can enter the text you want to be typeset in the color you specified. Finally, one last tab will move the cursor outside the braces. "Frame" (`f,r,a,m,e,tab`) is intended to work with the popular Beamer package. It enters `\begin{frame}[t]{title}`, a blank line, then `\end{frame}`. The `[t]` is highlighted; you can change the alignment specification if you wish (`t` is for top, `c` is for center, etc.). Hitting tab highlights the `title`, which of course you should adapt to suit your needs. Hitting `tab` again places the cursor on the blank line inside the frame environment. "Beamer box" (`b,o,x,tab`) is also meant for use with Beamer. It enters the `\begin{beamerboxesrounded}...` command, with some useful defaults and title; as above, hit tab to move to the different fields. PKW4=CqjXXSub-Paragraph.sublime-snippet subp text.tex.latex Sub Paragraph PKW4=8Cases.sublime-snippet cas text.tex.latex Cases PKW4=(lBoldface.sublime-snippet bf text.tex.latex Boldface PKW4=M(Matrix.sublime-snippetPKW4=~УTeX.tmLanguagePKW4=$Itemize.sublime-snippetPKW4=5]latexEnvCloser.pyPKW4=NŒbegin{}-end{}.sublime-snippetPKW4={(Listing.sublime-snippetPKW4=kD\q$latexEnvironment.pyPKW4=A# 4 viewPDF.pyPKW4=U2$Color.sublime-snippetPKW4=bUJ8%Beamer boxes.sublime-snippetPKW4=Ch&texSections.pyPKW4=Z; x/texify.pyPKW4=xll JjumpToPDF.pyPKW4=uɬJNFigure.sublime-snippetPKW4=RG AOLaTeX Log.tmLanguagePKW4=K,<\Description.sublime-snippetPKW4="̒R]lookupRefCite.pyPKW4=r3CjvblatexCommand.pyPKW4=Jo*dEnumerate.sublime-snippetPKW4=viH5eLaTeX.sublime-optionsPKW4=:ufTable.sublime-snippetPKW4=Zw{vv gtexMacro.pyPKW4=D mLaTeX.package-menuPKW4=^!brItem[description].sublime-snippetPKW4=YllsLaTeX.sublime-buildPKW4=gh]]'-tsubsubsection-..-(ssub).sublime-snippetPKW4=; ; uLaTeX Beamer.tmLanguagePKW4=c*}NN#?subsection-..-(sub).sublime-snippetPKW4=.cAA$΁section-..-(section).sublime-snippetPKW4=ՠQSection.sublime-snippetPKW4=F~IILParagraph.sublime-snippetPKW4= ̅texRef.pyPKW4=*S{Part.sublime-snippetPKW4=f(OBeamer frame.sublime-snippetPKW4=P??wComments.tmPreferencesPKW4=?_Page.sublime-snippetPKW4=@f בtexCite.pyPKW4=E2TeX Math.tmLanguagePKW4=8W3 $ $Bibtex.tmLanguagePKW4=7VLaTeX.tmLanguagePKW4=B=rEmphasize.sublime-snippetPKW4=Dd_ tDisplaymath-($$).sublime-snippetPKW4=/?uEquation.sublime-snippetPKW4=5AAvChapter.sublime-snippetPKW4=-A A 2xDDEExecute.pyPKW4=df  Default.sublime-keymapPKW4=<<<Tabular.sublime-snippetPKW4=ecLaTeX Memoir.tmLanguagePKW4=HSplit.sublime-snippetPKW4=,f@,, README.txtPKW4=CqjXXSub-Paragraph.sublime-snippetPKW4=8`Cases.sublime-snippetPKW4=(l~Boldface.sublime-snippetPK55 X