packages feed

pandoc 3.1.12.3 → 3.1.13

raw patch · 33 files changed

+546/−847 lines, 33 filesdep ~texmathdep ~typstPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: texmath, typst

API changes (from Hackage documentation)

+ Text.Pandoc.Readers.Typst: instance GHC.Classes.Eq Text.Pandoc.Readers.Typst.TableSection
+ Text.Pandoc.Readers.Typst: instance GHC.Classes.Ord Text.Pandoc.Readers.Typst.TableSection
+ Text.Pandoc.Readers.Typst: instance GHC.Show.Show Text.Pandoc.Readers.Typst.TableData
+ Text.Pandoc.Readers.Typst: instance GHC.Show.Show Text.Pandoc.Readers.Typst.TableSection
+ Text.Pandoc.Writers.Shared: isOrderedListMarker :: Text -> Bool

Files

AUTHORS.md view
@@ -65,6 +65,7 @@ - Cécile Chemin - Cédric Couralet - Cezary Drożak+- Chandrahas77 - Charanjit Singh - Charlotte Koch - Chris Black
MANUAL.txt view
@@ -1,7 +1,7 @@ --- title: Pandoc User's Guide author: John MacFarlane-date: March 17, 2024+date: April 7, 2024 ---  # Synopsis
changelog.md view
@@ -1,5 +1,75 @@ # Revision history for pandoc +## pandoc 3.1.13 (2024-04-07)++  * Org reader:++    + Fix treatment of `id` property under heading (#9639).++  * DocBook reader:++    + Add empty title to admonition div if not present (#9569).+      This allows admonition elements (e.g. `<note>`) to work with+      `gfm` admonitions even if the `<title>` is not present.++  * DokuWiki reader:++    + Link text cannot contain formatting (e.g., `//` is not italics) (#9630).+    + An explicitly empty link text (`[[url|]]`) works the same as an omitted+      link text (#9632).++  * Typst reader:++    + Support Typst 0.11 table features: col/rowspans, table head+      and foot (#9588).+    + Parse cell col/rowspans.++  * CSLJson writer:++    + Put `$` or `$$` around math in `csljson` output (#9616).++  * ConTeXt writer:++    + Fix options order with `\externalfigure`. The dimensions should+      come before the class if both are present.++  * Typst writer:++    + Put label after Span, not before. Labels get applied to preceding markup+      item.+    + Support Typst 0.11 table features (#9588): colspans, rowspans,+      cell alignment overrides, relative column widths,+      header and footer, multiple table bodies with intermediate headers.+      Row heads are not yet supported.+    + The default typst template has been modified so that tables+      don't have lines by default. As is standard with pandoc, we only+      add a line under a header or over a footer. However, a different+      default stroke pattern can easily be added in a template.+    + More reliable escaping in inline `[..]` contexts (#9586). For example,+      we need to escape `[\1. April]` or it will be treated as an ordered list.+    + Handle `unnumbered` on headings (#9585).++  * LaTeX writer:++    + Fix math inside strikeout (#9597).++  * Text.Pandoc.Writers.Shared:++    + Export `isOrderedListMarker` [API change].++  * Change lhs tests so they don't use `--standalone`.+    This will avoid test failures due to minor changes in+    skylighting versions, e.g. #9589.++  * Use latest texmath, typst.++  * Require pandoc-lua-marshal 0.2.6 (#9613, Albert Krewinkel).+    Fixes an issue arising when the value of `content` properties+    on *BlockQuote*, *Figure*, and *Div* elements was an empty list.++  * Update lua-filters.md (#9611, Carlos Scheidegger).++ ## pandoc 3.1.12.3 (2024-03-17)    * Markdown reader: Fix bug with footnotes at end of fenced div (#9576).@@ -32,7 +102,7 @@   * LaTeX template: Fix block headings support for unnumbered paragraphs     (#9542, #6018, Oliver Fabel). -  * HTML templates: Replace polyfill provider (#2384, @SukkaW).+  * HTML templates: Replace polyfill provider (#9537, @SukkaW).     Replace polyfill.io with cdnjs.cloudflare.com/polyfill.     polyfill.io has been acquired by Funnull, and the service has     become unstable.
data/templates/default.typst view
@@ -10,7 +10,8 @@ }  #set table(-  inset: 6pt+  inset: 6pt,+  stroke: none )  $if(template)$
pandoc.cabal view
@@ -1,6 +1,6 @@ cabal-version:   2.4 name:            pandoc-version:         3.1.12.3+version:         3.1.13 build-type:      Simple license:         GPL-2.0-or-later license-file:    COPYING.md@@ -326,6 +326,7 @@                  test/tables/*.html4                  test/tables/*.html5                  test/tables/*.latex+                 test/tables/*.typst                  test/tables/*.native                  test/tables/*.mediawiki                  test/tables/*.jats_archiving@@ -516,7 +517,7 @@                  syb                   >= 0.1      && < 0.8,                  tagsoup               >= 0.14.6   && < 0.15,                  temporary             >= 1.1      && < 1.4,-                 texmath               >= 0.12.8.7 && < 0.13,+                 texmath               >= 0.12.8.8 && < 0.13,                  text                  >= 1.1.1.0  && < 2.2,                  text-conversions      >= 0.3      && < 0.4,                  time                  >= 1.5      && < 1.14,@@ -526,7 +527,7 @@                  zip-archive           >= 0.4.3.1  && < 0.5,                  zlib                  >= 0.5      && < 0.8,                  xml                   >= 1.3.12   && < 1.4,-                 typst                 >= 0.5.0.2  && < 0.5.1,+                 typst                 >= 0.5.0.3  && < 0.5.1,                  vector                >= 0.12     && < 0.14,                  djot                  >= 0.1.1.3  && < 0.2,                  tls                   >= 2.0.1    && < 2.1,
src/Text/Pandoc/Readers/DocBook.hs view
@@ -1108,8 +1108,9 @@            -- the title: docbook references are ambiguous on that, and some implementations of admonitions            -- (e.g. asciidoctor) just use an icon in all cases. To be conservative, we don't            -- include the label and leave it to styling.-           title <- case filterChild (named "title") e of-                        Just t  -> divWith ("", ["title"], []) . plain <$> getInlines t+           title <- divWith ("", ["title"], []) . plain <$>+                    case filterChild (named "title") e of+                        Just t  -> getInlines t                         Nothing -> return mempty            -- this will ignore the title element if it is present            b <- getBlocks e
src/Text/Pandoc/Readers/DokuWiki.hs view
@@ -300,8 +300,11 @@ parseLink f l r = f   <$  textStr l   <*> many1TillChar anyChar (lookAhead (void (char '|') <|> try (void $ textStr r)))-  <*> optionMaybe (B.trimInlines . mconcat <$> (char '|' *> manyTill inline (try $ lookAhead $ textStr r)))-  <*  textStr r+  <*> ( (char '|' *> optionMaybe (B.trimInlines . B.text . T.pack <$>+                       many1Till anyChar (lookAhead (try (textStr r)))))+       <|> pure Nothing+      )+  <* textStr r  -- | Split Interwiki link into left and right part -- | Return Nothing if it is not Interwiki link
src/Text/Pandoc/Readers/Org/DocumentTree.hs view
@@ -16,7 +16,7 @@   ) where  import Control.Arrow ((***), first)-import Control.Monad (guard)+import Control.Monad (guard, mplus) import Data.List (intersperse) import Data.Maybe (mapMaybe) import Data.Text (Text)@@ -317,10 +317,12 @@   let     toTextPair = fromKey *** fromValue     customIdKey = toPropertyKey "custom_id"+    idKey = toPropertyKey "id"     classKey    = toPropertyKey "class"     unnumberedKey = toPropertyKey "unnumbered"-    specialProperties = [customIdKey, classKey, unnumberedKey]-    id'  = maybe mempty fromValue . lookup customIdKey $ properties+    specialProperties = [customIdKey, idKey, classKey, unnumberedKey]+    id'  = maybe mempty fromValue $+              (lookup customIdKey properties `mplus` lookup idKey properties)     cls  = maybe mempty fromValue . lookup classKey    $ properties     kvs' = map toTextPair . filter ((`notElem` specialProperties) . fst)            $ properties
src/Text/Pandoc/Readers/Typst.hs view
@@ -30,7 +30,7 @@ import Text.Pandoc.Error (PandocError(..)) import Text.Pandoc.Shared (tshow, blocksToInlines) import Control.Monad.Except (throwError)-import Control.Monad (MonadPlus (mplus), void, mzero, guard)+import Control.Monad (MonadPlus (mplus), void, guard, foldM) import qualified Data.Foldable as F import qualified Data.Map as M import Data.Maybe (catMaybes, fromMaybe)@@ -39,17 +39,17 @@ import qualified Data.Set as Set import Data.Text (Text) import qualified Data.Text as T-import qualified Data.Vector as V import qualified Text.Pandoc.Builder as B import Text.Pandoc.Walk import Text.Parsec import Text.TeXMath (writeTeX) import Text.TeXMath.Shared (getSpaceChars) import Text.Pandoc.Readers.Typst.Math (pMathMany)-import Text.Pandoc.Readers.Typst.Parsing (pTok, ignored, chunks, getField, P,+import Text.Pandoc.Readers.Typst.Parsing (pTok, ignored, getField, P,                                           PState(..), defaultPState) import Typst.Methods (formatNumber, applyPureFunction) import Typst.Types+import qualified Data.Vector as V  -- import Debug.Trace @@ -330,78 +330,8 @@         B.divWith ("", [], [("stack", repr (VDirection dir))]) $           mconcat $             map (B.divWith ("", [], [])) children)-  ,("grid", \mbident fields -> do-      children <- getField "children" fields >>= mapM (pWithContents pBlocks) . V.toList-      (columns :: Val) <- getField "columns" fields-      let toWidth (VFraction f) = Just (floor $ 1000 * f)-          toWidth _ = Nothing-      let normalizeWidths xs =-            let givenwidths = catMaybes xs-                (totgivenwidth :: Int) = sum givenwidths-                avgwidth = totgivenwidth `div` length givenwidths-                totwidth = avgwidth * length xs-             in if null givenwidths-                  then replicate (length xs) B.ColWidthDefault-                  else-                    map-                      ( \case-                          Just x -> B.ColWidth (fromIntegral x / fromIntegral totwidth)-                          Nothing ->-                            B.ColWidth (fromIntegral avgwidth / fromIntegral totwidth)-                      )-                      xs-      widths <- case columns of-        VInteger x -> pure $ replicate (fromIntegral x) B.ColWidthDefault-        VArray x -> pure $ normalizeWidths $ map toWidth (V.toList x)-        VNone -> pure [B.ColWidthDefault]-        _ -> fail $ "Could not determine number of columns: " <> show columns-      let numcols = length widths-      align <- getField "align" fields-      let toAlign (VAlignment (Just horiz) _) =-            case horiz of-              HorizStart -> B.AlignLeft-              HorizLeft -> B.AlignLeft-              HorizEnd -> B.AlignRight-              HorizRight -> B.AlignRight-              HorizCenter -> B.AlignCenter-          toAlign _ = B.AlignDefault-      aligns <--        case align of-          VAlignment {} -> pure $ replicate numcols (toAlign align)-          VArray v -> pure $ map toAlign (V.toList v)-          VFunction _ _ f -> do-            mapM-              ( \colnum -> case applyPureFunction-                  f-                  [VInteger colnum, VInteger 0] of-                  Success x -> pure $ toAlign x-                  Failure e -> fail e-              )-              [0 .. (fromIntegral numcols - 1)]-          _ -> pure $ replicate numcols B.AlignDefault-      let colspecs = zip (aligns ++ repeat B.AlignDefault) widths-      let rows =-            map (B.Row B.nullAttr) $-              chunks numcols $-                map-                  ( B.Cell-                      B.nullAttr-                      B.AlignDefault-                      (B.RowSpan 1)-                      (B.ColSpan 1)-                      . B.toList-                  )-                  children-      pure $-        B.tableWith-          (fromMaybe "" mbident, [], [])-          (B.Caption mempty mempty)-          colspecs-          (B.TableHead B.nullAttr [])-          [B.TableBody B.nullAttr 0 [] rows]-          (B.TableFoot B.nullAttr []))-  ,("table", \mbident fields ->-       maybe mzero (\f -> f mbident fields) $ M.lookup "grid" blockHandlers)+  ,("grid", \mbident fields -> parseTable mbident fields)+  ,("table", \mbident fields -> parseTable mbident fields)   ,("figure", \mbident fields -> do       body <- getField "body" fields >>= pWithContents pBlocks       (mbCaption :: Maybe (Seq Content)) <- getField "caption" fields@@ -630,3 +560,135 @@    go (Elt{ eltFields = fs }) = \ts -> foldr go' ts fs    go' (VContent cs) = (findLabels cs ++)    go' _ = id++parseTable :: PandocMonad m+           => Maybe Text -> M.Map Identifier Val -> P m B.Blocks+parseTable mbident fields = do+  children <- V.toList <$> getField "children" fields+  (columns :: Val) <- getField "columns" fields+  let toWidth (VFraction f) = Just (floor $ 1000 * f)+      toWidth _ = Nothing+  let normalizeWidths xs =+        let givenwidths = catMaybes xs+            (totgivenwidth :: Int) = sum givenwidths+            avgwidth = totgivenwidth `div` length givenwidths+            totwidth = avgwidth * length xs+         in if null givenwidths+              then replicate (length xs) B.ColWidthDefault+              else+                map+                  ( \case+                      Just x ->+                        B.ColWidth (fromIntegral x / fromIntegral totwidth)+                      Nothing ->+                        B.ColWidth+                        (fromIntegral avgwidth / fromIntegral totwidth)+                  )+                  xs+  widths <- case columns of+    VInteger x -> pure $ replicate (fromIntegral x) B.ColWidthDefault+    VArray x -> pure $ normalizeWidths $ map toWidth (V.toList x)+    VNone -> pure [B.ColWidthDefault]+    _ -> fail $ "Could not determine number of columns: " <> show columns+  let numcols = length widths+  align <- getField "align" fields+  let toAlign (VAlignment (Just horiz) _) =+        case horiz of+          HorizStart -> B.AlignLeft+          HorizLeft -> B.AlignLeft+          HorizEnd -> B.AlignRight+          HorizRight -> B.AlignRight+          HorizCenter -> B.AlignCenter+      toAlign _ = B.AlignDefault+  aligns <-+    case align of+      VAlignment {} -> pure $ replicate numcols (toAlign align)+      VArray v -> pure $ map toAlign (V.toList v)+      VFunction _ _ f -> do+        mapM+          ( \colnum -> case applyPureFunction+              f+              [VInteger colnum, VInteger 0] of+              Success x -> pure $ toAlign x+              Failure e -> fail e+          )+          [0 .. (fromIntegral numcols - 1)]+      _ -> pure $ replicate numcols B.AlignDefault+  let colspecs = zip (aligns ++ repeat B.AlignDefault) widths+  let addCell' cell Nothing = addCell' cell (Just ([], []))+      addCell' cell@(B.Cell _ _ (B.RowSpan rowspan) (B.ColSpan colspan) _)+       (Just (freecols, revrows))  =+        let freecols' =+              case (rowspan + 1) - length freecols of+                n | n < 0 -> freecols+                  | otherwise -> freecols ++ replicate n numcols+        in case freecols' of+             [] -> -- should not happen+                   error "empty freecols'"+             x:xs+               | colspan <= x -- there is room on current row+                 -> let (as, bs) = splitAt rowspan (x:xs)+                    in  Just+                        (map (\z -> z - colspan) as ++ bs,+                           case revrows of+                             [] -> [[cell]]+                             r:rs -> (cell:r):rs)+               | otherwise ->+                    let (as, bs) = splitAt rowspan xs+                    in  Just (map (\z -> z - colspan) as ++ bs, [cell]:revrows)+  let addCell tableSection cell (TableData tdata) =+        TableData (M.alter (addCell' cell) tableSection tdata)+  let toCell tableSection tableData contents = do+        case contents of+          [Elt (Identifier "grid.cell") _pos fs] -> do+            bs <- B.toList <$> (getField "body" fs >>= pWithContents pBlocks)+            rowspan <- getField "rowspan" fs <|> pure 1+            colspan <- getField "colspan" fs <|> pure 1+            align' <- (toAlign <$> getField "align" fs) <|> pure B.AlignDefault+            pure $ addCell tableSection+              (B.Cell B.nullAttr align' (B.RowSpan rowspan)+                (B.ColSpan colspan) bs) tableData+          [Elt (Identifier "table.cell") pos fs] ->+            toCell tableSection tableData [Elt (Identifier "grid.cell") pos fs]+          [Elt (Identifier "table.vline") _pos _fs] -> pure tableData+          [Elt (Identifier "table.hline") _pos _fs] -> pure tableData+          [Elt (Identifier "grid.vline") _pos _fs] -> pure tableData+          [Elt (Identifier "grid.hline") _pos _fs] -> pure tableData+          [Elt (Identifier "table.header") _pos fs] ->+            getField "children" fs >>=+              foldM (toCell THeader) tableData . V.toList+          [Elt (Identifier "table.footer") _pos fs] ->+            getField "children" fs >>=+              foldM (toCell TFooter) tableData . V.toList+          _ -> do+            bs <- B.toList <$> pWithContents pBlocks contents+            pure $ addCell tableSection+              (B.Cell B.nullAttr B.AlignDefault (B.RowSpan 1) (B.ColSpan 1) bs)+              tableData+  tableData <- foldM (toCell TBody) (TableData mempty) children+  let getRows tablePart = map (B.Row B.nullAttr . reverse)+                          . maybe [] (reverse . snd)+                          . M.lookup tablePart . unTableData+  let headRows = getRows THeader tableData+  let bodyRows = getRows TBody tableData+  let footRows = getRows TFooter tableData+  pure $+    B.tableWith+      (fromMaybe "" mbident, [], [])+      (B.Caption mempty mempty)+      colspecs+      (B.TableHead B.nullAttr headRows)+      [B.TableBody B.nullAttr 0 [] bodyRows]+      (B.TableFoot B.nullAttr footRows)++data TableSection = THeader | TBody | TFooter+  deriving (Show, Ord, Eq)++newtype TableData =+  TableData { unTableData :: M.Map TableSection ([Int], [[Cell]]) }+  deriving (Show)+  -- for each table section, we have a pair+  -- the first element indicates the number of column spaces left+  -- in [currentLine, nextLine, lineAfter, etc.]+  -- the second element is a list of rows, in reverse order,+  -- each of which is a list of cells, in reverse order
src/Text/Pandoc/Writers/ConTeXt.hs view
@@ -707,7 +707,7 @@              if isURI src                 then src                 else T.pack $ unEscapeString $ T.unpack src-  return $ braces $ "\\externalfigure" <> brackets (literal src') <> dims <> clas+  return $ braces $ "\\externalfigure" <> brackets (literal src') <> clas <> dims inlineToConTeXt (Note contents) = do   contents' <- blockListToConTeXt contents   let codeBlock x@(CodeBlock _ _) = [x]
src/Text/Pandoc/Writers/CslJson.hs view
@@ -71,7 +71,8 @@ fromInline Space = CslText " " fromInline SoftBreak = CslText " " fromInline LineBreak = CslText "\n"-fromInline (Math _ t) = CslText t+fromInline (Math InlineMath t) = CslText $ "$" <> t <> "$"+fromInline (Math DisplayMath t) = CslText $ "$$" <> t <> "$$" fromInline (RawInline _ _) = CslEmpty fromInline (Link _ ils _) = fromInlines ils fromInline (Image _ ils _) = fromInlines ils
src/Text/Pandoc/Writers/LaTeX.hs view
@@ -868,7 +868,10 @@   -- incorrect results if there is a space, see #5529   contents <- inlineListToLaTeX $ walk (concatMap protectCode) lst   modify $ \s -> s{ stStrikeout = True }-  return $ inCmd "st" contents+  -- soul doesn't like \(..\) delimiters, so we change these to $ (#9597):+  let fixMath = T.replace "\\(" "$" . T.replace "\\)" "$" .+                T.replace "\\[" "$$" . T.replace "\\]" "$$"+  return $ inCmd "st" $ fixMath <$> contents inlineToLaTeX (Superscript lst) =   inCmd "textsuperscript" <$> inlineListToLaTeX lst inlineToLaTeX (Subscript lst) =
src/Text/Pandoc/Writers/Markdown/Inline.hs view
@@ -332,14 +332,6 @@   toList (Concat a b) = a : toList b   toList x = [x] -isOrderedListMarker :: Text -> Bool-isOrderedListMarker xs = not (T.null xs) && (T.last xs `elem` ['.',')']) &&-              isRight (runParser (anyOrderedListMarker >> eof)-                       defaultParserState "" xs)- where-  isRight (Right _) = True-  isRight (Left  _) = False- -- | Convert Pandoc inline element to markdown. inlineToMarkdown :: PandocMonad m => WriterOptions -> Inline -> MD m (Doc Text) inlineToMarkdown opts (Span ("",["emoji"],kvs) [Str s]) =
src/Text/Pandoc/Writers/Shared.hs view
@@ -44,11 +44,13 @@                      , splitSentences                      , ensureValidXmlIdentifiers                      , setupTranslations+                     , isOrderedListMarker                      ) where import Safe (lastMay) import qualified Data.ByteString.Lazy as BL import Control.Monad (zipWithM)+import Data.Either (isRight) import Data.Aeson (ToJSON (..), encode) import Data.Char (chr, ord, isSpace, isLetter, isUpper) import Data.List (groupBy, intersperse, transpose, foldl')@@ -61,6 +63,8 @@ import Text.Pandoc.CSS (cssAttributes) import Text.Pandoc.Definition import Text.Pandoc.Options+import Text.Pandoc.Parsing (runParser, eof, defaultParserState,+                            anyOrderedListMarker) import Text.DocLayout import Text.Pandoc.Shared (stringify, makeSections, blocksToInlines) import Text.Pandoc.Walk (Walkable(..))@@ -626,3 +630,9 @@             "" -> pure defLang             s  -> fromMaybe defLang <$> toLang (Just s)   setTranslations lang++-- True if the string would count as a Markdown ordered list marker.+isOrderedListMarker :: Text -> Bool+isOrderedListMarker xs = not (T.null xs) && (T.last xs `elem` ['.',')']) &&+              isRight (runParser (anyOrderedListMarker >> eof)+                       defaultParserState "" xs)
src/Text/Pandoc/Writers/Typst.hs view
@@ -20,12 +20,13 @@ import Text.Pandoc.Class ( PandocMonad) import Text.Pandoc.Options ( WriterOptions(..), WrapOption(..), isEnabled ) import Data.Text (Text)-import Data.List (intercalate)+import Data.List (intercalate, intersperse) import Network.URI (unEscapeString) import qualified Data.Text as T import Control.Monad.State ( StateT, evalStateT, gets, modify ) import Text.Pandoc.Writers.Shared ( metaToContext, defField, resetField,-                                    toLegacyTable, lookupMetaString )+                                    lookupMetaString,+                                    isOrderedListMarker ) import Text.Pandoc.Shared (isTightList, orderedListMarkers, tshow) import Text.Pandoc.Writers.Math (convertMath) import qualified Text.TeXMath as TM@@ -33,6 +34,7 @@ import Text.DocTemplates (renderTemplate) import Text.Pandoc.Extensions (Extension(..)) import Text.Collate.Lang (Lang(..), parseLang)+import Text.Printf (printf) import Data.Char (isAlphaNum)  -- | Convert Pandoc to Typst.@@ -97,13 +99,18 @@     Header level (ident,cls,_) inlines -> do       contents <- inlinesToTypst inlines       let lab = toLabel FreestandingLabel ident+      let headingAttrs =+            ["outlined: false" | "unlisted" `elem` cls] +++            ["numbering: none" | "unnumbered" `elem` cls]       return $-        if "unlisted" `elem` cls-           then literal "#heading(outlined: false)" <> brackets contents <>-                 cr <> lab-           else nowrap+        if null headingAttrs+           then nowrap                  (literal (T.replicate level "=") <> space <> contents) <>                  cr <> lab+           else literal "#heading" <>+                  parens (literal (T.intercalate ", "+                              ("level: " <> tshow level : headingAttrs))) <>+                  brackets contents <> cr <> lab     RawBlock fmt str ->       case fmt of         Format "typst" -> return $ literal str@@ -156,33 +163,80 @@                    else vsep items') $$ blankline     DefinitionList items ->       ($$ blankline) . vsep <$> mapM defListItemToTypst items-    Table (ident,_,_) blkCapt colspecs thead tbodies tfoot -> do-      let (caption, aligns, _, headers, rows) =-            toLegacyTable blkCapt colspecs thead tbodies tfoot-      let numcols = length aligns-      headers' <- mapM blocksToTypst headers-      rows' <- mapM (mapM blocksToTypst) rows+    Table (ident,_,_) (Caption _ caption) colspecs thead tbodies tfoot -> do+      let lab = toLabel FreestandingLabel ident       capt' <- if null caption                   then return mempty                   else do-                    captcontents <- inlinesToTypst caption+                    captcontents <- blocksToTypst caption                     return $ ", caption: " <> brackets captcontents-      let lab = toLabel FreestandingLabel ident+      let numcols = length colspecs+      let (aligns, widths) = unzip colspecs+      let commaSep = hcat . intersperse ", "+      let toPercentage (ColWidth w) =+            literal $ (T.dropWhileEnd (== '.') . T.dropWhileEnd (== '0'))+                         (T.pack (printf "%0.2f" (w * 100))) <> "%"+          toPercentage ColWidthDefault = literal "auto"+      let columns = if all (== ColWidthDefault) widths+                       then literal $ tshow numcols+                       else parens (commaSep (map toPercentage widths))       let formatalign AlignLeft = "left,"           formatalign AlignRight = "right,"           formatalign AlignCenter = "center,"           formatalign AlignDefault = "auto,"       let alignarray = parens $ mconcat $ map formatalign aligns+      let fromCell (Cell _attr alignment rowspan colspan bs) = do+            let cellattrs =+                  (case alignment of+                     AlignDefault -> []+                     AlignLeft -> [ "align: left" ]+                     AlignRight -> [ "align: right" ]+                     AlignCenter -> [ "align: center" ]) +++                  (case rowspan of+                     RowSpan 1 -> []+                     RowSpan n -> [ "rowspan: " <> tshow n ]) +++                  (case colspan of+                     ColSpan 1 -> []+                     ColSpan n -> [ "colspan: " <> tshow n ])+            cellContents <- blocksToTypst bs+            pure $ if null cellattrs+                      then brackets cellContents+                      else "table.cell" <>+                            parens+                             (literal (T.intercalate ", " cellattrs)) <>+                            brackets cellContents+      let fromRow (Row _ cs) =+            (<> ",") . commaSep <$> mapM fromCell cs+      let fromHead (TableHead _attr headRows) =+            if null headRows+               then pure mempty+               else (($$ "table.hline(),") .+                      (<> ",") . ("table.header" <>) . parens . nest 2 . vcat)+                      <$> mapM fromRow headRows+      let fromFoot (TableFoot _attr footRows) =+            if null footRows+               then pure mempty+               else (("table.hline()," $$) .+                      (<> ",") . ("table.footer" <>) . parens . nest 2 . vcat)+                      <$> mapM fromRow footRows+      let fromTableBody (TableBody _attr _rowHeadCols headRows bodyRows) = do+            hrows <- mapM fromRow headRows+            brows <- mapM fromRow bodyRows+            pure $ vcat (hrows ++ ["table.hline()," | not (null hrows)] ++ brows)+      header <- fromHead thead+      footer <- fromFoot tfoot+      body <- vcat <$> mapM fromTableBody tbodies       return $         "#figure("         $$         nest 2          ("align(center)[#table("           $$ nest 2-             (  "columns: " <> text (show numcols) <> "," -- auto-             $$ "align: (col, row) => " <> alignarray <> ".at(col),"-             $$ hsep (map ((<>",") . brackets) headers')-             $$ vcat (map (\x -> brackets x <> ",") (concat rows'))+             (  "columns: " <> columns <> ","+             $$ "align: " <> alignarray <> ","+             $$ header+             $$ body+             $$ footer              )           $$ ")]"           $$ capt'@@ -227,9 +281,6 @@   return $ hang ind (marker <> space) contents  inlinesToTypst :: PandocMonad m => [Inline] -> TW m (Doc Text)-inlinesToTypst ils@(Str t : _) -- need to escape - in '[-]' #9478-  | Just (c, _) <- T.uncons t-  , needsEscapeAtLineStart c = ("\\" <>) . hcat <$> mapM inlineToTypst ils inlinesToTypst ils = hcat <$> mapM inlineToTypst ils  inlineToTypst :: PandocMonad m => Inline -> TW m (Doc Text)@@ -274,7 +325,7 @@     SmallCaps inlines -> textstyle "#smallcaps" inlines     Span (ident,_,_) inlines -> do       let lab = toLabel FreestandingLabel ident-      (lab $$) <$> inlinesToTypst inlines+      (<> lab) <$> inlinesToTypst inlines     Quoted quoteType inlines -> do       let q = case quoteType of                    DoubleQuote -> literal "\""@@ -325,7 +376,15 @@  textstyle :: PandocMonad m => Doc Text -> [Inline] -> TW m (Doc Text) textstyle s inlines =-  (<> endCode) . (s <>) . brackets <$> inlinesToTypst inlines+  (<> endCode) . (s <>) . brackets . addEscape <$> inlinesToTypst inlines+ where+   addEscape =+     case inlines of+       (Str t : _)+         | isOrderedListMarker t -> ("\\" <>)+         | Just (c, _) <- T.uncons t+         , needsEscapeAtLineStart c -> ("\\" <>)+       _ -> id  escapeTypst :: EscapeContext -> Text -> Doc Text escapeTypst context t =
test/Tests/Old.hs view
@@ -199,7 +199,7 @@     [ testGroup "writer" $ writerTests' "ms"     ]   , testGroup "typst"-    [ testGroup "writer" $ writerTests' "typst"+    [ testGroup "writer" $ writerTests' "typst" ++ extWriterTests' "typst"     , testGroup "reader"        [ test' "typst-reader" ["-r", "typst", "-w", "native", "-s"]           "typst-reader.typ" "typst-reader.native"@@ -264,7 +264,7 @@     ]   where     t n f = test pandocPath-             n ["--wrap=preserve", "-r", "native", "-s",+             n ["--wrap=preserve", "-r", "native",               "--markdown-headings=setext", "-w", f]              "lhs-test.native" ("lhs-test" <.> f) 
+ test/command/9569.md view
@@ -0,0 +1,19 @@+```+% pandoc -f docbook -t gfm+<note>+  <para>Some content</para>+</note>+<para>Spacer.</para>+<note>+  <title>A note with a title. Works, but the title is discarded.</title>+  <para>Some content</para>+</note>+^D+> [!NOTE]+> Some content++Spacer.++> [!NOTE]+> Some content+```
+ test/command/9585.md view
@@ -0,0 +1,11 @@+```+% pandoc -f native -t typst+[ Header 2 ( "" , [] , [] ) [ Str "One" ]+, Header 2 ( "" , [ "unnumbered", "unlisted" ] , [] ) [ Str "Two" ]+, Header 2 ( "" , [] , [] ) [ Str "Three" ]+]+^D+== One+#heading(level: 2, outlined: false, numbering: none)[Two]+== Three+```
+ test/command/9586.md view
@@ -0,0 +1,7 @@+```+% pandoc -t typst+**1. April 2024**+^D+#strong[\1. April 2024]++```
+ test/command/9597.md view
@@ -0,0 +1,6 @@+```+% pandoc -t latex+~~$T$~~+^D+\st{$T$}+```
+ test/command/9616.md view
@@ -0,0 +1,16 @@+```+% pandoc -f bibtex -t csljson -s+@MISC {3252037,+    TITLE = {Isomorphism between projective varieties $\mathbf{P}^{1}$ and a conic in $\mathbf{P}^{2}$},+    URL = {https://math.stackexchange.com/q/3252037}+}+^D+[+  {+    "URL": "https://math.stackexchange.com/q/3252037",+    "id": "3252037",+    "title": "Isomorphism between projective varieties $\\mathbf{P}^{1}$ and a conic in $\\mathbf{P}^{2}$",+    "type": ""+  }+]+```
+ test/command/9630.md view
@@ -0,0 +1,12 @@+```+% pandoc -f dokuwiki+  * [[https://example.com|https://example.com]]+  * [[https://example.com/start#monitoring|https://example.com/start#monitoring]]+^D+<ul>+<li><a href="https://example.com">https://example.com</a></li>+<li><a+href="https://example.com/start#monitoring">https://example.com/start#monitoring</a></li>+</ul>++```
+ test/command/9632.md view
@@ -0,0 +1,7 @@+```+% pandoc -f dokuwiki+[[.:supprimer-profil-windows|]]+^D+<p><a href="supprimer-profil-windows">supprimer-profil-windows</a></p>++```
+ test/command/9639.md view
@@ -0,0 +1,11 @@+```+% pandoc -f org -t native+#+title: repro++* heading-name+:PROPERTIES:+:ID:       123abc+:END:+^D+[ Header 1 ( "123abc" , [] , [] ) [ Str "heading-name" ] ]+```
test/lhs-test.html view
@@ -1,238 +1,3 @@-<!DOCTYPE html>-<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">-<head>-  <meta charset="utf-8" />-  <meta name="generator" content="pandoc" />-  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />-  <title>lhs-test</title>-  <style>-    html {-      color: #1a1a1a;-      background-color: #fdfdfd;-    }-    body {-      margin: 0 auto;-      max-width: 36em;-      padding-left: 50px;-      padding-right: 50px;-      padding-top: 50px;-      padding-bottom: 50px;-      hyphens: auto;-      overflow-wrap: break-word;-      text-rendering: optimizeLegibility;-      font-kerning: normal;-    }-    @media (max-width: 600px) {-      body {-        font-size: 0.9em;-        padding: 12px;-      }-      h1 {-        font-size: 1.8em;-      }-    }-    @media print {-      html {-        background-color: white;-      }-      body {-        background-color: transparent;-        color: black;-        font-size: 12pt;-      }-      p, h2, h3 {-        orphans: 3;-        widows: 3;-      }-      h2, h3, h4 {-        page-break-after: avoid;-      }-    }-    p {-      margin: 1em 0;-    }-    a {-      color: #1a1a1a;-    }-    a:visited {-      color: #1a1a1a;-    }-    img {-      max-width: 100%;-    }-    svg {-      height: auto;-      max-width: 100%;-    }-    h1, h2, h3, h4, h5, h6 {-      margin-top: 1.4em;-    }-    h5, h6 {-      font-size: 1em;-      font-style: italic;-    }-    h6 {-      font-weight: normal;-    }-    ol, ul {-      padding-left: 1.7em;-      margin-top: 1em;-    }-    li > ol, li > ul {-      margin-top: 0;-    }-    blockquote {-      margin: 1em 0 1em 1.7em;-      padding-left: 1em;-      border-left: 2px solid #e6e6e6;-      color: #606060;-    }-    code {-      font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;-      font-size: 85%;-      margin: 0;-      hyphens: manual;-    }-    pre {-      margin: 1em 0;-      overflow: auto;-    }-    pre code {-      padding: 0;-      overflow: visible;-      overflow-wrap: normal;-    }-    .sourceCode {-     background-color: transparent;-     overflow: visible;-    }-    hr {-      background-color: #1a1a1a;-      border: none;-      height: 1px;-      margin: 1em 0;-    }-    table {-      margin: 1em 0;-      border-collapse: collapse;-      width: 100%;-      overflow-x: auto;-      display: block;-      font-variant-numeric: lining-nums tabular-nums;-    }-    table caption {-      margin-bottom: 0.75em;-    }-    tbody {-      margin-top: 0.5em;-      border-top: 1px solid #1a1a1a;-      border-bottom: 1px solid #1a1a1a;-    }-    th {-      border-top: 1px solid #1a1a1a;-      padding: 0.25em 0.5em 0.25em 0.5em;-    }-    td {-      padding: 0.125em 0.5em 0.25em 0.5em;-    }-    header {-      margin-bottom: 4em;-      text-align: center;-    }-    #TOC li {-      list-style: none;-    }-    #TOC ul {-      padding-left: 1.3em;-    }-    #TOC > ul {-      padding-left: 0;-    }-    #TOC a:not(:hover) {-      text-decoration: none;-    }-    code{white-space: pre-wrap;}-    span.smallcaps{font-variant: small-caps;}-    div.columns{display: flex; gap: min(4vw, 1.5em);}-    div.column{flex: auto; overflow-x: auto;}-    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}-    /* The extra [class] is a hack that increases specificity enough to-       override a similar rule in reveal.js */-    ul.task-list[class]{list-style: none;}-    ul.task-list li input[type="checkbox"] {-      font-size: inherit;-      width: 0.8em;-      margin: 0 0.8em 0.2em -1.6em;-      vertical-align: middle;-    }-    .display.math{display: block; text-align: center; margin: 0.5rem auto;}-    /* CSS for syntax highlighting */-    pre > code.sourceCode { white-space: pre; position: relative; }-    pre > code.sourceCode > span { line-height: 1.25; }-    pre > code.sourceCode > span:empty { height: 1.2em; }-    .sourceCode { overflow: visible; }-    code.sourceCode > span { color: inherit; text-decoration: inherit; }-    div.sourceCode { margin: 1em 0; }-    pre.sourceCode { margin: 0; }-    @media screen {-    div.sourceCode { overflow: auto; }-    }-    @media print {-    pre > code.sourceCode { white-space: pre-wrap; }-    pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }-    }-    pre.numberSource code-      { counter-reset: source-line 0; }-    pre.numberSource code > span-      { position: relative; left: -4em; counter-increment: source-line; }-    pre.numberSource code > span > a:first-child::before-      { content: counter(source-line);-        position: relative; left: -1em; text-align: right; vertical-align: baseline;-        border: none; display: inline-block;-        -webkit-touch-callout: none; -webkit-user-select: none;-        -khtml-user-select: none; -moz-user-select: none;-        -ms-user-select: none; user-select: none;-        padding: 0 4px; width: 4em;-        color: #aaaaaa;-      }-    pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }-    div.sourceCode-      {   }-    @media screen {-    pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }-    }-    code span.al { color: #ff0000; font-weight: bold; } /* Alert */-    code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */-    code span.at { color: #7d9029; } /* Attribute */-    code span.bn { color: #40a070; } /* BaseN */-    code span.bu { color: #008000; } /* BuiltIn */-    code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */-    code span.ch { color: #4070a0; } /* Char */-    code span.cn { color: #880000; } /* Constant */-    code span.co { color: #60a0b0; font-style: italic; } /* Comment */-    code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */-    code span.do { color: #ba2121; font-style: italic; } /* Documentation */-    code span.dt { color: #902000; } /* DataType */-    code span.dv { color: #40a070; } /* DecVal */-    code span.er { color: #ff0000; font-weight: bold; } /* Error */-    code span.ex { } /* Extension */-    code span.fl { color: #40a070; } /* Float */-    code span.fu { color: #06287e; } /* Function */-    code span.im { color: #008000; font-weight: bold; } /* Import */-    code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */-    code span.kw { color: #007020; font-weight: bold; } /* Keyword */-    code span.op { color: #666666; } /* Operator */-    code span.ot { color: #007020; } /* Other */-    code span.pp { color: #bc7a00; } /* Preprocessor */-    code span.sc { color: #4070a0; } /* SpecialChar */-    code span.ss { color: #bb6688; } /* SpecialString */-    code span.st { color: #4070a0; } /* String */-    code span.va { color: #19177c; } /* Variable */-    code span.vs { color: #4070a0; } /* VerbatimString */-    code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */-  </style>-</head>-<body> <h1 id="lhs-test">lhs test</h1> <p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>@@ -247,5 +12,3 @@ <blockquote> <p>foo bar</p> </blockquote>-</body>-</html>
test/lhs-test.html+lhs view
@@ -1,238 +1,3 @@-<!DOCTYPE html>-<html xmlns="http://www.w3.org/1999/xhtml" lang="" xml:lang="">-<head>-  <meta charset="utf-8" />-  <meta name="generator" content="pandoc" />-  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />-  <title>lhs-test</title>-  <style>-    html {-      color: #1a1a1a;-      background-color: #fdfdfd;-    }-    body {-      margin: 0 auto;-      max-width: 36em;-      padding-left: 50px;-      padding-right: 50px;-      padding-top: 50px;-      padding-bottom: 50px;-      hyphens: auto;-      overflow-wrap: break-word;-      text-rendering: optimizeLegibility;-      font-kerning: normal;-    }-    @media (max-width: 600px) {-      body {-        font-size: 0.9em;-        padding: 12px;-      }-      h1 {-        font-size: 1.8em;-      }-    }-    @media print {-      html {-        background-color: white;-      }-      body {-        background-color: transparent;-        color: black;-        font-size: 12pt;-      }-      p, h2, h3 {-        orphans: 3;-        widows: 3;-      }-      h2, h3, h4 {-        page-break-after: avoid;-      }-    }-    p {-      margin: 1em 0;-    }-    a {-      color: #1a1a1a;-    }-    a:visited {-      color: #1a1a1a;-    }-    img {-      max-width: 100%;-    }-    svg {-      height: auto;-      max-width: 100%;-    }-    h1, h2, h3, h4, h5, h6 {-      margin-top: 1.4em;-    }-    h5, h6 {-      font-size: 1em;-      font-style: italic;-    }-    h6 {-      font-weight: normal;-    }-    ol, ul {-      padding-left: 1.7em;-      margin-top: 1em;-    }-    li > ol, li > ul {-      margin-top: 0;-    }-    blockquote {-      margin: 1em 0 1em 1.7em;-      padding-left: 1em;-      border-left: 2px solid #e6e6e6;-      color: #606060;-    }-    code {-      font-family: Menlo, Monaco, Consolas, 'Lucida Console', monospace;-      font-size: 85%;-      margin: 0;-      hyphens: manual;-    }-    pre {-      margin: 1em 0;-      overflow: auto;-    }-    pre code {-      padding: 0;-      overflow: visible;-      overflow-wrap: normal;-    }-    .sourceCode {-     background-color: transparent;-     overflow: visible;-    }-    hr {-      background-color: #1a1a1a;-      border: none;-      height: 1px;-      margin: 1em 0;-    }-    table {-      margin: 1em 0;-      border-collapse: collapse;-      width: 100%;-      overflow-x: auto;-      display: block;-      font-variant-numeric: lining-nums tabular-nums;-    }-    table caption {-      margin-bottom: 0.75em;-    }-    tbody {-      margin-top: 0.5em;-      border-top: 1px solid #1a1a1a;-      border-bottom: 1px solid #1a1a1a;-    }-    th {-      border-top: 1px solid #1a1a1a;-      padding: 0.25em 0.5em 0.25em 0.5em;-    }-    td {-      padding: 0.125em 0.5em 0.25em 0.5em;-    }-    header {-      margin-bottom: 4em;-      text-align: center;-    }-    #TOC li {-      list-style: none;-    }-    #TOC ul {-      padding-left: 1.3em;-    }-    #TOC > ul {-      padding-left: 0;-    }-    #TOC a:not(:hover) {-      text-decoration: none;-    }-    code{white-space: pre-wrap;}-    span.smallcaps{font-variant: small-caps;}-    div.columns{display: flex; gap: min(4vw, 1.5em);}-    div.column{flex: auto; overflow-x: auto;}-    div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}-    /* The extra [class] is a hack that increases specificity enough to-       override a similar rule in reveal.js */-    ul.task-list[class]{list-style: none;}-    ul.task-list li input[type="checkbox"] {-      font-size: inherit;-      width: 0.8em;-      margin: 0 0.8em 0.2em -1.6em;-      vertical-align: middle;-    }-    .display.math{display: block; text-align: center; margin: 0.5rem auto;}-    /* CSS for syntax highlighting */-    pre > code.sourceCode { white-space: pre; position: relative; }-    pre > code.sourceCode > span { line-height: 1.25; }-    pre > code.sourceCode > span:empty { height: 1.2em; }-    .sourceCode { overflow: visible; }-    code.sourceCode > span { color: inherit; text-decoration: inherit; }-    div.sourceCode { margin: 1em 0; }-    pre.sourceCode { margin: 0; }-    @media screen {-    div.sourceCode { overflow: auto; }-    }-    @media print {-    pre > code.sourceCode { white-space: pre-wrap; }-    pre > code.sourceCode > span { display: inline-block; text-indent: -5em; padding-left: 5em; }-    }-    pre.numberSource code-      { counter-reset: source-line 0; }-    pre.numberSource code > span-      { position: relative; left: -4em; counter-increment: source-line; }-    pre.numberSource code > span > a:first-child::before-      { content: counter(source-line);-        position: relative; left: -1em; text-align: right; vertical-align: baseline;-        border: none; display: inline-block;-        -webkit-touch-callout: none; -webkit-user-select: none;-        -khtml-user-select: none; -moz-user-select: none;-        -ms-user-select: none; user-select: none;-        padding: 0 4px; width: 4em;-        color: #aaaaaa;-      }-    pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }-    div.sourceCode-      {   }-    @media screen {-    pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }-    }-    code span.al { color: #ff0000; font-weight: bold; } /* Alert */-    code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */-    code span.at { color: #7d9029; } /* Attribute */-    code span.bn { color: #40a070; } /* BaseN */-    code span.bu { color: #008000; } /* BuiltIn */-    code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */-    code span.ch { color: #4070a0; } /* Char */-    code span.cn { color: #880000; } /* Constant */-    code span.co { color: #60a0b0; font-style: italic; } /* Comment */-    code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */-    code span.do { color: #ba2121; font-style: italic; } /* Documentation */-    code span.dt { color: #902000; } /* DataType */-    code span.dv { color: #40a070; } /* DecVal */-    code span.er { color: #ff0000; font-weight: bold; } /* Error */-    code span.ex { } /* Extension */-    code span.fl { color: #40a070; } /* Float */-    code span.fu { color: #06287e; } /* Function */-    code span.im { color: #008000; font-weight: bold; } /* Import */-    code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */-    code span.kw { color: #007020; font-weight: bold; } /* Keyword */-    code span.op { color: #666666; } /* Operator */-    code span.ot { color: #007020; } /* Other */-    code span.pp { color: #bc7a00; } /* Preprocessor */-    code span.sc { color: #4070a0; } /* SpecialChar */-    code span.ss { color: #bb6688; } /* SpecialString */-    code span.st { color: #4070a0; } /* String */-    code span.va { color: #19177c; } /* Variable */-    code span.vs { color: #4070a0; } /* VerbatimString */-    code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */-  </style>-</head>-<body> <h1 id="lhs-test">lhs test</h1> <p><code>unsplit</code> is an arrow that takes a pair of values and combines them to return a single value:</p>@@ -247,5 +12,3 @@ <blockquote> <p>foo bar</p> </blockquote>-</body>-</html>
test/lhs-test.latex view
@@ -1,98 +1,3 @@-% Options for packages loaded elsewhere-\PassOptionsToPackage{unicode}{hyperref}-\PassOptionsToPackage{hyphens}{url}-%-\documentclass[-]{article}-\usepackage{amsmath,amssymb}-\usepackage{iftex}-\ifPDFTeX-  \usepackage[T1]{fontenc}-  \usepackage[utf8]{inputenc}-  \usepackage{textcomp} % provide euro and other symbols-\else % if luatex or xetex-  \usepackage{unicode-math} % this also loads fontspec-  \defaultfontfeatures{Scale=MatchLowercase}-  \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}-\fi-\usepackage{lmodern}-\ifPDFTeX\else-  % xetex/luatex font selection-\fi-% Use upquote if available, for straight quotes in verbatim environments-\IfFileExists{upquote.sty}{\usepackage{upquote}}{}-\IfFileExists{microtype.sty}{% use microtype if available-  \usepackage[]{microtype}-  \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts-}{}-\makeatletter-\@ifundefined{KOMAClassName}{% if non-KOMA class-  \IfFileExists{parskip.sty}{%-    \usepackage{parskip}-  }{% else-    \setlength{\parindent}{0pt}-    \setlength{\parskip}{6pt plus 2pt minus 1pt}}-}{% if KOMA class-  \KOMAoptions{parskip=half}}-\makeatother-\usepackage{xcolor}-\usepackage{color}-\usepackage{fancyvrb}-\newcommand{\VerbBar}{|}-\newcommand{\VERB}{\Verb[commandchars=\\\{\}]}-\DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}-% Add ',fontsize=\small' for more characters per line-\newenvironment{Shaded}{}{}-\newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}-\newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}-\newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}}-\newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}-\newcommand{\BuiltInTok}[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}}-\newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}-\newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}}-\newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}-\newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}}-\newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}-\newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}}-\newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}-\newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}}-\newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}-\newcommand{\ExtensionTok}[1]{#1}-\newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}-\newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}}-\newcommand{\ImportTok}[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}}-\newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}-\newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}-\newcommand{\NormalTok}[1]{#1}-\newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}-\newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}}-\newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}}-\newcommand{\RegionMarkerTok}[1]{#1}-\newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}-\newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}}-\newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}-\newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}}-\newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}-\newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}-\setlength{\emergencystretch}{3em} % prevent overfull lines-\providecommand{\tightlist}{%-  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}-\setcounter{secnumdepth}{-\maxdimen} % remove section numbering-\ifLuaTeX-  \usepackage{selnolig}  % disable illegal ligatures-\fi-\usepackage{bookmark}-\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available-\urlstyle{same}-\hypersetup{-  hidelinks,-  pdfcreator={LaTeX via pandoc}}--\author{}-\date{}--\begin{document}- \section{lhs test}\label{lhs-test}  \texttt{unsplit} is an arrow that takes a pair of values and combines them to@@ -119,5 +24,3 @@ \begin{quote} foo bar \end{quote}--\end{document}
test/lhs-test.latex+lhs view
@@ -1,65 +1,3 @@-% Options for packages loaded elsewhere-\PassOptionsToPackage{unicode}{hyperref}-\PassOptionsToPackage{hyphens}{url}-%-\documentclass[-]{article}-\usepackage{amsmath,amssymb}-\usepackage{iftex}-\ifPDFTeX-  \usepackage[T1]{fontenc}-  \usepackage[utf8]{inputenc}-  \usepackage{textcomp} % provide euro and other symbols-\else % if luatex or xetex-  \usepackage{unicode-math} % this also loads fontspec-  \defaultfontfeatures{Scale=MatchLowercase}-  \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}-\fi-\usepackage{lmodern}-\ifPDFTeX\else-  % xetex/luatex font selection-\fi-% Use upquote if available, for straight quotes in verbatim environments-\IfFileExists{upquote.sty}{\usepackage{upquote}}{}-\IfFileExists{microtype.sty}{% use microtype if available-  \usepackage[]{microtype}-  \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts-}{}-\makeatletter-\@ifundefined{KOMAClassName}{% if non-KOMA class-  \IfFileExists{parskip.sty}{%-    \usepackage{parskip}-  }{% else-    \setlength{\parindent}{0pt}-    \setlength{\parskip}{6pt plus 2pt minus 1pt}}-}{% if KOMA class-  \KOMAoptions{parskip=half}}-\makeatother-\usepackage{xcolor}-\usepackage{listings}-\newcommand{\passthrough}[1]{#1}-\lstset{defaultdialect=[5.3]Lua}-\lstset{defaultdialect=[x86masm]Assembler}-\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{}-\setlength{\emergencystretch}{3em} % prevent overfull lines-\providecommand{\tightlist}{%-  \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}-\setcounter{secnumdepth}{-\maxdimen} % remove section numbering-\ifLuaTeX-  \usepackage{selnolig}  % disable illegal ligatures-\fi-\usepackage{bookmark}-\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available-\urlstyle{same}-\hypersetup{-  hidelinks,-  pdfcreator={LaTeX via pandoc}}--\author{}-\date{}--\begin{document}- \section{lhs test}\label{lhs-test}  \texttt{unsplit} is an arrow that takes a pair of values and combines them to@@ -84,5 +22,3 @@ \begin{quote} foo bar \end{quote}--\end{document}
test/tables.typst view
@@ -3,20 +3,12 @@ #figure(   align(center)[#table(     columns: 4,-    align: (col, row) => (right,left,center,auto,).at(col),-    [Right], [Left], [Center], [Default],-    [12],-    [12],-    [12],-    [12],-    [123],-    [123],-    [123],-    [123],-    [1],-    [1],-    [1],-    [1],+    align: (right,left,center,auto,),+    table.header([Right], [Left], [Center], [Default],),+    table.hline(),+    [12], [12], [12], [12],+    [123], [123], [123], [123],+    [1], [1], [1], [1],   )]   , caption: [Demonstration of simple table syntax.]   , kind: table@@ -27,20 +19,12 @@ #figure(   align(center)[#table(     columns: 4,-    align: (col, row) => (right,left,center,auto,).at(col),-    [Right], [Left], [Center], [Default],-    [12],-    [12],-    [12],-    [12],-    [123],-    [123],-    [123],-    [123],-    [1],-    [1],-    [1],-    [1],+    align: (right,left,center,auto,),+    table.header([Right], [Left], [Center], [Default],),+    table.hline(),+    [12], [12], [12], [12],+    [123], [123], [123], [123],+    [1], [1], [1], [1],   )]   , kind: table   )@@ -50,20 +34,12 @@ #figure(   align(center)[#table(     columns: 4,-    align: (col, row) => (right,left,center,auto,).at(col),-    [Right], [Left], [Center], [Default],-    [12],-    [12],-    [12],-    [12],-    [123],-    [123],-    [123],-    [123],-    [1],-    [1],-    [1],-    [1],+    align: (right,left,center,auto,),+    table.header([Right], [Left], [Center], [Default],),+    table.hline(),+    [12], [12], [12], [12],+    [123], [123], [123], [123],+    [1], [1], [1], [1],   )]   , caption: [Demonstration of simple table syntax.]   , kind: table@@ -73,17 +49,14 @@  #figure(   align(center)[#table(-    columns: 4,-    align: (col, row) => (center,left,right,left,).at(col),-    [Centered Header], [Left Aligned], [Right Aligned], [Default aligned],-    [First],-    [row],-    [12.0],-    [Example of a row that spans multiple lines.],-    [Second],-    [row],-    [5.0],-    [Here’s another one. Note the blank line between rows.],+    columns: (15%, 13.75%, 16.25%, 35%),+    align: (center,left,right,left,),+    table.header([Centered Header], [Left Aligned], [Right Aligned], [Default+      aligned],),+    table.hline(),+    [First], [row], [12.0], [Example of a row that spans multiple lines.],+    [Second], [row], [5.0], [Here’s another one. Note the blank line between+    rows.],   )]   , caption: [Here’s the caption. It may span multiple lines.]   , kind: table@@ -93,17 +66,14 @@  #figure(   align(center)[#table(-    columns: 4,-    align: (col, row) => (center,left,right,left,).at(col),-    [Centered Header], [Left Aligned], [Right Aligned], [Default aligned],-    [First],-    [row],-    [12.0],-    [Example of a row that spans multiple lines.],-    [Second],-    [row],-    [5.0],-    [Here’s another one. Note the blank line between rows.],+    columns: (15%, 13.75%, 16.25%, 35%),+    align: (center,left,right,left,),+    table.header([Centered Header], [Left Aligned], [Right Aligned], [Default+      aligned],),+    table.hline(),+    [First], [row], [12.0], [Example of a row that spans multiple lines.],+    [Second], [row], [5.0], [Here’s another one. Note the blank line between+    rows.],   )]   , kind: table   )@@ -113,19 +83,10 @@ #figure(   align(center)[#table(     columns: 4,-    align: (col, row) => (right,left,center,right,).at(col),-    [12],-    [12],-    [12],-    [12],-    [123],-    [123],-    [123],-    [123],-    [1],-    [1],-    [1],-    [1],+    align: (right,left,center,right,),+    [12], [12], [12], [12],+    [123], [123], [123], [123],+    [1], [1], [1], [1],   )]   , kind: table   )@@ -134,16 +95,11 @@  #figure(   align(center)[#table(-    columns: 4,-    align: (col, row) => (center,left,right,auto,).at(col),-    [First],-    [row],-    [12.0],-    [Example of a row that spans multiple lines.],-    [Second],-    [row],-    [5.0],-    [Here’s another one. Note the blank line between rows.],+    columns: (15%, 13.75%, 16.25%, 35%),+    align: (center,left,right,auto,),+    [First], [row], [12.0], [Example of a row that spans multiple lines.],+    [Second], [row], [5.0], [Here’s another one. Note the blank line between+    rows.],   )]   , kind: table   )
+ test/tables/nordics.typst view
@@ -0,0 +1,23 @@+#figure(+  align(center)[#table(+    columns: (30%, 30%, 20%, 20%),+    align: (center,left,left,left,),+    table.header(table.cell(align: center)[Name], table.cell(align: center)[Capital], table.cell(align: center)[Population+      \+      (in 2018)], table.cell(align: center)[Area \+      (in km#super[2];)],),+    table.hline(),+    [Denmark], [Copenhagen], [5,809,502], [43,094],+    [Finland], [Helsinki], [5,537,364], [338,145],+    [Iceland], [Reykjavik], [343,518], [103,000],+    [Norway], [Oslo], [5,372,191], [323,802],+    [Sweden], [Stockholm], [10,313,447], [450,295],+    table.hline(),+    table.footer([Total], [], [27,376,022], [1,258,336],),+  )]+  , caption: [States belonging to the #emph[Nordics.]++  ]+  , kind: table+  )+<nordics>
+ test/tables/planets.typst view
@@ -0,0 +1,33 @@+#figure(+  align(center)[#table(+    columns: 12,+    align: (center,center,auto,right,right,right,right,right,right,right,right,auto,),+    table.header(table.cell(colspan: 2)[], [Name], [Mass (10^24kg)], [Diameter+      (km)], [Density (kg/m^3)], [Gravity (m/s^2)], [Length of day+      (hours)], [Distance from Sun (10^6km)], [Mean temperature (C)], [Number of+      moons], [Notes],),+    table.hline(),+    table.cell(rowspan: 4, colspan: 2)[Terrestrial+    planets], [Mercury], [0.330], [4,879], [5427], [3.7], [4222.6], [57.9], [167], [0], [Closest+    to the Sun],+    [Venus], [4.87], [12,104], [5243], [8.9], [2802.0], [108.2], [464], [0], [],+    [Earth], [5.97], [12,756], [5514], [9.8], [24.0], [149.6], [15], [1], [Our+    world],+    [Mars], [0.642], [6,792], [3933], [3.7], [24.7], [227.9], [-65], [2], [The+    red planet],+    table.cell(rowspan: 4)[Jovian planets], table.cell(rowspan: 2)[Gas+    giants], [Jupiter], [1898], [142,984], [1326], [23.1], [9.9], [778.6], [-110], [67], [The+    largest planet],+    [Saturn], [568], [120,536], [687], [9.0], [10.7], [1433.5], [-140], [62], [],+    table.cell(rowspan: 2)[Ice+    giants], [Uranus], [86.8], [51,118], [1271], [8.7], [17.2], [2872.5], [-195], [27], [],+    [Neptune], [102], [49,528], [1638], [11.0], [16.1], [4495.1], [-200], [14], [],+    table.cell(colspan: 2)[Dwarf+    planets], [Pluto], [0.0146], [2,370], [2095], [0.7], [153.3], [5906.4], [-225], [5], [Declassified+    as a planet in 2006.],+  )]+  , caption: [Data about the planets of our solar system.++  ]+  , kind: table+  )
+ test/tables/students.typst view
@@ -0,0 +1,26 @@+#figure(+  align(center)[#table(+    columns: (50%, 50%),+    align: (left,left,),+    table.header(table.cell(align: center)[Student+      ID], table.cell(align: center)[Name],),+    table.hline(),+    table.cell(colspan: 2)[Computer Science],+    table.hline(),+    [3741255], [Jones, Martha],+    [4077830], [Pierce, Benjamin],+    [5151701], [Kirk, James],+    table.cell(colspan: 2)[Russian Literature],+    table.hline(),+    [3971244], [Nim, Victor],+    table.cell(colspan: 2)[Astrophysics],+    table.hline(),+    [4100332], [Petrov, Alexandra],+    [4100332], [Toyota, Hiroko],+  )]+  , caption: [List of Students++  ]+  , kind: table+  )+<students>
test/writer.typst view
@@ -16,7 +16,8 @@ }  #set table(-  inset: 6pt+  inset: 6pt,+  stroke: none )  #let conf(