From 3064de4499ae7e493b2d09705f757fc8c8e5285b Mon Sep 17 00:00:00 2001 From: adbac <126618591+adbac@users.noreply.github.com> Date: Fri, 11 Jul 2025 17:31:17 +0200 Subject: [PATCH 1/2] add support for character variant names and update documentation --- Lib/feaPyFoFum/feaPyFoFum.py | 50 ++++++++++++++++++++++++++++++++++++ readme.md | 19 +++++++++++++- 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/Lib/feaPyFoFum/feaPyFoFum.py b/Lib/feaPyFoFum/feaPyFoFum.py index 1c4fb31..36c002b 100644 --- a/Lib/feaPyFoFum/feaPyFoFum.py +++ b/Lib/feaPyFoFum/feaPyFoFum.py @@ -1057,3 +1057,53 @@ def _stylisticSetNames(self, names): self._indentText(text) self._identifierStack.append("stylisticSetNames") return text + + # character variant + + def formatCharacterVariantNames(self, *names): + lines = ["cvParameters {"] + orderedNames = dict( + FeatUILabelNameID=[], + FeatUITooltipTextNameID=[], + SampleTextNameID=[], + ParamUILabelNameID=[], + ) + for name in names: + if (nameType := name["type"]) in orderedNames: + orderedNames[nameType].append(name) + # XXX silently fail here? + for nameType in orderedNames: + block = [f"{self._whitespace}{nameType} {{"] + for name in orderedNames[nameType]: + text = name["text"] + platform = name.get("platform") + script = name.get("script") + language = name.get("language") + line = ["name"] + if platform is not None: + line.append(str(platform)) + if script is not None: + line.append(str(script)) + line.append(str(language)) + line.append(u'\"%s\"' % text) + line = (self._whitespace * 2) + " ".join(line) + ";" + block.append(line) + block.append((self._whitespace + "};")) + lines.extend(block) + lines.append("};") + text = "\n".join(lines) + return text + + def characterVariantNames(self, *names): + d = dict( + identifier="characterVariantNames", + names=names + ) + self._content.append(d) + + def _characterVariantNames(self, names): + text = self._handleBreakBefore("characterVariantNames") + text.extend(self.formatCharacterVariantNames(*names).splitlines()) + self._indentText(text) + self._identifierStack.append("characterVariantNames") + return text diff --git a/readme.md b/readme.md index f6b5b01..a4a8878 100644 --- a/readme.md +++ b/readme.md @@ -103,7 +103,7 @@ If `choice` is `True` the rule will be written as a `from` rule (GSUB LookupType The same contextual marking defined in the `substitution` method will be run for `ignoreSubstitution`. -##### writer.stylisticSetFeatureNames(name1, name2, name3, ...) +##### writer.stylisticSetNames(name1, name2, name3, ...) This will write the given names as `featureNames` in the current feature. Names must be dicts of this form: @@ -116,6 +116,21 @@ name = { } ``` +##### writer.characterVariantNames(name1, name2, name3, ...) + +This will write the given names as `cvParameters` in the current feature. Names must be dicts of this form: + +```python +name = { + "type": "type for this name", + # 'type' must be one of [FeatUILabelNameID, FeatUITooltipTextNameID, SampleTextNameID, ParamUILabelNameID] + "text" : "name for string", + "platform" : int, # optional + "script" : int, # optional + "language" : int, # optional +} +``` + ##### writer.write() Return a string containing everything stored in the writer properly formatted for .fea. @@ -149,6 +164,8 @@ This will only assume that the substitution rule should contain contextual marki ##### writer.formatStylisticSetNames(name1, name2, name3, ...) +##### writer.formatCharacterVariantNames(name1, name2, name3, ...) + # FeaPyFoFum From 7ef84a042173c47c7d6b446f47c3e461601e14eb Mon Sep 17 00:00:00 2001 From: adbac <126618591+adbac@users.noreply.github.com> Date: Fri, 11 Jul 2025 17:50:37 +0200 Subject: [PATCH 2/2] skip empty cv names categories --- Lib/feaPyFoFum/feaPyFoFum.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Lib/feaPyFoFum/feaPyFoFum.py b/Lib/feaPyFoFum/feaPyFoFum.py index 36c002b..33de275 100644 --- a/Lib/feaPyFoFum/feaPyFoFum.py +++ b/Lib/feaPyFoFum/feaPyFoFum.py @@ -1072,9 +1072,11 @@ def formatCharacterVariantNames(self, *names): if (nameType := name["type"]) in orderedNames: orderedNames[nameType].append(name) # XXX silently fail here? - for nameType in orderedNames: + for nameType, nameDicts in orderedNames.items(): + if len(nameDicts) == 0: + continue block = [f"{self._whitespace}{nameType} {{"] - for name in orderedNames[nameType]: + for name in nameDicts: text = name["text"] platform = name.get("platform") script = name.get("script")