PythonでSublimeTextのスニペットをAtom仕様に変換してみた
やること
SublimeTextで使用していたPythonの自作スニペットをAtom仕様に変換する
動機
最近Atomを使い始めたのだが、SublimeTextのスニペットを1つずつコピペするのが面倒なので自動化を試みた
SublimeTextとAtomのスニペットの違い
SublimeText
- 1ファイルに1スニペット
-
![CDATA[]]
内の文字列は、raw文字列として扱われる
sublime_sample1.sublime-snippet
<snippet>
<content><![CDATA[
print('hello world')
]]></content>
<description>hello world</description>
<tabTrigger>hello</tabTrigger>
<scope>source.python</scope>
</snippet>
sublime_sample2.sublime-snippet
<snippet>
<content><![CDATA[
a = 'foo'
b = a.replace(${1:'foo'}, $2)
c = '\n'
]]></content>
<description>sample</description>
<tabTrigger>test</tabTrigger>
<scope>source.python</scope>
</snippet>
Atom
- 1ファイル(
snippets.cson
)に全スニペットをまとめる
-
body
はraw文字列として扱われない(例えば\n
は改行として扱われる)
-
body
が複数行に渡る場合には、'''
(あるいは"""
)で閉じる必要がある
- 特殊文字(例えば
'\n'
)を、'\\\\n'
のように表記しなければならない(参考)
snippets.cson
'.source.python':
'hello world':
'prefix': 'hello'
'body': "print('hello world')"
'sample':
'prefix': 'test'
'body': '''
a = 'foo'
b = a.replace(${1:'foo'}, $2)
c = '\\\\n'
'''
コード
-
glob
でSublimeTextのスニペットファイルを取得
- 正規表現を使用し、必要な情報を抽出
-
content
以外(tabTrigger
とdescription
)はそのまま使用
-
content
は特殊文字を置換した後、複数行に渡るか、'
や"
を含むかチェックしAtom仕様に加工
- 各情報をAtomのスニペットフォーマットに代入し、
snippets.cson
に書き込み
sblm2atom.py
import os
import glob
import re
def convert_body(body):
# 特殊文字の置換(この他にも色々ありますが、、、)
sc1 = [r'\n', r'\t', r'\'', r'\"']
sc2 = [r'\\\\n', r'\\\\t', r"\\\\'", r'\\\\"']
for x, y in zip(sc1, sc2):
body = body.replace(x, y)
# bodyが複数行の場合
if len(body.split('\n')) > 1:
# 各行にTabを追加
body = '\n'.join(['\t\t\t' + x for x in body.split('\n')])
body = "'''\n{}\n\t\t'''".format(body)
# bodyが1行の場合
else:
if '\'' in body and '\"' in body:
body = "'''\n{}\n\t\t'''".format('\t\t\t' + body)
elif '\'' in body:
body = '\"{}\"'.format(body)
else:
body = '\'{}\''.format(body)
return body
def main():
sblm_snippets = glob.glob('*.sublime-snippet')
fname_out = 'python_snippets.cson'
with open(fname_out, 'w', encoding='utf-8') as f:
f.write("'.source.python':" + '\n')
# 情報を抽出するために必要な正規表現
body_pattern = r'<!\[CDATA\[(.*)\]\]></content>'
prefix_pattern = r'<tabTrigger>(.*)</tabTrigger>'
desc_pattern = r'<description>(.*)</description>'
atom_snippet_fmt = '''
'{}':
'prefix': '{}'
'body': {}
'''
for sblm_snippet in sblm_snippets:
# snippetの読み込み
with open(sblm_snippet, 'r', encoding='utf-8') as f:
src = f.read()
# 正規表現で必要な情報を抽出
body = re.findall(body_pattern, src, flags=re.DOTALL)[0].strip()
body = convert_body(body)
prefix = re.findall(prefix_pattern, src, flags=re.DOTALL)[0]
desc = re.findall(desc_pattern, src, flags=re.DOTALL)
desc = desc[0] if desc else 'no description'
print(desc)
print(prefix)
print(body)
print()
# Atom snippet formatに抽出した情報を挿入
atom_snippet = atom_snippet_fmt.format(desc, prefix, body).strip('\n')
# ファイルに書き込み
with open(fname_out, 'a', encoding='utf-8') as f:
f.write(atom_snippet + '\n')
if __name__ == '__main__':
main()
テスト
![CDATA[]]
内の文字列は、raw文字列として扱われるsublime_sample1.sublime-snippet
<snippet>
<content><![CDATA[
print('hello world')
]]></content>
<description>hello world</description>
<tabTrigger>hello</tabTrigger>
<scope>source.python</scope>
</snippet>
sublime_sample2.sublime-snippet
<snippet>
<content><![CDATA[
a = 'foo'
b = a.replace(${1:'foo'}, $2)
c = '\n'
]]></content>
<description>sample</description>
<tabTrigger>test</tabTrigger>
<scope>source.python</scope>
</snippet>
snippets.cson
)に全スニペットをまとめるbody
はraw文字列として扱われない(例えば\n
は改行として扱われる)body
が複数行に渡る場合には、'''
(あるいは"""
)で閉じる必要がある'\n'
)を、'\\\\n'
のように表記しなければならない(参考)snippets.cson
'.source.python':
'hello world':
'prefix': 'hello'
'body': "print('hello world')"
'sample':
'prefix': 'test'
'body': '''
a = 'foo'
b = a.replace(${1:'foo'}, $2)
c = '\\\\n'
'''
-
glob
でSublimeTextのスニペットファイルを取得 - 正規表現を使用し、必要な情報を抽出
-
content
以外(tabTrigger
とdescription
)はそのまま使用 -
content
は特殊文字を置換した後、複数行に渡るか、'
や"
を含むかチェックしAtom仕様に加工 - 各情報をAtomのスニペットフォーマットに代入し、
snippets.cson
に書き込み
sblm2atom.py
import os
import glob
import re
def convert_body(body):
# 特殊文字の置換(この他にも色々ありますが、、、)
sc1 = [r'\n', r'\t', r'\'', r'\"']
sc2 = [r'\\\\n', r'\\\\t', r"\\\\'", r'\\\\"']
for x, y in zip(sc1, sc2):
body = body.replace(x, y)
# bodyが複数行の場合
if len(body.split('\n')) > 1:
# 各行にTabを追加
body = '\n'.join(['\t\t\t' + x for x in body.split('\n')])
body = "'''\n{}\n\t\t'''".format(body)
# bodyが1行の場合
else:
if '\'' in body and '\"' in body:
body = "'''\n{}\n\t\t'''".format('\t\t\t' + body)
elif '\'' in body:
body = '\"{}\"'.format(body)
else:
body = '\'{}\''.format(body)
return body
def main():
sblm_snippets = glob.glob('*.sublime-snippet')
fname_out = 'python_snippets.cson'
with open(fname_out, 'w', encoding='utf-8') as f:
f.write("'.source.python':" + '\n')
# 情報を抽出するために必要な正規表現
body_pattern = r'<!\[CDATA\[(.*)\]\]></content>'
prefix_pattern = r'<tabTrigger>(.*)</tabTrigger>'
desc_pattern = r'<description>(.*)</description>'
atom_snippet_fmt = '''
'{}':
'prefix': '{}'
'body': {}
'''
for sblm_snippet in sblm_snippets:
# snippetの読み込み
with open(sblm_snippet, 'r', encoding='utf-8') as f:
src = f.read()
# 正規表現で必要な情報を抽出
body = re.findall(body_pattern, src, flags=re.DOTALL)[0].strip()
body = convert_body(body)
prefix = re.findall(prefix_pattern, src, flags=re.DOTALL)[0]
desc = re.findall(desc_pattern, src, flags=re.DOTALL)
desc = desc[0] if desc else 'no description'
print(desc)
print(prefix)
print(body)
print()
# Atom snippet formatに抽出した情報を挿入
atom_snippet = atom_snippet_fmt.format(desc, prefix, body).strip('\n')
# ファイルに書き込み
with open(fname_out, 'a', encoding='utf-8') as f:
f.write(atom_snippet + '\n')
if __name__ == '__main__':
main()
テスト
試しに上述のsublime_sample1.sublime-snippet
とsublime_sample2.sublime-snippet
を変換してみた⇩
snippets.cson
'.source.python':
'hello world':
'prefix': 'hello'
'body': "print('hello world')"
'sample':
'prefix': 'test'
'body': '''
a = 'foo'
b = a.replace(${1:'foo'}, $2)
c = '\\\\n'
'''
正しく変換されていることが確認できた
Author And Source
この問題について(PythonでSublimeTextのスニペットをAtom仕様に変換してみた), 我々は、より多くの情報をここで見つけました https://qiita.com/harupy/items/ca4b182a41905e120a02著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .