Clone in a terminal:
/*
    Copyright (C) 2014 Johan Mattsson

    This library is free software; you can redistribute it and/or modify 
    it under the terms of the GNU Lesser General Public License as 
    published by the Free Software Foundation; either version 3 of the 
    License, or (at your option) any later version.

    This library is distributed in the hope that it will be useful, but 
    WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 
    Lesser General Public License for more details.
*/
using Math;

namespace BirdFont {

public class LigatureList : GLib.Object {

	public Gee.ArrayList<LigatureSet> ligature_sets;

	LigatureSet lig_set;
	LigatureSet last_set;

	public LigatureList.clig (GlyfTable glyf_table) {
		ligature_sets = new Gee.ArrayList<LigatureSet> ();	
		lig_set = new LigatureSet (glyf_table);
		last_set = new LigatureSet (glyf_table);
		
		add_clig_ligatures (glyf_table);
	}

	public LigatureList.contextual (GlyfTable glyf_table, ContextualLigature ligature) {
		ligature_sets = new Gee.ArrayList<LigatureSet> ();	
		lig_set = new LigatureSet (glyf_table);
		last_set = new LigatureSet (glyf_table);

		add_contextual_ligatures (glyf_table, ligatures);
	}

	void add_clig_ligatures (GlyfTable glyf_table) {
		Font font = BirdFont.get_current_font ();
		Ligatures ligatures = font.get_ligatures ();	
		
		ligatures.get_ligatures ((parts, ligature) => {
			add_ligatures (glyf_table, parts, ligature);
		});	
	}

	void add_contextual_ligatures (GlyfTable glyf_table, ContextualLigatureSet ligatures) {
		foreach (ContextualLigature c in ligatures.ligature_context) {
			foreach (string l in c.ligatures.strip ().split (" ")) {
				add_ligatures (glyf_table, "r", l); // FIXME: parts = ""
			}
		}
	}

	// multiple ligatures in non-contextual substitution
	// FIXME: what if parts equals "" ? Which set does ligatures becomes a part of?
	public void add_ligatures (GlyfTable glyf_table, string characters, string ligatures) 
		requires (!is_null (lig_set) && !is_null (last_set)) {
			
		Font font = BirdFont.get_current_font ();
		string[] parts = characters.split (" ");
		string l = ligatures;

		if (l.has_prefix ("U+") || l.has_prefix ("u+")) {
			l = (!) Font.to_unichar (l).to_string ();
		}
						
		if (!font.has_glyph (l)) {
			warning (@"Ligature $l does not correspond to a glyph in this font.");
			return;
		}
		
		foreach (string p in parts) {		
			if (p.has_prefix ("U+") || p.has_prefix ("u+")) {
				p = (!) Font.to_unichar (p).to_string ();
			}
			
			if (!font.has_glyph (p)) {
				warning (@"Ligature substitution of $p is not possible, the character does have a glyph.");
				return;
			}
		}
		
		if (parts.length == 0) {
			warning ("No parts.");
			return;
		}
		
		if (last_set.starts_with (parts[0])) {
			last_set.add (new Ligature (l, characters));
		} else {
			lig_set = new LigatureSet (glyf_table);
			lig_set.add (new Ligature (l, characters));
			ligature_sets.add (lig_set);
			last_set = lig_set;
		}		
	}
}

}

Contact

Email: johan.mattsson.m@gmail.com
Mastodon: typo.social/@birdfont
GitHub: johanmattssonm
LinkedIn: johan-mattsson-2ab324112