Transform Rhotic hooks (U+02DE
) into superscript/subscript form when they are placed after a superscript/subscript letter (#1681).
This commit is contained in:
parent
a46c2d7773
commit
3ae03f6aac
11 changed files with 249 additions and 233 deletions
|
@ -17,3 +17,4 @@
|
||||||
* Improve aesthetics of Greek Dialytika Tonos, Dialytica Oxia, and Dialytika Varia.
|
* Improve aesthetics of Greek Dialytika Tonos, Dialytica Oxia, and Dialytika Varia.
|
||||||
* Remove ASCII caret (`^`) from operator centering, as it is usually considered asymmetric (#1507).
|
* Remove ASCII caret (`^`) from operator centering, as it is usually considered asymmetric (#1507).
|
||||||
* Make dotted circle narrow by default, as it is more frequently used as a mark carrier (#1672).
|
* Make dotted circle narrow by default, as it is more frequently used as a mark carrier (#1672).
|
||||||
|
* Transform Rhotic hooks (`U+02DE`) into superscript/subscript form when they are placed after a superscript/subscript letter (#1681).
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
###### Automatic builds
|
###### Automatic builds
|
||||||
$$include '../../meta/macros.ptl'
|
$$include '../../meta/macros.ptl'
|
||||||
|
|
||||||
import [Dotless AnyDerivingCv DotlessOrNot getGrTree CvDecompose CcmpDecompose RequireCcmpDecompose] from"../../support/gr.mjs"
|
import [Dotless AnyDerivingCv DotlessOrNot getGrTree CvDecompose] from"../../support/gr.mjs"
|
||||||
import [fallback] from"../../support/utils.mjs"
|
import [fallback] from"../../support/utils.mjs"
|
||||||
import as UnicodeKnowledge from"../../meta/unicode-knowledge.mjs"
|
import as UnicodeKnowledge from"../../meta/unicode-knowledge.mjs"
|
||||||
|
|
||||||
|
@ -124,10 +124,6 @@ glyph-block AutoBuild-Accents : begin
|
||||||
local decomposeParts { }
|
local decomposeParts { }
|
||||||
foreach part [items-of s_parts] : recursivelyDecompose part decomposeParts
|
foreach part [items-of s_parts] : recursivelyDecompose part decomposeParts
|
||||||
CvDecompose.set currentGlyph decomposeParts
|
CvDecompose.set currentGlyph decomposeParts
|
||||||
if [RequireCcmpDecompose.get s_parts.0] : begin
|
|
||||||
local ccmpParts { }
|
|
||||||
foreach part [items-of s_parts] : ccmpParts.push : glyphStore.queryNameOf part
|
|
||||||
CcmpDecompose.set currentGlyph ccmpParts
|
|
||||||
|
|
||||||
define [RootGlyphProc goalName code parts] : begin
|
define [RootGlyphProc goalName code parts] : begin
|
||||||
set s_goalName goalName
|
set s_goalName goalName
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
$$include '../../meta/macros.ptl'
|
$$include '../../meta/macros.ptl'
|
||||||
|
|
||||||
import [linreg clamp mix fallback] from"../../support/utils.mjs"
|
import [linreg clamp mix fallback] from"../../support/utils.mjs"
|
||||||
import [getGrTree getGrMesh] from"../../support/gr.mjs"
|
import [getGrTree getGrMesh IsSuperscript IsSubscript] from"../../support/gr.mjs"
|
||||||
import [AnyCv DotlessOrNot CvDecompose MathSansSerif] from"../../support/gr.mjs"
|
import [AnyCv DotlessOrNot CvDecompose MathSansSerif] from"../../support/gr.mjs"
|
||||||
import [NumeratorForm DenominatorForm] from"../../support/gr.mjs"
|
import [NumeratorForm DenominatorForm] from"../../support/gr.mjs"
|
||||||
extern Map
|
extern Map
|
||||||
|
@ -97,6 +97,7 @@ glyph-block Autobuild-Transformed : begin
|
||||||
include [Scale 0.7] true
|
include [Scale 0.7] true
|
||||||
include [Translate middle (CAP + AccentStackOffset / 2)] true
|
include [Translate middle (CAP + AccentStackOffset / 2)] true
|
||||||
include [Regizmo] true
|
include [Regizmo] true
|
||||||
|
IsSuperscript.set currentGlyph
|
||||||
if ([not fRelated] && gr) : gr.set [query-glyph glyphid] (targetNameMap.(glyphid))
|
if ([not fRelated] && gr) : gr.set [query-glyph glyphid] (targetNameMap.(glyphid))
|
||||||
link-relations relSets
|
link-relations relSets
|
||||||
return { targetNameMap records }
|
return { targetNameMap records }
|
||||||
|
@ -119,6 +120,7 @@ glyph-block Autobuild-Transformed : begin
|
||||||
include [Scale 0.7] true
|
include [Scale 0.7] true
|
||||||
include [Translate middle (Descender / 2)] true
|
include [Translate middle (Descender / 2)] true
|
||||||
include [Regizmo] true
|
include [Regizmo] true
|
||||||
|
IsSubscript.set currentGlyph
|
||||||
if ([not fRelated] && gr) : gr.set [query-glyph glyphid] (targetNameMap.(glyphid))
|
if ([not fRelated] && gr) : gr.set [query-glyph glyphid] (targetNameMap.(glyphid))
|
||||||
link-relations relSets
|
link-relations relSets
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
$$include '../../../meta/macros.ptl'
|
$$include '../../../meta/macros.ptl'
|
||||||
|
|
||||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||||
import [Dotless CvDecompose RequireCcmpDecompose] from"../../../support/gr.mjs"
|
import [Dotless CvDecompose] from"../../../support/gr.mjs"
|
||||||
|
|
||||||
glyph-module
|
glyph-module
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ glyph-block Letter-Latin-Lower-AE-OE : begin
|
||||||
set-width 0
|
set-width 0
|
||||||
set-mark-anchor 'cvDecompose' 0 0
|
set-mark-anchor 'cvDecompose' 0 0
|
||||||
include : EShape 1 df body
|
include : EShape 1 df body
|
||||||
|
|
||||||
create-glyph "aeInvE/right.\(suffix)" : glyph-proc
|
create-glyph "aeInvE/right.\(suffix)" : glyph-proc
|
||||||
local df : DivFrame para.diversityM 3
|
local df : DivFrame para.diversityM 3
|
||||||
set-width 0
|
set-width 0
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
$$include '../../../meta/macros.ptl'
|
$$include '../../../meta/macros.ptl'
|
||||||
|
|
||||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||||
import [Dotless CvDecompose RequireCcmpDecompose] from"../../../support/gr.mjs"
|
import [Dotless CvDecompose] from"../../../support/gr.mjs"
|
||||||
|
|
||||||
glyph-module
|
glyph-module
|
||||||
|
|
||||||
|
|
|
@ -27,5 +27,18 @@ glyph-block Letter-Latin-Rhotic : begin
|
||||||
if dohook {[hookend (y - rise)]} {[arcvh]}
|
if dohook {[hookend (y - rise)]} {[arcvh]}
|
||||||
g4 (right - [if dohook sw 0]) (y - [if dohook (rise * 0.5) rise]) [if dohook nothing [heading Rightward]]
|
g4 (right - [if dohook sw 0]) (y - [if dohook (rise * 0.5) rise]) [if dohook nothing [heading Rightward]]
|
||||||
|
|
||||||
create-glyph 'rhotichook' 0x2DE : glyph-proc
|
create-glyph 'rhoticHook' 0x2DE : glyph-proc
|
||||||
include : ErTail (-Stroke * HVContrast) (XH / 2) Stroke true
|
include : ErTail (-Stroke * HVContrast) (XH / 2) Stroke true
|
||||||
|
|
||||||
|
create-glyph 'rhoticHook/sup' : glyph-proc
|
||||||
|
local sw : [AdviceStroke 3.5] / 0.7
|
||||||
|
include : ErTail (-Stroke * HVContrast - 3 * SB) (XH / 2) sw true
|
||||||
|
include : Ungizmo
|
||||||
|
include : Translate (-Middle) (-CAP)
|
||||||
|
include : Scale 0.7
|
||||||
|
include : Translate (Middle) (CAP + AccentStackOffset / 2)
|
||||||
|
include : Regizmo
|
||||||
|
|
||||||
|
create-glyph 'rhoticHook/sub' : glyph-proc
|
||||||
|
include [refer-glyph 'rhoticHook/sup'] AS_BASE ALSO_METRICS
|
||||||
|
include : ApparentTranslate 0 ((Descender / 2) - (CAP + AccentStackOffset / 2) + 0.7 * CAP)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
$$include '../../../meta/macros.ptl'
|
$$include '../../../meta/macros.ptl'
|
||||||
|
|
||||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||||
import [Dotless CvDecompose RequireCcmpDecompose] from"../../../support/gr.mjs"
|
import [Dotless CvDecompose] from"../../../support/gr.mjs"
|
||||||
import [bitOr] from"../../../support/util/mask-bit.mjs"
|
import [bitOr] from"../../../support/util/mask-bit.mjs"
|
||||||
|
|
||||||
glyph-module
|
glyph-module
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
$$include '../../../meta/macros.ptl'
|
$$include '../../../meta/macros.ptl'
|
||||||
|
|
||||||
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
import [mix linreg clamp fallback] from"../../../support/utils.mjs"
|
||||||
import [Dotless CvDecompose RequireCcmpDecompose] from"../../../support/gr.mjs"
|
import [Dotless CvDecompose] from"../../../support/gr.mjs"
|
||||||
|
|
||||||
glyph-module
|
glyph-module
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ extern Map
|
||||||
extern Set
|
extern Set
|
||||||
|
|
||||||
define MarkClasses {
|
define MarkClasses {
|
||||||
'above' 'tieAbove' 'topright' 'grekLowerTonos' 'aboveBraceL' 'aboveBraceR'
|
'above' 'tieAbove' 'topright' 'grekUpperTonos' 'aboveBraceL' 'aboveBraceR'
|
||||||
'below' 'tieBelow' 'bottomright' 'trailing' 'lf' 'belowBraceL' 'belowBraceR'
|
'below' 'tieBelow' 'bottomright' 'trailing' 'lf' 'belowBraceL' 'belowBraceR'
|
||||||
|
|
||||||
'overlay' 'slash'
|
'overlay' 'slash'
|
||||||
|
@ -13,8 +13,8 @@ define MarkClasses {
|
||||||
}
|
}
|
||||||
|
|
||||||
define MarkInteractions : new Map : list
|
define MarkInteractions : new Map : list
|
||||||
list 'aboveBraceL' { 'aboveBraceL' 'above' 'tieAbove' 'topright' 'grekLowerTonos' }
|
list 'aboveBraceL' { 'aboveBraceL' 'above' 'tieAbove' 'topright' 'grekUpperTonos' }
|
||||||
list 'aboveBraceR' { 'aboveBraceR' 'above' 'tieAbove' 'topright' 'grekLowerTonos' }
|
list 'aboveBraceR' { 'aboveBraceR' 'above' 'tieAbove' 'topright' 'grekUpperTonos' }
|
||||||
list 'belowBraceL' { 'belowBraceL' 'below' 'tieBelow' 'bottomright' 'trailing' 'lf' }
|
list 'belowBraceL' { 'belowBraceL' 'below' 'tieBelow' 'bottomright' 'trailing' 'lf' }
|
||||||
list 'belowBraceR' { 'belowBraceR' 'below' 'tieBelow' 'bottomright' 'trailing' 'lf' }
|
list 'belowBraceR' { 'belowBraceR' 'below' 'tieBelow' 'bottomright' 'trailing' 'lf' }
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import [AddCommonFeature AddFeature AddLookup AddFeatureLookup ChainRuleBuilder BeginLookupBlock EndLookupBlock UkMapToLookup UkMap2ToLookup] from"./table-util.mjs"
|
import [AddCommonFeature AddFeature AddLookup AddFeatureLookup ChainRuleBuilder BeginLookupBlock EndLookupBlock UkMapToLookup UkMap2ToLookup] from"./table-util.mjs"
|
||||||
import [AnyCv Dotless TieMark TieGlyph CcmpDecompose OgonekTrY] from"../support/gr.mjs"
|
import [AnyCv Dotless TieMark TieGlyph OgonekTrY IsSuperscript IsSubscript] from"../support/gr.mjs"
|
||||||
import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs"
|
import as UnicodeKnowledge from"../meta/unicode-knowledge.mjs"
|
||||||
|
|
||||||
extern Set
|
extern Set
|
||||||
|
@ -7,227 +7,231 @@ extern Set
|
||||||
define-operator "~>" 880 'right' : syntax-rules
|
define-operator "~>" 880 'right' : syntax-rules
|
||||||
`(@l ~> @r) `{.left @l .right @r}
|
`(@l ~> @r) `{.left @l .right @r}
|
||||||
|
|
||||||
|
define-macro Ccmp-Group : syntax-rules
|
||||||
|
`[Ccmp-Group @description @body]
|
||||||
|
dirty `[$ExecCcmpGroup$ [function [export-lookup chain-rule] @[formOf body]]]
|
||||||
|
|
||||||
export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
export : define [buildCCMP sink glyphStore markGlyphs] : begin
|
||||||
local anyMark : Array.from markGlyphs.all
|
local anyMark : Array.from markGlyphs.all
|
||||||
local aboveMark : filterMarkByClass markGlyphs 'above'
|
local aboveMark : filterMarkByClass markGlyphs 'above'
|
||||||
|
|
||||||
local rec : BeginLookupBlock sink
|
|
||||||
|
|
||||||
define ccmp : AddFeature sink 'ccmp'
|
define ccmp : AddFeature sink 'ccmp'
|
||||||
define {chain-rule} : ChainRuleBuilder sink
|
|
||||||
|
|
||||||
define groupGrekUpperTonos {}
|
|
||||||
define groupLF {}
|
|
||||||
define dotlessFrom {}
|
|
||||||
define dotlessTo {}
|
|
||||||
define TieMarkFrom {}
|
|
||||||
define TieMarkTo {}
|
|
||||||
define TieGlyphs {}
|
|
||||||
|
|
||||||
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== "."): begin
|
|
||||||
if g.baseAnchors.lf : groupLF.push gid
|
|
||||||
if g.baseAnchors.grekUpperTonos : groupGrekUpperTonos.push gid
|
|
||||||
if [Dotless.get g] : begin
|
|
||||||
dotlessFrom.push gid
|
|
||||||
dotlessTo.push [Dotless.get g]
|
|
||||||
if [TieGlyph.get g] : TieGlyphs.push gid
|
|
||||||
if [TieMark.get g] : begin
|
|
||||||
TieMarkFrom.push gid
|
|
||||||
TieMarkTo.push [TieMark.get g]
|
|
||||||
|
|
||||||
define [IotaLF] : UkMapToLookup UnicodeKnowledge.iotaBelowToLfTf
|
|
||||||
define [GrekUpperTonosTf] : UkMapToLookup UnicodeKnowledge.upperGrekMarkToTonosTf
|
|
||||||
|
|
||||||
define [ToneToToneStart toneEnd] : begin
|
|
||||||
local f {}
|
|
||||||
local e {}
|
|
||||||
foreach toneStart [range 4 downtill 0] : begin
|
|
||||||
f.push ('tone' + toneStart)
|
|
||||||
e.push ('toneStart' + toneStart + toneEnd)
|
|
||||||
return (f ~> e)
|
|
||||||
|
|
||||||
define [ToneToToneEnd toneStart] : begin
|
|
||||||
local f {}
|
|
||||||
local e {}
|
|
||||||
foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('tone' + toneEnd)
|
|
||||||
e.push ('toneEnd' + toneStart + toneEnd)
|
|
||||||
return (f ~> e)
|
|
||||||
|
|
||||||
define [ToneStartOrMidAt y]: begin
|
|
||||||
local f {}
|
|
||||||
foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneStart' + y + toneEnd)
|
|
||||||
foreach toneStart [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneMid' + toneStart + y + toneEnd)
|
|
||||||
return f
|
|
||||||
|
|
||||||
define [ToneStartToToneMid toneStart] : begin
|
|
||||||
local f {}
|
|
||||||
local e {}
|
|
||||||
foreach toneMid [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneStart' + toneMid + toneEnd)
|
|
||||||
e.push ('toneMid' + toneStart + toneMid + toneEnd)
|
|
||||||
return (f ~> e)
|
|
||||||
|
|
||||||
define [ToneSandhiToToneStart toneEnd] : begin
|
|
||||||
local f {}
|
|
||||||
local e {}
|
|
||||||
foreach toneStart [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneSandhi' + toneStart)
|
|
||||||
e.push ('toneSandhiStart' + toneStart + toneEnd)
|
|
||||||
return (f ~> e)
|
|
||||||
|
|
||||||
define [ToneSandhiToToneEnd toneStart] : begin
|
|
||||||
local f {}
|
|
||||||
local e {}
|
|
||||||
foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneSandhi' + toneEnd)
|
|
||||||
e.push ('toneSandhiEnd' + toneStart + toneEnd)
|
|
||||||
return (f ~> e)
|
|
||||||
|
|
||||||
define [ToneSandhiStartOrMidAt y]: begin
|
|
||||||
local f {}
|
|
||||||
foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneSandhiStart' + y + toneEnd)
|
|
||||||
foreach toneStart [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneSandhiMid' + toneStart + y + toneEnd)
|
|
||||||
return f
|
|
||||||
|
|
||||||
define [ToneSandhiStartToToneMid toneStart] : begin
|
|
||||||
local f {}
|
|
||||||
local e {}
|
|
||||||
foreach toneMid [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
|
||||||
f.push ('toneSandhiStart' + toneMid + toneEnd)
|
|
||||||
e.push ('toneSandhiMid' + toneStart + toneMid + toneEnd)
|
|
||||||
return (f ~> e)
|
|
||||||
|
|
||||||
# Dot removal
|
|
||||||
define lookupMarks1 : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.ignoreGlyphs [filterMarkByClassNegated markGlyphs 'above']
|
|
||||||
.rules : list
|
|
||||||
chain-rule (dotlessFrom ~> dotlessTo) (aboveMark ~> null)
|
|
||||||
|
|
||||||
# Iota transform (max 6 middle marks are supported)
|
|
||||||
define lookupMarks2 : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.ignoreGlyphs [filterMarkByClassNegated markGlyphs 'below']
|
|
||||||
.rules : list
|
|
||||||
chain-rule groupLF [IotaLF]
|
|
||||||
|
|
||||||
define lookupMarks3 : AddLookup sink : object
|
|
||||||
.type 'gsub_ligature'
|
|
||||||
.substitutions : UkMap2ToLookup UnicodeKnowledge.markCompositionTf
|
|
||||||
|
|
||||||
define lookupMarks4 : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule groupGrekUpperTonos [GrekUpperTonosTf]
|
|
||||||
|
|
||||||
define lookupMarks5 : AddLookup sink : object
|
|
||||||
.type 'gsub_multiple'
|
|
||||||
.substitutions : object
|
|
||||||
'braceAbove' { 'leftParenAbove' 'rightParenAbove' }
|
|
||||||
'parenAbove' { 'leftBrackAbove' 'rightBrackAbove' }
|
|
||||||
'parenBelow' { 'leftParenBelow' 'rightParenBelow' }
|
|
||||||
|
|
||||||
define lookupCcmp-TieMarkLigature : AddLookup sink : object
|
|
||||||
.type 'gsub_ligature'
|
|
||||||
.substitutions : {}.concat
|
|
||||||
TieMarkFrom.map : lambda [gnFrom idx]
|
|
||||||
object [from {'cgj' gnFrom}] [to TieMarkTo.(idx)]
|
|
||||||
|
|
||||||
define lookupTieMarkContextual : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list : object
|
|
||||||
match {[TieGlyphs.concat TieMarkTo] {'cgj'} TieMarkFrom}
|
|
||||||
inputBegins 1
|
|
||||||
inputEnds 3
|
|
||||||
apply {{.at 1 .lookup lookupCcmp-TieMarkLigature}}
|
|
||||||
|
|
||||||
define lookupToneStart : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule [ToneToToneStart 0] {'tone0'}
|
|
||||||
chain-rule [ToneToToneStart 1] {'tone1'}
|
|
||||||
chain-rule [ToneToToneStart 2] {'tone2'}
|
|
||||||
chain-rule [ToneToToneStart 3] {'tone3'}
|
|
||||||
chain-rule [ToneToToneStart 4] {'tone4'}
|
|
||||||
|
|
||||||
define lookupToneMid : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule [ToneStartOrMidAt 0] [ToneStartToToneMid 0]
|
|
||||||
chain-rule [ToneStartOrMidAt 1] [ToneStartToToneMid 1]
|
|
||||||
chain-rule [ToneStartOrMidAt 2] [ToneStartToToneMid 2]
|
|
||||||
chain-rule [ToneStartOrMidAt 3] [ToneStartToToneMid 3]
|
|
||||||
chain-rule [ToneStartOrMidAt 4] [ToneStartToToneMid 4]
|
|
||||||
|
|
||||||
define lookupToneEnd : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule [ToneStartOrMidAt 0] [ToneToToneEnd 0]
|
|
||||||
chain-rule [ToneStartOrMidAt 1] [ToneToToneEnd 1]
|
|
||||||
chain-rule [ToneStartOrMidAt 2] [ToneToToneEnd 2]
|
|
||||||
chain-rule [ToneStartOrMidAt 3] [ToneToToneEnd 3]
|
|
||||||
chain-rule [ToneStartOrMidAt 4] [ToneToToneEnd 4]
|
|
||||||
|
|
||||||
define lookupToneSandhiStart : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule [ToneSandhiToToneStart 0] {'toneSandhi0'}
|
|
||||||
chain-rule [ToneSandhiToToneStart 1] {'toneSandhi1'}
|
|
||||||
chain-rule [ToneSandhiToToneStart 2] {'toneSandhi2'}
|
|
||||||
chain-rule [ToneSandhiToToneStart 3] {'toneSandhi3'}
|
|
||||||
chain-rule [ToneSandhiToToneStart 4] {'toneSandhi4'}
|
|
||||||
|
|
||||||
define lookupToneSandhiMid : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 0] [ToneSandhiStartToToneMid 0]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 1] [ToneSandhiStartToToneMid 1]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 2] [ToneSandhiStartToToneMid 2]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 3] [ToneSandhiStartToToneMid 3]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 4] [ToneSandhiStartToToneMid 4]
|
|
||||||
|
|
||||||
define lookupToneSandhiEnd : AddLookup sink : object
|
|
||||||
.type 'gsub_chaining'
|
|
||||||
.rules : list
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 0] [ToneSandhiToToneEnd 0]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 1] [ToneSandhiToToneEnd 1]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 2] [ToneSandhiToToneEnd 2]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 3] [ToneSandhiToToneEnd 3]
|
|
||||||
chain-rule [ToneSandhiStartOrMidAt 4] [ToneSandhiToToneEnd 4]
|
|
||||||
|
|
||||||
|
|
||||||
ccmp.lookups.push lookupMarks1 lookupMarks2 lookupMarks3 lookupMarks4 lookupMarks5 lookupTieMarkContextual
|
|
||||||
sink.lookupDep.push {lookupMarks1 lookupMarks2}
|
|
||||||
sink.lookupDep.push {lookupMarks2 lookupMarks3}
|
|
||||||
sink.lookupDep.push {lookupMarks3 lookupMarks4}
|
|
||||||
sink.lookupDep.push {lookupMarks4 lookupMarks5}
|
|
||||||
sink.lookupDep.push {lookupMarks5 lookupTieMarkContextual}
|
|
||||||
ccmp.lookups.push lookupToneStart lookupToneMid lookupToneEnd
|
|
||||||
sink.lookupDep.push {lookupToneStart lookupToneMid}
|
|
||||||
sink.lookupDep.push {lookupToneMid lookupToneEnd}
|
|
||||||
ccmp.lookups.push lookupToneSandhiStart lookupToneSandhiMid lookupToneSandhiEnd
|
|
||||||
sink.lookupDep.push {lookupToneSandhiStart lookupToneSandhiMid}
|
|
||||||
sink.lookupDep.push {lookupToneSandhiMid lookupToneSandhiEnd}
|
|
||||||
|
|
||||||
# CCMP decomposition
|
|
||||||
define decompositions {.}
|
|
||||||
foreach { gid g } [glyphStore.namedEntries] : begin
|
|
||||||
local parts : CcmpDecompose.get g
|
|
||||||
if (parts && parts.length) : set decompositions.(gid) parts
|
|
||||||
|
|
||||||
if [objectIsNotEmpty decompositions] : begin
|
|
||||||
define lookupCcmp-Decompose : AddLookup sink : object
|
|
||||||
.type 'gsub_multiple'
|
|
||||||
.substitutions decompositions
|
|
||||||
AddFeatureLookup ccmp lookupCcmp-Decompose
|
|
||||||
|
|
||||||
AddCommonFeature sink ccmp
|
AddCommonFeature sink ccmp
|
||||||
EndLookupBlock rec sink
|
|
||||||
|
define [$ExecCcmpGroup$ fn] : begin
|
||||||
|
local addedLookups {}
|
||||||
|
define [export-lookup lookupName] : begin
|
||||||
|
ccmp.lookups.push lookupName
|
||||||
|
addedLookups.push lookupName
|
||||||
|
|
||||||
|
|
||||||
|
local rec : BeginLookupBlock sink
|
||||||
|
define {chain-rule} : ChainRuleBuilder sink
|
||||||
|
|
||||||
|
fn export-lookup chain-rule
|
||||||
|
|
||||||
|
for [local j 1] (j < addedLookups.length) [inc j] : begin
|
||||||
|
sink.lookupDep.push {addedLookups.(j - 1) addedLookups.(j)}
|
||||||
|
|
||||||
|
EndLookupBlock rec sink
|
||||||
|
|
||||||
|
Ccmp-Group "Mark transforms" : begin
|
||||||
|
|
||||||
|
define groupGrekUpperTonos {}
|
||||||
|
define groupLF {}
|
||||||
|
define dotlessFrom {}
|
||||||
|
define dotlessTo {}
|
||||||
|
define TieMarkFrom {}
|
||||||
|
define TieMarkTo {}
|
||||||
|
define TieGlyphs {}
|
||||||
|
|
||||||
|
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== "."): begin
|
||||||
|
if g.baseAnchors.lf : groupLF.push gid
|
||||||
|
if g.baseAnchors.grekUpperTonos : groupGrekUpperTonos.push gid
|
||||||
|
if [Dotless.get g] : begin
|
||||||
|
dotlessFrom.push gid
|
||||||
|
dotlessTo.push [Dotless.get g]
|
||||||
|
if [TieGlyph.get g] : TieGlyphs.push gid
|
||||||
|
if [TieMark.get g] : begin
|
||||||
|
TieMarkFrom.push gid
|
||||||
|
TieMarkTo.push [TieMark.get g]
|
||||||
|
|
||||||
|
define [IotaLF] : UkMapToLookup UnicodeKnowledge.iotaBelowToLfTf
|
||||||
|
define [GrekUpperTonosTf] : UkMapToLookup UnicodeKnowledge.upperGrekMarkToTonosTf
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.ignoreGlyphs [filterMarkByClassNegated markGlyphs 'above']
|
||||||
|
.rules : list
|
||||||
|
chain-rule (dotlessFrom ~> dotlessTo) (aboveMark ~> null)
|
||||||
|
chain-rule groupGrekUpperTonos [GrekUpperTonosTf]
|
||||||
|
|
||||||
|
# Iota transform (max 6 middle marks are supported)
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.ignoreGlyphs [filterMarkByClassNegated markGlyphs 'below']
|
||||||
|
.rules : list
|
||||||
|
chain-rule groupLF [IotaLF]
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_ligature'
|
||||||
|
.substitutions : UkMap2ToLookup UnicodeKnowledge.markCompositionTf
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_multiple'
|
||||||
|
.substitutions : object
|
||||||
|
'braceAbove' { 'leftParenAbove' 'rightParenAbove' }
|
||||||
|
'parenAbove' { 'leftBrackAbove' 'rightBrackAbove' }
|
||||||
|
'parenBelow' { 'leftParenBelow' 'rightParenBelow' }
|
||||||
|
|
||||||
|
# Tie marks
|
||||||
|
define lookupTieMarkLigature : AddLookup sink : object
|
||||||
|
.type 'gsub_ligature'
|
||||||
|
.substitutions : {}.concat
|
||||||
|
TieMarkFrom.map : lambda [gnFrom idx]
|
||||||
|
object [from {'cgj' gnFrom}] [to TieMarkTo.(idx)]
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list : object
|
||||||
|
match {[TieGlyphs.concat TieMarkTo] {'cgj'} TieMarkFrom}
|
||||||
|
inputBegins 1
|
||||||
|
inputEnds 3
|
||||||
|
apply {{.at 1 .lookup lookupTieMarkLigature}}
|
||||||
|
|
||||||
|
Ccmp-Group "Rhotic Hook Transform" : begin
|
||||||
|
define superscripts {}
|
||||||
|
define subscripts {}
|
||||||
|
|
||||||
|
foreach { gid g } [glyphStore.namedEntries] : if (gid.(0) !== "."): begin
|
||||||
|
if [IsSuperscript.get g] : superscripts.push gid
|
||||||
|
if [IsSubscript.get g] : subscripts.push gid
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.ignoreGlyphs anyMark
|
||||||
|
.rules : list
|
||||||
|
chain-rule superscripts ({"rhoticHook"} ~> {"rhoticHook/sup"})
|
||||||
|
chain-rule subscripts ({"rhoticHook"} ~> {"rhoticHook/sub"})
|
||||||
|
|
||||||
|
Ccmp-Group "Tone Transform" : begin
|
||||||
|
define [ToneToToneStart toneEnd] : begin
|
||||||
|
local f {}
|
||||||
|
local e {}
|
||||||
|
foreach toneStart [range 4 downtill 0] : begin
|
||||||
|
f.push ('tone' + toneStart)
|
||||||
|
e.push ('toneStart' + toneStart + toneEnd)
|
||||||
|
return (f ~> e)
|
||||||
|
|
||||||
|
define [ToneToToneEnd toneStart] : begin
|
||||||
|
local f {}
|
||||||
|
local e {}
|
||||||
|
foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('tone' + toneEnd)
|
||||||
|
e.push ('toneEnd' + toneStart + toneEnd)
|
||||||
|
return (f ~> e)
|
||||||
|
|
||||||
|
define [ToneStartOrMidAt y]: begin
|
||||||
|
local f {}
|
||||||
|
foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneStart' + y + toneEnd)
|
||||||
|
foreach toneStart [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneMid' + toneStart + y + toneEnd)
|
||||||
|
return f
|
||||||
|
|
||||||
|
define [ToneStartToToneMid toneStart] : begin
|
||||||
|
local f {}
|
||||||
|
local e {}
|
||||||
|
foreach toneMid [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneStart' + toneMid + toneEnd)
|
||||||
|
e.push ('toneMid' + toneStart + toneMid + toneEnd)
|
||||||
|
return (f ~> e)
|
||||||
|
|
||||||
|
define [ToneSandhiToToneStart toneEnd] : begin
|
||||||
|
local f {}
|
||||||
|
local e {}
|
||||||
|
foreach toneStart [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneSandhi' + toneStart)
|
||||||
|
e.push ('toneSandhiStart' + toneStart + toneEnd)
|
||||||
|
return (f ~> e)
|
||||||
|
|
||||||
|
define [ToneSandhiToToneEnd toneStart] : begin
|
||||||
|
local f {}
|
||||||
|
local e {}
|
||||||
|
foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneSandhi' + toneEnd)
|
||||||
|
e.push ('toneSandhiEnd' + toneStart + toneEnd)
|
||||||
|
return (f ~> e)
|
||||||
|
|
||||||
|
define [ToneSandhiStartOrMidAt y]: begin
|
||||||
|
local f {}
|
||||||
|
foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneSandhiStart' + y + toneEnd)
|
||||||
|
foreach toneStart [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneSandhiMid' + toneStart + y + toneEnd)
|
||||||
|
return f
|
||||||
|
|
||||||
|
define [ToneSandhiStartToToneMid toneStart] : begin
|
||||||
|
local f {}
|
||||||
|
local e {}
|
||||||
|
foreach toneMid [range 4 downtill 0] : foreach toneEnd [range 4 downtill 0] : begin
|
||||||
|
f.push ('toneSandhiStart' + toneMid + toneEnd)
|
||||||
|
e.push ('toneSandhiMid' + toneStart + toneMid + toneEnd)
|
||||||
|
return (f ~> e)
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list
|
||||||
|
chain-rule [ToneToToneStart 0] {'tone0'}
|
||||||
|
chain-rule [ToneToToneStart 1] {'tone1'}
|
||||||
|
chain-rule [ToneToToneStart 2] {'tone2'}
|
||||||
|
chain-rule [ToneToToneStart 3] {'tone3'}
|
||||||
|
chain-rule [ToneToToneStart 4] {'tone4'}
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list
|
||||||
|
chain-rule [ToneStartOrMidAt 0] [ToneStartToToneMid 0]
|
||||||
|
chain-rule [ToneStartOrMidAt 1] [ToneStartToToneMid 1]
|
||||||
|
chain-rule [ToneStartOrMidAt 2] [ToneStartToToneMid 2]
|
||||||
|
chain-rule [ToneStartOrMidAt 3] [ToneStartToToneMid 3]
|
||||||
|
chain-rule [ToneStartOrMidAt 4] [ToneStartToToneMid 4]
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list
|
||||||
|
chain-rule [ToneStartOrMidAt 0] [ToneToToneEnd 0]
|
||||||
|
chain-rule [ToneStartOrMidAt 1] [ToneToToneEnd 1]
|
||||||
|
chain-rule [ToneStartOrMidAt 2] [ToneToToneEnd 2]
|
||||||
|
chain-rule [ToneStartOrMidAt 3] [ToneToToneEnd 3]
|
||||||
|
chain-rule [ToneStartOrMidAt 4] [ToneToToneEnd 4]
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list
|
||||||
|
chain-rule [ToneSandhiToToneStart 0] {'toneSandhi0'}
|
||||||
|
chain-rule [ToneSandhiToToneStart 1] {'toneSandhi1'}
|
||||||
|
chain-rule [ToneSandhiToToneStart 2] {'toneSandhi2'}
|
||||||
|
chain-rule [ToneSandhiToToneStart 3] {'toneSandhi3'}
|
||||||
|
chain-rule [ToneSandhiToToneStart 4] {'toneSandhi4'}
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 0] [ToneSandhiStartToToneMid 0]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 1] [ToneSandhiStartToToneMid 1]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 2] [ToneSandhiStartToToneMid 2]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 3] [ToneSandhiStartToToneMid 3]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 4] [ToneSandhiStartToToneMid 4]
|
||||||
|
|
||||||
|
export-lookup : AddLookup sink : object
|
||||||
|
.type 'gsub_chaining'
|
||||||
|
.rules : list
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 0] [ToneSandhiToToneEnd 0]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 1] [ToneSandhiToToneEnd 1]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 2] [ToneSandhiToToneEnd 2]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 3] [ToneSandhiToToneEnd 3]
|
||||||
|
chain-rule [ToneSandhiStartOrMidAt 4] [ToneSandhiToToneEnd 4]
|
||||||
|
|
||||||
return ccmp
|
return ccmp
|
||||||
|
|
||||||
|
|
|
@ -47,7 +47,6 @@ function OtlTaggedProp(key, otlTag) {
|
||||||
|
|
||||||
export const CvDecompose = DecompositionProp("CvDecompose");
|
export const CvDecompose = DecompositionProp("CvDecompose");
|
||||||
export const PseudoCvDecompose = DecompositionProp("PseudoCvDecompose");
|
export const PseudoCvDecompose = DecompositionProp("PseudoCvDecompose");
|
||||||
export const CcmpDecompose = DecompositionProp("CcmpDecompose");
|
|
||||||
function DecompositionProp(key) {
|
function DecompositionProp(key) {
|
||||||
return {
|
return {
|
||||||
get(glyph) {
|
get(glyph) {
|
||||||
|
@ -106,9 +105,10 @@ function BoolProp(id) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
export const Radical = BoolProp("Radical");
|
export const Radical = BoolProp("Radical");
|
||||||
export const RequireCcmpDecompose = BoolProp("RequireCcmpDecompose");
|
|
||||||
export const NeqLigationSlashDotted = BoolProp("NeqLigationSlashDotted");
|
export const NeqLigationSlashDotted = BoolProp("NeqLigationSlashDotted");
|
||||||
export const OgonekTrY = BoolProp("OgonekTrY");
|
export const OgonekTrY = BoolProp("OgonekTrY");
|
||||||
|
export const IsSuperscript = BoolProp("IsSuperscript");
|
||||||
|
export const IsSubscript = BoolProp("IsSubscript");
|
||||||
|
|
||||||
export const Joining = {
|
export const Joining = {
|
||||||
get(glyph) {
|
get(glyph) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue