diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,30 @@
 # Revision history for typst-hs
 
+## 0.12.1
+
+  * Tests: read top-level test files as raw bytes. This matches how
+    imports and the executable read files. Previously the tests read
+    them through a text handle, which should strip CRs on Windows.
+
+  * Tests: handle Windows paths and line endings. Golden files record
+    paths with forward slashes, and git converts them to CRLF when
+    checking them out on Windows.
+
+  * Switch to yamlet (#110, Théophile Choutri de Tarlé). This gives us
+    order-preserving mappings, as in typst itself, as well as correct
+    YAML semantics.
+
+  * Identify filepath in package relative to package root (#111).
+    This ensures that when we are interpreting modules that
+    don't reside at the package root, we get the right `evalLocalDir`
+    and resolve relative imports correctly.
+
+  * Fix path of entry point module for imports.
+
+  * Match Typst shorthand reference lexing (#108, Samuel Huang).
+    Require a label character after @, greedily consume internal
+    punctuation, and keep supplement failures fatal.
+
 ## 0.12
 
   * Support 'in' operator on modules (#106).
diff --git a/src/Typst/Evaluate.hs b/src/Typst/Evaluate.hs
--- a/src/Typst/Evaluate.hs
+++ b/src/Typst/Evaluate.hs
@@ -29,8 +29,7 @@
 import qualified Data.Text.Encoding as TE
 import qualified Data.Vector as V
 import GHC.Generics (Generic)
-import System.FilePath (replaceFileName, takeBaseName,
-                        takeFileName, takeDirectory, (</>))
+import System.FilePath (takeBaseName, makeRelative, takeDirectory, (</>))
 import Text.Parsec
 import Typst.Bind (destructuringBind, doBind)
 import Typst.Constructors (getConstructor)
@@ -1061,7 +1060,7 @@
   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)))
+      pure (takeDirectory tomlPath </> entrypoint (package cfg))
 
 loadModule :: Monad m => Text
            -> MP m (Seq Content, (Identifier, M.Map Identifier Val))
@@ -1080,7 +1079,7 @@
                      then pure dir'
                      else findPkgRoot (takeDirectory dir')
             pkgroot <- findPkgRoot (takeDirectory fp')
-            pure ( takeFileName fp',
+            pure ( makeRelative pkgroot fp',
                    Identifier
                     (T.pack $ takeWhile (/= ':') . takeBaseName $
                        T.unpack modname),
diff --git a/src/Typst/Module/Standard.hs b/src/Typst/Module/Standard.hs
--- a/src/Typst/Module/Standard.hs
+++ b/src/Typst/Module/Standard.hs
@@ -21,6 +21,7 @@
 import qualified Data.Aeson as Aeson
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.Csv as Csv
+import qualified Data.List.NonEmpty as NE
 import qualified Data.Map as M
 import qualified Data.Map.Ordered as OM
 import Data.Maybe (mapMaybe)
@@ -30,7 +31,7 @@
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as TE
 import qualified Data.Vector as V
-import qualified Data.Yaml as Yaml
+import qualified Yamlet
 import Text.Parsec (getPosition, getState, updateState, runParserT)
 import Text.Read (readMaybe)
 import qualified Text.XML as XML
@@ -583,19 +584,19 @@
           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
+    paintValue <- override paint asColor mbPaint
+    thicknessValue <- override thickness asLength mbThickness
+    capValue <- override cap asLineCap mbCap
+    joinValue <- override join asLineJoin mbJoin
+    miterLimitValue <- override miterLimit asMiterLimit mbMiterLimit
     pure $
       VStroke $
         emptyStroke
-          { paint = paint,
-            thickness = thickness,
-            cap = cap,
-            join = join,
-            miterLimit = miterLimit
+          { paint = paintValue,
+            thickness = thicknessValue,
+            cap = capValue,
+            join = joinValue,
+            miterLimit = miterLimitValue
           }
 
 loremWords :: [Text]
@@ -710,8 +711,8 @@
     ( "yaml",
       makeFunction $ do
         bs <- getFileOrBytes
-        case Yaml.decodeEither' (BL.toStrict bs) of
-          Left e -> fail $ show e
+        case Yamlet.decode (BL.toStrict bs) of
+          Left es -> fail $ unlines $ map (Yamlet.prettyError "yaml") $ NE.toList es
           Right (v :: Val) -> pure v
     ),
     ( "read",
@@ -800,20 +801,20 @@
         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
+  paintValue <- field "paint" asColor
+  thicknessValue <- field "thickness" asLength
+  capValue <- field "cap" asLineCap
+  joinValue <- field "join" asLineJoin
+  miterLimitValue <- 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
+      { paint = paintValue,
+        thickness = thicknessValue,
+        cap = capValue,
+        join = joinValue,
+        miterLimit = miterLimitValue
       }
 
 asColor :: MonadFail m => Val -> m Color
diff --git a/src/Typst/Parse.hs b/src/Typst/Parse.hs
--- a/src/Typst/Parse.hs
+++ b/src/Typst/Parse.hs
@@ -761,10 +761,13 @@
       ))
 
 pRef :: P Markup
-pRef =
-  Ref
-    <$> (char '@' *> (T.pack <$> many1 (satisfy isIdentContinue <|> char '_')))
-    <*> option (Literal Auto) (Block <$> pContent)
+pRef = do
+  let labelChars = many1 (satisfy isIdentContinue)
+      labelMore = (++) <$> many1 (oneOf ".:") <*> labelChars
+      labelRest = mconcat <$> many (try labelMore)
+  target <- try (char '@' *> ((++) <$> labelChars <*> labelRest))
+  supplement <- option (Literal Auto) (Block <$> pContent)
+  pure $ Ref (T.pack target) supplement
 
 -- "If a character would continue the expression but should be interpreted as
 -- text, the expression can forcibly be ended with a semicolon (;)."
diff --git a/src/Typst/Regex.hs b/src/Typst/Regex.hs
--- a/src/Typst/Regex.hs
+++ b/src/Typst/Regex.hs
@@ -21,7 +21,6 @@
 import qualified Data.Array as Array
 import Data.Text (Text)
 import qualified Data.Text as T
-import Data.Typeable (Typeable)
 import Text.Regex.TDFA (Regex, extract)
 import qualified Text.Regex.TDFA as TDFA
 import qualified Text.Regex.TDFA.Text as TDFA
@@ -31,7 +30,6 @@
 -- | A regular expression. Note that typst-hs does not use the same Regex engine
 -- as Typst. See issue [#28](https://github.com/jgm/typst-hs/issues/28).
 data RE = RE !Text !Regex
-  deriving (Typeable)
 
 instance Eq RE where
   RE t1 _ == RE t2 _ = t1 == t2
@@ -48,7 +46,7 @@
     matchText :: Text,
     matchCaptures :: [Text]
   }
-  deriving (Eq, Ord, Typeable)
+  deriving (Eq, Ord)
 
 replaceRegex :: RE -> Maybe Int -> (RegexMatch -> Text) -> Text -> Text
 replaceRegex (RE _ re) mbCount replaceFn strIn =
diff --git a/src/Typst/Syntax.hs b/src/Typst/Syntax.hs
--- a/src/Typst/Syntax.hs
+++ b/src/Typst/Syntax.hs
@@ -17,7 +17,7 @@
   )
 where
 
-import Data.Data (Data, Typeable)
+import Data.Data (Data)
 import Data.String
 import Data.Text (Text)
 import qualified Data.Text as T
@@ -52,10 +52,10 @@
   | MFrac Markup Markup
   | MAttach (Maybe Markup) (Maybe Markup) Markup -- bottom then top
   | MGroup (Maybe Text) (Maybe Text) [Markup] -- maybes are open/cloes delims
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 newtype Identifier = Identifier Text
-  deriving (Show, Eq, Ord, Data, Typeable, Semigroup, Monoid)
+  deriving (Show, Eq, Ord, Data, Semigroup, Monoid)
 
 instance IsString Identifier where
   fromString = Identifier . T.pack
@@ -66,7 +66,7 @@
   | ArrayArg [[Markup]]
   | SpreadArg Expr
   | BlockArg [Markup]
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Param
   = DefaultParam Identifier Expr
@@ -74,23 +74,23 @@
   | DestructuringParam [BindPart]
   | SinkParam (Maybe Identifier)
   | SkipParam -- _
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Bind
   = BasicBind (Maybe Identifier)
   | DestructuringBind [BindPart]
   | ExprBind Expr
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data BindPart
   = Simple Bind
   | WithKey Identifier Bind
   | Sink (Maybe Identifier)
   | ExprSink Expr
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Unit = Pt | Mm | Cm | In | Deg | Rad | Em | Fr | Percent
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Literal
   = String Text
@@ -100,17 +100,17 @@
   | Numeric Double Unit
   | None
   | Auto
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Block
   = Content [Markup]
   | CodeBlock [Expr]
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Spreadable a =
     Spr Expr
   | Reg a
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 -- binary-op ::=
 --   '+' | '-' | '*' | '/' | 'and' | 'or' | '==' | '!=' |
@@ -157,10 +157,10 @@
   | Break
   | Continue
   | Underscore
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
 
 data Imports
   = AllIdentifiers
   | SomeIdentifiers [(Identifier, Maybe Identifier)] -- Maybe is the 'as'
   | NoIdentifiers (Maybe Identifier)  -- Maybe is the 'as'
-  deriving (Show, Ord, Eq, Data, Typeable)
+  deriving (Show, Ord, Eq, Data)
diff --git a/src/Typst/Types.hs b/src/Typst/Types.hs
--- a/src/Typst/Types.hs
+++ b/src/Typst/Types.hs
@@ -57,13 +57,12 @@
 import Data.Aeson (FromJSON, parseJSON)
 import qualified Data.Aeson as Aeson
 import qualified Data.ByteString as BS
-import Data.Data (Typeable)
 import qualified Data.Foldable as F
 import Data.Functor.Classes (Ord1 (liftCompare))
 import qualified Data.Map as M
 import qualified Data.Map.Ordered as OM
 import Data.Maybe (fromMaybe, isJust, isNothing, catMaybes)
-import Data.Scientific (floatingOrInteger)
+import Data.Scientific (floatingOrInteger, toRealFloat)
 import Data.Sequence (Seq)
 import qualified Data.Sequence as Seq
 import qualified Data.Set as Set
@@ -79,6 +78,15 @@
 import qualified Toml.Pretty as Toml
 import qualified Text.PrettyPrint as P
 import Text.Read (readMaybe)
+import Yamlet
+  ( FloatValue (..),
+    FromYaml (..),
+    View (..),
+    parseItems,
+    parseNode,
+    typeMismatch,
+    view,
+  )
 import Typst.Regex (RE, makeLiteralRE)
 import Typst.Syntax (Identifier (..), Markup)
 import Data.Time (UTCTime, Day, DiffTime, timeOfDayToTime, localDay, localTimeOfDay)
@@ -154,7 +162,7 @@
   -- already resolved (relative to the file in which it was constructed).
   | VPath !FilePath
   | VType !ValType
-  deriving (Show, Eq, Typeable)
+  deriving (Show, Eq)
 
 instance FromJSON Val where
   parseJSON v@(Aeson.Object {}) =
@@ -166,6 +174,26 @@
   parseJSON (Aeson.Bool b) = pure $ VBoolean b
   parseJSON Aeson.Null = pure VNone
 
+-- | Like Typst, keeps the order of the keys of a mapping and drops the
+-- keys that are not strings.
+instance FromYaml Val where
+  parseYaml = parseNode $ \n -> case view n of
+    NullView -> pure VNone
+    BoolView b -> pure $ VBoolean b
+    IntView i -> pure $ VInteger i
+    FloatView f -> pure $ VFloat $ case f of
+      Finite s -> toRealFloat s
+      NegativeZero -> -0.0
+      Infinity -> 1 / 0
+      NegativeInfinity -> -1 / 0
+      NaN -> 0 / 0
+    StringView t -> pure $ VString t
+    SequenceView xs -> VArray . V.fromList <$> parseItems parseYaml xs
+    MappingView kvs -> do
+      let (ks, vs) = unzip [(Identifier k, v) | (kn, v) <- kvs, StringView k <- [view kn]]
+      VDict . OM.fromList . zip ks <$> parseItems parseYaml vs
+    AliasView _ -> typeMismatch "a value" n
+
 instance Toml.FromValue Val where
   fromValue = pure . tomlToVal
 
@@ -219,7 +247,7 @@
   | TType
   | TAny
   | ValType :|: ValType
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 valType :: Val -> ValType
 valType v =
@@ -370,14 +398,14 @@
   | SelectAnd Selector Selector
   | SelectBefore Selector Selector
   | SelectAfter Selector Selector
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 data Symbol = Symbol
   { symDefault :: !Text,
     symAccent :: !Bool,
     symVariants :: [(Set.Set Text, Text)]
   }
-  deriving (Show, Eq, Typeable)
+  deriving (Show, Eq)
 
 joinVals :: MonadFail m => Val -> Val -> m Val
 joinVals = go
@@ -587,7 +615,7 @@
         eltPos :: Maybe SourcePos,
         eltFields :: M.Map Identifier Val
       }
-  deriving (Show, Typeable)
+  deriving (Show)
 
 instance Eq Content where
   Txt t1 == Txt t2 = t1 == t2
@@ -610,7 +638,6 @@
   fromString x = Txt (T.pack x)
 
 newtype Function = Function (forall m. Monad m => Arguments -> MP m Val)
-  deriving (Typeable)
 
 instance Show Function where
   show _ = "<function>"
@@ -679,7 +706,7 @@
 data Attempt a
   = Success a
   | Failure String
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 instance Functor Attempt where
   fmap f (Success x) = Success (f x)
@@ -715,7 +742,7 @@
   { positional :: [Val],
     named :: OM.OMap Identifier Val
   }
-  deriving (Show, Eq, Typeable)
+  deriving (Show, Eq)
 
 instance Semigroup Arguments where
   Arguments ps1 ns1 <> Arguments ps2 ns2 =
@@ -756,16 +783,16 @@
   | CounterLabel !Text
   | CounterSelector !Selector
   | CounterPage
-  deriving (Eq, Ord, Show, Typeable)
+  deriving (Eq, Ord, Show)
 
 data LUnit = LEm | LPt | LIn | LCm | LMm
-  deriving (Show, Eq, Typeable)
+  deriving (Show, Eq)
 
 data Length
   = LExact Double LUnit
   | LRatio !Rational
   | LSum Length Length
-  deriving (Show, Eq, Typeable)
+  deriving (Show, Eq)
 
 instance Semigroup Length where
   (LExact x xu) <> (LExact y yu)
@@ -842,16 +869,16 @@
 negateLength (LSum x y) = LSum (negateLength x) (negateLength y)
 
 data Horiz = HorizStart | HorizEnd | HorizLeft | HorizCenter | HorizRight
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 data Vert = VertTop | VertHorizon | VertBottom
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 data Color
   = RGB Rational Rational Rational Rational
   | CMYK Rational Rational Rational Rational
   | Luma Rational
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 data Stroke = Stroke
   { paint :: !(Maybe Color), -- Nothing = auto (default: black)
@@ -860,7 +887,7 @@
     join :: !(Maybe Text), -- Nothing = auto (default: "miter")
     miterLimit :: !(Maybe Double) -- Nothing = auto (default: 4.0)
   }
-  deriving (Show, Eq, Typeable)
+  deriving (Show, Eq)
 
 -- | A stroke with every field unset (auto).
 emptyStroke :: Stroke
@@ -883,7 +910,7 @@
   | Rtl -- ^ Right to left
   | Ttb -- ^ Top to bottom
   | Btt -- ^ Bottom to top
-  deriving (Show, Eq, Ord, Typeable)
+  deriving (Show, Eq, Ord)
 
 -- | Render a set stroke field for the parenthesized stroke repr.
 strokeField :: Text -> Maybe P.Doc -> [P.Doc]
diff --git a/src/Typst/Util.hs b/src/Typst/Util.hs
--- a/src/Typst/Util.hs
+++ b/src/Typst/Util.hs
@@ -20,7 +20,7 @@
 
 import Control.Monad (foldM)
 import Control.Monad.Reader (ReaderT (runReaderT), asks)
-import Data.List (foldl')
+import qualified Data.List as List
 import qualified Data.Map as M
 import qualified Data.Map.Ordered as OM
 import qualified Data.Sequence as Seq
@@ -157,7 +157,7 @@
 allArgs = asks positional
 
 makeSymbolMap :: [Sym] -> M.Map Identifier Symbol
-makeSymbolMap = foldl' go mempty
+makeSymbolMap = List.foldl' go mempty
   where
     go :: M.Map Identifier Symbol -> Sym -> M.Map Identifier Symbol
     go m (Sym{ symName = name,
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -7,8 +7,8 @@
 import qualified Data.ByteString.Lazy as BL
 import qualified Data.Text as T
 import qualified Data.Text.Encoding as TE
-import Data.Text.IO as TIO
 import System.FilePath (replaceExtension)
+import System.Info (os)
 import Test.Tasty (TestTree, Timeout (..), defaultMain, localOption, testGroup)
 import Test.Tasty.Golden (findByExtension, goldenVsStringDiff)
 import Text.Show.Pretty (ppShow)
@@ -41,7 +41,11 @@
   inputs <- findByExtension [".typ"] "typ"
   pure $
     localOption (Timeout 1000000 "1s") $
-      testGroup "golden tests" (map (runTest testParse) inputs)
+      testGroup "golden tests" (map (runTest testParse . map fixSeparator) inputs)
+  where
+    -- Golden files record paths with forward slashes.
+    fixSeparator '\\' = '/'
+    fixSeparator c = c
 
 runTest :: [Markup] -> FilePath -> TestTree
 runTest testParse input =
@@ -53,8 +57,8 @@
 
 writeTest :: [Markup] -> FilePath -> IO BL.ByteString
 writeTest testParse input = do
-  let fromText = BL.fromStrict . TE.encodeUtf8 . (<> "\n")
-  contents <- TIO.readFile input
+  let fromText = BL.fromStrict . TE.encodeUtf8 . nativeNewlines . (<> "\n")
+  contents <- TE.decodeUtf8 <$> BS.readFile input
   if "// Error"
     `T.isInfixOf` contents
     || "cycle1.typ"
@@ -77,3 +81,9 @@
             Right c -> do
               let evalOutput = "--- evaluated ---\n" <> repr (VContent [c])
               pure $ fromText $ parseOutput <> evalOutput
+
+-- Git converts golden files to CRLF when checking them out on Windows.
+nativeNewlines :: T.Text -> T.Text
+nativeNewlines
+  | os == "mingw32" = T.replace "\n" "\r\n"
+  | otherwise = id
diff --git a/test/typ/compute/data-10.out b/test/typ/compute/data-10.out
--- a/test/typ/compute/data-10.out
+++ b/test/typ/compute/data-10.out
@@ -133,11 +133,7 @@
 ]), 
                  text(body: [
 ]), 
-                 text(body: [❌(]), 
-                 text(body: [8]), 
-                 text(body: [ /= ]), 
-                 text(body: [7]), 
-                 text(body: [)]), 
+                 text(body: [✅]), 
                  text(body: [
 ]), 
                  text(body: [✅]), 
@@ -161,9 +157,5 @@
                  text(body: [✅]), 
                  text(body: [
 ]), 
-                 text(body: [❌(]), 
-                 text(body: [true]), 
-                 text(body: [ /= ]), 
-                 text(body: [false]), 
-                 text(body: [)]), 
+                 text(body: [✅]), 
                  parbreak() })
diff --git a/test/typ/regression/issue108-colon.out b/test/typ/regression/issue108-colon.out
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-colon.out
@@ -0,0 +1,71 @@
+--- parse tree ---
+[ Heading 1 [ Text "First" ]
+, Space
+, Code
+    "typ/regression/issue108-colon.typ"
+    ( line 1 , column 9 )
+    (Label "my-anchor::")
+, ParBreak
+, Heading 1 [ Text "Second" ]
+, Space
+, Code
+    "typ/regression/issue108-colon.typ"
+    ( line 3 , column 10 )
+    (Label "my-anchor")
+, ParBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Code
+    "typ/regression/issue108-colon.typ"
+    ( line 5 , column 13 )
+    (FuncCall
+       (Ident (Identifier "ref")) [ NormalArg (Label "my-anchor::") ])
+, Text "."
+, ParBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Code
+    "typ/regression/issue108-colon.typ"
+    ( line 7 , column 13 )
+    (FuncCall
+       (Ident (Identifier "ref")) [ NormalArg (Label "my-anchor") ])
+, Text "."
+, ParBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text ":"
+, Text "."
+, ParBreak
+]
+--- evaluated ---
+document(body: { heading(body: text(body: [First]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <my-anchor::>, 
+                 parbreak(), 
+                 heading(body: text(body: [Second]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <my-anchor>, 
+                 parbreak(), 
+                 text(body: [Please see ]), 
+                 ref(target: <my-anchor::>), 
+                 text(body: [.]), 
+                 parbreak(), 
+                 text(body: [Please see ]), 
+                 ref(target: <my-anchor>), 
+                 text(body: [.]), 
+                 parbreak(), 
+                 text(body: [Please see ]), 
+                 ref(supplement: auto, 
+                     target: <my-anchor>), 
+                 text(body: [::.]), 
+                 parbreak() })
diff --git a/test/typ/regression/issue108-colon.typ b/test/typ/regression/issue108-colon.typ
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-colon.typ
@@ -0,0 +1,9 @@
+= First <my-anchor::>
+
+= Second <my-anchor>
+
+Please see #ref(<my-anchor::>).
+
+Please see #ref(<my-anchor>).
+
+Please see @my-anchor::.
diff --git a/test/typ/regression/issue108-differential.out b/test/typ/regression/issue108-differential.out
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-differential.out
@@ -0,0 +1,540 @@
+--- parse tree ---
+[ Code
+    "typ/regression/issue108-differential.typ"
+    ( line 1 , column 2 )
+    (Show
+       (Just (Ident (Identifier "ref")))
+       (FuncExpr
+          [ NormalParam (Identifier "it") ]
+          (Block
+             (Content
+                [ Code
+                    "typ/regression/issue108-differential.typ"
+                    ( line 1 , column 20 )
+                    (FuncCall
+                       (Ident (Identifier "str"))
+                       [ NormalArg
+                           (FieldAccess
+                              (Ident (Identifier "target")) (Ident (Identifier "it")))
+                       ])
+                ]))))
+, SoftBreak
+, Heading 1 [ Text "First" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 2 , column 9 )
+    (Label "my-anchor::")
+, SoftBreak
+, Heading 1 [ Text "Second" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 3 , column 10 )
+    (Label "my-anchor")
+, SoftBreak
+, Heading 1 [ Text "Colon" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 4 , column 9 )
+    (Label "tab:attributes")
+, SoftBreak
+, Heading 1 [ Text "Dot" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 5 , column 7 )
+    (Label "fig:sub.1")
+, SoftBreak
+, Heading 1 [ Text "Unicode" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 6 , column 11 )
+    (Label "\945:\946.\947")
+, SoftBreak
+, Heading 1 [ Text "Multi" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 7 , column 9 )
+    (Label "a:b.c:d")
+, SoftBreak
+, Heading 1 [ Text "Short" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 8 , column 9 )
+    (Label "fig")
+, SoftBreak
+, Heading 1 [ Text "Longer" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 9 , column 10 )
+    (Label "fig:alpha")
+, SoftBreak
+, Heading 1 [ Text "Dotted" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 10 , column 10 )
+    (Label "a.b.")
+, SoftBreak
+, Heading 1 [ Text "Run" , Space , Text "One" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 11 , column 11 )
+    (Label "a..b")
+, SoftBreak
+, Heading 1 [ Text "Run" , Space , Text "Two" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 12 , column 11 )
+    (Label "a.:b")
+, SoftBreak
+, Heading 1 [ Text "Run" , Space , Text "Three" ]
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 13 , column 13 )
+    (Label "a::b")
+, ParBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 15 , column 13 )
+    (FuncCall
+       (Ident (Identifier "ref")) [ NormalArg (Label "my-anchor::") ])
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 16 , column 13 )
+    (FuncCall
+       (Ident (Identifier "ref")) [ NormalArg (Label "my-anchor") ])
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text ":"
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "tab:attributes" (Literal Auto)
+, Text ","
+, Space
+, Ref "fig:sub.1" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "\945:\946.\947" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "a:b.c:d" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "fig" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "fig:alpha" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "fig:alpha" (Literal Auto)
+, Space
+, Text "and"
+, Space
+, Ref "fig:alpha" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text ":"
+, Space
+, Text "trailing"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Space
+, Text "trailing"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text "."
+, Space
+, Text "trailing"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text ":"
+, Space
+, Text "trailing"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text "["
+, Text "note"
+, Text "]"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text "."
+, Space
+, Text "["
+, Text "note"
+, Text "]"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Space
+, Text "["
+, Text "note"
+, Text "]"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Space
+, Text "["
+, Text "note"
+, Text "]"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Text "@"
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Text "@"
+, Text ":"
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "unknown:x" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "unknown:x" (Literal Auto)
+, Space
+, Text "and"
+, Space
+, Ref "unknown:y" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "a.b" (Literal Auto)
+, Text "."
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Text "@"
+, Text "."
+, Text "x"
+, Space
+, Text "and"
+, Space
+, Text "@"
+, Text ":"
+, Text "x"
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "a..b" (Literal Auto)
+, Text ","
+, Space
+, Ref "a.:b" (Literal Auto)
+, Text ","
+, Space
+, Ref "a::b" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "a" (Literal Auto)
+, Text "."
+, Text "."
+, Space
+, Text "and"
+, Space
+, Ref "a:b" (Literal Auto)
+, Text ":"
+, Text "."
+, ParBreak
+, Text "See"
+, Space
+, Ref "my-anchor" (Literal Auto)
+, Text ":"
+, Text "."
+, Space
+, Code
+    "typ/regression/issue108-differential.typ"
+    ( line 43 , column 19 )
+    (Let (BasicBind (Just (Identifier "z"))) (Literal (Int 1)))
+, ParBreak
+]
+--- evaluated ---
+document(body: { text(body: [
+]), 
+                 heading(body: text(body: [First]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <my-anchor::>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Second]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <my-anchor>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Colon]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <tab:attributes>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Dot]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <fig:sub.1>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Unicode]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <α:β.γ>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Multi]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <a:b.c:d>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Short]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <fig>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Longer]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <fig:alpha>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Dotted]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <a.b.>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Run One]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <a..b>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Run Two]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <a.:b>, 
+                 text(body: [
+]), 
+                 heading(body: text(body: [Run Three]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <a::b>, 
+                 parbreak(), 
+                 text(body: [Please see ]), 
+                 text(body: [<my-anchor::>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [::.
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [:.
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<tab:attributes>]), 
+                 text(body: [, ]), 
+                 text(body: [<fig:sub.1>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<α:β.γ>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<a:b.c:d>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<fig>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<fig:alpha>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<fig:alpha>]), 
+                 text(body: [ and ]), 
+                 text(body: [<fig:alpha>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [:: trailing
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [: trailing
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [. trailing
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [:: trailing
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [:[note]
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [. [note]
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [: [note]
+Please see ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [ [note]
+Please see @.
+Please see @:
+Please see ]), 
+                 text(body: [<unknown:x>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<unknown:x>]), 
+                 text(body: [ and ]), 
+                 text(body: [<unknown:y>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<a.b>]), 
+                 text(body: [..
+Please see @.x and @:x.
+Please see ]), 
+                 text(body: [<a..b>]), 
+                 text(body: [, ]), 
+                 text(body: [<a.:b>]), 
+                 text(body: [, ]), 
+                 text(body: [<a::b>]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<a>]), 
+                 text(body: [.. and ]), 
+                 text(body: [<a:b>]), 
+                 text(body: [:.]), 
+                 parbreak(), 
+                 text(body: [See ]), 
+                 text(body: [<my-anchor>]), 
+                 text(body: [:. ]), 
+                 parbreak() })
diff --git a/test/typ/regression/issue108-differential.typ b/test/typ/regression/issue108-differential.typ
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-differential.typ
@@ -0,0 +1,43 @@
+#show ref: it => [#str(it.target)]
+= First <my-anchor::>
+= Second <my-anchor>
+= Colon <tab:attributes>
+= Dot <fig:sub.1>
+= Unicode <α:β.γ>
+= Multi <a:b.c:d>
+= Short <fig>
+= Longer <fig:alpha>
+= Dotted <a.b.>
+= Run One <a..b>
+= Run Two <a.:b>
+= Run Three <a::b>
+
+Please see #ref(<my-anchor::>).
+Please see #ref(<my-anchor>).
+Please see @my-anchor::.
+Please see @my-anchor:.
+Please see @my-anchor.
+Please see @tab:attributes, @fig:sub.1.
+Please see @α:β.γ.
+Please see @a:b.c:d.
+Please see @fig.
+Please see @fig:alpha.
+Please see @fig:alpha and @fig:alpha.
+Please see @my-anchor:: trailing
+Please see @my-anchor: trailing
+Please see @my-anchor. trailing
+Please see @my-anchor:: trailing
+Please see @my-anchor:[note]
+Please see @my-anchor. [note]
+Please see @my-anchor: [note]
+Please see @my-anchor [note]
+Please see @.
+Please see @:
+Please see @unknown:x.
+Please see @unknown:x and @unknown:y.
+Please see @a.b..
+Please see @.x and @:x.
+Please see @a..b, @a.:b, @a::b.
+Please see @a.. and @a:b:.
+
+See @my-anchor:. #let z = 1
diff --git a/test/typ/regression/issue108-hyphen.out b/test/typ/regression/issue108-hyphen.out
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-hyphen.out
@@ -0,0 +1,56 @@
+--- parse tree ---
+[ Code
+    "typ/regression/issue108-hyphen.typ"
+    ( line 1 , column 2 )
+    (Show
+       (Just (Ident (Identifier "ref")))
+       (FuncExpr
+          [ NormalParam (Identifier "it") ]
+          (Block
+             (Content
+                [ Code
+                    "typ/regression/issue108-hyphen.typ"
+                    ( line 1 , column 20 )
+                    (FuncCall
+                       (Ident (Identifier "str"))
+                       [ NormalArg
+                           (FieldAccess
+                              (Ident (Identifier "target")) (Ident (Identifier "it")))
+                       ])
+                ]))))
+, SoftBreak
+, Heading 1 [ Text "Hyphen" ]
+, Space
+, Code
+    "typ/regression/issue108-hyphen.typ"
+    ( line 2 , column 10 )
+    (Label "my-anchor-")
+, ParBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor-" (Literal Auto)
+, Text "."
+, SoftBreak
+, Text "Please"
+, Space
+, Text "see"
+, Space
+, Ref "my-anchor-" (Block (Content [ Text "note" ]))
+, ParBreak
+]
+--- evaluated ---
+document(body: { text(body: [
+]), 
+                 heading(body: text(body: [Hyphen]), 
+                         level: 1), 
+                 text(body: [ ]), 
+                 <my-anchor->, 
+                 parbreak(), 
+                 text(body: [Please see ]), 
+                 text(body: [<my-anchor->]), 
+                 text(body: [.
+Please see ]), 
+                 text(body: [<my-anchor->]), 
+                 parbreak() })
diff --git a/test/typ/regression/issue108-hyphen.typ b/test/typ/regression/issue108-hyphen.typ
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-hyphen.typ
@@ -0,0 +1,5 @@
+#show ref: it => [#str(it.target)]
+= Hyphen <my-anchor->
+
+Please see @my-anchor-.
+Please see @my-anchor-[note]
diff --git a/test/typ/regression/issue108-unclosed.out b/test/typ/regression/issue108-unclosed.out
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-unclosed.out
@@ -0,0 +1,3 @@
+"typ/regression/issue108-unclosed.typ" (line 4, column 1):
+unexpected end of input
+expecting "*/", "//", "/*", new-line, "=", "\\", "*", "_", "$", "-", "+", digit, "/", "http://", "https://", letter or digit, "```", "`", "~", ".", "'", "\"", "<", "@", "#" or unclosed delimiter at"typ/regression/issue108-unclosed.typ" (line 3, column 22)
diff --git a/test/typ/regression/issue108-unclosed.typ b/test/typ/regression/issue108-unclosed.typ
new file mode 100644
--- /dev/null
+++ b/test/typ/regression/issue108-unclosed.typ
@@ -0,0 +1,3 @@
+= Anchor <my-anchor>
+
+Please see @my-anchor[unclosed
diff --git a/typst.cabal b/typst.cabal
--- a/typst.cabal
+++ b/typst.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.4
 name:               typst
-version:            0.12
+version:            0.12.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
@@ -76,7 +76,7 @@
                       aeson,
                       scientific,
                       xml-conduit,
-                      yaml,
+                      yamlet >= 1.0 && < 2,
                       toml-parser ^>= 2.0.0.0,
                       regex-tdfa,
                       array,
