Exemple #1
0
 def parse(self, *args, **kwargs):
     text = get_text(self.view)
     try:
         text = strip_js_comments(text)
         data = json.loads(text)
     except ValueError, e:
         self.output.write_line(self.debug_base % (self.file_path, str(e)))
Exemple #2
0
 def parse(self, *args, **kwargs):
     text = get_text(self.view)
     try:
         text = strip_js_comments(text)
         data = json.loads(text)
     except ValueError, e:
         self.output.write_line(self.debug_base % (self.file_path, str(e)))
    def parse(self, *args, **kwargs):
        text = get_text(self.view)

        # Parsing will fail if `<?xml version="1.0" encoding="UTF-8"?>` encoding is in the first
        # line, so strip it.
        # XXX: Find a better way to fix this misbehaviour of xml stuff in Python
        #      (I mean, plistliv even "writes" that line)
        if text.startswith('<?xml version="1.0" encoding="UTF-8"?>'):
            text = text[38:]

        try:
            from xml.parsers.expat import ExpatError, ErrorString
        except ImportError:
            # xml.parsers.expat is not available on certain Linux dists, use plist_parser then.
            # See https://github.com/SublimeText/AAAPackageDev/issues/19
            import plist_parser
            print("[AAAPackageDev] Using plist_parser")

            try:
                data = plist_parser.parse_string(text)
            except plist_parser.PropertyListParseError, e:
                self.output.write_line(self.debug_base %
                                       (self.file_path, str(e), 0, 0))
            else:
                return data
Exemple #4
0
 def parse(self, *args, **kwargs):
     text = get_text(self.view)
     try:
         data = yaml.safe_load(text)
     except yaml.YAMLError, e:
         out = self.debug_base % _join_multiline(str(e))
         self.output.write_line(out.replace("<unicode string>", self.file_path))
Exemple #5
0
 def parse(self, *args, **kwargs):
     text = get_text(self.view)
     try:
         data = yaml.safe_load(text)
     except yaml.YAMLError, e:
         out = self.debug_base % str(e).replace("<unicode string>", self.file_path)
         self.output.write_line(out)
Exemple #6
0
 def run(self, edit):
     content = get_text(self.view)
     clear(self.view)
     self.view.run_command('insert_snippet', {'contents': TPL})
     self.view.settings().set('syntax', 'Packages/XML/XML.tmLanguage')
     # Insert existing contents into CDATA section. We rely on the fact
     # that Sublime will place the first selection in the first field of
     # the newly inserted snippet.
     self.view.insert(edit, self.view.sel()[0].begin(), content)
Exemple #7
0
 def run(self, edit):
     content = get_text(self.view)
     clear(self.view)
     self.view.run_command('insert_snippet', {'contents': TPL})
     self.view.set_syntax_file(XML_SYNTAX)
     # Insert existing contents into CDATA section. We rely on the fact
     # that Sublime will place the first selection in the first field of
     # the newly inserted snippet.
     self.view.insert(edit, self.view.sel()[0].begin(), content)
Exemple #8
0
 def run(self, edit):
     content = get_text(self.view)
     clear(self.view)
     self.view.run_command('insert_snippet', {'contents': TPL})
     self.view.set_syntax_file(XML_SYNTAX)
     # Insert existing contents into CDATA section. We rely on the fact
     # that Sublime will place the first selection in the first field of
     # the newly inserted snippet.
     self.view.insert(edit, self.view.sel()[0].begin(), content)
 def run(self, edit):
     content = get_text(self.view)
     clear(self.view)
     self.view.run_command('insert_snippet', {'contents': TPL})
     self.view.settings().set('syntax', 'Packages/XML/XML.tmLanguage')
     # Insert existing contents into CDATA section. We rely on the fact
     # that Sublime will place the first selection in the first field of
     # the newly inserted snippet.
     self.view.insert(edit, self.view.sel()[0].begin(), content)
