Since Sketch version 43, Sketch files are really just ZIP archives containing primarily JSON files that describe the pages, symbols, and layers in a Sketch document. This allows for doing some pretty cool things. For example, here are two scripts I created and used recently. While working on a large Sketch library file with multiple people, we finally settled on a naming convention for our symbol names. One aspect of it was that we wanted the names to be entirely lowercase. Unfortunately many of the symbols were already created and they were not all lowercase. This meant I was going to have to go through and manually fix each symbol name (and try not to introduce new typos!). Instead, after a little reading of online Python resources, I put together this script that opens the Sketch file, finds every symbol master layer in the document, and makes sure its name is all lowercase. At this point it could be modified for any sort of formatting, but this is all we needed this time.
The second script is based on the first and is a little simpler. It dumps all the symbol names in the document into a text file to make auditing the names easier. Instead of scrolling through Sketch, we have an alphabetically sorted list of the symbol names. Here are both the scripts:
format.py GitHub Gist
1 import os 2 import zipfile 3 import tempfile 4 import sys 5 import json 6 7 zipname = sys.argv 8 def format_symbol_name(name): 9 return name.lower() 10 11 def update_file(zipname): 12 # generate a temp file 13 tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname)) 14 os.close(tmpfd) 15 16 # read the sketch file as a zip file 17 with zipfile.ZipFile(zipname, 'r') as zin: 18 with zipfile.ZipFile(tmpname, 'w') as zout: 19 zout.comment = zin.comment # preserve the comment 20 21 # track how many layer names were changed 22 updated = 0 23 24 for item in zin.infolist(): 25 data = zin.read(item.filename) 26 27 # find pages and update symbol names 28 if item.filename.startswith('pages') and item.filename.endswith('.json'): 29 parsed_json = json.loads(data) 30 for layer in parsed_json['layers']: 31 32 # only modify symbol masters 33 if layer['_class'] == 'symbolMaster': 34 before_name = layer['name'] 35 formatted_name = format_symbol_name(layer['name']) 36 layer['name'] = formatted_name 37 38 if before_name != formatted_name: updated += 1 39 data = json.dumps(parsed_json) 40 41 #write back to temp archive 42 zout.writestr(item, data) 43 print '%d symbol names updated.' % updated 44 # replace with the temp archive 45 os.remove(zipname) 46 os.rename(tmpname, zipname) 47 48 update_file(zipname)
symbol-names.py GitHub Gist
1 import os 2 import zipfile 3 import tempfile 4 import sys 5 import json 6 7 sketch_doc = sys.argv 8 9 def get_symbol_names(zipname): 10 symbol_names =  11 12 # read the sketch file as a zip file 13 with zipfile.ZipFile(zipname, 'r') as sketch_file: 14 for item in sketch_file.infolist(): 15 data = sketch_file.read(item.filename) 16 17 # find pages and collect symbol names 18 if item.filename.startswith('pages') and item.filename.endswith('.json'): 19 parsed_json = json.loads(data) 20 for layer in parsed_json['layers']: 21 22 # only collect names of symbol masters 23 if layer['_class'] == 'symbolMaster': 24 symbol_names.append(layer['name']) 25 sketch_file.close() 26 27 sorted_symbol_names = sorted(symbol_names) 28 29 # make new file for symbol names 30 out_name = '%s-symbol-names.txt' % sketch_doc 31 out = open(out_name, 'w+') 32 33 for item in sorted_symbol_names: 34 line = '%s\r\n' % item 35 out.write(line) 36 37 out.close() 38 print 'Found %d symbols in the document.' % len(symbol_names) 39 40 get_symbol_names(sketch_doc)