├── .gitignore ├── .rspec ├── .travis.yml ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Rakefile ├── bin └── sublime_syntax_convertor ├── lib ├── sublime_syntax_convertor.rb └── sublime_syntax_convertor │ ├── convertor.rb │ ├── formatter.rb │ ├── patterns.rb │ ├── syntax_yaml.rb │ └── version.rb └── sublime_syntax_convertor.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /.yardoc 3 | /Gemfile.lock 4 | /_yardoc/ 5 | /coverage/ 6 | /doc/ 7 | /pkg/ 8 | /spec/reports/ 9 | /tmp/ 10 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.2.1 4 | before_install: gem install bundler -v 1.10.6 5 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # gem's dependencies are in sublime_syntax_convertor.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | sublime_syntax_convertor (0.1.0) 5 | plist 6 | 7 | GEM 8 | remote: https://rubygems.org/ 9 | specs: 10 | abstract_type (0.0.7) 11 | adamantium (0.2.0) 12 | ice_nine (~> 0.11.0) 13 | memoizable (~> 0.4.0) 14 | ast (2.0.0) 15 | awesome_print (1.6.1) 16 | axiom-types (0.1.1) 17 | descendants_tracker (~> 0.0.4) 18 | ice_nine (~> 0.11.0) 19 | thread_safe (~> 0.3, >= 0.3.1) 20 | coderay (1.1.0) 21 | coercible (1.0.0) 22 | descendants_tracker (~> 0.0.1) 23 | concord (0.1.5) 24 | adamantium (~> 0.2.0) 25 | equalizer (~> 0.0.9) 26 | descendants_tracker (0.0.4) 27 | thread_safe (~> 0.3, >= 0.3.1) 28 | diff-lcs (1.2.5) 29 | docile (1.1.5) 30 | equalizer (0.0.11) 31 | ffi (1.9.10) 32 | flay (2.4.0) 33 | ruby_parser (~> 3.0) 34 | sexp_processor (~> 4.0) 35 | flog (4.2.1) 36 | ruby_parser (~> 3.1, > 3.1.0) 37 | sexp_processor (~> 4.4) 38 | formatador (0.2.5) 39 | guard (2.12.9) 40 | formatador (>= 0.2.4) 41 | listen (>= 2.7, <= 4.0) 42 | lumberjack (~> 1.0) 43 | nenv (~> 0.1) 44 | notiffany (~> 0.0) 45 | pry (>= 0.9.12) 46 | shellany (~> 0.0) 47 | thor (>= 0.18.1) 48 | guard-compat (1.2.1) 49 | guard-rspec (4.6.3) 50 | guard (~> 2.1) 51 | guard-compat (~> 1.1) 52 | rspec (>= 2.99.0, < 4.0) 53 | ice_nine (0.11.1) 54 | json (1.8.6) 55 | listen (3.0.3) 56 | rb-fsevent (>= 0.9.3) 57 | rb-inotify (>= 0.9) 58 | lumberjack (1.0.9) 59 | memoizable (0.4.2) 60 | thread_safe (~> 0.3, >= 0.3.1) 61 | method_source (0.8.2) 62 | nenv (0.2.0) 63 | notiffany (0.0.6) 64 | nenv (~> 0.1) 65 | shellany (~> 0.0) 66 | parser (2.2.2.6) 67 | ast (>= 1.1, < 3.0) 68 | plist (3.1.0) 69 | procto (0.0.2) 70 | pry (0.10.1) 71 | coderay (~> 1.1.0) 72 | method_source (~> 0.8.1) 73 | slop (~> 3.4) 74 | rainbow (2.0.0) 75 | rake (10.4.2) 76 | rb-fsevent (0.9.5) 77 | rb-inotify (0.9.5) 78 | ffi (>= 0.5.0) 79 | reek (1.6.5) 80 | parser (~> 2.2.0.pre.7) 81 | rainbow (>= 1.99, < 3.0) 82 | unparser (~> 0.2.2) 83 | rspec (3.3.0) 84 | rspec-core (~> 3.3.0) 85 | rspec-expectations (~> 3.3.0) 86 | rspec-mocks (~> 3.3.0) 87 | rspec-core (3.3.2) 88 | rspec-support (~> 3.3.0) 89 | rspec-expectations (3.3.1) 90 | diff-lcs (>= 1.2.0, < 2.0) 91 | rspec-support (~> 3.3.0) 92 | rspec-mocks (3.3.2) 93 | diff-lcs (>= 1.2.0, < 2.0) 94 | rspec-support (~> 3.3.0) 95 | rspec-support (3.3.0) 96 | ruby_parser (3.7.0) 97 | sexp_processor (~> 4.1) 98 | rubycritic (1.4.0) 99 | flay (= 2.4.0) 100 | flog (= 4.2.1) 101 | parser (>= 2.2.0, < 3.0) 102 | reek (= 1.6.5) 103 | virtus (~> 1.0) 104 | sexp_processor (4.6.0) 105 | shellany (0.0.1) 106 | simplecov (0.10.0) 107 | docile (~> 1.1.0) 108 | json (~> 1.8) 109 | simplecov-html (~> 0.10.0) 110 | simplecov-html (0.10.0) 111 | slop (3.6.0) 112 | thor (0.19.1) 113 | thread_safe (0.3.5) 114 | unparser (0.2.4) 115 | abstract_type (~> 0.0.7) 116 | adamantium (~> 0.2.0) 117 | concord (~> 0.1.5) 118 | diff-lcs (~> 1.2.5) 119 | equalizer (~> 0.0.9) 120 | parser (~> 2.2.2) 121 | procto (~> 0.0.2) 122 | virtus (1.0.5) 123 | axiom-types (~> 0.1) 124 | coercible (~> 1.0) 125 | descendants_tracker (~> 0.0, >= 0.0.3) 126 | equalizer (~> 0.0, >= 0.0.9) 127 | 128 | PLATFORMS 129 | ruby 130 | 131 | DEPENDENCIES 132 | awesome_print 133 | bundler (~> 1.10) 134 | guard-rspec 135 | rake (~> 10.0) 136 | rspec 137 | rubycritic 138 | simplecov 139 | sublime_syntax_convertor! 140 | 141 | BUNDLED WITH 142 | 1.16.2 143 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 Allen A. Bargi 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Sublime Syntax Convertor 2 | Converts `tmLanguage` to `sublime-syntax` 3 | 4 | ## Install 5 | Add this line to your application's Gemfile: 6 | 7 | ```ruby 8 | gem 'sublime_syntax_convertor' 9 | ``` 10 | 11 | And then execute: 12 | 13 | bundle 14 | 15 | Or install it yourself as: 16 | 17 | gem install sublime_syntax_convertor 18 | 19 | ## USAGE 20 | 21 | ### Command line 22 | ```bash 23 | sublime_syntax_convertor files 24 | sublime_syntax_convertor folder 25 | ``` 26 | 27 | ### In your code 28 | ```ruby 29 | require 'sublime_syntax_convertor' 30 | file = File.read(tmLanguage_file) 31 | convertor = SublimeSyntaxConvertor::Convertor.new(file) 32 | sublime_syntax = convertor.to_yaml 33 | ``` 34 | 35 | 36 | --- 37 | © Copyright 2015 Allen Bargi. See LICENSE for details. 38 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | require 'rspec/core/rake_task' 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | task default: :spec 6 | -------------------------------------------------------------------------------- /bin/sublime_syntax_convertor: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'yaml' 3 | require_relative '../lib/sublime_syntax_convertor' 4 | 5 | def difference(a, b) 6 | diff = (a.size >= b.size) ? a.to_a - b.to_a : b.to_a - a.to_a 7 | Hash[*diff.flatten] 8 | end 9 | 10 | if ARGV.empty? 11 | puts "USAGE: sublime_syntax_convertor files" 12 | puts " sublime_syntax_convertor folder" 13 | else 14 | filenames = [] 15 | ARGV.each do |path| 16 | path = File.expand_path(path) 17 | if File.directory?(path) 18 | filenames.push(*Dir[File.join(path, '*.tmLanguage')]) 19 | else 20 | filenames.push(path) 21 | end 22 | end 23 | 24 | filenames.each do |fname| 25 | outfile = File.join(File.dirname(fname), File.basename(fname, '.tmLanguage') + ".sublime-syntax") 26 | if File.exist?(outfile) 27 | puts "file already exists, deleting: #{outfile}" 28 | File.delete(outfile) 29 | end 30 | 31 | convertor = SublimeSyntaxConvertor::Convertor.new(File.read(fname)) 32 | text = convertor.to_yaml 33 | 34 | # verify that to_yaml produces valid yaml for this syntax 35 | if convertor.syntax != YAML.load(text.gsub('%YAML 1.2', '')) 36 | yaml = YAML.load(text.gsub('%YAML 1.2', '')) 37 | syntax = convertor.syntax 38 | diff = difference(yaml, syntax) 39 | fail "Sorry, generated invalid YAML! #{fname}" 40 | end 41 | 42 | File.open(outfile, "w") { |f| f.write(text) } 43 | puts "converted #{outfile}" 44 | end 45 | end 46 | -------------------------------------------------------------------------------- /lib/sublime_syntax_convertor.rb: -------------------------------------------------------------------------------- 1 | require 'plist' 2 | require_relative './sublime_syntax_convertor/version' 3 | require_relative './sublime_syntax_convertor/formatter' 4 | require_relative './sublime_syntax_convertor/patterns' 5 | require_relative './sublime_syntax_convertor/syntax_yaml' 6 | require_relative './sublime_syntax_convertor/convertor' 7 | -------------------------------------------------------------------------------- /lib/sublime_syntax_convertor/convertor.rb: -------------------------------------------------------------------------------- 1 | module SublimeSyntaxConvertor 2 | class Convertor 3 | include Formatter 4 | attr_reader :syntax 5 | 6 | def initialize(lang) 7 | @lang = Plist.parse_xml(lang) 8 | @repository = @lang.fetch('repository', {}) 9 | @patterns = @lang.fetch('patterns', []) 10 | @syntax = {} 11 | normalize_repository 12 | convert 13 | end 14 | 15 | def to_yaml 16 | SyntaxYaml.new(@syntax).yaml 17 | end 18 | 19 | private 20 | 21 | def normalize_repository 22 | @repository.each do |key, value| 23 | if value.key?('begin') || value.key?('match') 24 | @repository[key] = [value] 25 | else 26 | @repository[key] = value['patterns'] 27 | end 28 | end 29 | end 30 | 31 | def create_contexts 32 | contexts = {} 33 | contexts['main'] = make_context(@lang['patterns']) 34 | @repository.each do |key, value| 35 | fail 'Double definition of main context' if key == 'main' 36 | contexts[key] = make_context(value) 37 | end 38 | contexts 39 | end 40 | 41 | def convert 42 | syntax = {} 43 | syntax['comment'] = format_comment(@lang['comment']) if @lang.key?('comment') 44 | syntax['first_line_match'] = format_regex(@lang['firstLineMatch']) if @lang.key?('firstLineMatch') 45 | syntax['name'] = @lang['name'] if @lang.key?('name') 46 | syntax['scope'] = @lang['scopeName'] if @lang.key?('scopeName') 47 | syntax['file_extensions'] = @lang['fileTypes'] if @lang.key?('fileTypes') 48 | syntax['hidden'] = @lang['hideFromUser'] if @lang.key?('hideFromUser') 49 | syntax['hidden'] = @lang['hidden'] if @lang.key?('hidden') 50 | syntax['contexts'] = create_contexts 51 | @syntax = syntax 52 | end 53 | 54 | def handle_begin_pattern(pattern) 55 | entry = BeginEndPattern.new('begin', pattern).to_h 56 | entry['comment'] = format_comment(pattern['comment']) if pattern.key?('comment') && !format_comment(pattern['comment']).empty? 57 | entry['push'] = handle_child_pattern(pattern) 58 | entry 59 | end 60 | 61 | def handle_child_pattern(pattern) 62 | end_entry = BeginEndPattern.new('end', pattern).to_h 63 | child_patterns = pattern.key?('patterns') ? pattern["patterns"] : [] 64 | child = make_context(child_patterns) 65 | apply_last = pattern.key?('applyEndPatternLast') && pattern['applyEndPatternLast'] == 1 66 | apply_last ? child.push(end_entry) : child.unshift(end_entry) 67 | child.unshift('meta_content_scope' => pattern['contentName']) if pattern.key?('contentName') 68 | child.unshift('meta_scope' => pattern['name']) if pattern.key?('name') 69 | if end_entry['match'].include? "\\G" 70 | puts """WARNING: 71 | pop pattern contains \\G, this will not work as expected 72 | if it's intended to refer to the begin regex: #{end_entry['match']}""" 73 | end 74 | child 75 | end 76 | 77 | def handle_include_pattern(pattern) 78 | key = pattern['include'] 79 | if key[0] == '#' 80 | key = key[1..-1] 81 | fail Exception("no entry in repository for #{key}") unless @repository.key?(key) 82 | return { 'include' => key } 83 | elsif key == '$self' 84 | return { 'include' => 'main' } 85 | elsif key == '$base' 86 | return { 'include' => '$top_level_main' } 87 | elsif key[0] == '$' 88 | fail Exception "unknown include: #{key}" 89 | else 90 | return { 'include' => format_external_syntax(key) } 91 | end 92 | end 93 | 94 | def make_context(patterns) 95 | ctx = [] 96 | patterns.each do |pattern| 97 | if pattern.key?('begin') 98 | entry = handle_begin_pattern(pattern) 99 | elsif pattern.key?('match') 100 | entry = MatchPattern.new(pattern).to_h 101 | elsif pattern.key?('include') 102 | entry = handle_include_pattern(pattern) 103 | else 104 | fail Exception.new("unknown pattern type: #{pattern.keys}") 105 | end 106 | ctx.push(entry) if entry 107 | end 108 | ctx 109 | end 110 | end 111 | end 112 | -------------------------------------------------------------------------------- /lib/sublime_syntax_convertor/formatter.rb: -------------------------------------------------------------------------------- 1 | module SublimeSyntaxConvertor 2 | module Formatter 3 | def format_comment(str) 4 | str = str.strip.gsub("\t", " ") 5 | str = str.rstrip + "\n" if str.include?("\n") 6 | str 7 | end 8 | 9 | def format_regex(str) 10 | if str.include? "\n" 11 | lines = str.split("\n") 12 | # trim common indentation off of each line 13 | if lines.size > 1 14 | common_indent = leading_whitespace(lines[1]) 15 | lines[2..-1].each do |line| 16 | cur_indent = leading_whitespace(line) 17 | if cur_indent.start_with?(common_indent) 18 | next 19 | elsif common_indent.start_with?(cur_indent) 20 | common_indent = cur_indent 21 | else 22 | common_indent = '' 23 | end 24 | end 25 | # Generally the first line doesn't have any indentation, add some 26 | lines[0] = common_indent + lines[0].lstrip unless lines[0].start_with?(common_indent) 27 | else 28 | common_indent = leading_whitespace(lines[0]) 29 | end 30 | str = lines.map { |line| line[common_indent.size..-1] }.join("\n").rstrip 31 | end 32 | str 33 | end 34 | 35 | def format_captures(cap) 36 | captures = {} 37 | cap.each do |key, value| 38 | unless value.key?('name') 39 | puts "patterns and includes are not supported within captures: #{cap}" 40 | next 41 | end 42 | 43 | begin 44 | captures[key.to_i] = value['name'] 45 | rescue 46 | puts 'named capture used, this is unsupported' 47 | captures[key] = value['name'] 48 | end 49 | end 50 | captures 51 | end 52 | 53 | def format_external_syntax(key) 54 | fail 'invalid external syntax name' if '#$'.include?(key[0]) 55 | if key.include?('#') 56 | syntax, rule = key.split('#') 57 | return "scope:#{syntax}##{rule}" 58 | else 59 | return "scope:#{key}" 60 | end 61 | end 62 | 63 | def needs_quoting?(str) 64 | ( 65 | str == "" || 66 | str.start_with?('<<') || 67 | "\"'%-:?@`&*!,#|>0123456789=".include?(str[0]) || 68 | %w(true false null).include?(str) || 69 | str.include?("# ") || 70 | str.include?(': ') || 71 | str.include?('[') || 72 | str.include?(']') || 73 | str.include?('{') || 74 | str.include?('}') || 75 | str.include?("\n") || 76 | ":#".include?(str[-1]) || 77 | str.strip != str 78 | ) 79 | end 80 | 81 | def quote(str) 82 | if str.include?("\\") || str.include?('"') 83 | return "'" + str.gsub("'", "''") + "'" 84 | else 85 | return '"' + str.gsub("\\", "\\\\").gsub('"', '\\"') + '"' 86 | end 87 | end 88 | 89 | def leading_whitespace(str) 90 | str[0...(str.size - str.lstrip.size)] 91 | end 92 | end 93 | end 94 | -------------------------------------------------------------------------------- /lib/sublime_syntax_convertor/patterns.rb: -------------------------------------------------------------------------------- 1 | require_relative './formatter' 2 | 3 | module SublimeSyntaxConvertor 4 | class MatchPattern 5 | include Formatter 6 | attr_reader :match, :scope, :captures, :comment 7 | 8 | def initialize(pat) 9 | @match = format_regex(pat['match']) 10 | @scope = pat['name'] if pat.key?('name') 11 | @captures = format_captures(pat['captures']) if pat.key?('captures') 12 | @comment = format_comment(pat['comment']) if pat.key?('comment') && !format_comment(pat['comment']).empty? 13 | end 14 | 15 | def to_h 16 | hash = {} 17 | hash['match'] = @match if @match 18 | hash['scope'] = @scope if @scope 19 | hash['captures'] = @captures if @captures 20 | hash['comment'] = @comment if @comment 21 | hash 22 | end 23 | end 24 | 25 | class BeginEndPattern 26 | include Formatter 27 | attr_reader :match, :pop, :captures 28 | 29 | def initialize(type, pattern) 30 | @pattern = pattern 31 | @type = type 32 | @match = format_regex(pattern[type]) 33 | @pop = true if type == 'end' 34 | handle_captures 35 | end 36 | 37 | def to_h 38 | hash = {} 39 | hash['match'] = @match if @match 40 | hash['pop'] = @pop if @pop 41 | hash['captures'] = @captures if @captures 42 | hash 43 | end 44 | 45 | private 46 | 47 | def handle_captures 48 | pattern_captures = @pattern["#{@type}Captures"] || @pattern["captures"] 49 | return unless pattern_captures 50 | captures = format_captures(pattern_captures) 51 | if captures.key?('0') 52 | entry['scope'] = captures['0'] 53 | captures.delete('0') 54 | end 55 | @captures = captures if captures.size > 0 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /lib/sublime_syntax_convertor/syntax_yaml.rb: -------------------------------------------------------------------------------- 1 | require_relative './formatter' 2 | 3 | module SublimeSyntaxConvertor 4 | class SyntaxYaml 5 | include Formatter 6 | attr_reader :yaml 7 | TAB_SIZE = 2 8 | 9 | def initialize(val) 10 | @yaml = to_yaml(val, false, 0) 11 | end 12 | 13 | private 14 | 15 | def to_yaml(val, start_block_on_newline, indent) 16 | out = '' 17 | 18 | if indent == 0 19 | out += "%YAML 1.2\n---\n" 20 | out += "# http://www.sublimetext.com/docs/3/syntax.html\n" 21 | end 22 | 23 | if val.is_a?(Array) 24 | out += array_to_yaml(val, start_block_on_newline, indent) 25 | elsif val.is_a?(Hash) 26 | out += hash_to_yaml(val, start_block_on_newline, indent) 27 | elsif val.is_a?(String) 28 | out += string_to_yaml(val, start_block_on_newline, indent) 29 | elsif val.is_a?(TrueClass) || val.is_a?(FalseClass) 30 | out += boolean_to_yaml(val) 31 | else 32 | out += "#{val}\n" 33 | end 34 | # to_yaml will leave some trailing whitespace, remove it 35 | out.split("\n").map(&:rstrip).join("\n") + "\n" 36 | end 37 | 38 | def array_to_yaml(val, start_block_on_newline, indent) 39 | out = '' 40 | if val.size == 0 41 | out += "[]\n" 42 | else 43 | out += "\n" if start_block_on_newline 44 | val.each { |item| out += ' ' * indent + '- ' + to_yaml(item, false, indent + 2) } 45 | end 46 | out 47 | end 48 | 49 | def hash_to_yaml(val, start_block_on_newline, indent) 50 | out = '' 51 | out += "\n" if start_block_on_newline 52 | first = true 53 | order_keys(val.keys).each do |key| 54 | value = val[key] 55 | if !first || start_block_on_newline 56 | out += ' ' * indent 57 | else 58 | first = false 59 | end 60 | 61 | if key.is_a?(Numeric) 62 | out += key.to_s 63 | elsif needs_quoting?(key) 64 | out += quote(key) 65 | else 66 | out += key 67 | end 68 | 69 | out += ": " 70 | out += to_yaml(value, true, indent + TAB_SIZE) 71 | end 72 | out 73 | end 74 | 75 | def string_to_yaml(val, start_block_on_newline, indent) 76 | out = '' 77 | if needs_quoting?(val) 78 | if val.include?("\n") 79 | fail unless start_block_on_newline 80 | out += (val[-1] == "\n") ? "|\n" : "|-\n" 81 | val.split("\n").each { |line| out += "#{' ' * indent}#{line}\n" } 82 | else 83 | out += "#{quote(val)}\n" 84 | end 85 | return out 86 | else 87 | return "#{val}\n" 88 | end 89 | end 90 | 91 | def boolean_to_yaml(val) 92 | val ? "true\n" : "false\n" 93 | end 94 | 95 | def order_keys(list) 96 | key_order = %w(name main match comment file_extensions first_line_match hidden match scope main).reverse 97 | list = list.sort 98 | key_order.each do |key| 99 | if list.include?(key) 100 | list.delete_at(list.index(key)) 101 | list.insert(0, key) 102 | end 103 | end 104 | list 105 | end 106 | 107 | end 108 | end 109 | -------------------------------------------------------------------------------- /lib/sublime_syntax_convertor/version.rb: -------------------------------------------------------------------------------- 1 | module SublimeSyntaxConvertor 2 | VERSION = '0.1.0' 3 | end 4 | -------------------------------------------------------------------------------- /sublime_syntax_convertor.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'sublime_syntax_convertor/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = 'sublime_syntax_convertor' 8 | spec.version = SublimeSyntaxConvertor::VERSION 9 | spec.authors = ['Allen Bargi'] 10 | spec.email = ['allen.bargi@gmail.com'] 11 | spec.description = 'Converts tmLanguage to sublime-syntax' 12 | spec.summary = 'Converts tmLanguage to sublime-syntax' 13 | spec.homepage = 'https://github.com/aziz/SublimeSyntaxConvertor' 14 | spec.license = 'MIT' 15 | 16 | spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 17 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 18 | spec.require_paths = ['lib'] 19 | 20 | spec.add_dependency 'plist' 21 | 22 | spec.add_development_dependency 'bundler', '~> 1.10' 23 | spec.add_development_dependency 'rake', '~> 10.0' 24 | spec.add_development_dependency 'rspec' 25 | spec.add_development_dependency 'awesome_print' 26 | spec.add_development_dependency 'guard-rspec' 27 | spec.add_development_dependency 'simplecov' 28 | spec.add_development_dependency 'rubycritic' 29 | end 30 | --------------------------------------------------------------------------------