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
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))
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)
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)
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 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): # 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
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
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
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
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 })
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)
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})