예제 #1
0
    def __init__(self, *args):
        # Sets the file name parts, plus internal stuff
        super(WineBuilder, self).__init__(*args)

        # Now do our own initialization: set our name, see if we want to display output
        self.name = "Custom Builder"
        self.display_log = self.builder_settings.get("display_log", False)
        self.env = self.builder_settings.get(sublime.platform(),
                                             {}).get("env", None)
        # Loaded here so it is calculated on the main thread
        self.texpath = get_texpath() or os.environ['PATH']
예제 #2
0
	def __init__(self, *args):
		# Sets the file name parts, plus internal stuff
		super(ScriptBuilder, self).__init__(*args)
		# Now do our own initialization: set our name
		self.name = "Script Builder"
		# Display output?
		self.display_log = self.builder_settings.get("display_log", False)
		plat = sublime.platform()
		self.cmd = self.builder_settings.get(plat, {}).get("script_commands", None)
		self.env = self.builder_settings.get(plat, {}).get("env", None)
		# Loaded here so it is calculated on the main thread
		self.texpath = get_texpath() or os.environ['PATH']
예제 #3
0
    def run_bibtex(self, command=None):
        if command is None:
            command = [self.bibtex]
        elif isinstance(command, strbase):
            command = [command]

        # to get bibtex to work with the output directory, we change the
        # cwd to the output directory and add the main directory to
        # BIBINPUTS and BSTINPUTS
        env = dict(os.environ)
        cwd = self.tex_dir

        output_directory = (
            self.aux_directory_full or self.output_directory_full
        )
        if output_directory is not None:
            # cwd is, at the point, the path to the main tex file
            if _ST3:
                env['BIBINPUTS'] = cwd + os.pathsep + env.get('BIBINPUTS', '')
                env['BSTINPUTS'] = cwd + os.pathsep + env.get('BSTINPUTS', '')
            else:
                env['BIBINPUTS'] = \
                    (cwd + os.pathsep + env.get('BIBINPUTS', '')).encode(
                        sys.getfilesystemencoding())
                env['BSTINPUTS'] = \
                    (cwd + os.pathsep + env.get('BSTINPUTS', '')).encode(
                        sys.getfilesystemencoding())
            # now we modify cwd to be the output directory
            # NOTE this cwd is not reused by any of the other command
            cwd = output_directory
        env['PATH'] = get_texpath()

        command.append(self.job_name)
        return external_command(
            command,
            env=env,
            cwd=cwd,
            preexec_fn=os.setsid if sublime.platform() != 'windows' else None,
            use_texpath=False,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT
        )
예제 #4
0
    def run_bibtex(self, command=None):
        if command is None:
            command = [self.bibtex]
        elif isinstance(command, strbase):
            command = [command]

        # to get bibtex to work with the output directory, we change the
        # cwd to the output directory and add the main directory to
        # BIBINPUTS and BSTINPUTS
        env = dict(os.environ)
        cwd = self.tex_dir

        output_directory = (
            self.aux_directory_full or self.output_directory_full
        )
        if output_directory is not None:
            # cwd is, at the point, the path to the main tex file
            if _ST3:
                env['BIBINPUTS'] = cwd + os.pathsep + env.get('BIBINPUTS', '')
                env['BSTINPUTS'] = cwd + os.pathsep + env.get('BSTINPUTS', '')
            else:
                env['BIBINPUTS'] = \
                    (cwd + os.pathsep + env.get('BIBINPUTS', '')).encode(
                        sys.getfilesystemencoding())
                env['BSTINPUTS'] = \
                    (cwd + os.pathsep + env.get('BSTINPUTS', '')).encode(
                        sys.getfilesystemencoding())
            # now we modify cwd to be the output directory
            # NOTE this cwd is not reused by any of the other command
            cwd = output_directory
        env['PATH'] = get_texpath()

        command.append(self.job_name)
        return external_command(
            command,
            env=env,
            cwd=cwd,
            preexec_fn=os.setsid if sublime.platform() != 'windows' else None,
            use_texpath=False,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT
        )
예제 #5
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
		)
예제 #6
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)