diff --git a/MANUAL.txt b/MANUAL.txt
--- a/MANUAL.txt
+++ b/MANUAL.txt
@@ -1,7 +1,7 @@
 ---
 title: Pandoc User's Guide
 author: John MacFarlane
-date: December 11, 2023
+date: December 15, 2023
 ---
 
 # Synopsis
diff --git a/changelog.md b/changelog.md
--- a/changelog.md
+++ b/changelog.md
@@ -1,5 +1,48 @@
 # Revision history for pandoc
 
+## pandoc 3.1.11 (2023-12-15)
+
+  * Typst writer:
+
+    + Emit `;` after typst code, unless followed by space (#9252).
+      Otherwise there's the potential that the typst code will swallow
+      up a following character.
+
+  * Text.Pandoc.Logging:
+
+    + Add `MakePDFWarning` constructor to LogMessage [API change].
+    + Add `MakePDFInfo` constructor to LogMessage [API change].
+
+  * Text.Pandoc.PDF:
+
+    + LaTeX warnings are passed on to the user as warnings.
+    + Use `report` with `MakePDFWarning` and `MakePDFInfo` to relay
+      verbose information and warnings, instead of writing directly
+      to stderr.
+    + Parse logs to determine whether additional runs needed, instead of
+      running a fixed number of times (#9255). (The number of times
+      that was appropriate given pandoc's default templates didn't
+      always work for custom templates, and thus pandoc 3.1.10's
+      change in the number of runs led to some regressions in PDF
+      production.)
+
+  * Makefile: in `make prelease`, add checks that pandoc-cli and
+    pandoc have the same version, that pandoc-cli depends on this
+    exact version of pandoc, that there is an entry for this version
+    in the changelog, and that the version numbers in the
+    generated man pages are correct.
+
+  * Regenerate man pages with pandoc 3.1.10. This properly escapes hyphens
+    and fixes version numbers in man pages for `pandoc-server` and
+    `pandoc-lua`.
+
+  * Depend on texmath 0.12.8.6. This omits unneeded `lr`s in typst
+    math output.
+
+  * Depend on typst 0.5. This allows the typst reader to support
+    multiline strings, the version type, and the `as`
+    keyword with `import`.
+
 ## pandoc 3.1.10 (2023-12-12)
 
   * Link pandoc-cli version to pandoc version. Henceforth pandoc-cli's
diff --git a/pandoc.cabal b/pandoc.cabal
--- a/pandoc.cabal
+++ b/pandoc.cabal
@@ -1,6 +1,6 @@
 cabal-version:   2.4
 name:            pandoc
-version:         3.1.10
+version:         3.1.11
 build-type:      Simple
 license:         GPL-2.0-or-later
 license-file:    COPYING.md
@@ -512,7 +512,7 @@
                  syb                   >= 0.1      && < 0.8,
                  tagsoup               >= 0.14.6   && < 0.15,
                  temporary             >= 1.1      && < 1.4,
-                 texmath               >= 0.12.8.5 && < 0.13,
+                 texmath               >= 0.12.8.6 && < 0.13,
                  text                  >= 1.1.1.0  && < 2.2,
                  text-conversions      >= 0.3      && < 0.4,
                  time                  >= 1.5      && < 1.14,
@@ -522,7 +522,7 @@
                  zip-archive           >= 0.4.3    && < 0.5,
                  zlib                  >= 0.5      && < 0.7,
                  xml                   >= 1.3.12   && < 1.4,
-                 typst                 >= 0.4      && < 0.4.1,
+                 typst                 >= 0.5      && < 0.5.1,
                  vector                >= 0.12     && < 0.14
 
   if !os(windows)
diff --git a/src/Text/Pandoc/Logging.hs b/src/Text/Pandoc/Logging.hs
--- a/src/Text/Pandoc/Logging.hs
+++ b/src/Text/Pandoc/Logging.hs
@@ -99,6 +99,8 @@
   | EnvironmentVariableUndefined Text
   | DuplicateAttribute Text Text
   | NotUTF8Encoded FilePath
+  | MakePDFInfo Text Text
+  | MakePDFWarning Text
   deriving (Show, Eq, Data, Ord, Typeable, Generic)
 
 instance ToJSON LogMessage where
@@ -253,6 +255,11 @@
            ,"value" .= val]
       NotUTF8Encoded src ->
            ["source" .= src]