Exemple #10
0
 def parse(self, *args, **kwargs):
     text = get_text(self.view)
     try:
         data = yaml.safe_load(text)
     except yaml.YAMLError as e:
         out = self.debug_base % str(e).replace("<unicode string>", self.file_path)
         self.output.write_line(out)
     except IOError as e:
         self.output.write_line('Error opening "%s": %s' % (self.file_path, str(e)))
     else:
         return data
 def parse(self, *args, **kwargs):
     text = get_text(self.view)
     try:
         data = yaml.safe_load(text)
     except yaml.YAMLError as e:
         out = self.debug_base % str(e).replace("<unicode string>",
                                                self.file_path)
         self.output.write_line(out)
     except IOError as e:
         self.output.write_line('Error opening "%s": %s' %
                                (self.file_path, str(e)))
     else:
         return data
Exemple #12
0
    def parse(self, *args, **kwargs):
        # Note: I hate Plist and XML. And it doesn't help a bit that parsing
        # plist files is a REAL PITA.
        text = get_text(self.view)

        # Parsing will fail if `<?xml version="1.0" encoding="UTF-8"?>` encoding is in the first
        # line, so strip it.
        # XXX: Find a better way to fix this misbehaviour of xml stuff in Python
        #      (I mean, plistliv even "writes" that line)
        if text.startswith('<?xml version="1.0" encoding="UTF-8"?>'):
            text = text[38:]

        # See https://github.com/SublimeText/AAAPackageDev/issues/34
        if ST2 and isinstance(text, unicode):  # NOQA
            text = text.encode('utf-8')

        if use_plistlib:
            try:
                # This will try `from xml.parsers.expat import ParserCreate`
                # but since it is already tried above it should succeed.
                if ST2:
                    data = plistlib.readPlistFromString(text)
                else:
                    data = plistlib.readPlistFromBytes(text.encode('utf-8'))
            except ExpatError as e:
                self.output.write_line(self.debug_base
                                       % (self.file_path,
                                          ErrorString(e.code),
                                          e.lineno,
                                          e.offset)
                                       )
            # except BaseException as e:
            #     # Whatever could happen here ...
            #     self.output.write_line(self.debug_base % (self.file_path, str(e), 0, 0))
            else:
                return data
        else:
            # falling back to plist_parser
            from xml.sax._exceptions import SAXReaderNotAvailable
            try:
                data = plist_parser.parse_string(text)
            except plist_parser.PropertyListParseError as e:
                self.output.write_line(self.debug_base % (self.file_path, str(e), 0, 0))
            except SAXReaderNotAvailable:
                # https://github.com/SublimeText/AAAPackageDev/issues/48
                self.output.write_line("Unable to parse Property List because of missing XML "
                                       "parsers in your Python environment.\n"
                                       "Please use Sublime Text 3 or reinstall Python 2.6 "
                                       "on your system.")
            else:
                return data
Exemple #13
0
    def parse(self, *args, **kwargs):
        # Note: I hate Plist and XML. And it doesn't help a bit that parsing
        # plist files is a REAL PITA.
        text = get_text(self.view)

        # Parsing will fail if `<?xml version="1.0" encoding="UTF-8"?>` encoding is in the first
        # line, so strip it.
        # XXX: Find a better way to fix this misbehaviour of xml stuff in Python
        #      (I mean, plistliv even "writes" that line)
        if text.startswith('<?xml version="1.0" encoding="UTF-8"?>'):
            text = text[38:]

        # See https://github.com/SublimeText/AAAPackageDev/issues/34
        if ST2 and isinstance(text, unicode):
            text = text.encode('utf-8')

        try:
            from xml.parsers.expat import ExpatError, ErrorString
        except ImportError:
            # xml.parsers.expat is not available on certain Linux dists, use plist_parser then.
            # See https://github.com/SublimeText/AAAPackageDev/issues/19
            import plist_parser
            print("[AAAPackageDev] Using plist_parser")

            try:
                data = plist_parser.parse_string(text)
            except plist_parser.PropertyListParseError as e:
                self.output.write_line(self.debug_base % (self.file_path, str(e), 0, 0))
            else:
                return data
        else:
            try:
                # This will try `from xml.parsers.expat import ParserCreate`
                # but since it is already tried above it should succeed.
                if ST2:
                    data = plistlib.readPlistFromString(text)
                else:
                    data = plistlib.readPlistFromBytes(text.encode('utf-8'))
            except ExpatError as e:
                self.output.write_line(self.debug_base
                                       % (self.file_path,
                                          ErrorString(e.code),
                                          e.lineno,
                                          e.offset)
                                       )
            except BaseException as e:
                # Whatever could happen here ...
                self.output.write_line(self.debug_base % (self.file_path, str(e), 0, 0))
            else:
                return data
