packages feed

typst 0.3.0.0 → 0.3.1.0

raw patch · 9 files changed

+156/−36 lines, 9 filesdep ~toml-parserdep ~typst-symbols

Dependency ranges changed: toml-parser, typst-symbols

Files

CHANGELOG.md view
@@ -1,5 +1,28 @@ # Revision history for typst-hs +## 0.3.1.0++  * Allow multiplying a ratio by a length.++  * Use `symModule` and `mathModule` directly when evaluating+    Equation instead of looking up `sym` and `math`.++  * Fix parsing of escapes in string literals. Symbols in general+    can't be escaped. There is just a small list of valid escapes.++  * Fix bugs in converting typst regexes to TDFA's format.++  * Allow Symbol to be regex replacement text.++  * Allow VString and VSymbol to be +'d.++  * Update for toml-parser-1.2.0.0 API changes (#9, Eric Mertens).++  * Derive the decoder for typst.toml (#7, Eric Mertens)++  * Implement typst's `toml()` function (#8, Eric Mertens).++ ## 0.3.0.0    * We now target typst 0.6.
src/Typst/Evaluate.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-}@@ -26,11 +27,13 @@ import qualified Data.Text as T import qualified Data.Text.Encoding as TE import qualified Data.Vector as V+import GHC.Generics (Generic) import System.FilePath (replaceFileName, takeBaseName, takeDirectory, (</>)) import Text.Parsec import Typst.Bind (destructuringBind) import Typst.Methods (getMethod)-import Typst.Module.Standard (loadFileText, standardModule)+import Typst.Module.Standard (loadFileText, standardModule, symModule)+import Typst.Module.Math (mathModule) import Typst.Parse (parseTypst) import Typst.Regex (match) import Typst.Show (applyShowRules)@@ -38,6 +41,8 @@ import Typst.Types import Typst.Util (makeFunction, nthArg) import qualified Toml as Toml+import qualified Toml.FromValue as Toml+import qualified Toml.FromValue.Generic as Toml  -- import Debug.Trace @@ -233,10 +238,8 @@                 [("level", VInteger (fromIntegral level))]           }     Equation display ms -> inBlock BlockScope $ do-      VModule _ mathmod <- lookupIdentifier "math"-      importModule mathmod-      VModule _ symmod <- lookupIdentifier "sym"-      importModule symmod+      importModule mathModule+      importModule symModule       oldMath <- evalMath <$> getState       updateState $ \st -> st {evalMath = True}       content <- pInnerContents ms@@ -888,6 +891,24 @@           pure res   pure fn +-- | Type of TOML configuration file used in 'findPackageEntryPoint' saved as `typst.toml`+data Config = Config {+  package :: PackageConfig++} deriving (Show, Generic)++data PackageConfig = PackageConfig {+  entrypoint :: String+} deriving (Show, Generic)++-- | Derived generically from record field names+instance Toml.FromValue Config where+  fromValue = Toml.parseTableFromValue Toml.genericParseTable++-- | Derived generically from record field names+instance Toml.FromValue PackageConfig where+  fromValue = Toml.parseTableFromValue Toml.genericParseTable+ findPackageEntryPoint :: Monad m => Text -> MP m FilePath findPackageEntryPoint modname = do   let (namespace, rest) = break (=='/') (drop 1 $ T.unpack modname)@@ -931,15 +952,10 @@                     "\nCompile with typst compile to bring the package into your local cache."              -- TODO? fetch from CDN if not present in cache?   tomlString <- T.unpack . TE.decodeUtf8 <$> lift (loadBytes operations tomlPath)-  case Toml.parse tomlString of-    Left e -> fail e-    Right toptbl ->-      case M.lookup "package" toptbl of-        Just (Toml.Table tbl) ->-          case M.lookup "entrypoint" tbl of-            Just (Toml.String f) -> pure $ replaceFileName tomlPath f-            _ -> fail "Could not find entrypoint"-        _ -> fail "Could not find [package] table"+  case Toml.decode tomlString of+    Toml.Failure e -> fail (unlines ("Failure loading typst.toml" : e))+    Toml.Success _warnings cfg -> -- ignores warnings like unused keys in TOML+      pure (replaceFileName tomlPath (entrypoint (package cfg)))  loadModule :: Monad m => Text            -> MP m (Seq Content, (Identifier, M.Map Identifier Val))
src/Typst/Methods.hs view
@@ -234,6 +234,8 @@               case replacement of                 VString r ->                   pure $ VString $ replaceRegex patt mbCount (const r) t+                VSymbol (Symbol r _ _) ->+                  pure $ VString $ replaceRegex patt mbCount (const r) t                 VFunction _ _ f ->                   pure $                     VString $
src/Typst/Module/Standard.hs view
@@ -6,6 +6,7 @@  module Typst.Module.Standard   ( standardModule,+    symModule,     loadFileText,     applyPureFunction   )@@ -32,6 +33,7 @@ import Text.Parsec (getPosition, getState, updateState, runParserT) import Text.Read (readMaybe) import qualified Text.XML as XML+import qualified Toml import Typst.Emoji (typstEmojis) import Typst.Module.Calc (calcModule) import Typst.Module.Math (mathModule)@@ -549,7 +551,14 @@         t <- lift $ loadFileText fp         pure $ VString t     ),-    ("toml", makeFunction $ fail "unimplemented toml"),+    ( "toml",+      makeFunction $ do+        fp <- nthArg 1+        t <- lift $ loadFileText fp+        case Toml.decode (T.unpack t) of+          Toml.Failure e -> fail (unlines ("toml errors:" : e))+          Toml.Success _ v -> pure v+    ),     ( "xml",       makeFunction $ do         fp <- nthArg 1
src/Typst/Parse.hs view
@@ -579,7 +579,8 @@   try $     char '\\'       *> ( uniEsc-             <|> satisfy isSpecial+             <|> ('\\' <$ char '\\')+             <|> ('"' <$ char '"')              <|> ('\n' <$ char 'n')              <|> ('\t' <$ char 't')              <|> ('\r' <$ char 'r')
src/Typst/Regex.hs view
@@ -84,22 +84,39 @@   where     (caseSensitive, t') =       if "(?i)" `T.isPrefixOf` t-        then (False, T.pack . go . T.unpack $ T.drop 4 t)-        else (True, T.pack . go . T.unpack $ t)+        then (False, T.pack . go False . T.unpack $ T.drop 4 t)+        else (True, T.pack . go False . T.unpack $ t)     compopts = TDFA.defaultCompOpt {TDFA.caseSensitive = caseSensitive}-    -- handle things not supported in TFFA (posix) regexes, e.g. \d \w \s, +, ?-    go [] = []-    go ('?' : cs) = "{0,1}" ++ go cs-    go ('+' : cs) = "{1,}" ++ go cs-    go ('\\' : c : cs)-      | c == 'd' = "[[:digit:]]" ++ go cs-      | c == 'D' = "[^[:digit:]]" ++ go cs-      | c == 's' = "[[:space:]]" ++ go cs-      | c == 'S' = "[^[:space:]]" ++ go cs-      | c == 'w' = "[[:word:]]" ++ go cs-      | c == 'W' = "[^[:word:]]" ++ go cs-      | otherwise = '\\' : c : go cs-    go (c : cs) = c : go cs++    -- Handle things not supported in TFFA posix regexes, e.g. \d \w \s, +, ?+    -- Note that we have to track whether we're in a character class, because+    -- the expansions will be different in that case.  The first+    -- parameter of `go` is True if in a character class.+    go _ [] = []+    go True (']' : cs) = ']' : go False cs+    go False ('[' : cs) = '[' :+      case cs of+        '^':']':ds -> '^' : ']' : go True ds+        '^':'\\':']':ds -> '^' : ']' : go True ds+        ']':ds -> ']' : go True ds+        '\\':']':ds -> ']' : go True ds+        _ -> go True cs+    go False ('?' : cs) = "{0,1}" ++ go False cs+    go False ('+' : cs) = "{1,}" ++ go False cs+    go inCharClass ('\\' : c : cs)+      = let f = if inCharClass+                   then id+                   else \x -> "[" ++ x ++ "]"+            r = case c of+                  'd' -> f "[:digit:]"+                  'D' -> f "^[:digit:]"+                  's' -> f "[:space:]"+                  'S' -> f "^[:space:]"+                  'w' -> f "[:word:]"+                  'W' -> f "^[:word:]"+                  _ -> ['\\', c]+        in r ++ go inCharClass cs+    go inCharClass (c : cs) = c : go inCharClass cs  match :: TDFA.RegexContext Regex source target => RE -> source -> target match (RE _ re) t = TDFA.match re t
src/Typst/Types.hs view
@@ -70,11 +70,14 @@ import Data.Vector (Vector) import qualified Data.Vector as V import Text.Parsec+import qualified Toml+import qualified Toml.FromValue as Toml+import qualified Toml.Pretty as Toml import qualified Text.PrettyPrint as P import Text.Read (readMaybe) import Typst.Regex (RE, makeLiteralRE) import Typst.Syntax (Identifier (..), Markup)-import Data.Time (UTCTime, Day, DiffTime)+import Data.Time (UTCTime, Day, DiffTime, timeOfDayToTime, localDay, localTimeOfDay) import Data.Time.Format (defaultTimeLocale, formatTime) import System.Directory (XdgDirectory(..)) @@ -120,6 +123,22 @@   parseJSON (Aeson.Bool b) = pure $ VBoolean b   parseJSON Aeson.Null = pure VNone +instance Toml.FromValue Val where+  fromValue = pure . tomlToVal++tomlToVal :: Toml.Value -> Val+tomlToVal (Toml.Bool x) = VBoolean x+tomlToVal (Toml.Integer x) = VInteger x+tomlToVal (Toml.String x) = VString (T.pack x)+tomlToVal (Toml.Float x) = VFloat x+tomlToVal (Toml.TimeOfDay x) = VDateTime Nothing (Just (timeOfDayToTime x))+tomlToVal (Toml.Day x) = VDateTime (Just x) Nothing+tomlToVal (Toml.LocalTime x) = VDateTime (Just (localDay x)) (Just (timeOfDayToTime (localTimeOfDay x)))+tomlToVal (Toml.Array x) = VArray (V.fromList (map tomlToVal x))+tomlToVal (Toml.Table x) = VDict (OM.fromList [(Identifier (T.pack k), tomlToVal v) | (k,v) <- M.assocs x])+  -- typst specifies that unsupported datetimes map to strings and we don't have a place for the timezone+tomlToVal v@Toml.ZonedTime{} = VString (T.pack (show (Toml.prettyValue v)))+ data ValType   = TNone   | TAuto@@ -386,6 +405,8 @@   maybePlus (VContent c1) (VContent c2) = pure $ VContent (c1 <> c2)   maybePlus (VString s1) (VContent c2) = pure $ VContent (Txt s1 Seq.<| c2)   maybePlus (VContent c1) (VString s2) = pure $ VContent (c1 Seq.|> Txt s2)+  maybePlus (VString s1) sym@(VSymbol{}) = pure $ VString (s1 <> repr sym)+  maybePlus sym@(VSymbol{}) (VString s2) = pure $ VString (repr sym <> s2)   maybePlus (VLength l1) (VLength l2) = pure $ VLength (l1 <> l2)   maybePlus (VLength l1) (VRatio r1) = pure $ VLength (l1 <> LRatio r1)   maybePlus (VRatio r1) (VLength l1) = pure $ VLength (l1 <> LRatio r1)@@ -422,6 +443,8 @@     | i >= 0 = pure $ VContent (mconcat $ replicate (fromIntegral i) c)   maybeTimes (VInteger i) (VLength l) = pure $ VLength $ timesLength (fromIntegral i) l   maybeTimes (VLength l) (VInteger i) = pure $ VLength $ timesLength (fromIntegral i) l+  maybeTimes (VRatio r) (VLength l) = pure $ VLength $ timesLength (fromRational r) l+  maybeTimes (VLength l) (VRatio r) = pure $ VLength $ timesLength (fromRational r) l   maybeTimes (VFloat f) (VLength l) = pure $ VLength $ timesLength f l   maybeTimes (VLength l) (VFloat f) = pure $ VLength $ timesLength f l   maybeTimes (VInteger i) (VAngle a) = pure $ VAngle (fromIntegral i * a)
test/out/compute/data-08.out view
@@ -169,5 +169,34 @@        ]) , ParBreak ]-"test/typ/compute/data-08.typ" (line 3, column 2):-unimplemented toml+--- evaluated ---+{ 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() }
typst.cabal view
@@ -1,6 +1,6 @@ cabal-version:      2.4 name:               typst-version:            0.3.0.0+version:            0.3.1.0 synopsis:           Parsing and evaluating typst syntax. description:        A library for parsing and evaluating typst syntax.                     Typst (<https://typst.app>) is a document layout and@@ -70,7 +70,7 @@                       scientific,                       xml-conduit,                       yaml,-                      toml-parser,+                      toml-parser ^>= 1.2.0.0,                       regex-tdfa,                       array,                       time,