Change name on variable instance with script

I’ve made a small export script that creates a new variable instance and then delete that after the export. I want to make the Variable instance have a name so the family name of the variable font becomes like this “Family Name VAR”.
I have tried with this: new_instanceVariable.name = f"{font.familyName} Variable" but that didn’t seem to work. How can I do this with script?

My script looks like this:

new_instanceVariable = GSInstance()
#new_instanceVariable.name = f"{font.familyName} Variable"
new_instanceVariable.customParameters['fileName'] = f"{font.familyName}Variable"
new_instanceVariable = GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)
font.instances.append(new_instanceVariable)

print(Glyphs.font.export(Format=VARIABLE, Containers=[PLAIN, WOFF, WOFF2], FontPath=os.path.expanduser(subfolder_paths["Variable"]), UseProductionNames=UseProductionNames, AutoHint=TTF_AutoHint))

print()

font.instances.remove(new_instanceVariable)

Thanks

The variable setting “name” is not what you are looking for. Set that to Regular, unless you have an Italic variable font.

You are looking for GSInstance.properties, and the GSFontInfoValueLocalized property. Read more here: Glyphs.app Python Scripting API Documentation — Glyphs.app Python Scripting API 3.0.4 documentation

Thanks!
I tried new_instanceVariable.fontInfoValueLocalized = f"{font.familyName} Variable" but that doesn’t seem to work? What am I missing?

I recommend you take a look at the Method Reporter script from the mekkablue scripts. You can search for the GSFontInfoValueLocalized object and will find some useful functions to initialise an instance with a key and a value.

You dont need to mess with the GSFontInfoValues directly. The docu at: Glyphs.app Python Scripting API Documentation — Glyphs.app Python Scripting API 3.0.4 documentation has some code that shows how to do it. And the keys are at: Glyphs.app Python Scripting API Documentation — Glyphs.app Python Scripting API 3.0.4 documentation

1 Like

Thanks!
I tried this, but it doesn’t really seem to change the family name of the exported variable font:
new_instanceVariable.setProperty_value_languageTag_(GSPropertyNameFamilyNamesKey, "SomeName", None)

Can you help me out here?

Can you post your full script again? Because in the one you posted above, you overwrite new_instanceVariable just after you added the custom parameter/name.

And you can use the instance directly to export:

new_instanceVariable.generate( … )

And don’t mix up the variables. You use font and Glyphs.font that might give unexpected results.

And why not add the instance to the font directly? You can add several and activate/deactivate them as needed.

Yes as you might have guessed I’m not really a python coder. So thanks for pointing out.
But the script is actually a really cool production script for exporting files. It makes a complete production package with folders and variable version of web protected files. You should really try it out and see the result😄

So it makes TTF, OTF and WOFF files - Of course.
Then it makes 2 temporary variable instances for protected web files. This is quite a common way to protect fonts.
A) One that contains only the space character
B) One that contains the rest of the glyphs but has a space 20000 wide.
In css I’ll use the first and then the second for fallback.

Besides this it also makes a temporary instance that is the “Actual variable export”.
And it is this one that I would like to be called “Font Name Variable”. So the user can have both the static and the variable installed at the same time.
I still don’t know what to do here.

But you should try it out and see how cool it is :slight_smile:

#MenuTitle: Export All Fonts
# -*- coding: utf-8 -*-
__doc__="""
Export All Fonts
"""

from GlyphsApp import OTF, TTF, WOFF, WOFF2, EOT, UFO, GSFont, GSInstance, GSCustomParameter, GSPropertyNameFamilyNamesKey, INSTANCETYPEVARIABLE, PLAIN
import os

# Load your font
font = Glyphs.font

# Get the current document
doc = Glyphs.currentDocument

# Get the file path of the current document
doc_path = doc.filePath

# Get the folder path of the current Glyphs document
folder_path = os.path.dirname(doc_path)

# Define the name of the subfolder
subfolder_name = "Export"

# Create the subfolder if it doesn't exist
export_folder = os.path.join(folder_path, subfolder_name)
if not os.path.exists(export_folder):
    os.mkdir(export_folder)

# Define the names of the subfolders inside the "export" subfolder
subfolder_names = ["OTF", "TTF", "WOFF", "Variable", "Website - Protected files"]

# Create the font family subfolder
font_family_name = font.familyName
font_family_folder = os.path.join(export_folder, font_family_name)
if not os.path.exists(font_family_folder):
    os.mkdir(font_family_folder)

# Create the subfolders inside the font family folder
subfolder_paths = {}
for name in subfolder_names:
    if name != "Website - Protected files":
        subfolder_path = os.path.join(font_family_folder, name)
        if not os.path.exists(subfolder_path):
            os.mkdir(subfolder_path)
    else:
        subfolder_path = os.path.join(export_folder, name)
        if not os.path.exists(subfolder_path):
            os.mkdir(subfolder_path)
    subfolder_paths[name] = subfolder_path