Exemple #14
0
    def parse(self, *args, **kwargs):
        # Note: I hate Plist and XML. And it doesn't help a bit that parsing
        # plist files is a REAL PITA.
        text = get_text(self.view)

        # Parsing will fail if `<?xml version="1.0" encoding="UTF-8"?>` encoding is in the first
        # line, so strip it.
        # XXX: Find a better way to fix this misbehaviour of xml stuff in Python
        #      (I mean, plistliv even "writes" that line)
        if text.startswith('<?xml version="1.0" encoding="UTF-8"?>'):
            text = text[38:]

        # See https://github.com/SublimeText/AAAPackageDev/issues/34
        if ST2 and isinstance(text, unicode):  # NOQA
            text = text.encode('utf-8')

        if use_plistlib:
            try:
                # This will try `from xml.parsers.expat import ParserCreate`
                # but since it is already tried above it should succeed.
                if ST2:
                    data = plistlib.readPlistFromString(text)
                else:
                    data = plistlib.readPlistFromBytes(text.encode('utf-8'))
            except ExpatError as e:
                self.output.write_line(
                    self.debug_base %
                    (self.file_path, ErrorString(e.code), e.lineno, e.offset))
            # except BaseException as e:
            #     # Whatever could happen here ...
            #     self.output.write_line(self.debug_base % (self.file_path, str(e), 0, 0))
            else:
                return data
        else:
            # falling back to plist_parser
            from xml.sax._exceptions import SAXReaderNotAvailable
            try:
                data = plist_parser.parse_string(text)
            except plist_parser.PropertyListParseError as e:
                self.output.write_line(self.debug_base %
                                       (self.file_path, str(e), 0, 0))
            except SAXReaderNotAvailable:
                # https://github.com/SublimeText/AAAPackageDev/issues/48
                self.output.write_line(
                    "Unable to parse Property List because of missing XML "
                    "parsers in your Python environment.\n"
                    "Please use Sublime Text 3 or reinstall Python 2.6 "
                    "on your system.")
            else:
                return data
Exemple #15
0
    def parse(self, *args, **kwargs):
        # Note: I hate Plist and XML. And it doesn't help a bit that parsing
        # plist files is a REAL PITA.
        text = get_text(self.view)

        # Parsing will fail if `<?xml version="1.0" encoding="UTF-8"?>` encoding is in the first
        # line, so strip it.
        # XXX: Find a better way to fix this misbehaviour of xml stuff in Python
        #      (I mean, plistliv even "writes" that line)
        if text.startswith('<?xml version="1.0" encoding="UTF-8"?>'):
            text = text[38:]

        # See https://github.com/SublimeText/AAAPackageDev/issues/34
        if ST2 and isinstance(text, unicode):
            text = text.encode('utf-8')

        try:
            from xml.parsers.expat import ExpatError, ErrorString
        except ImportError:
            # xml.parsers.expat is not available on certain Linux dists, use plist_parser then.
            # See https://github.com/SublimeText/AAAPackageDev/issues/19
            import plist_parser
            print("[AAAPackageDev] Using plist_parser")

            try:
                data = plist_parser.parse_string(text)
            except plist_parser.PropertyListParseError as e:
                self.output.write_line(self.debug_base %
                                       (self.file_path, str(e), 0, 0))
            else:
                return data
        else:
            try:
                # This will try `from xml.parsers.expat import ParserCreate`
                # but since it is already tried above it should succeed.
                if ST2:
                    data = plistlib.readPlistFromString(text)
                else:
                    data = plistlib.readPlistFromBytes(text.encode('utf-8'))
            except ExpatError as e:
                self.output.write_line(
                    self.debug_base %
                    (self.file_path, ErrorString(e.code), e.lineno, e.offset))
            except BaseException as e:
                # Whatever could happen here ...
                self.output.write_line(self.debug_base %
                                       (self.file_path, str(e), 0, 0))
            else:
                return data
