From 0ce83fb1335342f166e966fa5002e05a70e0bdcb Mon Sep 17 00:00:00 2001 From: wzy <32936898+Freed-Wu@users.noreply.github.com> Date: Fri, 21 Aug 2026 04:38:53 +0800 Subject: [PATCH] Add `--completion={bash,zsh,fish}` (#11818) Make `--bash-completion` an alias of `--completion=bash`. Reorganize option parsing code using a new data structure OptionSpec, which can encode the type of completion needed by each option. Add new unexported module Text.Pandoc.Completion. Unexported module Text.Pandoc.CommandLineOptions: export OptionSpec. Closes #8542. --- MANUAL.txt | 17 +- data/bash_completion.tpl | 90 ---- pandoc.cabal | 3 +- src/Text/Pandoc/App/CommandLineOptions.hs | 594 +++++++++++++--------- src/Text/Pandoc/App/Completion.hs | 296 +++++++++++ src/Text/Pandoc/App/Opt.hs | 58 ++- test/command/completion.md | 373 ++++++++++++++ 7 files changed, 1096 insertions(+), 335 deletions(-) delete mode 100644 data/bash_completion.tpl create mode 100644 src/Text/Pandoc/App/Completion.hs create mode 100644 test/command/completion.md diff --git a/MANUAL.txt b/MANUAL.txt index 89a73dca3..39acac4d3 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -431,12 +431,21 @@ header when requesting a document from a URL: overridden or extended by subsequent options on the command line. +`--completion=`*SHELL* + +: Generate a shell completion script for the given shell, one of + `bash`, `zsh`, or `fish`. To enable completion with pandoc, + evaluate the output of this command in your shell's startup + file. For example, for bash add this to your `.bashrc`: + + eval "$(pandoc --completion=bash)" + + The generated scripts are produced from pandoc's list of options + and do not require pandoc to be invoked while completing. + `--bash-completion` -: Generate a bash completion script. To enable bash completion - with pandoc, add this to your `.bashrc`: - - eval "$(pandoc --bash-completion)" +: *Deprecated. Use `--completion=bash` instead.* `--sandbox[=true|false]` diff --git a/data/bash_completion.tpl b/data/bash_completion.tpl deleted file mode 100644 index dca0fcb89..000000000 --- a/data/bash_completion.tpl +++ /dev/null @@ -1,90 +0,0 @@ -# This script enables bash autocompletion for pandoc. To enable -# bash completion, add this to your .bashrc: -# eval "$(pandoc --bash-completion)" - -_pandoc() -{ - local cur prev opts lastc informats outformats highlight_styles datafiles - COMPREPLY=() - cur="${COMP_WORDS[COMP_CWORD]}" - prev="${COMP_WORDS[COMP_CWORD-1]}" - - # These should be filled in by pandoc: - opts="%s" - informats="%s" - outformats="%s" - highlight_styles="%s" - datafiles="%s" - - case "${prev}" in - --from|-f|--read|-r) - COMPREPLY=( $(compgen -W "${informats}" -- ${cur}) ) - return 0 - ;; - --to|-t|--write|-w|-D|--print-default-template) - COMPREPLY=( $(compgen -W "${outformats}" -- ${cur}) ) - return 0 - ;; - --email-obfuscation) - COMPREPLY=( $(compgen -W "references javascript none" -- ${cur}) ) - return 0 - ;; - --ipynb-output) - COMPREPLY=( $(compgen -W "all none best" -- ${cur}) ) - return 0 - ;; - --pdf-engine) - COMPREPLY=( $(compgen -W "pdflatex lualatex xelatex latexmk tectonic wkhtmltopdf weasyprint prince context pdfroff groff" -- ${cur}) ) - return 0 - ;; - --print-default-data-file) - COMPREPLY=( $(compgen -W "${datafiles}" -- ${cur}) ) - return 0 - ;; - --wrap) - COMPREPLY=( $(compgen -W "auto none preserve" -- ${cur}) ) - return 0 - ;; - --track-changes) - COMPREPLY=( $(compgen -W "accept reject all" -- ${cur}) ) - return 0 - ;; - --reference-location) - COMPREPLY=( $(compgen -W "block section document" -- ${cur}) ) - return 0 - ;; - --top-level-division) - COMPREPLY=( $(compgen -W "section chapter part" -- ${cur}) ) - return 0 - ;; - --highlight-style|--print-highlight-style) - COMPREPLY=( $(compgen -W "${highlight_styles}" -- ${cur}) ) - return 0 - ;; - --eol) - COMPREPLY=( $(compgen -W "crlf lf native" -- ${cur}) ) - return 0 - ;; - --markdown-headings) - COMPREPLY=( $(compgen -W "setext atx" -- ${cur}) ) - return 0 - ;; - *) - ;; - esac - - case "${cur}" in - -*) - COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) - return 0 - ;; - *) - local IFS=$'\n' - COMPREPLY=( $(compgen -X '' -f "${cur}") ) - return 0 - ;; - esac - -} - -complete -o filenames -o bashdefault -F _pandoc pandoc diff --git a/pandoc.cabal b/pandoc.cabal index 95d5be174..26df4b819 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -201,8 +201,6 @@ data-files: data/creole.lua -- lua init script data/init.lua - -- bash completion template - data/bash_completion.tpl -- citeproc data/default.csl citeproc/biblatex-localization/*.lbx.strings @@ -719,6 +717,7 @@ library Text.Pandoc.Transforms, Text.Pandoc.Version other-modules: Text.Pandoc.App.CommandLineOptions, + Text.Pandoc.App.Completion, Text.Pandoc.App.Input, Text.Pandoc.App.Opt, Text.Pandoc.App.OutputSettings, diff --git a/src/Text/Pandoc/App/CommandLineOptions.hs b/src/Text/Pandoc/App/CommandLineOptions.hs index 77b8e0f92..0dc90f759 100644 --- a/src/Text/Pandoc/App/CommandLineOptions.hs +++ b/src/Text/Pandoc/App/CommandLineOptions.hs @@ -19,6 +19,7 @@ module Text.Pandoc.App.CommandLineOptions ( , parseOptionsFromArgs , handleOptInfo , options + , OptionSpec(..) , engines , setVariable , versionInfo @@ -49,14 +50,16 @@ import Text.DocTemplates (Context (..), ToContext (toVal), Val (..)) import Text.Pandoc import Text.Pandoc.Builder (setMeta) import Data.Version (showVersion) +import Text.Pandoc.App.Completion (generateCompletion) import Text.Pandoc.App.Opt (Opt (..), LineEnding (..), IpynbOutput (..), DefaultsState (..), applyDefaults, - fullDefaultsPath, OptInfo(..)) + fullDefaultsPath, OptInfo(..), CompletionShell(..), + OptionSpec(..), option, toOptDescr, + CompletionKind(..)) import Text.Pandoc.Filter (Filter (..)) import Text.Pandoc.Highlighting (highlightingStyles, lookupHighlightingStyle) import Text.Pandoc.Scripting (ScriptingEngine (..), customTemplate) import Text.Pandoc.Shared (safeStrRead) -import Text.Printf import qualified Control.Exception as E import Control.Monad.Except (ExceptT(..), runExceptT, throwError) import qualified Data.ByteString as BS @@ -66,7 +69,7 @@ import qualified Data.Set as Set import qualified Data.Text as T import qualified Text.Pandoc.UTF8 as UTF8 -parseOptions :: [OptDescr (Opt -> ExceptT OptInfo IO Opt)] +parseOptions :: [OptionSpec] -> Opt -> IO (Either OptInfo Opt) parseOptions options' defaults = do rawArgs <- liftIO getArgs @@ -74,11 +77,11 @@ parseOptions options' defaults = do parseOptionsFromArgs options' defaults prg rawArgs parseOptionsFromArgs - :: [OptDescr (Opt -> ExceptT OptInfo IO Opt)] + :: [OptionSpec] -> Opt -> String -> [String] -> IO (Either OptInfo Opt) parseOptionsFromArgs options' defaults prg rawArgs = do let (actions, args, unrecognizedOpts, errors) = - getOpt' Permute options' (preprocessArgs rawArgs) + getOpt' Permute (map toOptDescr options') (preprocessArgs rawArgs) let unknownOptionErrors = foldr (handleUnrecognizedOption . takeWhile (/= '=')) [] @@ -111,20 +114,12 @@ parseOptionsFromArgs options' defaults prg rawArgs = do handleOptInfo :: ScriptingEngine -> OptInfo -> IO () handleOptInfo engine info = E.handle (handleError . Left) $ do case info of - BashCompletion -> do + Completion shell -> do datafiles <- getDataFileNames - tpl <- runIOorExplode $ - UTF8.toString <$> - readDefaultDataFile "bash_completion.tpl" - let optnames (Option shorts longs _ _) = - map (\c -> ['-',c]) shorts ++ - map ("--" ++) longs - let allopts = unwords (concatMap optnames options) - UTF8.hPutStrLn stdout $ T.pack $ printf tpl allopts - (T.unpack $ T.unwords readersNames) - (T.unpack $ T.unwords writersNames) - (T.unpack $ T.unwords $ map fst highlightingStyles) - (unwords datafiles) + script <- generateCompletion shell options + readersNames writersNames + (map fst highlightingStyles) pdfEngines datafiles + UTF8.hPutStrLn stdout script ListInputFormats -> mapM_ (UTF8.hPutStrLn stdout) readersNames ListOutputFormats -> mapM_ (UTF8.hPutStrLn stdout) writersNames ListExtensions mbfmt -> do @@ -200,7 +195,7 @@ handleOptInfo engine info = E.handle (handleError . Left) $ do Help -> do prg <- getProgName mapM_ (UTF8.hPutStrLn stdout . T.stripEnd . T.pack) $ - lines $ usageMessage prg options + lines $ usageMessage prg (map toOptDescr options) OptError e -> E.throwIO e exitSuccess @@ -253,12 +248,12 @@ isShortBooleanOpt :: Char -> Bool isShortBooleanOpt = (`Set.member` shortBooleanOpts) where shortBooleanOpts = - Set.fromList [c | Option [c] _ (OptArg _ "true|false") _ <- options] + Set.fromList [c | OptionSpec [c] _ (OptArg _ "true|false") _ _ <- options] isShortOpt :: Char -> Bool isShortOpt = (`Set.member` shortOpts) where - shortOpts = Set.fromList $ concat [cs | Option cs _ _ _ <- options] + shortOpts = Set.fromList $ concat [cs | OptionSpec cs _ _ _ _ <- options] splitArg :: String -> [String] splitArg (c:d:cs) @@ -270,51 +265,57 @@ splitArg [] = [] -- | A list of functions, each transforming the options data structure -- in response to a command-line option. -options :: [OptDescr (Opt -> ExceptT OptInfo IO Opt)] +options :: [OptionSpec] options = - [ Option "fr" ["from","read"] + [ option "fr" ["from","read"] (ReqArg (\arg opt -> return opt { optFrom = Just $ T.pack arg }) "FORMAT") - "" + InputFormats + (T.pack "Reader format") - , Option "tw" ["to","write"] + , option "tw" ["to","write"] (ReqArg (\arg opt -> return opt { optTo = Just $ T.pack arg }) "FORMAT") - "" + OutputFormats + (T.pack "Writer format") - , Option "o" ["output"] + , option "o" ["output"] (ReqArg (\arg opt -> return opt { optOutputFile = Just (normalizePath arg) }) "FILE") - "" -- "Name of output file" + Files + (T.pack "Output file") - , Option "" ["data-dir"] + , option "" ["data-dir"] (ReqArg (\arg opt -> return opt { optDataDir = Just (normalizePath arg) }) "DIRECTORY") -- "Directory containing pandoc data files." - "" + Files + (T.pack "Directory for data files") - , Option "M" ["metadata"] + , option "M" ["metadata"] (ReqArg (\arg opt -> do let (key, val) = splitField arg return opt{ optMetadata = addMeta key val $ optMetadata opt }) "KEY[=VALUE]") - "" + Files + (T.pack "Metadata field KEY=VALUE") - , Option "" ["metadata-file"] + , option "" ["metadata-file"] (ReqArg (\arg opt -> return opt{ optMetadataFiles = optMetadataFiles opt ++ [normalizePath arg] }) "FILE") - "" + Files + (T.pack "Metadata file") - , Option "d" ["defaults"] + , option "d" ["defaults"] (ReqArg (\arg opt -> do res <- liftIO $ runIO $ do @@ -328,40 +329,45 @@ options = Right x -> return x ) "FILE") - "" + Files + (T.pack "Defaults file") - , Option "" ["file-scope"] + , option "" ["file-scope"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--file-scope" arg return opt { optFileScope = boolValue }) "true|false") - "" -- "Parse input files before combining" + OptFlag + (T.pack "Parse files before combining") - , Option "" ["sandbox"] + , option "" ["sandbox"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--sandbox" arg return opt { optSandbox = boolValue }) "true|false") - "" + OptFlag + (T.pack "Run pandoc in a sandbox") - , Option "s" ["standalone"] + , option "s" ["standalone"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--standalone/-s" arg return opt { optStandalone = boolValue }) "true|false") - "" -- "Include needed header and footer on output" + OptFlag + (T.pack "Include header and footer") - , Option "" ["template"] + , option "" ["template"] (ReqArg (\arg opt -> return opt{ optTemplate = Just (normalizePath arg) }) "FILE") - "" -- "Use custom template" + Files + (T.pack "Custom template file") - , Option "V" ["variable"] + , option "V" ["variable"] (ReqArg (\arg opt -> do let (key, val) = splitField arg @@ -369,9 +375,10 @@ options = setVariable (T.pack key) (T.pack val) $ optVariables opt }) "KEY[=VALUE]") - "" + Files + (T.pack "Template variable KEY=VALUE") - , Option "" ["variable-json"] + , option "" ["variable-json"] (ReqArg (\arg opt -> do let (key, json) = splitField arg @@ -386,9 +393,10 @@ options = "Could not parse '" <> T.pack json <> "' as JSON:\n" <> T.pack err') "KEY[:JSON]") - "" + Files + (T.pack "Template variable KEY=JSON") - , Option "" ["wrap"] + , option "" ["wrap"] (ReqArg (\arg opt -> case arg of @@ -398,25 +406,28 @@ options = _ -> optError $ PandocOptionError "--wrap must be auto, none, or preserve") "auto|none|preserve") - "" -- "Option for wrapping text in output" + (Fixed ["auto","none","preserve"]) + (T.pack "Text wrapping mode") - , Option "" ["ascii"] + , option "" ["ascii"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--ascii" arg return opt { optAscii = boolValue }) "true|false") - "" -- "Prefer ASCII output" + OptFlag + (T.pack "Prefer ASCII output") - , Option "" ["toc", "table-of-contents"] + , option "" ["toc", "table-of-contents"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--toc/--table-of-contents" arg return opt { optTableOfContents = boolValue }) "true|false") - "" -- "Include table of contents" + OptFlag + (T.pack "Include table of contents") - , Option "" ["toc-depth"] + , option "" ["toc-depth"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -425,33 +436,37 @@ options = _ -> optError $ PandocOptionError "Argument of --toc-depth must be a number 1-6") "NUMBER") - "" -- "Number of levels to include in TOC" + Files + (T.pack "Number of TOC levels") - , Option "" ["lof", "list-of-figures"] + , option "" ["lof", "list-of-figures"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--lof/--list-of-figures" arg return opt { optListOfFigures = boolValue }) "true|false") - "" -- "Include list of figures" + OptFlag + (T.pack "Include list of figures") - , Option "" ["lot", "list-of-tables"] + , option "" ["lot", "list-of-tables"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--lot/--list-of-tables" arg return opt { optListOfTables = boolValue }) "true|false") - "" -- "Include list of tables" + OptFlag + (T.pack "Include list of tables") - , Option "N" ["number-sections"] + , option "N" ["number-sections"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--number-sections/-N" arg return opt { optNumberSections = boolValue }) "true|false") - "" -- "Number sections" + OptFlag + (T.pack "Number section headings") - , Option "" ["number-offset"] + , option "" ["number-offset"] (ReqArg (\arg opt -> case safeStrRead ("[" <> arg <> "]") of @@ -460,9 +475,10 @@ options = _ -> optError $ PandocOptionError "could not parse argument of --number-offset") "NUMBERS") - "" -- "Starting number for sections, subsections, etc." + Files + (T.pack "Starting number for sections") - , Option "" ["top-level-division"] + , option "" ["top-level-division"] (ReqArg (\arg opt -> case arg of @@ -478,57 +494,64 @@ options = "Argument of --top-level division must be " <> "section, chapter, part, or default" ) "section|chapter|part") - "" -- "Use top-level division type in LaTeX, ConTeXt, DocBook" + (Fixed ["section","chapter","part"]) + (T.pack "Top-level document division") - , Option "" ["extract-media"] + , option "" ["extract-media"] (ReqArg (\arg opt -> return opt { optExtractMedia = Just (normalizePath arg) }) "PATH") - "" -- "Directory to which to extract embedded media" + Files + (T.pack "Directory to extract media into") - , Option "" ["resource-path"] + , option "" ["resource-path"] (ReqArg (\arg opt -> return opt { optResourcePath = splitSearchPath arg ++ optResourcePath opt }) "SEARCHPATH") - "" -- "Paths to search for images and other resources" + Files + (T.pack "Search path for resources") - , Option "H" ["include-in-header"] + , option "H" ["include-in-header"] (ReqArg (\arg opt -> return opt{ optIncludeInHeader = optIncludeInHeader opt ++ [normalizePath arg] }) "FILE") - "" -- "File to include at end of header (implies -s)" + Files + (T.pack "File to include in the header") - , Option "B" ["include-before-body"] + , option "B" ["include-before-body"] (ReqArg (\arg opt -> return opt{ optIncludeBeforeBody = optIncludeBeforeBody opt ++ [normalizePath arg] }) "FILE") - "" -- "File to include before document body" + Files + (T.pack "File to include before the body") - , Option "A" ["include-after-body"] + , option "A" ["include-after-body"] (ReqArg (\arg opt -> return opt{ optIncludeAfterBody = optIncludeAfterBody opt ++ [normalizePath arg] }) "FILE") - "" -- "File to include after document body" + Files + (T.pack "File to include after the body") - , Option "" ["no-highlight"] + , option "" ["no-highlight"] (NoArg (\opt -> do deprecatedOption "--no-highlight" "Use --syntax-highlighting=none instead." return opt { optSyntaxHighlighting = NoHighlightingString })) - "" -- "Don't highlight source code" + OptFlag + (T.pack "Disable syntax highlighting") - , Option "" ["highlight-style"] + , option "" ["highlight-style"] (ReqArg (\arg opt -> do deprecatedOption "--highlight-style" @@ -536,25 +559,28 @@ options = return opt{ optSyntaxHighlighting = T.pack $ normalizePath arg }) "STYLE|FILE") - "" -- "Style for highlighted code" + HighlightStyles + (T.pack "Highlighting style") - , Option "" ["syntax-definition"] + , option "" ["syntax-definition"] (ReqArg (\arg opt -> return opt{ optSyntaxDefinitions = normalizePath arg : optSyntaxDefinitions opt }) "FILE") - "" -- "Syntax definition (xml) file" + Files + (T.pack "Syntax definition XML file") - , Option "" ["syntax-highlighting"] + , option "" ["syntax-highlighting"] (ReqArg (\arg opt -> return opt{ optSyntaxHighlighting = T.pack $ normalizePath arg }) "none|default|idiomatic||") - "" -- "syntax highlighting method for code" + (Fixed ["none","default","idiomatic"]) + (T.pack "Syntax highlighting method") - , Option "" ["dpi"] + , option "" ["dpi"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -562,9 +588,10 @@ options = _ -> optError $ PandocOptionError "Argument of --dpi must be a number greater than 0") "NUMBER") - "" -- "Dpi (default 96)" + Files + (T.pack "DPI for imported images") - , Option "" ["eol"] + , option "" ["eol"] (ReqArg (\arg opt -> case toLower <$> arg of @@ -575,9 +602,10 @@ options = _ -> optError $ PandocOptionError "Argument of --eol must be crlf, lf, or native") "crlf|lf|native") - "" -- "EOL (default OS-dependent)" + (Fixed ["crlf","lf","native"]) + (T.pack "End-of-line characters") - , Option "" ["columns"] + , option "" ["columns"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -585,17 +613,19 @@ options = _ -> optError $ PandocOptionError "Argument of --columns must be a number greater than 0") "NUMBER") - "" -- "Length of line in characters" + Files + (T.pack "Line length in characters") - , Option "p" ["preserve-tabs"] + , option "p" ["preserve-tabs"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--preserve-tabs/-p" arg return opt { optPreserveTabs = boolValue }) "true|false") - "" -- "Preserve tabs instead of converting to spaces" + OptFlag + (T.pack "Preserve tabs") - , Option "" ["tab-stop"] + , option "" ["tab-stop"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -603,9 +633,10 @@ options = _ -> optError $ PandocOptionError "Argument of --tab-stop must be a number greater than 0") "NUMBER") - "" -- "Tab stop (default 4)" + Files + (T.pack "Tab stop width") - , Option "" ["pdf-engine"] + , option "" ["pdf-engine"] (ReqArg (\arg opt -> do let b = takeBaseName arg @@ -616,109 +647,123 @@ options = "Argument of --pdf-engine must be one of\n" ++ concatMap (\e -> "\t" <> e <> "\n") pdfEngines) "PROGRAM") - "" -- "Name of program to use in generating PDF" + Engines + (T.pack "Program used to produce PDF") - , Option "" ["pdf-engine-opt"] + , option "" ["pdf-engine-opt"] (ReqArg (\arg opt -> do let oldArgs = optPdfEngineOpts opt return opt { optPdfEngineOpts = oldArgs ++ [arg]}) "STRING") - "" -- "Flags to pass to the PDF-engine, all instances of this option are accumulated and used" + Files + (T.pack "Flag to pass to the PDF engine") - , Option "" ["reference-doc"] + , option "" ["reference-doc"] (ReqArg (\arg opt -> return opt { optReferenceDoc = Just $ normalizePath arg }) "FILE") - "" -- "Path of custom reference doc" + Files + (T.pack "Custom reference doc") - , Option "" ["self-contained"] + , option "" ["self-contained"] (OptArg (\arg opt -> do deprecatedOption "--self-contained" "use --embed-resources --standalone" boolValue <- readBoolFromOptArg "--self-contained" arg return opt { optSelfContained = boolValue }) "true|false") - "" -- "Make slide shows include all the needed js and css (deprecated)" + OptFlag + (T.pack "Embed resources (deprecated)") - , Option "" ["embed-resources"] -- maybe True (\argStr -> argStr == "true") arg + , option "" ["embed-resources"] -- maybe True (\argStr -> argStr == "true") arg (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--embed-resources" arg return opt { optEmbedResources = boolValue }) "true|false") - "" -- "Make slide shows include all the needed js and css" + OptFlag + (T.pack "Embed referenced resources") - , Option "" ["link-images"] -- maybe True (\argStr -> argStr == "true") arg + , option "" ["link-images"] -- maybe True (\argStr -> argStr == "true") arg (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--link-images" arg return opt { optLinkImages = boolValue }) "true|false") - "" -- "Link images in ODT rather than embedding them" + OptFlag + (T.pack "Link images in ODT rather than embedding") - , Option "" ["request-header"] + , option "" ["request-header"] (ReqArg (\arg opt -> do let (key, val) = splitField arg return opt{ optRequestHeaders = (T.pack key, T.pack val) : optRequestHeaders opt }) "NAME=VALUE") - "" + Files + (T.pack "HTTP header NAME=VALUE") - , Option "" ["no-check-certificate"] + , option "" ["no-check-certificate"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--no-check-certificate" arg return opt { optNoCheckCertificate = boolValue }) "true|false") - "" -- "Disable certificate validation" + OptFlag + (T.pack "Disable certificate validation") - , Option "" ["abbreviations"] + , option "" ["abbreviations"] (ReqArg (\arg opt -> return opt { optAbbreviations = Just $ normalizePath arg }) "FILE") - "" -- "Specify file for custom abbreviations" + Files + (T.pack "File with abbreviations") - , Option "" ["typst-input"] + , 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") - "" + Files + (T.pack "Typst variable KEY=VALUE") - , Option "" ["indented-code-classes"] + , option "" ["indented-code-classes"] (ReqArg (\arg opt -> return opt { optIndentedCodeClasses = T.words $ T.map (\c -> if c == ',' then ' ' else c) $ T.pack arg }) "STRING") - "" -- "Classes (whitespace- or comma-separated) to use for indented code-blocks" + Files + (T.pack "Classes for indented code blocks") - , Option "" ["default-image-extension"] + , option "" ["default-image-extension"] (ReqArg (\arg opt -> return opt { optDefaultImageExtension = T.pack arg }) "extension") - "" -- "Default extension for extensionless images" + Files + (T.pack "Default extension for images") - , Option "F" ["filter"] + , option "F" ["filter"] (ReqArg (\arg opt -> return opt { optFilters = optFilters opt ++ [JSONFilter (normalizePath arg)] }) "PROGRAM") - "" -- "External JSON filter" + Files + (T.pack "External JSON filter") - , Option "L" ["lua-filter"] + , option "L" ["lua-filter"] (ReqArg (\arg opt -> return opt { optFilters = optFilters opt ++ [LuaFilter (normalizePath arg)] }) "SCRIPTPATH") - "" -- "Lua filter" + Files + (T.pack "Lua filter script") - , Option "" ["shift-heading-level-by"] + , option "" ["shift-heading-level-by"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -727,9 +772,10 @@ options = _ -> optError $ PandocOptionError "Argument of --shift-heading-level-by must be an integer") "NUMBER") - "" -- "Shift heading level" + Files + (T.pack "Shift heading level by N") - , Option "" ["base-header-level"] + , option "" ["base-header-level"] (ReqArg (\arg opt -> do deprecatedOption "--base-header-level" @@ -740,9 +786,10 @@ options = _ -> optError $ PandocOptionError "Argument of --base-header-level must be 1-5") "NUMBER") - "" -- "Headers base level" + Files + (T.pack "Base header level (deprecated)") - , Option "" ["track-changes"] + , option "" ["track-changes"] (ReqArg (\arg opt -> do action <- case arg of @@ -753,25 +800,28 @@ options = "Argument of --track-changes must be accept, reject, or all" return opt { optTrackChanges = action }) "accept|reject|all") - "" -- "Accepting or reject MS Word track-changes."" + (Fixed ["accept","reject","all"]) + (T.pack "Handling of Word track-changes") - , Option "" ["strip-comments"] + , option "" ["strip-comments"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--strip-comments" arg return opt { optStripComments = boolValue }) "true|false") - "" -- "Strip HTML comments" + OptFlag + (T.pack "Strip HTML comments") - , Option "" ["reference-links"] + , option "" ["reference-links"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--reference-links" arg return opt { optReferenceLinks = boolValue }) "true|false") - "" -- "Use reference links in parsing HTML" + OptFlag + (T.pack "Use reference links in HTML") - , Option "" ["reference-location"] + , option "" ["reference-location"] (ReqArg (\arg opt -> do action <- case arg of @@ -782,9 +832,10 @@ options = "Argument of --reference-location must be block, section, or document" return opt { optReferenceLocation = action }) "block|section|document") - "" -- "Specify where reference links and footnotes go" + (Fixed ["block","section","document"]) + (T.pack "Location of references") - , Option "" ["figure-caption-position"] + , option "" ["figure-caption-position"] (ReqArg (\arg opt -> do pos <- case arg of @@ -794,9 +845,10 @@ options = "Argument of --figure-caption-position must be above or below" return opt { optFigureCaptionPosition = pos }) "above|below") - "" -- "Specify where figure captions go" + (Fixed ["above","below"]) + (T.pack "Figure caption position") - , Option "" ["table-caption-position"] + , option "" ["table-caption-position"] (ReqArg (\arg opt -> do pos <- case arg of @@ -806,9 +858,10 @@ options = "Argument of --table-caption-position must be above or below" return opt { optTableCaptionPosition = pos }) "above|below") - "" -- "Specify where table captions go" + (Fixed ["above","below"]) + (T.pack "Table caption position") - , Option "" ["markdown-headings"] + , option "" ["markdown-headings"] (ReqArg (\arg opt -> do headingFormat <- case arg of @@ -819,17 +872,19 @@ options = pure opt { optSetextHeaders = headingFormat } ) "setext|atx") - "" + (Fixed ["setext","atx"]) + (T.pack "Markdown heading style") - , Option "" ["list-tables"] + , option "" ["list-tables"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--list-tables" arg return opt { optListTables = boolValue }) "true|false") - "" -- "Use list tables for RST" + OptFlag + (T.pack "Use list tables for RST") - , Option "" ["listings"] + , option "" ["listings"] (OptArg (\arg opt -> do deprecatedOption "--listings" @@ -841,17 +896,19 @@ options = IdiomaticHighlightingString } else opt) "true|false") - "" -- "Use listings package for LaTeX code blocks" + OptFlag + (T.pack "Use listings package (deprecated)") - , Option "i" ["incremental"] + , option "i" ["incremental"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--incremental/-i" arg return opt { optIncremental = boolValue }) "true|false") - "" -- "Make list items display incrementally in Slidy/Slideous/S5" + OptFlag + (T.pack "Make list items display incrementally") - , Option "" ["slide-level"] + , option "" ["slide-level"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -860,25 +917,28 @@ options = _ -> optError $ PandocOptionError "Argument of --slide-level must be a number between 0 and 6") "NUMBER") - "" -- "Force header level for slides" + Files + (T.pack "Header level used for slides") - , Option "" ["section-divs"] + , option "" ["section-divs"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--section-divs" arg return opt { optSectionDivs = boolValue }) "true|false") - "" -- "Put sections in div tags in HTML" + OptFlag + (T.pack "Wrap sections in div tags") - , Option "" ["html-q-tags"] + , option "" ["html-q-tags"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--html-q-tags" arg return opt { optHtmlQTags = boolValue }) "true|false") - "" -- "Use tags for quotes in HTML" + OptFlag + (T.pack "Use q tags for quotes in HTML") - , Option "" ["email-obfuscation"] + , option "" ["email-obfuscation"] (ReqArg (\arg opt -> do method <- case arg of @@ -889,15 +949,17 @@ options = "Argument of --email-obfuscation must be references, javascript, or none" return opt { optEmailObfuscation = method }) "none|javascript|references") - "" -- "Method for obfuscating email in HTML" + (Fixed ["references","javascript","none"]) + (T.pack "Email obfuscation method") - , Option "" ["id-prefix"] + , option "" ["id-prefix"] (ReqArg (\arg opt -> return opt { optIdentifierPrefix = T.pack arg }) "STRING") - "" -- "Prefix to add to automatically generated HTML identifiers" + Files + (T.pack "Prefix for auto identifiers") - , Option "T" ["title-prefix"] + , option "T" ["title-prefix"] (ReqArg (\arg opt -> return opt { @@ -906,23 +968,26 @@ options = optVariables opt, optStandalone = True }) "STRING") - "" -- "String to prefix to HTML window title" + Files + (T.pack "Window title prefix") - , Option "c" ["css"] + , option "c" ["css"] (ReqArg (\arg opt -> return opt{ optCss = optCss opt ++ [arg] }) -- add new link to end, so it is included in proper order "URL") - "" -- "Link to CSS style sheet" + Files + (T.pack "CSS style sheet") - , Option "" ["epub-subdirectory"] + , option "" ["epub-subdirectory"] (ReqArg (\arg opt -> return opt { optEpubSubdirectory = arg }) "DIRNAME") - "" -- "Name of subdirectory for epub content in OCF container" + Files + (T.pack "EPUB content subdirectory") - , Option "" ["epub-cover-image"] + , option "" ["epub-cover-image"] (ReqArg (\arg opt -> return opt { optVariables = @@ -930,32 +995,36 @@ options = (T.pack $ normalizePath arg) $ optVariables opt }) "FILE") - "" -- "Path of epub cover image" + Files + (T.pack "EPUB cover image") - , Option "" ["epub-title-page"] + , option "" ["epub-title-page"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--epub-title-page" arg return opt{ optEpubTitlePage = boolValue }) "true|false") - "" + Files + (T.pack "URL or file for EPUB title page") - , Option "" ["epub-metadata"] + , option "" ["epub-metadata"] (ReqArg (\arg opt -> return opt { optEpubMetadata = Just $ normalizePath arg }) "FILE") - "" -- "Path of epub metadata file" + Files + (T.pack "EPUB metadata file") - , Option "" ["epub-embed-font"] + , option "" ["epub-embed-font"] (ReqArg (\arg opt -> return opt{ optEpubFonts = normalizePath arg : optEpubFonts opt }) "FILE") - "" -- "Directory of fonts to embed" + Files + (T.pack "Font file to embed in EPUB") - , Option "" ["split-level"] + , option "" ["split-level"] (ReqArg (\arg opt -> case safeStrRead arg of @@ -964,16 +1033,18 @@ options = _ -> optError $ PandocOptionError "Argument of --split-level must be a number between 1 and 6") "NUMBER") - "" -- "Header level at which to split documents in chunked HTML or EPUB" + Files + (T.pack "Split level for chunked HTML or EPUB") - , Option "" ["chunk-template"] + , option "" ["chunk-template"] (ReqArg (\arg opt -> return opt{ optChunkTemplate = Just (T.pack arg) }) "PATHTEMPLATE") - "" -- "Template for file paths in chunkedhtml" + Files + (T.pack "Template for chunked HTML paths") - , Option "" ["epub-chapter-level"] + , option "" ["epub-chapter-level"] (ReqArg (\arg opt -> do deprecatedOption "--epub-chapter-level" @@ -984,9 +1055,10 @@ options = _ -> optError $ PandocOptionError "Argument of --epub-chapter-level must be a number between 1 and 6") "NUMBER") - "" -- "Header level at which to split documents in chunked HTML or EPUB" + Files + (T.pack "Split level (deprecated)") - , Option "" ["ipynb-output"] + , option "" ["ipynb-output"] (ReqArg (\arg opt -> case arg of @@ -996,188 +1068,227 @@ options = _ -> optError $ PandocOptionError "Argument of --ipynb-output must be all, none, or best") "all|none|best") - "" -- "Starting number for sections, subsections, etc." + (Fixed ["all","none","best"]) + (T.pack "Handling of ipynb output cells") - , Option "C" ["citeproc"] + , option "C" ["citeproc"] (NoArg (\opt -> return opt { optFilters = optFilters opt ++ [CiteprocFilter] })) - "" -- "Process citations" + OptFlag + (T.pack "Process citations") - , Option "" ["bibliography"] + , option "" ["bibliography"] (ReqArg (\arg opt -> return opt{ optBibliography = optBibliography opt ++ [normalizePath arg] }) "FILE") - "" + Files + (T.pack "Bibliography file") - , Option "" ["csl"] + , option "" ["csl"] (ReqArg (\arg opt -> do return opt{ optCSL = Just (normalizePath arg) }) "FILE") - "" + Files + (T.pack "CSL style file") - , Option "" ["citation-abbreviations"] + , option "" ["citation-abbreviations"] (ReqArg (\arg opt -> return opt{ optMetadata = addMeta "citation-abbreviations" (normalizePath arg) $ optMetadata opt }) "FILE") - "" + Files + (T.pack "Citation abbreviations file") - , Option "" ["natbib"] + , option "" ["natbib"] (NoArg (\opt -> return opt { optCiteMethod = Natbib })) - "" -- "Use natbib cite commands in LaTeX output" + OptFlag + (T.pack "Use natbib citations in LaTeX") - , Option "" ["biblatex"] + , option "" ["biblatex"] (NoArg (\opt -> return opt { optCiteMethod = Biblatex })) - "" -- "Use biblatex cite commands in LaTeX output" + OptFlag + (T.pack "Use biblatex citations in LaTeX") - , Option "" ["mathml"] + , option "" ["mathml"] (NoArg (\opt -> return opt { optHTMLMathMethod = MathML })) - "" -- "Use mathml for HTML math" + OptFlag + (T.pack "Use MathML for HTML math") - , Option "" ["webtex"] + , option "" ["webtex"] (OptArg (\arg opt -> do let url' = maybe defaultWebTeXURL T.pack arg return opt { optHTMLMathMethod = WebTeX url' }) "URL") - "" -- "Use web service for HTML math" + OptFlag + (T.pack "Use WebTeX for HTML math") - , Option "" ["mathjax"] + , option "" ["mathjax"] (OptArg (\arg opt -> do let url' = maybe defaultMathJaxURL T.pack arg return opt { optHTMLMathMethod = MathJax url'}) "URL") - "" -- "Use MathJax for HTML math" + OptFlag + (T.pack "Use MathJax for HTML math") - , Option "" ["katex"] + , option "" ["katex"] (OptArg (\arg opt -> return opt { optHTMLMathMethod = KaTeX $ maybe defaultKaTeXURL T.pack arg }) "URL") - "" -- Use KaTeX for HTML Math + OptFlag + (T.pack "Use KaTeX for HTML math") - , Option "" ["gladtex"] + , option "" ["gladtex"] (NoArg (\opt -> return opt { optHTMLMathMethod = GladTeX })) - "" -- "Use gladtex for HTML math" + OptFlag + (T.pack "Use gladTeX for HTML math") - , Option "" ["trace"] + , option "" ["trace"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--trace" arg return opt { optTrace = boolValue }) "true|false") - "" -- "Turn on diagnostic tracing in readers." + OptFlag + (T.pack "Turn on diagnostic tracing") - , Option "" ["dump-args"] + , option "" ["dump-args"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--dump-args" arg return opt { optDumpArgs = boolValue }) "true|false") - "" -- "Print output filename and arguments to stdout." + OptFlag + (T.pack "Print output filename and arguments") - , Option "" ["ignore-args"] + , option "" ["ignore-args"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--ignore-args" arg return opt { optIgnoreArgs = boolValue }) "true|false") - "" -- "Ignore command-line arguments." + OptFlag + (T.pack "Ignore command-line arguments") - , Option "" ["verbose"] + , option "" ["verbose"] (NoArg (\opt -> return opt { optVerbosity = INFO })) - "" -- "Verbose diagnostic output." + OptFlag + (T.pack "Verbose diagnostic output") - , Option "" ["quiet"] + , option "" ["quiet"] (NoArg (\opt -> return opt { optVerbosity = ERROR })) - "" -- "Suppress warnings." + OptFlag + (T.pack "Suppress warning messages") - , Option "" ["fail-if-warnings"] + , option "" ["fail-if-warnings"] (OptArg (\arg opt -> do boolValue <- readBoolFromOptArg "--fail-if-warnings" arg return opt { optFailIfWarnings = boolValue }) "true|false") - "" -- "Exit with error status if there were warnings." + OptFlag + (T.pack "Exit with error status if there were warnings") - , Option "" ["log"] + , option "" ["log"] (ReqArg (\arg opt -> return opt{ optLogFile = Just $ normalizePath arg }) "FILE") - "" -- "Log messages in JSON format to this file." + Files + (T.pack "Log messages in JSON format to this file") - , Option "" ["bash-completion"] - (NoArg (\_ -> optInfo BashCompletion)) - "" -- "Print bash completion script" + , option "" ["completion"] + (ReqArg + (\arg _opt -> optInfo $ parseCompletionShell arg) + "SHELL") + OptFlag + (T.pack "Shell for which to print the completion script") - , Option "" ["list-input-formats"] + , option "" ["bash-completion"] + (NoArg (\_ -> do + deprecatedOption "--bash-completion" "use --completion=bash" + optInfo $ Completion Bash)) + OptFlag + (T.pack "Print bash completion script (deprecated)") + + , option "" ["list-input-formats"] (NoArg (\_ -> optInfo ListInputFormats)) - "" + OptFlag + (T.pack "List supported input formats") - , Option "" ["list-output-formats"] + , option "" ["list-output-formats"] (NoArg (\_ -> optInfo ListOutputFormats)) - "" + OptFlag + (T.pack "List supported output formats") - , Option "" ["list-extensions"] + , option "" ["list-extensions"] (OptArg (\arg _ -> optInfo $ ListExtensions $ T.pack <$> arg) "FORMAT") - "" + OptFlag + (T.pack "List supported extensions") - , Option "" ["list-highlight-languages"] + , option "" ["list-highlight-languages"] (NoArg (\_ -> optInfo ListHighlightLanguages)) - "" + OptFlag + (T.pack "List highlighting languages") - , Option "" ["list-highlight-styles"] + , option "" ["list-highlight-styles"] (NoArg (\_ -> optInfo ListHighlightStyles)) - "" + OptFlag + (T.pack "List highlighting styles") - , Option "D" ["print-default-template"] + , option "D" ["print-default-template"] (ReqArg (\arg opts -> optInfo $ PrintDefaultTemplate (optOutputFile opts) (T.pack arg)) "FORMAT") - "" -- "Print default template for FORMAT" + OutputFormats + (T.pack "Format to print template for") - , Option "" ["print-default-data-file"] + , option "" ["print-default-data-file"] (ReqArg (\arg opts -> optInfo $ PrintDefaultDataFile (optOutputFile opts) (T.pack arg)) "FILE") - "" -- "Print default data file" + DataFiles + (T.pack "Data file to print") - , Option "" ["print-highlight-style"] + , option "" ["print-highlight-style"] (ReqArg (\arg opts -> optInfo $ PrintHighlightStyle (optOutputFile opts) (T.pack arg)) "STYLE|FILE") - "" -- "Print default template for FORMAT" + HighlightStyles + (T.pack "Highlighting style") - , Option "v" ["version"] + , option "v" ["version"] (NoArg (\_ -> optInfo VersionInfo)) - "" -- "Print version" + OptFlag + (T.pack "Print version") - , Option "h" ["help"] + , option "h" ["help"] (NoArg (\_ -> optInfo Help)) - "" -- "Show help" + OptFlag + (T.pack "Show help") ] optError :: PandocError -> ExceptT OptInfo IO a @@ -1186,6 +1297,15 @@ optError = throwError . OptError optInfo :: OptInfo -> ExceptT OptInfo IO a optInfo = throwError +parseCompletionShell :: String -> OptInfo +parseCompletionShell "bash" = Completion Bash +parseCompletionShell "zsh" = Completion Zsh +parseCompletionShell "fish" = Completion Fish +parseCompletionShell s = + OptError $ PandocOptionError $ + "Unknown completion shell '" <> T.pack s <> + "'. Expected one of: bash, zsh, fish." + -- Returns usage message usageMessage :: String -> [OptDescr (Opt -> ExceptT OptInfo IO Opt)] -> String usageMessage programName = usageInfo (programName ++ " [OPTIONS] [FILES]") diff --git a/src/Text/Pandoc/App/Completion.hs b/src/Text/Pandoc/App/Completion.hs new file mode 100644 index 000000000..0161565c8 --- /dev/null +++ b/src/Text/Pandoc/App/Completion.hs @@ -0,0 +1,296 @@ +{-# LANGUAGE OverloadedStrings #-} +{-# LANGUAGE ScopedTypeVariables #-} +{-# LANGUAGE FlexibleContexts #-} +{- | + Module : Text.Pandoc.App.Completion + Copyright : Copyright (C) 2006-2024 John MacFarlane + License : GNU GPL, version 2 or above + + Maintainer : John MacFarlane + Stability : alpha + Portability : portable + +Generation of shell completion scripts for bash, zsh and fish. +The scripts are generated at runtime from pandoc's single list of +command-line options ('OptionSpec'), together with the completion +metadata that each option carries (its 'CompletionKind' and a short +description). All completions are static: the lists of formats, +styles, engines and data files are embedded into the generated script, +so no call to pandoc is made while completing. +-} +module Text.Pandoc.App.Completion ( generateCompletion ) where + +import Data.List (intercalate) +import Data.Text (Text) +import qualified Data.List as L +import qualified Data.Text as T +import System.Console.GetOpt (ArgDescr (..)) + +import Text.Pandoc.App.Opt (CompletionShell (..), OptionSpec (..), + CompletionKind (..)) + +-- | Generate a completion script for the given shell. The completion +-- behaviour and descriptions are taken from the per-option 'OptionSpec' +-- data, so the script cannot drift from the actual options. +generateCompletion :: CompletionShell + -> [OptionSpec] -- ^ the option list + -> [Text] -- ^ input formats + -> [Text] -- ^ output formats + -> [Text] -- ^ highlighting style names + -> [String] -- ^ PDF engines + -> [String] -- ^ data files + -> IO Text +generateCompletion Bash = bashScript +generateCompletion Zsh = zshScript +generateCompletion Fish = fishScript + +-- | The list of all option names (short and long), space separated. +allOptionNames :: [OptionSpec] -> String +allOptionNames opts = + unwords [ name | OptionSpec shorts longs _ _ _ <- opts + , name <- map (\c -> '-' : [c]) shorts ++ + map ("--" ++) longs ] + +-- | The completion kind and description for an option. This is taken +-- directly from the 'OptionSpec'; there is no separate specification to +-- keep in sync. +optionKindDesc :: OptionSpec -> (CompletionKind, Text) +optionKindDesc (OptionSpec _ _ _ k desc) = (k, desc) + +placeholder :: ArgDescr a -> Maybe String +placeholder (ReqArg _ s) = Just s +placeholder (OptArg _ s) = Just s +placeholder _ = Nothing + +-- | Whether an option needs an explicit @case "${prev}"@ arm in the bash +-- script. Options that just take a file or are boolean flags fall +-- through to the default file completion, so they need no arm. +isCompletableKind :: CompletionKind -> Bool +isCompletableKind OptFlag = False +isCompletableKind Files = False +isCompletableKind _ = True + +-- | The argument passed to @compgen -W@ for an option of the given kind. +-- Dynamic kinds reference the shell variables that pandoc fills in; +-- fixed enumerations are listed verbatim. +prevSource :: CompletionKind -- ^ completion kind + -> String -- ^ engine list (already space-joined) + -> String +prevSource InputFormats _ = "${informats}" +prevSource OutputFormats _ = "${outformats}" +prevSource HighlightStyles _ = "${highlight_styles}" +prevSource DataFiles _ = "${datafiles}" +prevSource Engines e = e +prevSource (Fixed vs) _ = unwords vs +prevSource OptFlag _ = "" +prevSource Files _ = "" + +---------------------------------------------------------------------- +-- bash +---------------------------------------------------------------------- + +-- | The bash completion script reproduces the historical script that +-- was previously generated from @data/bash_completion.tpl@. The list +-- of options completed per value (the @case "${prev}"@ arms) is derived +-- from the option list, so it cannot drift from the actual options. +bashScript :: [OptionSpec] -> [Text] -> [Text] -> [Text] -> [String] + -> [String] -> IO Text +bashScript opts informats outformats hstyles engines datafiles = do + let optsStr = allOptionNames opts + infStr = unwords (map T.unpack informats) + outfStr = unwords (map T.unpack outformats) + hsStr = unwords (map T.unpack hstyles) + dfStr = unwords datafiles + engStr = unwords engines + caseBody = concatMap armToLines (bashCaseArms opts engStr) + return $ T.unlines $ + [ "# This script enables bash autocompletion for pandoc. To enable" + , "# bash completion, add this to your .bashrc:" + , "# eval \"$(pandoc --completion=bash)\"" + , "" + , "_pandoc()" + , "{" + , " local cur prev opts informats outformats highlight_styles datafiles" + , " COMPREPLY=()" + , " cur=\"${COMP_WORDS[COMP_CWORD]}\"" + , " prev=\"${COMP_WORDS[COMP_CWORD-1]}\"" + , "" + , " # These should be filled in by pandoc:" + , T.pack $ " opts=\"" ++ optsStr ++ "\"" + , T.pack $ " informats=\"" ++ infStr ++ "\"" + , T.pack $ " outformats=\"" ++ outfStr ++ "\"" + , T.pack $ " highlight_styles=\"" ++ hsStr ++ "\"" + , T.pack $ " datafiles=\"" ++ dfStr ++ "\"" + , "" + , " case \"${prev}\" in" + ] + ++ caseBody ++ + [ " *)" + , " ;;" + , " esac" + , "" + , " case \"${cur}\" in" + , " -*)" + , " COMPREPLY=( $(compgen -W \"${opts}\" -- ${cur}) )" + , " return 0" + , " ;;" + , " *)" + , " local IFS=$'\\n'" + , " COMPREPLY=( $(compgen -X '' -f \"${cur}\") )" + , " return 0" + , " ;;" + , " esac" + , "" + , "}" + , "" + , "complete -o filenames -o bashdefault -F _pandoc pandoc" + ] + +-- | The @case "${prev}"@ arms, one per distinct completion source, +-- merging all options that share the same source so that (for example) +-- @--from@ and @--read@ end up in a single arm. +bashCaseArms :: [OptionSpec] -> String -> [(String, [String])] +bashCaseArms opts engStr = + let arms = [ (prevSource k engStr, names) + | o@(OptionSpec shorts longs _ _ _) <- opts + , let (k, _) = optionKindDesc o + , isCompletableKind k + , let names = map (\c -> '-' : [c]) shorts ++ + map ("--" ++) longs ] + in mergeArms arms + +-- | Merge arms that share the same completion source, preserving the +-- order in which the sources first appear in the option list. +mergeArms :: [(String, [String])] -> [(String, [String])] +mergeArms = L.foldl' go [] + where go [] (src, ns) = [(src, ns)] + go (x@(s, ns0) : xs) (src, ns) + | s == src = (s, ns0 ++ ns) : xs + | otherwise = x : go xs (src, ns) + +-- | Render one merged arm as the four lines of a bash @case@ body. +armToLines :: (String, [String]) -> [Text] +armToLines (src, names) = + let pat = intercalate "|" names + in [ T.pack (" " ++ pat ++ ")") + , T.pack (" COMPREPLY=( $(compgen -W \"" ++ src ++ + "\" -- ${cur}) )") + , " return 0" + , " ;;" ] + +---------------------------------------------------------------------- +-- zsh +---------------------------------------------------------------------- + +zshScript :: [OptionSpec] -> [Text] -> [Text] -> [Text] -> [String] + -> [String] -> IO Text +zshScript opts informats outformats hstyles engines datafiles = do + let infStr = unwords (map T.unpack informats) + outfStr = unwords (map T.unpack outformats) + hsStr = unwords (map T.unpack hstyles) + dfStr = unwords datafiles + engStr = unwords engines + action k mbP = T.pack $ zshAction k mbP infStr outfStr hsStr dfStr engStr + optLines = concat + [ zshOptionLine o action + | o@(OptionSpec _shorts _longs _ad _ _) <- opts ] + return $ T.unlines $ + [ "#compdef pandoc" + , "" + , "_pandoc() {" + , " local -a args" + , " args=(" + ] + ++ optLines + ++ [ " '*:files:_files'" + , " )" + , " _arguments -s -S $args" + , "}" + , "" + , "_pandoc \"$@\"" + ] + +-- | Produce one or more @_arguments@ spec lines (one per name) for an +-- option. The description and action are embedded in single quotes. +zshOptionLine :: OptionSpec + -> (CompletionKind -> Maybe String -> Text) + -> [Text] +zshOptionLine (OptionSpec shorts longs ad k desc) action = + let desc' = escapeZshDesc desc + act = action k (placeholder ad) + line name = T.pack (" '" ++ name ++ "[") <> desc' <> + T.pack ("]") <> act <> T.pack "'" + in map line (map (\c -> '-' : [c]) shorts ++ map ("--" ++) longs) + +-- | The zsh completion action for a given kind. All lists are embedded +-- statically. +zshAction :: CompletionKind -> Maybe String -> String -> String -> String + -> String -> String -> String +zshAction OptFlag _ _ _ _ _ _ = "" +zshAction Files mbP _ _ _ _ _ = + ":" ++ maybe "FILE" id mbP ++ ":_files" +zshAction (Fixed vs) mbP _ _ _ _ _ = + ":" ++ maybe "VALUE" id mbP ++ ":(" ++ unwords vs ++ ")" +zshAction InputFormats _ inf _ _ _ _ = ":FORMAT:(" ++ inf ++ ")" +zshAction OutputFormats _ _ outf _ _ _ = ":FORMAT:(" ++ outf ++ ")" +zshAction HighlightStyles _ _ _ hs _ _ = ":STYLE:(" ++ hs ++ ")" +zshAction DataFiles _ _ _ _ df _ = ":FILE:(" ++ df ++ ")" +zshAction Engines _ _ _ _ _ eng = ":PROGRAM:(" ++ eng ++ ")" + +-- | Escape a description for embedding inside a single-quoted zsh +-- @_arguments@ spec. Single quotes are the only character that needs +-- special treatment; the descriptions are kept free of colons and +-- square brackets. +escapeZshDesc :: Text -> Text +escapeZshDesc = T.replace "'" "'\\''" + +---------------------------------------------------------------------- +-- fish +---------------------------------------------------------------------- + +fishScript :: [OptionSpec] -> [Text] -> [Text] -> [Text] -> [String] + -> [String] -> IO Text +fishScript opts informats outformats hstyles engines datafiles = do + let infStr = unwords (map T.unpack informats) + outfStr = unwords (map T.unpack outformats) + hsStr = unwords (map T.unpack hstyles) + dfStr = unwords datafiles + engStr = unwords engines + argPart k mbP = T.pack $ fishArg k mbP infStr outfStr hsStr dfStr engStr + optLines = concat + [ fishOptionLine o argPart + | o@(OptionSpec _shorts _longs _ad _ _) <- opts ] + return $ T.unlines optLines + +fishOptionLine :: OptionSpec + -> (CompletionKind -> Maybe String -> Text) + -> [Text] +fishOptionLine (OptionSpec shorts longs ad k desc) argPart = + let shortPart = case shorts of + [c] -> T.pack (" -s " ++ [c]) + _ -> "" + descPart = if T.null desc + then "" + else T.pack " -d \"" <> escapeFishDesc desc <> T.pack "\"" + in [ T.pack "complete -c pandoc" <> shortPart <> + T.pack (" -l " ++ l) <> descPart <> + argPart k (placeholder ad) + | l <- take 1 longs ] + +fishArg :: CompletionKind -> Maybe String -> String -> String -> String + -> String -> String -> String +fishArg OptFlag _ _ _ _ _ _ = "" +fishArg Files _ _ _ _ _ _ = " -r" +fishArg (Fixed vs) _ _ _ _ _ _ = " -r -a \"" ++ unwords vs ++ "\"" +fishArg InputFormats _ inf _ _ _ _ = " -r -a \"" ++ inf ++ "\"" +fishArg OutputFormats _ _ outf _ _ _ = " -r -a \"" ++ outf ++ "\"" +fishArg HighlightStyles _ _ _ hs _ _ = " -r -a \"" ++ hs ++ "\"" +fishArg DataFiles _ _ _ _ df _ = " -r -a \"" ++ df ++ "\"" +fishArg Engines _ _ _ _ _ eng = " -r -a \"" ++ eng ++ "\"" + +-- | Escape a description for a fish completion @-d@ argument, which is +-- wrapped in double quotes. +escapeFishDesc :: Text -> Text +escapeFishDesc = T.replace "\\" "\\\\" + . T.replace "\"" "\\\"" + . T.replace "$" "\\$" diff --git a/src/Text/Pandoc/App/Opt.hs b/src/Text/Pandoc/App/Opt.hs index 8b0f805f7..712a63c0c 100644 --- a/src/Text/Pandoc/App/Opt.hs +++ b/src/Text/Pandoc/App/Opt.hs @@ -20,14 +20,20 @@ Options for pandoc when used as an app. module Text.Pandoc.App.Opt ( Opt(..) , OptInfo(..) + , CompletionShell(..) , LineEnding (..) , IpynbOutput (..) , DefaultsState (..) , defaultOpts , applyDefaults , fullDefaultsPath + , CompletionKind(..) + , OptionSpec(..) + , toOptDescr + , option ) where -import Control.Monad.Except (throwError) +import System.Console.GetOpt (OptDescr (..), ArgDescr (..)) +import Control.Monad.Except (ExceptT, throwError) import Control.Monad.Trans (MonadIO, liftIO, lift) import Control.Monad ((>=>), foldM) import Control.Monad.State.Strict (StateT, modify, gets) @@ -85,9 +91,57 @@ data IpynbOutput = $(deriveJSON defaultOptions{ fieldLabelModifier = map toLower . drop 11 } ''IpynbOutput) +-- | The shell for which a completion script is requested. +data CompletionShell = Bash | Zsh | Fish + deriving (Show, Generic) + +-- | What kind of value an option expects, and hence how it should be +-- completed in zsh/fish/bash. +data CompletionKind + = OptFlag -- ^ a boolean flag, no value + | InputFormats -- ^ an input (reader) format + | OutputFormats -- ^ an output (writer) format + | HighlightStyles -- ^ a highlighting style + | DataFiles -- ^ a pandoc data file + | Engines -- ^ a PDF engine program + | Files -- ^ a file path + | Fixed [String] -- ^ one of a fixed set of values + deriving (Show) + +-- | The single source of truth for a command-line option: its short and +-- long names, its argument parser, and the metadata needed to generate +-- shell completions. Everything else (option parsing, usage messages, +-- and completion scripts) is derived from this one structure, so an +-- option is declared in exactly one place. +data OptionSpec = OptionSpec + { optShorts :: [Char] + , optLongs :: [String] + , optArgument :: ArgDescr (Opt -> ExceptT OptInfo IO Opt) + , optCompletion :: CompletionKind + , optCompDesc :: Text + } + +-- | Convert an 'OptionSpec' into the 'OptDescr' that GetOpt consumes. +-- The GetOpt usage description is left empty (the help text is +-- documented in the manual, not the --help summary). +toOptDescr :: OptionSpec -> OptDescr (Opt -> ExceptT OptInfo IO Opt) +toOptDescr (OptionSpec shorts longs arg _ _) = + Option shorts longs arg "" + +-- | Smart constructor for an 'OptionSpec'. The completion kind and +-- description are supplied alongside the rest of the option, so the +-- single declaration fully describes both parsing and completion. +option :: [Char] + -> [String] + -> ArgDescr (Opt -> ExceptT OptInfo IO Opt) + -> CompletionKind + -> Text + -> OptionSpec +option = OptionSpec + -- | Option parser results requesting informational output. data OptInfo = - BashCompletion + Completion CompletionShell | ListInputFormats | ListOutputFormats | ListExtensions (Maybe Text) diff --git a/test/command/completion.md b/test/command/completion.md new file mode 100644 index 000000000..f99b0aee6 --- /dev/null +++ b/test/command/completion.md @@ -0,0 +1,373 @@ +``` +% pandoc --completion=bash +^D +# This script enables bash autocompletion for pandoc. To enable +# bash completion, add this to your .bashrc: +# eval "$(pandoc --completion=bash)" + +_pandoc() +{ + local cur prev opts informats outformats highlight_styles datafiles + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # These should be filled in by pandoc: + opts="-f -r --from --read -t -w --to --write -o --output --data-dir -M --metadata --metadata-file -d --defaults --file-scope --sandbox -s --standalone --template -V --variable --variable-json --wrap --ascii --toc --table-of-contents --toc-depth --lof --list-of-figures --lot --list-of-tables -N --number-sections --number-offset --top-level-division --extract-media --resource-path -H --include-in-header -B --include-before-body -A --include-after-body --no-highlight --highlight-style --syntax-definition --syntax-highlighting --dpi --eol --columns -p --preserve-tabs --tab-stop --pdf-engine --pdf-engine-opt --reference-doc --self-contained --embed-resources --link-images --request-header --no-check-certificate --abbreviations --typst-input --indented-code-classes --default-image-extension -F --filter -L --lua-filter --shift-heading-level-by --base-header-level --track-changes --strip-comments --reference-links --reference-location --figure-caption-position --table-caption-position --markdown-headings --list-tables --listings -i --incremental --slide-level --section-divs --html-q-tags --email-obfuscation --id-prefix -T --title-prefix -c --css --epub-subdirectory --epub-cover-image --epub-title-page --epub-metadata --epub-embed-font --split-level --chunk-template --epub-chapter-level --ipynb-output -C --citeproc --bibliography --csl --citation-abbreviations --natbib --biblatex --mathml --webtex --mathjax --katex --gladtex --trace --dump-args --ignore-args --verbose --quiet --fail-if-warnings --log --completion --bash-completion --list-input-formats --list-output-formats --list-extensions --list-highlight-languages --list-highlight-styles -D --print-default-template --print-default-data-file --print-highlight-style -v --version -h --help" + informats="asciidoc biblatex bibtex bits commonmark commonmark_x creole csljson csv djot docbook docx dokuwiki endnotexml epub fb2 gfm haddock html ipynb jats jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict mdoc mediawiki muse native odt opml org pod pptx ris rst rtf t2t textile tikiwiki tsv twiki typst vimwiki xlsx xml" + outformats="ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki" + highlight_styles="pygments tango espresso zenburn kate monochrome breezedark haddock" + datafiles="reference.docx reference.odt reference.pptx MANUAL.txt docx/_rels/.rels pptx/_rels/.rels abbreviations creole.lua default.csl docbook-entities.txt docx/[Content_Types].xml docx/docProps/app.xml docx/docProps/core.xml docx/docProps/custom.xml docx/word/_rels/document.xml.rels docx/word/_rels/footnotes.xml.rels docx/word/comments.xml docx/word/document.xml docx/word/fontTable.xml docx/word/footnotes.xml docx/word/numbering.xml docx/word/settings.xml docx/word/styles.xml docx/word/theme/theme1.xml docx/word/webSettings.xml dzslides/template.html epub.css init.lua odt/META-INF/manifest.xml odt/content.xml odt/manifest.rdf odt/meta.xml odt/mimetype odt/styles.xml pptx/[Content_Types].xml pptx/docProps/app.xml pptx/docProps/core.xml pptx/ppt/_rels/presentation.xml.rels pptx/ppt/notesMasters/_rels/notesMaster1.xml.rels pptx/ppt/notesMasters/notesMaster1.xml pptx/ppt/notesSlides/_rels/notesSlide1.xml.rels pptx/ppt/notesSlides/_rels/notesSlide2.xml.rels pptx/ppt/notesSlides/notesSlide1.xml pptx/ppt/notesSlides/notesSlide2.xml pptx/ppt/presProps.xml pptx/ppt/presentation.xml pptx/ppt/slideLayouts/_rels/slideLayout1.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout10.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout11.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout2.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout3.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout4.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout5.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout6.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout7.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout8.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout9.xml.rels pptx/ppt/slideLayouts/slideLayout1.xml pptx/ppt/slideLayouts/slideLayout10.xml pptx/ppt/slideLayouts/slideLayout11.xml pptx/ppt/slideLayouts/slideLayout2.xml pptx/ppt/slideLayouts/slideLayout3.xml pptx/ppt/slideLayouts/slideLayout4.xml pptx/ppt/slideLayouts/slideLayout5.xml pptx/ppt/slideLayouts/slideLayout6.xml pptx/ppt/slideLayouts/slideLayout7.xml pptx/ppt/slideLayouts/slideLayout8.xml pptx/ppt/slideLayouts/slideLayout9.xml pptx/ppt/slideMasters/_rels/slideMaster1.xml.rels pptx/ppt/slideMasters/slideMaster1.xml pptx/ppt/slides/_rels/slide1.xml.rels pptx/ppt/slides/_rels/slide2.xml.rels pptx/ppt/slides/_rels/slide3.xml.rels pptx/ppt/slides/_rels/slide4.xml.rels pptx/ppt/slides/slide1.xml pptx/ppt/slides/slide2.xml pptx/ppt/slides/slide3.xml pptx/ppt/slides/slide4.xml pptx/ppt/tableStyles.xml pptx/ppt/theme/theme1.xml pptx/ppt/theme/theme2.xml pptx/ppt/viewProps.xml templates/affiliations.jats templates/after-header-includes.latex templates/article.jats_publishing templates/common.latex templates/default.ansi templates/default.asciidoc templates/default.bbcode templates/default.beamer templates/default.biblatex templates/default.bibtex templates/default.chunkedhtml templates/default.commonmark templates/default.context templates/default.djot templates/default.docbook4 templates/default.docbook5 templates/default.dokuwiki templates/default.dzslides templates/default.epub2 templates/default.epub3 templates/default.haddock templates/default.html4 templates/default.html5 templates/default.icml templates/default.jats_archiving templates/default.jats_articleauthoring templates/default.jats_publishing templates/default.jira templates/default.latex templates/default.man templates/default.markdown templates/default.markua templates/default.mediawiki templates/default.ms templates/default.muse templates/default.opendocument templates/default.openxml templates/default.opml templates/default.org templates/default.plain templates/default.revealjs templates/default.rst templates/default.rtf templates/default.s5 templates/default.slideous templates/default.slidy templates/default.t2t templates/default.tei templates/default.texinfo templates/default.textile templates/default.typst templates/default.vimdoc templates/default.xwiki templates/default.zimwiki templates/document-metadata.latex templates/font-settings.latex templates/fonts.latex templates/hypersetup.latex templates/passoptions.latex templates/styles.citations.html templates/styles.html templates/template.typst translations/af.yaml translations/alt.yaml translations/am.yaml translations/ar.yaml translations/as.yaml translations/ast.yaml translations/az.yaml translations/be.yaml translations/bg.yaml translations/bn.yaml translations/bo.yaml translations/br.yaml translations/bs.yaml translations/bua.yaml translations/ca.yaml translations/ckb-Arab.yaml translations/ckb-Latn.yaml translations/cs.yaml translations/cu.yaml translations/cy.yaml translations/cz.yaml translations/da.yaml translations/de.yaml translations/dsb.yaml translations/el.yaml translations/en.yaml translations/eo.yaml translations/es-ES.yaml translations/es-MX.yaml translations/es.yaml translations/et.yaml translations/eu.yaml translations/fa.yaml translations/fi.yaml translations/fil.yaml translations/fr.yaml translations/fur.yaml translations/ga.yaml translations/gd.yaml translations/gl.yaml translations/grc.yaml translations/gu.yaml translations/ha.yaml translations/he.yaml translations/hi.yaml translations/hr.yaml translations/hsb.yaml translations/hu.yaml translations/hy.yaml translations/ia.yaml translations/id.yaml translations/is.yaml translations/it.yaml translations/ja.yaml translations/ka.yaml translations/km.yaml translations/kmr-Arab.yaml translations/kmr-Latn.yaml translations/kn.yaml translations/ko.yaml translations/la.yaml translations/lb.yaml translations/lo.yaml translations/lt.yaml translations/lv.yaml translations/mk.yaml translations/ml.yaml translations/mn.yaml translations/mr.yaml translations/ms.yaml translations/nb.yaml translations/nko.yaml translations/nl.yaml translations/nn.yaml translations/no.yaml translations/oc.yaml translations/or.yaml translations/pa.yaml translations/pl.yaml translations/pms.yaml translations/pt-BR.yaml translations/pt-PT.yaml translations/pt.yaml translations/rm.yaml translations/ro.yaml translations/ru.yaml translations/se.yaml translations/si.yaml translations/sk.yaml translations/sl.yaml translations/sq.yaml translations/sr-Cyrl.yaml translations/sr-Latn.yaml translations/sr.yaml translations/sv.yaml translations/ta.yaml translations/te.yaml translations/th.yaml translations/tk.yaml translations/tr.yaml translations/ua.yaml translations/ug.yaml translations/uk.yaml translations/ur.yaml translations/vi.yaml translations/zh-Hans.yaml translations/zh-Hant.yaml" + + case "${prev}" in + -f|-r|--from|--read) + COMPREPLY=( $(compgen -W "${informats}" -- ${cur}) ) + return 0 + ;; + -t|-w|--to|--write|-D|--print-default-template) + COMPREPLY=( $(compgen -W "${outformats}" -- ${cur}) ) + return 0 + ;; + --wrap) + COMPREPLY=( $(compgen -W "auto none preserve" -- ${cur}) ) + return 0 + ;; + --top-level-division) + COMPREPLY=( $(compgen -W "section chapter part" -- ${cur}) ) + return 0 + ;; + --highlight-style|--print-highlight-style) + COMPREPLY=( $(compgen -W "${highlight_styles}" -- ${cur}) ) + return 0 + ;; + --syntax-highlighting) + COMPREPLY=( $(compgen -W "none default idiomatic" -- ${cur}) ) + return 0 + ;; + --eol) + COMPREPLY=( $(compgen -W "crlf lf native" -- ${cur}) ) + return 0 + ;; + --pdf-engine) + COMPREPLY=( $(compgen -W "weasyprint wkhtmltopdf pagedjs-cli prince pdflatex lualatex xelatex latexmk tectonic pdflatex-dev lualatex-dev groff pdfroff typst context" -- ${cur}) ) + return 0 + ;; + --track-changes) + COMPREPLY=( $(compgen -W "accept reject all" -- ${cur}) ) + return 0 + ;; + --reference-location) + COMPREPLY=( $(compgen -W "block section document" -- ${cur}) ) + return 0 + ;; + --figure-caption-position|--table-caption-position) + COMPREPLY=( $(compgen -W "above below" -- ${cur}) ) + return 0 + ;; + --markdown-headings) + COMPREPLY=( $(compgen -W "setext atx" -- ${cur}) ) + return 0 + ;; + --email-obfuscation) + COMPREPLY=( $(compgen -W "references javascript none" -- ${cur}) ) + return 0 + ;; + --ipynb-output) + COMPREPLY=( $(compgen -W "all none best" -- ${cur}) ) + return 0 + ;; + --print-default-data-file) + COMPREPLY=( $(compgen -W "${datafiles}" -- ${cur}) ) + return 0 + ;; + *) + ;; + esac + + case "${cur}" in + -*) + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + ;; + *) + local IFS=$'\n' + COMPREPLY=( $(compgen -X '' -f "${cur}") ) + return 0 + ;; + esac + +} + +complete -o filenames -o bashdefault -F _pandoc pandoc + +. +``` + +``` +% pandoc --completion=zsh +^D +#compdef pandoc + +_pandoc() { + local -a args + args=( + '-f[Reader format]:FORMAT:(asciidoc biblatex bibtex bits commonmark commonmark_x creole csljson csv djot docbook docx dokuwiki endnotexml epub fb2 gfm haddock html ipynb jats jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict mdoc mediawiki muse native odt opml org pod pptx ris rst rtf t2t textile tikiwiki tsv twiki typst vimwiki xlsx xml)' + '-r[Reader format]:FORMAT:(asciidoc biblatex bibtex bits commonmark commonmark_x creole csljson csv djot docbook docx dokuwiki endnotexml epub fb2 gfm haddock html ipynb jats jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict mdoc mediawiki muse native odt opml org pod pptx ris rst rtf t2t textile tikiwiki tsv twiki typst vimwiki xlsx xml)' + '--from[Reader format]:FORMAT:(asciidoc biblatex bibtex bits commonmark commonmark_x creole csljson csv djot docbook docx dokuwiki endnotexml epub fb2 gfm haddock html ipynb jats jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict mdoc mediawiki muse native odt opml org pod pptx ris rst rtf t2t textile tikiwiki tsv twiki typst vimwiki xlsx xml)' + '--read[Reader format]:FORMAT:(asciidoc biblatex bibtex bits commonmark commonmark_x creole csljson csv djot docbook docx dokuwiki endnotexml epub fb2 gfm haddock html ipynb jats jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict mdoc mediawiki muse native odt opml org pod pptx ris rst rtf t2t textile tikiwiki tsv twiki typst vimwiki xlsx xml)' + '-t[Writer format]:FORMAT:(ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki)' + '-w[Writer format]:FORMAT:(ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki)' + '--to[Writer format]:FORMAT:(ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki)' + '--write[Writer format]:FORMAT:(ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki)' + '-o[Output file]:FILE:_files' + '--output[Output file]:FILE:_files' + '--data-dir[Directory for data files]:DIRECTORY:_files' + '-M[Metadata field KEY=VALUE]:KEY[=VALUE]:_files' + '--metadata[Metadata field KEY=VALUE]:KEY[=VALUE]:_files' + '--metadata-file[Metadata file]:FILE:_files' + '-d[Defaults file]:FILE:_files' + '--defaults[Defaults file]:FILE:_files' + '--file-scope[Parse files before combining]' + '--sandbox[Run pandoc in a sandbox]' + '-s[Include header and footer]' + '--standalone[Include header and footer]' + '--template[Custom template file]:FILE:_files' + '-V[Template variable KEY=VALUE]:KEY[=VALUE]:_files' + '--variable[Template variable KEY=VALUE]:KEY[=VALUE]:_files' + '--variable-json[Template variable KEY=JSON]:KEY[:JSON]:_files' + '--wrap[Text wrapping mode]:auto|none|preserve:(auto none preserve)' + '--ascii[Prefer ASCII output]' + '--toc[Include table of contents]' + '--table-of-contents[Include table of contents]' + '--toc-depth[Number of TOC levels]:NUMBER:_files' + '--lof[Include list of figures]' + '--list-of-figures[Include list of figures]' + '--lot[Include list of tables]' + '--list-of-tables[Include list of tables]' + '-N[Number section headings]' + '--number-sections[Number section headings]' + '--number-offset[Starting number for sections]:NUMBERS:_files' + '--top-level-division[Top-level document division]:section|chapter|part:(section chapter part)' + '--extract-media[Directory to extract media into]:PATH:_files' + '--resource-path[Search path for resources]:SEARCHPATH:_files' + '-H[File to include in the header]:FILE:_files' + '--include-in-header[File to include in the header]:FILE:_files' + '-B[File to include before the body]:FILE:_files' + '--include-before-body[File to include before the body]:FILE:_files' + '-A[File to include after the body]:FILE:_files' + '--include-after-body[File to include after the body]:FILE:_files' + '--no-highlight[Disable syntax highlighting]' + '--highlight-style[Highlighting style]:STYLE:(pygments tango espresso zenburn kate monochrome breezedark haddock)' + '--syntax-definition[Syntax definition XML file]:FILE:_files' + '--syntax-highlighting[Syntax highlighting method]:none|default|idiomatic||:(none default idiomatic)' + '--dpi[DPI for imported images]:NUMBER:_files' + '--eol[End-of-line characters]:crlf|lf|native:(crlf lf native)' + '--columns[Line length in characters]:NUMBER:_files' + '-p[Preserve tabs]' + '--preserve-tabs[Preserve tabs]' + '--tab-stop[Tab stop width]:NUMBER:_files' + '--pdf-engine[Program used to produce PDF]:PROGRAM:(weasyprint wkhtmltopdf pagedjs-cli prince pdflatex lualatex xelatex latexmk tectonic pdflatex-dev lualatex-dev groff pdfroff typst context)' + '--pdf-engine-opt[Flag to pass to the PDF engine]:STRING:_files' + '--reference-doc[Custom reference doc]:FILE:_files' + '--self-contained[Embed resources (deprecated)]' + '--embed-resources[Embed referenced resources]' + '--link-images[Link images in ODT rather than embedding]' + '--request-header[HTTP header NAME=VALUE]:NAME=VALUE:_files' + '--no-check-certificate[Disable certificate validation]' + '--abbreviations[File with abbreviations]:FILE:_files' + '--typst-input[Typst variable KEY=VALUE]:KEY=VALUE:_files' + '--indented-code-classes[Classes for indented code blocks]:STRING:_files' + '--default-image-extension[Default extension for images]:extension:_files' + '-F[External JSON filter]:PROGRAM:_files' + '--filter[External JSON filter]:PROGRAM:_files' + '-L[Lua filter script]:SCRIPTPATH:_files' + '--lua-filter[Lua filter script]:SCRIPTPATH:_files' + '--shift-heading-level-by[Shift heading level by N]:NUMBER:_files' + '--base-header-level[Base header level (deprecated)]:NUMBER:_files' + '--track-changes[Handling of Word track-changes]:accept|reject|all:(accept reject all)' + '--strip-comments[Strip HTML comments]' + '--reference-links[Use reference links in HTML]' + '--reference-location[Location of references]:block|section|document:(block section document)' + '--figure-caption-position[Figure caption position]:above|below:(above below)' + '--table-caption-position[Table caption position]:above|below:(above below)' + '--markdown-headings[Markdown heading style]:setext|atx:(setext atx)' + '--list-tables[Use list tables for RST]' + '--listings[Use listings package (deprecated)]' + '-i[Make list items display incrementally]' + '--incremental[Make list items display incrementally]' + '--slide-level[Header level used for slides]:NUMBER:_files' + '--section-divs[Wrap sections in div tags]' + '--html-q-tags[Use q tags for quotes in HTML]' + '--email-obfuscation[Email obfuscation method]:none|javascript|references:(references javascript none)' + '--id-prefix[Prefix for auto identifiers]:STRING:_files' + '-T[Window title prefix]:STRING:_files' + '--title-prefix[Window title prefix]:STRING:_files' + '-c[CSS style sheet]:URL:_files' + '--css[CSS style sheet]:URL:_files' + '--epub-subdirectory[EPUB content subdirectory]:DIRNAME:_files' + '--epub-cover-image[EPUB cover image]:FILE:_files' + '--epub-title-page[URL or file for EPUB title page]:true|false:_files' + '--epub-metadata[EPUB metadata file]:FILE:_files' + '--epub-embed-font[Font file to embed in EPUB]:FILE:_files' + '--split-level[Split level for chunked HTML or EPUB]:NUMBER:_files' + '--chunk-template[Template for chunked HTML paths]:PATHTEMPLATE:_files' + '--epub-chapter-level[Split level (deprecated)]:NUMBER:_files' + '--ipynb-output[Handling of ipynb output cells]:all|none|best:(all none best)' + '-C[Process citations]' + '--citeproc[Process citations]' + '--bibliography[Bibliography file]:FILE:_files' + '--csl[CSL style file]:FILE:_files' + '--citation-abbreviations[Citation abbreviations file]:FILE:_files' + '--natbib[Use natbib citations in LaTeX]' + '--biblatex[Use biblatex citations in LaTeX]' + '--mathml[Use MathML for HTML math]' + '--webtex[Use WebTeX for HTML math]' + '--mathjax[Use MathJax for HTML math]' + '--katex[Use KaTeX for HTML math]' + '--gladtex[Use gladTeX for HTML math]' + '--trace[Turn on diagnostic tracing]' + '--dump-args[Print output filename and arguments]' + '--ignore-args[Ignore command-line arguments]' + '--verbose[Verbose diagnostic output]' + '--quiet[Suppress warning messages]' + '--fail-if-warnings[Exit with error status if there were warnings]' + '--log[Log messages in JSON format to this file]:FILE:_files' + '--completion[Shell for which to print the completion script]' + '--bash-completion[Print bash completion script (deprecated)]' + '--list-input-formats[List supported input formats]' + '--list-output-formats[List supported output formats]' + '--list-extensions[List supported extensions]' + '--list-highlight-languages[List highlighting languages]' + '--list-highlight-styles[List highlighting styles]' + '-D[Format to print template for]:FORMAT:(ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki)' + '--print-default-template[Format to print template for]:FORMAT:(ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki)' + '--print-default-data-file[Data file to print]:FILE:(reference.docx reference.odt reference.pptx MANUAL.txt docx/_rels/.rels pptx/_rels/.rels abbreviations creole.lua default.csl docbook-entities.txt docx/[Content_Types].xml docx/docProps/app.xml docx/docProps/core.xml docx/docProps/custom.xml docx/word/_rels/document.xml.rels docx/word/_rels/footnotes.xml.rels docx/word/comments.xml docx/word/document.xml docx/word/fontTable.xml docx/word/footnotes.xml docx/word/numbering.xml docx/word/settings.xml docx/word/styles.xml docx/word/theme/theme1.xml docx/word/webSettings.xml dzslides/template.html epub.css init.lua odt/META-INF/manifest.xml odt/content.xml odt/manifest.rdf odt/meta.xml odt/mimetype odt/styles.xml pptx/[Content_Types].xml pptx/docProps/app.xml pptx/docProps/core.xml pptx/ppt/_rels/presentation.xml.rels pptx/ppt/notesMasters/_rels/notesMaster1.xml.rels pptx/ppt/notesMasters/notesMaster1.xml pptx/ppt/notesSlides/_rels/notesSlide1.xml.rels pptx/ppt/notesSlides/_rels/notesSlide2.xml.rels pptx/ppt/notesSlides/notesSlide1.xml pptx/ppt/notesSlides/notesSlide2.xml pptx/ppt/presProps.xml pptx/ppt/presentation.xml pptx/ppt/slideLayouts/_rels/slideLayout1.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout10.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout11.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout2.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout3.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout4.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout5.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout6.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout7.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout8.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout9.xml.rels pptx/ppt/slideLayouts/slideLayout1.xml pptx/ppt/slideLayouts/slideLayout10.xml pptx/ppt/slideLayouts/slideLayout11.xml pptx/ppt/slideLayouts/slideLayout2.xml pptx/ppt/slideLayouts/slideLayout3.xml pptx/ppt/slideLayouts/slideLayout4.xml pptx/ppt/slideLayouts/slideLayout5.xml pptx/ppt/slideLayouts/slideLayout6.xml pptx/ppt/slideLayouts/slideLayout7.xml pptx/ppt/slideLayouts/slideLayout8.xml pptx/ppt/slideLayouts/slideLayout9.xml pptx/ppt/slideMasters/_rels/slideMaster1.xml.rels pptx/ppt/slideMasters/slideMaster1.xml pptx/ppt/slides/_rels/slide1.xml.rels pptx/ppt/slides/_rels/slide2.xml.rels pptx/ppt/slides/_rels/slide3.xml.rels pptx/ppt/slides/_rels/slide4.xml.rels pptx/ppt/slides/slide1.xml pptx/ppt/slides/slide2.xml pptx/ppt/slides/slide3.xml pptx/ppt/slides/slide4.xml pptx/ppt/tableStyles.xml pptx/ppt/theme/theme1.xml pptx/ppt/theme/theme2.xml pptx/ppt/viewProps.xml templates/affiliations.jats templates/after-header-includes.latex templates/article.jats_publishing templates/common.latex templates/default.ansi templates/default.asciidoc templates/default.bbcode templates/default.beamer templates/default.biblatex templates/default.bibtex templates/default.chunkedhtml templates/default.commonmark templates/default.context templates/default.djot templates/default.docbook4 templates/default.docbook5 templates/default.dokuwiki templates/default.dzslides templates/default.epub2 templates/default.epub3 templates/default.haddock templates/default.html4 templates/default.html5 templates/default.icml templates/default.jats_archiving templates/default.jats_articleauthoring templates/default.jats_publishing templates/default.jira templates/default.latex templates/default.man templates/default.markdown templates/default.markua templates/default.mediawiki templates/default.ms templates/default.muse templates/default.opendocument templates/default.openxml templates/default.opml templates/default.org templates/default.plain templates/default.revealjs templates/default.rst templates/default.rtf templates/default.s5 templates/default.slideous templates/default.slidy templates/default.t2t templates/default.tei templates/default.texinfo templates/default.textile templates/default.typst templates/default.vimdoc templates/default.xwiki templates/default.zimwiki templates/document-metadata.latex templates/font-settings.latex templates/fonts.latex templates/hypersetup.latex templates/passoptions.latex templates/styles.citations.html templates/styles.html templates/template.typst translations/af.yaml translations/alt.yaml translations/am.yaml translations/ar.yaml translations/as.yaml translations/ast.yaml translations/az.yaml translations/be.yaml translations/bg.yaml translations/bn.yaml translations/bo.yaml translations/br.yaml translations/bs.yaml translations/bua.yaml translations/ca.yaml translations/ckb-Arab.yaml translations/ckb-Latn.yaml translations/cs.yaml translations/cu.yaml translations/cy.yaml translations/cz.yaml translations/da.yaml translations/de.yaml translations/dsb.yaml translations/el.yaml translations/en.yaml translations/eo.yaml translations/es-ES.yaml translations/es-MX.yaml translations/es.yaml translations/et.yaml translations/eu.yaml translations/fa.yaml translations/fi.yaml translations/fil.yaml translations/fr.yaml translations/fur.yaml translations/ga.yaml translations/gd.yaml translations/gl.yaml translations/grc.yaml translations/gu.yaml translations/ha.yaml translations/he.yaml translations/hi.yaml translations/hr.yaml translations/hsb.yaml translations/hu.yaml translations/hy.yaml translations/ia.yaml translations/id.yaml translations/is.yaml translations/it.yaml translations/ja.yaml translations/ka.yaml translations/km.yaml translations/kmr-Arab.yaml translations/kmr-Latn.yaml translations/kn.yaml translations/ko.yaml translations/la.yaml translations/lb.yaml translations/lo.yaml translations/lt.yaml translations/lv.yaml translations/mk.yaml translations/ml.yaml translations/mn.yaml translations/mr.yaml translations/ms.yaml translations/nb.yaml translations/nko.yaml translations/nl.yaml translations/nn.yaml translations/no.yaml translations/oc.yaml translations/or.yaml translations/pa.yaml translations/pl.yaml translations/pms.yaml translations/pt-BR.yaml translations/pt-PT.yaml translations/pt.yaml translations/rm.yaml translations/ro.yaml translations/ru.yaml translations/se.yaml translations/si.yaml translations/sk.yaml translations/sl.yaml translations/sq.yaml translations/sr-Cyrl.yaml translations/sr-Latn.yaml translations/sr.yaml translations/sv.yaml translations/ta.yaml translations/te.yaml translations/th.yaml translations/tk.yaml translations/tr.yaml translations/ua.yaml translations/ug.yaml translations/uk.yaml translations/ur.yaml translations/vi.yaml translations/zh-Hans.yaml translations/zh-Hant.yaml)' + '--print-highlight-style[Highlighting style]:STYLE:(pygments tango espresso zenburn kate monochrome breezedark haddock)' + '-v[Print version]' + '--version[Print version]' + '-h[Show help]' + '--help[Show help]' + '*:files:_files' + ) + _arguments -s -S $args +} + +_pandoc "$@" + +. +``` + +``` +% pandoc --completion=fish +^D +complete -c pandoc -l from -d "Reader format" -r -a "asciidoc biblatex bibtex bits commonmark commonmark_x creole csljson csv djot docbook docx dokuwiki endnotexml epub fb2 gfm haddock html ipynb jats jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict mdoc mediawiki muse native odt opml org pod pptx ris rst rtf t2t textile tikiwiki tsv twiki typst vimwiki xlsx xml" +complete -c pandoc -l to -d "Writer format" -r -a "ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki" +complete -c pandoc -s o -l output -d "Output file" -r +complete -c pandoc -l data-dir -d "Directory for data files" -r +complete -c pandoc -s M -l metadata -d "Metadata field KEY=VALUE" -r +complete -c pandoc -l metadata-file -d "Metadata file" -r +complete -c pandoc -s d -l defaults -d "Defaults file" -r +complete -c pandoc -l file-scope -d "Parse files before combining" +complete -c pandoc -l sandbox -d "Run pandoc in a sandbox" +complete -c pandoc -s s -l standalone -d "Include header and footer" +complete -c pandoc -l template -d "Custom template file" -r +complete -c pandoc -s V -l variable -d "Template variable KEY=VALUE" -r +complete -c pandoc -l variable-json -d "Template variable KEY=JSON" -r +complete -c pandoc -l wrap -d "Text wrapping mode" -r -a "auto none preserve" +complete -c pandoc -l ascii -d "Prefer ASCII output" +complete -c pandoc -l toc -d "Include table of contents" +complete -c pandoc -l toc-depth -d "Number of TOC levels" -r +complete -c pandoc -l lof -d "Include list of figures" +complete -c pandoc -l lot -d "Include list of tables" +complete -c pandoc -s N -l number-sections -d "Number section headings" +complete -c pandoc -l number-offset -d "Starting number for sections" -r +complete -c pandoc -l top-level-division -d "Top-level document division" -r -a "section chapter part" +complete -c pandoc -l extract-media -d "Directory to extract media into" -r +complete -c pandoc -l resource-path -d "Search path for resources" -r +complete -c pandoc -s H -l include-in-header -d "File to include in the header" -r +complete -c pandoc -s B -l include-before-body -d "File to include before the body" -r +complete -c pandoc -s A -l include-after-body -d "File to include after the body" -r +complete -c pandoc -l no-highlight -d "Disable syntax highlighting" +complete -c pandoc -l highlight-style -d "Highlighting style" -r -a "pygments tango espresso zenburn kate monochrome breezedark haddock" +complete -c pandoc -l syntax-definition -d "Syntax definition XML file" -r +complete -c pandoc -l syntax-highlighting -d "Syntax highlighting method" -r -a "none default idiomatic" +complete -c pandoc -l dpi -d "DPI for imported images" -r +complete -c pandoc -l eol -d "End-of-line characters" -r -a "crlf lf native" +complete -c pandoc -l columns -d "Line length in characters" -r +complete -c pandoc -s p -l preserve-tabs -d "Preserve tabs" +complete -c pandoc -l tab-stop -d "Tab stop width" -r +complete -c pandoc -l pdf-engine -d "Program used to produce PDF" -r -a "weasyprint wkhtmltopdf pagedjs-cli prince pdflatex lualatex xelatex latexmk tectonic pdflatex-dev lualatex-dev groff pdfroff typst context" +complete -c pandoc -l pdf-engine-opt -d "Flag to pass to the PDF engine" -r +complete -c pandoc -l reference-doc -d "Custom reference doc" -r +complete -c pandoc -l self-contained -d "Embed resources (deprecated)" +complete -c pandoc -l embed-resources -d "Embed referenced resources" +complete -c pandoc -l link-images -d "Link images in ODT rather than embedding" +complete -c pandoc -l request-header -d "HTTP header NAME=VALUE" -r +complete -c pandoc -l no-check-certificate -d "Disable certificate validation" +complete -c pandoc -l abbreviations -d "File with abbreviations" -r +complete -c pandoc -l typst-input -d "Typst variable KEY=VALUE" -r +complete -c pandoc -l indented-code-classes -d "Classes for indented code blocks" -r +complete -c pandoc -l default-image-extension -d "Default extension for images" -r +complete -c pandoc -s F -l filter -d "External JSON filter" -r +complete -c pandoc -s L -l lua-filter -d "Lua filter script" -r +complete -c pandoc -l shift-heading-level-by -d "Shift heading level by N" -r +complete -c pandoc -l base-header-level -d "Base header level (deprecated)" -r +complete -c pandoc -l track-changes -d "Handling of Word track-changes" -r -a "accept reject all" +complete -c pandoc -l strip-comments -d "Strip HTML comments" +complete -c pandoc -l reference-links -d "Use reference links in HTML" +complete -c pandoc -l reference-location -d "Location of references" -r -a "block section document" +complete -c pandoc -l figure-caption-position -d "Figure caption position" -r -a "above below" +complete -c pandoc -l table-caption-position -d "Table caption position" -r -a "above below" +complete -c pandoc -l markdown-headings -d "Markdown heading style" -r -a "setext atx" +complete -c pandoc -l list-tables -d "Use list tables for RST" +complete -c pandoc -l listings -d "Use listings package (deprecated)" +complete -c pandoc -s i -l incremental -d "Make list items display incrementally" +complete -c pandoc -l slide-level -d "Header level used for slides" -r +complete -c pandoc -l section-divs -d "Wrap sections in div tags" +complete -c pandoc -l html-q-tags -d "Use q tags for quotes in HTML" +complete -c pandoc -l email-obfuscation -d "Email obfuscation method" -r -a "references javascript none" +complete -c pandoc -l id-prefix -d "Prefix for auto identifiers" -r +complete -c pandoc -s T -l title-prefix -d "Window title prefix" -r +complete -c pandoc -s c -l css -d "CSS style sheet" -r +complete -c pandoc -l epub-subdirectory -d "EPUB content subdirectory" -r +complete -c pandoc -l epub-cover-image -d "EPUB cover image" -r +complete -c pandoc -l epub-title-page -d "URL or file for EPUB title page" -r +complete -c pandoc -l epub-metadata -d "EPUB metadata file" -r +complete -c pandoc -l epub-embed-font -d "Font file to embed in EPUB" -r +complete -c pandoc -l split-level -d "Split level for chunked HTML or EPUB" -r +complete -c pandoc -l chunk-template -d "Template for chunked HTML paths" -r +complete -c pandoc -l epub-chapter-level -d "Split level (deprecated)" -r +complete -c pandoc -l ipynb-output -d "Handling of ipynb output cells" -r -a "all none best" +complete -c pandoc -s C -l citeproc -d "Process citations" +complete -c pandoc -l bibliography -d "Bibliography file" -r +complete -c pandoc -l csl -d "CSL style file" -r +complete -c pandoc -l citation-abbreviations -d "Citation abbreviations file" -r +complete -c pandoc -l natbib -d "Use natbib citations in LaTeX" +complete -c pandoc -l biblatex -d "Use biblatex citations in LaTeX" +complete -c pandoc -l mathml -d "Use MathML for HTML math" +complete -c pandoc -l webtex -d "Use WebTeX for HTML math" +complete -c pandoc -l mathjax -d "Use MathJax for HTML math" +complete -c pandoc -l katex -d "Use KaTeX for HTML math" +complete -c pandoc -l gladtex -d "Use gladTeX for HTML math" +complete -c pandoc -l trace -d "Turn on diagnostic tracing" +complete -c pandoc -l dump-args -d "Print output filename and arguments" +complete -c pandoc -l ignore-args -d "Ignore command-line arguments" +complete -c pandoc -l verbose -d "Verbose diagnostic output" +complete -c pandoc -l quiet -d "Suppress warning messages" +complete -c pandoc -l fail-if-warnings -d "Exit with error status if there were warnings" +complete -c pandoc -l log -d "Log messages in JSON format to this file" -r +complete -c pandoc -l completion -d "Shell for which to print the completion script" +complete -c pandoc -l bash-completion -d "Print bash completion script (deprecated)" +complete -c pandoc -l list-input-formats -d "List supported input formats" +complete -c pandoc -l list-output-formats -d "List supported output formats" +complete -c pandoc -l list-extensions -d "List supported extensions" +complete -c pandoc -l list-highlight-languages -d "List highlighting languages" +complete -c pandoc -l list-highlight-styles -d "List highlighting styles" +complete -c pandoc -s D -l print-default-template -d "Format to print template for" -r -a "ansi asciidoc asciidoc_legacy asciidoctor bbcode bbcode_fluxbb bbcode_hubzilla bbcode_phpbb bbcode_steam bbcode_xenforo beamer biblatex bibtex chunkedhtml commonmark commonmark_x context csljson djot docbook docbook4 docbook5 docx dokuwiki dzslides epub epub2 epub3 fb2 gfm haddock html html4 html5 icml ipynb jats jats_archiving jats_articleauthoring jats_publishing jira json latex man markdown markdown_github markdown_mmd markdown_phpextra markdown_strict markua mediawiki ms muse native odt opendocument opml org pdf plain pptx revealjs rst rtf s5 slideous slidy t2t tei texinfo textile typst vimdoc xml xwiki zimwiki" +complete -c pandoc -l print-default-data-file -d "Data file to print" -r -a "reference.docx reference.odt reference.pptx MANUAL.txt docx/_rels/.rels pptx/_rels/.rels abbreviations creole.lua default.csl docbook-entities.txt docx/[Content_Types].xml docx/docProps/app.xml docx/docProps/core.xml docx/docProps/custom.xml docx/word/_rels/document.xml.rels docx/word/_rels/footnotes.xml.rels docx/word/comments.xml docx/word/document.xml docx/word/fontTable.xml docx/word/footnotes.xml docx/word/numbering.xml docx/word/settings.xml docx/word/styles.xml docx/word/theme/theme1.xml docx/word/webSettings.xml dzslides/template.html epub.css init.lua odt/META-INF/manifest.xml odt/content.xml odt/manifest.rdf odt/meta.xml odt/mimetype odt/styles.xml pptx/[Content_Types].xml pptx/docProps/app.xml pptx/docProps/core.xml pptx/ppt/_rels/presentation.xml.rels pptx/ppt/notesMasters/_rels/notesMaster1.xml.rels pptx/ppt/notesMasters/notesMaster1.xml pptx/ppt/notesSlides/_rels/notesSlide1.xml.rels pptx/ppt/notesSlides/_rels/notesSlide2.xml.rels pptx/ppt/notesSlides/notesSlide1.xml pptx/ppt/notesSlides/notesSlide2.xml pptx/ppt/presProps.xml pptx/ppt/presentation.xml pptx/ppt/slideLayouts/_rels/slideLayout1.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout10.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout11.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout2.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout3.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout4.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout5.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout6.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout7.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout8.xml.rels pptx/ppt/slideLayouts/_rels/slideLayout9.xml.rels pptx/ppt/slideLayouts/slideLayout1.xml pptx/ppt/slideLayouts/slideLayout10.xml pptx/ppt/slideLayouts/slideLayout11.xml pptx/ppt/slideLayouts/slideLayout2.xml pptx/ppt/slideLayouts/slideLayout3.xml pptx/ppt/slideLayouts/slideLayout4.xml pptx/ppt/slideLayouts/slideLayout5.xml pptx/ppt/slideLayouts/slideLayout6.xml pptx/ppt/slideLayouts/slideLayout7.xml pptx/ppt/slideLayouts/slideLayout8.xml pptx/ppt/slideLayouts/slideLayout9.xml pptx/ppt/slideMasters/_rels/slideMaster1.xml.rels pptx/ppt/slideMasters/slideMaster1.xml pptx/ppt/slides/_rels/slide1.xml.rels pptx/ppt/slides/_rels/slide2.xml.rels pptx/ppt/slides/_rels/slide3.xml.rels pptx/ppt/slides/_rels/slide4.xml.rels pptx/ppt/slides/slide1.xml pptx/ppt/slides/slide2.xml pptx/ppt/slides/slide3.xml pptx/ppt/slides/slide4.xml pptx/ppt/tableStyles.xml pptx/ppt/theme/theme1.xml pptx/ppt/theme/theme2.xml pptx/ppt/viewProps.xml templates/affiliations.jats templates/after-header-includes.latex templates/article.jats_publishing templates/common.latex templates/default.ansi templates/default.asciidoc templates/default.bbcode templates/default.beamer templates/default.biblatex templates/default.bibtex templates/default.chunkedhtml templates/default.commonmark templates/default.context templates/default.djot templates/default.docbook4 templates/default.docbook5 templates/default.dokuwiki templates/default.dzslides templates/default.epub2 templates/default.epub3 templates/default.haddock templates/default.html4 templates/default.html5 templates/default.icml templates/default.jats_archiving templates/default.jats_articleauthoring templates/default.jats_publishing templates/default.jira templates/default.latex templates/default.man templates/default.markdown templates/default.markua templates/default.mediawiki templates/default.ms templates/default.muse templates/default.opendocument templates/default.openxml templates/default.opml templates/default.org templates/default.plain templates/default.revealjs templates/default.rst templates/default.rtf templates/default.s5 templates/default.slideous templates/default.slidy templates/default.t2t templates/default.tei templates/default.texinfo templates/default.textile templates/default.typst templates/default.vimdoc templates/default.xwiki templates/default.zimwiki templates/document-metadata.latex templates/font-settings.latex templates/fonts.latex templates/hypersetup.latex templates/passoptions.latex templates/styles.citations.html templates/styles.html templates/template.typst translations/af.yaml translations/alt.yaml translations/am.yaml translations/ar.yaml translations/as.yaml translations/ast.yaml translations/az.yaml translations/be.yaml translations/bg.yaml translations/bn.yaml translations/bo.yaml translations/br.yaml translations/bs.yaml translations/bua.yaml translations/ca.yaml translations/ckb-Arab.yaml translations/ckb-Latn.yaml translations/cs.yaml translations/cu.yaml translations/cy.yaml translations/cz.yaml translations/da.yaml translations/de.yaml translations/dsb.yaml translations/el.yaml translations/en.yaml translations/eo.yaml translations/es-ES.yaml translations/es-MX.yaml translations/es.yaml translations/et.yaml translations/eu.yaml translations/fa.yaml translations/fi.yaml translations/fil.yaml translations/fr.yaml translations/fur.yaml translations/ga.yaml translations/gd.yaml translations/gl.yaml translations/grc.yaml translations/gu.yaml translations/ha.yaml translations/he.yaml translations/hi.yaml translations/hr.yaml translations/hsb.yaml translations/hu.yaml translations/hy.yaml translations/ia.yaml translations/id.yaml translations/is.yaml translations/it.yaml translations/ja.yaml translations/ka.yaml translations/km.yaml translations/kmr-Arab.yaml translations/kmr-Latn.yaml translations/kn.yaml translations/ko.yaml translations/la.yaml translations/lb.yaml translations/lo.yaml translations/lt.yaml translations/lv.yaml translations/mk.yaml translations/ml.yaml translations/mn.yaml translations/mr.yaml translations/ms.yaml translations/nb.yaml translations/nko.yaml translations/nl.yaml translations/nn.yaml translations/no.yaml translations/oc.yaml translations/or.yaml translations/pa.yaml translations/pl.yaml translations/pms.yaml translations/pt-BR.yaml translations/pt-PT.yaml translations/pt.yaml translations/rm.yaml translations/ro.yaml translations/ru.yaml translations/se.yaml translations/si.yaml translations/sk.yaml translations/sl.yaml translations/sq.yaml translations/sr-Cyrl.yaml translations/sr-Latn.yaml translations/sr.yaml translations/sv.yaml translations/ta.yaml translations/te.yaml translations/th.yaml translations/tk.yaml translations/tr.yaml translations/ua.yaml translations/ug.yaml translations/uk.yaml translations/ur.yaml translations/vi.yaml translations/zh-Hans.yaml translations/zh-Hant.yaml" +complete -c pandoc -l print-highlight-style -d "Highlighting style" -r -a "pygments tango espresso zenburn kate monochrome breezedark haddock" +complete -c pandoc -s v -l version -d "Print version" +complete -c pandoc -s h -l help -d "Show help" + +. +```