+      MakePDFInfo description contents ->
+           ["description" .= description
+           ,"contents" .= contents]
+      MakePDFWarning message ->
+           ["message" .= message]
 
 showPos :: SourcePos -> Text
 showPos pos = Text.pack $ sn ++ "line " ++
@@ -387,6 +394,12 @@
        NotUTF8Encoded src ->
          Text.pack src <>
            " is not UTF-8 encoded: falling back to latin1."
+       MakePDFInfo description contents ->
+         "[makePDF] " <> description <>
+          if Text.null contents
+             then mempty
+             else "\n" <> contents
+       MakePDFWarning message -> "[makePDF] " <> message
 
 messageVerbosity :: LogMessage -> Verbosity
 messageVerbosity msg =
@@ -440,3 +453,5 @@
        EnvironmentVariableUndefined{}-> WARNING
        DuplicateAttribute{}          -> WARNING
        NotUTF8Encoded{}              -> WARNING
+       MakePDFInfo{}                 -> INFO
+       MakePDFWarning{}              -> WARNING
diff --git a/src/Text/Pandoc/PDF.hs b/src/Text/Pandoc/PDF.hs
--- a/src/Text/Pandoc/PDF.hs
+++ b/src/Text/Pandoc/PDF.hs
@@ -18,8 +18,8 @@
 
 import qualified Codec.Picture as JP
 import qualified Control.Exception as E
-import Control.Monad (when)
 import Control.Monad.Trans (MonadIO (..))
+import Control.Monad (foldM_)
 import qualified Data.ByteString as BS
 import Data.ByteString.Lazy (ByteString)
 import qualified Data.ByteString.Lazy as BL
@@ -35,11 +35,11 @@
 import System.Environment
 import System.Exit (ExitCode (..))
 import System.FilePath
-import System.IO (stderr, hClose)
+import System.IO (hClose)
 import System.IO.Temp (withSystemTempDirectory, withTempDirectory,
                        withTempFile)
 import qualified System.IO.Error as IE
-import Text.DocLayout (literal)
+import Text.DocLayout (literal, render, hsep)
 import Text.Pandoc.Definition
 import Text.Pandoc.Error (PandocError (PandocPDFProgramNotFoundError))
 import Text.Pandoc.MIME (getMimeType)
@@ -57,9 +57,9 @@
 import Data.List (intercalate)
 #endif
 import Data.List (isPrefixOf, find)
-import Text.Pandoc.Class (fillMediaBag, getVerbosity,
+import Text.Pandoc.Class (fillMediaBag, getVerbosity, setVerbosity,
                           readFileLazy, readFileStrict, fileExists,
-                          report, extractMedia, PandocMonad)
+                          report, extractMedia, PandocMonad, runIOorExplode)
 import Text.Pandoc.Logging
 import Text.DocTemplates ( FromContext(lookupContext) )
 
@@ -264,11 +264,17 @@
         -> FilePath                        -- ^ temp directory for output
         -> Text                            -- ^ tex source
         -> m (Either ByteString ByteString)
