def find_labels_in_files(rootdir, src, labels): if not is_tex_file(src): src_tex_file = None for ext in get_tex_extensions(): src_tex_file = ''.join((src, ext)) if os.path.exists(os.path.join(rootdir, src_tex_file)): src = src_tex_file break if src != src_tex_file: print("Could not find file {0}".format(src)) return file_path = os.path.normpath(os.path.join(rootdir, src)) print("Searching file: " + repr(file_path)) # The following was a mistake: #dir_name = os.path.dirname(file_path) # THe reason is that \input and \include reference files **from the directory # of the master file**. So we must keep passing that (in rootdir). # read src file and extract all label tags # We open with utf-8 by default. If you use a different encoding, too bad. # If we really wanted to be safe, we would read until \begin{document}, # then stop. Hopefully we wouldn't encounter any non-ASCII chars there. # But for now do the dumb thing. try: src_file = codecs.open(file_path, "r", "UTF-8") except IOError: sublime.status_message( "LaTeXTools WARNING: cannot find included file " + file_path) print( "WARNING! I can't find it! Check your \\include's and \\input's.") return src_content = re.sub("%.*", "", src_file.read()) src_file.close() # If the file uses inputenc with a DIFFERENT encoding, try re-opening # This is still not ideal because we may still fail to decode properly, but still... m = re.search(r"\\usepackage\[(.*?)\]\{inputenc\}", src_content) if m and (m.group(1) not in ["utf8", "UTF-8", "utf-8"]): print("reopening with encoding " + m.group(1)) f = None try: f = codecs.open(file_path, "r", m.group(1)) src_content = re.sub("%.*", "", f.read()) except: print("Uh-oh, could not read file " + file_path + " with encoding " + m.group(1)) finally: if f and not f.closed: f.close() labels += re.findall(r'\\label\{([^{}]+)\}', src_content) # search through input tex files recursively for f in re.findall(r'\\(?:input|include|subfile)\{([^\{\}]+)\}', src_content): find_labels_in_files(rootdir, f, labels)
def find_labels_in_files(rootdir, src, labels): if not is_tex_file(src): src_tex_file = None for ext in get_tex_extensions(): src_tex_file = ''.join((src, ext)) if os.path.exists(os.path.join(rootdir, src_tex_file)): src = src_tex_file break if src != src_tex_file: print("Could not find file {0}".format(src)) return file_path = os.path.normpath(os.path.join(rootdir, src)) print ("Searching file: " + repr(file_path)) # The following was a mistake: #dir_name = os.path.dirname(file_path) # THe reason is that \input and \include reference files **from the directory # of the master file**. So we must keep passing that (in rootdir). # read src file and extract all label tags # We open with utf-8 by default. If you use a different encoding, too bad. # If we really wanted to be safe, we would read until \begin{document}, # then stop. Hopefully we wouldn't encounter any non-ASCII chars there. # But for now do the dumb thing. try: src_file = codecs.open(file_path, "r", "UTF-8") except IOError: sublime.status_message("LaTeXTools WARNING: cannot find included file " + file_path) print ("WARNING! I can't find it! Check your \\include's and \\input's." ) return src_content = re.sub("%.*", "", src_file.read()) src_file.close() # If the file uses inputenc with a DIFFERENT encoding, try re-opening # This is still not ideal because we may still fail to decode properly, but still... m = re.search(r"\\usepackage\[(.*?)\]\{inputenc\}", src_content) if m and (m.group(1) not in ["utf8", "UTF-8", "utf-8"]): print("reopening with encoding " + m.group(1)) f = None try: f = codecs.open(file_path, "r", m.group(1)) src_content = re.sub("%.*", "", f.read()) except: print("Uh-oh, could not read file " + file_path + " with encoding " + m.group(1)) finally: if f and not f.closed: f.close() labels += re.findall(r'\\label\{([^{}]+)\}', src_content) labels += re.findall(r'\\begin\{(?:definition|theorem|lemma|corollary|proof)\}\{[^}]*?\}\{([^}]*?)\}', src_content) # search through input tex files recursively for f in re.findall(r'\\(?:input|include)\{([^\{\}]+)\}', src_content): find_labels_in_files(rootdir, f, labels)
def detect_and_apply_syntax(self, view): if view.is_scratch() or not view.file_name(): return if view.score_selector(0, "text.tex"): return if not get_setting('latextools_set_syntax', True): return file_name = view.file_name() if is_tex_file(file_name): view.set_syntax_file(LATEX_SYNTAX)
def detect_and_apply_syntax(self, view): if view.is_scratch() or not view.file_name(): return current_syntax = view.settings().get('syntax') if current_syntax == LATEX_SYNTAX: return if not get_setting('latextools_set_syntax', True): return file_name = view.file_name() if is_tex_file(file_name): view.set_syntax_file(LATEX_SYNTAX)
def detect_and_apply_syntax(self, view): if view.is_scratch() or not view.file_name(): return current_syntax = view.settings().get("syntax") if current_syntax == LATEX_SYNTAX: return if not get_setting("latextools_set_syntax", True): return file_name = view.file_name() if is_tex_file(file_name): view.set_syntax_file(LATEX_SYNTAX)
def detect_and_apply_syntax(self, view): if view.is_scratch() or not view.file_name(): return current_syntax = view.settings().get('syntax') if current_syntax == LATEX_SYNTAX: return global_settings = sublime.load_settings('LaTeXTools.sublime-settings') if not view.settings().get('latextools_set_syntax', global_settings.get('latextools_set_syntax', True)): return file_name = view.file_name() if is_tex_file(file_name): view.set_syntax_file(LATEX_SYNTAX)
def run(self): prefs_lin = get_setting('linux', {}) view = self.window.active_view() if not is_tex_file(view.file_name()): sublime.error_message("%s is not a TeX source file: cannot view." % (os.path.basename(view.file_name()),)) return quotes = ""# \"" MUST CHECK WHETHER WE NEED QUOTES ON WINDOWS!!! root = getTeXRoot.get_tex_root(view) rootFile, rootExt = os.path.splitext(root) pdfFile = quotes + rootFile + '.pdf' + quotes s = platform.system() script_path = None if s == "Darwin": # for inverse search, set up a "Custom" sync profile, using # "subl" as command and "%file:%line" as argument # you also have to put a symlink to subl somewhere on your path # Also check the box "check for file changes" viewercmd = ["open", "-a", "Skim"] elif s == "Windows": # with new version of SumatraPDF, can set up Inverse # Search in the GUI: under Settings|Options... # Under "Set inverse search command-line", set: # sublime_text "%f":%l prefs_win = get_setting("windows", {}) su_binary = prefs_win.get("sumatra", "SumatraPDF.exe") viewercmd = [su_binary, "-reuse-instance"] elif s == "Linux": # the required scripts are in the 'evince' subdir script_path = os.path.join(sublime.packages_path(), 'LaTeXTools', 'evince') ev_sync_exec = os.path.join(script_path, 'evince_sync') # so we get inverse search # Get python binary if set in preferences: py_binary = prefs_lin["python2"] or 'python' sb_binary = prefs_lin["sublime"] or 'sublime-text' viewercmd = ['sh', ev_sync_exec, py_binary, sb_binary] else: sublime.error_message("Platform as yet unsupported. Sorry!") return print (viewercmd + [pdfFile]) try: Popen(viewercmd + [pdfFile], cwd=script_path) except OSError: sublime.error_message("Cannot launch Viewer. Make sure it is on your PATH.")
def get_tex_root(view): view_file = view.file_name() root = None directives = parse_tex_directives(view, only_for=['root']) try: root = directives['root'] except KeyError: pass else: if not is_tex_file(root): root = None elif not os.path.isabs(root) and view_file is not None: file_path, _ = os.path.split(view_file) root = os.path.normpath(os.path.join(file_path, root)) if root is None: root = get_tex_root_from_settings(view) if root is not None: return root return view_file
def find_bib_files(rootdir, src, bibfiles): if not is_tex_file(src): src_tex_file = None for ext in get_tex_extensions(): src_tex_file = ''.join((src, ext)) if os.path.exists(os.path.join(rootdir, src_tex_file)): src = src_tex_file break if src != src_tex_file: print("Could not find file {0}".format(src)) return file_path = os.path.normpath(os.path.join(rootdir,src)) print("Searching file: " + repr(file_path)) # See latex_ref_completion.py for why the following is wrong: #dir_name = os.path.dirname(file_path) # read src file and extract all bibliography tags try: src_file = codecs.open(file_path, "r", 'UTF-8') except IOError: sublime.status_message("LaTeXTools WARNING: cannot open included file " + file_path) print ("WARNING! I can't find it! Check your \\include's and \\input's.") return src_content = re.sub("%.*","",src_file.read()) src_file.close() m = re.search(r"\\usepackage\[(.*?)\]\{inputenc\}", src_content) if m: f = None try: f = codecs.open(file_path, "r", m.group(1)) src_content = re.sub("%.*", "", f.read()) except: pass finally: if f and not f.closed: f.close() # While these commands only allow a single resource as their argument... resources = re.findall(r'\\addbibresource(?:\[[^\]]+\])?\{([^\}]+\.bib)\}', src_content) resources += re.findall(r'\\addglobalbib(?:\[[^\]]+\])?\{([^\}]+\.bib)\}', src_content) resources += re.findall(r'\\addsectionbib(?:\[[^\]]+\])?\{([^\}]+\.bib)\}', src_content) # ... these can have a comma-separated list of resources as their argument. multi_resources = re.findall(r'\\begin\{refsection\}\[([^\]]+)\]', src_content) multi_resources += re.findall(r'\\bibliography\{([^\}]+)\}', src_content) multi_resources += re.findall(r'\\nobibliography\{([^\}]+)\}', src_content) for multi_resource in multi_resources: for res in multi_resource.split(','): res = res.strip() if res[-4:].lower() != '.bib': res = res + '.bib' resources.append(res) # extract absolute filepath for each bib file for res in resources: # We join with rootdir, the dir of the master file candidate_file = os.path.normpath(os.path.join(rootdir, res)) # if the file doesn't exist, search the default tex paths if not os.path.exists(candidate_file): candidate_file = kpsewhich(res, 'mlbib') if candidate_file is not None and os.path.exists(candidate_file): bibfiles.append(candidate_file) # search through input tex files recursively for f in re.findall(r'\\(?:input|include|subfile)\{[^\}]+\}',src_content): input_f = re.search(r'\{([^\}]+)', f).group(1) find_bib_files(rootdir, input_f, bibfiles)
def run(self, cmd="", file_regex="", path=""): # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") if sublime.platform() == 'windows': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), startupinfo=startupinfo, shell=True ) else: os.killpg(self.proc.pid, signal.SIGTERM) self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base, self.tex_ext = os.path.splitext(self.file_name) tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("exec") # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("exec") self.output_view.settings().set("result_file_regex", "^([^:\n\r]*):([0-9]+):?([0-9]+)?:? (.*)$") # self.output_view.settings().set("result_line_regex", line_regex) self.output_view.settings().set("result_base_dir", tex_dir) self.window.run_command("show_panel", {"panel": "output.exec"}) self.output_view.settings().set("result_file_regex", file_regex) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) builder_name = get_setting("builder", "traditional") self.hide_panel_level = get_setting("hide_build_panel", "never") # This *must* exist, so if it doesn't, the user didn't migrate if builder_name is None: sublime.error_message("LaTeXTools: you need to migrate your preferences. See the README file for instructions.") return # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # relative to ST packages dir! builder_path = get_setting("builder_path", "") builder_file_name = builder_name + 'Builder.py' builder_class_name = builder_name.capitalize() + 'Builder' builder_settings = get_setting("builder_settings", {}) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat) if builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'default','']: builder_path = None # Now actually get the builder ltt_path = os.path.join(sublime.packages_path(),'LaTeXTools','builders') if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) else: bld_path = ltt_path bld_file = os.path.join(bld_path, builder_file_name) if not os.path.isfile(bld_file): sublime.error_message("Cannot find builder " + builder_name + ".\n" \ "Check your LaTeXTools Preferences") return # We save the system path and TEMPORARILY add the builders path to it, # so we can simply "import pdfBuilder" in the builder module # For custom builders, we need to add both the LaTeXTools builders # path, as well as the custom path specified above. # The mechanics are from http://effbot.org/zone/import-string.htm syspath_save = list(sys.path) sys.path.insert(0, ltt_path) if builder_path: sys.path.insert(0, bld_path) builder_module = __import__(builder_name + 'Builder') sys.path[:] = syspath_save print(repr(builder_module)) builder_class = getattr(builder_module, builder_class_name) print(repr(builder_class)) # We should now be able to construct the builder object self.builder = builder_class(self.file_name, self.output, builder_settings, platform_settings) # Restore Python system path sys.path[:] = syspath_save # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! self.path = platform_settings['texpath'] os.chdir(tex_dir) CmdThread(self).start() print (threading.active_count())
def run(self, edit, **args): # Check prefs for PDF focus and sync keep_focus = get_setting('keep_focus', True) forward_sync = get_setting('forward_sync', True) prefs_lin = get_setting("linux", {}) prefs_win = get_setting("windows", {}) # If invoked from keybinding, we sync # Rationale: if the user invokes the jump command, s/he wants to see the result of the compilation. # If the PDF viewer window is already visible, s/he probably wants to sync, or s/he would have no # need to invoke the command. And if it is not visible, the natural way to just bring up the # window without syncing is by using the system's window management shortcuts. # As for focusing, we honor the toggles / prefs. from_keybinding = args[ "from_keybinding"] if "from_keybinding" in args else False if from_keybinding: forward_sync = True print(from_keybinding, keep_focus, forward_sync) if not is_tex_file(self.view.file_name()): sublime.error_message("%s is not a TeX source file: cannot jump." % (os.path.basename(view.fileName()), )) return quotes = "\"" root = getTeXRoot.get_tex_root(self.view) print("!TEX root = ", repr(root)) # need something better here, but this works. rootName, rootExt = os.path.splitext(root) pdffile = rootName + u'.pdf' (line, col) = self.view.rowcol(self.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 # issue #625: we need to pass the path to the file to the viewer when # there are files in subfolders of the main folder. # Thanks rstein and arahlin for this code! srcfile = self.view.file_name() # Query view settings to see if we need to keep focus or let the PDF viewer grab it # By default, we respect settings in Preferences # platform-specific code: plat = sublime_plugin.sys.platform if plat == 'darwin': options = ["-r", "-g"] if keep_focus else ["-r"] if forward_sync: path_to_skim = '/Applications/Skim.app/' if not os.path.exists(path_to_skim): path_to_skim = subprocess.check_output([ 'osascript', '-e', 'POSIX path of (path to app id "net.sourceforge.skim-app.skim")' ]).decode("utf8")[:-1] subprocess.Popen([ os.path.join(path_to_skim, "Contents/SharedSupport/displayline") ] + options + [str(line), pdffile, srcfile]) else: skim = os.path.join(sublime.packages_path(), 'LaTeXTools', 'skim', 'displayfile') subprocess.Popen(['sh', skim] + options + [pdffile]) elif plat == 'win32': # determine if Sumatra is running, launch it if not print("Windows, Calling Sumatra") si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.wShowWindow = 4 #constant for SHOWNOACTIVATE su_binary = prefs_win.get("sumatra", "SumatraPDF.exe") or 'SumatraPDF.exe' startCommands = [su_binary, "-reuse-instance"] if forward_sync: startCommands.append("-forward-search") startCommands.append(srcfile) startCommands.append(str(line)) startCommands.append(pdffile) subprocess.Popen(startCommands, startupinfo=si) if keep_focus: self.focus_st() elif 'linux' in plat: # for some reason, I get 'linux2' from sys.platform print("Linux!") # the required scripts are in the 'evince' subdir ev_path = os.path.join(sublime.packages_path(), 'LaTeXTools', 'evince') ev_fwd_exec = os.path.join(ev_path, 'evince_forward_search') ev_sync_exec = os.path.join(ev_path, 'evince_sync') # for inverse search! #print ev_fwd_exec, ev_sync_exec # Run evince if either it's not running, or if focus PDF was toggled # Sadly ST2 has Python <2.7, so no check_output: running_apps = subprocess.Popen( ['ps', 'xw'], stdout=subprocess.PIPE).communicate()[0] # If there are non-ascii chars in the output just captured, we will fail. # Thus, decode using the 'ignore' option to simply drop them---we don't need them running_apps = running_apps.decode( sublime_plugin.sys.getdefaultencoding(), 'ignore') # Run scripts through sh because the script files will lose their exec bit on github # Get python binary if set: py_binary = prefs_lin["python2"] or 'python' sb_binary = prefs_lin["sublime"] or 'sublime-text' # How long we should wait after launching sh before syncing sync_wait = prefs_lin["sync_wait"] or 1.0 evince_running = ("evince " + pdffile in running_apps) if (not keep_focus) or (not evince_running): print("(Re)launching evince") subprocess.Popen( ['sh', ev_sync_exec, py_binary, sb_binary, pdffile], cwd=ev_path) print("launched evince_sync") if not evince_running: # Don't wait if we have already shown the PDF time.sleep(sync_wait) if forward_sync: subprocess.Popen( [py_binary, ev_fwd_exec, pdffile, str(line), srcfile]) if keep_focus: self.focus_st() else: # ??? pass
def run(self, cmd="", file_regex="", path=""): # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") if sublime.platform() == 'windows': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), startupinfo=startupinfo, shell=True ) else: os.killpg(self.proc.pid, signal.SIGTERM) self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("exec") # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("exec") self.output_view.settings().set("result_file_regex", "^([^:\n\r]*):([0-9]+):?([0-9]+)?:? (.*)$") # self.output_view.settings().set("result_line_regex", line_regex) self.output_view.settings().set("result_base_dir", tex_dir) self.window.run_command("show_panel", {"panel": "output.exec"}) self.output_view.settings().set("result_file_regex", file_regex) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) builder_name = get_setting("builder", "traditional") self.hide_panel_level = get_setting("hide_build_panel", "never") self.display_bad_boxes = get_setting("display_bad_boxes", False) # This *must* exist, so if it doesn't, the user didn't migrate if builder_name is None: sublime.error_message("LaTeXTools: you need to migrate your preferences. See the README file for instructions.") self.window.run_command('hide_panel', {"panel": "output.exec"}) return # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'} ) # determine the engine engine = tex_directives.get('program', builder_settings.get("program", "pdflatex")) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [opt for opt in options if ( not opt.startswith('--aux-directory') and not opt.startswith('--output-directory') and not opt.startswith('--jobname') )] self.aux_directory = get_aux_directory(self.file_name) self.output_directory = get_output_directory(self.file_name) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat) if builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Now actually get the builder builder_path = get_setting("builder_path", "") # relative to ST packages dir! # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: sublime.error_message("Cannot find builder " + builder_name + ".\n" \ "Check your LaTeXTools Preferences") self.window.run_command('hide_panel', {"panel": "output.exec"}) return print(repr(builder)) self.builder = builder( self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings ) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! self.path = platform_settings['texpath'] os.chdir(tex_dir) CmdThread(self).start() print(threading.active_count())
def run(self, cmd="", file_regex="", path=""): # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") if sublime.platform() == 'windows': startupinfo = subprocess.STARTUPINFO() startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW subprocess.call( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), startupinfo=startupinfo, shell=True ) else: os.killpg(self.proc.pid, signal.SIGTERM) self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("latextools") output_view_settings = self.output_view.settings() output_view_settings.set("result_file_regex", file_regex) output_view_settings.set("result_base_dir", tex_dir) output_view_settings.set("line_numbers", False) output_view_settings.set("gutter", False) output_view_settings.set("scroll_past_end", False) output_view_settings.set( "syntax", "Packages/LaTeXTools/LaTeXTools Console.hidden-tmLanguage" ) output_view_settings.set( "color_scheme", sublime.load_settings('Preferences.sublime-settings'). get('color_scheme') ) self.output_view.set_read_only(True) # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("latextools") self.hide_panel_level = get_setting("hide_build_panel", "never") if self.hide_panel_level != "always": self.window.run_command("show_panel", {"panel": "output.latextools"}) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) builder_name = get_setting("builder", "traditional") self.display_bad_boxes = get_setting("display_bad_boxes", False) # This *must* exist, so if it doesn't, the user didn't migrate if builder_name is None: sublime.error_message("LaTeXTools: you need to migrate your preferences. See the README file for instructions.") self.window.run_command('hide_panel', {"panel": "output.latextools"}) return # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'} ) # determine the engine engine = tex_directives.get('program', builder_settings.get("program", "pdflatex")) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [opt for opt in options if ( not opt.startswith('--aux-directory') and not opt.startswith('--output-directory') and not opt.startswith('--jobname') )] self.aux_directory = get_aux_directory(self.file_name) self.output_directory = get_output_directory(self.file_name) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat) if builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Now actually get the builder builder_path = get_setting("builder_path", "") # relative to ST packages dir! # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: sublime.error_message("Cannot find builder " + builder_name + ".\n" \ "Check your LaTeXTools Preferences") self.window.run_command('hide_panel', {"panel": "output.latextools"}) return print(repr(builder)) self.builder = builder( self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings ) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! self.path = platform_settings['texpath'] os.chdir(tex_dir) CmdThread(self).start() print(threading.active_count())
def run(self, edit, **args): # Check prefs for PDF focus and sync keep_focus = args.get('keep_focus', get_setting('keep_focus', True)) forward_sync = args.get('forward_sync', get_setting('forward_sync', True)) # If invoked from keybinding, we sync # Rationale: if the user invokes the jump command, s/he wants to see the result of the compilation. # If the PDF viewer window is already visible, s/he probably wants to sync, or s/he would have no # need to invoke the command. And if it is not visible, the natural way to just bring up the # window without syncing is by using the system's window management shortcuts. # As for focusing, we honor the toggles / prefs. from_keybinding = args.pop("from_keybinding", False) if from_keybinding: forward_sync = True print (from_keybinding, keep_focus, forward_sync) if not is_tex_file(self.view.file_name()): sublime.error_message("%s is not a TeX source file: cannot jump." % (os.path.basename(view.fileName()),)) return root = getTeXRoot.get_tex_root(self.view) file_name = get_jobname(root) output_directory = get_output_directory(self.view) if output_directory is None: root = getTeXRoot.get_tex_root(self.view) pdffile = os.path.join( os.path.dirname(root), file_name + u'.pdf' ) else: pdffile = os.path.join( output_directory, file_name + u'.pdf' ) if not os.path.exists(pdffile): pdffile = os.path.join( os.path.dirname(root), file_name + u'.pdf' ) (line, col) = self.view.rowcol(self.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 # issue #625: we need to pass the path to the file to the viewer when # there are files in subfolders of the main folder. # Thanks rstein and arahlin for this code! srcfile = self.view.file_name() try: viewer = get_viewer() except NoViewerException: return if forward_sync: try: viewer.forward_sync(pdffile, srcfile, line, col, keep_focus=keep_focus) except (AttributeError, NotImplementedError): try: viewer.view_file(pdffile, keep_focus=keep_focus) except (AttributeError, NotImplementedError): traceback.print_exc() sublime.error_message('Viewer ' + viewer_name + ' does not appear to be a proper LaTeXTools viewer plugin.' + ' Please contact the plugin author.') return else: try: viewer.view_file(pdffile, keep_focus=keep_focus) except (AttributeError, NotImplementedError): traceback.print_exc() sublime.error_message('Viewer ' + viewer_name + ' does not appear to be a proper LaTeXTools viewer plugin.' + ' Please contact the plugin author.') return if keep_focus: try: if viewer.supports_keep_focus(): return except (AttributeError, NotImplementedError): pass focus_st()
def run( self, file_regex="", program=None, builder=None, command=None, env=None, path=None, script_commands=None, update_phantoms_only=False, hide_phantoms_only=False, **kwargs ): if update_phantoms_only: if self.show_errors_inline: self.update_phantoms() return if hide_phantoms_only: self.hide_phantoms() return # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") try: if sublime.platform() == 'windows': execute_command( 'taskkill /t /f /pid {pid}'.format(pid=self.proc.pid), use_texpath=False ) else: os.killpg(self.proc.pid, signal.SIGTERM) except: print('Exception occurred while killing build') traceback.print_exc() self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if _HAS_PHANTOMS: self.hide_phantoms() pref_settings = sublime.load_settings("Preferences.sublime-settings") self.show_errors_inline = pref_settings.get("show_errors_inline", True) if view.is_dirty(): print ("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message('Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) self.tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message("%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()),)) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("latextools") output_view_settings = self.output_view.settings() output_view_settings.set("result_file_regex", file_regex) output_view_settings.set("result_base_dir", self.tex_dir) output_view_settings.set("line_numbers", False) output_view_settings.set("gutter", False) output_view_settings.set("scroll_past_end", False) if get_setting("highlight_build_panel", True): self.output_view.set_syntax_file( "Packages/LaTeXTools/LaTeXTools Console.hidden-tmLanguage" ) output_view_settings.set( "color_scheme", sublime.load_settings('Preferences.sublime-settings'). get('color_scheme') ) self.output_view.set_read_only(True) # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("latextools") self.hide_panel_level = get_setting("hide_build_panel", "no_warnings") if self.hide_panel_level == "never": self.show_output_panel(force=True) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}) self.display_bad_boxes = get_setting("display_bad_boxes", False) if builder is not None: builder_name = builder else: builder_name = get_setting("builder", "traditional") # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}) # override the command if command is not None: builder_settings.set("command", command) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'} ) # determine the engine if program is not None: engine = program else: engine = tex_directives.get( 'program', builder_settings.get("program", "pdflatex") ) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [opt for opt in options if ( not opt.startswith('--aux-directory') and not opt.startswith('--output-directory') and not opt.startswith('--jobname') )] self.aux_directory = get_aux_directory(self.file_name) self.output_directory = get_output_directory(self.file_name) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat, {}) if env is not None: self.env = env elif builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None else: # relative to ST packages dir! builder_path = get_setting("builder_path", "") if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: sublime.error_message( "Cannot find builder {0}.\n" "Check your LaTeXTools Preferences".format(builder_name) ) self.window.run_command('hide_panel', {"panel": "output.latextools"}) return if builder_name == 'script' and script_commands: builder_platform_settings['script_commands'] = script_commands builder_settings[self.plat] = builder_platform_settings print(repr(builder)) self.builder = builder( self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings ) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! if path is not None: self.path = path else: self.path = get_texpath() or os.environ['PATH'] thread = CmdThread(self) thread.start() print(threading.active_count()) # setup the progress indicator display_message_length = long( get_setting('build_finished_message_length', 2.0) * 1000 ) # NB CmdThread will change the success message self.progress_indicator = ProgressIndicator( thread, 'Building', 'Build failed', display_message_length=display_message_length )
def run(self, edit, **args): # Check prefs for PDF focus and sync keep_focus = get_setting('keep_focus', True) forward_sync = get_setting('forward_sync', True) prefs_lin = get_setting("linux", {}) prefs_win = get_setting("windows", {}) # If invoked from keybinding, we sync # Rationale: if the user invokes the jump command, s/he wants to see the result of the compilation. # If the PDF viewer window is already visible, s/he probably wants to sync, or s/he would have no # need to invoke the command. And if it is not visible, the natural way to just bring up the # window without syncing is by using the system's window management shortcuts. # As for focusing, we honor the toggles / prefs. from_keybinding = args["from_keybinding"] if "from_keybinding" in args else False if from_keybinding: forward_sync = True print (from_keybinding, keep_focus, forward_sync) if not is_tex_file(self.view.file_name()): sublime.error_message("%s is not a TeX source file: cannot jump." % (os.path.basename(view.fileName()),)) return quotes = "\"" srcfile = os.path.basename(self.view.file_name()) root = getTeXRoot.get_tex_root(self.view) print ("!TEX root = ", repr(root) ) # need something better here, but this works. rootName, rootExt = os.path.splitext(root) pdffile = rootName + u'.pdf' (line, col) = self.view.rowcol(self.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 # Query view settings to see if we need to keep focus or let the PDF viewer grab it # By default, we respect settings in Preferences # platform-specific code: plat = sublime_plugin.sys.platform if plat == 'darwin': options = ["-r","-g"] if keep_focus else ["-r"] if forward_sync: path_to_skim = '/Applications/Skim.app/' if not os.path.exists(path_to_skim): path_to_skim = subprocess.check_output( ['osascript', '-e', 'POSIX path of (path to app id "net.sourceforge.skim-app.skim")'] ).decode("utf8")[:-1] subprocess.Popen([os.path.join(path_to_skim, "Contents/SharedSupport/displayline")] + options + [str(line), pdffile, srcfile]) else: skim = os.path.join(sublime.packages_path(), 'LaTeXTools', 'skim', 'displayfile') subprocess.Popen(['sh', skim] + options + [pdffile]) elif plat == 'win32': # determine if Sumatra is running, launch it if not print ("Windows, Calling Sumatra") si = subprocess.STARTUPINFO() si.dwFlags |= subprocess.STARTF_USESHOWWINDOW si.wShowWindow = 4 #constant for SHOWNOACTIVATE su_binary = prefs_win.get("sumatra", "SumatraPDF.exe") or 'SumatraPDF.exe' startCommands = [su_binary, "-reuse-instance"] if forward_sync: startCommands.append("-forward-search") startCommands.append(srcfile) startCommands.append(str(line)) startCommands.append(pdffile) subprocess.Popen(startCommands, startupinfo = si) if keep_focus: self.focus_st() elif 'linux' in plat: # for some reason, I get 'linux2' from sys.platform print ("Linux!") # the required scripts are in the 'evince' subdir ev_path = os.path.join(sublime.packages_path(), 'LaTeXTools', 'evince') ev_fwd_exec = os.path.join(ev_path, 'evince_forward_search') ev_sync_exec = os.path.join(ev_path, 'evince_sync') # for inverse search! #print ev_fwd_exec, ev_sync_exec # Run evince if either it's not running, or if focus PDF was toggled # Sadly ST2 has Python <2.7, so no check_output: running_apps = subprocess.Popen(['ps', 'xw'], stdout=subprocess.PIPE).communicate()[0] # If there are non-ascii chars in the output just captured, we will fail. # Thus, decode using the 'ignore' option to simply drop them---we don't need them running_apps = running_apps.decode(sublime_plugin.sys.getdefaultencoding(), 'ignore') # Run scripts through sh because the script files will lose their exec bit on github # Get python binary if set: py_binary = prefs_lin["python2"] or 'python' sb_binary = prefs_lin["sublime"] or 'sublime-text' # How long we should wait after launching sh before syncing sync_wait = prefs_lin["sync_wait"] or 1.0 evince_running = ("evince " + pdffile in running_apps) if (not keep_focus) or (not evince_running): print ("(Re)launching evince") subprocess.Popen(['sh', ev_sync_exec, py_binary, sb_binary, pdffile], cwd=ev_path) print ("launched evince_sync") if not evince_running: # Don't wait if we have already shown the PDF time.sleep(sync_wait) if forward_sync: subprocess.Popen([py_binary, ev_fwd_exec, pdffile, str(line), srcfile]) if keep_focus: self.focus_st() else: # ??? pass
def find_bib_files(rootdir, src, bibfiles): if not is_tex_file(src): src_tex_file = None for ext in get_tex_extensions(): src_tex_file = ''.join((src, ext)) if os.path.exists(os.path.join(rootdir, src_tex_file)): src = src_tex_file break if src != src_tex_file: print("Could not find file {0}".format(src)) return file_path = os.path.normpath(os.path.join(rootdir,src)) print("Searching file: " + repr(file_path)) # See latex_ref_completion.py for why the following is wrong: #dir_name = os.path.dirname(file_path) # read src file and extract all bibliography tags try: src_file = codecs.open(file_path, "r", 'UTF-8') except IOError: sublime.status_message("LaTeXTools WARNING: cannot open included file " + file_path) print ("WARNING! I can't find it! Check your \\include's and \\input's.") return src_content = re.sub("%.*","",src_file.read()) src_file.close() m = re.search(r"\\usepackage\[(.*?)\]\{inputenc\}", src_content) if m: f = None try: f = codecs.open(file_path, "r", m.group(1)) src_content = re.sub("%.*", "", f.read()) except: pass finally: if f and not f.closed: f.close() # While these commands only allow a single resource as their argument... resources = re.findall(r'\\addbibresource(?:\[[^\]]+\])?\{([^\}]+\.bib)\}', src_content) resources += re.findall(r'\\addglobalbib(?:\[[^\]]+\])?\{([^\}]+\.bib)\}', src_content) resources += re.findall(r'\\addsectionbib(?:\[[^\]]+\])?\{([^\}]+\.bib)\}', src_content) # ... these can have a comma-separated list of resources as their argument. multi_resources = re.findall(r'\\begin\{refsection\}\[([^\]]+)\]', src_content) multi_resources += re.findall(r'\\bibliography\{([^\}]+)\}', src_content) multi_resources += re.findall(r'\\nobibliography\{([^\}]+)\}', src_content) for multi_resource in multi_resources: for res in multi_resource.split(','): res = res.strip() if res[-4:].lower() != '.bib': res = res + '.bib' resources.append(res) # extract absolute filepath for each bib file for res in resources: # We join with rootdir, the dir of the master file candidate_file = os.path.normpath(os.path.join(rootdir, res)) # if the file doesn't exist, search the default tex paths if not os.path.exists(candidate_file): candidate_file = kpsewhich(res, 'mlbib') if candidate_file is not None and os.path.exists(candidate_file): bibfiles.append(candidate_file) # search through input tex files recursively for f in re.findall(r'\\(?:input|include)\{[^\}]+\}',src_content): input_f = re.search(r'\{([^\}]+)', f).group(1) find_bib_files(rootdir, input_f, bibfiles)
def run(self, file_regex="", program=None, builder=None, command=None, env=None, path=None, script_commands=None, update_phantoms_only=False, hide_phantoms_only=False, **kwargs): if update_phantoms_only: if self.show_errors_inline: self.update_phantoms() return if hide_phantoms_only: self.hide_phantoms() return # Try to handle killing with self.proc_lock: if self.proc: # if we are running, try to kill running process self.output("\n\n### Got request to terminate compilation ###") try: if sublime.platform() == 'windows': execute_command('taskkill /t /f /pid {pid}'.format( pid=self.proc.pid), use_texpath=False) else: os.killpg(self.proc.pid, signal.SIGTERM) except: print('Exception occurred while killing build') traceback.print_exc() self.proc = None return else: # either it's the first time we run, or else we have no running processes self.proc = None view = self.view = self.window.active_view() if _HAS_PHANTOMS: self.hide_phantoms() pref_settings = sublime.load_settings( "Preferences.sublime-settings") self.show_errors_inline = pref_settings.get( "show_errors_inline", True) if view.is_dirty(): print("saving...") view.run_command('save') # call this on view, not self.window if view.file_name() is None: sublime.error_message( 'Please save your file before attempting to build.') return self.file_name = getTeXRoot.get_tex_root(view) if not os.path.isfile(self.file_name): sublime.error_message(self.file_name + ": file not found.") return self.tex_base = get_jobname(view) self.tex_dir = os.path.dirname(self.file_name) if not is_tex_file(self.file_name): sublime.error_message( "%s is not a TeX source file: cannot compile." % (os.path.basename(view.file_name()), )) return # Output panel: from exec.py if not hasattr(self, 'output_view'): self.output_view = self.window.get_output_panel("latextools") output_view_settings = self.output_view.settings() output_view_settings.set("result_file_regex", file_regex) output_view_settings.set("result_base_dir", self.tex_dir) output_view_settings.set("line_numbers", False) output_view_settings.set("gutter", False) output_view_settings.set("scroll_past_end", False) if get_setting("highlight_build_panel", True, view=view): self.output_view.set_syntax_file( "Packages/LaTeXTools/LaTeXTools Console.hidden-tmLanguage") output_view_settings.set( "color_scheme", sublime.load_settings('Preferences.sublime-settings').get( 'color_scheme')) self.output_view.set_read_only(True) # Dumb, but required for the moment for the output panel to be picked # up as the result buffer self.window.get_output_panel("latextools") self.hide_panel_level = get_setting("hide_build_panel", "no_warnings", view=view) if self.hide_panel_level == "never": self.show_output_panel(force=True) self.plat = sublime.platform() if self.plat == "osx": self.encoding = "UTF-8" elif self.plat == "windows": self.encoding = getOEMCP() elif self.plat == "linux": self.encoding = "UTF-8" else: sublime.error_message("Platform as yet unsupported. Sorry!") return # Get platform settings, builder, and builder settings platform_settings = get_setting(self.plat, {}, view=view) self.display_bad_boxes = get_setting("display_bad_boxes", False, view=view) if builder is not None: builder_name = builder else: builder_name = get_setting("builder", "traditional", view=view) # Default to 'traditional' builder if builder_name in ['', 'default']: builder_name = 'traditional' # this is to convert old-style names (e.g. AReallyLongName) # to new style plugin names (a_really_long_name) builder_name = _classname_to_internal_name(builder_name) builder_settings = get_setting("builder_settings", {}, view=view) # override the command if command is not None: builder_settings.set("command", command) # parse root for any %!TEX directives tex_directives = parse_tex_directives( self.file_name, multi_values=['options'], key_maps={'ts-program': 'program'}) # determine the engine if program is not None: engine = program else: engine = tex_directives.get( 'program', builder_settings.get("program", "pdflatex")) engine = engine.lower() # Sanity check: if "strange" engine, default to pdflatex (silently...) if engine not in [ 'pdflatex', "pdftex", 'xelatex', 'xetex', 'lualatex', 'luatex' ]: engine = 'pdflatex' options = builder_settings.get("options", []) if isinstance(options, strbase): options = [options] if 'options' in tex_directives: options.extend(tex_directives['options']) # filter out --aux-directory and --output-directory options which are # handled separately options = [ opt for opt in options if (not opt.startswith('--aux-directory') and not opt.startswith( '--output-directory') and not opt.startswith('--jobname')) ] self.aux_directory = get_aux_directory(view) self.output_directory = get_output_directory(view) # Read the env option (platform specific) builder_platform_settings = builder_settings.get(self.plat, {}) if env is not None: self.env = env elif builder_platform_settings: self.env = builder_platform_settings.get("env", None) else: self.env = None # Safety check: if we are using a built-in builder, disregard # builder_path, even if it was specified in the pref file if builder_name in ['simple', 'traditional', 'script', 'basic']: builder_path = None else: # relative to ST packages dir! builder_path = get_setting("builder_path", "", view=view) if builder_path: bld_path = os.path.join(sublime.packages_path(), builder_path) add_plugin_path(bld_path) try: builder = get_plugin('{0}_builder'.format(builder_name)) except NoSuchPluginException: try: builder = get_plugin(builder_name) except NoSuchPluginException: sublime.error_message( "Cannot find builder {0}.\n" "Check your LaTeXTools Preferences".format(builder_name)) self.window.run_command('hide_panel', {"panel": "output.latextools"}) return if builder_name == 'script' and script_commands: builder_platform_settings['script_commands'] = script_commands builder_settings[self.plat] = builder_platform_settings print(repr(builder)) self.builder = builder(self.file_name, self.output, engine, options, self.aux_directory, self.output_directory, self.tex_base, tex_directives, builder_settings, platform_settings) # Now get the tex binary path from prefs, change directory to # that of the tex root file, and run! if path is not None: self.path = path else: self.path = get_texpath() or os.environ['PATH'] thread = CmdThread(self) thread.start() print(threading.active_count()) # setup the progress indicator display_message_length = long( get_setting('build_finished_message_length', 2.0, view=view) * 1000) # NB CmdThread will change the success message self.progress_indicator = ProgressIndicator( thread, 'Building', 'Build failed', display_message_length=display_message_length)
def find_bib_files(rootdir, src, bibfiles): if not is_tex_file(src): src_tex_file = None for ext in get_tex_extensions(): src_tex_file = ''.join((src, ext)) if os.path.exists(os.path.join(rootdir, src_tex_file)): src = src_tex_file break if src != src_tex_file: print("Could not find file {0}".format(src)) return file_path = os.path.normpath(os.path.join(rootdir,src)) print("Searching file: " + repr(file_path)) # See latex_ref_completion.py for why the following is wrong: #dir_name = os.path.dirname(file_path) # read src file and extract all bibliography tags try: src_file = codecs.open(file_path, "r", 'UTF-8') except IOError: sublime.status_message("LaTeXTools WARNING: cannot open included file " + file_path) print ("WARNING! I can't find it! Check your \\include's and \\input's.") return src_content = re.sub("%.*","",src_file.read()) src_file.close() m = re.search(r"\\usepackage\[(.*?)\]\{inputenc\}", src_content) if m: f = None try: f = codecs.open(file_path, "r", m.group(1)) src_content = re.sub("%.*", "", f.read()) except: pass finally: if f and not f.closed: f.close() bibtags = re.findall(r'\\bibliography\{[^\}]+\}', src_content) bibtags += re.findall(r'\\nobibliography\{[^\}]+\}', src_content) bibtags += re.findall(r'\\addbibresource\{[^\}]+.bib\}', src_content) # extract absolute filepath for each bib file for tag in bibtags: bfiles = re.search(r'\{([^\}]+)', tag).group(1).split(',') for bf in bfiles: if bf[-4:].lower() != '.bib': bf = bf + '.bib' # We join with rootdir, the dir of the master file candidate_file = os.path.normpath(os.path.join(rootdir,bf)) # if the file doesn't exist, search the default tex paths if not os.path.exists(candidate_file): candidate_file = kpsewhich(bf, 'mlbib') if candidate_file is not None and os.path.exists(candidate_file): bibfiles.append(candidate_file) # search through input tex files recursively for f in re.findall(r'\\(?:input|include)\{[^\}]+\}',src_content): input_f = re.search(r'\{([^\}]+)', f).group(1) find_bib_files(rootdir, input_f, bibfiles)
def find_bib_files(rootdir, src, bibfiles): if not is_tex_file(src): src_tex_file = None for ext in get_tex_extensions(): src_tex_file = ''.join((src, ext)) if os.path.exists(os.path.join(rootdir, src_tex_file)): src = src_tex_file break if src != src_tex_file: print("Could not find file {0}".format(src)) return file_path = os.path.normpath(os.path.join(rootdir, src)) print("Searching file: " + repr(file_path)) # See latex_ref_completion.py for why the following is wrong: #dir_name = os.path.dirname(file_path) # read src file and extract all bibliography tags try: src_file = codecs.open(file_path, "r", 'UTF-8') except IOError: sublime.status_message( "LaTeXTools WARNING: cannot open included file " + file_path) print( "WARNING! I can't find it! Check your \\include's and \\input's.") return src_content = re.sub("%.*", "", src_file.read()) src_file.close() m = re.search(r"\\usepackage\[(.*?)\]\{inputenc\}", src_content) if m: f = None try: f = codecs.open(file_path, "r", m.group(1)) src_content = re.sub("%.*", "", f.read()) except: pass finally: if f and not f.closed: f.close() bibtags = re.findall(r'\\bibliography\{[^\}]+\}', src_content) bibtags += re.findall(r'\\nobibliography\{[^\}]+\}', src_content) bibtags += re.findall(r'\\addbibresource\{[^\}]+.bib\}', src_content) # extract absolute filepath for each bib file for tag in bibtags: bfiles = re.search(r'\{([^\}]+)', tag).group(1).split(',') for bf in bfiles: if bf[-4:].lower() != '.bib': bf = bf + '.bib' # We join with rootdir, the dir of the master file candidate_file = os.path.normpath(os.path.join(rootdir, bf)) # if the file doesn't exist, search the default tex paths if not os.path.exists(candidate_file): candidate_file = kpsewhich(bf, 'mlbib') if candidate_file is not None and os.path.exists(candidate_file): bibfiles.append(candidate_file) # search through input tex files recursively for f in re.findall(r'\\(?:input|include)\{[^\}]+\}', src_content): input_f = re.search(r'\{([^\}]+)', f).group(1) find_bib_files(rootdir, input_f, bibfiles)