2011-07-13 08:07:44 -04:00
#!/usr/bin/env python
# encoding: utf-8
"""
2011-07-17 06:17:23 -04:00
Convert snipmate compatible snippets to UltiSnips compatible snippets
by Phillip Berndt
2011-07-13 08:07:44 -04:00
"""
import sys
import re
import os
2011-07-14 06:24:14 -04:00
import argparse
2011-07-13 08:07:44 -04:00
def convert_snippet_contents ( content ) :
2011-07-17 06:17:23 -04:00
" If the snippet contains snipmate style substitutions, convert them to ultisnips style "
content = re . sub ( " `([^`]+`) " , " `!v \ g<1> " , content )
return content
2011-07-13 08:07:44 -04:00
def convert_snippet_file ( source ) :
2011-07-17 06:17:23 -04:00
" One file per filetype "
retval = " "
state = 0
for line in open ( source ) . readlines ( ) :
# Ignore empty lines
if line . strip ( ) == " " :
continue
2012-11-24 04:32:00 -05:00
# The rest of the handling is stateful
2011-07-17 06:17:23 -04:00
if state == 0 :
2012-11-24 04:32:00 -05:00
# Find snippet start. Keep comments.
2011-07-17 06:17:23 -04:00
if line [ : 8 ] == " snippet " :
snippet_info = re . match ( " ( \ S+) \ s*(.*) " , line [ 8 : ] )
if not snippet_info :
print >> sys . stderr , " Warning: Malformed snippet \n %s \n " % line
continue
retval + = ' snippet %s " %s " ' % ( snippet_info . group ( 1 ) , snippet_info . group ( 2 ) if snippet_info . group ( 2 ) else snippet_info . group ( 1 ) ) + " \n "
state = 1
snippet = " "
2012-11-24 04:32:00 -05:00
elif line [ : 1 ] == " # " :
retval + = line
state = 0
2011-07-17 06:17:23 -04:00
elif state == 1 :
# First line of snippet: Get indentation
whitespace = re . search ( " ^ \ s+ " , line )
if not whitespace :
print >> sys . stderr , " Warning: Malformed snippet, content not indented. \n "
retval + = " endsnippet \n \n "
state = 0
else :
whitespace = whitespace . group ( 0 )
snippet + = line [ len ( whitespace ) : ]
state = 2
elif state == 2 :
2012-11-24 04:32:00 -05:00
# In snippet: If indentation level is the same, add to snippet. Else end snippet.
if line [ : len ( whitespace ) ] == whitespace :
snippet + = line [ len ( whitespace ) : ]
else :
2011-07-17 06:17:23 -04:00
retval + = convert_snippet_contents ( snippet ) + " endsnippet \n \n "
2012-11-24 04:32:00 -05:00
#Copy-paste the section from state=0 so that we don't skip every other snippet
2012-02-05 12:40:58 -05:00
if line [ : 8 ] == " snippet " :
snippet_info = re . match ( " ( \ S+) \ s*(.*) " , line [ 8 : ] )
if not snippet_info :
print >> sys . stderr , " Warning: Malformed snippet \n %s \n " % line
continue
retval + = ' snippet %s " %s " ' % ( snippet_info . group ( 1 ) , snippet_info . group ( 2 ) if snippet_info . group ( 2 ) else snippet_info . group ( 1 ) ) + " \n "
state = 1
snippet = " "
2012-11-24 04:32:00 -05:00
elif line [ : 1 ] == " # " :
retval + = line
state = 0
2011-07-17 06:17:23 -04:00
if state == 2 :
retval + = convert_snippet_contents ( snippet ) + " endsnippet \n \n "
return retval
2011-07-13 08:07:44 -04:00
def convert_snippet ( source ) :
2011-07-17 06:17:23 -04:00
" One file per snippet "
name = os . path . basename ( source ) [ : - 8 ]
return ' snippet %s " %s " ' % ( name , name ) + " \n " + \
convert_snippet_contents ( open ( source ) . read ( ) ) + \
" \n endsnippet \n "
2011-07-13 08:07:44 -04:00
def convert_snippets ( source ) :
2011-07-17 06:17:23 -04:00
if os . path . isdir ( source ) :
return " \n " . join ( ( convert_snippet ( os . path . join ( source , x ) ) for x in os . listdir ( source ) if x [ - 8 : ] == " .snippet " ) )
else :
return convert_snippet_file ( source )
2011-07-13 08:07:44 -04:00
if __name__ == ' __main__ ' :
2011-07-17 06:17:23 -04:00
# Parse command line
argsp = argparse . ArgumentParser ( description = " Convert snipmate compatible snippets to UltiSnips ' file format " ,
epilog = " example: \n %s drupal/ drupal.snippets \n will convert all drupal specific snippets from snipmate into one file drupal.snippets " % sys . argv [ 0 ] ,
formatter_class = argparse . RawDescriptionHelpFormatter )
argsp . add_argument ( " source " , help = " Source directory for one filetype or a snippets file " )
argsp . add_argument ( " target " , help = " File to write the resulting snippets into. If omitted, the snippets will be written to stdout. " , nargs = " ? " , default = " - " )
args = argsp . parse_args ( )
2011-07-14 06:24:14 -04:00
2012-11-24 04:32:00 -05:00
source_file_name = args . source
tmp_file_name = ' ' . join ( [ args . target , ' .tmp ' ] )
2011-07-17 06:17:23 -04:00
try :
2012-11-24 04:32:00 -05:00
tmp = sys . stdout if args . target == " - " else open ( tmp_file_name , " w " )
2011-07-17 06:17:23 -04:00
except IOError :
2012-11-24 04:32:00 -05:00
print >> sys . stderr , " Error: Failed to open output file %s for writing " % tmp_file_name
2011-07-17 06:17:23 -04:00
sys . exit ( 1 )
2011-07-13 08:07:44 -04:00
2012-11-24 04:32:00 -05:00
snippets = convert_snippets ( source_file_name )
print >> tmp , snippets
if args . target != " - " :
if os . access ( args . target , os . F_OK ) :
os . remove ( args . target )
os . rename ( tmp_file_name , args . target )