Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
    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)
Ejemplo n.º 4
0
    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)
Ejemplo n.º 5
0
    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)
Ejemplo n.º 7
0
	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.")
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
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)
Ejemplo n.º 11
0
	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())
Ejemplo n.º 12
0
    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
Ejemplo n.º 13
0
	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())
Ejemplo n.º 14
0
	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())
Ejemplo n.º 15
0
	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()
Ejemplo n.º 16
0
	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
		)
Ejemplo n.º 17
0
	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)
Ejemplo n.º 19
0
    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)
Ejemplo n.º 20
0
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)
Ejemplo n.º 21
0
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)
Ejemplo n.º 22
0
	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())