From f16e43ebf203630f65c80abb55151cfaab1e61f1 Mon Sep 17 00:00:00 2001 From: Karl Engelhardt Date: Fri, 9 Nov 2018 12:14:19 +0100 Subject: [PATCH] Add option to specify table env. in LaTeX output This commit adds a command line switch (`--latex-table-environment`) for switching between possible table environments. Currently pandoc is hardcoded to use `longtable`, which allows for multi-page-tables. This commit adds support for the tabularx environment (allowing columns that span over the while remaining table-width) and gives the possibility to easily add new environments in the future. --- MANUAL.txt | 22 ++++++++++--- data/templates/default.latex | 2 +- src/Text/Pandoc/App/CommandLineOptions.hs | 11 +++++++ src/Text/Pandoc/App/Opt.hs | 6 +++- src/Text/Pandoc/Options.hs | 15 ++++++++- src/Text/Pandoc/Writers/LaTeX.hs | 38 ++++++++++++++++++----- 6 files changed, 78 insertions(+), 16 deletions(-) diff --git a/MANUAL.txt b/MANUAL.txt index 50df6edbb2ea..f4207635cec6 100644 --- a/MANUAL.txt +++ b/MANUAL.txt @@ -921,7 +921,7 @@ Options affecting specific writers {.options} : Use the [`listings`] package for LaTeX code blocks. The package does not support multi-byte encoding for source code. To handle UTF-8 - you would need to use a custom template. This issue is fully + you would need to use a custom template. This issue is fully documented here: [Encoding issue with the listings package]. `-i`, `--incremental` @@ -1148,10 +1148,18 @@ Options affecting specific writers {.options} If used multiple times, the arguments are provided with spaces between them. Note that no check for duplicate options is done. +`--latex-table-environment=longtable`|`tabularx` + +: Use the specified table environment when producing LaTeX output. + The default is [`longtable`] which allows table to spread over multiple pages. + [`tabularx`] allows for paragraph-like columns whose width automatically expand to fill the width of the environment. + [Dublin Core elements]: http://dublincore.org/documents/dces/ [ISO 8601 format]: http://www.w3.org/TR/NOTE-datetime [Encoding issue with the listings package]: https://en.wikibooks.org/wiki/LaTeX/Source_Code_Listings#Encoding_issue +[`longtable`]: https://ctan.org/pkg/longtable +[`tabularx`]: https://ctan.org/pkg/tabularx Citation rendering {.options} ------------------ @@ -1599,6 +1607,10 @@ LaTeX variables are used when [creating a PDF]. supports 'plain' (default), 'empty', and 'headings'; headings puts section titles in the header. +`table_environment` +: The environemnt given by `--latex-table-environment` + + [`article`]: https://ctan.org/pkg/article [`report`]: https://ctan.org/pkg/report [`book`]: https://ctan.org/pkg/book @@ -4484,7 +4496,7 @@ the [Beamer User's Guide] may also be used: `allowdisplaybreaks`, Background in reveal.js and beamer ---------------------------------- -Background images can be added to self-contained reveal.js slideshows and +Background images can be added to self-contained reveal.js slideshows and to beamer slideshows. For the same image on every slide, use the configuration @@ -4492,9 +4504,9 @@ option `background-image` either in the YAML metadata block or as a command-line variable. (There are no other options in beamer and the rest of this section concerns reveal.js slideshows.) -For reveal.js, you can instead use the reveal.js-native option -`parallaxBackgroundImage`. You can also set `parallaxBackgroundHorizontal` -and `parallaxBackgroundVertical` the same way and must also set +For reveal.js, you can instead use the reveal.js-native option +`parallaxBackgroundImage`. You can also set `parallaxBackgroundHorizontal` +and `parallaxBackgroundVertical` the same way and must also set `parallaxBackgroundSize` to have your values take effect. To set an image for a particular reveal.js slide, add diff --git a/data/templates/default.latex b/data/templates/default.latex index 737ebaa447cf..0440905e6831 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -214,7 +214,7 @@ $if(highlighting-macros)$ $highlighting-macros$ $endif$ $if(tables)$ -\usepackage{longtable,booktabs} +\usepackage{$table-environment$,booktabs} $if(beamer)$ \usepackage{caption} % These lines are needed to make table captions work with longtable: diff --git a/src/Text/Pandoc/App/CommandLineOptions.hs b/src/Text/Pandoc/App/CommandLineOptions.hs index 0881920210d1..56eb523116d0 100644 --- a/src/Text/Pandoc/App/CommandLineOptions.hs +++ b/src/Text/Pandoc/App/CommandLineOptions.hs @@ -850,6 +850,17 @@ options = UTF8.hPutStr stdout (usageMessage prg options) exitSuccess )) "" -- "Show help" + , Option "" ["latex-table-class"] + (ReqArg + (\arg opt -> + case toLower <$> arg of + "longtable" -> return opt { optLatexTableEnvironment = Longtable } + "tabularx" -> return opt { optLatexTableEnvironment = Tabularx } + -- mac-syntax (cr) is not supported in ghc-base. + _ -> E.throwIO $ PandocOptionError + "--latex-table-class must be longtable or tabularx") + "longtable|tabularx") + "" -- "EOL (default OS-dependent)" ] getDataFileNames :: IO [FilePath] diff --git a/src/Text/Pandoc/App/Opt.hs b/src/Text/Pandoc/App/Opt.hs index 5ef7efaa09e1..a44c266ea848 100644 --- a/src/Text/Pandoc/App/Opt.hs +++ b/src/Text/Pandoc/App/Opt.hs @@ -48,7 +48,8 @@ import Text.Pandoc.Options (TopLevelDivision (TopLevelDefault), WrapOption (WrapAuto), HTMLMathMethod (PlainMath), ReferenceLocation (EndOfDocument), ObfuscationMethod (NoObfuscation), - CiteMethod (Citeproc)) + CiteMethod (Citeproc), + LatexTableEnvironment (Longtable)) #ifdef DERIVE_JSON_VIA_TH import Data.Aeson.TH (deriveJSON, defaultOptions) @@ -130,6 +131,7 @@ data Opt = Opt , optRequestHeaders :: [(String, String)] -- ^ Headers for HTTP requests , optEol :: LineEnding -- ^ Style of line-endings to use , optStripComments :: Bool -- ^ Skip HTML comments + , optLatexTableEnvironment :: LatexTableEnvironment } deriving (Generic, Show) -- | Defaults for command-line options. @@ -203,6 +205,8 @@ defaultOpts = Opt , optRequestHeaders = [] , optEol = Native , optStripComments = False + , optLatexTableEnvironment = Longtable + } #ifdef DERIVE_JSON_VIA_TH diff --git a/src/Text/Pandoc/Options.hs b/src/Text/Pandoc/Options.hs index cea365ab4374..59d3f314aab7 100644 --- a/src/Text/Pandoc/Options.hs +++ b/src/Text/Pandoc/Options.hs @@ -48,6 +48,7 @@ module Text.Pandoc.Options ( module Text.Pandoc.Extensions , WriterOptions (..) , TrackChanges (..) , ReferenceLocation (..) + , LatexTableEnvironment (..) , def , isEnabled ) where @@ -168,6 +169,11 @@ data ReferenceLocation = EndOfBlock -- ^ End of block | EndOfDocument -- ^ at end of document deriving (Show, Read, Eq, Data, Typeable, Generic) +-- | Class of tables to use in LaTeX output +data LatexTableEnvironment = Longtable -- ^ Use longtable for tables + | Tabularx -- ^ Use tabularx tables + deriving (Show, Read, Eq, Data, Typeable, Generic) + -- | Options for writers data WriterOptions = WriterOptions { writerTemplate :: Maybe String -- ^ Template to use @@ -204,7 +210,8 @@ data WriterOptions = WriterOptions , writerReferenceLocation :: ReferenceLocation -- ^ Location of footnotes and references for writing markdown , writerSyntaxMap :: SyntaxMap , writerPreferAscii :: Bool -- ^ Prefer ASCII representations of characters when possible - } deriving (Show, Data, Typeable, Generic) + , writerLatexTableEnvironment :: LatexTableEnvironment +} deriving (Show, Data, Typeable, Generic) instance Default WriterOptions where def = WriterOptions { writerTemplate = Nothing @@ -239,6 +246,7 @@ instance Default WriterOptions where , writerReferenceLocation = EndOfDocument , writerSyntaxMap = defaultSyntaxMap , writerPreferAscii = False + , writerLatexTableEnvironment = Longtable } instance HasSyntaxExtensions WriterOptions where @@ -258,6 +266,7 @@ $(deriveJSON defaultOptions ''TrackChanges) $(deriveJSON defaultOptions ''WrapOption) $(deriveJSON defaultOptions ''TopLevelDivision) $(deriveJSON defaultOptions ''ReferenceLocation) +$(deriveJSON defaultOptions ''LatexTableEnvironment) #else instance ToJSON CiteMethod where toEncoding = genericToEncoding defaultOptions @@ -294,4 +303,8 @@ instance FromJSON ReferenceLocation instance ToJSON TrackChanges where toEncoding = genericToEncoding defaultOptions instance FromJSON TrackChanges + +instance ToJSON LatexTableEnvironment where + toEncoding = genericToEncoding defaultOptions +instance FromJSON LatexTableEnvironment #endif diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs index 480c973565bc..ca7d0f8a20fc 100644 --- a/src/Text/Pandoc/Writers/LaTeX.hs +++ b/src/Text/Pandoc/Writers/LaTeX.hs @@ -257,6 +257,8 @@ pandocToLaTeX options (Pandoc meta blocks) = do else defField "dir" ("ltr" :: String)) $ defField "section-titles" True $ defField "geometry" geometryFromMargins $ + defField "table-environment" (latexTableEnvironment + (writerLatexTableEnvironment options)) $ (case getField "papersize" metadata of -- uppercase a4, a5, etc. Just (('A':d:ds) :: String) @@ -775,6 +777,7 @@ blockToLaTeX (Header level (id',classes,_) lst) = do modify $ \s -> s{stInHeading = False} return hdr blockToLaTeX (Table caption aligns widths heads rows) = do + opts <- gets stOptions (captionText, captForLof, footnotes) <- getCaption caption let toHeaders hs = do contents <- tableRowToLaTeX True aligns widths hs return ("\\toprule" $$ contents $$ "\\midrule") @@ -794,20 +797,30 @@ blockToLaTeX (Table caption aligns widths heads rows) = do else "\\caption" <> captForLof <> braces captionText <> "\\tabularnewline" rows' <- mapM (tableRowToLaTeX False aligns widths) rows - let colDescriptors = text $ concatMap toColDescriptor aligns modify $ \s -> s{ stTable = True } - return $ "\\begin{longtable}[]" <> - braces ("@{}" <> colDescriptors <> "@{}") - -- the @{} removes extra space at beginning and end + return $ beginTable (writerLatexTableEnvironment opts) aligns $$ capt $$ firsthead $$ head' $$ "\\endhead" $$ vcat rows' $$ "\\bottomrule" - $$ "\\end{longtable}" + $$ endTable (writerLatexTableEnvironment opts) $$ footnotes +beginTable :: LatexTableEnvironment -> [Alignment] -> Doc +beginTable tableEnvironment aligns = do + let colsWithIndices = case tableEnvironment of + Longtable -> map ((,) 0) aligns + Tabularx -> zip [0..] aligns + let colDescriptors = text $ concatMap toColDescriptor colsWithIndices + case tableEnvironment of + Longtable -> text "\\begin{longtable}[]" <> + braces ("@{}" <> colDescriptors <> "@{}") + Tabularx -> text "\\begin{tabularx}{\\linewidth}" <> + braces ("@{}" <> colDescriptors <> "@{}") + -- the @{} removes extra space at beginning and end + getCaption :: PandocMonad m => [Inline] -> LW m (Doc, Doc, Doc) getCaption txt = do inMinipage <- gets stInMinipage @@ -822,13 +835,22 @@ getCaption txt = do let footnotes = notesToLaTeX notes return (capt, captForLof, footnotes) -toColDescriptor :: Alignment -> String -toColDescriptor align = +endTable :: LatexTableEnvironment -> Doc +endTable tableEnvironment = text "\\end{" <> + text (latexTableEnvironment tableEnvironment) <> "}" + +toColDescriptor :: (Integer, Alignment) -> String +toColDescriptor (index, align) = case align of AlignLeft -> "l" AlignRight -> "r" AlignCenter -> "c" - AlignDefault -> "l" + AlignDefault -> if index == 0 then "l" else "X" + +latexTableEnvironment :: LatexTableEnvironment -> String +latexTableEnvironment tableEnvironment = case tableEnvironment of + Longtable -> "longtable" + Tabularx -> "tabularx" blockListToLaTeX :: PandocMonad m => [Block] -> LW m Doc blockListToLaTeX lst =