-tex2pdf program args tmpDir source = do
-  let numruns | takeBaseName program == "latexmk"        = 1
-              | "\\tableofcontents" `T.isInfixOf` source = 3  -- to get page numbers
-              | otherwise                                = 1
-  (exit, log', mbPdf) <- runTeXProgram program args numruns tmpDir source
+tex2pdf program args tmpDir' source = do
+  let isOutdirArg x = "-outdir=" `isPrefixOf` x ||
+                      "-output-directory=" `isPrefixOf` x
+  let tmpDir =
+        case find isOutdirArg args of
+          Just x  -> drop 1 $ dropWhile (/='=') x
+          Nothing -> tmpDir'
+  liftIO $ createDirectoryIfMissing True tmpDir
+  let file = tmpDir ++ "/input.tex"  -- note: tmpDir has / path separators
+  liftIO $ BS.writeFile file $ UTF8.fromText source
+  (exit, log', mbPdf) <- runTeXProgram program args tmpDir
   case (exit, mbPdf) of
        (ExitFailure _, _)      -> do
           let logmsg = extractMsg log'
@@ -281,13 +287,14 @@
           return $ Left $ logmsg <> extramsg
        (ExitSuccess, Nothing)  -> return $ Left ""
        (ExitSuccess, Just pdf) -> do
+          latexWarnings log'
           missingCharacterWarnings log'
           return $ Right pdf
 
 missingCharacterWarnings :: PandocMonad m => ByteString -> m ()
 missingCharacterWarnings log' = do
   let ls = BC.lines log'
-  let isMissingCharacterWarning = BC.isPrefixOf "Missing character: "
+  let isMissingCharacterWarning = BC.isPrefixOf "Missing character:"
   let toCodePoint c
         | isAscii c   = T.singleton c
         | otherwise   = T.pack $ c : " (U+" ++ printf "%04X" (ord c) ++ ")"
@@ -298,6 +305,20 @@
                  ]
   mapM_ (report . MissingCharacter) warnings
 
+latexWarnings :: PandocMonad m => ByteString -> m ()
+latexWarnings log' = foldM_ go Nothing (BC.lines log')
+ where
+   go Nothing ln
+     | BC.isPrefixOf "LaTeX Warning:" ln =
+       pure $ Just ln
+     | otherwise = pure Nothing
+   go (Just msg) ln
+     | ln == "" = do -- emit report and reset accumulator
+         report $ MakePDFWarning $ render (Just 60) $
+            hsep $ map literal $ T.words $ UTF8.toText $ BC.toStrict msg
+         pure Nothing
+     | otherwise = pure $ Just (msg <> ln)
+
 -- parsing output
 
 extractMsg :: ByteString -> ByteString
@@ -334,17 +355,11 @@
     let sourceBL = BL.fromStrict $ UTF8.fromText source
     let programArgs = ["--outdir", tmpDir] ++ args ++ ["-"]
     env <- liftIO getEnvironment
-    verbosity <- getVerbosity
-    when (verbosity >= INFO) $ liftIO $
-      showVerboseInfo (Just tmpDir) program programArgs env
-         (utf8ToText sourceBL)
+    showVerboseInfo (Just tmpDir) program programArgs env (utf8ToText sourceBL)
     (exit, out) <- liftIO $ E.catch
       (pipeProcess (Just env) program programArgs sourceBL)
       (handlePDFProgramNotFound program)
-    when (verbosity >= INFO) $ liftIO $ do
-      UTF8.hPutStrLn stderr "[makePDF] Running"
-      BL.hPutStr stderr out
-      UTF8.hPutStr stderr "\n"
+    report $ MakePDFInfo "tectonic output" (UTF8.toText $ BL.toStrict out)
     let pdfFile = tmpDir ++ "/texput.pdf"
     (_, pdf) <- getResultingPDF Nothing pdfFile
     return (exit, out, pdf)
