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 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 import os import zipfile import tempfile import sys import json zipname = sys.argv def format_symbol_name(name): return name.lower() def update_file(zipname): # generate a temp file tmpfd, tmpname = tempfile.mkstemp(dir=os.path.dirname(zipname)) os.close(tmpfd) # read the sketch file as a zip file with zipfile.ZipFile(zipname, 'r') as zin: with zipfile.ZipFile(tmpname, 'w') as zout: zout.comment = zin.comment # preserve the comment # track how many layer names were changed updated = 0 for item in zin.infolist(): data = zin.read(item.filename) # find pages and update symbol names if item.filename.startswith('pages') and item.filename.endswith('.json'): parsed_json = json.loads(data) for layer in parsed_json['layers']: # only modify symbol masters if layer['_class'] == 'symbolMaster': before_name = layer['name'] formatted_name = format_symbol_name(layer['name']) layer['name'] = formatted_name if before_name != formatted_name: updated += 1 data = json.dumps(parsed_json) #write back to temp archive zout.writestr(item, data) print '%d symbol names updated.' % updated # replace with the temp archive os.remove(zipname) os.rename(tmpname, zipname) update_file(zipname)
symbol-names.py GitHub Gist
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 import os import zipfile import tempfile import sys import json sketch_doc = sys.argv def get_symbol_names(zipname): symbol_names =  # read the sketch file as a zip file with zipfile.ZipFile(zipname, 'r') as sketch_file: for item in sketch_file.infolist(): data = sketch_file.read(item.filename) # find pages and collect symbol names if item.filename.startswith('pages') and item.filename.endswith('.json'): parsed_json = json.loads(data) for layer in parsed_json['layers']: # only collect names of symbol masters if layer['_class'] == 'symbolMaster': symbol_names.append(layer['name']) sketch_file.close() sorted_symbol_names = sorted(symbol_names) # make new file for symbol names out_name = '%s-symbol-names.txt' % sketch_doc out = open(out_name, 'w+') for item in sorted_symbol_names: line = '%s\r\n' % item out.write(line) out.close() print 'Found %d symbols in the document.' % len(symbol_names) get_symbol_names(sketch_doc)