From 00736062727487810bead9ddd0b9a97adda0b682 Mon Sep 17 00:00:00 2001 From: Adrian Cochrane Date: Wed, 26 Apr 2023 17:01:28 +1200 Subject: [PATCH] Draft Ethiopic numbering implementation. --- .../CSS/Preprocessor/Text/CounterStyle.hs | 36 ++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/Data/CSS/Preprocessor/Text/CounterStyle.hs b/src/Data/CSS/Preprocessor/Text/CounterStyle.hs index f47c94c..a4d6aaf 100644 --- a/src/Data/CSS/Preprocessor/Text/CounterStyle.hs +++ b/src/Data/CSS/Preprocessor/Text/CounterStyle.hs @@ -28,7 +28,7 @@ data CounterStyle = CounterStyle { speakAs :: Maybe Text } data CounterSystem = Cyclic | Fixed Int | Symbolic | Alphabetic | Numeric - | Additive | Chinese { isSimplified :: Bool } + | Additive | Chinese { isSimplified :: Bool } | Ethiopic defaultCounter, decimalCounter, simpChineseInformal, cjkDecimal :: CounterStyle defaultCounter = CounterStyle { @@ -71,6 +71,9 @@ isValid CounterStyle { system = Additive, additiveSymbols = [] } = False isValid self@CounterStyle { system = Chinese _, symbols = syms, additiveSymbols = markers } = length syms == 10 && length markers >= 4 && ranges self == Nothing +isValid CounterStyle { + system = Ethiopic, symbols = units, additiveSymbols = tens + } = length units == 10 && length tens == 10 isValid CounterStyle { symbols = [] } = False isValid _ = True @@ -89,6 +92,8 @@ parseCounterProperty _ ("system", [Ident "numeric"]) self = self { system = Numeric } parseCounterProperty _ ("system", [Ident "-argo-chinese", Ident x]) self = self { system = Chinese (x == "simplified") } +parseCounterProperty _ ("system", [Ident "-argo-ethiopic"]) self = + self { system = Ethiopic } -- Handled by caller so property overrides work correctly. parseCounterProperty _ ("system", [Ident "extends", Ident _]) self = self @@ -245,6 +250,34 @@ counterRenderCore CounterStyle { -- Select characters per steps 2 & 5 renderDigit (place, digit) = Txt.concat [syms !! digit, markers' !! place] markers' = map snd markers +-- Following https://w3c.github.io/csswg-drafts/css-counter-styles-3/#ethiopic-numeric-counter-style +-- 1. If the number is 1, return "፩" (U+1369). +counterRenderCore CounterStyle { system = Ethiopic, symbols = (sym:_) } 1 = sym +counterRenderCore CounterStyle { + system = Ethiopic, symbols = unitSyms, additiveSymbols = tenSyms + } x = Txt.concat $ renderPairs True $ + reverse $ enumerate $ pairDigits $ decimalDigits x + where + -- 2. Split the number into groups of two digits, + -- starting with the least significant decimal digit. + pairDigits (units:tens:digits) = (tens,units):pairDigits digits + pairDigits [units] = (0, units):[] + pairDigits [] = [] + + renderPairs isBigEnd (group:groups) = + renderPair isBigEnd group:renderPairs False groups + -- Handle step 4's exceptions. + renderPair' _ (_,(0, 0)) = "" + renderPair' True (_, (0,1)) = "" + renderPair' _ (i, (0,1)) | odd i = "" + -- Step 5 + renderPair' _ (_, (tens, units)) = + (map snd tenSyms !! tens) `Txt.append` (unitSyms !! units) + -- Step 6 & 7 + renderPair _ (i, (0,0)) = "" + renderPair isBigEnd (i, group) + | odd i = renderPair' isBigEnd (i, group) `Txt.append` "፻" + | even i = renderPair' isBigEnd (i, group) `Txt.append` "፼" decimalDigits :: Int -> [Int] decimalDigits 0 = [] decimalDigits x = rem x 10:decimalDigits (quot x 10) @@ -291,6 +324,7 @@ ranges' CounterStyle { system = Alphabetic } = [(1, maxBound)] ranges' CounterStyle { system = Symbolic } = [(1, maxBound)] ranges' CounterStyle { system = Additive } = [(0, maxBound)] ranges' CounterStyle { system = Chinese _ } = [(-9999, 9999)] +ranges' CounterStyle { system = Ethiopic } = [(1, maxBound)] speakAs' :: CounterStyle -> Text speakAs' CounterStyle { speakAs = Just ret } = ret -- 2.30.2