Add color label to selected glyph using a script

I fear this is so basic! Please bear with a beginner. Apologies if this is a double-post, I did my due diligence searching in this forum, studying the 4 tutorials on Glyphs scripting, studying every relevant-looking script in @mekkablue’s repo in my code editor, and searching on Google and couldn’t turn anything up—at least nothing I yet have a clear understanding of. I know the concepts are described, but I think I need something obvious to get me kickstarted.

I am currently learning to write Glyphs scripts, and need to get my head around the relationship between Python concepts and Glyphs API functionality. One of my first challenges is to write a script to change a glyph’s color label to light green (code = 4). I can get the following variables to print successfully, but don’t know how to ‘grab’ the current glyph and do things with it. I believe I need to use a ‘for’ loop (for something in something), which I’ve attempted below with no success.

#MenuTitle: Set Green Label
# -*- coding: utf-8 -*-
# Created by Dave
__doc__="""
Set green label
"""

import GlyphsApp

currentFont = Glyphs.font
selectedLayers = currentFont.selectedLayers

print "currentFont: %s\nselectedLayers: %s" % (currentFont, selectedLayers)

for selectedLayers in currentFont:
	try:
		glyph.color = 4
	except:
		print "Oh no"

I get the following error when trying out this code:

for selectedLayers in currentFont:
TypeError: 'NSKVONotifying_GSFont' object is not iterable

Thanks for any advice!

I could write you the correct code but that would spoil the most fun for you ;).

You have almost all things in place. The problem is in the ‘for … in’ loop. Check the python into tutorial and try the examples to understand the code.

2 Likes

haha seriously thank you for not spoiling it! Wanna learn! But good to be put on the scent, thanks Georg, will check that out! :mag_right::thinking:

Hint: if an object is not iterable, that means it is a single object, not a collection. But you need a collection (list, set, tuple, etc.) to loop through.

Thanks Rainer, that helps a lot, I’m getting warmer. Please indulge me: what is thisLayer? It seems to get used a lot, but I sometimes see it defined as a variable, and sometimes not?? Is it python based, or Glyphs based? Does it have meaning beyond a user-defined variable?

Thanks!

No, it is just an arbitrary variable name, most likely to store the current layer in a loop through layers.

OK, thanks! P.s, finally cracked it :slight_smile:

#MenuTitle: Set Green Label
# -*- coding: utf-8 -*-
# Created by Dave
__doc__="""
Set green label
"""

import GlyphsApp

currentFont = Glyphs.font
selectedLayers = currentFont.selectedLayers
selectedLayer = selectedLayers[0]
selection = selectedLayer.selection
errorMessage = "Didn't work :("

#print "currentFont: %s\nselectedLayers: %s" % (currentFont, selectedLayers)

for thisLayer in selectedLayers:
	thisGlyph = thisLayer.parent
	if thisGlyph.color == 4:
		try:
			thisGlyph.color = 9223372036854775807
		except:
			print errorMessage
	else:
		try:
			thisGlyph.color = 4
		except:
			print errorMessage

P.p.s if thisLayer is totally arbitrary/meaningless, why on earth does it work here, when it’s never defined as a variable??

1 Like

Ot may still be in memory from a previously run script. But that is not the case here because thisLayer is defined as loop variable in the for statement.

You do not need to import GlyphsApp anymore. Was that still in one of my snippets?

And instead of the big number, it is probably safer to write NSNotFound.

Minor style issue: The two try/except statements are code reduplication. Better to put the whole if/then inside the try statement rather than the other way around. The error message could be more informative. At least state the glyph and layer name so the user can trace down the problematic glyph.

1 Like

The thisLayer variable is assigned by the dir loop.

And there are a few lines in the beginning of the script that are not needed (selectedLayee and selection).

1 Like