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[1]
 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[1]
 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)