@@ 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