packages feed

typst 0.11.0.1 → 0.12

raw patch · 37 files changed

+2060/−60 lines, 37 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Typst.Types: Stroke :: !Maybe Color -> !Maybe Length -> !Maybe Text -> !Maybe Text -> !Maybe Double -> Stroke
+ Typst.Types: TStroke :: ValType
+ Typst.Types: VStroke :: !Stroke -> Val
+ Typst.Types: [cap] :: Stroke -> !Maybe Text
+ Typst.Types: [join] :: Stroke -> !Maybe Text
+ Typst.Types: [miterLimit] :: Stroke -> !Maybe Double
+ Typst.Types: [paint] :: Stroke -> !Maybe Color
+ Typst.Types: [thickness] :: Stroke -> !Maybe Length
+ Typst.Types: data Stroke
+ Typst.Types: emptyStroke :: Stroke
+ Typst.Types: instance GHC.Classes.Eq Typst.Types.Stroke
+ Typst.Types: instance GHC.Show.Show Typst.Types.Stroke
+ Typst.Util: getNamed :: forall (m :: Type -> Type). Monad m => Identifier -> ReaderT Arguments (MP m) (Maybe Val)

Files

CHANGELOG.md view
@@ -1,5 +1,16 @@ # Revision history for typst-hs +## 0.12++  * Support 'in' operator on modules (#106).++  * Return an error instead of crashing on integer division by zero (#103,+    Vladimir Babin).++  * Add support for the stroke type (#76, #107, Samuel Huang)+    [API change] Adds `VStroke` to `Val`, `TStroke` to `ValType`,+    `Stroke`, `emptyStroke`.+ ## 0.11.0.1    * Fix `calc.pow` so it accepts negative exponents (#102).
src/Typst/Constructors.hs view
@@ -25,7 +25,7 @@ import Typst.Regex (makeRE) import Data.List (genericTake) import Control.Monad.Reader (asks, lift)-import Typst.Module.Standard (getPath)+import Typst.Module.Standard (getPath, strokeConstructor) import Control.Monad (mplus) import Data.Char (ord, chr, isDigit, isAsciiLower, isAsciiUpper) @@ -81,6 +81,7 @@              pure $ VString $ T.pack [chr val] )       ]     TLabel -> Just $ makeFunction $ VLabel <$> nthArg 1+    TStroke -> Just strokeConstructor     TSymbol -> Just $ makeFunction $ do         (t :: Text) <- nthArg 1         vs <- drop 1 <$> allArgs
src/Typst/Evaluate.hs view
@@ -734,6 +734,10 @@           case v1 of             VString t -> pure $ VBoolean $ isJust $ OM.lookup (Identifier t) m             _ -> pure $ VBoolean False+        VModule _ m ->+          case v1 of+            VString t -> pure $ VBoolean $ isJust $ M.lookup (Identifier t) m+            _ -> pure $ VBoolean False         _ -> fail $ "Can't apply 'in' to " <> show v2 <> show (e1,e2)      Negated e -> do
src/Typst/Methods.hs view
@@ -154,6 +154,14 @@             CMYK c m y k -> CMYK (1 - c) (1 - m) (1 - y) k             Luma x -> Luma (1 - x)         _ -> noMethod "Color" fld+    VStroke s ->+      case fld of+        "paint" -> pure $ maybe VAuto VColor (paint s)+        "thickness" -> pure $ maybe VAuto VLength (thickness s)+        "cap" -> pure $ maybe VAuto VString (cap s)+        "join" -> pure $ maybe VAuto VString (join s)+        "miter-limit" -> pure $ maybe VAuto VFloat (miterLimit s)+        _ -> noMethod "Stroke" fld     VString t -> do       let toPos n =             if n < 0
src/Typst/Module/Calc.hs view
@@ -157,16 +157,21 @@         makeFunction $ do           (a :: Integer) <- nthArg 1           (b :: Integer) <- nthArg 2-          pure $ VInteger $ a `quot` b+          if b == 0+            then fail "division by zero"+            else pure $ VInteger $ a `quot` b       ),       ( "rem",         makeFunction $ do           (a :: Integer, f :: Double) <- properFraction <$> nthArg 1           (b :: Integer) <- nthArg 2-          pure $-            if f == 0-              then VInteger $ rem a b-              else VFloat $ fromIntegral (rem a b) + f+          if b == 0+            then fail "division by zero"+            else+              pure $+                if f == 0+                  then VInteger $ rem a b+                  else VFloat $ fromIntegral (rem a b) + f       ),       ( "round",         makeFunction $ do
src/Typst/Module/Standard.hs view
@@ -10,7 +10,8 @@     loadFileText,     getPath,     applyPureFunction,-    elementDefaults+    elementDefaults,+    strokeConstructor   ) where @@ -400,6 +401,9 @@   , ("length", VType TLength)   , ("alignment", VType TAlignment)   , ("color", VType TColor)+  -- The stroke type is bound to VType, like other types; stroke(...)+  -- works because VType values are callable via getConstructor.+  , ("stroke", VType TStroke)   , ("symbol", VType TSymbol)   , ("str", VType TString)   , ("label", VType TLabel)@@ -547,6 +551,53 @@     )   ] +-- | The stroke() constructor, also used by getConstructor for TStroke.+strokeConstructor :: Val+strokeConstructor =+  makeFunction $ do+    base <-+      nthArg 1 >>= \case+        VNone -> pure emptyStroke+        VStroke s -> pure s+        VColor c -> pure emptyStroke { paint = Just c }+        VLength l -> pure emptyStroke { thickness = Just l }+        VDict m -> strokeFromDict m+        _ -> fail "expected stroke, color, length, or dictionary"+    -- getNamed (not namedArg) so an explicit `none` is distinguishable+    -- from an absent argument; like `auto`, it resets the field.+    -- (typst errors on `none` here, and rejects combining a base with+    -- named arguments.)+    --+    -- This can't be reduced to `mergeStrokes base <$> strokeFromDict+    -- named`: mergeStrokes falls back to the base field when a named+    -- argument is explicitly none or auto, so a reset would silently+    -- become an inherit.+    mbPaint <- getNamed "paint"+    mbThickness <- getNamed "thickness"+    mbCap <- getNamed "cap"+    mbJoin <- getNamed "join"+    mbMiterLimit <- getNamed "miter-limit"+    -- A named argument overrides the base field; auto or none resets it.+    let override get f mb = case mb of+          Nothing -> pure (get base)+          Just VAuto -> pure Nothing+          Just VNone -> pure Nothing+          Just v -> Just <$> f v+    paint <- override paint asColor mbPaint+    thickness <- override thickness asLength mbThickness+    cap <- override cap asLineCap mbCap+    join <- override join asLineJoin mbJoin+    miterLimit <- override miterLimit asMiterLimit mbMiterLimit+    pure $+      VStroke $+        emptyStroke+          { paint = paint,+            thickness = thickness,+            cap = cap,+            join = join,+            miterLimit = miterLimit+          }+ loremWords :: [Text] loremWords =   cycle $@@ -739,3 +790,52 @@   case v of     VBytes bs -> pure $ BL.fromStrict bs     _ -> lift $ resolvePathVal v >>= loadResolvedLazyBytes++-- | Build a 'Stroke' from a dictionary such as+-- @(paint: red, thickness: 2pt)@.+strokeFromDict :: MonadFail m => OM.OMap Identifier Val -> m Stroke+strokeFromDict m = do+  let field k f = case OM.lookup k m of+        Nothing -> pure Nothing+        Just VAuto -> pure Nothing+        Just VNone -> pure Nothing+        Just v -> Just <$> f v+  paint <- field "paint" asColor+  thickness <- field "thickness" asLength+  cap <- field "cap" asLineCap+  join <- field "join" asLineJoin+  miterLimit <- field "miter-limit" asMiterLimit+  -- Unknown keys (e.g. `dash` until it is supported) are ignored;+  -- typst rejects them.+  pure $+    emptyStroke+      { paint = paint,+        thickness = thickness,+        cap = cap,+        join = join,+        miterLimit = miterLimit+      }++asColor :: MonadFail m => Val -> m Color+asColor (VColor c) = pure c+asColor _ = fail "paint must be a color"++asLength :: MonadFail m => Val -> m Length+asLength (VLength l) = pure l+asLength _ = fail "thickness must be a length"++-- typst only defines these for specific strings, but we accept any+-- string (a superset of what typst accepts).+asLineCap :: MonadFail m => Val -> m Text+asLineCap (VString s) = pure s+asLineCap _ = fail "cap must be a string"++asLineJoin :: MonadFail m => Val -> m Text+asLineJoin (VString s) = pure s+asLineJoin _ = fail "join must be a string"++asMiterLimit :: MonadFail m => Val -> m Double+asMiterLimit (VFloat x) = pure x+asMiterLimit (VInteger x) = pure (fromIntegral x)+asMiterLimit (VRatio x) = pure (fromRational x)+asMiterLimit _ = fail "miter-limit must be a number"
src/Typst/Types.hs view
@@ -39,6 +39,8 @@     Horiz (..),     Vert (..),     Color (..),+    Stroke (..),+    emptyStroke,     Direction (..),     Identifier (..), -- reexported     lookupIdentifier,@@ -60,7 +62,7 @@ import Data.Functor.Classes (Ord1 (liftCompare)) import qualified Data.Map as M import qualified Data.Map.Ordered as OM-import Data.Maybe (fromMaybe, isJust, catMaybes)+import Data.Maybe (fromMaybe, isJust, isNothing, catMaybes) import Data.Scientific (floatingOrInteger) import Data.Sequence (Seq) import qualified Data.Sequence as Seq@@ -115,6 +117,8 @@   -- only @rgb@, @cmyk@, and @luma@ are available.    -- See issue [#35](https://github.com/jgm/typst-hs/issues/35#issuecomment-1926182040).   | VColor !Color+  -- | A @stroke@ value, representing stroke properties for shapes and lines.+  | VStroke !Stroke   -- | A @symbol@ value, representing a Unicode symbol.   | VSymbol !Symbol   -- | A UTF-8 encoded text @string@.@@ -191,6 +195,7 @@   | TAngle   | TFraction   | TColor+  | TStroke   | TSymbol   | TString   | TRegex@@ -230,6 +235,7 @@     VAngle {} -> TAngle     VFraction {} -> TFraction     VColor {} -> TColor+    VStroke {} -> TStroke     VSymbol {} -> TSymbol     VString {} -> TString     VRegex {} -> TRegex@@ -407,6 +413,8 @@   comp (VAngle x1) (VAngle x2) = Just $ compare x1 x2   comp (VFraction x1) (VFraction x2) = Just $ compare x1 x2   comp (VColor c1) (VColor c2) = Just $ compare c1 c2+  comp (VStroke s1) (VStroke s2) =+    if s1 == s2 then Just EQ else Nothing   comp (VSymbol (Symbol s1 _ _)) (VSymbol (Symbol s2 _ _)) = Just $ compare s1 s2   comp (VString s1) (VString s2) = Just $ compare s1 s2   comp (VPath p1) (VPath p2) = Just $ compare p1 p2@@ -473,11 +481,26 @@   maybePlus (VFraction f1) (VFraction f2) = pure $ VFraction (f1 + f2)   maybePlus (VArray v1) (VArray v2) = pure $ VArray (v1 <> v2)   maybePlus (VDict m1) (VDict m2) = pure $ VDict (m1 OM.<>| m2)+  -- Stroke '1pt + red'   maybePlus (VColor c) (VLength l) =-    -- Stroke '1pt + red'-    pure $ VDict $ OM.fromList [("thickness", VLength l), ("color", VColor c)]+    pure $ VStroke $ emptyStroke { paint = Just c, thickness = Just l }   maybePlus (VLength l) (VColor c) = maybePlus (VColor c) (VLength l)+  -- typst-hs extension: adding to a stroke refines its fields; adding+  -- a stroke merges per field, with the right operand taking precedence.+  maybePlus (VStroke s) (VColor c) = pure $ VStroke s { paint = Just c }+  maybePlus (VStroke s) (VLength l) = pure $ VStroke s { thickness = Just l }+  maybePlus (VStroke s1) (VStroke s2) = pure $ VStroke $ mergeStrokes s1 s2+  maybePlus (VColor c) (VStroke s) =+    pure $ VStroke $ mergeStrokes (emptyStroke { paint = Just c }) s+  maybePlus (VLength l) (VStroke s) =+    pure $ VStroke $ mergeStrokes (emptyStroke { thickness = Just l }) s   maybePlus v1 v2 = fail $ "could not add " <> show v1 <> " and " <> show v2+  -- Typst has no color - length or stroke - length; block the default+  -- negate-and-add, which would otherwise produce a stroke with+  -- negative thickness.+  maybeMinus (VColor _) (VLength _) = Nothing+  maybeMinus (VStroke _) (VLength _) = Nothing+  maybeMinus v1 v2 = maybeNegate v2 >>= maybePlus v1  class Multipliable a where   maybeTimes :: a -> a -> Maybe a@@ -523,9 +546,11 @@   maybeTimes v1 v2 = fail $ "could not multiply " <> show v1 <> " and " <> show v2    maybeDividedBy (VInteger i1) (VInteger i2) =-    if i1 `mod` i2 == 0-      then pure $ VInteger (i1 `div` i2)-      else pure $ VFloat (fromIntegral i1 / fromIntegral i2)+    if i2 == 0+      then fail "division by zero"+      else if i1 `mod` i2 == 0+        then pure $ VInteger (i1 `div` i2)+        else pure $ VFloat (fromIntegral i1 / fromIntegral i2)   maybeDividedBy (VFloat x1) (VFloat x2) = maybeTimes (VFloat x1) (VFloat (1 / x2))   maybeDividedBy (VInteger i1) (VFloat f2) = pure $ VFloat (fromIntegral i1 / f2)   maybeDividedBy (VFloat f1) (VInteger i2) = pure $ VFloat (f1 / fromIntegral i2)@@ -828,6 +853,31 @@   | Luma Rational   deriving (Show, Eq, Ord, Typeable) +data Stroke = Stroke+  { paint :: !(Maybe Color), -- Nothing = auto (default: black)+    thickness :: !(Maybe Length), -- Nothing = auto (default: 1pt)+    cap :: !(Maybe Text), -- Nothing = auto (default: "butt")+    join :: !(Maybe Text), -- Nothing = auto (default: "miter")+    miterLimit :: !(Maybe Double) -- Nothing = auto (default: 4.0)+  }+  deriving (Show, Eq, Typeable)++-- | A stroke with every field unset (auto).+emptyStroke :: Stroke+emptyStroke = Stroke Nothing Nothing Nothing Nothing Nothing++-- | Merge two strokes, with fields set on the second taking precedence+-- (the same per-field semantics as typst's Fold for strokes).+mergeStrokes :: Stroke -> Stroke -> Stroke+mergeStrokes a b =+  Stroke+    { paint = paint b `mplus` paint a,+      thickness = thickness b `mplus` thickness a,+      cap = cap b `mplus` cap a,+      join = join b `mplus` join a,+      miterLimit = miterLimit b `mplus` miterLimit a+    }+ data Direction    = Ltr -- ^ Left to right   | Rtl -- ^ Right to left@@ -835,6 +885,11 @@   | Btt -- ^ Bottom to top   deriving (Show, Eq, Ord, Typeable) +-- | Render a set stroke field for the parenthesized stroke repr.+strokeField :: Text -> Maybe P.Doc -> [P.Doc]+strokeField _ Nothing = []+strokeField k (Just v) = [text k <> ": " <> v]+ prettyVal :: Val -> P.Doc prettyVal expr =   case expr of@@ -885,6 +940,28 @@     VFunction _ _ _ -> mempty     VLabel t -> text $ "<" <> t <> ">"     VCounter _ -> mempty+    VStroke s ->+      -- Matches typst's Repr for Stroke: the simple stroke forms are+      -- used when only paint and thickness are set, otherwise a+      -- parenthesized list of the set fields, in typst's order.+      if isNothing (cap s) && isNothing (join s) && isNothing (miterLimit s)+        then case (paint s, thickness s) of+          (Just p, Just t) ->+            prettyVal (VLength t) <> " + " <> prettyVal (VColor p)+          (Just p, Nothing) -> prettyVal (VColor p)+          (Nothing, Just t) -> prettyVal (VLength t)+          -- typst hardcodes "1pt + black" for the fully-auto stroke+          -- (stroke.rs), even though that repr denotes explicit fields.+          (Nothing, Nothing) -> "1pt + black"+        else+          -- hcat, so the repr is a single line as in typst+          P.parens . P.hcat . P.punctuate ", " . concat $+            ([ strokeField "paint" (prettyVal . VColor <$> paint s),+               strokeField "thickness" (prettyVal . VLength <$> thickness s),+               strokeField "cap" (prettyVal . VString <$> cap s),+               strokeField "join" (prettyVal . VString <$> join s),+               strokeField "miter-limit" (prettyVal . VFloat <$> miterLimit s)+             ] :: [[P.Doc]])     VColor (RGB r g b o) ->       "rgb("         <> text (toPercent r)
src/Typst/Util.hs view
@@ -13,6 +13,7 @@     argsToFields,     nthArg,     namedArg,+    getNamed,     allArgs   ) where
test/typ/compiler/repr-02.out view
@@ -95,8 +95,7 @@                       size: 0.8em),                   text(body: [ ], size: 0.8em),                   linebreak(), -                 text(body: [(thickness: 2.0pt,- color: rgb(96%,63%,1%,100%))], +                 text(body: [2.0pt + rgb(96%,63%,1%,100%)],                        size: 0.8em),                   parbreak(),                   text(body: [
test/typ/compiler/show-selector-00.out view
@@ -150,8 +150,7 @@                        fill: luma(23000%),                         inset: 11.0pt,                         outset: -3.0pt, -                       stroke: (left: (thickness: 1.5pt,-                                       color: luma(18000%)))), +                       stroke: (left: 1.5pt + luma(18000%))),                   parbreak(),                   text(body: [You can use the ]),                   block(body: raw(block: true, @@ -160,8 +159,7 @@                        fill: luma(23000%),                         inset: 11.0pt,                         outset: -3.0pt, -                       stroke: (left: (thickness: 1.5pt,-                                       color: luma(18000%)))), +                       stroke: (left: 1.5pt + luma(18000%))),                   text(body: [ pointer or the ]),                   block(body: raw(block: true, @@ -170,7 +168,6 @@                        fill: luma(23000%),                         inset: 11.0pt,                         outset: -3.0pt, -                       stroke: (left: (thickness: 1.5pt,-                                       color: luma(18000%)))), +                       stroke: (left: 1.5pt + luma(18000%))),                   text(body: [ reference.]),                   parbreak() })
+ test/typ/issue-106.out view
@@ -0,0 +1,83 @@+--- parse tree ---+[ Comment+, SoftBreak+, Code+    "typ/issue-106.typ"+    ( line 2 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (InCollection+              (Literal (String "divider")) (Ident (Identifier "std")))+       , NormalArg (Literal (Boolean True))+       ])+, SoftBreak+, Code+    "typ/issue-106.typ"+    ( line 3 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (InCollection+              (Literal (String "nonexistent")) (Ident (Identifier "std")))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Code+    "typ/issue-106.typ"+    ( line 4 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Not+              (InCollection+                 (Literal (String "divider")) (Ident (Identifier "std"))))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Code+    "typ/issue-106.typ"+    ( line 5 , column 2 )+    (Let+       (BasicBind (Just (Identifier "divider")))+       (If+          [ ( InCollection+                (Literal (String "divider")) (Ident (Identifier "std"))+            , Block (CodeBlock [ Ident (Identifier "divider") ])+            )+          , ( Literal (Boolean True) , Block (CodeBlock [ Literal None ]) )+          ]))+, SoftBreak+, Code+    "typ/issue-106.typ"+    ( line 6 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "str"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "type"))+                     [ NormalArg (Ident (Identifier "divider")) ])+              ])+       , NormalArg (Literal (String "function"))+       ])+, ParBreak+]+--- evaluated ---+document(body: { text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak() })
+ test/typ/issue-106.typ view
@@ -0,0 +1,6 @@+// Test 'in' operator on a module (issue #106).+#test("divider" in std, true)+#test("nonexistent" in std, false)+#test("divider" not in std, false)+#let divider = if "divider" in std { divider } else { none }+#test(str(type(divider)), "function")
test/typ/layout/clip-01.out view
@@ -94,8 +94,7 @@                                parbreak() },                         clip: false,                         height: 2.0em, -                       stroke: (thickness: 1.0pt,-                                color: rgb(0%,0%,0%,100%)), +                       stroke: 1.0pt + rgb(0%,0%,0%,100%),                         width: 5.0em),                   parbreak(),                   v(amount: 2.0em), @@ -106,7 +105,6 @@                                parbreak() },                         clip: true,                         height: 2.0em, -                       stroke: (thickness: 1.0pt,-                                color: rgb(0%,0%,0%,100%)), +                       stroke: 1.0pt + rgb(0%,0%,0%,100%),                         width: 5.0em),                   parbreak() })
test/typ/layout/clip-02.out view
@@ -50,13 +50,11 @@ Emoji: ]),                   box(body: text(body: [🐪, 🌋, 🏞]),                       height: 0.5em, -                     stroke: (thickness: 1.0pt,-                              color: rgb(0%,0%,0%,100%))), +                     stroke: 1.0pt + rgb(0%,0%,0%,100%)),                   parbreak(),                   text(body: [Emoji: ]),                   box(body: text(body: [🐪, 🌋, 🏞]),                       clip: true,                       height: 0.5em, -                     stroke: (thickness: 1.0pt,-                              color: rgb(0%,0%,0%,100%))), +                     stroke: 1.0pt + rgb(0%,0%,0%,100%)),                   parbreak() })
test/typ/layout/clip-03.out view
@@ -72,6 +72,5 @@                                parbreak() },                         clip: true,                         height: 4.0em, -                       stroke: (thickness: 1.0pt,-                                color: rgb(0%,0%,0%,100%))), +                       stroke: 1.0pt + rgb(0%,0%,0%,100%)),                   parbreak() })
test/typ/layout/table-00.out view
@@ -94,6 +94,5 @@                                  1.0fr,                                   1.0fr),                         fill: , -                       stroke: (thickness: 2.0pt,-                                color: rgb(1%,1%,1%,100%))), +                       stroke: 2.0pt + rgb(1%,1%,1%,100%)),                   parbreak() })
test/typ/math/cancel-04.out view
@@ -86,8 +86,7 @@                                        text(body: [−]),                                         math.cancel(body: text(body: [x]),                                                     length: 50%, -                                                   stroke: (thickness: 1.1pt,-                                                            color: rgb(100%,25%,21%,100%))) }, +                                                   stroke: 1.1pt + rgb(100%,25%,21%,100%)) },                                 numbering: none),                   text(body: [ ]), @@ -103,7 +102,6 @@                                                            text(body: [+]),                                                             text(body: [c]) },                                                     length: 50%, -                                                   stroke: (thickness: 1.2pt,-                                                            color: rgb(0%,45%,85%,100%))) }, +                                                   stroke: 1.2pt + rgb(0%,45%,85%,100%)) },                                 numbering: none),                   parbreak() })
+ test/typ/regression/pr-103-calc-quo-zero.out view
@@ -0,0 +1,14 @@+--- parse tree ---+[ Comment+, SoftBreak+, Code+    "typ/regression/pr-103-calc-quo-zero.typ"+    ( line 2 , column 2 )+    (FuncCall+       (FieldAccess+          (Ident (Identifier "quo")) (Ident (Identifier "calc")))+       [ NormalArg (Literal (Int 5)) , NormalArg (Literal (Int 0)) ])+, ParBreak+]+"typ/regression/pr-103-calc-quo-zero.typ" (line 2, column 2):+Module does not have a method "quo" or division by zero
+ test/typ/regression/pr-103-calc-quo-zero.typ view
@@ -0,0 +1,2 @@+// calc.quo with a zero divisor must error, not crash.+#calc.quo(5, 0)
+ test/typ/regression/pr-103-calc-rem-zero.out view
@@ -0,0 +1,14 @@+--- parse tree ---+[ Comment+, SoftBreak+, Code+    "typ/regression/pr-103-calc-rem-zero.typ"+    ( line 2 , column 2 )+    (FuncCall+       (FieldAccess+          (Ident (Identifier "rem")) (Ident (Identifier "calc")))+       [ NormalArg (Literal (Int 5)) , NormalArg (Literal (Int 0)) ])+, ParBreak+]+"typ/regression/pr-103-calc-rem-zero.typ" (line 2, column 2):+Module does not have a method "rem" or division by zero
+ test/typ/regression/pr-103-calc-rem-zero.typ view
@@ -0,0 +1,2 @@+// calc.rem with a zero divisor must error, not crash.+#calc.rem(5, 0)
+ test/typ/regression/pr-103-division-by-zero.out view
@@ -0,0 +1,13 @@+--- parse tree ---+[ Comment+, SoftBreak+, Comment+, SoftBreak+, Code+    "typ/regression/pr-103-division-by-zero.typ"+    ( line 3 , column 2 )+    (Divided (Literal (Int 5)) (Literal (Int 0)))+, ParBreak+]+"typ/regression/pr-103-division-by-zero.typ" (line 3, column 2):+Can't / VInteger 5 and VInteger 0
+ test/typ/regression/pr-103-division-by-zero.typ view
@@ -0,0 +1,3 @@+// Integer division by zero must yield an evaluation error, not crash (uncaught+// Haskell exception) the evaluator.+#(5 / 0)
test/typ/text/deco-01.out view
@@ -78,8 +78,7 @@ There might be ]),                   strike(body: text(body: [redacted]),                          extent: 5.0e-2em, -                        stroke: (thickness: 10.0pt,-                                 color: rgb(67%,80%,93%,53%))), +                        stroke: 10.0pt + rgb(67%,80%,93%,53%)),                   text(body: [ things. underline()]),                   parbreak() })
test/typ/visualize/curve-01.out view
@@ -91,6 +91,5 @@                                                 end: (50.0pt,                                                        0.0pt)),                                      curve.close(mode: "straight")), -                       stroke: (thickness: 2.0pt,-                                color: rgb(100%,25%,21%,100%))), +                       stroke: 2.0pt + rgb(100%,25%,21%,100%)),                   parbreak() })
test/typ/visualize/shape-circle-01.out view
@@ -166,8 +166,7 @@                                     body: text(body: [But, soft!])),                          fill: rgb(92%,32%,47%,100%),                          inset: 0.0pt, -                        stroke: (thickness: 2.0pt,-                                 color: rgb(0%,0%,0%,100%))), +                        stroke: 2.0pt + rgb(0%,0%,0%,100%)),                   parbreak(),                   text(body: [Center-aligned rect in auto-sized circle. ]), 
test/typ/visualize/shape-ellipse-01.out view
@@ -176,8 +176,7 @@                                  parbreak() },                           fill: rgb(18%,80%,25%,100%),                           inset: 3.0pt, -                         stroke: (thickness: 3.0pt,-                                  color: rgb(100%,25%,21%,100%))), +                         stroke: 3.0pt + rgb(100%,25%,21%,100%)),                   parbreak(),                   text(body: [An inline ], 
test/typ/visualize/shape-fill-stroke-00.out view
@@ -171,8 +171,7 @@                                        body: { text(body: [6]),                                                 text(body: [.]) }),                                   rect(height: 10.0pt, -                                      stroke: (thickness: 2.0pt,-                                               color: rgb(13%,61%,67%,100%)), +                                      stroke: 2.0pt + rgb(13%,61%,67%,100%),                                        width: 20.0pt),                                   {  },                                   align(alignment: horizon, @@ -211,8 +210,7 @@                                                text(body: [.]) }),                                   rect(fill: rgb(100%,25%,21%,100%),                                        height: 10.0pt, -                                      stroke: (thickness: 2.0pt,-                                               color: rgb(0%,0%,0%,100%)), +                                      stroke: 2.0pt + rgb(0%,0%,0%,100%),                                        width: 20.0pt),                                   {  },                                   align(alignment: horizon, @@ -220,8 +218,7 @@                                                text(body: [.]) }),                                   rect(fill: rgb(100%,25%,21%,100%),                                        height: 10.0pt, -                                      stroke: (thickness: 2.0pt,-                                               color: rgb(18%,80%,25%,100%)), +                                      stroke: 2.0pt + rgb(18%,80%,25%,100%),                                        width: 20.0pt),                                   {  }),                        columns: (auto, 
test/typ/visualize/shape-fill-stroke-01.out view
@@ -119,6 +119,5 @@ ]),                   box(body: square(fill: rgb(22%,80%,80%,100%),                                    size: 10.0pt, -                                  stroke: (thickness: 2.0pt,-                                           color: rgb(0%,45%,85%,100%)))), +                                  stroke: 2.0pt + rgb(0%,45%,85%,100%))),                   parbreak() })
test/typ/visualize/shape-rect-01.out view
@@ -218,8 +218,7 @@ ]),                   block(body: rect(fill: rgb(27%,70%,76%,100%),                                    height: 15.0pt, -                                  stroke: (thickness: 2.0pt,-                                           color: rgb(13%,28%,58%,100%)))), +                                  stroke: 2.0pt + rgb(13%,28%,58%,100%))),                   parbreak(),                   text(body: [ ]), 
test/typ/visualize/stroke-00.out view
@@ -103,8 +103,7 @@                  text(body: [ ]),                   line(length: 60.0pt, -                      stroke: (thickness: 1.5pt,-                               color: rgb(0%,45%,85%,100%))), +                      stroke: 1.5pt + rgb(0%,45%,85%,100%)),                   text(body: [ ]),                   v(amount: 3.0pt), 
test/typ/visualize/stroke-07.out view
@@ -224,8 +224,7 @@ ]),                   rect(fill: rgb(0%,45%,85%,100%),                        height: 10.0pt, -                      stroke: (thickness: 0.0pt,-                               color: rgb(100%,25%,21%,100%)), +                      stroke: 0.0pt + rgb(100%,25%,21%,100%),                        width: 10.0pt),                   parbreak(),                   line(length: 30.0pt, 
+ test/typ/visualize/stroke-08.out view
@@ -0,0 +1,491 @@+--- parse tree ---+[ Comment+, ParBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 3 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Plus (Literal (Numeric 2.0 Pt)) (Ident (Identifier "red")))+                 ]))+       , NormalArg (Ident (Identifier "red"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 4 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Plus (Literal (Numeric 2.0 Pt)) (Ident (Identifier "red")))+                 ]))+       , NormalArg (Literal (Numeric 2.0 Pt))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 5 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "paint") (Ident (Identifier "blue")) ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 6 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 3.0 Pt)) ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 7 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Ident (Identifier "red")) ]))+       , NormalArg (Ident (Identifier "red"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 8 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 3.0 Pt)) ]))+       , NormalArg (Literal (Numeric 3.0 Pt))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 9 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "paint") (Literal Auto) ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 10 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "thickness") (Literal Auto) ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 11 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict [ Reg ( Ident (Identifier "paint") , Literal Auto ) ])+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 12 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "thickness") , Literal (Numeric 2.0 Pt) )+                        ])+                 ]))+       , NormalArg (Literal (Numeric 2.0 Pt))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 13 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "paint") , Ident (Identifier "blue") )+                        , Reg ( Ident (Identifier "thickness") , Literal (Numeric 2.0 Pt) )+                        ])+                 ]))+       , NormalArg (Ident (Identifier "blue"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 14 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "paint") (Ident (Identifier "red")) ])+                 ]))+       , NormalArg (Ident (Identifier "red"))+       ])+, ParBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 16 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red"))))+       , NormalArg (Ident (Identifier "red"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 17 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red"))))+       , NormalArg (Literal (Numeric 1.0 Pt))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 18 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (Plus (Ident (Identifier "red")) (Literal (Numeric 1.0 Pt))))+       , NormalArg (Ident (Identifier "red"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 19 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (Plus (Ident (Identifier "red")) (Literal (Numeric 1.0 Pt))))+       , NormalArg (Literal (Numeric 1.0 Pt))+       ])+, ParBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 21 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 1.0 Pt)) ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 1.0 Pt)) ]))+       , NormalArg (Literal (Boolean True))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 22 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 1.0 Pt)) ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 2.0 Pt)) ]))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 23 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Literal (Numeric 1.0 Pt)) ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg (Ident (Identifier "red")) ]))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 25 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall (Ident (Identifier "stroke")) [])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "paint") (Ident (Identifier "black")) ]))+       , NormalArg (Literal (Boolean False))+       ])+, ParBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 27 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "type"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg (Literal (Numeric 1.0 Pt)) ])+              ])+       , NormalArg (Literal (String "stroke"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 28 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "type"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg (Literal (Numeric 1.0 Pt)) ])+              ])+       , NormalArg (Ident (Identifier "stroke"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 29 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "type"))+              [ NormalArg+                  (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+              ])+       , NormalArg (Ident (Identifier "stroke"))+       ])+, ParBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 32 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus (Literal (Numeric 2.0 Pt)) (Ident (Identifier "red")))+              ])+       , NormalArg (Literal (String "2.0pt + rgb(100%,25%,21%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 33 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg (Ident (Identifier "red")) ])+              ])+       , NormalArg (Literal (String "rgb(100%,25%,21%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 34 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg (Literal (Numeric 2.0 Pt)) ])+              ])+       , NormalArg (Literal (String "2.0pt"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-08.typ"+    ( line 35 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg (FuncCall (Ident (Identifier "stroke")) []) ])+       , NormalArg (Literal (String "1pt + black"))+       ])+, ParBreak+]+--- evaluated ---+document(body: { parbreak(), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak() })
+ test/typ/visualize/stroke-08.typ view
@@ -0,0 +1,35 @@+// Test the stroke type: constructor, field access, arithmetic, equality++#test(stroke(2pt + red).paint, red)+#test(stroke(2pt + red).thickness, 2pt)+#test(stroke(paint: blue).thickness, auto)+#test(stroke(3pt).paint, auto)+#test(stroke(red).paint, red)+#test(stroke(3pt).thickness, 3pt)+#test(stroke(paint: auto).paint, auto)+#test(stroke(thickness: auto).thickness, auto)+#test(stroke((paint: auto)).paint, auto)+#test(stroke((thickness: 2pt)).thickness, 2pt)+#test(stroke((paint: blue, thickness: 2pt)).paint, blue)+#test(stroke(stroke(paint: red)).paint, red)++#test((1pt + red).paint, red)+#test((1pt + red).thickness, 1pt)+#test((red + 1pt).paint, red)+#test((red + 1pt).thickness, 1pt)++#test(stroke(1pt) == stroke(1pt), true)+#test(stroke(1pt) == stroke(2pt), false)+#test(stroke(1pt) == stroke(red), false)+// an explicitly set field differs from auto, as in typst+#test(stroke() == stroke(paint: black), false)++#test(type(stroke(1pt)), "stroke")+#test(type(stroke(1pt)), stroke)+#test(type(1pt + red), stroke)++// repr, matching typst's simple stroke forms+#test(repr(2pt + red), "2.0pt + rgb(100%,25%,21%,100%)")+#test(repr(stroke(red)), "rgb(100%,25%,21%,100%)")+#test(repr(stroke(2pt)), "2.0pt")+#test(repr(stroke()), "1pt + black")
+ test/typ/visualize/stroke-09.out view
@@ -0,0 +1,1081 @@+--- parse tree ---+[ Comment+, ParBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 4 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "cap") (Literal (String "round")) ]))+       , NormalArg (Literal (String "round"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 5 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "join"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "join") (Literal (String "bevel")) ]))+       , NormalArg (Literal (String "bevel"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 6 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "miter-limit"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "miter-limit") (Literal (Float 2.5)) ]))+       , NormalArg (Literal (Float 2.5))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 7 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "miter-limit"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "miter-limit") (Literal (Int 4)) ]))+       , NormalArg (Literal (Float 4.0))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 8 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "type"))+              [ NormalArg+                  (FieldAccess+                     (Ident (Identifier "cap"))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ]))+              ])+       , NormalArg (Literal (String "string"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 9 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "type"))+              [ NormalArg+                  (FieldAccess+                     (Ident (Identifier "miter-limit"))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "miter-limit") (Literal (Float 2.5)) ]))+              ])+       , NormalArg (Literal (String "float"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 10 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "cap") , Literal (String "square") )+                        , Reg ( Ident (Identifier "miter-limit") , Literal (Float 2.0) )+                        ])+                 ]))+       , NormalArg (Literal (String "square"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 11 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "join"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "join") , Literal (String "round") ) ])+                 ]))+       , NormalArg (Literal (String "round"))+       ])+, ParBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 14 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 15 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "join"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 16 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "miter-limit"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+                 ]))+       , NormalArg (Literal Auto)+       ])+, ParBreak+, Comment+, SoftBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 20 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+                 ]))+       , NormalArg (Literal (String "round"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 21 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+                 , KeyValArg (Identifier "cap") (Literal Auto)+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 22 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "join"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "cap") , Literal (String "round") ) ])+                 , KeyValArg (Identifier "join") (Literal (String "bevel"))+                 ]))+       , NormalArg (Literal (String "bevel"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 23 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict [ Reg ( Ident (Identifier "cap") , Literal Auto ) ])+                 ]))+       , NormalArg (Literal Auto)+       ])+, ParBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 26 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "cap") (Literal (String "round")) ]))+       , NormalArg (Literal (Boolean True))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 27 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+              (FuncCall (Ident (Identifier "stroke")) []))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 28 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "join") (Literal (String "bevel")) ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "join") (Literal (String "round")) ]))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 29 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "miter-limit") (Literal (Int 4)) ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "miter-limit") (Literal (Float 4.0)) ]))+       , NormalArg (Literal (Boolean True))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 30 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "miter-limit") (Literal (Int 4)) ])+              (FuncCall (Ident (Identifier "stroke")) []))+       , NormalArg (Literal (Boolean False))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 31 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "cap") (Literal (String "round"))+                 , KeyValArg (Identifier "join") (Literal (String "bevel"))+                 ])+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "join") (Literal (String "bevel"))+                 , KeyValArg (Identifier "cap") (Literal (String "round"))+                 ]))+       , NormalArg (Literal (Boolean True))+       ])+, ParBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 34 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+              ])+       , NormalArg (Literal (String "(cap: \"round\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 35 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "join") (Literal (String "bevel")) ])+              ])+       , NormalArg (Literal (String "(join: \"bevel\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 36 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "miter-limit") (Literal (Float 3.0)) ])+              ])+       , NormalArg (Literal (String "(miter-limit: 3.0)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 37 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "miter-limit") (Literal (Int 4)) ])+              ])+       , NormalArg (Literal (String "(miter-limit: 4.0)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 38 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "paint") (Ident (Identifier "red"))+                     , KeyValArg (Identifier "cap") (Literal (String "round"))+                     ])+              ])+       , NormalArg+           (Literal+              (String "(paint: rgb(100%,25%,21%,100%), cap: \"round\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 39 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "thickness") (Literal (Numeric 2.0 Pt))+                     , KeyValArg (Identifier "miter-limit") (Literal (Float 4.0))+                     ])+              ])+       , NormalArg+           (Literal (String "(thickness: 2.0pt, miter-limit: 4.0)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 40 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg+                         (Dict+                            [ Reg ( Ident (Identifier "paint") , Ident (Identifier "red") )+                            , Reg ( Ident (Identifier "cap") , Literal (String "round") )+                            , Reg ( Ident (Identifier "miter-limit") , Literal (Float 2.0) )+                            , Reg ( Ident (Identifier "thickness") , Literal (Numeric 1.0 Pt) )+                            ])+                     ])+              ])+       , NormalArg+           (Literal+              (String+                 "(paint: rgb(100%,25%,21%,100%), thickness: 1.0pt, cap: \"round\", miter-limit: 2.0)"))+       ])+, SoftBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 42 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg+                         (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+                     ])+              ])+       , NormalArg (Literal (String "1.0pt + rgb(100%,25%,21%,100%)"))+       ])+, ParBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 45 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Plus (Literal (Numeric 2.0 Pt)) (Ident (Identifier "red")))+                     (Ident (Identifier "blue")))+              ])+       , NormalArg (Literal (String "2.0pt + rgb(0%,45%,85%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 46 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Plus (Literal (Numeric 2.0 Pt)) (Ident (Identifier "red")))+                     (Literal (Numeric 3.0 Pt)))+              ])+       , NormalArg (Literal (String "3.0pt + rgb(100%,25%,21%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 47 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+                     (Literal (Numeric 2.0 Pt)))+              ])+       , NormalArg (Literal (String "(thickness: 2.0pt, cap: \"round\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 48 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ]))+              ])+       , NormalArg+           (Literal+              (String+                 "(paint: rgb(100%,25%,21%,100%), thickness: 1.0pt, cap: \"round\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 49 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "join") (Literal (String "bevel")) ]))+              ])+       , NormalArg (Literal (String "(cap: \"round\", join: \"bevel\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 50 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "round")) ])+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "cap") (Literal (String "square")) ]))+              ])+       , NormalArg (Literal (String "(cap: \"square\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 51 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "paint") (Ident (Identifier "red"))+                        , KeyValArg (Identifier "cap") (Literal (String "round"))+                        ])+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "paint") (Ident (Identifier "blue")) ]))+              ])+       , NormalArg+           (Literal (String "(paint: rgb(0%,45%,85%,100%), cap: \"round\")"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 52 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (Equals+              (Plus+                 (Plus (Literal (Numeric 2.0 Pt)) (Ident (Identifier "red")))+                 (Literal (Numeric 3.0 Pt)))+              (Plus (Literal (Numeric 3.0 Pt)) (Ident (Identifier "red"))))+       , NormalArg (Literal (Boolean True))+       ])+, SoftBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 54 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Ident (Identifier "blue"))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ NormalArg (Literal (Numeric 2.0 Pt)) ]))+              ])+       , NormalArg (Literal (String "2.0pt + rgb(0%,45%,85%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 55 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Ident (Identifier "blue"))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ NormalArg (Literal (Numeric 2.0 Pt))+                        , KeyValArg (Identifier "paint") (Ident (Identifier "red"))+                        ]))+              ])+       , NormalArg (Literal (String "2.0pt + rgb(100%,25%,21%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 56 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Literal (Numeric 2.0 Pt))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ KeyValArg (Identifier "paint") (Ident (Identifier "red")) ]))+              ])+       , NormalArg (Literal (String "2.0pt + rgb(100%,25%,21%,100%)"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 57 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (Plus+                     (Literal (Numeric 2.0 Pt))+                     (FuncCall+                        (Ident (Identifier "stroke"))+                        [ NormalArg (Literal (Numeric 3.0 Pt))+                        , KeyValArg (Identifier "cap") (Literal (String "round"))+                        ]))+              ])+       , NormalArg (Literal (String "(thickness: 3.0pt, cap: \"round\")"))+       ])+, ParBreak+, Comment+, SoftBreak+, Comment+, SoftBreak+, Comment+, SoftBreak+, Comment+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 63 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "paint") (Literal None) ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 64 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Plus (Literal (Numeric 1.0 Pt)) (Ident (Identifier "red")))+                 , KeyValArg (Identifier "paint") (Literal None)+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 65 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "paint"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict [ Reg ( Ident (Identifier "paint") , Literal None ) ])+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 66 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "thickness"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict [ Reg ( Ident (Identifier "thickness") , Literal None ) ])+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 67 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg (Identifier "cap") (Literal (String "bogus")) ]))+       , NormalArg (Literal (String "bogus"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 68 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "miter-limit"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ KeyValArg+                     (Identifier "miter-limit") (Literal (Numeric 250.0 Percent))+                 ]))+       , NormalArg (Literal (Float 2.5))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 69 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "cap") , Literal (String "round") )+                        , Reg ( Ident (Identifier "bogus") , Literal (Int 1) )+                        ])+                 ]))+       , NormalArg (Literal (String "round"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 70 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FieldAccess+              (Ident (Identifier "cap"))+              (FuncCall+                 (Ident (Identifier "stroke"))+                 [ NormalArg+                     (Dict+                        [ Reg ( Ident (Identifier "dash") , Literal (String "dashed") ) ])+                 ]))+       , NormalArg (Literal Auto)+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 71 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ KeyValArg (Identifier "dash") (Literal (String "dashed")) ])+              ])+       , NormalArg (Literal (String "1pt + black"))+       ])+, SoftBreak+, Code+    "typ/visualize/stroke-09.typ"+    ( line 72 , column 2 )+    (FuncCall+       (Ident (Identifier "test"))+       [ NormalArg+           (FuncCall+              (Ident (Identifier "repr"))+              [ NormalArg+                  (FuncCall+                     (Ident (Identifier "stroke"))+                     [ NormalArg (Literal (Numeric 2.0 Pt))+                     , KeyValArg (Identifier "dash") (Literal (String "dashed"))+                     ])+              ])+       , NormalArg (Literal (String "2.0pt"))+       ])+, ParBreak+]+--- evaluated ---+document(body: { parbreak(), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak(), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 text(body: [+]), +                 text(body: [✅]), +                 parbreak() })
+ test/typ/visualize/stroke-09.typ view
@@ -0,0 +1,72 @@+// Test the cap, join, and miter-limit stroke fields.++// constructor and dictionary fields+#test(stroke(cap: "round").cap, "round")+#test(stroke(join: "bevel").join, "bevel")+#test(stroke(miter-limit: 2.5).miter-limit, 2.5)+#test(stroke(miter-limit: 4).miter-limit, 4.0)+#test(type(stroke(cap: "round").cap), "string")+#test(type(stroke(miter-limit: 2.5).miter-limit), "float")+#test(stroke((cap: "square", miter-limit: 2.0)).cap, "square")+#test(stroke((join: "round")).join, "round")++// unset fields are auto+#test(stroke(1pt + red).cap, auto)+#test(stroke(1pt + red).join, auto)+#test(stroke(1pt + red).miter-limit, auto)++// a named argument overrides the base, and auto resets it; combining a+// base with named arguments is a typst-hs extension+#test(stroke(stroke(cap: "round")).cap, "round")+#test(stroke(stroke(cap: "round"), cap: auto).cap, auto)+#test(stroke((cap: "round"), join: "bevel").join, "bevel")+#test(stroke((cap: auto)).cap, auto)++// equality, including an explicitly set field vs auto+#test(stroke(cap: "round") == stroke(cap: "round"), true)+#test(stroke(cap: "round") == stroke(), false)+#test(stroke(join: "bevel") == stroke(join: "round"), false)+#test(stroke(miter-limit: 4) == stroke(miter-limit: 4.0), true)+#test(stroke(miter-limit: 4) == stroke(), false)+#test(stroke(cap: "round", join: "bevel") == stroke(join: "bevel", cap: "round"), true)++// repr, matching typst's parenthesized stroke form+#test(repr(stroke(cap: "round")), "(cap: \"round\")")+#test(repr(stroke(join: "bevel")), "(join: \"bevel\")")+#test(repr(stroke(miter-limit: 3.0)), "(miter-limit: 3.0)")+#test(repr(stroke(miter-limit: 4)), "(miter-limit: 4.0)")+#test(repr(stroke(paint: red, cap: "round")), "(paint: rgb(100%,25%,21%,100%), cap: \"round\")")+#test(repr(stroke(thickness: 2pt, miter-limit: 4.0)), "(thickness: 2.0pt, miter-limit: 4.0)")+#test(repr(stroke((paint: red, cap: "round", miter-limit: 2.0, thickness: 1pt))), "(paint: rgb(100%,25%,21%,100%), thickness: 1.0pt, cap: \"round\", miter-limit: 2.0)")+// the simple forms still apply when these fields are unset+#test(repr(stroke(1pt + red)), "1.0pt + rgb(100%,25%,21%,100%)")++// typst-hs extension: adding to a stroke refines or merges fields+#test(repr((2pt + red) + blue), "2.0pt + rgb(0%,45%,85%,100%)")+#test(repr((2pt + red) + 3pt), "3.0pt + rgb(100%,25%,21%,100%)")+#test(repr(stroke(cap: "round") + 2pt), "(thickness: 2.0pt, cap: \"round\")")+#test(repr((1pt + red) + stroke(cap: "round")), "(paint: rgb(100%,25%,21%,100%), thickness: 1.0pt, cap: \"round\")")+#test(repr(stroke(cap: "round") + stroke(join: "bevel")), "(cap: \"round\", join: \"bevel\")")+#test(repr(stroke(cap: "round") + stroke(cap: "square")), "(cap: \"square\")")+#test(repr(stroke(paint: red, cap: "round") + stroke(paint: blue)), "(paint: rgb(0%,45%,85%,100%), cap: \"round\")")+#test((2pt + red) + 3pt == 3pt + red, true)+// likewise with the stroke as the right operand+#test(repr(blue + stroke(2pt)), "2.0pt + rgb(0%,45%,85%,100%)")+#test(repr(blue + stroke(2pt, paint: red)), "2.0pt + rgb(100%,25%,21%,100%)")+#test(repr(2pt + stroke(paint: red)), "2.0pt + rgb(100%,25%,21%,100%)")+#test(repr(2pt + stroke(3pt, cap: "round")), "(thickness: 3.0pt, cap: \"round\")")++// typst-hs leniency, accepted though typst rejects it: `none` resets a+// field like `auto`, and any string or number works for cap, join, and+// miter-limit. Unknown dictionary keys are ignored, and `dash` values+// are dropped until dash is supported (typst accepts them).+#test(stroke(paint: none).paint, auto)+#test(stroke(1pt + red, paint: none).paint, auto)+#test(stroke((paint: none)).paint, auto)+#test(stroke((thickness: none)).thickness, auto)+#test(stroke(cap: "bogus").cap, "bogus")+#test(stroke(miter-limit: 250%).miter-limit, 2.5)+#test(stroke((cap: "round", bogus: 1)).cap, "round")+#test(stroke((dash: "dashed")).cap, auto)+#test(repr(stroke(dash: "dashed")), "1pt + black")+#test(repr(stroke(2pt, dash: "dashed")), "2.0pt")
typst.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               typst-version:            0.11.0.1+version:            0.12 synopsis:           Parsing and evaluating typst syntax. description:        A library for parsing and evaluating typst syntax.                     Typst (<https://typst.app>) is a document layout and