Iosevka/font-src/otl/gsub-ligation.ptl
be5invis 153cf38e85 * Improve T's metrics for Etoile (#1449).
* Fix custom build of ligations when `ineq` is disabled but `ltgt-diamond-tag` or `ltgt-slash-tag` are enabled (#1450).
2022-11-24 16:42:50 -08:00

1044 lines
34 KiB
Text

import [AddCommonFeature AddFeature ChainRuleBuilder BeginLookupBlock EndLookupBlock] from"./table-util.mjs"
extern Set
define-operator "~>" 880 'right' : syntax-rules
`(@l ~> @r) `{.left @l .right @r}
define [lsx s] : lambda [t] : t.map : lambda [x] "\(x).lig.\(s)"
define [csx s] : lambda [t] : t.map : lambda [x] "\(x).\(s)"
define [just s] : lambda [t] : t.map : lambda [x] s
define look-around null
define advance : lambda [t] null
define ident : lambda [t] : t.map : lambda [x] x
export : define [buildLigations sink para plm] : begin
local rec : BeginLookupBlock sink
local rankedLookups {}
foreach [ {featureName mappedFeature} : pairs-of plm] : begin
buildLigationsImpl sink para featureName mappedFeature rankedLookups
EndLookupBlock rec sink
define [buildLigationsImpl sink para featureName mappedFeature rankedLookups] : begin
define {chain-rule reverse-rule} : ChainRuleBuilder sink
define arrowStick {'hyphen' 'equal'}
define [stickClass style] : [lsx style] {'hyphen' 'equal'}
define [stickTf style] : {'hyphen' 'equal'} ~> [lsx style]
define anyWave {'asciiTilde' 'asciiTilde.low' 'asciiTilde.high'}
define [waveClass cl] : [just ('wave.lig.' + cl)] anyWave
define [waveTf cl] : anyWave ~> [waveClass cl]
define less {'less'}
define lessAndEquiv {'less' 'less.lig.shift0' 'less.lig.shift0.anti'}
define hyphen {'hyphen'}
define equal {'equal'}
define anyStraightRod { 'hyphen' 'equal' }
define exclam {'exclam'}
define greater {'greater'}
define greaterAndEquiv {'greater' 'greater.lig.shift0' 'greater.lig.shift0.anti'}
define lessOrGreater : {}.concat less greater
define lessOrGreaterAndEquiv : {}.concat lessAndEquiv greaterAndEquiv
define anyBar {'bar' 'slash' 'backslash'}
define slash {'slash'}
define backslash {'backslash'}
define bar {'bar'}
define underscore {'underscore'}
define regexLookAround [less.concat hyphen equal exclam greater anyBar]
define [acops] : if [hasLG 'bar-triggers-op-centering']
begin {'less' 'greater' 'hyphen' 'equal' 'plus' 'slash' 'bar' 'backslash'}
begin {'less' 'greater' 'hyphen' 'equal' 'plus'}
define [acskip] : if [hasLG 'bar-triggers-op-centering']
begin {'at' 'ampersand' 'percent' 'numberSign'}
begin {'slash' 'bar' 'backslash' 'at' 'ampersand' 'percent' 'numberSign'}
local ligationLookupName : 'lig_' + featureName + '{' + mappedFeature + '}'
define [hasLG ln] : [mappedFeature.indexOf ln] >= 0
define feature : AddCommonFeature sink : AddFeature sink featureName
local lastLookupName null
local lookupRank 0
local [dedup ln0 rank obj] : begin
local h : JSON.stringify obj
foreach [{name lookup} : items-of rankedLookups.(rank)] : begin
local h1 : JSON.stringify lookup
if (h == h1) : return {name false}
return {ln0 true}
local [AddRankedLookup obj] : begin
if [not rankedLookups.(lookupRank)] : set rankedLookups.(lookupRank) {}
local sameRankLookupBlob rankedLookups.(lookupRank)
local {ln unique} : dedup (ligationLookupName + feature.lookups.length) lookupRank obj
if [not sink.lookups.(ln)] : set sink.lookups.(ln) obj
feature.lookups.push ln
# In-feature ordering
if lastLookupName : sink.lookupDep.push {lastLookupName ln}
set lastLookupName ln
# Cross-feature ordering
if unique : begin
if sameRankLookupBlob.length : begin
local lastSameRank (sameRankLookupBlob.(sameRankLookupBlob.length - 1).0)
if (lastSameRank != ln) : sink.lookupDep.push {lastSameRank ln}
sameRankLookupBlob.push {ln obj}
define [filterNulls _rules] : begin
if [not _rules] : return _rules
define rules {}
foreach [rule : items-of _rules] : if rule : rules.push rule
return rules
define [CreateLigationLookup _rules] : begin
define rules : filterNulls _rules
if (rules && rules.length) : AddRankedLookup
.type 'gsub_chaining'
.rules rules
set lookupRank : lookupRank + 1
define [CreateReverseLigationLookup _rules] : begin
define rules : filterNulls _rules
if (rules && rules.length) : AddRankedLookup
.type 'gsub_reverse'
.rules rules
set lookupRank : lookupRank + 1
do "Bracket-star" : if [hasLG 'brst'] : begin
CreateLigationLookup : list
chain-rule # (*
{'parenLeft'} ~> look-around
{'asterisk'} ~> {'asterisk/sMid'}
chain-rule # *)
{'asterisk'} ~> {'asterisk/sMid'}
{'parenRight'} ~> look-around
do "Operator centering" : if [hasLG 'center-ops'] : begin
define [centerAsterisk] : {'asterisk'} ~> {'asterisk/sMid'}
define [centerColon] : {'colon'} ~> {'colon/mid'}
define [centerCaret] : {'asciiCaret'} ~> {'asciiCaret.low'}
define [centerTilde] : {'asciiTilde'} ~> {'asciiTilde.low'}
define [centerPeriod] : {'period'} ~> {'period/mid'}
define [deCenterPeriod] : {'period/mid'} ~> {'period'}
define centerizeGroups : list centerAsterisk centerColon centerCaret centerTilde
if [hasLG 'dot-oper'] : centerizeGroups.push centerPeriod
define centerizeL : centerizeGroups.map : x => [x].left.0
define centerizeR : centerizeGroups.map : lambda [x] : begin
local left [x].left
local right [x].right
while (right <@ Function) : set right [right left]
return : if right (right.0 || left.0) (left.0)
define [Cg] : centerizeL ~> centerizeR
do "Bracket-colon"
CreateLigationLookup : list
chain-rule # (:
{'parenLeft' 'bracketLeft' 'braceLeft'} ~> look-around
centerColon
chain-rule # :)
centerColon
{'parenRight' 'bracketRight' 'braceRight'} ~> look-around
do "Operator Centering"
CreateLigationLookup : list
chain-rule [Cg] [Cg] [acskip] [acskip] [acops] # ::+
chain-rule [Cg] [Cg] [acskip] [acops] # ::+
chain-rule [Cg] [Cg] [acops] # ::+
chain-rule [Cg] [acskip] [acskip] [acops] # :+
chain-rule [Cg] [acskip] [acops] # :+
chain-rule [Cg] [acops] # :+
chain-rule [acops] [acskip] [acskip] [Cg] # +:
chain-rule [acops] [acskip] [Cg] # +:
chain-rule [acops] [Cg] # +:
do "Operator centering : Trailing"
CreateLigationLookup : list
chain-rule centerizeR [acskip] [acskip] [Cg]
chain-rule centerizeR [acskip] [Cg]
chain-rule centerizeR [Cg]
CreateReverseLigationLookup : list
reverse-rule [Cg] [acskip] [acskip] centerizeR
reverse-rule [Cg] [acskip] centerizeR
reverse-rule [Cg] centerizeR
do "Operator centering : Apple fix"
# Apple (still) have problem when dealing with reverse chaining lookup
# They give up at run beginning. Fix them.
CreateLigationLookup : list
chain-rule [Cg] [acskip] [acskip] centerizeR
chain-rule [Cg] [acskip] centerizeR
chain-rule [Cg] centerizeR
do "slash-asterisk" : if [hasLG 'slash-asterisk'] : begin
CreateLigationLookup : list
chain-rule # /*
{'slash'} ~> look-around
{'asterisk'} ~> [just 'asterisk/high']
chain-rule # */
{'asterisk'} ~> [just 'asterisk/low']
{'slash'} ~> look-around
CreateReverseLigationLookup : list
reverse-rule
{'asterisk'} ~> [just 'asterisk/low']
{'asterisk/low'} ~> look-around
reverse-rule
{'asterisk/high'} ~> [just 'asterisk/sMid/ligComment']
{'asterisk/low'} ~> look-around
CreateLigationLookup : list
chain-rule
{'asterisk/high'} ~> look-around
{'asterisk'} ~> {'asterisk/high'}
chain-rule
{'asterisk/sMid/ligComment'} ~> look-around
{'asterisk' 'asterisk/low'} ~> [just 'asterisk/sMid/ligComment']
do "Kern Dotty" : if [hasLG 'kern-dotty'] : begin
define dottyPunctuationSets : list
list { "period" "period/mid" } { "colon" "colon/mid" "question" "exclam" }
list { "comma" } { "semicolon" }
define dottyConnected : list
list
* 'equal'
* 'hyphen'
* 'plus'
* 'less'
* 'greater'
* 'asterisk'
* 'asciiTilde'
* 'asciiCaret'
list
* 'parenLeft'
* 'parenRight'
* 'bracketLeft'
* 'bracketRight'
* 'braceLeft'
* 'braceRight'
* 'numberSign'
* 'ampersand'
* 'slash'
* 'bar'
foreach { dpShort dpTall } [items-of dottyPunctuationSets] : begin
define dp : {}.concat dpShort dpTall
define dLeft : [lsx 'dLeft'] dp
define dRight : [lsx 'dRight'] dp
define dLeftHalf : [lsx 'dLeftHalf'] dp
define dRightHalf : [lsx 'dRightHalf'] dp
define dMid : [lsx 'dMid'] dp
CreateLigationLookup : list
chain-rule
[dRight.concat dMid] ~> look-around
dp ~> dMid
dp ~> look-around
chain-rule
[dRight.concat dMid] ~> look-around
dp ~> dLeft
chain-rule
dp ~> dRight
dp ~> look-around
foreach boundary [items-of dottyConnected] : do
define dg : if (boundary == dottyConnected.0) dp dpTall
define dgLeft : [lsx 'dLeftHalf'] dg
define dgRight : [lsx 'dRightHalf'] dg
define dgLeftHalf : [lsx 'dLeftHalf'] dg
define dgRightHalf : [lsx 'dRightHalf'] dg
define dgMid : [lsx 'dMid'] dg
CreateLigationLookup : list
chain-rule
boundary ~> look-around
dgRight ~> dgMid
dgLeft ~> dgMid
boundary ~> look-around
chain-rule
boundary ~> look-around
dgRight ~> dgMid
[dgMid.concat dgLeft] ~> look-around
chain-rule
[dgMid.concat dgRight] ~> look-around
dgLeft ~> dgMid
boundary ~> look-around
CreateLigationLookup : list
chain-rule
dRight ~> look-around
dMid ~> dRightHalf
dMid ~> dLeftHalf
dLeft ~> look-around
chain-rule
dRight ~> look-around
dMid ~> dRightHalf
dMid ~> look-around
chain-rule
dMid ~> look-around
dMid ~> dLeftHalf
dLeft ~> look-around
chain-rule
dRight ~> dRightHalf
dLeft ~> dLeftHalf
do "triangles" : if [hasLG 'trig'] : begin
CreateLigationLookup : list
chain-rule # <|
less ~> [lsx 'trig']
{'bar'} ~> [lsx 'trig']
chain-rule # |>
{'bar'} ~> [lsx 'trig']
greater ~> [lsx 'trig']
chain-rule # |>
[[lsx 'trig'] {'bar'}] ~> look-around
greater ~> [lsx 'trig']
chain-rule # <||||
[[lsx 'trig'] {'bar'}] ~> look-around
{'bar'} ~> [lsx 'trig']
CreateReverseLigationLookup : list
reverse-rule
{'bar'} ~> [[lsx 'trig'] {'bar'}]
[[lsx 'trig'] {'bar'}] ~> look-around
# Apple fix
CreateLigationLookup : list
chain-rule
{'bar'} ~> [[lsx 'trig'] {'bar'}]
[[lsx 'trig'] {'bar'}] ~> look-around
do "shift-eq operators (<<= and >>=)" : if [hasLG 'llggeq'] : begin
CreateLigationLookup : list
chain-rule # =<<<=
equal ~> look-around
less ~> advance
less ~> advance
less ~> advance
equal ~> look-around
chain-rule # <<<==
less ~> advance
less ~> advance
less ~> advance
equal ~> look-around
equal ~> look-around
chain-rule # <<<=
less ~> [lsx 'shiftN0h']
less ~> look-around
less ~> [lsx 'shift0h']
equal ~> look-around
chain-rule # =>>>=
equal ~> look-around
greater ~> advance
greater ~> advance
greater ~> advance
equal ~> look-around
chain-rule # >>>==
greater ~> advance
greater ~> advance
greater ~> advance
equal ~> look-around
equal ~> look-around
chain-rule # >>>=
greater ~> [lsx 'shift0h']
greater ~> look-around
greater ~> [lsx 'shiftN0h']
equal ~> look-around
chain-rule # =<<=
equal ~> look-around
less ~> advance
less ~> advance
equal ~> look-around
chain-rule # <<==
less ~> advance
less ~> advance
equal ~> look-around
equal ~> look-around
chain-rule # <<=
less ~> [lsx 'shiftN0h']
less ~> [lsx 'shift0h']
equal ~> look-around
chain-rule # =>>=
equal ~> look-around
greater ~> advance
greater ~> advance
equal ~> look-around
chain-rule # >>==
greater ~> advance
greater ~> advance
equal ~> look-around
equal ~> look-around
chain-rule # >>=
greater ~> [lsx 'shift0h']
greater ~> [lsx 'shiftN0h']
equal ~> look-around
do "HTML Comment" : if [hasLG 'html-comment'] : begin
CreateLigationLookup : list
chain-rule # <!---
less ~> look-around
exclam ~> [lsx 'htmlcommentstart']
hyphen ~> [lsx 'lxc']
hyphen ~> [lsx 'cc']
hyphen ~> [lsx 'cf']
chain-rule # <!--
less ~> look-around
exclam ~> [lsx 'htmlcommentstart']
hyphen ~> [lsx 'lxc']
hyphen ~> [lsx 'cf']
do "Arrows" : if [hasLG 'arrow'] : begin
define singular : hyphen.concat anyWave
define [CBarSingular k] : begin
local hyphenSet : new Set hyphen
local fHyphen : lsx k
local fWave : just "wave.lig.\(k)"
return : lambda [t] : begin
local hyphenResults : fHyphen t
local waveResults : fWave t
return : t.map : lambda [x j]
if [hyphenSet.has x] hyphenResults.(j) waveResults.(j)
define ArrowFormationConfig : list
# rod dbl ltgt FBarCls
list equal 1 1 lsx
list singular 0 0 CBarSingular
define ArrowExtensionConfig : list
# rod FBarCls
list equal lsx
list hyphen lsx
list anyWave [lambda [k] [just "wave.lig.\(k)"]]
foreach [{rodCls dbl ltgt CRod} : items-of ArrowFormationConfig] : do
define heads {}
define rods {}
# Disable regular expression lookaheads
heads.push : chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
heads.push : chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
heads.push : chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
define [CJoinHeadForce] : if dbl [lsx 'dblhead'] [lsx 'shift0.head']
define [CJoinHeadMid] : if dbl [lsx 'dblhead.mid'] [lsx 'shift0.mid']
define [CJoinHeadForceShift1] : if dbl [lsx 'dblhead.shift1'] [lsx 'shift1.head']
define [CAntiHeadForce] : if dbl [lsx 'hole'] [lsx 'shift0.anti']
define [CAntiHeadForceShiftN1] : if dbl [lsx 'hole.shiftN1'] [lsx 'shiftN1.anti']
define [TJoinHeadForce] : if [hasLG 'arrow'] [CJoinHeadForce] advance
define [TJoinHeadAmbig] : if [not ltgt] [TJoinHeadForce] advance
define [TJoinHeadForceShift1] : if [hasLG 'arrow'] [CJoinHeadForceShift1] advance
define [TMiddleHead] : if [hasLG 'arrow2'] [CJoinHeadMid] [TJoinHeadForce]
define [TAntiHeadForce] : if [hasLG 'arrow2'] [CAntiHeadForce] advance
define [TAntiHeadAmbig] : if [not ltgt] [TAntiHeadForce] advance
define [TAntiHeadForceShiftN1] : if [hasLG 'arrow2'] [CAntiHeadForceShiftN1] advance
define [CollectApply ck fns] : begin
local a : new Set
foreach [fnT : items-of fns] : begin
define fn [fnT]
define transformed : if fn [fn ck] ck
foreach [g : items-of transformed] : begin
a.add g
return : Array.from a
local arrowIndicator : anyBar.concat : CollectApply [less.concat greater] : list [lambda [] ident] CJoinHeadForce CJoinHeadForceShift1 CAntiHeadForce CAntiHeadForceShiftN1 CJoinHeadMid
# Arrow head identifier
begin "Central"
heads.push : chain-rule # = > > =
rodCls ~> look-around
greater ~> [TJoinHeadForceShift1]
greater ~> [TAntiHeadForce]
rodCls ~> look-around
heads.push : chain-rule # = < < =
rodCls ~> look-around
less ~> [TAntiHeadForce]
less ~> [TJoinHeadForceShift1]
rodCls ~> look-around
heads.push : chain-rule # = > < =
rodCls ~> look-around
greater ~> [TJoinHeadForce]
less ~> [TJoinHeadForce]
rodCls ~> look-around
heads.push : chain-rule # = < > =
rodCls ~> look-around
less ~> [TAntiHeadForce]
greater ~> [TAntiHeadForce]
rodCls ~> look-around
heads.push : chain-rule # = > =
rodCls ~> look-around
greater ~> [TMiddleHead]
rodCls ~> look-around
heads.push : chain-rule # = < =
rodCls ~> look-around
less ~> [TMiddleHead]
rodCls ~> look-around
begin "Boundary"
heads.push : chain-rule # = > >
rodCls ~> look-around
greater ~> [TJoinHeadForceShift1]
greater ~> look-around
heads.push : chain-rule # = < <
rodCls ~> look-around
less ~> [TAntiHeadForceShiftN1]
less ~> look-around
heads.push : chain-rule # > > =
greater ~> look-around
greater ~> [TAntiHeadForceShiftN1]
rodCls ~> look-around
heads.push : chain-rule # < < =
less ~> look-around
less ~> [TJoinHeadForceShift1]
rodCls ~> look-around
heads.push : chain-rule # = = >
rodCls ~> look-around
rodCls ~> look-around
greater ~> [TJoinHeadForce]
heads.push : chain-rule # = = <
rodCls ~> look-around
rodCls ~> look-around
less ~> [TAntiHeadForce]
heads.push : chain-rule # > = =
greater ~> [TAntiHeadForce]
rodCls ~> look-around
rodCls ~> look-around
heads.push : chain-rule # < = =
less ~> [TJoinHeadForce]
rodCls ~> look-around
rodCls ~> look-around
heads.push : chain-rule # * = >
arrowIndicator ~> look-around
rodCls ~> look-around
greater ~> [TJoinHeadForce]
heads.push : chain-rule # * = <
arrowIndicator ~> look-around
rodCls ~> look-around
less ~> [TAntiHeadForce]
heads.push : chain-rule # > = *
greater ~> [TAntiHeadForce]
rodCls ~> look-around
arrowIndicator ~> look-around
heads.push : chain-rule # < = *
less ~> [TJoinHeadForce]
rodCls ~> look-around
arrowIndicator ~> look-around
begin "Ambiguous"
heads.push : chain-rule # = >
rodCls ~> look-around
greater ~> [TJoinHeadAmbig]
heads.push : chain-rule # = <
rodCls ~> look-around
less ~> [TAntiHeadAmbig]
heads.push : chain-rule # > =
greater ~> [TAntiHeadAmbig]
rodCls ~> look-around
heads.push : chain-rule # < =
less ~> [TJoinHeadAmbig]
rodCls ~> look-around
# Rod transformer
define kindLeftMid : list
list false 'l' : CollectApply less : list CJoinHeadForce CJoinHeadMid
list false 'l1' : CollectApply less : list CJoinHeadForceShift1
list false 'j' : CollectApply greater : list CAntiHeadForce CJoinHeadMid
list true 'm' anyBar
list false 'j1' : CollectApply greater : list CAntiHeadForceShiftN1
define kindRightMid : list
list false 'r' : CollectApply greater : list CJoinHeadForce CJoinHeadMid
list false 'r1' : CollectApply greater : list CJoinHeadForceShift1
list false 'j' : CollectApply less : list CAntiHeadForce CJoinHeadMid
list true 'm' anyBar
list false 'j1' : CollectApply less : list CAntiHeadForceShiftN1
# console.log featureName rodCls kindLeftMid kindRightMid
foreach [{ lBar kl envL } : items-of kindLeftMid] : begin
foreach [{ rBar kr envR } : items-of kindRightMid] : begin
if (!lBar || !rBar) : begin
rods.push : chain-rule # < - >
envL ~> look-around
rodCls ~> [CRod "\(kl)\(kr)"]
envR ~> look-around
foreach [{ lBar kl envL } : items-of kindLeftMid] : begin
if (!lBar) : begin
rods.push : chain-rule # < -
envL ~> look-around
rodCls ~> [CRod "\(kl)f"]
foreach [{ rBar kr envR } : items-of kindRightMid] : begin
if (!rBar) : begin
rods.push : chain-rule # - >
rodCls ~> [CRod "f\(kr)"]
envR ~> look-around
CreateLigationLookup heads
CreateLigationLookup rods
foreach [{rodCls CRod} : items-of ArrowExtensionConfig] : do "Extended arrow sticks"
# Extension
local rodTermLeft {}
local rodConnLeft {}
foreach [lc : items-of {'l' 'l1' 'j' 'j1' 'c' 'z' 'm'}] : begin
set rodTermLeft : rodTermLeft.concat : [CRod "\(lc)f"] rodCls
set rodConnLeft : rodConnLeft.concat : [CRod "\(lc)c"] rodCls
local rodTermRight {}
local rodConnRight {}
foreach [rc : items-of {'r' 'r1' 'j' 'j1' 'c' 'z' 'm'}] : begin
set rodTermRight : rodTermRight.concat : [CRod "f\(rc)"] rodCls
set rodConnRight : rodConnRight.concat : [CRod "c\(rc)"] rodCls
CreateLigationLookup : list
chain-rule
rodTermLeft ~> look-around
rodCls ~> [CRod 'zf']
CreateReverseLigationLookup : list
reverse-rule
rodCls ~> [CRod 'fz']
rodTermRight ~> look-around
# Fix for Apple : arrow bar at line start won't join with the rest (#548)
CreateLigationLookup : list
chain-rule
rodCls ~> [CRod 'fz']
rodTermRight ~> look-around
CreateLigationLookup : list
chain-rule
rodTermLeft ~> look-around
[[CRod 'zf'] rodCls] ~> [[CRod 'zm'] rodCls]
anyBar ~> [lsx 'dMid']
chain-rule
anyBar ~> [lsx 'dMid']
[[CRod 'fz'] rodCls] ~> [[CRod 'mz'] rodCls]
rodTermRight ~> look-around
# Gap filling
CreateLigationLookup : list
chain-rule
rodTermLeft ~> rodConnLeft
rodTermRight ~> rodConnRight
foreach [{rodCls dbl ltgt CRod} : items-of ArrowFormationConfig] : do "Ambiguous rods"
define [CJoinHeadForce] : if dbl [lsx 'dblhead'] [lsx 'shift0']
define [CAntiHeadForce] : if dbl [lsx 'hole'] [lsx 'shift0.anti']
define ambiguousRods {}
ambiguousRods.push : chain-rule # =>
rodCls ~> [if [hasLG 'arrow'] [CRod 'fr'] advance]
greater ~> [if [hasLG 'arrow'] [CJoinHeadForce] advance]
if ltgt
ambiguousRods.push : chain-rule # <=
less ~> [if [hasLG 'arrowZALE'] [CJoinHeadForce] advance]
rodCls ~> [if [hasLG 'arrowZALE'] [CRod 'lf'] advance]
ambiguousRods.push : chain-rule # <-
less ~> [if [hasLG 'arrow'] [CJoinHeadForce] advance]
rodCls ~> [if [hasLG 'arrow'] [CRod 'lf'] advance]
ambiguousRods.push : chain-rule # =<
rodCls ~> [if [hasLG 'arrow2'] [CRod 'fj'] advance]
less ~> [if [hasLG 'arrow2'] [CAntiHeadForce] advance]
if ltgt
ambiguousRods.push : chain-rule # >=
greater ~> [if [hasLG 'arrowZAGE'] [CAntiHeadForce] advance]
rodCls ~> [if [hasLG 'arrowZAGE'] [CRod 'jf'] advance]
ambiguousRods.push : chain-rule # >-
greater ~> [if [hasLG 'arrow2'] [CAntiHeadForce] advance]
rodCls ~> [if [hasLG 'arrow2'] [CRod 'jf'] advance]
CreateLigationLookup ambiguousRods
# <<, >>, <<<, >>>
do "Less/Greater Chaining" : if [hasLG 'llgg'] : begin
CreateLigationLookup : list
chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
chain-rule # <<<
less ~> [lsx 'shiftN0h']
less ~> look-around
less ~> [lsx 'shift0h']
chain-rule # >>>
greater ~> [lsx 'shift0h']
greater ~> look-around
greater ~> [lsx 'shiftN0h']
chain-rule # <<
less ~> [lsx 'shiftN0h']
less ~> [lsx 'shift0h']
chain-rule # >>
greater ~> [lsx 'shift0h']
greater ~> [lsx 'shiftN0h']
# Cancel alternates of < and > shapes if there are more after them
local lAll {"less" "less.lig.shift0h" "less.lig.shiftN0h"}
local lNeut {"less" "less" "less"}
local gAll {"greater" "greater.lig.shift0h" "greater.lig.shiftN0h"}
local gNeut {"greater" "greater" "greater"}
local lgAll : lAll.concat gAll
local lgNeut : lNeut.concat gNeut
CreateLigationLookup : list
chain-rule
lgAll ~> lgNeut
lgAll ~> lgNeut
lgAll ~> lgNeut
lgAll ~> look-around
CreateLigationLookup : list
chain-rule
lgAll ~> look-around
lgAll ~> look-around
lgAll ~> look-around
lgAll ~> lgNeut
CreateLigationLookup : list
chain-rule
lAll ~> lNeut
lAll ~> lNeut
gAll ~> gNeut
chain-rule
gAll ~> gNeut
gAll ~> gNeut
lAll ~> lNeut
chain-rule
lAll ~> lNeut
gAll ~> gNeut
gAll ~> gNeut
chain-rule
gAll ~> gNeut
lAll ~> lNeut
lAll ~> lNeut
# /\ and \/
do "logical" : if [hasLG 'logic'] : begin
CreateLigationLookup : list
chain-rule
slash ~> [csx 'left']
backslash ~> [csx 'right']
chain-rule
backslash ~> [csx 'left']
slash ~> [csx 'right']
chain-rule
bar ~> [lsx "dMid"]
anyStraightRod ~> [lsx 'mf']
chain-rule
anyStraightRod ~> [lsx 'fm']
bar ~> [lsx "dMid"]
chain-rule
underscore ~> [lsx 'fm']
bar ~> [lsx 'bottomMid']
underscore ~> [lsx 'mf']
# == and !=, and other related
do "equals" : begin
define AnyEqualEnding {'equal' 'equal.cf' 'equal.jf' 'equal.fc+cf' 'ident.cf' 'ident.cc+cf'}
CreateLigationLookup : list
piecewise
[hasLG 'eqeq'] : chain-rule
{'equal.cf' 'equal.jf'} ~> look-around
equal ~> {'equal.jf'}
piecewise
[hasLG 'eqexeq'] : chain-rule
equal ~> {'ident.fc'}
exclam ~> {'neq.allow-dot.1m'}
equal ~> {'ident.cc+cf'}
[hasLG 'eqexeq-dl'] : chain-rule
equal ~> {'equal.fc'}
exclam ~> {'neq.allow-dot.1m'}
equal ~> {'equal.cc+cf'}
true : chain-rule
AnyEqualEnding ~> look-around
exclam ~> advance
equal ~> look-around
piecewise
[hasLG 'exeqeqeq'] : chain-rule
exclam ~> {'neq.allow-dot.4l'}
equal ~> {'ident.fc+cc'}
equal ~> {'ident.cc'}
equal ~> {'ident.cf'}
[hasLG 'exeq'] : chain-rule
exclam ~> {'neq.allow-dot.4l'}
equal ~> {'equal.fc+cc'}
equal ~> {'equal.cc'}
equal ~> {'equal.cf'}
piecewise
[hasLG 'eqeq'] : chain-rule
equal ~> {'equal.fc'}
equal ~> {'equal.cc'}
equal ~> {'equal.cc'}
equal ~> {'equal.cf'}
piecewise
[hasLG 'exeqeq'] : chain-rule
exclam ~> {'neq.allow-dot.3l'}
equal ~> {'ident.fc+cc'}
equal ~> {'ident.cf'}
[hasLG 'exeq'] : chain-rule
exclam ~> {'neq.allow-dot.3l'}
equal ~> {'equal.fc+cc'}
equal ~> {'equal.cf'}
piecewise
[hasLG 'eqslasheq'] : chain-rule
equal ~> {'ident.fc'}
slash ~> {'neq.bar-only.1m'}
equal ~> {'ident.cc+cf'}
[hasLG 'slasheq'] : chain-rule
equal ~> {'equal.fc'}
slash ~> {'neq.bar-only.1m'}
equal ~> {'equal.cc+cf'}
piecewise
[hasLG 'eqeqeq'] : chain-rule
equal ~> {'ident.fc'}
equal ~> {'ident.cc'}
equal ~> {'ident.cf'}
piecewise
[hasLG 'tildeeq'] : chain-rule
anyWave ~> [just 'neq.bar-only.2l']
equal ~> {'equal.fc+cf'}
piecewise
[hasLG 'slasheq'] : chain-rule
slash ~> {'neq.bar-only.2l'}
equal ~> {'equal.fc+cf'}
piecewise
[hasLG 'exeq'] : chain-rule
exclam ~> {'neq.allow-dot.2l'}
equal ~> {'equal.fc+cf'}
piecewise
[hasLG 'eqeq'] : chain-rule
equal ~> {'equal.fc'}
equal ~> {'equal.cf'}
# <= and >=
do "inequals" : CreateLigationLookup : list
# Disable regular expression lookaheads
if [hasLG 'ineq'] : chain-rule
{'parenLeft'} ~>look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
if [hasLG 'ineq'] : chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
regexLookAround ~> advance
if [hasLG 'ineq'] : chain-rule
{'parenLeft'} ~> look-around
{'question'} ~> look-around
regexLookAround ~> advance
regexLookAround ~> advance
# <>
piecewise
[hasLG 'ltgt-diamond'] : chain-rule
lessAndEquiv ~> [just 'less.lig.diamond']
greaterAndEquiv ~> [just 'greater.lig.diamond']
[hasLG 'ltgt-diamond-tag'] : chain-rule
lessAndEquiv ~> [just 'less.lig.diamond.tag']
greaterAndEquiv ~> [just 'greater.lig.diamond.tag']
[hasLG 'ltgt-ne'] : chain-rule
lessAndEquiv ~> [just 'neq.bar-only.2l']
greaterAndEquiv ~> [just 'equal.fc+cf']
# <=, >=
if [hasLG 'ineq'] : chain-rule
[acops] ~> look-around
lessOrGreaterAndEquiv ~> advance
equal ~> advance
if [hasLG 'ineq'] : chain-rule
lessOrGreaterAndEquiv ~> advance
equal ~> advance
[acops] ~> look-around
if [hasLG 'ineq'] : chain-rule
lessAndEquiv ~> [just 'less.lig2']
equal ~> {'eq.at-lteq.lig2'}
if [hasLG 'ineq'] : chain-rule
greaterAndEquiv ~> [just 'greater.lig2']
equal ~> {'eq.at-gteq.lig2'}
# </, /> and </>
if [hasLG 'ltgt-slash-tag'] : chain-rule
lessAndEquiv ~> [just 'less.lig.tag-slash']
slash ~> look-around
if [hasLG 'ltgt-slash-tag'] : chain-rule
slash ~> look-around
greaterAndEquiv ~> [just 'greater.lig.tag-slash']
# :>
do "colon-less-greater" : if [hasLG 'colon-greater'] : begin
CreateLigationLookup : list
chain-rule
{'colon/mid'} ~> look-around
greaterAndEquiv ~> [just 'greaterArrow']
# [| |] {| |}
CreateLigationLookup : list
if [hasLG 'brack-bar'] : chain-rule
{'bracketLeft'} ~> {'ligExtBracketLeft'}
{'bar'} ~> {'ligBarInsideBracketLeft'}
if [hasLG 'brack-bar'] : chain-rule
{'bar'} ~> {'ligBarInsideBracketRight'}
{'bracketRight'} ~> {'ligExtBracketRight'}
if [hasLG 'brace-bar'] : chain-rule
{'braceLeft'} ~> {'ligExtBraceLeft'}
{'bar'} ~> {'ligBarInsideBracketLeft'}
if [hasLG 'brace-bar'] : chain-rule
{'bar'} ~> {'ligBarInsideBracketRight'}
{'braceRight'} ~> {'ligExtBraceRight'}
do "Plus chains" : if [hasLG 'plusplus'] : begin
CreateLigationLookup : list
# +++++++++
chain-rule
{'plus.lig.cf' 'plus.lig.zf'} ~> look-around
{'plus'} ~> [lsx 'zf']
chain-rule
{'plus'} ~> [lsx 'fc']
{'plus'} ~> [lsx 'cc']
{'plus'} ~> [lsx 'cc']
{'plus'} ~> [lsx 'cf']
chain-rule
{'plus'} ~> [lsx 'fc']
{'plus'} ~> [lsx 'cc']
{'plus'} ~> [lsx 'cf']
chain-rule
{'plus'} ~> [lsx 'fc']
{'plus'} ~> [lsx 'cf']
CreateLigationLookup : list
chain-rule # +++
{'plus.lig.fc'} ~> {'plus.lig.fc.s'}
{'plus.lig.cc'} ~> look-around
{'plus.lig.cf'} ~> {'plus.lig.cf.s'}
chain-rule # ++
{'plus.lig.fc'} ~> {'plus.lig.fc.s'}
{'plus.lig.cf'} ~> {'plus.lig.cf.s'}
do "Underscore chains" : if [hasLG 'connected-underscore'] : begin
CreateLigationLookup : list
chain-rule
[underscore.concat : [lsx 'zf'] underscore] ~> look-around
underscore ~> [lsx 'zf']
do "Tilde chains" : if [hasLG 'connected-tilde-as-wave'] : begin
CreateLigationLookup : list
chain-rule
{'wave.lig.cf' 'wave.lig.zf'} ~> look-around
{'asciiTilde'} ~> {'wave.lig.zf'}
chain-rule
{'asciiTilde'} ~> {"wave.lig.fc"}
{'asciiTilde'} ~> {"wave.lig.cf"}
do "Hyphen chains" : if [hasLG 'connected-hyphen-as-solid-line'] : begin
CreateLigationLookup : list
chain-rule
{'hyphen.lig.zf'} ~> look-around
{'hyphen'} ~> {'hyphen.lig.zf'}
chain-rule
{'hyphen'} ~> {"hyphen.lig.fc"}
{'hyphen'} ~> {"hyphen.lig.zf"}
CreateLigationLookup : list
chain-rule
{'hyphen.lig.jf'} ~> {'hyphen.lig.jc'}
{'hyphen'} ~> {'hyphen.lig.cc'}
{'hyphen.lig.fj'} ~> {'hyphen.lig.cj'}
chain-rule
{'hyphen.lig.jf'} ~> {'hyphen.lig.jc'}
{'hyphen.lig.fc'} ~> {'hyphen.lig.cc'}
chain-rule
{'hyphen.lig.zf'} ~> {'hyphen.lig.zc'}
{'hyphen.lig.fj'} ~> {'hyphen.lig.cj'}
do "Hyphen chains" : if [hasLG 'connected-hyphen-as-semi-dashed-line'] : begin
CreateLigationLookup : list
chain-rule
{'hyphen.lig.zf.notched'} ~> look-around
{'hyphen'} ~> {'hyphen.lig.zf.notched'}
chain-rule
{'hyphen'} ~> {"hyphen.lig.fc.notched"}
{'hyphen'} ~> {"hyphen.lig.zf.notched"}
CreateLigationLookup : list
chain-rule
{'hyphen.lig.jf'} ~> {'hyphen.lig.jc.notched'}
{'hyphen'} ~> {'hyphen.lig.cc.notched'}
{'hyphen.lig.fj'} ~> {'hyphen.lig.cj.notched'}
chain-rule
{'hyphen.lig.jf'} ~> {'hyphen.lig.jc.notched'}
{'hyphen.lig.fc.notched'} ~> {'hyphen.lig.cc.notched'}
chain-rule
{'hyphen.lig.zf.notched'} ~> {'hyphen.lig.zc.notched'}
{'hyphen.lig.fj'} ~> {'hyphen.lig.cj.notched'}
do "Number sign chains" : if [hasLG 'connected-number-sign'] : begin
CreateLigationLookup : list
chain-rule
{'numberSign' 'numberSign.jr'} ~> look-around
{'numberSign'} ~> {'numberSign.jr'}
do "Kern Bars" : if [hasLG 'kern-bars'] : foreach chBar [items-of anyBar] : begin
define dp { chBar }
define dLeft : [lsx 'dLeft'] dp
define dRight : [lsx 'dRight'] dp
define dLeftHalf : [lsx 'dLeftHalf'] dp
define dRightHalf : [lsx 'dRightHalf'] dp
define dMid : [lsx 'dMid'] dp
CreateLigationLookup : list
chain-rule
[dRight.concat dMid] ~> look-around
dp ~> dMid
[dp.concat dMid] ~> look-around
chain-rule
[dRight.concat dMid] ~> look-around
dp ~> dLeft
chain-rule
dp ~> dRight
[dp.concat dMid] ~> look-around
CreateLigationLookup : list
chain-rule
dRight ~> look-around
dMid ~> dRightHalf
dMid ~> dLeftHalf
dLeft ~> look-around
chain-rule
dRight ~> look-around
dMid ~> dRightHalf
dMid ~> look-around
chain-rule
dMid ~> look-around
dMid ~> dLeftHalf
dLeft ~> look-around
chain-rule
dRight ~> dRightHalf
dLeft ~> dLeftHalf