Exemple #16
0
    def parse(self, *args, **kwargs):
        text = get_text(self.view)

        # Parsing will fail if `<?xml version="1.0" encoding="UTF-8"?>` encoding is in the first
        # line, so strip it.
        # XXX: Find a better way to fix this misbehaviour of xml stuff in Python
        #      (I mean, plistliv even "writes" that line)
        if text.startswith('<?xml version="1.0" encoding="UTF-8"?>'):
            text = text[38:]

        try:
            from xml.parsers.expat import ExpatError, ErrorString
        except ImportError:
            # xml.parsers.expat is not available on certain Linux dists, use plist_parser then.
            # See https://github.com/SublimeText/AAAPackageDev/issues/19
            import plist_parser
            print("[AAAPackageDev] Using plist_parser")

            try:
                data = plist_parser.parse_string(text)
            except plist_parser.PropertyListParseError, e:
                self.output.write_line(self.debug_base % (self.file_path, str(e), 0, 0))
            else:
                return data
Exemple #17
0
 def run(self, edit):
     snippet = get_text(self.view)
     contents = ET.fromstring(snippet).findtext(".//content")
     v = self.view.window().new_file()
     v.insert(edit, 0, contents)
     v.settings().set('syntax', RAW_SNIPPETS_SYNTAX)
    def run(self,
            edit=None,
            source_format=None,
            target_format=None,
            ext=None,
            open_new_file=False,
            rearrange_yaml_syntax_def=False,
            _output=None,
            *args,
            **kwargs):
        """Available parameters:

            edit (sublime.Edit) = None
                The edit parameter from TextCommand. Unused.

            source_format (str) = None
                The source format. Any of "yaml", "plist" or "json".
                If `None`, attempt to automatically detect the format by extension, used syntax
                highlight or (with plist) the actual contents.

            target_format (str) = None
                The target format. Any of "yaml", "plist" or "json".
                If `None`, attempt to find an option set in the file to parse.
                If unable to find an option, ask the user directly with all available format options.

            ext (str) = None
                The extension of the file to convert to, without leading dot. If `None`, the extension
                will be automatically determined by a special algorythm using "appendixes".

                Here are a few examples:
                    ".YAML-ppplist" yaml  -> plist ".ppplist"
                    ".json"         json  -> yaml  ".yaml"
                    ".tmplist"      plist -> json  ".JSON-tmplist"
                    ".yaml"         json  -> plist ".JSON-yaml" (yes, doesn't make much sense)

            open_new_file (bool) = False
                Open the (newly) created file in a new buffer.

            rearrange_yaml_syntax_def (bool) = False
                Interesting for language definitions, will automatically run
                "rearrange_yaml_syntax_def" command on it, if the target format is "yaml".
                Overrides "open_new_file" parameter.

            _output (OutputPanel) = None
                For internal use only.

            *args
                Forwarded to pretty much every relevant call but does not have any effect.
                You can't pass *args in commands anyway.

            **kwargs
                Will be forwarded to both the loading function and the dumping function, after stripping
                unsopported entries. Only do this if you know what you're doing.

                Functions in question:
                    yaml.dump
                    json.dump
                    plist.writePlist (does not support any parameters)

                A more detailed description of each supported parameter for the respective dumper can be
                found in `fileconv/dumpers.py`.
        """
        # TODO: Ditch *args, can't be passed in commands anyway

        # Check the environment (view, args, ...)

        if self.view.is_dirty():
            # Save the file so that source and target file on the drive don't differ
            self.view.run_command("save")
            if self.view.is_dirty():
                return sublime.error_message(
                    "The file could not be saved correctly. "
                    "The build was aborted")

        file_path = self.view.file_name()
        if not file_path:
            return self.status("File does not exist.", file_path)

        if source_format and target_format == source_format:
            return self.status(
                "Target and source file format are identical. (%s)" %
                target_format)

        if source_format and source_format not in loaders.get:
            return self.status("%s for '%s' not supported/implemented." %
                               ("Loader", source_format))

        if target_format and target_format not in dumpers.get:
            return self.status("%s for '%s' not supported/implemented." %
                               ("Dumper", target_format))

        # Now the actual "building" starts (collecting remaining parameters)
        with OutputPanel(self.window, "package_dev") as output:
            output.show()

            # Auto-detect the file type if it's not specified
            if not source_format:
                output.write("Input type not specified, auto-detecting...")
                for Loader in loaders.get.values():
                    if Loader.file_is_valid(self.view):
                        source_format = Loader.ext
                        output.write_line(' %s\n' % Loader.name)
                        break

                if not source_format:
                    return output.write_line("\nUnable to detect file type.")
                elif target_format == source_format:
                    return output.write_line("File already is %s." %
                                             loaders.get[source_format].name)

            # Load inline options
            Loader = loaders.get[source_format]
            opts = Loader.load_options(self.view)

            # Function to determine the new file extension depending on the target format
            def get_new_ext(target_format):
                if ext:
                    return '.' + ext
                if opts and 'ext' in opts:
                    return '.' + opts['ext']
                else:
                    new_ext, prepend_target_format = Loader.get_new_file_ext(
                        self.view)
                    if prepend_target_format:
                        new_ext = ".%s-%s" % (target_format.upper(),
                                              new_ext[1:])

                return (new_ext or '.' + target_format)

            path_tuple = file_path_tuple(
                file_path)  # This is the latest point possible

            if not target_format:
                output.write(
                    "No target format specified, searching in file...")

                # No information about a target format; ask for it
                if not opts or 'target_format' not in opts:
                    output.write(" Could not detect target format.\n"
                                 "Please select or define a target format...")

                    # Show overlay with all dumping options except for the current type
                    # Save stripped-down `items` for later
                    options, items = [], []
                    for itm in self.target_list:
                        # To not clash with function-local "target_format"
                        target_format_ = itm['kwargs']['target_format']
                        if target_format_ != source_format:
                            options.append([
                                "Convert to: %s" % itm['name'],
                                path_tuple.base_name +
                                get_new_ext(target_format_)
                            ])
                            items.append(itm)

                    def on_select(index):
                        if index < 0 or index >= len(items):
                            # canceled or other magic
                            output.write_line("\n\nBuild canceled.")
                            return

                        target = items[index]
                        output.write_line(' %s\n' % target['name'])

                        kwargs.update(target['kwargs'])
                        kwargs.update(
                            dict(source_format=source_format, _output=output))
                        self.run(*args, **kwargs)

                    # Forward all params to the new command call
                    self.window.show_quick_panel(options, on_select)
                    return

                target_format = opts['target_format']
                # Validate the shit again, but this time print to output panel
                if source_format is not None and target_format == source_format:
                    return output.write_line(
                        "\nTarget and source file format are identical. (%s)" %
                        target_format)

                if target_format not in dumpers.get:
                    return output.write_line(
                        "\n%s for '%s' not supported/implemented." %
                        ("Dumper", target_format))

                output.write_line(' %s\n' % dumpers.get[target_format].name)

            start_time = time.time()

            # Okay, THIS is where the building really starts
            # Note: loader or dumper errors are not caught in order to receive a nice traceback in the console
            loader_ = Loader(self.window, self.view, output=output)
            try:
                data = loader_.load(*args, **kwargs)
            except:
                output.write_line("Unexpected error occured while parsing, "
                                  "please see the console for details.")
                raise
            if not data:
                return

            # Determine new file name
            new_file_path = path_tuple.no_ext + get_new_ext(target_format)
            new_dir = os.path.dirname(new_file_path)
            if not os.path.exists(new_dir):
                try:
                    os.makedirs(new_dir)
                except OSError:
                    output.write_line("Could not create folder '%s'" % new_dir)
                    return

            # Now dump to new file
            dumper = dumpers.get[target_format](self.window,
                                                self.view,
                                                new_file_path,
                                                output=output)
            try:
                dumper.dump(data, *args, **kwargs)
            except:
                output.write_line("Unexpected error occured while dumping, "
                                  "please see the console for details.")
                raise
            self.status("File conversion successful. (%s -> %s)" %
                        (source_format, target_format))

            # Finish
            output.write_line("[Finished in %.3fs]" %
                              (time.time() - start_time))
            # We need to save the text if calling "rearrange_yaml_syntax_def"
            # because `get_output_panel` resets its contents.
            output_text = get_text(output.view)

        # Continue with potential further steps
        if open_new_file or rearrange_yaml_syntax_def:
            new_view = self.window.open_file(new_file_path)

            if rearrange_yaml_syntax_def:
                new_view.run_command("rearrange_yaml_syntax_def", {
                    "save": True,
                    "_output_text": output_text
                })
