Has anyone had problems working with Glyphs files on Github?

Michal Sahar has just published a new Hebrew + Latin font family, but on initial publication it only had lining proportionally spaced figures.

I reported this issue, https://github.com/MichalSahar/Miriam-Libre/issues/2

And then I partially addressed this, and made a pull request, https://github.com/MichalSahar/Miriam-Libre/pull/3/files

I am worried that in this situation, if the upstream project continues to develop the file without merging, then such a pull request will become unmergable, due to the serialization structure of the .glyphs file data.

I am curious if anyone else has experienced this situation?

I wonder that the protocol buffers text format might be better suited to developing glyphs projects with Github, while continuing to be as fast as the current plist format. PB is officially supported for ObjectiveC - https://developers.google.com/protocol-buffers/docs/reference/objective-c-generated - and thereā€™s a convenience package in https://cocoapods.org/pods/ProtocolBuffers

1 Like

i didnā€™t heard of problems like this. I donā€™t see the problem being specific to glyphs files. If you wait to long with any pull request it will become more difficult.

And in what way should the protocol buffer should help? The binary version will be much worse for version control and the ā€˜debugā€™ text representation would have a very similar structure like plist. So the (possible) fundamental problem is not changed. Or did I miss something?

But the data format itself, or better put, the infrastructure around it, is very interesting. Iā€™ll play around with it.

One nice thing about the Glyphs APIs are that someone would be able to write a file format plugin that would allow reading and writing to any format ;).

Given how much trouble designers have with Git and Github itā€™s might be time to accept that itā€™s not a good tool for distributing typefaces in the first place.

I agree, but the problem I am considering is that with other formats, it is easier to recover from the difficult situation; with the current format, trying to rescue a merged state in a text editor is a pain, and I suspect people would rather just redo the work in the editor (which sucks.)

I agree, the binary version will be much worse, but the plain text version will be better, I think, because it reduces the nesting by consolidating keys and values to the same line. That could probably be done to the existing plist format syntax.

(A simple example of the text version here, fonts/ofl/merriweather/METADATA.pb at main Ā· google/fonts Ā· GitHub)

I hear what you are saying about the Glyphs API and file format plugins.

Given how much trouble designers have with Git and Github itā€™s might be time to accept that itā€™s not a good tool for distributing typefaces in the first place.

What alternative do you suggest?

FTP is nice.

This is the file in plist format. The differences are superfluous, it seems to be similar to JASO (which is plist). The structure to store list is different, other than that its just a few semicolons.

{
	name = "Merriweather";
	designer = "Eben Sorkin";
	license = "OFL";
	category = "SERIF";
	date_added = "2011-05-11";
	fonts = (
		{
			name = "Merriweather";
			style = "normal";
			weight = 300;
			filename = "Merriweather-Light.ttf";
			post_script_name = "Merriweather-Light";
			full_name = "Merriweather Light";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "italic";
			weight = 300;
			filename = "Merriweather-LightItalic.ttf";
			post_script_name = "Merriweather-LightItalic";
			full_name = "Merriweather Light Italic";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "normal";
			weight = 400;
			filename = "Merriweather-Regular.ttf";
			post_script_name = "Merriweather-Regular";
			full_name = "Merriweather";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "italic";
			weight = 400;
			filename = "Merriweather-Italic.ttf";
			post_script_name = "Merriweather-Italic";
			full_name = "Merriweather Italic";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "normal";
			weight = 700;
			filename = "Merriweather-Bold.ttf";
			post_script_name = "Merriweather-Bold";
			full_name = "Merriweather Bold";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "italic";
			weight = 700;
			filename = "Merriweather-BoldItalic.ttf";
			post_script_name = "Merriweather-BoldItalic";
			full_name = "Merriweather Bold Italic";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "normal";
			weight = 900;
			filename = "Merriweather-Black.ttf";
			post_script_name = "Merriweather-Black";
			full_name = "Merriweather Black";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		},
		{
			name = "Merriweather";
			style = "italic";
			weight = 900;
			filename = "Merriweather-BlackItalic.ttf";
			post_script_name = "Merriweather-BlackItalic";
			full_name = "Merriweather Black Italic";
			copyright = "Copyright (c) 2010-2016, Sorkin Type Co (www.sorkintype.com) with Reserved Font Name \'Merriweather\'";
		}
	);
	subsets = "cyrillic";
	subsets = "cyrillic-ext";
	subsets = "latin";
	subsets = "latin-ext";
	subsets = "menu";
}

haha james :slight_smile: Iā€™ll bite: How does FTP help with managing development over time?

Okay, but that is NOT the file in .glyphs format :wink:

For example, in that fileā€™s plist format there is a line like

weight = 900;

and the .glyphs format stores that the same way (example):

weightValue = 400;

but the Custom Parameters take up 22 (example) could take up 7 lines with just whitespace changes:

customParameters = (
{name = fsType; value = ();},
{name = license; value = "This Font Software is licensed under the SIL Open Font License, Version 1.1. This license is available with a FAQ at: http://scripts.sil.org/OFL";},
{name = trademark; value = "Miriam Libre is a tradmark of Michal Sahar";},
{name = licenseURL; value = "http://scripts.sil.org/OFL";},
{name = vendorID; value = MCHL;}
);

Also, in each glyph dictionary, the width and unicode values are ordered at the end of the dictionary, but it would be easier to work with the file if they were near the start.

Similarly, some font dictionary items are ordered at the start (copyright, custom parameters) while some (manufacturer, manufacturerURL, unitsPerEm, versionMajor, versionMinor) are at the end.

It would be better to have all items at the same level groups line after line.

The keys in the plist should be ordered alphabetically. I broke that in two cases and those are the only two things this prevent proper source compatibility of the current .glyphs file writer in the glyphslib repository. I reorder the keys if nobody complains about breaking conformance with the plist spec.

Hmm its worse to go off-spec for plists in general, I thinkā€¦ I guess Iā€™d like a glyphs file format plugin that overrrides the default save format with a git-friendly one. Then more radical changes (that are slower) could be made to make it really perfect for git.

One pet peeve with .glyphs and VCS like git is the ā€œlastChangeā€ for each glyph.
It prevents two people from working on the same glyph each on a different layer at the same time. Since both have changed the glyph, the lastChange creates a merge conflict.

@GeorgSeifert what is lastChange used for? Is there a way to not include it in the .glyphs file?
More generally, is there a way to run a script on the .glyphs file after every save (that could normalize, strip lastChange or DisplayStrings)?

Would a ā€œDisable Last Changeā€ parameter help?

Yes, that parameter would help, merging would be smoother in that case.

Any news on this? :slight_smile:

The parameter is implemented.

In implementing this parameter, did you break the original behavior of this? When I open a font and run thisā€¦
print Glyphs.fonts[0].glyphs[ā€˜Aā€™].lastChange
I get:
None

If I open the source in a text editor, I see:
glyphname = A;
lastChange = ā€œ2015-11-02 12:41:35 +0000ā€;

Something isnā€™t right anymore.

This is not a problem with the parameter, but with the python wrapper. I fixed it.