-
-
Save arialcrime/d2fa5b7abaee7f8dba9bdf40c74d8894 to your computer and use it in GitHub Desktop.
make adjustments to an existing designspace file
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import pathlib | |
| from fontTools.designspaceLib import (DesignSpaceDocument, AxisDescriptor, | |
| SourceDescriptor, InstanceDescriptor) | |
| remap_dict = { | |
| 'weight': { | |
| 50: ['air', 'hairline'], | |
| 100: ['thin'], | |
| 200: ['ultralight', 'extralight'], | |
| 300: ['light'], | |
| 400: ['regular'], | |
| 450: ['book'], | |
| 500: ['medium'], | |
| 600: ['semibold'], | |
| 700: ['bold'], | |
| 800: ['extrabold'], | |
| 900: ['black'] | |
| } | |
| } | |
| rename_stylenames_dict = { | |
| 'Semi Bold': 'Semibold', | |
| } | |
| def sort(elements, axisname=None): | |
| return sorted(elements, key=lambda e: e.location[axisname]) | |
| def sort_sources_instances(doc, axisname): | |
| if not axisname: | |
| axisname = doc.axes[0].name | |
| doc.sources = sort(doc.sources, axisname) | |
| doc.instances = sort(doc.instances, axisname) | |
| def remap_source_instance(items_list, axis_name): | |
| mapping_values = [] | |
| for i in items_list: | |
| style_name = i.styleName.replace(' Italic','').replace(' ','').lower() | |
| new_value = next((key for key,values in remap_dict[axis_name].items() if style_name in values), None) | |
| if new_value: | |
| mapping_values.append((new_value, i.location[axis_name])) | |
| return sorted(mapping_values) | |
| def write_axis_map(doc): | |
| for a in doc.axes: | |
| if a.name == "weight": | |
| axis_name = a.name | |
| # we assume here that all masters have an instance too | |
| # otherwise we’d need to loop through doc.sources too | |
| a.map = remap_source_instance(doc.instances, axis_name) | |
| # fix min/max/defaults since they thould be user-values | |
| a.minimum = a.map[0][0] | |
| a.maximum = a.map[-1][0] | |
| a.default = next((t[0] for t in a.map if t[1] == a.default), a.default) | |
| # rename source files in path | |
| def rename_sources(doc): | |
| doc_path = pathlib.Path(doc.path) | |
| dir_path = doc_path.parent | |
| # get the ufo paths | |
| if 'italic' in doc_path.name.lower(): | |
| source_ufo_paths = [u for u in dir_path.glob(f'*.ufo') if 'italic' in u.name.lower()] | |
| ita = '-Italic' | |
| else: | |
| source_ufo_paths = [u for u in dir_path.glob(f'*.ufo') if not 'italic' in u.name.lower()] | |
| ita = '' | |
| # find out index of file in designspace doc | |
| source_filenames = [s.filename for s in doc.sources] | |
| for source_ufo_path in source_ufo_paths: | |
| if source_ufo_path.name in source_filenames: | |
| i = source_filenames.index(source_ufo_path.name) | |
| new_source_name = f'{source_ufo_path.name.split("-")[0]}{ita}_{i}.ufo' | |
| new_source_path = pathlib.Path(source_ufo_path.parent, new_source_name) | |
| source_ufo_path.rename(new_source_path) | |
| doc.sources[i].path = str(new_source_path) | |
| #doc.sources[i].name = new_source_name | |
| def fix_instances(doc): | |
| doc_path = pathlib.Path(doc.path) | |
| dir_path = doc_path.parent | |
| for i in doc.instances: | |
| # fix styleName | |
| if i.styleName.title() != i.styleName: | |
| i.styleName = i.styleName.title() | |
| if i.styleName in rename_stylenames_dict: | |
| i.styleName = rename_stylenames_dict[i.styleName] | |
| ps_styleName = i.styleName.replace(" Italic","It") | |
| ps_familyName = i.familyName.replace("\'","").replace(" ","") | |
| # fix path | |
| instance_path = dir_path / f'../Instances/{ps_styleName}/font.ufo' | |
| i.path = str(instance_path.resolve()) | |
| i.postScriptFontName = f'{ps_familyName}-{ps_styleName}' | |
| if __name__ == "__main__": | |
| root_path = pathlib.Path(__file__).parent | |
| dsp_path = "../path/to/your.designspace" | |
| input_path = root_path / dsp_path | |
| input_path = input_path.resolve() # | |
| doc = DesignSpaceDocument.fromfile(input_path) | |
| write_axis_map(doc) | |
| sort_sources_instances(doc, axisname=None) # sorts by first axis if none given | |
| rename_sources(doc) | |
| fix_instances(doc) | |
| output_name = input_path.stem + "_relocated" + input_path.suffix | |
| output_path = input_path.parent / output_name | |
| doc.write(output_path) | |
| print(f"Saved {output_path.name}.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment