Set Anchors through Python

Is there a way to make Set Anchors command + U thought the Macro Panel, I can’t find a method in GSLayer Class Reference

I am trying to do something like this:

for layer in Glyphs.font.selectedLayers:
  layer.setAnchors_(Auto) # I need help here
  if layer.anchors:
    print [anchor.name for anchor in layer.anchors]

layer.setAnchors_(Auto)

is the equivalent of

layer.anchors = Auto

that is not what you intended. This is how (as written in docu.glyphsapp.com.

layer.addMissingAnchors()

Thanks @GeorgSeifert, that example was very illustrative.

Is there a quick script to add eg. bottom anchors to all selected glyphs on all layers? Should be easy, right? :smile:

All layers must also include all Brace and Bracket layers. Here is one that just puts one in all layers it can find.

thisFont = Glyphs.font

# iterate through all layers of all selected glyphs:
for thisGlyph in [l.parent for l in thisFont.selectedLayers]:
	for thisLayer in thisGlyph.layers:
	
		# check if bottom anchor is missing:
		if not thisLayer.anchorForName_("bottom"):
		
			# add anchor:
			bottomAnchor = GSAnchor.alloc().init()
			bottomAnchor.name = "bottom"
			thisLayer.addAnchor_(bottomAnchor)

			# set its position:
			halfWidth = thisLayer.width * 0.5
			halfWidthOnTheBaseline = NSPoint( halfWidth, 0.0 )
			bottomAnchor.setPosition_( halfWidthOnTheBaseline )

It doesn’t do anything if the bottom anchor already exists on that layer.

That’s very helpful, thank you! How can I add the line to move it to half the width, please? Sorry!

Whoops, I must be doing something wrong, I can’t get that script to do anything. Feeling stupid now :frowning:

No, I made a mistake in the code sample. It is corrected now. Copy and paste again :smile:

Okay, I adapted the sample for this, and corrected another mistake I had made. Now it should work as intended. Do you understand the code?

Um, it seems to add bottom anchors to all glyphs, not just the selected one. Think I might cry :smile:

Yes, of course. I updated the script sample above again.

What about your own Python skills? The level of understanding it takes to write (or fix) such a script yourself is easy to reach.

Phew, no crying needed :smile:

Thanks, Erich, that’s very good. I need to do some Python workshop at next opportunity, I don’t get it at all.

There is a workshop coming up in Frankfurt, probably early next year.

And there is a three-part introductory tutorial in the Tutorials section. That one is pretty easy and known to have gotten a bunch of type designers started in Python. Just to whet your appetite. :wink:

Frankfurt, who’s teaching it?

Will have a look at the intro tutorial, thanks. I have yet to find something that suits my learning style. Thanks!

Some other resources for learning Python, some free:

https://developers.google.com/edu/python/?csw=1
http://learnpythonthehardway.org/book/
https://www.codecademy.com/en/tracks/python

Yours truly.

1 Like

Keep me posted about Frankfurt :smile:

George, thank you. I’d tried Codecademy and hated it, will have a look at the others when not under deadline pressure! :smile:

@mekkablue If it’s not too complicated, would you be able to give an example of how to set an anchor at a particular position in a particular master? E.g. x, y coordinates in the regular master?

anchor = GSAnchor("top", (400, 20))
layer.anchors.append(anchor)

to get to the layer:

master = Font.masters[1]
glyph = Font.glyphs["A"]
layer = glyph.layers[master.id]

or

layer = Font.selectedLayers[0]

or for all selected layers

for layer in Font.selectedLayers:
    ...

Thanks, Georg. I should get to the layer first, right, before trying to add an anchor?

What I’m hoping to do is to select a bunch of marks of a particular type and add identical anchors to all of them, at set coordinates in each master. I’ll see how this goes.

There seems to be a problem with the wrapper so it need to be like this:

anchorName = "top"
anchorPosition = (123, 456)
for layer in Font.selectedLayers:
    anchor = GSAnchor.alloc().init()
    anchor.name = anchorName
    anchor.position = anchorPosition
    layer.anchors.append(anchor)