Delete Current Master Layers

There is a script that Rainer has in git that I use quite often to delete all my layers. However, it goes through all the layers in all masters. Can it delete only the layers for the selected master? And if not, is there anything else I can use at current master level.

Not sure I get this right. You mean, delete all non-master layers that are associated with the current master?
e.g.:

  1. Regular
    • Regular Dec 24
    • Regular Dec 25
  2. Bold
    • Bold Dec 22
    • Bold Dec 23

And if Regular is the current master, you want the script to delete Regular Dec 24 and Regular Dec 25?

Yes, that is the use that I am after. [smile]

However, instead of two non-master layers I have 20 layers for each glyph (10 Regular, 10 Bold) and when I want to wipe the current master’s non-master layers I manually click the “-” in each.

I couldn’t figure how to iterate only the current master non-layers opposed to all.

You need to check if associatedMasterId is the same as the ID of the master in question. This yields all the layers that belong to the master. But you must not delete the layer whose layerId is the master ID, because that is the master layer. So you could do something like this:

thisMaster = Glyphs.font.selectedFontMaster
masterID = thisMaster.id
thisGlyph = thisFont.selectedLayers[0].parent

for i in range(len(thisGlyph.layers))[::-1]:
	thisLayer = thisGlyph.layers[i]
	if thisLayer.associatedMasterId == masterID and thisLayer.layerId != masterID:
		thisGlyph.removeLayerForKey_(thisLayer.layerId)
1 Like

Erik, I’ve been trying to figure out how to amend your existing script with the code you supply but I cannot understand where I should add it (or what I need to replace) in the existing code. Can you please help.

Thanks

That Code should do what you asked for. I have not tried it though and am not on my Mac now. Paste it in your macro window, select a glyph, and run it.

It didn’t work but based on this I changed your existing script and it works fine now. Thanks!

Can you paste it here?

Of course. Here you are:

#MenuTitle: Delete all non-Current Master layers
# -*- coding: utf-8 -*-
__doc__="""
Goes through selected glyphs in Current Master and deletes all glyph layers which are not a Master, Bracket or Brace layer.
"""

import GlyphsApp

Font = Glyphs.font
thisMaster = Glyphs.font.selectedFontMaster
masterID = thisMaster.id

selectedLayers = Font.selectedLayers
searchTerms = [ "[]", "{}" ]

def process( thisGlyph ):
	count = 0
	
	numberOfLayers = len( thisGlyph.layers )
	for i in range( numberOfLayers )[::-1]:
		thisLayer = thisGlyph.layers[i]
		if thisLayer.associatedMasterId == masterID and thisLayer.layerId != thisLayer.associatedMasterId: # not the master layer
			thisLayerName = thisLayer.name
			thisLayerShouldBeRemoved = True
			if thisLayerName: # always delete unnamed layers
				for parentheses in searchTerms:
					opening = parentheses[0]
					closing = parentheses[1]
					
					# check if ONE of them is at the END of the layer name, like:
					# Bold [160], Bold [160[, Bold ]160], Regular {120}
					if thisLayerName.endswith(opening) or thisLayerName.endswith(closing):
						thisLayerShouldBeRemoved = False
						
			if thisLayerShouldBeRemoved:
				count += 1
				del thisGlyph.layers[i]
			
	return count

Font.disableUpdateInterface()

for thisLayer in selectedLayers:
	thisGlyph = thisLayer.parent

	thisGlyph.beginUndo()
	print "%s layers deleted in %s." % ( process( thisGlyph ), thisGlyph.name )
	thisGlyph.endUndo()

Font.enableUpdateInterface()
1 Like

Hi @Mekkablue, any chance to get this great script “Delete all non-Master layers” for Glyphs 3?

@displaay, try this

#MenuTitle: Delete all non-Current Master layers
# -*- coding: utf-8 -*-
__doc__="""
Goes through selected glyphs in Current Master and deletes all glyph layers which are not a Master, Bracket or Brace layer.
"""

import GlyphsApp

Font = Glyphs.font
thisMaster = Glyphs.font.selectedFontMaster
masterID = thisMaster.id

selectedLayers = Font.selectedLayers
searchTerms = [ "[]", "{}" ]

def process( thisGlyph ):
	count = 0
	
	numberOfLayers = len( thisGlyph.layers )
	for i in range( numberOfLayers )[::-1]:
		thisLayer = thisGlyph.layers[i]
		if thisLayer.associatedMasterId == masterID and thisLayer.layerId != thisLayer.associatedMasterId: # not the master layer
			thisLayerName = thisLayer.name
			thisLayerShouldBeRemoved = True
			if thisLayerName: # always delete unnamed layers
				for parentheses in searchTerms:
					opening = parentheses[0]
					closing = parentheses[1]
					
					# check if ONE of them is at the END of the layer name, like:
					# Bold [160], Bold [160[, Bold ]160], Regular {120}
					if thisLayerName.endswith(opening) or thisLayerName.endswith(closing):
						thisLayerShouldBeRemoved = False
						
			if thisLayerShouldBeRemoved:
				count += 1
				del thisGlyph.layers[i]
			
	return count

Font.disableUpdateInterface()

for thisLayer in selectedLayers:
	thisGlyph = thisLayer.parent

	thisGlyph.beginUndo()
	print("%s layers deleted in %s." % ( process( thisGlyph ), thisGlyph.name ))
	thisGlyph.endUndo()

Font.enableUpdateInterface()

Brilliant. Thank you so much. I owe you beer!

See also:

Less code, same (?) functionality.

In Glyphs 3, you can install this via the Plugin Manager/Scripts/Freemix Tools.

Be careful to not delete variation layers for smart components (such as _part.### glyphs with internal variation). I recently applied on of these scripts to my font and all of my smart components broke. (Luckily my Glyphs file was managed by revision control, so I could restore.)

Thanks for the notice! I’ll have to update the script then.

Also, in Glyphs 3, it’s much easier to check whether a layer is a special layer (Glyphs.app Python Scripting API Documentation — Glyphs.app Python Scripting API 3.0 documentation) so, no more need for parsing the string.