-
Notifications
You must be signed in to change notification settings - Fork 14
/
Generate Assets.sketchplugin
159 lines (129 loc) · 5.24 KB
/
Generate Assets.sketchplugin
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// (ctrl cmd alt g)
// This command is a recreation of the Photoshop Generator functionality,
// introduced by Adobe on Photoshop CC <http://blogs.adobe.com/photoshopdotcom/2013/09/introducing-adobe-generator-for-photoshop-cc.html>
var generator = {
version: "0.1",
regexp: /\.png\d*\s*|\.jpg\d*\s*|\.gif\s*|\.svg\s*|\.eps\s*|\.pdf\s*|\.tif\s*|\d+%+|\d+\s*x\s*\d+/g
}
var document_path = [[doc fileURL] path].split([doc displayName])[0],
document_name = [doc displayName].replace(".sketch",""),
assets_folder = document_path + "/" + document_name + "-assets",
file_manager = [NSFileManager defaultManager],
current_page_name,
current_artboard_name;
Array.prototype.each = function(callback){
var count = 0;
for (var i = 0; i < this.length(); i++){
var el = this[i];
callback.call(this,el,count);
count++;
}
}
function process_layer(layer) {
log('Processing layer "' + [layer name] + '"');
if(should_export(layer)) {
// log("We should export it...");
var layer_metadata = get_data_from_layer(layer);
for(var i=0; i < layer_metadata.length; i++) {
export_layer(layer, layer_metadata[i]);
}
};
// Process sublayers
if (is_group(layer)) {
// log("Also, it's a group");
var sublayers = [layer layers];
sublayers.each(function(sublayer){
process_layer(sublayer);
});
}
}
function should_export(layer) {
log("should_export(" + [layer name] + ")")
return [layer name].match(generator.regexp);
}
function get_data_from_layer(layer) {
log('Getting data from ' + layer);
var name = [layer name],
assets = name.split(","),
assets_data = [];
for (var i = 0; i < assets.length; i++) {
var current_asset = assets[i],
filename = current_asset.replace(generator.regexp,'').replace(' ','')
var asset_metadata = {
name: sanitize_filename(filename),
filetype: current_asset.split(".")[1].substr(0,3),
// TODO: Add support for '@2x' and 'HDPI' style scales
scale: current_asset.match(/(\d+)%/) ? current_asset.match(/(\d+)%/)[1]/100.0 : 1.0
}
assets_data.push(asset_metadata);
// log('Asset scale: ' + asset_metadata.scale);
}
return assets_data;
}
function sanitize_filename(name){
return name.replace(/(\s+|\:|\/)/g ,"_").replace(/__/g,"_");
}
function export_layer(layer, options) {
log("Exporting " + options.name + ", with scale: " + options.scale);
// var filename = assets_folder + "/" + sanitize_filename(options.name);
var filename = assets_folder + "/" + sanitize_filename(current_page_name) + "/" + sanitize_filename(current_artboard_name) + "/" + sanitize_filename(options.name);
// copy off-screen
var copy = [layer duplicate];
var frame = [copy frame];
[frame setX:-100000];
[frame setY:-100000];
// export
var rect = [copy rectByAccountingForStyleSize:[[copy absoluteRect] rect]],
slice = [MSSlice sliceWithRect:rect scale:options.scale];
// Maybe: add scale in filename
// filename += "-" + options.scale + "x";
[doc saveArtboardOrSlice:slice toFile:(filename + "." + options.filetype)];
// remove it
// log("Removing copy");
[copy removeFromParent];
}
function is_group(layer) {
return [layer isMemberOfClass:[MSLayerGroup class]];
}
function main(){
log('##########################################################################################')
log('Sketch Generator running')
// Traverse pages...
[doc pages].each(function(page){
[doc setCurrentPage:page];
current_page_name = [[doc currentPage] name];
log("#####################################################################################")
log("Traversing page: " + current_page_name);
log("#####################################################################################")
[file_manager createDirectoryAtPath:(assets_folder + "/" + sanitize_filename(current_page_name)) withIntermediateDirectories:true attributes:nil error:nil];
// ...then artboards...
var artboards = [[doc currentPage] artboards];
if([artboards length] >= 1) {
artboards.each(function(artboard){
current_artboard_name = [artboard name];
log("Traversing artboard " + current_artboard_name);
[file_manager createDirectoryAtPath:(assets_folder + "/" + sanitize_filename(current_page_name) + "/" + sanitize_filename(current_artboard_name)) withIntermediateDirectories:true attributes:nil error:nil];
// TODO: support artboards named artboard.png
// if(should_export(artboard)) {
// log("Will try to export artboard " + [artboard name]);
// export_layer(artboard, get_data_from_layer(artboard));
// }
// var all_layers = [[doc currentPage] layers];
var all_layers = [artboard layers];
all_layers.each(function(layer){
process_layer(layer);
});
});
} else {
log("No artboards in document...");
current_artboard_name = 'no_artboard';
[file_manager createDirectoryAtPath:(assets_folder + "/" + sanitize_filename(current_page_name) + "/" + sanitize_filename(current_artboard_name)) withIntermediateDirectories:true attributes:nil error:nil];
var all_layers = [[doc currentPage] layers];
all_layers.each(function(layer){
process_layer(layer);
});
}
});
}
// Let's go!
main();