├── LICENSE ├── LayerRenamer.sketchplugin └── Contents │ ├── Resources │ └── icons │ │ ├── copyPageOutlineToClipboard.png │ │ ├── layerRenamerRename.png │ │ └── layerRenamerSelect.png │ └── Sketch │ ├── helpers.cocoascript │ ├── layerRenamer.sketchscript │ └── manifest.json ├── appcast.xml ├── demos ├── copy outline pug beta.gif ├── rename group using inner layer name.gif ├── rename using children.gif ├── screenshot color.png ├── screenshot.png └── transform cases.gif ├── readme.md └── view plugin log /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Leonard Pauli 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LayerRenamer.sketchplugin/Contents/Resources/icons/copyPageOutlineToClipboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leonardpauli/layer-renamer/f1ba7edded29a27e1db59a1da733eb18fbdfe6f6/LayerRenamer.sketchplugin/Contents/Resources/icons/copyPageOutlineToClipboard.png -------------------------------------------------------------------------------- /LayerRenamer.sketchplugin/Contents/Resources/icons/layerRenamerRename.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leonardpauli/layer-renamer/f1ba7edded29a27e1db59a1da733eb18fbdfe6f6/LayerRenamer.sketchplugin/Contents/Resources/icons/layerRenamerRename.png -------------------------------------------------------------------------------- /LayerRenamer.sketchplugin/Contents/Resources/icons/layerRenamerSelect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/leonardpauli/layer-renamer/f1ba7edded29a27e1db59a1da733eb18fbdfe6f6/LayerRenamer.sketchplugin/Contents/Resources/icons/layerRenamerSelect.png -------------------------------------------------------------------------------- /LayerRenamer.sketchplugin/Contents/Sketch/helpers.cocoascript: -------------------------------------------------------------------------------- 1 | // helpers.cocoascript 2 | // Sketch Plugins 3 | // 4 | // Created by Leonard Pauli, jan 2017 5 | // Copyright © Leonard Pauli, jan 2017 6 | // 7 | var LOG_DEBUG = false 8 | 9 | // createDynamicClassInstanceWithMethods(methods) 10 | // methods: {'sayHey:with:': function(phrase, name) {log(phrase+' '+name+'!')}} 11 | // -> object 12 | // object.sayHey_with_("Hello", "Cocoa") 13 | function createDynamicClassInstanceWithMethods(methods) { 14 | var uniqueClassName = "CocoaScript_DynamicClass_" + NSUUID.UUID().UUIDString(); 15 | var delegateClassDesc = MOClassDescription.allocateDescriptionForClassWithName_superclass_(uniqueClassName, NSObject); 16 | delegateClassDesc.registerClass(); 17 | 18 | var methodNames = Object.keys(methods) 19 | methodNames.forEach(function(selectorString) { 20 | var dynamicFunction = methods[selectorString] 21 | var selector = NSSelectorFromString(selectorString); 22 | delegateClassDesc.addInstanceMethodWithSelector_function_(selector, dynamicFunction); 23 | }) 24 | 25 | var classInstance = NSClassFromString(uniqueClassName).new() 26 | return classInstance 27 | } 28 | 29 | 30 | function getLayerKind(obj) { 31 | var objClass = obj.class() 32 | if (objClass == MSLayerGroup) 33 | return 'Group' 34 | 35 | var str = NSStringFromClass(objClass) 36 | if (str.substr(0,2)=='MS') str = str.substr(2) 37 | if (str.substr(-5)=='Group' || str.substr(-5)=='Layer') 38 | str = str.substr(0,str.length-5) 39 | 40 | if (str=='SymbolInstance') return 'Symbol' 41 | if (str.length>5 && (str.substr(-5)=='Shape' || str=='ShapePath')) return 'Path' 42 | 43 | return str} 44 | 45 | 46 | // Padder helper 47 | function paddStringToLength(str, len, append, char) { 48 | char = char || ' ' 49 | var txt = '' 50 | for (var i=Math.max(0,len-str.length); i>0; i--) txt+=char 51 | return append? str+txt: txt+str} 52 | 53 | 54 | // Log helper 55 | function dLog(str) { 56 | if (!LOG_DEBUG) return; 57 | log(str)} 58 | 59 | 60 | // Alert helper 61 | // opt: { 62 | // title 63 | // message 64 | // width: 500 or fields: { 65 | // _find: ['value', 'placeholder'], // no label 66 | // replace: 'value and placeholder' // label: 'replace' 67 | // } 68 | // buttons: ['Cancel','OK'] // default ['OK'] 69 | // showHelp: function(_alert) {return true;} // default null 70 | // // shows a help (?) button 71 | // beforeShow: function(alert) {} 72 | // -> .selected: {index, title} 73 | // -> .canceled: false 74 | // -> .fields.find.value 75 | // -> .fields.replace.value 76 | // } 77 | var showAlert = function(opt) { 78 | if (!opt) return 79 | if (typeof opt == 'string') 80 | opt = {title:opt} 81 | 82 | var self = {} 83 | self._v = COSAlertWindow.new(); 84 | self.rawAlert = self._v.alert() 85 | 86 | self._v.setMessageText(opt.title || ''); 87 | self._v.setInformativeText(opt.message || ''); 88 | 89 | // Fields 90 | self.fields = {} 91 | if (opt.fields) { 92 | var labels = Object.keys(opt.fields) 93 | 94 | var prevField = null, prevViewIndex = -1 95 | for (var i=0; i=1 && i<=3 && i