@@ -374,22 +389,13 @@
               Nothing -> return Nothing
     return (log', pdf)
 
--- Run a TeX program on an input bytestring and return (exit code,
--- contents of stdout, contents of produced PDF if any).  Rerun
--- a fixed number of times to resolve references.
+-- Run a TeX program once in a temp directory (on input.tex) and return (exit code,
+-- contents of stdout, contents of produced PDF if any).
 runTeXProgram :: (PandocMonad m, MonadIO m)
-              => String -> [String] -> Int -> FilePath
-              -> Text -> m (ExitCode, ByteString, Maybe ByteString)
-runTeXProgram program args numRuns tmpDir' source = do
-    let isOutdirArg x = "-outdir=" `isPrefixOf` x ||
-                        "-output-directory=" `isPrefixOf` x
-    let tmpDir =
-          case find isOutdirArg args of
-            Just x  -> drop 1 $ dropWhile (/='=') x
-            Nothing -> tmpDir'
-    liftIO $ createDirectoryIfMissing True tmpDir
-    let file = tmpDir ++ "/input.tex"  -- note: tmpDir has / path separators
-    liftIO $ BS.writeFile file $ UTF8.fromText source
+              => String -> [String] -> FilePath
+              -> m (ExitCode, ByteString, Maybe ByteString)
+runTeXProgram program args tmpDir = do
+    let file = tmpDir ++ "/input.tex"
     let isLatexMk = takeBaseName program == "latexmk"
         programArgs | isLatexMk = ["-interaction=batchmode", "-halt-on-error", "-pdf",
                                    "-quiet", "-outdir=" ++ tmpDir] ++ args ++ [file]
@@ -403,27 +409,35 @@
                 ("TEXMFOUTPUT", tmpDir) :
                   [(k,v) | (k,v) <- env'
                          , k /= "TEXINPUTS" && k /= "TEXMFOUTPUT"]
-    verbosity <- getVerbosity
-    when (verbosity >= INFO) $ liftIO $
-        UTF8.readFile file >>=
-         showVerboseInfo (Just tmpDir) program programArgs env''
-    let runTeX runNumber = do
-          (exit, out) <- liftIO $ E.catch
-            (pipeProcess (Just env'') program programArgs BL.empty)
-            (handlePDFProgramNotFound program)
-          when (verbosity >= INFO) $ liftIO $ do
-            UTF8.hPutStrLn stderr $ "[makePDF] Run #" <> tshow runNumber
-            BL.hPutStr stderr out
-            UTF8.hPutStr stderr "\n"
-          if runNumber < numRuns
-             then runTeX (runNumber + 1)
-             else do
-               let logFile = replaceExtension file ".log"
-               let pdfFile = replaceExtension file ".pdf"
-               (log', pdf) <- getResultingPDF (Just logFile) pdfFile
-               return (exit, fromMaybe out log', pdf)
-    runTeX 1
+    liftIO (UTF8.readFile file) >>=
+      showVerboseInfo (Just tmpDir) program programArgs env''
+    go file env'' programArgs (1 :: Int)
+ where
+   go file env'' programArgs runNumber = do
+     report $ MakePDFInfo ("LaTeX run number " <> tshow runNumber) mempty
+     (exit, out) <- liftIO $ E.catch
+       (pipeProcess (Just env'') program programArgs BL.empty)
+       (handlePDFProgramNotFound program)
+     report $ MakePDFInfo "LaTeX output" (UTF8.toText $ BL.toStrict out)
+     -- parse log to see if we need to rerun LaTeX
+     let logFile = replaceExtension file ".log"
+     logExists <- fileExists logFile
+     logContents <- if logExists
+                       then readFileLazy logFile
+                       else return mempty
+     needsRerun <- checkForRerun logContents
+     if needsRerun && runNumber < 3
+        then go file env'' programArgs (runNumber + 1)
+       else do
+          let pdfFile = replaceExtension file ".pdf"
+          (log', pdf) <- getResultingPDF (Just logFile) pdfFile
+          return (exit, fromMaybe out log', pdf)
 
+   checkForRerun log' = pure $ any isRerunWarning $ BC.lines log'
+
+   isRerunWarning ln = BC.isPrefixOf "LaTeX Warning:" ln &&
+                       BS.isInfixOf "Rerun to" (BL.toStrict ln)
+
 generic2pdf :: (PandocMonad m, MonadIO m)
             => String
             -> [String]
@@ -431,9 +445,7 @@
             -> m (Either ByteString ByteString)
 generic2pdf program args source = do
   env' <- liftIO getEnvironment
-  verbosity <- getVerbosity
-  when (verbosity >= INFO) $
-    liftIO $ showVerboseInfo Nothing program args env' source
+  showVerboseInfo Nothing program args env' source
   (exit, out) <- liftIO $ E.catch
     (pipeProcess (Just env') program args
                      (BL.fromStrict $ UTF8.fromText source))
@@ -457,15 +469,16 @@
       BS.writeFile file $ UTF8.fromText source
       let programArgs = args ++ [file] ++ mkOutArgs pdfFile
       env' <- getEnvironment
-      when (verbosity >= INFO) $
-        UTF8.readFile file >>=
-          showVerboseInfo Nothing program programArgs env'
+      fileContents <- UTF8.readFile file
+      runIOorExplode $ do
+        setVerbosity verbosity
+        showVerboseInfo Nothing program programArgs env' fileContents
       (exit, out) <- E.catch
         (pipeProcess (Just env') program programArgs BL.empty)
         (handlePDFProgramNotFound program)
-      when (verbosity >= INFO) $ do
-        BL.hPutStr stderr out
-        UTF8.hPutStr stderr "\n"
+      runIOorExplode $ do
+        setVerbosity verbosity
+        report $ MakePDFInfo "pdf-engine output" (UTF8.toText $ BL.toStrict out)
       pdfExists <- doesFileExist pdfFile
       mbPdf <- if pdfExists
                 -- We read PDF as a strict bytestring to make sure that the
@@ -485,21 +498,20 @@
             -> Text         -- ^ ConTeXt source
             -> m (Either ByteString ByteString)
 context2pdf program pdfargs tmpDir source = do
+  let file = "input.tex"
+  let programArgs = "--batchmode" : pdfargs ++ [file]
+  env' <- liftIO getEnvironment
   verbosity <- getVerbosity
+  liftIO $ BS.writeFile (tmpDir </> file) $ UTF8.fromText source
+  liftIO (UTF8.readFile (tmpDir </> file)) >>=
+    showVerboseInfo (Just tmpDir) program programArgs env'
   liftIO $ inDirectory tmpDir $ do
-    let file = "input.tex"
-    BS.writeFile file $ UTF8.fromText source
-    let programArgs = "--batchmode" : pdfargs ++ [file]
-    env' <- getEnvironment
-    when (verbosity >= INFO) $ liftIO $
-      UTF8.readFile file >>=
-        showVerboseInfo (Just tmpDir) program programArgs env'
     (exit, out) <- E.catch
       (pipeProcess (Just env') program programArgs BL.empty)
       (handlePDFProgramNotFound program)
-    when (verbosity >= INFO) $ do
-      BL.hPutStr stderr out
-      UTF8.hPutStr stderr "\n"
+    runIOorExplode $ do
+      setVerbosity verbosity
+      report $ MakePDFInfo "ConTeXt run output" (UTF8.toText $ BL.toStrict out)
     let pdfFile = replaceExtension file ".pdf"
     pdfExists <- doesFileExist pdfFile
     mbPdf <- if pdfExists
@@ -516,23 +528,19 @@
          (ExitSuccess, Just pdf) -> return $ Right pdf
 
 
-showVerboseInfo :: Maybe FilePath
+showVerboseInfo :: PandocMonad m
+                => Maybe FilePath
                 -> String
                 -> [String]
                 -> [(String, String)]
                 -> Text
-                -> IO ()
+                -> m ()
 showVerboseInfo mbTmpDir program programArgs env source = do
   case mbTmpDir of
-    Just tmpDir -> do
-      UTF8.hPutStrLn stderr "[makePDF] temp dir:"
-      UTF8.hPutStrLn stderr (T.pack tmpDir)
+    Just tmpDir -> report $ MakePDFInfo "Temp dir:" (T.pack tmpDir)
     Nothing -> return ()
-  UTF8.hPutStrLn stderr "[makePDF] Command line:"
-  UTF8.hPutStrLn stderr $
-       T.pack program <> " " <> T.pack (unwords (map show programArgs))
-  UTF8.hPutStr stderr "\n"
-  UTF8.hPutStrLn stderr "[makePDF] Relevant environment variables:"
+  report $ MakePDFInfo "Command line:"
+           (T.pack program <> " " <> T.pack (unwords (map show programArgs)))
   -- we filter out irrelevant stuff to avoid leaking passwords and keys!
   let isRelevant ("PATH",_) = True
       isRelevant ("TMPDIR",_) = True
@@ -545,10 +553,9 @@
       isRelevant ("TEXINPUTS",_) = True
       isRelevant ("TEXMFOUTPUT",_) = True
       isRelevant _ = False
-  mapM_ (UTF8.hPutStrLn stderr . tshow) (filter isRelevant env)
-  UTF8.hPutStr stderr "\n"
-  UTF8.hPutStrLn stderr "[makePDF] Source:"
-  UTF8.hPutStrLn stderr source
+  report $ MakePDFInfo "Relevant environment variables:"
+             (T.intercalate "\n" $ map tshow $ filter isRelevant env)
+  report $ MakePDFInfo "Source:" source
 
 handlePDFProgramNotFound :: String -> IE.IOError -> IO a
 handlePDFProgramNotFound program e
diff --git a/src/Text/Pandoc/Writers/Typst.hs b/src/Text/Pandoc/Writers/Typst.hs
--- a/src/Text/Pandoc/Writers/Typst.hs
+++ b/src/Text/Pandoc/Writers/Typst.hs
@@ -243,8 +243,9 @@
     Code (_,cls,_) code -> return $
       case cls of
         (lang:_) -> "#raw(lang:" <> doubleQuoted lang <>
-                        ", " <> doubleQuoted code <> ")"
+                        ", " <> doubleQuoted code <> ")" <> endCode
         _ | T.any (=='`') code -> "#raw(" <> doubleQuoted code <> ")"
+                                     <> endCode
           | otherwise -> "`" <> literal code <> "`"
     RawInline fmt str ->
       case fmt of
@@ -273,6 +274,7 @@
                        [] -> pure mempty
                        suff -> brackets <$> inlinesToTypst suff
             pure $ "#cite" <> parens (toLabel (citationId cite)) <> suppl
+                      <> endCode
       if isEnabled Ext_citations opts
          -- Note: this loses prefix
          then mconcat <$> mapM toCite citations
@@ -283,9 +285,9 @@
                    Just ('#', ident) -> "<" <> literal ident <> ">"
                    _ -> doubleQuoted src
       return $ "#link" <> parens dest <>
-                if inlines == [Str src]
-                   then mempty
-                   else nowrap $ brackets contents
+                (if inlines == [Str src]
+                    then mempty
+                    else nowrap $ brackets contents) <> endCode
     Image (_,_,kvs) _inlines (src,_tit) -> do
       opts <- gets stOptions
       let mbHeight = lookup "height" kvs
@@ -304,17 +306,21 @@
           case realWidth of
             Just w -> return $ "#box" <>
                         parens ("width: " <> literal w <> ", " <> coreImage)
-            Nothing -> return $ "#" <> coreImage
+                        <> endCode
+            Nothing -> return $ "#" <> coreImage <> endCode
         (Just w, _) -> return $ "#box" <>
                         parens ("width: " <> literal w <> ", " <> coreImage)
+                        <> endCode
         (_, Just h) -> return $ "#box" <>
                         parens ("height: " <> literal h <> ", " <> coreImage)
+                        <> endCode
     Note blocks -> do
       contents <- blocksToTypst blocks
-      return $ "#footnote" <> brackets (chomp contents)
+      return $ "#footnote" <> brackets (chomp contents) <> endCode
 
 textstyle :: PandocMonad m => Doc Text -> [Inline] -> TW m (Doc Text)
-textstyle s inlines = (s <>) . brackets <$> inlinesToTypst inlines
+textstyle s inlines =
+  (<> endCode) . (s <>) . brackets <$> inlinesToTypst inlines
 
 escapeTypst :: EscapeContext -> Text -> Text
 escapeTypst context t =
@@ -360,3 +366,6 @@
   escapeChar '\\' = "\\\\"
   escapeChar '"' = "\\\""
   escapeChar c = T.singleton c
+
+endCode :: Doc Text
+endCode = beforeNonBlank ";"
diff --git a/test/writer.typst b/test/writer.typst
--- a/test/writer.typst
+++ b/test/writer.typst
@@ -435,13 +435,13 @@
 
 Multiple blocks with italics:
 
-/ #emph[apple]: #block[
+/ #emph[apple];: #block[
 red fruit
 
 contains seeds, crisp, pleasant to taste
 ]
 
-/ #emph[orange]: #block[
+/ #emph[orange];: #block[
 orange fruit
 
 ```
@@ -571,27 +571,27 @@
 
 = Inline Markup
 <inline-markup>
-This is #emph[emphasized], and so #emph[is this].
+This is #emph[emphasized];, and so #emph[is this];.
 
-This is #strong[strong], and so #strong[is this].
+This is #strong[strong];, and so #strong[is this];.
 
-An #emph[#link("/url")[emphasized link]].
+An #emph[#link("/url")[emphasized link];];.
 
-#strong[#emph[This is strong and em.]]
+#strong[#emph[This is strong and em.];]
 
-So is #strong[#emph[this]] word.
+So is #strong[#emph[this];] word.
 
-#strong[#emph[This is strong and em.]]
+#strong[#emph[This is strong and em.];]
 
-So is #strong[#emph[this]] word.
+So is #strong[#emph[this];] word.
 
 This is code: `>`, `$`, `\`, `\$`, `<html>`.
 
-#strike[This is #emph[strikeout].]
+#strike[This is #emph[strikeout];.]
 
-Superscripts: a#super[bc]d a#super[#emph[hello]] a#super[hello~there].
+Superscripts: a#super[bc];d a#super[#emph[hello];] a#super[hello~there];.
 
-Subscripts: H#sub[2]O, H#sub[23]O, H#sub[many~of~them]O.
+Subscripts: H#sub[2];O, H#sub[23];O, H#sub[many~of~them];O.
 
 These should not be superscripts or subscripts, because of the unescaped spaces:
 a^b c^d, a\~b c\~d.
@@ -609,7 +609,7 @@
 'He said, "I want to go."' Were you alive in the 70’s?
 
 Here is some quoted '`code`' and a
-"#link("http://example.com/?foo=1&bar=2")[quoted link]".
+"#link("http://example.com/?foo=1&bar=2")[quoted link];".
 
 Some dashes: one—two — three—four — five.
 
@@ -628,7 +628,7 @@
 - $223$
 - $p$-Tree
 - Here’s some display math:
-  $ frac(d, d x) f lr((x)) = lim_(h arrow.r 0) frac(f lr((x + h)) - f lr((x)), h) $
+  $ frac(d, d x) f (x) = lim_(h arrow.r 0) frac(f (x + h) - f (x), h) $
 - Here’s one that has a line break in it: $alpha + omega times x^2$.
 
 These shouldn’t be math:
@@ -701,13 +701,13 @@
 <links>
 == Explicit
 <explicit>
-Just a #link("/url/")[URL].
+Just a #link("/url/")[URL];.
 
-#link("/url/")[URL and title].
+#link("/url/")[URL and title];.
 
-#link("/url/")[URL and title].
+#link("/url/")[URL and title];.
 
-#link("/url/")[URL and title].
+#link("/url/")[URL and title];.
 
 #link("/url/")[URL and title]
 
@@ -717,21 +717,21 @@
 
 #link("mailto:nobody@nowhere.net")[Email link]
 
-#link("")[Empty].
+#link("")[Empty];.
 
 == Reference
 <reference>
-Foo #link("/url/")[bar].
+Foo #link("/url/")[bar];.
 
-With #link("/url/")[embedded \[brackets\]].
+With #link("/url/")[embedded \[brackets\]];.
 
 #link("/url/")[b] by itself should be a link.
 
-Indented #link("/url")[once].
+Indented #link("/url")[once];.
 
-Indented #link("/url")[twice].
+Indented #link("/url")[twice];.
 
-Indented #link("/url")[thrice].
+Indented #link("/url")[thrice];.
 
 This should \[not\]\[\] be a link.
 
@@ -739,20 +739,20 @@
 [not]: /url
 ```
 
-Foo #link("/url/")[bar].
+Foo #link("/url/")[bar];.
 
-Foo #link("/url/")[biz].
+Foo #link("/url/")[biz];.
 
 == With ampersands
 <with-ampersands>
 Here’s a
-#link("http://example.com/?foo=1&bar=2")[link with an ampersand in the URL].
+#link("http://example.com/?foo=1&bar=2")[link with an ampersand in the URL];.
 
-Here’s a link with an amersand in the link text: #link("http://att.com/")[AT&T].
+Here’s a link with an amersand in the link text: #link("http://att.com/")[AT&T];.
 
-Here’s an #link("/script?foo=1&bar=2")[inline link].
+Here’s an #link("/script?foo=1&bar=2")[inline link];.
 
-Here’s an #link("/script?foo=1&bar=2")[inline link in pointy braces].
+Here’s an #link("/script?foo=1&bar=2")[inline link in pointy braces];.
 
 == Autolinks
 <autolinks>
@@ -780,7 +780,7 @@
 <images>
 From "Voyage dans la Lune" by Georges Melies \(1902):
 
-#figure([#box(width: 150.0pt, image("lalune.jpg"))],
+#figure([#box(width: 150.0pt, image("lalune.jpg"));],
   caption: [
     lalune
   ]