Exemple #19
0
 def run(self, edit):
     snippet = get_text(self.view)
     contents = ET.fromstring(snippet).findtext(".//content")
     v = self.view.window().new_file()
     v.insert(edit, 0, contents)
     v.set_syntax_file(RAW_SNIPPETS_SYNTAX)
Exemple #20
0
 def run(self, edit):
     snip = get_text(self.view)
     self.view.window().run_command('close')
     target = sublime.active_window().active_view()
     target.replace(edit, target.sel()[0], snip)
Exemple #21
0
 def run(self, edit):
     snip = get_text(self.view)
     self.view.window().run_command('close')
     target = sublime.active_window().active_view()
     target.replace(edit, target.sel()[0], snip)
    def run(
        self,
        edit=None,
        source_format=None,
        target_format=None,
        ext=None,
        open_new_file=False,
        rearrange_yaml_syntax_def=False,
        _output=None,
        *args,
        **kwargs
    ):
        """Available parameters:

        edit (sublime.Edit) = None
            The edit parameter from TextCommand. Unused.

        source_format (str) = None
            The source format. Any of "yaml", "plist" or "json".
            If `None`, attempt to automatically detect the format by extension, used syntax
            highlight or (with plist) the actual contents.

        target_format (str) = None
            The target format. Any of "yaml", "plist" or "json".
            If `None`, attempt to find an option set in the file to parse.
            If unable to find an option, ask the user directly with all available format options.

        ext (str) = None
            The extension of the file to convert to, without leading dot. If `None`, the extension
            will be automatically determined by a special algorythm using "appendixes".

            Here are a few examples:
                ".YAML-ppplist" yaml  -> plist ".ppplist"
                ".json"         json  -> yaml  ".yaml"
                ".tmplist"      plist -> json  ".JSON-tmplist"
                ".yaml"         json  -> plist ".JSON-yaml" (yes, doesn't make much sense)

        open_new_file (bool) = False
            Open the (newly) created file in a new buffer.

        rearrange_yaml_syntax_def (bool) = False
            Interesting for language definitions, will automatically run
            "rearrange_yaml_syntax_def" command on it, if the target format is "yaml".
            Overrides "open_new_file" parameter.

        _output (OutputPanel) = None
            For internal use only.

        *args
            Forwarded to pretty much every relevant call but does not have any effect.
            You can't pass *args in commands anyway.

        **kwargs
            Will be forwarded to both the loading function and the dumping function, after
            stripping unsupported entries. Only do this if you know what you're doing.

            Functions in question:
                yaml.dump
                json.dump
                plist.writePlist (does not support any parameters)

            A more detailed description of each supported parameter for the respective dumper can
            be found in `fileconv/dumpers.py`.
        """
        # TODO: Ditch *args, can't be passed in commands anyway

        # Check the environment (view, args, ...)

        if self.view.is_dirty():
            # Save the file so that source and target file on the drive don't differ
            self.view.run_command("save")
            if self.view.is_dirty():
                return sublime.error_message("The file could not be saved correctly. " "The build was aborted")

        file_path = self.view.file_name()
        if not file_path:
            return self.status("File does not exist.", file_path)

        if source_format and target_format == source_format:
            return self.status("Target and source file format are identical. (%s)" % target_format)

        if source_format and source_format not in loaders.get:
            return self.status("Loader for '%s' not supported/implemented." % source_format)

        if target_format and target_format not in dumpers.get:
            return self.status("Dumper for '%s' not supported/implemented." % target_format)

        # Now the actual "building" starts (collecting remaining parameters)
        with OutputPanel(self.window, "package_dev") as output:
            output.show()

            # Auto-detect the file type if it's not specified
            if not source_format:
                output.write("Input type not specified, auto-detecting...")
                for Loader in loaders.get.values():
                    if Loader.file_is_valid(self.view):
                        source_format = Loader.ext
                        output.write_line(" %s\n" % Loader.name)
                        break

                if not source_format:
                    return output.write_line("\nUnable to detect file type.")
                elif target_format == source_format:
                    return output.write_line("File already is %s." % Loader.name)

            # Load inline options
            Loader = loaders.get[source_format]
            opts = Loader.load_options(self.view)

            # Function to determine the new file extension depending on the target format
            def get_new_ext(target_format):
                if ext:
                    return "." + ext
                if opts and "ext" in opts:
                    return "." + opts["ext"]
                else:
                    new_ext, prepend_target_format = Loader.get_new_file_ext(self.view)
                    if prepend_target_format:
                        new_ext = ".%s-%s" % (target_format.upper(), new_ext[1:])

                return new_ext or "." + target_format

            path_tuple = file_path_tuple(file_path)  # This is the latest point possible

            if not target_format:
                output.write("No target format specified, searching in file...")

                # No information about a target format; ask for it
                if not opts or "target_format" not in opts:
                    output.write(" Could not detect target format.\n" "Please select or define a target format...")

                    # Show overlay with all dumping options except for the current type
                    # Save stripped-down `items` for later
                    options, items = [], []
                    for itm in self.target_list:
                        # To not clash with function-local "target_format"
                        target_format_ = itm["kwargs"]["target_format"]
                        if target_format_ != source_format:
                            options.append(
                                ["Convert to: %s" % itm["name"], path_tuple.base_name + get_new_ext(target_format_)]
                            )
                            items.append(itm)

                    def on_select(index):
                        if index < 0 or index >= len(items):
                            # canceled or other magic
                            output.write_line("\n\nBuild canceled.")
                            return

                        target = items[index]
                        output.write_line(" %s\n" % target["name"])

                        kwargs.update(target["kwargs"])
                        kwargs.update(dict(source_format=source_format, _output=output))
                        self.run(*args, **kwargs)

                    # Forward all params to the new command call
                    self.window.show_quick_panel(options, on_select)
                    return

                target_format = opts["target_format"]
                # Validate the shit again, but this time print to output panel
                if source_format is not None and target_format == source_format:
                    return output.write_line("\nTarget and source file format are identical. (%s)" % target_format)

                if target_format not in dumpers.get:
                    return output.write_line("\nDumper for '%s' not supported/implemented." % target_format)

                output.write_line(" %s\n" % dumpers.get[target_format].name)

            start_time = time.time()

            # Okay, THIS is where the building really starts
            # Note: loader or dumper errors are not caught
            #       in order to receive a nice traceback in the console
            loader_ = Loader(self.window, self.view, output=output)
            try:
                data = loader_.load(*args, **kwargs)
            except:
                output.write_line("Unexpected error occured while parsing, " "please see the console for details.")
                raise
            if not data:
                return

            # Determine new file name
            new_file_path = path_tuple.no_ext + get_new_ext(target_format)
            new_dir = os.path.dirname(new_file_path)
            if not os.path.exists(new_dir):
                try:
                    os.makedirs(new_dir)
                except OSError:
                    output.write_line("Could not create folder '%s'" % new_dir)
                    return

            # Now dump to new file
            dumper = dumpers.get[target_format](self.window, self.view, new_file_path, output=output)
            try:
                dumper.dump(data, *args, **kwargs)
            except:
                output.write_line("Unexpected error occured while dumping, " "please see the console for details.")
                raise
            self.status("File conversion successful. (%s -> %s)" % (source_format, target_format))

            # Finish
            output.write_line("[Finished in %.3fs]" % (time.time() - start_time))
            # We need to save the text if calling "rearrange_yaml_syntax_def"
            # because `get_output_panel` resets its contents.
            output_text = get_text(output.view)

        # Continue with potential further steps
        if open_new_file or rearrange_yaml_syntax_def:
            new_view = self.window.open_file(new_file_path)

            if rearrange_yaml_syntax_def:
                new_view.run_command("rearrange_yaml_syntax_def", {"save": True, "_output_text": output_text})