sublime2yas 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +60 -0
- data/Rakefile +1 -0
- data/bin/sublime2yas +146 -0
- data/lib/sublime2yas.rb +290 -0
- data/lib/sublime2yas/version.rb +3 -0
- data/sublime2yas.gemspec +25 -0
- metadata +110 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
MDgzYjJhMWNjYmQ4ZmMyMGFhYjQ3OWFkZWRlYTBjMzE2N2FlNWM0ZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MzliNmEwYmE0ODhmM2QzM2Y0MWYzNzc1ZDA1ZGUxMDI2NTcxNTY1NA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
NGVhMGJkOGVjNzRmY2ZmMGM0MTExZWYwNWMwODk2MGI2ODgzMzcxMTdlZjZj
|
10
|
+
MDI5MzBiNjg2ZTkxODhjZDA3YWY3NzE0ZTU1NGEyOTU1MjlmZDEyYTkzMzVj
|
11
|
+
MzQ1MmY4YWI3YmFjNzk1N2JmZGMyOGM2MGQzOTZhZWVlYmQ4NDM=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDdkOTdhMWQ0NzA5MmM2MDkxODI3MGQxMTk2ZTVlZWU3MGZkZmMyMDVlZWZl
|
14
|
+
MjIyY2QxMWYyNjU0NjA2OGUzYzNlODQ2NzI5MGVhNjY0NjAxZTI2YTcwMDg5
|
15
|
+
Mzk1MmY0Y2I1ZDU1NTMzNzA1YjViM2QwMmQwZWViNzEzMzlkOTA=
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Jasonm23
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
# Sublime2yas
|
2
|
+
|
3
|
+
##### SublimeText to YaSnippet / Emacs conversion
|
4
|
+
|
5
|
+
This is a script based on the old TextMate import script that
|
6
|
+
ship(ped) with YASnippet for Emacs.
|
7
|
+
|
8
|
+
This script is focussed only on `.sublime-snippet` files, and ignores
|
9
|
+
commands or macros or whatever else might exist in the SublimeText
|
10
|
+
universe (I'm largely ignorant of it TBH.) What I do know is there's
|
11
|
+
a lot of snippets I want to harvest from it and bring into Emacs, and
|
12
|
+
I'll be hornswoggled if I'm going to do that mucky business by hand.
|
13
|
+
|
14
|
+
So instead here's a script which will take care of it, with a few
|
15
|
+
extra bells and whistles thrown in for good measure.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
|
19
|
+
gem install sublime2yas
|
20
|
+
|
21
|
+
## Uninstall
|
22
|
+
|
23
|
+
gem uninstall sublime2yas
|
24
|
+
|
25
|
+
## Usage
|
26
|
+
|
27
|
+
For help run `sublime2yas --help` from the command line on a single folder of SublimeText Snippets.
|
28
|
+
|
29
|
+
sublime2yas -d SublimeSnippetsFolder -o YasnippetsFolder
|
30
|
+
|
31
|
+
### Options
|
32
|
+
|
33
|
+
Options:
|
34
|
+
--snippet-dir, -d <s>: Sublime-snippet directory
|
35
|
+
--output-dir, -o <s>: Output directory, use the major-mode name you are targeting as the containing folder's name, e.g.
|
36
|
+
snippets/major-mode
|
37
|
+
--major-mode, -m <s>: Explicit setting of major-mode if the folder name is different
|
38
|
+
--parent-modes, -p <s>: List of Yasnippet parent modes as a quoted string eg. "cc-mode,text-mode"
|
39
|
+
--glob, -g <s>: Specific snippet file (or glob) inside <snippet_dir>, default is *.sublime-snippet (default:
|
40
|
+
*.sublime-snippet)
|
41
|
+
--snippet-group, -G <s>: Yasnippet group: to use in generated snippets, eg. -G rails to add 'group: rails' to each snippet. They will
|
42
|
+
appear in submenu's on the major-mode Yasnippet menu
|
43
|
+
--quiet, -q: quiet output
|
44
|
+
--doc, -c: generate a quick reference in markdown format, listing the shortcut and description. Stored in the
|
45
|
+
--output-dir as QUICKREF.md
|
46
|
+
--help, -h: Show this message
|
47
|
+
|
48
|
+
|
49
|
+
### Auto Quickref
|
50
|
+
|
51
|
+
When using the `--doc` or `-c` option a quick reference / cheatsheet
|
52
|
+
is generated in the `--output-dir` as `QUICKREF.md`. [See this example](https://gist.github.com/jasonm23/6396154)
|
53
|
+
|
54
|
+
## Contributing
|
55
|
+
|
56
|
+
1. Fork it
|
57
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
58
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
59
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
60
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/sublime2yas
ADDED
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# -*- coding: utf-8 -*-
|
3
|
+
# sublime2yas.rb --- convert Sublime Text Snippets to YASnippet
|
4
|
+
#
|
5
|
+
# generate YASnippets from Sublime Text Snippets.
|
6
|
+
# Use sublime2yas --help to get usage information.
|
7
|
+
#
|
8
|
+
# Copyright ©2013 Jason Milkins
|
9
|
+
# based on original work Copyright ©2009 Rob Christie, ©2010 João Távora
|
10
|
+
# which was in turn based on a python script by Jeff Wheeler: http://nokrev.com
|
11
|
+
# http://code.nokrev.com/?p=snippet-copier.git;a=blob_plain;f=snippet_copier.py
|
12
|
+
#
|
13
|
+
require 'sublime2yas'
|
14
|
+
require 'trollop'
|
15
|
+
require 'fileutils'
|
16
|
+
|
17
|
+
Encoding.default_external = Encoding::UTF_8 if RUBY_VERSION > '1.8.7'
|
18
|
+
|
19
|
+
snippet_doc = []
|
20
|
+
|
21
|
+
opts = Trollop::options do
|
22
|
+
opt :snippet_dir, %q(Sublime-snippet directory),
|
23
|
+
|
24
|
+
:short => '-d', :type => :string
|
25
|
+
|
26
|
+
opt :output_dir, %(Output directory, use the major-mode name you are targeting as the containing folder's name, e.g. snippets/major-mode),
|
27
|
+
|
28
|
+
:short => '-o', :type => :string
|
29
|
+
|
30
|
+
opt :major_mode, %(Explicit setting of major-mode if the folder name is different),
|
31
|
+
|
32
|
+
:short => '-m', :type => :string
|
33
|
+
|
34
|
+
opt :parent_modes, %q(List of Yasnippet parent modes as a quoted string eg. "cc-mode,text-mode"),
|
35
|
+
|
36
|
+
:short => '-p', :type => :string
|
37
|
+
|
38
|
+
opt :glob, %q(Specific snippet file (or glob) inside <snippet_dir>, default is *.sublime-snippet),
|
39
|
+
|
40
|
+
:short => '-g', :default => '*.sublime-snippet'
|
41
|
+
|
42
|
+
opt :snippet_group, %q(Yasnippet group: to use in generated snippets, eg. -G rails to add 'group: rails' to each snippet. They will appear in submenu's on the major-mode Yasnippet menu),
|
43
|
+
|
44
|
+
:short => '-G', :type => :string
|
45
|
+
|
46
|
+
opt :quiet, %(quiet output),
|
47
|
+
|
48
|
+
:short => '-q'
|
49
|
+
|
50
|
+
opt :doc, %(generate a quick reference in markdown format, listing the shortcut and description. Stored in the --output-dir as QUICKREF.md)
|
51
|
+
|
52
|
+
end
|
53
|
+
|
54
|
+
Trollop::die :snippet_dir, "'must be provided" unless opts.snippet_dir
|
55
|
+
Trollop::die :snippet_dir, "must exist" unless File.directory? opts.snippet_dir
|
56
|
+
|
57
|
+
Trollop::die :output_dir, "must be provided" unless opts.output_dir
|
58
|
+
Trollop::die :output_dir, "must exist" unless File.directory? opts.output_dir
|
59
|
+
|
60
|
+
|
61
|
+
modename = if opts.major_mode
|
62
|
+
opts.major_mode
|
63
|
+
else
|
64
|
+
File.basename opts.output_dir
|
65
|
+
end
|
66
|
+
|
67
|
+
original_dir = Dir.pwd
|
68
|
+
|
69
|
+
if opts.parent_modes
|
70
|
+
yas_parents_file = File.join(opts.output_dir, ".yas-parents")
|
71
|
+
File.open yas_parents_file, 'w' do |yp|
|
72
|
+
yp.puts opts.parent_modes
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
yas_setup_el_file = File.join(original_dir, opts.output_dir, ".yas-setup.el")
|
77
|
+
separator = ";; --**--"
|
78
|
+
whole, head, tail = "", "", ""
|
79
|
+
|
80
|
+
if File::exists? yas_setup_el_file
|
81
|
+
File.open yas_setup_el_file, '"r' do |file|
|
82
|
+
whole = file.read
|
83
|
+
head, tail = whole.split(separator)
|
84
|
+
end
|
85
|
+
else
|
86
|
+
head = ";; .yas-setup.el for #{modename}\n" + ";; \n"
|
87
|
+
end
|
88
|
+
|
89
|
+
tail ||= ""
|
90
|
+
head ||= ""
|
91
|
+
directive = nil
|
92
|
+
head.each_line do |line|
|
93
|
+
case line
|
94
|
+
when /^;; Substitutions for:(.*)$/
|
95
|
+
directive = $~[1].strip
|
96
|
+
when /^;;(.*)[ ]+=yyas>(.*)$/
|
97
|
+
replacewith = $~[2].strip
|
98
|
+
lookfor = $~[1]
|
99
|
+
lookfor.gsub!(/^[ ]*/, "")
|
100
|
+
lookfor.gsub!(/[ ]*$/, "")
|
101
|
+
unless !directive or replacewith =~ /yas-unknown/ then
|
102
|
+
Sublime2yas::SublimeSnippet.extra_substitutions[directive][lookfor] = replacewith
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
Dir.chdir opts.snippet_dir
|
108
|
+
snippet_files_glob = File.join("**", opts.glob)
|
109
|
+
snippet_files = Dir.glob(snippet_files_glob)
|
110
|
+
puts "Attempting to convert #{snippet_files.length} snippets...\n" unless opts.quiet
|
111
|
+
snippet_files.each do |file|
|
112
|
+
begin
|
113
|
+
$stdout.print "Processing \"#{File.join(opts.snippet_dir,file)}\"..." unless opts.quiet
|
114
|
+
snippet = Sublime2yas::SublimeSnippet.new(file)
|
115
|
+
file_to_create = File.join(original_dir, opts.output_dir, snippet.yas_file)
|
116
|
+
FileUtils.mkdir_p(File.dirname(file_to_create))
|
117
|
+
File.open(file_to_create, 'w') do |f|
|
118
|
+
f.write(snippet.to_yas opts)
|
119
|
+
end
|
120
|
+
|
121
|
+
snippet_doc << {keys: snippet.key, name: snippet.name} if opts.doc
|
122
|
+
|
123
|
+
$stdout.print "done\n" unless opts.quiet
|
124
|
+
rescue Sublime2yas::SkipSnippet => e
|
125
|
+
$stdout.print "skipped! #{e.message}\n" unless opts.quiet
|
126
|
+
rescue RuntimeError => e
|
127
|
+
$stderr.print "failed! #{e.message}\n"
|
128
|
+
$strerr.print "#{e.backtrace.join("\n")}" unless opts.quiet
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
# TODO: Perhaps do this as a slim template so we can use tables, flex-boxes and what-not.
|
133
|
+
if opts.doc
|
134
|
+
doc_file = File.join opts.output_dir, "QUICKREF.md"
|
135
|
+
File.open(doc_file, "w") do |f|
|
136
|
+
f.puts "# #{modename.capitalize} - Snippets Quick Reference"
|
137
|
+
snippet_doc.each do |doc|
|
138
|
+
f.puts "\n`#{doc[:keys]}` ➔ "
|
139
|
+
f.puts "\n>#### `#{doc[:name]}`"
|
140
|
+
end
|
141
|
+
f.puts "\n\n<sub>Generated by Sublime Snippet Import to Yasnippet, <sup>Powered by tea, figs and ruby</sup></sub>"
|
142
|
+
end
|
143
|
+
puts "#{modename.capitalize} - Snippets Quick Reference created."
|
144
|
+
end
|
145
|
+
|
146
|
+
|
data/lib/sublime2yas.rb
ADDED
@@ -0,0 +1,290 @@
|
|
1
|
+
require "sublime2yas/version"
|
2
|
+
require 'nokogiri'
|
3
|
+
require 'fileutils'
|
4
|
+
|
5
|
+
module Sublime2yas
|
6
|
+
|
7
|
+
|
8
|
+
class SublimeSubmenu
|
9
|
+
|
10
|
+
@@excluded_items = [];
|
11
|
+
def self.excluded_items; @@excluded_items; end
|
12
|
+
|
13
|
+
attr_reader :items, :name
|
14
|
+
def initialize(name, hash)
|
15
|
+
@items = hash["items"]
|
16
|
+
@name = name
|
17
|
+
end
|
18
|
+
|
19
|
+
def to_lisp(allsubmenus,
|
20
|
+
deleteditems,
|
21
|
+
indent = 0,
|
22
|
+
thingy = ["(", ")"])
|
23
|
+
|
24
|
+
first = true;
|
25
|
+
|
26
|
+
string = ""
|
27
|
+
separator_useless = true;
|
28
|
+
items.each do |uuid|
|
29
|
+
if deleteditems && deleteditems.index(uuid)
|
30
|
+
$stderr.puts "#{uuid} has been deleted!"
|
31
|
+
next
|
32
|
+
end
|
33
|
+
string += "\n"
|
34
|
+
string += " " * indent
|
35
|
+
string += (first ? thingy[0] : (" " * thingy[0].length))
|
36
|
+
|
37
|
+
submenu = allsubmenus[uuid]
|
38
|
+
snippet = SublimeSnippet::snippets_by_uid[uuid]
|
39
|
+
unimplemented = SublimeSnippet::unknown_substitutions["content"][uuid]
|
40
|
+
if submenu
|
41
|
+
str = "(yas-submenu "
|
42
|
+
string += str + "\"" + submenu.name + "\""
|
43
|
+
string += submenu.to_lisp(allsubmenus, deleteditems,
|
44
|
+
indent + str.length + thingy[0].length)
|
45
|
+
elsif snippet and not unimplemented
|
46
|
+
string += ";; " + snippet.name + "\n"
|
47
|
+
string += " " * (indent + thingy[0].length)
|
48
|
+
string += "(yas-item \"" + uuid + "\")"
|
49
|
+
separator_useless = false;
|
50
|
+
elsif snippet and unimplemented
|
51
|
+
string += ";; Ignoring " + snippet.name + "\n"
|
52
|
+
string += " " * (indent + thingy[0].length)
|
53
|
+
string += "(yas-ignore-item \"" + uuid + "\")"
|
54
|
+
separator_useless = true;
|
55
|
+
elsif (uuid =~ /---------------------/)
|
56
|
+
string += "(yas-separator)" unless separator_useless
|
57
|
+
end
|
58
|
+
first = false;
|
59
|
+
end
|
60
|
+
string += ")"
|
61
|
+
string += thingy[1]
|
62
|
+
|
63
|
+
return string
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.main_menu_to_lisp (parsed_plist, modename)
|
67
|
+
mainmenu = parsed_plist["mainMenu"]
|
68
|
+
deleted = parsed_plist["deleted"]
|
69
|
+
|
70
|
+
root = SublimeSubmenu.new("__main_menu__", mainmenu)
|
71
|
+
all = {}
|
72
|
+
|
73
|
+
mainmenu["submenus"].each_pair do |k,v|
|
74
|
+
all[k] = SublimeSubmenu.new(v["name"], v)
|
75
|
+
end
|
76
|
+
|
77
|
+
excluded = (mainmenu["excludedItems"] || []) + SublimeSubmenu::excluded_items
|
78
|
+
closing = "\n '("
|
79
|
+
closing+= excluded.collect do |uuid|
|
80
|
+
"\"" + uuid + "\""
|
81
|
+
end.join( "\n ") + "))"
|
82
|
+
|
83
|
+
str = "(yas-define-menu "
|
84
|
+
return str + "'#{modename}" + root.to_lisp(all,
|
85
|
+
deleted,
|
86
|
+
str.length,
|
87
|
+
["'(" , closing])
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
class SkipSnippet < RuntimeError; end
|
92
|
+
|
93
|
+
class SublimeSnippet
|
94
|
+
|
95
|
+
@@known_substitutions = {
|
96
|
+
"content" => {
|
97
|
+
"${TM_RAILS_TEMPLATE_START_RUBY_EXPR}" => "<%= ",
|
98
|
+
"${TM_RAILS_TEMPLATE_END_RUBY_EXPR}" => " %>",
|
99
|
+
"${TM_RAILS_TEMPLATE_START_RUBY_INLINE}" => "<% ",
|
100
|
+
"${TM_RAILS_TEMPLATE_END_RUBY_INLINE}" => " -%>",
|
101
|
+
"${TM_RAILS_TEMPLATE_END_RUBY_BLOCK}" => "end" ,
|
102
|
+
"${0:$TM_SELECTED_TEXT}" => "${0:`yas-selected-text`}",
|
103
|
+
/\$\{(\d+)\}/ => "$\\1",
|
104
|
+
"${1:$TM_SELECTED_TEXT}" => "${1:`yas-selected-text`}",
|
105
|
+
"${2:$TM_SELECTED_TEXT}" => "${2:`yas-selected-text`}",
|
106
|
+
'$TM_SELECTED_TEXT' => "`yas-selected-text`",
|
107
|
+
%r'\$\{TM_SELECTED_TEXT:([^\}]*)\}' => "`(or (yas-selected-text) \"\\1\")`",
|
108
|
+
%r'`[^`]+\n[^`]`' => Proc.new {|uuid, match| "(yas-multi-line-unknown " + uuid + ")"}},
|
109
|
+
"condition" => {
|
110
|
+
/^source\..*$/ => "" },
|
111
|
+
"binding" => {},
|
112
|
+
"type" => {}
|
113
|
+
}
|
114
|
+
|
115
|
+
def self.extra_substitutions; @@extra_substitutions; end
|
116
|
+
@@extra_substitutions = {
|
117
|
+
"content" => {},
|
118
|
+
"condition" => {},
|
119
|
+
"binding" => {},
|
120
|
+
"type" => {}
|
121
|
+
}
|
122
|
+
|
123
|
+
def self.unknown_substitutions; @@unknown_substitutions; end
|
124
|
+
@@unknown_substitutions = {
|
125
|
+
"content" => {},
|
126
|
+
"condition" => {},
|
127
|
+
"binding" => {},
|
128
|
+
"type" => {}
|
129
|
+
}
|
130
|
+
|
131
|
+
@@snippets_by_uid={}
|
132
|
+
def self.snippets_by_uid; @@snippets_by_uid; end
|
133
|
+
|
134
|
+
def initialize(file)
|
135
|
+
@file = file
|
136
|
+
@snippet = SublimeSnippet::read_snippet(open(file))
|
137
|
+
@@snippets_by_uid[self.uuid] = self;
|
138
|
+
raise SkipSnippet.new "This is not a sublime-snippet, I just do sublime-snippets." unless (@snippet.xpath "//scope")
|
139
|
+
raise RuntimeError.new("Cannot convert this snippet #{file}!") unless @snippet;
|
140
|
+
end
|
141
|
+
|
142
|
+
def name
|
143
|
+
(@snippet.xpath "//description").text
|
144
|
+
end
|
145
|
+
|
146
|
+
def uuid
|
147
|
+
(@snippet.xpath "//uuid").text
|
148
|
+
end
|
149
|
+
|
150
|
+
def key
|
151
|
+
(@snippet.xpath "//tabTrigger").text
|
152
|
+
end
|
153
|
+
|
154
|
+
def condition
|
155
|
+
yas_directive "condition"
|
156
|
+
end
|
157
|
+
|
158
|
+
def type
|
159
|
+
override = yas_directive "type"
|
160
|
+
if override
|
161
|
+
return override
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
def binding
|
166
|
+
yas_directive "binding"
|
167
|
+
end
|
168
|
+
|
169
|
+
def content
|
170
|
+
known = @@known_substitutions["content"]
|
171
|
+
extra = @@extra_substitutions["content"]
|
172
|
+
if direct = extra[uuid]
|
173
|
+
return direct
|
174
|
+
else
|
175
|
+
ct = (@snippet.xpath "//content").text
|
176
|
+
if ct
|
177
|
+
known.each_pair do |k,v|
|
178
|
+
if v.respond_to? :call
|
179
|
+
ct.gsub!(k) {|match| v.call(uuid, match)}
|
180
|
+
else
|
181
|
+
ct.gsub!(k,v)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
extra.each_pair do |k,v|
|
185
|
+
ct.gsub!(k,v)
|
186
|
+
end
|
187
|
+
# the remaining stuff is an unknown substitution
|
188
|
+
#
|
189
|
+
[ %r'\$\{ [^/\}\{:]* / [^/]* / [^/]* / [^\}]*\}'x ,
|
190
|
+
%r'\$\{[^\d][^}]+\}',
|
191
|
+
%r'`[^`]+`',
|
192
|
+
%r'\$TM_[\w_]+',
|
193
|
+
%r'\(yas-multi-line-unknown [^\)]*\)'
|
194
|
+
].each do |reg|
|
195
|
+
ct.scan(reg) do |match|
|
196
|
+
@@unknown_substitutions["content"][match] = self
|
197
|
+
end
|
198
|
+
end
|
199
|
+
return ct
|
200
|
+
else
|
201
|
+
@@unknown_substitutions["content"][uuid] = self
|
202
|
+
SublimeSubmenu::excluded_items.push(uuid)
|
203
|
+
return "(yas-unimplemented)"
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
def to_yas opts
|
209
|
+
doc = "# -*- mode: snippet -*-\n"
|
210
|
+
doc << "# contributor: Translated to yasnippet by sublime-snippet import\n"
|
211
|
+
doc << (self.type || "")
|
212
|
+
# doc << "# uuid: #{self.uuid}\n" unless self.uuid.empty?
|
213
|
+
doc << "# key: #{self.key}\n" if self.key
|
214
|
+
doc << "# group: #{opts.snippet_group}\n" if opts.snippet_group
|
215
|
+
doc << "# name: #{self.name}\n"
|
216
|
+
doc << (self.binding || "")
|
217
|
+
doc << (self.condition || "")
|
218
|
+
doc << "# --\n"
|
219
|
+
doc << (self.content || "(yas-unimplemented)")
|
220
|
+
doc
|
221
|
+
end
|
222
|
+
|
223
|
+
def self.canonicalize(filename)
|
224
|
+
invalid_char = /[^ a-z_0-9.+=~(){}\/'`&#,-]/i
|
225
|
+
|
226
|
+
filename.
|
227
|
+
gsub(invalid_char, ''). # remove invalid characters
|
228
|
+
gsub(/ {2,}/,' '). # squeeze repeated spaces into a single one
|
229
|
+
rstrip # remove trailing whitespaces
|
230
|
+
end
|
231
|
+
|
232
|
+
def yas_file()
|
233
|
+
File.join(SublimeSnippet::canonicalize(@file[0, @file.length-File.extname(@file).length]) + ".yasnippet")
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.read_snippet(xml)
|
237
|
+
begin
|
238
|
+
parsed = Nokogiri::XML(xml)
|
239
|
+
return parsed if parsed
|
240
|
+
raise ArgumentError.new "Format not recognised as sublime-snippet..."
|
241
|
+
rescue StandardError => e
|
242
|
+
raise RuntimeError.new "Failed to read sublime-snippet - Nokogiri gem is required, make sure it's installed"
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
private
|
247
|
+
|
248
|
+
@@yas_to_tm_directives = {"condition" => "scope", "binding" => "keyEquivalent", "key" => "tabTrigger"}
|
249
|
+
def yas_directive(yas_directive)
|
250
|
+
#
|
251
|
+
# Merge "known" hardcoded substitution with "extra" substitutions
|
252
|
+
# provided in the .yas-setup.el file.
|
253
|
+
#
|
254
|
+
merged = @@known_substitutions[yas_directive].
|
255
|
+
merge(@@extra_substitutions[yas_directive])
|
256
|
+
#
|
257
|
+
# First look for an uuid-based direct substitution for this
|
258
|
+
# directive.
|
259
|
+
#
|
260
|
+
if direct = merged[uuid]
|
261
|
+
return "# #{yas_directive}: "+ direct + "\n" unless direct.empty?
|
262
|
+
else
|
263
|
+
tm_directive = @@yas_to_tm_directives[yas_directive]
|
264
|
+
val = tm_directive && @snippet[tm_directive]
|
265
|
+
if val and !val.delete(" ").empty? then
|
266
|
+
#
|
267
|
+
# Sort merged substitutions by length (bigger ones first,
|
268
|
+
# regexps last), and apply them to the value gotten for plist.
|
269
|
+
#
|
270
|
+
allsubs = merged.sort_by do |what, with|
|
271
|
+
if what.respond_to? :length then -what.length else 0 end
|
272
|
+
end
|
273
|
+
allsubs.each do |sub|
|
274
|
+
if val.gsub!(sub[0],sub[1])
|
275
|
+
return "# #{yas_directive}: "+ val + "\n" unless val.empty?
|
276
|
+
end
|
277
|
+
end
|
278
|
+
#
|
279
|
+
# If we get here, no substitution matched, so mark this an
|
280
|
+
# unknown substitution.
|
281
|
+
#
|
282
|
+
@@unknown_substitutions[yas_directive][val] = self
|
283
|
+
return "## #{yas_directive}: \""+ val + "\n"
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
|
290
|
+
end
|
data/sublime2yas.gemspec
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'sublime2yas/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "sublime2yas"
|
8
|
+
spec.version = Sublime2yas::VERSION
|
9
|
+
spec.authors = ["Jasonm23"]
|
10
|
+
spec.email = ["jasonm23@gmail.com"]
|
11
|
+
spec.description = %q{SublimeTextSnippets to YaSnippet}
|
12
|
+
spec.summary = %q{SublimeText Snippet to YaSnippet/Emacs conversion}
|
13
|
+
spec.homepage = %q{https://github.com/jasonm23/sublime2yas}
|
14
|
+
spec.license = %q{MIT}
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_runtime_dependency "nokogiri"
|
24
|
+
spec.add_runtime_dependency "trollop"
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: sublime2yas
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jasonm23
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-08-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: nokogiri
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: trollop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: SublimeTextSnippets to YaSnippet
|
70
|
+
email:
|
71
|
+
- jasonm23@gmail.com
|
72
|
+
executables:
|
73
|
+
- sublime2yas
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- bin/sublime2yas
|
83
|
+
- lib/sublime2yas.rb
|
84
|
+
- lib/sublime2yas/version.rb
|
85
|
+
- sublime2yas.gemspec
|
86
|
+
homepage: https://github.com/jasonm23/sublime2yas
|
87
|
+
licenses:
|
88
|
+
- MIT
|
89
|
+
metadata: {}
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
requirements:
|
96
|
+
- - ! '>='
|
97
|
+
- !ruby/object:Gem::Version
|
98
|
+
version: '0'
|
99
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ! '>='
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
requirements: []
|
105
|
+
rubyforge_project:
|
106
|
+
rubygems_version: 2.0.7
|
107
|
+
signing_key:
|
108
|
+
specification_version: 4
|
109
|
+
summary: SublimeText Snippet to YaSnippet/Emacs conversion
|
110
|
+
test_files: []
|