    {-# LANGUAGE LambdaCase #-}
    {-# LANGUAGE OverloadedLists #-}
    {-# LANGUAGE OverloadedStrings #-}
    {-# LANGUAGE RankNTypes #-}
    {-# LANGUAGE ScopedTypeVariables #-}
    {-# LANGUAGE TupleSections #-}

    module Typst.Constructors
      ( getConstructor
      )
    where

    import qualified Data.Vector as V
    import qualified Data.Map.Ordered as OM
    import qualified Data.Map as M
    import Data.Time (fromGregorian, secondsToDiffTime)
    import Data.Maybe (fromMaybe, mapMaybe)
    import qualified Data.ByteString as B
    import Typst.Types
    import Typst.Util (makeFunction, makeFunctionWithScope, namedArg, nthArg, allArgs)
    import qualified Data.Set as Set
    import Data.Text (Text)
    import qualified Data.Text as T
    import qualified Data.Text.Encoding as TE
    import Typst.Regex (makeRE)
    import Data.List (genericTake)
    import Control.Monad.Reader (asks, lift)
    import Typst.Module.Standard (getPath)
    import Control.Monad (mplus)
    import Data.Char (ord, chr, isDigit, isAsciiLower, isAsciiUpper)

    getConstructor :: ValType -> Maybe Val
    getConstructor :: ValType -> Maybe Val
    getConstructor ValType
    typ =
      case ValType
    typ of
        ValType
    TFloat -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Double -> Val
    VFloat (Double -> Val)
    -> ReaderT Arguments (MP m') Double
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Double
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
        ValType
    TInteger -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Map Identifier Val -> Val
    makeFunctionWithScope
          (do
            val <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
            (base :: Integer) <- namedArg "base" 10
            case val of
              Val
    _ | Integer
    base Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    == Integer
    10 -> Integer -> Val
    VInteger (Integer -> Val)
    -> ReaderT Arguments (MP m') Integer
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Val -> ReaderT Arguments (MP m') Integer
    forall a (m :: * -> *).
    (FromVal a, MonadPlus m, MonadFail m) =>
    Val -> m a
    forall (m :: * -> *).
    (MonadPlus m, MonadFail m) =>
    Val -> m Integer
    fromVal Val
    val
              VString Text
    s
                | Integer
    base Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Integer
    2 Bool -> Bool -> Bool
    && Integer
    base Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    <= Integer
    36 ->
                    ReaderT Arguments (MP m') Val
    -> (Integer -> ReaderT Arguments (MP m') Val)
    -> Maybe Integer
    -> ReaderT Arguments (MP m') Val
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe (String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "invalid digits for the given base")
                          (Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> (Integer -> Val) -> Integer -> ReaderT Arguments (MP m') Val
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Val
    VInteger)
                          (Integer -> Text -> Maybe Integer
    parseInBase Integer
    base Text
    s)
                | Bool
    otherwise -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "base must be between 2 and 36"
              Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "base is only supported when parsing strings")
          [ (Identifier
    "min", Integer -> Val
    VInteger (-Integer
    9223372036854775808)),  -- i64 bounds, as in typst
            (Identifier
    "max", Integer -> Val
    VInteger Integer
    9223372036854775807)
          ]
        ValType
    TRegex -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ RE -> Val
    VRegex (RE -> Val)
    -> ReaderT Arguments (MP m') RE -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> (Int -> ReaderT Arguments (MP m') Text
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1 ReaderT Arguments (MP m') Text
    -> (Text -> ReaderT Arguments (MP m') RE)
    -> ReaderT Arguments (MP m') RE
    forall a b.
    ReaderT Arguments (MP m') a
    -> (a -> ReaderT Arguments (MP m') b)
    -> ReaderT Arguments (MP m') b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= Text -> ReaderT Arguments (MP m') RE
    forall (m :: * -> *). MonadFail m => Text -> m RE
    makeRE)
        ValType
    TVersion -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ [Integer] -> Val
    VVersion ([Integer] -> Val)
    -> ReaderT Arguments (MP m') [Integer]
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> ((Arguments -> [Val]) -> ReaderT Arguments (MP m') [Val]
    forall r (m :: * -> *) a. MonadReader r m => (r -> a) -> m a
    asks Arguments -> [Val]
    positional ReaderT Arguments (MP m') [Val]
    -> ([Val] -> ReaderT Arguments (MP m') [Integer])
    -> ReaderT Arguments (MP m') [Integer]
    forall a b.
    ReaderT Arguments (MP m') a
    -> (a -> ReaderT Arguments (MP m') b)
    -> ReaderT Arguments (MP m') b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (Val -> ReaderT Arguments (MP m') Integer)
    -> [Val] -> ReaderT Arguments (MP m') [Integer]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Val -> ReaderT Arguments (MP m') Integer
    forall a (m :: * -> *).
    (FromVal a, MonadPlus m, MonadFail m) =>
    Val -> m a
    forall (m :: * -> *).
    (MonadPlus m, MonadFail m) =>
    Val -> m Integer
    fromVal)
        ValType
    TString -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Map Identifier Val -> Val
    makeFunctionWithScope
          (do
            val <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
            base <- namedArg "base" (10 :: Integer)
            let digitVector :: V.Vector Char
                digitVector = String -> Vector Char
    forall a. [a] -> Vector a
    V.fromList (String -> Vector Char) -> String -> Vector Char
    forall a b. (a -> b) -> a -> b
    $ [Char
    Item String
    '0'..Char
    Item String
    '9'] String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ [Char
    Item String
    'A'..Char
    Item String
    'Z']
            let renderDigit a
    n = Vector Char
    digitVector Vector Char -> Int -> Maybe Char
    forall a. Vector a -> Int -> Maybe a
    V.!? (a -> Int
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral a
    n)
            VString <$>
              case val of
                VInteger Integer
    n | Integer
    base Integer -> Integer -> Bool
    forall a. Eq a => a -> a -> Bool
    /= Integer
    10
                  -> case Integer -> Integer -> Maybe [Integer]
    forall n. Integral n => n -> n -> Maybe [n]
    mDigits Integer
    base Integer
    n of
                       Maybe [Integer]
    Nothing -> String -> ReaderT Arguments (MP m') Text
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Could not convert number to base"
                       Just [Integer]
    ds -> ReaderT Arguments (MP m') Text
    -> (String -> ReaderT Arguments (MP m') Text)
    -> Maybe String
    -> ReaderT Arguments (MP m') Text
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe
                         (String -> ReaderT Arguments (MP m') Text
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "Could not convert number to base")
                         (Text -> ReaderT Arguments (MP m') Text
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Text -> ReaderT Arguments (MP m') Text)
    -> (String -> Text) -> String -> ReaderT Arguments (MP m') Text
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Text
    T.pack)
                         ((Integer -> Maybe Char) -> [Integer] -> Maybe String
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Integer -> Maybe Char
    forall {a}. Integral a => a -> Maybe Char
    renderDigit [Integer]
    ds)
                Val
    _ -> Val -> ReaderT Arguments (MP m') Text
    forall a (m :: * -> *).
    (FromVal a, MonadPlus m, MonadFail m) =>
    Val -> m a
    forall (m :: * -> *). (MonadPlus m, MonadFail m) => Val -> m Text
    fromVal Val
    val ReaderT Arguments (MP m') Text
    -> ReaderT Arguments (MP m') Text -> ReaderT Arguments (MP m') Text
    forall a.
    ReaderT Arguments (MP m') a
    -> ReaderT Arguments (MP m') a -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadPlus m => m a -> m a -> m a
    `mplus` Text -> ReaderT Arguments (MP m') Text
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> Text
    repr Val
    val))
          [ ( Identifier
    "to-unicode",
               (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
                 (val :: Text) <- Int -> ReaderT Arguments (MP m') Text
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
                 case T.uncons val of
                   Just (Char
    c, Text
    t) | Text -> Bool
    T.null Text
    t ->
                     Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ Integer -> Val
    VInteger (Integer -> Val) -> Integer -> Val
    forall a b. (a -> b) -> a -> b
    $ Int -> Integer
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Int -> Integer) -> Int -> Integer
    forall a b. (a -> b) -> a -> b
    $ Char -> Int
    ord Char
    c
                   Maybe (Char, Text)
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "to-unicode expects a single character" )
          , ( Identifier
    "from-unicode",
               (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
                 (val :: Int) <- Int -> ReaderT Arguments (MP m') Int
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
                 pure $ VString $ T.pack [chr val] )
          ]
        ValType
    TLabel -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ Text -> Val
    VLabel (Text -> Val)
    -> ReaderT Arguments (MP m') Text -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Int -> ReaderT Arguments (MP m') Text
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
        ValType
    TSymbol -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
            (t :: Text) <- Int -> ReaderT Arguments (MP m') Text
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
            vs <- drop 1 <$> allArgs
            variants <-
              mapM
                ( \case
                    VArray [VString Text
    k, VString Text
    v] ->
                      (Set Text, Text) -> ReaderT Arguments (MP m') (Set Text, Text)
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure ([Text] -> Set Text
    forall a. Ord a => [a] -> Set a
    Set.fromList ((Char -> Bool) -> Text -> [Text]
    T.split (Char -> Char -> Bool
    forall a. Eq a => a -> a -> Bool
    == Char
    '.') Text
    k), Text
    v)
                    Val
    _ -> String -> ReaderT Arguments (MP m') (Set Text, Text)
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "wrong type in symbol arguments"
                )
                vs
            pure $ VSymbol $ Symbol t False variants
        ValType
    TDateTime -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
          mbyr <- Identifier
    -> Maybe Integer -> ReaderT Arguments (MP m') (Maybe Integer)
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Identifier -> a -> ReaderT Arguments (MP m) a
    namedArg Identifier
    "year" Maybe Integer
    forall a. Maybe a
    Nothing
          mbmo <- namedArg "month" Nothing
          mbda <- namedArg "day" Nothing
          mbhr <- namedArg "hour" Nothing
          mbmn <- namedArg "minute" Nothing
          mbsc <- namedArg "second" Nothing
          let mbday = case (Maybe Integer
    mbyr, Maybe Int
    mbmo, Maybe Int
    mbda) of
                         (Maybe Integer
    Nothing, Maybe Int
    _, Maybe Int
    _) -> Maybe Day
    forall a. Maybe a
    Nothing
                         (Just Integer
    yr, Maybe Int
    _, Maybe Int
    _) -> Day -> Maybe Day
    forall a. a -> Maybe a
    Just (Day -> Maybe Day) -> Day -> Maybe Day
    forall a b. (a -> b) -> a -> b
    $
                           Integer -> Int -> Int -> Day
    fromGregorian Integer
    yr (Int -> Maybe Int -> Int
    forall a. a -> Maybe a -> a
    fromMaybe Int
    1 Maybe Int
    mbmo) (Int -> Maybe Int -> Int
    forall a. a -> Maybe a -> a
    fromMaybe Int
    1 Maybe Int
    mbda)
          let mbdifftime = case (Maybe Integer
    mbhr, Maybe Integer
    mbmn, Maybe Integer
    mbsc) of
                                  (Maybe Integer
    Nothing, Maybe Integer
    _, Maybe Integer
    _) -> Maybe DiffTime
    forall a. Maybe a
    Nothing
                                  (Just Integer
    hr, Maybe Integer
    _, Maybe Integer
    _) -> DiffTime -> Maybe DiffTime
    forall a. a -> Maybe a
    Just (DiffTime -> Maybe DiffTime) -> DiffTime -> Maybe DiffTime
    forall a b. (a -> b) -> a -> b
    $ Integer -> DiffTime
    secondsToDiffTime (Integer -> DiffTime) -> Integer -> DiffTime
    forall a b. (a -> b) -> a -> b
    $
                                    (Integer
    hr Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * Integer
    60 Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * Integer
    60) Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    + Integer -> (Integer -> Integer) -> Maybe Integer -> Integer
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe Integer
    0 (Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    * Integer
    60) Maybe Integer
    mbmn Integer -> Integer -> Integer
    forall a. Num a => a -> a -> a
    +
                                      Integer -> Maybe Integer -> Integer
    forall a. a -> Maybe a -> a
    fromMaybe Integer
    0 Maybe Integer
    mbsc
          pure $ VDateTime mbday mbdifftime
        ValType
    TDict -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
          a <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
          case a of
            VModule Identifier
    _ Map Identifier Val
    m -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ OMap Identifier Val -> Val
    VDict (OMap Identifier Val -> Val) -> OMap Identifier Val -> Val
    forall a b. (a -> b) -> a -> b
    $ [(Identifier, Val)] -> OMap Identifier Val
    forall k v. Ord k => [(k, v)] -> OMap k v
    OM.fromList ([(Identifier, Val)] -> OMap Identifier Val)
    -> [(Identifier, Val)] -> OMap Identifier Val
    forall a b. (a -> b) -> a -> b
    $ Map Identifier Val -> [(Identifier, Val)]
    forall k a. Map k a -> [(k, a)]
    M.toList Map Identifier Val
    m
            Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "dictionary constructor requires a module as argument"
        ValType
    TPath -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
          v <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
          case v of
            -- paths are returned unchanged
            VPath String
    _ -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure Val
    v
            -- relative paths are resolved at construction time,
            -- relative to the constructing file
            VString Text
    fp -> String -> Val
    VPath (String -> Val)
    -> ReaderT Arguments (MP m') String
    -> ReaderT Arguments (MP m') Val
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> MP m' String -> ReaderT Arguments (MP m') String
    forall (m :: * -> *) a. Monad m => m a -> ReaderT Arguments m a
    forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
    (MonadTrans t, Monad m) =>
    m a -> t m a
    lift (String -> MP m' String
    forall (m :: * -> *). Monad m => String -> MP m String
    getPath (Text -> String
    T.unpack Text
    fp))
            Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "expected string or path"
        ValType
    TBytes -> Val -> Maybe Val
    forall a. a -> Maybe a
    Just (Val -> Maybe Val) -> Val -> Maybe Val
    forall a b. (a -> b) -> a -> b
    $ (forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
    -> Val
    makeFunction ((forall (m' :: * -> *). Monad m' => ReaderT Arguments (MP m') Val)
     -> Val)
    -> (forall (m' :: * -> *).
        Monad m' =>
        ReaderT Arguments (MP m') Val)
    -> Val
    forall a b. (a -> b) -> a -> b
    $ do
          x <- Int -> ReaderT Arguments (MP m') Val
    forall (m :: * -> *) a.
    (Monad m, FromVal a) =>
    Int -> ReaderT Arguments (MP m) a
    nthArg Int
    1
          let extractWord8 (VInteger Integer
    w) = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Integer -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral Integer
    w
              extractWord8 Val
    _ = Maybe a
    forall a. Maybe a
    Nothing
          case x of
            VString Text
    s -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Val
    VBytes (ByteString -> Val) -> ByteString -> Val
    forall a b. (a -> b) -> a -> b
    $ Text -> ByteString
    TE.encodeUtf8 Text
    s
            VArray Vector Val
    xs -> Val -> ReaderT Arguments (MP m') Val
    forall a. a -> ReaderT Arguments (MP m') a
    forall (f :: * -> *) a. Applicative f => a -> f a
    pure (Val -> ReaderT Arguments (MP m') Val)
    -> Val -> ReaderT Arguments (MP m') Val
    forall a b. (a -> b) -> a -> b
    $ ByteString -> Val
    VBytes (ByteString -> Val) -> ByteString -> Val
    forall a b. (a -> b) -> a -> b
    $ [Word8] -> ByteString
    B.pack ([Word8] -> ByteString) -> [Word8] -> ByteString
    forall a b. (a -> b) -> a -> b
    $ (Val -> Maybe Word8) -> [Val] -> [Word8]
    forall a b. (a -> Maybe b) -> [a] -> [b]
    mapMaybe Val -> Maybe Word8
    forall {a}. Num a => Val -> Maybe a
    extractWord8 ([Val] -> [Word8]) -> [Val] -> [Word8]
    forall a b. (a -> b) -> a -> b
    $ Vector Val -> [Val]
    forall a. Vector a -> [a]
    V.toList Vector Val
    xs
            Val
    _ -> String -> ReaderT Arguments (MP m') Val
    forall a. String -> ReaderT Arguments (MP m') a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "bytes constructor requires a string or array as argument"
        ValType
    TArguments -> Maybe Val
    forall a. Maybe a
    Nothing
        -- TODO https://typst.app/docs/reference/foundations/arguments/
        ValType
    TSelector -> Maybe Val
    forall a. Maybe a
    Nothing
        -- TODO https://typst.app/docs/reference/foundations/selector/
        ValType
    TCounter -> Maybe Val
    forall a. Maybe a
    Nothing
        -- TODO https://typst.app/docs/reference/introspection/counter/
        ValType
    _ -> Maybe Val
    forall a. Maybe a
    Nothing

    -- | Parse an integer (with optional sign) in the given base (2-36).
    parseInBase :: Integer -> Text -> Maybe Integer
    parseInBase :: Integer -> Text -> Maybe Integer
    parseInBase Integer
    base Text
    t =
      case Text -> Maybe (Char, Text)
    T.uncons Text
    t of
        Just (Char
    '-', Text
    rest) -> Integer -> Integer
    forall a. Num a => a -> a
    negate (Integer -> Integer) -> Maybe Integer -> Maybe Integer
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> Text -> Maybe Integer
    go Text
    rest
        Just (Char
    '+', Text
    rest) -> Text -> Maybe Integer
    go Text
    rest
        Maybe (Char, Text)
    _ -> Text -> Maybe Integer
    go Text
    t
      where
        go :: Text -> Maybe Integer
    go Text
    s
          | Text -> Bool
    T.null Text
    s = Maybe Integer
    forall a. Maybe a
    Nothing
          | Bool
    otherwise = (Maybe Integer -> Char -> Maybe Integer)
    -> Maybe Integer -> Text -> Maybe Integer
    forall a. (a -> Char -> a) -> a -> Text -> a
    T.foldl' Maybe Integer -> Char -> Maybe Integer
    step (Integer -> Maybe Integer
    forall a. a -> Maybe a
    Just Integer
    0) Text
    s
        step :: Maybe Integer -> Char -> Maybe Integer
    step Maybe Integer
    macc Char
    c = do
          acc <- Maybe Integer
    macc
          d <- digitVal c
          if d < base
            then Just (acc * base + d)
            else Nothing
        digitVal :: Char -> Maybe a
    digitVal Char
    c
          | Char -> Bool
    isDigit Char
    c = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Int -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Char -> Int
    ord Char
    c Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Char -> Int
    ord Char
    '0')
          | Char -> Bool
    isAsciiLower Char
    c = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Int -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Char -> Int
    ord Char
    c Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Char -> Int
    ord Char
    'a' Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    10)
          | Char -> Bool
    isAsciiUpper Char
    c = a -> Maybe a
    forall a. a -> Maybe a
    Just (a -> Maybe a) -> a -> Maybe a
    forall a b. (a -> b) -> a -> b
    $ Int -> a
    forall a b. (Integral a, Num b) => a -> b
    fromIntegral (Char -> Int
    ord Char
    c Int -> Int -> Int
    forall a. Num a => a -> a -> a
    - Char -> Int
    ord Char
    'A' Int -> Int -> Int
    forall a. Num a => a -> a -> a
    + Int
    10)
          | Bool
    otherwise = Maybe a
    forall a. Maybe a
    Nothing

    -- mDigitsRev, mDigits from the unmaintained digits package
    -- https://hackage.haskell.org/package/digits-0.3.1
    -- (c) 2009-2016 Henry Bucklow, Charlie Harvey -- BSD-3-Clause license.
    mDigitsRev :: Integral n
        => n         -- ^ The base to use.
        -> n         -- ^ The number to convert to digit form.
        -> Maybe [n] -- ^ Nothing or Just the digits of the number in list form, in reverse.
    mDigitsRev :: forall n. Integral n => n -> n -> Maybe [n]
    mDigitsRev n
    base n
    i = if n
    base n -> n -> Bool
    forall a. Ord a => a -> a -> Bool
    < n
    1
                        then Maybe [n]
    forall a. Maybe a
    Nothing -- We do not support zero or negative bases
                        else [n] -> Maybe [n]
    forall a. a -> Maybe a
    Just ([n] -> Maybe [n]) -> [n] -> Maybe [n]
    forall a b. (a -> b) -> a -> b
    $ n -> n -> [n]
    forall {t}. Integral t => t -> t -> [t]
    dr n
    base n
    i
        where
          dr :: t -> t -> [t]
    dr t
    _ t
    0 = []
          dr t
    b t
    x = case n
    base of
                    n
    1 -> t -> [t] -> [t]
    forall i a. Integral i => i -> [a] -> [a]
    genericTake t
    x ([t] -> [t]) -> [t] -> [t]
    forall a b. (a -> b) -> a -> b
    $ t -> [t]
    forall a. a -> [a]
    repeat t
    1
                    n
    _ -> let (t
    rest, t
    lastDigit) = t -> t -> (t, t)
    forall a. Integral a => a -> a -> (a, a)
    quotRem t
    x t
    b
                         in t
    lastDigit t -> [t] -> [t]
    forall a. a -> [a] -> [a]
    : t -> t -> [t]
    dr t
    b t
    rest

    -- | Returns the digits of a positive integer as a Maybe list.
    --   or Nothing if a zero or negative base is given
    mDigits :: Integral n
        => n -- ^ The base to use.
        -> n -- ^ The number to convert to digit form.
        -> Maybe [n] -- ^ Nothing or Just the digits of the number in list form
    mDigits :: forall n. Integral n => n -> n -> Maybe [n]
    mDigits n
    base n
    i = [n] -> [n]
    forall a. [a] -> [a]
    reverse ([n] -> [n]) -> Maybe [n] -> Maybe [n]
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> n -> n -> Maybe [n]
    forall n. Integral n => n -> n -> Maybe [n]
    mDigitsRev n
    base n
    i