From aa571d2c4186a88b35d60263d292383e20237575 Mon Sep 17 00:00:00 2001 From: John MacFarlane Date: Sat, 18 Apr 2026 13:03:32 +0200 Subject: [PATCH] Add `--typst-input` CLI option. This allows one to pass parameters to typst, which are available at `sys.inputs`, just as `typst` itself does with its `--input` option. [API changes] * ReaderOptions has a new field `readerTypstInputs`. * Opt has a new field `optTypstInputs`. Closes #11588. --- MANUAL.txt | 9 ++++++++- cabal.project | 2 +- src/Text/Pandoc/App.hs | 1 + src/Text/Pandoc/App/CommandLineOptions.hs | 16 ++++++++++++---- src/Text/Pandoc/App/Opt.hs | 3 +++ src/Text/Pandoc/Options.hs | 2 ++ src/Text/Pandoc/Readers/Typst.hs | 4 ++-- stack.yaml | 3 ++- test/command/11588.md | 10 ++++++++++ 9 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 test/command/11588.md diff --git a/MANUAL.txt b/MANUAL.txt index 79f61e534..e45a9f6bf 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -765,6 +765,13 @@ header when requesting a document from a URL: space, and the period will not produce sentence-ending space in formats like LaTeX. The strings may not contain spaces. +`--typst-input=`*KEY*[`=`*VAL*] + +: Set a parameter value that will be made available to the typst + parser in `sys.inputs`, like `--input` in the `typst` CLI. + Either `:` or `=` may be used to separate *KEY* from *VAL*. + Values containing spaces must be quoted. + `--trace[=true|false]` : Print diagnostic output tracing parser progress to stderr. @@ -816,7 +823,7 @@ header when requesting a document from a URL: `-V keyword=Joe -V author=Sue` makes `author` contain a list of strings: `Joe` and `Sue`. -`--variable-json=`*KEY*[`=`:*JSON*] +`--variable-json=`*KEY*[`=`*JSON*] : Set the template variable *KEY* to the value specified by a JSON string (this may be a boolean, a string, a list, or a mapping; diff --git a/cabal.project b/cabal.project index 74efb306d..5d852b665 100644 --- a/cabal.project +++ b/cabal.project @@ -15,7 +15,7 @@ source-repository-package source-repository-package type: git location: https://github.com/jgm/typst-hs.git - tag: 97e075131fc794f7370648eb231fdfdc712b5dbd + tag: bd0f68d0d03063bbd902b271f89fbc156b1da2dd package pandoc flags: +embed_data_files +http diff --git a/src/Text/Pandoc/App.hs b/src/Text/Pandoc/App.hs index 4241c71c5..a3cab3d9f 100644 --- a/src/Text/Pandoc/App.hs +++ b/src/Text/Pandoc/App.hs @@ -238,6 +238,7 @@ convertWithOpts' scriptingEngine istty datadir opts = do , readerAbbreviations = abbrevs , readerExtensions = readerExts , readerStripComments = optStripComments opts + , readerTypstInputs = optTypstInputs opts } metadataFromFile <- getMetadataFromFiles readerNameBase readerOpts diff --git a/src/Text/Pandoc/App/CommandLineOptions.hs b/src/Text/Pandoc/App/CommandLineOptions.hs index e16c4e6f1..bf2390ddd 100644 --- a/src/Text/Pandoc/App/CommandLineOptions.hs +++ b/src/Text/Pandoc/App/CommandLineOptions.hs @@ -303,7 +303,7 @@ options = let (key, val) = splitField arg return opt{ optMetadata = addMeta key val $ optMetadata opt }) - "KEY[:VALUE]") + "KEY[=VALUE]") "" , Option "" ["metadata-file"] @@ -345,7 +345,7 @@ options = "true|false") "" - , Option "s" ["standalone"] + , Option "s" ["standalone"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--standalone/-s" arg @@ -367,7 +367,7 @@ options = return opt{ optVariables = setVariable (T.pack key) (T.pack val) $ optVariables opt }) - "KEY[:VALUE]") + "KEY[=VALUE]") "" , Option "" ["variable-json"] @@ -663,7 +663,7 @@ options = let (key, val) = splitField arg return opt{ optRequestHeaders = (T.pack key, T.pack val) : optRequestHeaders opt }) - "NAME:VALUE") + "NAME=VALUE") "" , Option "" ["no-check-certificate"] @@ -681,6 +681,14 @@ options = "FILE") "" -- "Specify file for custom abbreviations" + , Option "" ["typst-input"] + (ReqArg + (\arg opt -> do + let (key, val) = splitField arg + return opt{ optTypstInputs = (T.pack key, T.pack val) : optTypstInputs opt }) + "KEY=VALUE") + "" + , Option "" ["indented-code-classes"] (ReqArg (\arg opt -> return opt { optIndentedCodeClasses = T.words $ diff --git a/src/Text/Pandoc/App/Opt.hs b/src/Text/Pandoc/App/Opt.hs index ac9359147..f95ba2a44 100644 --- a/src/Text/Pandoc/App/Opt.hs +++ b/src/Text/Pandoc/App/Opt.hs @@ -184,6 +184,7 @@ data Opt = Opt , optBibliography :: [FilePath] -- ^ Bibliography files , optCitationAbbreviations :: Maybe FilePath -- ^ Citation abbreviations , optSandbox :: Bool + , optTypstInputs :: [(Text, Text)] -- ^ List of parameter values for typst } deriving (Generic, Show) instance FromJSON Opt where @@ -271,6 +272,7 @@ instance FromJSON Opt where <*> o .:? "bibliography" .!= optBibliography defaultOpts <*> o .:? "citation-abbreviations" <*> o .:? "sandbox" .!= optSandbox defaultOpts + <*> o .:? "typst-inputs" .!= optTypstInputs defaultOpts instance ToJSON Opt where toJSON = genericToJSON defaultOptions{ @@ -848,6 +850,7 @@ defaultOpts = Opt , optBibliography = [] , optCitationAbbreviations = Nothing , optSandbox = False + , optTypstInputs = [] } yamlToMeta :: Value -> Parser Meta diff --git a/src/Text/Pandoc/Options.hs b/src/Text/Pandoc/Options.hs index 1079a3748..3705b9c41 100644 --- a/src/Text/Pandoc/Options.hs +++ b/src/Text/Pandoc/Options.hs @@ -74,6 +74,7 @@ data ReaderOptions = ReaderOptions{ , readerTrackChanges :: TrackChanges -- ^ Track changes setting for docx , readerStripComments :: Bool -- ^ Strip HTML comments instead of parsing as raw HTML -- (only implemented in commonmark) + , readerTypstInputs :: [(Text, Text)] -- ^ parameters specified using --typst-input } deriving (Show, Read, Data, Typeable, Generic) instance HasSyntaxExtensions ReaderOptions where @@ -90,6 +91,7 @@ instance Default ReaderOptions , readerDefaultImageExtension = "" , readerTrackChanges = AcceptChanges , readerStripComments = False + , readerTypstInputs = [] } defaultAbbrevs :: Set.Set Text diff --git a/src/Text/Pandoc/Readers/Typst.hs b/src/Text/Pandoc/Readers/Typst.hs index 93cde4f8d..0f2231cbb 100644 --- a/src/Text/Pandoc/Readers/Typst.hs +++ b/src/Text/Pandoc/Readers/Typst.hs @@ -60,7 +60,7 @@ import qualified System.FilePath.Posix as Posix -- | Read Typst from an input string and return a Pandoc document. readTypst :: (PandocMonad m, ToSources a) => ReaderOptions -> a -> m Pandoc -readTypst _opts inp = do +readTypst opts inp = do let sources = toSources inp let inputName = case sources of Sources ((pos, _):_) -> sourceName pos @@ -73,7 +73,7 @@ readTypst _opts inp = do currentUTCTime = getCurrentTime, lookupEnvVar = fmap (fmap T.unpack) . lookupEnv . T.pack, checkExistence = fileExists } - res <- evaluateTypst ops inputName parsed + res <- evaluateTypst ops (readerTypstInputs opts) inputName parsed case res of Left e -> throwError $ PandocParseError $ tshow e Right content -> do diff --git a/stack.yaml b/stack.yaml index 112e2c509..98ca34154 100644 --- a/stack.yaml +++ b/stack.yaml @@ -27,7 +27,8 @@ extra-deps: - djot-0.1.4 - asciidoc-0.1.0.2 - texmath-0.13.1.1 -- typst-0.9.0.1 +- git: https://github.com/jgm/typst-hs.git + commit: bd0f68d0d03063bbd902b271f89fbc156b1da2dd ghc-options: "$locals": -fhide-source-paths -Wno-missing-home-modules diff --git a/test/command/11588.md b/test/command/11588.md new file mode 100644 index 000000000..86f0cf292 --- /dev/null +++ b/test/command/11588.md @@ -0,0 +1,10 @@ +``` +% pandoc --typst-input foo=FOO --typst-input bar="bar bim" -f typst -t plain +#sys.inputs.at("foo"); + +#sys.inputs.at("bar"); +^D +FOO + +bar bim +```