~alcinnz/haskell-stylist

00736062727487810bead9ddd0b9a97adda0b682 — Adrian Cochrane 1 year, 7 months ago 6546445
Draft Ethiopic numbering implementation.
1 files changed, 35 insertions(+), 1 deletions(-)

M src/Data/CSS/Preprocessor/Text/CounterStyle.hs
M src/Data/CSS/Preprocessor/Text/CounterStyle.hs => src/Data/CSS/Preprocessor/Text/CounterStyle.hs +35 -1
@@ 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