Sublime Forum

Converting tmLanguage plists to JSON?

#1

I want to edit the SQL.tmLanguage bundle from TextMate. It’s available here as an XML plist:

github.com/jbrooksuk/SublimeTex … tmLanguage

but it’s a PITA to edit an XML plist in Sublime, and Property List Editor is no walk in the park either. I’d much rather edit them as JSON in Sublime, and use AAAPackageDev.

Is there a way to convert from the plist into a JSON style that AAAPackageDev can read?

0 Likes

#2

I’ve been meaning to add that to AAAPAckageDev, but I never got around to doing it. I think Python provides a plist module too, so I suppose it’d be a matter of reading the plist and saving to .JSON-tmLanguage.

0 Likes

#3

$20 Paypal bounty? :smile:

0 Likes

#4

Did the google fail you?

google.com/search?q=plist+to+JSON+converter

0 Likes

#5

LOL. First, that was too nice; I totally deserved this:

lmgtfy.com/?q=plist+to+json+converter

Second, I did actually try this one first:

github.com/codeboxed/Plist-to-JSON

but the resulting JSON had some syntax error that wasn’t obvious to me but was obvious to the syntax highlighter (most of the file was bright red inverted), and I gave up for the moment. I’ll try some of the others though.

0 Likes

#6

I build this one some time ago, for the same reason. To manage my PL/SQL colouring.

# pl2tml

import sys
import shlex
import re

PLISTHEADER = """\
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
"""
indentsize = 2
current_indent = indentsize

def incr_indent():
  global current_indent
  current_indent += indentsize

def decr_indent():
  global current_indent
  current_indent -= indentsize

def indent():
  global current_indent
  return current_indent*' '

def writeln (text):
  print '%s%s' % (indent(), text)

key_mode = True
quote = re.compile ('&quot', re.IGNORECASE)

def handle_token (token):
  global key_mode
  if token == '{':
    writeln ('<dict>')
    incr_indent()
    key_mode = True
  elif token == '}':
    decr_indent()
    writeln ('</dict>')
  elif token == '(':
    writeln ('<array>')
    incr_indent()
    key_mode = False
  elif token == ')':
    decr_indent()
    writeln ('</array>')
  elif token == ';':
    key_mode = True
  elif token == ',':
    pass
  elif token == '=':
    key_mode = False
  else:
    if key_mode:
      writeln ('<key>%s</key>' % token)
    else:
      not_string_token = quote.sub ("'", token [1:-1])
      writeln ('<string>%s</string>' % not_string_token)

def pretty_print (lexer):
  count = 0
  lexer.commenters = '//'
  while True :
    token = lexer.get_token()
    if token == '': return
    count += 1
    handle_token (token)

def main ():
  for filename in sys.argv [1:]:
    print PLISTHEADER
    print '<plist version=\"1.0\">'
    pretty_print (shlex.shlex (open (filename)))
    print '</plist>'

if __name__ == "__main__":
  main ()

and the opposite

[code]#! python

-- coding: utf-8 --

“”" print file to XML Apple plist files in old style plist format “”"
“”"
used keywrds:
name
match
begin, end
(contentName)
captures, (beginCaptures, endCaptures)
include
patterns
repository
“”"
import sys
import plistlib as pl

current_indent = 0
indentsize = 2

def incr_indent():
global current_indent
current_indent += indentsize

def decr_indent():
global current_indent
current_indent -= indentsize

def indent():
global current_indent
return current_indent*’ ’

def print_value (tmLang, key, align=8):
value = tmLang.get (key)
if value : print “%s%s = ‘%s’;” % (indent(), key.ljust(align), value)

def print_array (tmLang, key, align=8):
value = tmLang.get (key)
if value : print “%s%s = %s;” % (indent(), key.ljust(align), tuple(value))

def print_patterns (tmLang):
print “%spatterns = (” % indent()
incr_indent()
array = tmLang.get (‘patterns’)
for dictionary in array:
print_dictionary (tmLang, dictionary)
decr_indent()
print “%s);” % indent()

def print_captured (tmLang, key, align=2):
value = tmLang.get (key)
if value :
name = value.get (‘name’)
print “%s%s = { name = ‘%s’;};” % (indent(), key.ljust(align), name)

def print_captures (tmLang):
print “%scaptures = {” % indent()
incr_indent()
for key in tmLang.iterkeys():
print_captured (tmLang, key)
decr_indent()
print “%s};” % indent()

def print_rule (tmLang):
print_value (tmLang, ‘name’)
print_value (tmLang, ‘include’)
print_value (tmLang, ‘begin’)
print_value (tmLang, ‘end’)
print_value (tmLang, ‘match’)
if tmLang.get (‘captures’):
print_captures (tmLang.get (‘captures’))
if tmLang.get (‘patterns’):
print_patterns (tmLang)

def print_dictionary (tmLang, dictionary, name=None):
if name :
print “%s%s = {” % (indent(), name)
else:
print “%s{” % indent()

incr_indent()
print_rule (dictionary)
decr_indent()

if name:
print “%s};” % indent()
else:
print “%s},” % indent()

def print_repository (tmLang):
print “%srepository = {” % indent()
incr_indent()
repository = tmLang.get (‘repository’)
for (name, dictionary) in repository.iteritems():
print_dictionary (tmLang, dictionary, name)
decr_indent()
print “%s};” % indent()

def pretty_print (tmLang):
“”“oberste Ebene der tmLanguage”""
print ‘{’
incr_indent()

print_value (tmLang, ‘name’, 18)
print_value (tmLang, ‘comment’, 18)
print_value (tmLang, ‘uuid’, 18)
print_value (tmLang, ‘scopeName’, 18)
print_array (tmLang, ‘fileTypes’, 18)
print_value (tmLang, ‘firstLineMatch’, 18)
print_value (tmLang, ‘foldingStartMarker’, 18)
print_value (tmLang, ‘foldingStopMarker’, 18)
print
print_patterns (tmLang)
print
print_repository (tmLang)
decr_indent()
print ‘}’

def main ():
for filename in sys.argv [1:]:
pretty_print (pl.readPlist (filename))

if name == “main”:
main ()[/code]

0 Likes

#7

I’ve just added this to AAAPackageDev. You should see a command in the Command Palette when the active file has a .tmLanguage extension.

github.com/SublimeText/AAAPackageDev

0 Likes

#8

My hero! I was serious about the $20 - PM me your email or your favorite charity :smile:

0 Likes

#9

try this one

http://json2plist.sinaapp.com/

or this one

0 Likes