packages feed

typst 0.6 → 0.6.1

raw patch · 19 files changed

+432/−116 lines, 19 filesdep ~typst-symbols

Dependency ranges changed: typst-symbols

Files

CHANGELOG.md view
@@ -1,5 +1,59 @@ # Revision history for typst-hs +## 0.6.1++  * Fix precedence for functions (#55).+    `1(x)` and `!(x)` should not be parsed as functions.+    Note that we still don't match typst's behavior for `f_"!"(x)`.+    For us this works just like `f_!(x)`, but for typst we get+    a function in the subscript for the former but not the latter.+    Fixing this would require some changes in the types.++  * Define sys.version and sys.inputs.typst-hs-version (#56).+    The former is set to the version of typst we are trying to+    implement. The latter is a stringified version number from typst-hs.+    This will allow typst programs to tell when they're running+    on typst-hs (or pandoc), and react accordingly.++  * Rename stBeforeSpace -> stSpaceBefore to avoid confusion.++  * Fix precedence issues in math parsing (#54).+    Increased precedence of ! (factorial).+    `_` or `^` should eagerly gobble a grouped argument (`c_(a)`).++  * Minimal support for `context` (#53). Parse `context` keyword.+    New Context constructor in Expr [API change].+    Evaluate this by just evaluating the expression, for now.+    Note that we don't support the features (like location or+    numbering) that context is used to affect anyway, so this change+    probably won't be enough for meaningful support. But it might+    prevent some documents from issuing errors.++  * Arguments at method.++  * Array windows, reduce, to-dict methods.++  * Allow parentheses in import.++  * Make standard module available under std (typst 0.12).++  * Add over/underparen, over/undershell in math module.++  * Add stretch function.++  * Add skew.++  * Depend on typst-symbols 0.1.7 and start to target typst 0.12.++  * Reset indentation requirements inside `[]` content block. e.g.+    ```+    / B: #block[+    - a+    ]+    ```+    We don't need indentation inside the block content.++ ## 0.6    * Recognize figure.caption function (#52).
src/Typst/Evaluate.hs view
@@ -69,10 +69,11 @@ initialEvalState =   emptyEvalState { evalIdentifiers = [(BlockScope, mempty)]                  , evalMathIdentifiers = [(BlockScope, mathModule <> symModule)]-                 , evalStandardIdentifiers = [(BlockScope, standardModule')]+                 , evalStandardIdentifiers = [(BlockScope, standardModule'')]                  }   where     standardModule' = M.insert "eval" evalFunction standardModule+    standardModule'' = M.insert "std" (VModule "std" standardModule') standardModule'     evalFunction = makeFunction $ do       code :: Text <- nthArg 1       case parseTypst "eval" ("#{\n" <> code <> "\n}") of@@ -815,6 +816,8 @@         _ -> fail $ "For expression requires an Array or Dictionary"       updateState $ \st -> st {evalFlowDirective = FlowNormal}       go items VNone+    Context e -> do+      evalExpr e -- TODO for now we just ignore "context"     Return mbe -> do       -- these flow directives are examined in CodeBlock       updateState (\st -> st {evalFlowDirective = FlowReturn (isJust mbe)})
src/Typst/Methods.hs view
@@ -521,6 +521,12 @@           Function fn <- nthArg 2           let f acc y = fn Arguments {positional = [acc, y], named = OM.empty}           lift $ foldM f start $ V.toList v+        "reduce" -> pure $ makeFunction $ do+          Function fn <- nthArg 1+          let f acc y = fn Arguments {positional = [acc, y], named = OM.empty}+          case V.toList v of+            [] -> pure VNone+            (x:xs) -> lift $ foldM f x xs         "any" -> pure $ makeFunction $ do           Function fn <- nthArg 1           let predicate y = do@@ -566,6 +572,21 @@                                 VArray v' -> v' V.!? i                                 _ -> Nothing) (val : xs)))               (V.enumFromTo 0 (len - 1))+        "to-dict" -> pure $ makeFunction $+          VDict . OM.fromList <$>+                 mapM (\x -> do+                         vx <- fromVal x+                         case V.toList vx of+                           [a,b] -> do+                             k <- fromVal a+                             pure (Identifier k, b)+                           _ -> fail "vector has wrong shape") (V.toList v)+        "windows" -> pure $ makeFunction $ do+          (windowsize :: Int) <- nthArg 1+          case V.length v - windowsize of+            n | n < 0 -> pure $ VArray mempty+              | otherwise -> pure $ VArray $ V.fromList $+                   map (\x -> VArray $ V.take windowsize $ V.drop x v) [0..n]         "sum" -> pure $ makeFunction $ do           mbv <- namedArg "default" Nothing           case V.uncons v of@@ -638,6 +659,21 @@     VArguments args ->       case fld of         "pos" -> pure $ makeFunction $ pure $ VArray $ V.fromList (positional args)+        "at" ->+          pure $ makeFunction $ do+            (x :: Val) <- nthArg 1+            defval <- namedArg "default" VNone+            case x of+              VInteger{} -> do+                i <- fromVal x+                case positional args of+                  xs | i < length xs -> pure $ xs !! i+                     | otherwise -> pure defval+              VString t ->+                case OM.lookup (Identifier t) (named args) of+                  Just a -> pure a+                  Nothing -> pure defval+              _ -> pure defval         "named" -> pure $ makeFunction $ pure $ VDict $ named args         _ -> noMethod "Arguments" fld     VDateTime mbdate mbtime -> do
src/Typst/Module/Math.hs view
@@ -74,6 +74,11 @@       makeElement (Just "math") "op" [("text", One TAny)],       makeElement (Just "math") "underline" [("body", One TContent)],       makeElement (Just "math") "overline" [("body", One TContent)],+      makeElement (Just "math") "underparen" [("body", One TContent)],+      makeElement (Just "math") "undershell" [("body", One TContent)],+      makeElement (Just "math") "overparen" [("body", One TContent)],+      makeElement (Just "math") "overshell" [("body", One TContent)],+      makeElement (Just "math") "stretch" [("body", One TContent)],       makeElement         (Just "math")         "underbrace"
src/Typst/Module/Standard.hs view
@@ -13,6 +13,8 @@   ) where +import Paths_typst (version)+import Data.Version (showVersion) import Data.Char (ord, chr) import Control.Applicative ((<|>)) import Control.Monad (mplus, unless)@@ -72,7 +74,11 @@  sysModule :: M.Map Identifier Val sysModule =-  M.fromList [ makeElement (Just "sys") "version" [] ]+  M.fromList [ ("version", VVersion [0,12,0])+             , ("inputs", VDict (OM.fromList+                                  [("typst-hs-version",+                                    VString (T.pack (showVersion version)))]))+             ]  symModule :: M.Map Identifier Val symModule = M.map VSymbol $ makeSymbolMap typstSymbols@@ -132,6 +138,7 @@       [ ("alignment", One TAlignment),         ("body", One TContent)       ],+    makeElement Nothing "skew" [("body", One TContent)],     makeElement Nothing "block" [("body", One TContent)],     makeElement Nothing "box" [("body", One TContent)],     makeElement Nothing "colbreak" [],
src/Typst/Parse.hs view
@@ -40,7 +40,8 @@   { stIndent :: [Int],     stLineStartCol :: !Int,     stAllowNewlines :: !Int, -- allow newlines if > 0-    stBeforeSpace :: Maybe (SourcePos, Text),+    stSpaceBefore :: Maybe (SourcePos, Text),+    stLastMathTok :: Maybe (SourcePos, Markup),     stContentBlockNesting :: Int   }   deriving (Show)@@ -51,7 +52,8 @@     { stIndent = [],       stLineStartCol = 1,       stAllowNewlines = 0,-      stBeforeSpace = Nothing,+      stSpaceBefore = Nothing,+      stLastMathTok = Nothing,       stContentBlockNesting = 0     } @@ -69,9 +71,9 @@         | allowNewlines > 0 = isSpace c         | otherwise = isSpace c && c /= '\r' && c /= '\n'   ( skipMany1 (void (satisfy isSp) <|> void pComment)-      *> updateState (\st -> st {stBeforeSpace = Just (p1, inp)})+      *> updateState (\st -> st {stSpaceBefore = Just (p1, inp)})     )-    <|> updateState (\st -> st {stBeforeSpace = Nothing})+    <|> updateState (\st -> st {stSpaceBefore = Nothing})  lexeme :: P a -> P a lexeme pa = pa <* ws@@ -164,32 +166,52 @@  mathOperatorTable :: [[Operator Text PState Identity Markup]] mathOperatorTable =-  [ -- precedence 7 -- attachment with number, e.g. a_1 (see #17)-    [ Infix (attachBottom <$ (try (op "_" *> lookAhead mNumber))) AssocLeft,-      Infix (attachTop <$ (try (op "^" *> lookAhead mNumber))) AssocLeft+  [ -- precedence 7 -- attachment with number, e.g. a_1 (#17), or (..) group+    [ Infix (attachBottom <$ (try (op "_" *> lookAhead (mNumber <|> mGroup))))+        AssocLeft,+      Infix (attachTop <$ (try (op "^" *> lookAhead (mNumber <|> mGroup))))+        AssocLeft     ],     -- precedence 6     [ Postfix         ( try $ do-            mbBeforeSpace <- stBeforeSpace <$> getState+            getState >>= guard . isNothing . stSpaceBefore             -- NOTE: can't have space before () or [] arg in a             -- function call! to prevent bugs with e.g. 'if 2<3 [...]'.-            guard $ isNothing mbBeforeSpace+            pos <- getPosition+            lastMathTok <- stLastMathTok <$> getState+            -- 1(a) is not a function+            -- !(a) is not a function+            -- f(a) is a function+            -- "alpha"(a) is a function+            -- alpha(a) is a function+            -- see #55+            -- but we still don't match typst for "!"(a), which typst DOES consider+            -- a function+            guard $ case lastMathTok of+                      Just (pos', MGroup _ (Just t) _)+                        | pos == pos' -> T.all isLetter t+                      Just (pos', Text t)+                        | pos == pos'+                        -> case T.unsnoc t of+                                  Nothing -> True+                                  Just (_,c) -> isLetter c+                      _ -> True             args <- mGrouped '(' ')' True             pure $ \expr -> MGroup Nothing Nothing [expr, args]         )     ],-    -- precedence 5 -- attachment with non-number, e.g. a_x-    [ Infix (attachBottom <$ op "_") AssocLeft,-      Infix (attachTop <$ op "^") AssocLeft-    ],-    -- precedence 4  -- factorial needs to take precedence over fraction+    -- precedence 5  -- factorial needs to take precedence over fraction     [ Postfix (try $ do-                  mbBeforeSpace <- stBeforeSpace <$> getState+                  mbBeforeSpace <- stSpaceBefore <$> getState                   guard $ isNothing mbBeforeSpace                   lexeme $ char '!' *> notFollowedBy (char '=')                   pure (\expr -> MGroup Nothing Nothing [expr, Text "!"]))     ],+    -- precedence 4 -- attachment with non-number, e.g. a_x+    [ Infix (attachBottom <$ op "_") AssocLeft,+      Infix (attachTop <$ op "^") AssocLeft+    ],     -- precedence 3     [ Infix (makeFrac <$ op "/") AssocLeft     ]@@ -231,7 +253,7 @@ mathFunctionCall =   Postfix     ( do-        mbBeforeSpace <- stBeforeSpace <$> getState+        mbBeforeSpace <- stSpaceBefore <$> getState         -- NOTE: can't have space before () or [] arg in a         -- function call! to prevent bugs with e.g. 'if 2<3 [...]'.         guard $ isNothing mbBeforeSpace@@ -275,7 +297,8 @@ pMath = buildExpressionParser mathOperatorTable pBaseMath  pBaseMath :: P Markup-pBaseMath = mNumber+pBaseMath = do+  tok <-    mNumber         <|> mLiteral         <|> mEscaped         <|> mShorthand@@ -286,6 +309,9 @@         <|> mCode         <|> mMid         <|> mSymbol+  pos <- getPosition+  updateState $ \s -> s{ stLastMathTok = Just (pos, tok) }+  pure tok  mGroup :: P Markup mGroup = mGrouped '(' ')' False@@ -314,10 +340,10 @@  mLiteral :: P Markup mLiteral = do-  mbBeforeSpace <- stBeforeSpace <$> getState+  mbBeforeSpace <- stSpaceBefore <$> getState   String t <- pStr   -- ensure space in e.g. x "is natural":-  mbAfterSpace <- stBeforeSpace <$> getState+  mbAfterSpace <- stSpaceBefore <$> getState   pure $     Text $       (maybe "" (const " ") mbBeforeSpace)@@ -384,7 +410,7 @@  mMid :: P Markup mMid = try $ do-  getState >>= guard . isJust . stBeforeSpace+  getState >>= guard . isJust . stSpaceBefore   void $ char '|' *> space *> ws   pure $ MGroup Nothing Nothing [Nbsp, Text "|", Nbsp] @@ -710,7 +736,7 @@   void $ char '#'   res <- Code <$> getPosition <*> pBasicExpr <* optional (sym ";")   -- rewind if we gobbled space:-  mbBeforeSpace <- stBeforeSpace <$> getState+  mbBeforeSpace <- stSpaceBefore <$> getState   case mbBeforeSpace of     Nothing -> pure ()     Just (pos, inp) -> do@@ -831,7 +857,7 @@ functionCall =   Postfix     ( do-        mbBeforeSpace <- stBeforeSpace <$> getState+        mbBeforeSpace <- stSpaceBefore <$> getState         -- NOTE: can't have space before () or [] arg in a         -- function call! to prevent bugs with e.g. 'if 2<3 [...]'.         guard $ isNothing mbBeforeSpace@@ -990,11 +1016,13 @@   void $ char '['   col <- sourceColumn <$> getPosition   oldLineStartCol <- stLineStartCol <$> getState+  oldIndent <- stIndent <$> getState   updateState $ \st ->     st       { stLineStartCol = col,         stContentBlockNesting =-          stContentBlockNesting st + 1+          stContentBlockNesting st + 1,+        stIndent = []       }   ms <- manyTill pMarkup (char ']')   ws@@ -1002,7 +1030,8 @@     st       { stLineStartCol = oldLineStartCol,         stContentBlockNesting =-          stContentBlockNesting st - 1+          stContentBlockNesting st - 1,+        stIndent = oldIndent       }   pure $ Content ms @@ -1064,6 +1093,7 @@     <|> pBreakExpr     <|> pContinueExpr     <|> pReturnExpr+    <|> pContextExpr  -- args ::= ('(' (arg (',' arg)* ','?)? ')' content-block*) | content-block+ pArgs :: P [Arg]@@ -1072,7 +1102,7 @@   args <- option [] $ inParens $ sepEndBy pArg (sym ",")   blocks <- many $ do     -- make sure we haven't had a space-    skippedSpaces <- isJust . stBeforeSpace <$> getState+    skippedSpaces <- isJust . stSpaceBefore <$> getState     if skippedSpaces       then mzero       else do@@ -1206,10 +1236,11 @@     pImportItems =         (sym ":"           *> ( (AllIdentifiers <$ sym "*")-                 <|> (SomeIdentifiers-                       <$> sepEndBy pIdentifierAs (sym ","))+                 <|> inParens pIdentifierList+                 <|> pIdentifierList              )         ) <|> (NoIdentifiers <$> pAs)+    pIdentifierList = SomeIdentifiers <$> sepEndBy pIdentifierAs (sym ",")     pIdentifierAs = do       ident <- pIdentifier       mbAs <- pAs@@ -1230,6 +1261,9 @@   if sourceLine pos' > sourceLine pos     then pure $ Return Nothing     else Return <$> (option Nothing (Just <$> pExpr))++pContextExpr :: P Expr+pContextExpr = Context <$> (pKeyword "context" *> pExpr)  pIncludeExpr :: P Expr pIncludeExpr = Include <$> (pKeyword "include" *> pExpr)
src/Typst/Syntax.hs view
@@ -136,6 +136,7 @@   | Ident Identifier   | FuncCall Expr [Arg]   | FuncExpr [Param] Expr+  | Context Expr   | FieldAccess Expr Expr   | Group Expr   | Array [Spreadable Expr]
test/out/layout/list-02.out view
@@ -39,38 +39,40 @@                     ]                 ])))) , SoftBreak-, Text "-"-, Space-, Text "Level"-, Space-, Text "1"-, SoftBreak-, Text "-"-, Space-, Text "Level"-, Space-, Code-    "test/typ/layout/list-02.typ"-    ( line 3 , column 12 )-    (Block-       (Content-          [ SoftBreak-          , Text "2"-          , Space-          , Text "through"-          , Space-          , Text "content"-          , Space-          , Text "block"-          , ParBreak-          ]))-, ParBreak+, BulletListItem+    [ Text "Level"+    , Space+    , Text "1"+    , SoftBreak+    , BulletListItem+        [ Text "Level"+        , Space+        , Code+            "test/typ/layout/list-02.typ"+            ( line 3 , column 12 )+            (Block+               (Content+                  [ SoftBreak+                  , Text "2"+                  , Space+                  , Text "through"+                  , Space+                  , Text "content"+                  , Space+                  , Text "block"+                  , ParBreak+                  ]))+        , ParBreak+        ]+    ] ] --- evaluated --- document(body: { text(body: [-- Level 1-- Level ]), -                 text(body: [+]), +                 list(children: ({ text(body: [Level 1+]), +                                   list(children: ({ text(body: [Level ]), +                                                     text(body: [ 2 through content block]), -                 parbreak(), -                 parbreak() })+                                                     parbreak(), +                                                     parbreak() })) })) })
test/out/math/attach-03.out view
@@ -42,18 +42,14 @@ , Comment , Equation     False-    [ MGroup-        Nothing+    [ MAttach+        (Just (Text "1"))         Nothing-        [ MAttach-            (Just (Text "1"))-            Nothing-            (Code-               "test/typ/math/attach-03.typ"-               ( line 3 , column 2 )-               (Ident (Identifier "pi")))-        , MGroup (Just "(") (Just ")") [ Text "Y" ]-        ]+        (Code+           "test/typ/math/attach-03.typ"+           ( line 3 , column 2 )+           (Ident (Identifier "pi")))+    , MGroup (Just "(") (Just ")") [ Text "Y" ]     , Text ","     , MAttach         (Just@@ -103,11 +99,7 @@            (MGroup               Nothing               Nothing-              [ MGroup-                  Nothing-                  Nothing-                  [ Text "1" , MGroup (Just "(") (Just ")") [ Text "Y" ] ]-              ]))+              [ Text "1" , MGroup (Just "(") (Just ")") [ Text "Y" ] ]))         Nothing         (Code            "test/typ/math/attach-03.typ"
test/out/math/frac-06.out view
@@ -107,12 +107,8 @@     , Text "+"     , MFrac (MGroup (Just "[") (Just "]") [ Text "x" ]) (Text "2")     , Text ","-    , MFrac-        (MGroup-           Nothing-           Nothing-           [ Text "1" , MGroup (Just "(") (Just ")") [ Text "x" ] ])-        (Text "2")+    , Text "1"+    , MFrac (MGroup (Just "(") (Just ")") [ Text "x" ]) (Text "2")     , Text ","     , Text "2"     , MFrac (MGroup (Just "[") (Just "]") [ Text "x" ]) (Text "2")@@ -202,11 +198,9 @@                                                                        text(body: [x]),                                                                         []] }))),                                         text(body: [,]), +                                       text(body: [1]),                                         math.frac(denom: text(body: [2]), -                                                 num: { text(body: [1]), -                                                        math.lr(body: ({ [(], -                                                                         text(body: [x]), -                                                                         [)] })) }), +                                                 num: text(body: [x])),                                         text(body: [,]),                                         text(body: [2]),                                         math.frac(denom: text(body: [2]), 
test/out/math/multiline-05.out view
@@ -75,12 +75,8 @@         (MGroup            (Just "(")            (Just ")")-           [ MGroup-               Nothing-               Nothing-               [ Text "5"-               , MGroup (Just "(") (Just ")") [ Text "5" , Text "+" , Text "1" ]-               ]+           [ Text "5"+           , MGroup (Just "(") (Just ")") [ Text "5" , Text "+" , Text "1" ]            ])         (Text "2")     , Text "="
test/out/math/op-01.out view
@@ -65,18 +65,14 @@         ( line 4 , column 5 )         (FuncCall (Ident (Identifier "sin")) [ BlockArg [ Text "x" ] ])     , Text "+"-    , MGroup-        Nothing+    , MAttach+        (Just (Text "2"))         Nothing-        [ MAttach-            (Just (Text "2"))-            Nothing-            (Code-               "test/typ/math/op-01.typ"-               ( line 4 , column 14 )-               (Ident (Identifier "log")))-        , MGroup (Just "(") (Just ")") [ Text "x" ]-        ]+        (Code+           "test/typ/math/op-01.typ"+           ( line 4 , column 14 )+           (Ident (Identifier "log")))+    , MGroup (Just "(") (Just ")") [ Text "x" ]     ] , ParBreak ]
test/out/math/unbalanced-00.out view
@@ -78,11 +78,7 @@            , MGroup                (Just "(")                (Just ")")-               [ MGroup-                   Nothing-                   Nothing-                   [ Text "2" , MGroup (Just "(") (Just ")") [ Text "3" ] ]-               ]+               [ Text "2" , MGroup (Just "(") (Just ")") [ Text "3" ] ]            ])     ] , ParBreak
test/out/regression/issue17.out view
@@ -52,12 +52,8 @@ , ParBreak , Equation     False-    [ MGroup-        Nothing-        Nothing-        [ MAttach (Just (Text "1")) Nothing (Text "a")-        , MGroup (Just "(") (Just ")") [ Text "x" ]-        ]+    [ MAttach (Just (Text "1")) Nothing (Text "a")+    , MGroup (Just "(") (Just ")") [ Text "x" ]     ] , ParBreak , Equation
+ test/out/regression/issue54.out view
@@ -0,0 +1,114 @@+--- parse tree ---+[ Code+    "test/typ/regression/issue54.typ"+    ( line 1 , column 2 )+    (Let+       (BasicBind (Just (Identifier "test")))+       (FuncExpr+          [ NormalParam (Identifier "x") , NormalParam (Identifier "y") ]+          (Block+             (CodeBlock+                [ If+                    [ ( Equals (Ident (Identifier "x")) (Ident (Identifier "y"))+                      , Block (Content [ Text "\9989" ])+                      )+                    , ( Literal (Boolean True)+                      , Block+                          (Content+                             [ Text "\10060"+                             , Text "("+                             , Code+                                 "test/typ/regression/issue54.typ"+                                 ( line 1 , column 47 )+                                 (FuncCall+                                    (Ident (Identifier "repr"))+                                    [ NormalArg (Ident (Identifier "x")) ])+                             , Space+                             , Text "/"+                             , Text "="+                             , Space+                             , Code+                                 "test/typ/regression/issue54.typ"+                                 ( line 1 , column 59 )+                                 (FuncCall+                                    (Ident (Identifier "repr"))+                                    [ NormalArg (Ident (Identifier "y")) ])+                             , Text ")"+                             ])+                      )+                    ]+                ]))))+, SoftBreak+, Equation+    True+    [ MAttach+        (Just+           (MGroup+              Nothing+              Nothing+              [ Text "a" , MGroup (Just "(") (Just ")") [ Text "b" ] ]))+        Nothing+        (Text "c")+    , HardBreak+    , MAttach+        (Just (MGroup Nothing Nothing [ Text "a" ])) Nothing (Text "c")+    , MGroup (Just "(") (Just ")") [ Text "b" ]+    , HardBreak+    , MAttach+        (Just (MGroup Nothing Nothing [ Text "a" , Text "!" ]))+        Nothing+        (Text "c")+    , HardBreak+    , MAttach+        (Just (MGroup Nothing Nothing [ Text "a" , Text "!" ]))+        Nothing+        (Text "c")+    , MGroup (Just "(") (Just ")") [ Text "b" ]+    , HardBreak+    , MFrac+        (Text "a")+        (MAttach+           Nothing+           (Just (Text "n"))+           (MGroup Nothing Nothing [ Text "b" , Text "!" ]))+    ]+, ParBreak+]+--- evaluated ---+document(body: { text(body: [+]), +                 math.equation(block: true, +                               body: { math.attach(b: { text(body: [a]), +                                                        math.lr(body: ({ [(], +                                                                         text(body: [b]), +                                                                         [)] })) }, +                                                   base: text(body: [c]), +                                                   t: none), +                                       linebreak(), +                                       math.attach(b: text(body: [a]), +                                                   base: text(body: [c]), +                                                   t: none), +                                       math.lr(body: ({ [(], +                                                        text(body: [b]), +                                                        [)] })), +                                       linebreak(), +                                       math.attach(b: { text(body: [a]), +                                                        text(body: [!]) }, +                                                   base: text(body: [c]), +                                                   t: none), +                                       linebreak(), +                                       math.attach(b: { text(body: [a]), +                                                        text(body: [!]) }, +                                                   base: text(body: [c]), +                                                   t: none), +                                       math.lr(body: ({ [(], +                                                        text(body: [b]), +                                                        [)] })), +                                       linebreak(), +                                       math.frac(denom: math.attach(b: none, +                                                                    base: { text(body: [b]), +                                                                            text(body: [!]) }, +                                                                    t: text(body: [n])), +                                                 num: text(body: [a])) }, +                               numbering: none), +                 parbreak() })
+ test/out/regression/issue55.out view
@@ -0,0 +1,76 @@+--- parse tree ---+[ Code+    "test/typ/regression/issue55.typ"+    ( line 1 , column 2 )+    (Let+       (BasicBind (Just (Identifier "test")))+       (FuncExpr+          [ NormalParam (Identifier "x") , NormalParam (Identifier "y") ]+          (Block+             (CodeBlock+                [ If+                    [ ( Equals (Ident (Identifier "x")) (Ident (Identifier "y"))+                      , Block (Content [ Text "\9989" ])+                      )+                    , ( Literal (Boolean True)+                      , Block+                          (Content+                             [ Text "\10060"+                             , Text "("+                             , Code+                                 "test/typ/regression/issue55.typ"+                                 ( line 1 , column 47 )+                                 (FuncCall+                                    (Ident (Identifier "repr"))+                                    [ NormalArg (Ident (Identifier "x")) ])+                             , Space+                             , Text "/"+                             , Text "="+                             , Space+                             , Code+                                 "test/typ/regression/issue55.typ"+                                 ( line 1 , column 59 )+                                 (FuncCall+                                    (Ident (Identifier "repr"))+                                    [ NormalArg (Ident (Identifier "y")) ])+                             , Text ")"+                             ])+                      )+                    ]+                ]))))+, SoftBreak+, Equation+    True+    [ MGroup (Just "(") (Just ")") [ Text "b" ]+    , MFrac+        (MGroup (Just "(") (Just ")") [ Text "c" ])+        (MGroup Nothing Nothing [ Text "d" ])+    , Text "!"+    , MFrac+        (MGroup (Just "(") (Just ")") [ Text "a" ])+        (MGroup Nothing Nothing [ Text "b" ])+    , MGroup Nothing Nothing [ HardBreak , Text "!" ]+    , MFrac+        (MGroup (Just "(") (Just ")") [ Text "a" ])+        (MGroup Nothing Nothing [ Text "b" ])+    ]+, ParBreak+]+--- evaluated ---+document(body: { text(body: [+]), +                 math.equation(block: true, +                               body: { math.lr(body: ({ [(], +                                                        text(body: [b]), +                                                        [)] })), +                                       math.frac(denom: text(body: [d]), +                                                 num: text(body: [c])), +                                       text(body: [!]), +                                       math.frac(denom: text(body: [b]), +                                                 num: text(body: [a])), +                                       linebreak(), +                                       text(body: [!]), +                                       math.frac(denom: text(body: [b]), +                                                 num: text(body: [a])) }, +                               numbering: none), +                 parbreak() })
+ test/typ/regression/issue54.typ view
@@ -0,0 +1,7 @@+$+  c_a(b)\+  c_(a)(b)\+  c_a!\+  c_a!(b)\+  a/b!^n+$
+ test/typ/regression/issue55.typ view
@@ -0,0 +1,5 @@+$+  (b)(c)/(d)+  !(a)/(b)+  \ !(a)/(b)+$
typst.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               typst-version:            0.6+version:            0.6.1 synopsis:           Parsing and evaluating typst syntax. description:        A library for parsing and evaluating typst syntax.                     Typst (<https://typst.app>) is a document layout and@@ -44,7 +44,9 @@                       Typst.Evaluate                       Typst.Methods                       Typst.Util+    autogen-modules:  Paths_typst     other-modules:+                      Paths_typst                       Typst.Bind                       Typst.Regex                       Typst.Show@@ -55,7 +57,7 @@      -- other-extensions:     build-depends:    base >= 4.14 && <= 5,-                      typst-symbols >= 0.1.6 && < 0.1.7,+                      typst-symbols >= 0.1.7 && < 0.1.8,                       mtl,                       vector,                       parsec,