diff --git a/MANUAL.txt b/MANUAL.txt index ad3cd11a5bf3..2edef40d9c4b 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -1058,6 +1058,18 @@ header when requesting a document from a URL: specifying `--reference-location=section` will cause notes to be rendered at the bottom of a slide. +`--figure-caption-position=above`|`below` + +: Specify whether figure captions go above or below figures + (default is `below`). This option only affects HTML, + LaTeX, Docx, ODT, and Typst output. + +`--table-caption-position=above`|`below` + +: Specify whether table captions go above or below tables + (default is `above`). This option only affects HTML, + LaTeX, Docx, ODT, and Typst output. + `--markdown-headings=setext`|`atx` : Specify whether to use ATX-style (`#`-prefixed) or diff --git a/data/templates/default.typst b/data/templates/default.typst index e2b154221e29..1e7b5efd422e 100644 --- a/data/templates/default.typst +++ b/data/templates/default.typst @@ -14,6 +14,14 @@ $definitions.typst()$ stroke: none ) +#show figure.where( + kind: table +): set figure.caption(position: $if(table-caption-position)$$table-caption-position$$else$top$endif$) + +#show figure.where( + kind: image +): set figure.caption(position: $if(figure-caption-position)$$figure-caption-position$$else$bottom$endif$) + $if(template)$ #import "$template$": conf $else$ diff --git a/data/templates/styles.html b/data/templates/styles.html index 58fff9f2f03b..cd3b95958f1c 100644 --- a/data/templates/styles.html +++ b/data/templates/styles.html @@ -144,7 +144,12 @@ font-variant-numeric: lining-nums tabular-nums; } table caption { +$if(table-caption-below)$ + caption-side: bottom; + margin-top: 0.75em; +$else$ margin-bottom: 0.75em; +$endif$ } tbody { margin-top: 0.5em; diff --git a/src/Text/Pandoc/App/CommandLineOptions.hs b/src/Text/Pandoc/App/CommandLineOptions.hs index a1ccda704b96..cf319e834ca3 100644 --- a/src/Text/Pandoc/App/CommandLineOptions.hs +++ b/src/Text/Pandoc/App/CommandLineOptions.hs @@ -728,7 +728,31 @@ options = "Argument of --reference-location must be block, section, or document" return opt { optReferenceLocation = action }) "block|section|document") - "" -- "Accepting or reject MS Word track-changes."" + "" -- "Specify where reference links and footnotes go" + + , Option "" ["figure-caption-position"] + (ReqArg + (\arg opt -> do + pos <- case arg of + "above" -> return CaptionAbove + "below" -> return CaptionBelow + _ -> optError $ PandocOptionError $ T.pack + "Argument of --figure-caption-position must be above or below" + return opt { optFigureCaptionPosition = pos }) + "above|below") + "" -- "Specify where figure captions go" + + , Option "" ["table-caption-position"] + (ReqArg + (\arg opt -> do + pos <- case arg of + "above" -> return CaptionAbove + "below" -> return CaptionBelow + _ -> optError $ PandocOptionError $ T.pack + "Argument of --table-caption-position must be above or below" + return opt { optTableCaptionPosition = pos }) + "above|below") + "" -- "Specify where table captions go" , Option "" ["markdown-headings"] (ReqArg diff --git a/src/Text/Pandoc/App/Opt.hs b/src/Text/Pandoc/App/Opt.hs index b6050f117bc2..1bbf82522699 100644 --- a/src/Text/Pandoc/App/Opt.hs +++ b/src/Text/Pandoc/App/Opt.hs @@ -41,6 +41,7 @@ import Text.Pandoc.Options (TopLevelDivision (TopLevelDefault), TrackChanges (AcceptChanges), WrapOption (WrapAuto), HTMLMathMethod (PlainMath), ReferenceLocation (EndOfDocument), + CaptionPosition (..), ObfuscationMethod (NoObfuscation), CiteMethod (Citeproc)) import Text.Pandoc.Class (readFileStrict, fileExists, setVerbosity, report, @@ -143,6 +144,8 @@ data Opt = Opt , optFailIfWarnings :: Bool -- ^ Fail on warnings , optReferenceLinks :: Bool -- ^ Use reference links in writing markdown, rst , optReferenceLocation :: ReferenceLocation -- ^ location for footnotes and link references in markdown output + , optFigureCaptionPosition :: CaptionPosition -- ^ position for figure caption + , optTableCaptionPosition :: CaptionPosition -- ^ position for table caption , optDpi :: Int -- ^ Dpi , optWrap :: WrapOption -- ^ Options for wrapping text , optColumns :: Int -- ^ Line length in characters @@ -227,6 +230,8 @@ instance FromJSON Opt where <*> o .:? "fail-if-warnings" .!= optFailIfWarnings defaultOpts <*> o .:? "reference-links" .!= optReferenceLinks defaultOpts <*> o .:? "reference-location" .!= optReferenceLocation defaultOpts + <*> o .:? "figure-caption-position" .!= optFigureCaptionPosition defaultOpts + <*> o .:? "table-caption-position" .!= optTableCaptionPosition defaultOpts <*> o .:? "dpi" .!= optDpi defaultOpts <*> o .:? "wrap" .!= optWrap defaultOpts <*> o .:? "columns" .!= optColumns defaultOpts @@ -594,6 +599,10 @@ doOpt (k,v) = do parseJSON v >>= \x -> return (\o -> o{ optReferenceLinks = x }) "reference-location" -> parseJSON v >>= \x -> return (\o -> o{ optReferenceLocation = x }) + "figure-caption-position" -> + parseJSON v >>= \x -> return (\o -> o{ optFigureCaptionPosition = x }) + "table-caption-position" -> + parseJSON v >>= \x -> return (\o -> o{ optTableCaptionPosition = x }) "dpi" -> parseJSON v >>= \x -> return (\o -> o{ optDpi = x }) "wrap" -> @@ -766,6 +775,8 @@ defaultOpts = Opt , optFailIfWarnings = False , optReferenceLinks = False , optReferenceLocation = EndOfDocument + , optFigureCaptionPosition = CaptionBelow + , optTableCaptionPosition = CaptionAbove , optDpi = 96 , optWrap = WrapAuto , optColumns = 72 diff --git a/src/Text/Pandoc/App/OutputSettings.hs b/src/Text/Pandoc/App/OutputSettings.hs index 11d813e5e6bb..dd4b2ed477a7 100644 --- a/src/Text/Pandoc/App/OutputSettings.hs +++ b/src/Text/Pandoc/App/OutputSettings.hs @@ -238,6 +238,8 @@ optToOutputSettings scriptingEngine opts = do , writerExtensions = writerExts , writerReferenceLinks = optReferenceLinks opts , writerReferenceLocation = optReferenceLocation opts + , writerFigureCaptionPosition = optFigureCaptionPosition opts + , writerTableCaptionPosition = optTableCaptionPosition opts , writerDpi = optDpi opts , writerWrapText = optWrap opts , writerColumns = optColumns opts diff --git a/src/Text/Pandoc/Options.hs b/src/Text/Pandoc/Options.hs index e4ff56b7741a..c19a8318fa6e 100644 --- a/src/Text/Pandoc/Options.hs +++ b/src/Text/Pandoc/Options.hs @@ -28,6 +28,7 @@ module Text.Pandoc.Options ( module Text.Pandoc.Extensions , WriterOptions (..) , TrackChanges (..) , ReferenceLocation (..) + , CaptionPosition (..) , def , isEnabled , defaultMathJaxURL @@ -286,6 +287,22 @@ instance ToJSON ReferenceLocation where toJSON EndOfSection = "end-of-section" toJSON EndOfDocument = "end-of-document" +-- | Positions for figure and table captions +data CaptionPosition = CaptionAbove -- ^ above figure or table + | CaptionBelow -- ^ below figure or table + deriving (Show, Read, Eq, Data, Typeable, Generic) + +instance FromJSON CaptionPosition where + parseJSON v = + case v of + String "above" -> return CaptionAbove + String "below" -> return CaptionBelow + _ -> fail $ "Unknown caption position " <> toStringLazy (encode v) + +instance ToJSON CaptionPosition where + toJSON CaptionAbove = "above" + toJSON CaptionBelow = "below" + -- | Options for writers data WriterOptions = WriterOptions { writerTemplate :: Maybe (Template Text) -- ^ Template to use @@ -323,6 +340,8 @@ data WriterOptions = WriterOptions , writerTOCDepth :: Int -- ^ Number of levels to include in TOC , writerReferenceDoc :: Maybe FilePath -- ^ Path to reference document if specified , writerReferenceLocation :: ReferenceLocation -- ^ Location of footnotes and references for writing markdown + , writerFigureCaptionPosition :: CaptionPosition -- ^ Position of figure caption + , writerTableCaptionPosition :: CaptionPosition -- ^ Position of table caption , writerSyntaxMap :: SyntaxMap , writerPreferAscii :: Bool -- ^ Prefer ASCII representations of characters when possible , writerLinkImages :: Bool -- ^ Use links rather than embedding ODT images @@ -362,6 +381,8 @@ instance Default WriterOptions where , writerTOCDepth = 3 , writerReferenceDoc = Nothing , writerReferenceLocation = EndOfDocument + , writerFigureCaptionPosition = CaptionBelow + , writerTableCaptionPosition = CaptionAbove , writerSyntaxMap = defaultSyntaxMap , writerPreferAscii = False , writerLinkImages = False diff --git a/src/Text/Pandoc/Writers/Docx/OpenXML.hs b/src/Text/Pandoc/Writers/Docx/OpenXML.hs index fadaedb5ce2b..07030e3c1ff6 100644 --- a/src/Text/Pandoc/Writers/Docx/OpenXML.hs +++ b/src/Text/Pandoc/Writers/Docx/OpenXML.hs @@ -455,7 +455,10 @@ blockToOpenXML' opts (Figure (ident, _, _) (Caption _ longcapt) body) = do (Para xs : bs) -> imageCaption (fstCaptionPara xs : bs) (Plain xs : bs) -> imageCaption (fstCaptionPara xs : bs) _ -> imageCaption longcapt - wrapBookmark ident $ contentsNode : captionNode + wrapBookmark ident $ + case writerFigureCaptionPosition opts of + CaptionBelow -> contentsNode : captionNode + CaptionAbove -> captionNode ++ [contentsNode] toFigureTable :: PandocMonad m => WriterOptions -> [Block] -> WS m Content diff --git a/src/Text/Pandoc/Writers/Docx/Table.hs b/src/Text/Pandoc/Writers/Docx/Table.hs index d866265fe486..b66e98617ddd 100644 --- a/src/Text/Pandoc/Writers/Docx/Table.hs +++ b/src/Text/Pandoc/Writers/Docx/Table.hs @@ -46,7 +46,7 @@ import Text.Pandoc.Writers.Docx.Types withParaPropM ) import Control.Monad.Reader (asks) import Text.Pandoc.Shared ( tshow, stringify ) -import Text.Pandoc.Options (WriterOptions, isEnabled) +import Text.Pandoc.Options (WriterOptions(..), isEnabled, CaptionPosition(..)) import Text.Pandoc.Extensions (Extension(Ext_native_numbering)) import Text.Pandoc.Error (PandocError(PandocSomeError)) import Text.Printf (printf) @@ -134,7 +134,10 @@ tableToOpenXML opts blocksToOpenXML gridTable = do : head' ++ mconcat bodies ++ foot' ) modify $ \s -> s { stInTable = False } - return $ captionXml ++ [Elem tbl] + return $ + case writerTableCaptionPosition opts of + CaptionAbove -> captionXml ++ [Elem tbl] + CaptionBelow -> Elem tbl : captionXml addLabel :: Text -> Text -> Int -> [Block] -> [Block] addLabel tableid tablename tablenum bs = diff --git a/src/Text/Pandoc/Writers/HTML.hs b/src/Text/Pandoc/Writers/HTML.hs index efb85c08b8ae..076f11d7a8c5 100644 --- a/src/Text/Pandoc/Writers/HTML.hs +++ b/src/Text/Pandoc/Writers/HTML.hs @@ -446,6 +446,8 @@ pandocToHtml opts (Pandoc meta blocks) = do defField "slideous-url" ("slideous" :: Doc Text) . defField "revealjs-url" ("https://unpkg.com/reveal.js@^4/" :: Doc Text) $ defField "s5-url" ("s5/default" :: Doc Text) . + defField "table-caption-below" + (writerTableCaptionPosition opts == CaptionBelow) . defField "html5" (stHtml5 st) $ metadata return (thebody, context) @@ -1056,24 +1058,26 @@ blockToHtmlInner opts (Figure attrs (Caption _ captBody) body) = do figAttrs <- attrsToHtml opts attrs contents <- blockListToHtml opts body - figCaption <- if null captBody - then return mempty - else do - captCont <- blockListToHtml opts captBody - return . mconcat $ + captCont <- blockListToHtml opts captBody + let figCaption = mconcat $ if html5 then let fcattr = if captionIsAlt captBody body then H5.customAttribute (textTag "aria-hidden") (toValue @Text "true") else mempty - in [ H5.figcaption ! fcattr $ captCont, nl ] - else [ (H.div ! A.class_ "figcaption") captCont, nl ] + in [ H5.figcaption ! fcattr $ captCont ] + else [ (H.div ! A.class_ "figcaption") captCont ] + let innards = mconcat $ + if null captBody + then [nl, contents, nl] + else case writerFigureCaptionPosition opts of + CaptionAbove -> [nl, figCaption, nl, contents, nl] + CaptionBelow -> [nl, contents, nl, figCaption, nl] return $ if html5 - then foldl (!) H5.figure figAttrs $ mconcat [nl, contents, nl, figCaption] - else foldl (!) H.div (A.class_ "float" : figAttrs) $ mconcat - [nl, contents, nl, figCaption] + then foldl (!) H5.figure figAttrs innards + else foldl (!) H.div (A.class_ "float" : figAttrs) innards where captionIsAlt capt [Plain [Image (_, _, kv) desc _]] = let alt = fromMaybe (stringify desc) $ lookup "alt" kv diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs index 18bc15f3d49b..76d180d35085 100644 --- a/src/Text/Pandoc/Writers/LaTeX.hs +++ b/src/Text/Pandoc/Writers/LaTeX.hs @@ -605,6 +605,7 @@ blockToLaTeX (Table attr blkCapt specs thead tbodies tfoot) = tableToLaTeX inlineListToLaTeX blockListToLaTeX (Ann.toTable attr blkCapt specs thead tbodies tfoot) blockToLaTeX (Figure (ident, _, _) captnode body) = do + opts <- gets stOptions (capt, captForLof, footnotes) <- getCaption inlineListToLaTeX True captnode lab <- labelFor ident let caption = "\\caption" <> captForLof <> braces capt <> lab @@ -615,7 +616,10 @@ blockToLaTeX (Figure (ident, _, _) captnode body) = do [b] -> blockToLaTeX b bs -> mconcat . intersperse (cr <> "\\hfill") <$> mapM (toSubfigure (length bs)) bs - let innards = "\\centering" $$ contents $$ caption <> cr + let innards = "\\centering" $$ + (case writerFigureCaptionPosition opts of + CaptionBelow -> contents $$ caption + CaptionAbove -> caption $$ contents) <> cr modify $ \st -> st{ stInFigure = isSubfigure , stSubfigure = stSubfigure st || isSubfigure diff --git a/src/Text/Pandoc/Writers/LaTeX/Table.hs b/src/Text/Pandoc/Writers/LaTeX/Table.hs index db01b95790be..47e1785373c7 100644 --- a/src/Text/Pandoc/Writers/LaTeX/Table.hs +++ b/src/Text/Pandoc/Writers/LaTeX/Table.hs @@ -33,11 +33,12 @@ import Text.Pandoc.Writers.LaTeX.Caption (getCaption) import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX) import Text.Pandoc.Writers.LaTeX.Types ( LW, WriterState (stBeamer, stExternalNotes, stInMinipage, stMultiRow - , stNotes, stTable) ) + , stNotes, stTable, stOptions) ) import Text.Pandoc.Writers.LaTeX.Util (labelFor) import Text.Printf (printf) import qualified Text.Pandoc.Builder as B import qualified Text.Pandoc.Writers.AnnotatedTable as Ann +import Text.Pandoc.Options (CaptionPosition(..), WriterOptions(..)) tableToLaTeX :: PandocMonad m => ([Inline] -> LW m (Doc Text)) @@ -45,8 +46,13 @@ tableToLaTeX :: PandocMonad m -> Ann.Table -> LW m (Doc Text) tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do + opts <- gets stOptions let (Ann.Table (ident, _, _) caption specs thead tbodies tfoot) = tbl CaptionDocs capt captNotes <- captionToLaTeX inlnsToLaTeX caption ident + let hasTopCaption = not (isEmpty capt) && + writerTableCaptionPosition opts == CaptionAbove + let hasBottomCaption = not (isEmpty capt) && + writerTableCaptionPosition opts == CaptionBelow let isSimpleTable = all ((== ColWidthDefault) . snd) specs && all (all isSimpleCell) @@ -64,24 +70,31 @@ tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do -- duplicate the header rows for this. head' <- do let mkHead = headToLaTeX blksToLaTeX isSimpleTable colCount - case (not $ isEmpty capt, not $ isEmptyHead thead) of - (False, False) -> return "\\toprule\\noalign{}" - (False, True) -> mkHead thead - (True, False) -> return (capt $$ "\\toprule\\noalign{}" $$ "\\endfirsthead") - (True, True) -> do + case (hasTopCaption, isEmptyHead thead) of + (False, True) -> return "\\toprule\\noalign{}" + (False, False) -> mkHead thead + (True, True) -> return (capt <> "\\tabularnewline" + $$ "\\toprule\\noalign{}" + $$ "\\endfirsthead") + (True, False) -> do -- avoid duplicate notes in head and firsthead: firsthead <- mkHead thead repeated <- mkHead (walk removeNote thead) - return $ capt $$ firsthead $$ "\\endfirsthead" $$ repeated + return $ capt <> "\\tabularnewline" + $$ firsthead + $$ "\\endfirsthead" + $$ repeated rows' <- mapM (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $ mconcat (map bodyRows tbodies) - foot' <- if isEmptyFoot tfoot - then pure empty - else do - lastfoot <- mapM - (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $ - footRows tfoot - pure $ "\\midrule\\noalign{}" $$ vcat lastfoot + lastfoot <- mapM (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $ + footRows tfoot + let foot' = (if isEmptyFoot tfoot + then mempty + else "\\midrule\\noalign{}" $$ vcat lastfoot) + $$ "\\bottomrule\\noalign{}" + $$ (if hasBottomCaption + then "\\tabularnewline" $$ capt + else mempty) modify $ \s -> s{ stTable = True } notes <- notesToLaTeX <$> gets stNotes beamer <- gets stBeamer @@ -99,10 +112,8 @@ tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do (if beamer then [ vcat rows' , foot' - , "\\bottomrule\\noalign{}" ] else [ foot' - , "\\bottomrule\\noalign{}" , "\\endlastfoot" , vcat rows' ]) @@ -192,7 +203,6 @@ captionToLaTeX inlnsToLaTeX caption ident = do else "\\caption" <> captForLot <> braces captionText <> label - <> "\\tabularnewline" } type BlocksWriter m = [Block] -> LW m (Doc Text) diff --git a/src/Text/Pandoc/Writers/OpenDocument.hs b/src/Text/Pandoc/Writers/OpenDocument.hs index b2b4b2ee910c..8238bf288947 100644 --- a/src/Text/Pandoc/Writers/OpenDocument.hs +++ b/src/Text/Pandoc/Writers/OpenDocument.hs @@ -396,13 +396,14 @@ blockToOpenDocument o = \case Left msg -> do unless (T.null msg) $ report $ CouldNotHighlight msg unhighlighted s - Table a bc s th tb tf -> setFirstPara >> table (Ann.toTable a bc s th tb tf) + Table a bc s th tb tf -> setFirstPara >> + table o (Ann.toTable a bc s th tb tf) HorizontalRule -> setFirstPara >> return (selfClosingTag "text:p" [ ("text:style-name", "Horizontal_20_Line") ]) b@(RawBlock f s) -> if f == Format "opendocument" then return $ text $ T.unpack s else empty <$ report (BlockNotRendered b) - Figure a capt b -> figure a capt b + Figure a capt b -> figure o a capt b where defList b = do setInDefinitionList True r <- vcat <$> mapM (deflistItemToOpenDocument o) b @@ -427,8 +428,9 @@ blockToOpenDocument o = \case orderedList a b = do (ln,pn) <- newOrderedListStyle (isTightList b) a inTags True "text:list" [ ("text:style-name", "L" <> tshow ln)] <$> orderedListToOpenDocument o pn b - table :: PandocMonad m => Ann.Table -> OD m (Doc Text) - table (Ann.Table (ident, _, _) (Caption _ c) colspecs thead tbodies _) = do + table :: PandocMonad m => WriterOptions -> Ann.Table -> OD m (Doc Text) + table opts + (Ann.Table (ident, _, _) (Caption _ c) colspecs thead tbodies _) = do tn <- length <$> gets stTableStyles pn <- length <$> gets stParaStyles let genIds = map chr [65..] @@ -458,8 +460,11 @@ blockToOpenDocument o = \case ("table:name" , name) , ("table:style-name", name) ] (vcat columns $$ th $$ vcat tr) - return $ captionDoc $$ tableDoc - figure (ident, _, _) (Caption _ longcapt) body = + return $ + case writerTableCaptionPosition opts of + CaptionAbove -> captionDoc $$ tableDoc + CaptionBelow -> tableDoc $$ captionDoc + figure opts (ident, _, _) (Caption _ longcapt) body = case blocksToInlines longcapt of [] -> withParagraphStyle o "Figure" body @@ -470,7 +475,10 @@ blockToOpenDocument o = \case if isEnabled Ext_native_numbering o then numberedFigureCaption ident else unNumberedCaption "FigureCaption" - return $ imageDoc $$ captionDoc + return $ + case writerFigureCaptionPosition opts of + CaptionAbove -> captionDoc $$ imageDoc + CaptionBelow -> imageDoc $$ captionDoc numberedTableCaption :: PandocMonad m => Text -> Doc Text -> OD m (Doc Text) diff --git a/src/Text/Pandoc/Writers/Typst.hs b/src/Text/Pandoc/Writers/Typst.hs index b4e8d20a4c31..6def6d150557 100644 --- a/src/Text/Pandoc/Writers/Typst.hs +++ b/src/Text/Pandoc/Writers/Typst.hs @@ -18,7 +18,8 @@ module Text.Pandoc.Writers.Typst ( ) where import Text.Pandoc.Definition import Text.Pandoc.Class ( PandocMonad) -import Text.Pandoc.Options ( WriterOptions(..), WrapOption(..), isEnabled ) +import Text.Pandoc.Options ( WriterOptions(..), WrapOption(..), isEnabled, + CaptionPosition(..) ) import Data.Text (Text) import Data.List (intercalate, intersperse) import Data.Bifunctor (first, second) @@ -67,6 +68,9 @@ pandocToTypst options (Pandoc meta blocks) = do (fmap chomp . inlinesToTypst) meta main <- blocksToTypst blocks + let toPosition :: CaptionPosition -> Text + toPosition CaptionAbove = "top" + toPosition CaptionBelow = "bottom" let context = defField "body" main $ defField "toc" (writerTableOfContents options) $ (if isEnabled Ext_citations options @@ -81,6 +85,10 @@ pandocToTypst options (Pandoc meta blocks) = do resetField "lang" (langLanguage l) . maybe id (resetField "region") (langRegion l)) $ defField "toc-depth" (tshow $ writerTOCDepth options) + $ defField "figure-caption-position" + (toPosition $ writerFigureCaptionPosition options) + $ defField "table-caption-position" + (toPosition $ writerTableCaptionPosition options) $ (if writerNumberSections options then defField "numbering" ("1.1.1.1.1" :: Text) else id) diff --git a/test/command/5116.md b/test/command/5116.md new file mode 100644 index 000000000000..ac49286591f1 --- /dev/null +++ b/test/command/5116.md @@ -0,0 +1,107 @@ +``` +% pandoc -t latex +![This is a figure.](img.jpg) + + Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 + + : Demonstration of simple table syntax. +^D +\begin{figure} +\centering +\pandocbounded{\includegraphics[keepaspectratio]{img.jpg}} +\caption{This is a figure.} +\end{figure} + +\begin{longtable}[]{@{}rlcl@{}} +\caption{Demonstration of simple table syntax.}\tabularnewline +\toprule\noalign{} +Right & Left & Center & Default \\ +\midrule\noalign{} +\endfirsthead +\toprule\noalign{} +Right & Left & Center & Default \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +12 & 12 & 12 & 12 \\ +123 & 123 & 123 & 123 \\ +1 & 1 & 1 & 1 \\ +\end{longtable} + +``` + +``` +% pandoc -t latex --figure-caption-position=above --table-caption-position=above +![This is a figure.](img.jpg) + + Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 + + : Demonstration of simple table syntax. +^D +\begin{figure} +\centering +\caption{This is a figure.} +\pandocbounded{\includegraphics[keepaspectratio]{img.jpg}} +\end{figure} + +\begin{longtable}[]{@{}rlcl@{}} +\caption{Demonstration of simple table syntax.}\tabularnewline +\toprule\noalign{} +Right & Left & Center & Default \\ +\midrule\noalign{} +\endfirsthead +\toprule\noalign{} +Right & Left & Center & Default \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\endlastfoot +12 & 12 & 12 & 12 \\ +123 & 123 & 123 & 123 \\ +1 & 1 & 1 & 1 \\ +\end{longtable} + +``` + +``` +% pandoc -t latex --figure-caption-position=below --table-caption-position=below +![This is a figure.](img.jpg) + + Right Left Center Default +------- ------ ---------- ------- + 12 12 12 12 + 123 123 123 123 + 1 1 1 1 + + : Demonstration of simple table syntax. +^D +\begin{figure} +\centering +\pandocbounded{\includegraphics[keepaspectratio]{img.jpg}} +\caption{This is a figure.} +\end{figure} + +\begin{longtable}[]{@{}rlcl@{}} +\toprule\noalign{} +Right & Left & Center & Default \\ +\midrule\noalign{} +\endhead +\bottomrule\noalign{} +\tabularnewline +\caption{Demonstration of simple table syntax.} +\endlastfoot +12 & 12 & 12 & 12 \\ +123 & 123 & 123 & 123 \\ +1 & 1 & 1 & 1 \\ +\end{longtable} + +``` diff --git a/test/writer.typst b/test/writer.typst index 91d600c81906..7609e0db01b3 100644 --- a/test/writer.typst +++ b/test/writer.typst @@ -20,6 +20,14 @@ stroke: none ) +#show figure.where( + kind: table +): set figure.caption(position: top) + +#show figure.where( + kind: image +): set figure.caption(position: bottom) + #let content-to-string(content) = { if content.has("text") { content.text