OTF_AutoHint = True
TTF_AutoHint = True
RemoveOverlap = True
UseSubroutines = True
UseProductionNames = True
Web_OutlineFormat = TTF

familyName = font.familyNames["ENG"]



# Website - Protected files

# Temporary Variable Instance - A (Only the space glyph) 
TemporaryVariableInstance_A = GSInstance()
TemporaryVariableInstance_A.name = "Web variable A"
TemporaryVariableInstance_A = GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)
TemporaryVariableInstance_A.customParameters['fileName'] = f"{font.familyName} - A"
TemporaryVariableInstance_A.customParameters['Keep Glyphs'] = "space"
font.instances.append(TemporaryVariableInstance_A)

# Temporary Variable Instance - B (The rest of the glyphs, but the space is 20000 wide) 
TemporaryVariableInstance_B = GSInstance()
TemporaryVariableInstance_B.name = "Web variable B"
TemporaryVariableInstance_B = GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)
TemporaryVariableInstance_B.customParameters['fileName'] = f"{font.familyName} - B"
TemporaryVariableInstance_B.customParameters['Filter'] = "Transformations; Width: +20000; include:space"
font.instances.append(TemporaryVariableInstance_B)

print("== Exporting Website - Protected files ==")
print(font.export(Format=VARIABLE, Containers=[PLAIN, WOFF, WOFF2], FontPath=os.path.expanduser(subfolder_paths["Website - Protected files"]), UseProductionNames=UseProductionNames, AutoHint=TTF_AutoHint))
print()

# Delete the Temporary Variable Instances
font.instances.remove(TemporaryVariableInstance_A)
font.instances.remove(TemporaryVariableInstance_B)



# Actual Variable Export

# Temporary Variable Instance Shich should have the name "FontName - Variable"
TemporaryVariableInstance_Actual = GSInstance()
TemporaryVariableInstance_Actual.setProperty_value_languageTag_(GSPropertyNameFamilyNamesKey, "SomeName", None)
TemporaryVariableInstance_Actual.customParameters['fileName'] = f"{font.familyName}Variable"
TemporaryVariableInstance_Actual = GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)
font.instances.append(TemporaryVariableInstance_Actual)

print("== Exporting Variable ==")
print(font.export(Format=VARIABLE, Containers=[PLAIN, WOFF, WOFF2], FontPath=os.path.expanduser(subfolder_paths["Variable"]), UseProductionNames=UseProductionNames, AutoHint=TTF_AutoHint))
print()

# Delete the Actual Temporary Variable Instance
font.instances.remove(TemporaryVariableInstance_Actual)


# Export OTF, TTF and WOFF
for instance in font.instances:
    print("== Exporting OTF ==")
    print(instance.generate(Format=OTF, FontPath=os.path.expanduser(subfolder_paths["OTF"]), AutoHint=OTF_AutoHint, RemoveOverlap=RemoveOverlap, UseSubroutines=UseSubroutines, UseProductionNames=UseProductionNames))
print()

for instance in font.instances:
    print("== Exporting TTF ==")
    print(instance.generate(Format=TTF, FontPath=os.path.expanduser(subfolder_paths["TTF"]), AutoHint=TTF_AutoHint, RemoveOverlap=RemoveOverlap, UseProductionNames=UseProductionNames))
print()

for instance in font.instances:
    print("== Exporting Web ==")
    print(instance.generate(Format=Web_OutlineFormat, FontPath=os.path.expanduser(subfolder_paths["WOFF"]), AutoHint=TTF_AutoHint, RemoveOverlap=RemoveOverlap, UseSubroutines=UseSubroutines, UseProductionNames=UseProductionNames, Containers=[WOFF, WOFF2, EOT]))
print()

I didn’t look at the details, yet. But most of what you explain in the text, you can do with several sets of instances (and if this leads to too many instances could be done with a glyphspackage).

Why the names do not appear in the final fonts:

TemporaryVariableInstance_Actual = GSInstance()
TemporaryVariableInstance_Actual.setProperty_value_languageTag_(GSPropertyNameFamilyNamesKey, "SomeName", None)
TemporaryVariableInstance_Actual.customParameters['fileName'] = f"{font.familyName}Variable"
TemporaryVariableInstance_Actual = GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)
font.instances.append(TemporaryVariableInstance_Actual)

In the first line, you make a new instance, in second and third line, you add some stuff to it. But in the forth line, you throw it away and make a new instance and append that to the font. So this should work.

TemporaryVariableInstance_Actual = GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)

TemporaryVariableInstance_Actual.setProperty_value_languageTag_(GSPropertyNameFamilyNamesKey, "SomeName", None)
TemporaryVariableInstance_Actual.customParameters['fileName'] = f"{font.familyName}Variable"

font.instances.append(TemporaryVariableInstance_Actual)

and use this:

GSInstance(type=INSTANCETYPEVARIABLE)

instead of

GSInstance.alloc().initWithType_(INSTANCETYPEVARIABLE)

Great — This worked!
Thank you so much :slight_smile: