mirror of
https://github.com/jgm/pandoc.git
synced 2026-09-12 18:45:58 +00:00
LaTeX writer: Provide a way to use table instead of longtable.
When the `float` class is attached to a table, a standard floating `table` will be generated instead of a `longtable`. Placement can be specified via the `latex-placement` attribute. This will help, especially, those who use two-column layouts, since `longtable` is incompatible with these. Small change to the default LaTeX template: the `caption` package is included and a default spacing set between the caption and the table. Closes #1023.
This commit is contained in:
+18
-2
@@ -138,8 +138,8 @@ When using LaTeX, the following packages need to be available
|
||||
[`amsfonts`], [`amsmath`], [`lm`], [`unicode-math`],
|
||||
[`iftex`], [`listings`] (if the
|
||||
`--listings` option is used), [`fancyvrb`], [`longtable`],
|
||||
[`booktabs`], [`multirow`] (if the document contains a table with
|
||||
cells that cross multiple rows), [`graphicx`] (if the document
|
||||
[`caption`], [`booktabs`], [`multirow`] (if the document contains a table
|
||||
with cells that cross multiple rows), [`graphicx`] (if the document
|
||||
contains images), [`bookmark`], [`xcolor`],
|
||||
[`soul`], [`geometry`] (with the `geometry` variable set),
|
||||
[`setspace`] (with `linestretch`), and
|
||||
@@ -191,6 +191,7 @@ better line breaks in URLs), and [`footnotehyper`] or
|
||||
[`lua-ul`]: https://ctan.org/pkg/lua-ul
|
||||
[`luatexja`]: https://ctan.org/pkg/luatexja
|
||||
[`longtable`]: https://ctan.org/pkg/longtable
|
||||
[`caption`]: https://ctan.org/pkg/caption
|
||||
[`mathspec`]: https://ctan.org/pkg/mathspec
|
||||
[`microtype`]: https://ctan.org/pkg/microtype
|
||||
[`multirow`]: https://ctan.org/pkg/multirow
|
||||
@@ -5005,6 +5006,21 @@ of the caption. (For the syntax, see
|
||||
|
||||
: Here's the caption. {#ident .class key="value"}
|
||||
|
||||
### Table placement in LaTeX ###
|
||||
|
||||
By default, pandoc will render tables in LaTeX using the `longtable`
|
||||
environment. The tables will not "float" and they can span page boundaries.
|
||||
If you prefer standard "floating" tables (which are limited to what can
|
||||
fit on one page), add the `float` class to the table's attributes
|
||||
(which can be specified after the caption). Optionally, the `latex-placement`
|
||||
attribute may be used to pass parameters affecting the float placement:
|
||||
|
||||
: The caption of the table. {#ident .float latex-placement="ht"}
|
||||
|
||||
Note that `longtable` does not work with two-column layouts, so if you
|
||||
are producing a two-column document using LaTeX, you will need to specify
|
||||
the `float` class on every table (or use a Lua filter to add it automatically).
|
||||
|
||||
## Metadata blocks
|
||||
|
||||
### Extension: `pandoc_title_block` ###
|
||||
|
||||
@@ -69,6 +69,8 @@ $-- tables
|
||||
$--
|
||||
$if(tables)$
|
||||
\usepackage{longtable,booktabs,array}
|
||||
\usepackage{caption}
|
||||
\captionsetup[table]{skip=6pt}
|
||||
\newcounter{none} % for unnumbered tables
|
||||
$if(multirow)$
|
||||
\usepackage{multirow}
|
||||
|
||||
@@ -305,6 +305,8 @@ tex2pdf program args tmpDir source = do
|
||||
x | "! Package inputenc Error" `BC.isPrefixOf` x
|
||||
&& program /= "xelatex"
|
||||
-> "\nTry running pandoc with --pdf-engine=xelatex."
|
||||
"! Package longtable Error: longtable not in 1-column mode."
|
||||
-> "\nTry adding the .float class attribute to your tables."
|
||||
_ -> ""
|
||||
return $ Left $ logmsg <> extramsg
|
||||
(ExitSuccess, Nothing) -> return $ Left ""
|
||||
|
||||
@@ -56,7 +56,7 @@ import Text.Pandoc.Shared
|
||||
import Text.Pandoc.URI
|
||||
import Text.Pandoc.Slides
|
||||
import Text.Pandoc.Walk (query, walk, walkM)
|
||||
import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
|
||||
import Text.Pandoc.Writers.LaTeX.Util (getAccumulatedNotes)
|
||||
import Text.Pandoc.Writers.LaTeX.Caption (getCaption)
|
||||
import Text.Pandoc.Writers.LaTeX.Table (tableToLaTeX)
|
||||
import Text.Pandoc.Writers.LaTeX.Citation (citationsToNatbib,
|
||||
@@ -65,7 +65,7 @@ import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState (..), startingState,
|
||||
PdfStandard (..))
|
||||
import Text.Pandoc.Writers.LaTeX.Lang (toBabel)
|
||||
import Text.Pandoc.Writers.LaTeX.Util (stringToLaTeX, StringContext(..),
|
||||
toLabel, inCmd,
|
||||
toLabel, inCmd, withExternalNotes,
|
||||
wrapDiv, hypertarget, labelFor,
|
||||
getListingsLanguage, mbBraced)
|
||||
import Text.Pandoc.Writers.Shared
|
||||
@@ -663,7 +663,7 @@ blockToLaTeX (DefinitionList lst) = do
|
||||
let spacing = if all (isTightList . snd) lst
|
||||
then text "\\tightlist"
|
||||
else empty
|
||||
notes <- notesToLaTeX <$> gets stNotes
|
||||
notes <- getAccumulatedNotes
|
||||
return $ text ("\\begin{description}" <> inc) $$ spacing $$ vcat items $$
|
||||
"\\end{description}" $$ notes
|
||||
blockToLaTeX HorizontalRule =
|
||||
@@ -679,7 +679,7 @@ blockToLaTeX (Table attr blkCapt specs thead tbodies tfoot) =
|
||||
(Ann.toTable attr blkCapt specs thead tbodies tfoot)
|
||||
blockToLaTeX (Figure (ident, _, kvs) captnode body) = do
|
||||
opts <- gets stOptions
|
||||
(capt, captForLof, footnotes) <- getCaption inlineListToLaTeX True captnode
|
||||
(capt, captForLof) <- withExternalNotes $ getCaption inlineListToLaTeX captnode
|
||||
lab <- labelFor ident
|
||||
let caption = "\\caption" <> captForLof <> braces capt <> lab
|
||||
placement = case lookup "latex-placement" kvs of
|
||||
@@ -705,6 +705,7 @@ blockToLaTeX (Figure (ident, _, kvs) captnode body) = do
|
||||
Table {} -> Any True
|
||||
_ -> Any False)
|
||||
st <- get
|
||||
footnotes <- getAccumulatedNotes
|
||||
return $ (case () of
|
||||
_ | containsTable body ->
|
||||
-- placing a longtable in a figure or center environment does
|
||||
@@ -764,10 +765,9 @@ listItemToLaTeX isOrdered lst
|
||||
defListItemToLaTeX :: PandocMonad m => ([Inline], [[Block]]) -> LW m (Doc Text)
|
||||
defListItemToLaTeX (term, defs) = do
|
||||
-- needed to turn off 'listings' because it breaks inside \item[...]:
|
||||
oldExternalNotes <- gets stExternalNotes
|
||||
modify $ \s -> s{stInItem = True, stExternalNotes = True}
|
||||
term' <- inlineListToLaTeX term
|
||||
modify $ \s -> s{stInItem = False, stExternalNotes = oldExternalNotes}
|
||||
modify $ \s -> s{ stInItem = True }
|
||||
term' <- withExternalNotes $ inlineListToLaTeX term
|
||||
modify $ \s -> s{ stInItem = False }
|
||||
-- put braces around term if it contains an internal link,
|
||||
-- since otherwise we get bad bracket interactions: \item[\hyperref[..]
|
||||
let isInternalLink (Link _ _ (src,_))
|
||||
|
||||
@@ -21,29 +21,20 @@ import Text.Pandoc.Definition
|
||||
import Text.DocLayout (Doc, brackets, empty)
|
||||
import Text.Pandoc.Shared
|
||||
import Text.Pandoc.Walk
|
||||
import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
|
||||
import Text.Pandoc.Writers.LaTeX.Types
|
||||
( LW, WriterState (stExternalNotes, stNotes, stInCaption) )
|
||||
import Text.Pandoc.Writers.LaTeX.Types ( LW, WriterState (stInCaption) )
|
||||
|
||||
|
||||
-- | Produces the components of a LaTeX 'caption' command. Returns a triple
|
||||
-- containing the caption text, the short caption for the list of
|
||||
-- figures/tables, and the footnote definitions.
|
||||
-- | Produces the components of a LaTeX 'caption' command. Returns a pair
|
||||
-- containing the caption text and the short caption for the list of
|
||||
-- figures/tables.
|
||||
getCaption :: PandocMonad m
|
||||
=> ([Inline] -> LW m (Doc Text)) -- ^ inlines converter
|
||||
-> Bool -- ^ whether to extract notes
|
||||
-> Caption
|
||||
-> LW m (Doc Text, Doc Text, Doc Text)
|
||||
getCaption inlineListToLaTeX externalNotes (Caption maybeShort long) = do
|
||||
-> LW m (Doc Text, Doc Text)
|
||||
getCaption inlineListToLaTeX (Caption maybeShort long) = do
|
||||
modify $ \st -> st{ stInCaption = True }
|
||||
let long' = blocksToInlines long
|
||||
oldExternalNotes <- gets stExternalNotes
|
||||
modify $ \st -> st{ stExternalNotes = externalNotes, stNotes = [] }
|
||||
capt <- inlineListToLaTeX long'
|
||||
footnotes <- if externalNotes
|
||||
then notesToLaTeX <$> gets stNotes
|
||||
else return empty
|
||||
modify $ \st -> st{ stExternalNotes = oldExternalNotes, stNotes = [] }
|
||||
-- We can't have footnotes in the list of figures/tables, so remove them:
|
||||
let getNote (Note _) = Any True
|
||||
getNote _ = Any False
|
||||
@@ -55,4 +46,4 @@ getCaption inlineListToLaTeX externalNotes (Caption maybeShort long) = do
|
||||
else return empty
|
||||
Just short -> toShortCapt short
|
||||
modify $ \st -> st{ stInCaption = False }
|
||||
return (capt, captForLof, footnotes)
|
||||
return (capt, captForLof)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
{-# LANGUAGE LambdaCase #-}
|
||||
{-# LANGUAGE OverloadedStrings #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{-# LANGUAGE FlexibleContexts #-}
|
||||
{- |
|
||||
Module : Text.Pandoc.Writers.LaTeX.Table
|
||||
Copyright : Copyright (C) 2006-2024 John MacFarlane
|
||||
@@ -24,17 +26,17 @@ import qualified Data.Text as T
|
||||
import Text.Pandoc.Class.PandocMonad (PandocMonad)
|
||||
import Text.Pandoc.Definition
|
||||
import Text.DocLayout
|
||||
( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest
|
||||
, text, vcat, ($$) )
|
||||
( Doc, braces, brackets, cr, empty, hcat, hsep, isEmpty, literal, nest
|
||||
, text, vcat, ($$))
|
||||
import Text.Pandoc.Shared (splitBy, tshow)
|
||||
import Text.Pandoc.Walk (walk, query)
|
||||
import Data.Monoid (Any(..))
|
||||
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, stOptions) )
|
||||
import Text.Pandoc.Writers.LaTeX.Util (labelFor)
|
||||
( LW, WriterState (stBeamer, stInMinipage, stMultiRow
|
||||
, stTable, stOptions) )
|
||||
import Text.Pandoc.Writers.LaTeX.Util (labelFor, withExternalNotes,
|
||||
getAccumulatedNotes)
|
||||
import Text.Printf (printf)
|
||||
import qualified Text.Pandoc.Builder as B
|
||||
import qualified Text.Pandoc.Writers.AnnotatedTable as Ann
|
||||
@@ -46,30 +48,103 @@ tableToLaTeX :: PandocMonad m
|
||||
-> Ann.Table
|
||||
-> LW m (Doc Text)
|
||||
tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do
|
||||
let (Ann.Table (ident, classes, kvs) caption specs thead tbodies tfoot) = tbl
|
||||
let placement = brackets $ maybe mempty (text . T.unpack)
|
||||
$ lookup "latex-placement" kvs
|
||||
-- if the float class is included in table attributes, we generate a floating
|
||||
-- table environment; otherwise we use longtable
|
||||
beamer <- gets stBeamer
|
||||
let float = "float" `elem` classes
|
||||
let renderTable = do
|
||||
capt <- captionToLaTeX inlnsToLaTeX caption ident
|
||||
let isSimpleTable =
|
||||
all ((== ColWidthDefault) . snd) specs &&
|
||||
all (all isSimpleCell)
|
||||
(mconcat [ headRows thead
|
||||
, concatMap bodyRows tbodies
|
||||
, footRows tfoot
|
||||
])
|
||||
let colDesc' = colDescriptors isSimpleTable tbl
|
||||
let colDesc = braces ("@{}" <> colDesc' <> "@{}")
|
||||
-- the @{} removes extra space at beginning and end
|
||||
let colCount = ColumnCount $ length specs
|
||||
let mkHead = headToLaTeX blksToLaTeX isSimpleTable colCount
|
||||
let mkRow = rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell
|
||||
if float
|
||||
then tableToLaTeXTable placement colDesc mkHead mkRow capt thead tbodies tfoot
|
||||
else tableToLaTeXLongtable colDesc mkHead mkRow capt thead tbodies tfoot
|
||||
-- See #5367 -- footnotehyper/footnote don't work in beamer,
|
||||
-- so we need to produce the notes outside the table...
|
||||
if float || beamer
|
||||
then ($$) <$> withExternalNotes renderTable <*> getAccumulatedNotes
|
||||
else renderTable
|
||||
|
||||
tableToLaTeXTable :: PandocMonad m
|
||||
=> Doc Text
|
||||
-> Doc Text
|
||||
-> (Ann.TableHead -> LW m (Doc Text))
|
||||
-> ([Ann.Cell] -> LW m (Doc Text))
|
||||
-> Doc Text
|
||||
-> Ann.TableHead
|
||||
-> [Ann.TableBody]
|
||||
-> Ann.TableFoot
|
||||
-> LW m (Doc Text)
|
||||
tableToLaTeXTable placement colDesc mkHead mkRow capt thead tbodies tfoot = do
|
||||
opts <- gets stOptions
|
||||
let hasTopCaption = not (isEmpty capt) &&
|
||||
writerTableCaptionPosition opts == CaptionAbove
|
||||
let hasBottomCaption = not (isEmpty capt) &&
|
||||
writerTableCaptionPosition opts == CaptionBelow
|
||||
head' <- if isEmptyHead thead
|
||||
then return "\\toprule\\noalign{}"
|
||||
else mkHead thead
|
||||
rows' <- mapM mkRow $ mconcat (map bodyRows tbodies)
|
||||
lastfoot <- mapM mkRow $ footRows tfoot
|
||||
let foot' = (if isEmptyFoot tfoot
|
||||
then mempty
|
||||
else "\\midrule\\noalign{}" $$ vcat lastfoot)
|
||||
$$ "\\bottomrule\\noalign{}"
|
||||
modify $ \s -> s{ stTable = True }
|
||||
let makeUnnumbered x = "{\\def\\LTcaptype{none} % do not increment counter" $$ x $$ "}"
|
||||
return
|
||||
$ (if null capt then makeUnnumbered else id)
|
||||
$ "\\begin{table}" <> placement
|
||||
$$ "\\centering"
|
||||
$$ (if hasTopCaption
|
||||
then capt <> "\\tabularnewline"
|
||||
else mempty)
|
||||
$$ "\\begin{tabular}" <> colDesc
|
||||
$$ head'
|
||||
$$ vcat rows'
|
||||
$$ foot'
|
||||
$$ "\\end{tabular}"
|
||||
$$ (if hasBottomCaption
|
||||
then capt <> "\\tabularnewline"
|
||||
else mempty)
|
||||
$$ "\\end{table}"
|
||||
|
||||
|
||||
tableToLaTeXLongtable :: PandocMonad m
|
||||
=> Doc Text
|
||||
-> (Ann.TableHead -> LW m (Doc Text))
|
||||
-> ([Ann.Cell] -> LW m (Doc Text))
|
||||
-> Doc Text
|
||||
-> Ann.TableHead
|
||||
-> [Ann.TableBody]
|
||||
-> Ann.TableFoot
|
||||
-> LW m (Doc Text)
|
||||
tableToLaTeXLongtable colDesc mkHead mkRow capt thead tbodies tfoot = 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)
|
||||
(mconcat [ headRows thead
|
||||
, concatMap bodyRows tbodies
|
||||
, footRows tfoot
|
||||
])
|
||||
let removeNote (Note _) = Span ("", [], []) []
|
||||
removeNote x = x
|
||||
let colCount = ColumnCount $ length specs
|
||||
-- The first head is not repeated on the following pages. If we were to just
|
||||
-- use a single head, without a separate first head, then the caption would be
|
||||
-- repeated on all pages that contain a part of the table. We avoid this by
|
||||
-- making the caption part of the first head. The downside is that we must
|
||||
-- duplicate the header rows for this.
|
||||
head' <- do
|
||||
let mkHead = headToLaTeX blksToLaTeX isSimpleTable colCount
|
||||
case (hasTopCaption, isEmptyHead thead) of
|
||||
(False, True) -> return "\\toprule\\noalign{}"
|
||||
(False, False) -> mkHead thead
|
||||
@@ -79,15 +154,15 @@ tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do
|
||||
(True, False) -> do
|
||||
-- avoid duplicate notes in head and firsthead:
|
||||
firsthead <- mkHead thead
|
||||
let removeNote (Note _) = Span ("", [], []) []
|
||||
removeNote x = x
|
||||
repeated <- mkHead (walk removeNote thead)
|
||||
return $ capt <> "\\tabularnewline"
|
||||
$$ firsthead
|
||||
$$ "\\endfirsthead"
|
||||
$$ repeated
|
||||
rows' <- mapM (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $
|
||||
mconcat (map bodyRows tbodies)
|
||||
lastfoot <- mapM (rowToLaTeX blksToLaTeX isSimpleTable colCount BodyCell) $
|
||||
footRows tfoot
|
||||
rows' <- mapM mkRow $ mconcat (map bodyRows tbodies)
|
||||
lastfoot <- mapM mkRow $ footRows tfoot
|
||||
let foot' = (if isEmptyFoot tfoot
|
||||
then mempty
|
||||
else "\\midrule\\noalign{}" $$ vcat lastfoot)
|
||||
@@ -96,14 +171,11 @@ tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do
|
||||
then "\\tabularnewline" $$ capt
|
||||
else mempty)
|
||||
modify $ \s -> s{ stTable = True }
|
||||
notes <- notesToLaTeX <$> gets stNotes
|
||||
beamer <- gets stBeamer
|
||||
let makeUnnumbered x = "{\\def\\LTcaptype{none} % do not increment counter" $$ x $$ "}"
|
||||
return
|
||||
$ (if null capt then makeUnnumbered else id)
|
||||
$ "\\begin{longtable}[]" <>
|
||||
braces ("@{}" <> colDescriptors isSimpleTable tbl <> "@{}")
|
||||
-- the @{} removes extra space at beginning and end
|
||||
$ "\\begin{longtable}[]" <> colDesc
|
||||
$$ head'
|
||||
$$ "\\endhead"
|
||||
$$ vcat
|
||||
@@ -120,8 +192,6 @@ tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do
|
||||
, vcat rows'
|
||||
])
|
||||
$$ "\\end{longtable}"
|
||||
$$ captNotes
|
||||
$$ notes
|
||||
|
||||
isSimpleCell :: Ann.Cell -> Bool
|
||||
isSimpleCell (Ann.Cell _ _ (Cell _attr _align _rowspan _colspan blocks)) =
|
||||
@@ -184,28 +254,18 @@ colAlign = \case
|
||||
AlignCenter -> "c"
|
||||
AlignDefault -> "l"
|
||||
|
||||
data CaptionDocs =
|
||||
CaptionDocs
|
||||
{ captionCommand :: Doc Text
|
||||
, captionNotes :: Doc Text
|
||||
}
|
||||
|
||||
captionToLaTeX :: PandocMonad m
|
||||
=> ([Inline] -> LW m (Doc Text))
|
||||
-> Caption
|
||||
-> Text -- ^ table identifier (label)
|
||||
-> LW m CaptionDocs
|
||||
-> LW m (Doc Text)
|
||||
captionToLaTeX inlnsToLaTeX caption ident = do
|
||||
(captionText, captForLot, captNotes) <- getCaption inlnsToLaTeX False caption
|
||||
(captionText, captForLot) <- getCaption inlnsToLaTeX caption
|
||||
label <- labelFor ident
|
||||
return $ CaptionDocs
|
||||
{ captionNotes = captNotes
|
||||
, captionCommand = if isEmpty captionText && isEmpty label
|
||||
then empty
|
||||
else "\\caption" <> captForLot <>
|
||||
braces captionText
|
||||
<> label
|
||||
}
|
||||
return $ if isEmpty captionText && isEmpty label
|
||||
then empty
|
||||
else "\\caption" <> captForLot <>
|
||||
braces captionText <> label
|
||||
|
||||
type BlocksWriter m = [Block] -> LW m (Doc Text)
|
||||
|
||||
@@ -322,11 +382,6 @@ cellToLaTeX blockListToLaTeX isSimpleTable colCount celltype annotatedCell = do
|
||||
let align = case align' of
|
||||
AlignDefault -> specAlign
|
||||
_ -> align'
|
||||
beamer <- gets stBeamer
|
||||
externalNotes <- gets stExternalNotes
|
||||
-- See #5367 -- footnotehyper/footnote don't work in beamer,
|
||||
-- so we need to produce the notes outside the table...
|
||||
modify $ \st -> st{ stExternalNotes = beamer }
|
||||
let isPlainOrPara = \case
|
||||
Para{} -> True
|
||||
Plain{} -> True
|
||||
@@ -352,7 +407,6 @@ cellToLaTeX blockListToLaTeX isSimpleTable colCount celltype annotatedCell = do
|
||||
(if hasLineBreaks then "\\strut" else mempty)
|
||||
<> cr <>
|
||||
"\\end{minipage}"
|
||||
modify $ \st -> st{ stExternalNotes = externalNotes }
|
||||
when (rowspan /= RowSpan 1) $
|
||||
modify (\st -> st{ stMultiRow = True })
|
||||
let inMultiColumn x = case colspan of
|
||||
|
||||
@@ -18,6 +18,8 @@ module Text.Pandoc.Writers.LaTeX.Util (
|
||||
, labelFor
|
||||
, getListingsLanguage
|
||||
, mbBraced
|
||||
, withExternalNotes
|
||||
, getAccumulatedNotes
|
||||
)
|
||||
where
|
||||
|
||||
@@ -27,6 +29,7 @@ import Text.Pandoc.Class (PandocMonad, toLang)
|
||||
import Text.Pandoc.Options (WriterOptions(..), isEnabled)
|
||||
import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState(..))
|
||||
import Text.Pandoc.Writers.LaTeX.Lang (toBabel)
|
||||
import Text.Pandoc.Writers.LaTeX.Notes (notesToLaTeX)
|
||||
import Text.Pandoc.Highlighting (toListingsLanguage)
|
||||
import Text.DocLayout
|
||||
import Text.Pandoc.Definition
|
||||
@@ -285,3 +288,20 @@ mbBraced :: Text -> Text
|
||||
mbBraced x = if not (T.all isAlphaNum x)
|
||||
then "{" <> x <> "}"
|
||||
else x
|
||||
|
||||
withExternalNotes :: PandocMonad m
|
||||
=> LW m a
|
||||
-> LW m a
|
||||
withExternalNotes p = do
|
||||
oldExternalNotes <- gets stExternalNotes
|
||||
modify $ \st -> st{ stExternalNotes = True }
|
||||
res <- p
|
||||
modify $ \st -> st{ stExternalNotes = oldExternalNotes }
|
||||
return res
|
||||
|
||||
getAccumulatedNotes :: PandocMonad m
|
||||
=> LW m (Doc Text)
|
||||
getAccumulatedNotes = do
|
||||
res <- notesToLaTeX <$> gets stNotes
|
||||
modify $ \st -> st{ stNotes = [] }
|
||||
return res
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
```
|
||||
% pandoc -t latex
|
||||
: Here's the caption.
|
||||
It may span multiple lines. {.float #ident latex-placement="ht"}
|
||||
|
||||
---------------------------------------------------------------
|
||||
Centered Left Right
|
||||
Header Aligned Aligned Default aligned
|
||||
---------- --------- ----------- ---------------------------
|
||||
First row 12.0 Example of a row that spans
|
||||
multiple lines.
|
||||
|
||||
Second row 5.0 Here's another one. Note
|
||||
the blank line between rows.
|
||||
---------------------------------------------------------------
|
||||
^D
|
||||
\begin{table}[ht]
|
||||
\centering
|
||||
\caption{Here's the caption. It may span multiple
|
||||
lines.}\label{ident}\tabularnewline
|
||||
\begin{tabular}{@{}
|
||||
>{\centering\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1667}}
|
||||
>{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1528}}
|
||||
>{\raggedleft\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.1806}}
|
||||
>{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.3889}}@{}}
|
||||
\toprule\noalign{}
|
||||
\begin{minipage}[b]{\linewidth}\centering
|
||||
Centered Header
|
||||
\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
|
||||
Left Aligned
|
||||
\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedleft
|
||||
Right Aligned
|
||||
\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
|
||||
Default aligned
|
||||
\end{minipage} \\
|
||||
\midrule\noalign{}
|
||||
First & row & 12.0 & Example of a row that spans multiple lines. \\
|
||||
Second & row & 5.0 & Here's another one. Note the blank line between
|
||||
rows. \\
|
||||
\bottomrule\noalign{}
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
% pandoc -t latex
|
||||
: Simple table with no column headers {.float #ident}
|
||||
|
||||
------- ------ ---------- -------
|
||||
12 12 12 12
|
||||
123 123 123 123
|
||||
1 1 1 1
|
||||
------- ------ ---------- -------
|
||||
^D
|
||||
\begin{table}[]
|
||||
\centering
|
||||
\caption{Simple table with no column
|
||||
headers}\label{ident}\tabularnewline
|
||||
\begin{tabular}{@{}rlcr@{}}
|
||||
\toprule\noalign{}
|
||||
12 & 12 & 12 & 12 \\
|
||||
123 & 123 & 123 & 123 \\
|
||||
1 & 1 & 1 & 1 \\
|
||||
\bottomrule\noalign{}
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
|
||||
```
|
||||
|
||||
```
|
||||
% pandoc -t latex
|
||||
+--------------------+---------------------+---------------+---------------+
|
||||
| Name^[In English.] | Capital | Population\ | Area\ |
|
||||
| | | (in 2018) | (in km^2^) |
|
||||
+:==================:+:====================+:==============+:==============+
|
||||
| Denmark | Copenhagen | 5,809,502 | 43,094 |
|
||||
+--------------------+---------------------+---------------+---------------+
|
||||
| Finland | Helsinki | 5,537,364 | 338,145 |
|
||||
+--------------------+---------------------+---------------+---------------+
|
||||
| Iceland^[Brrr.] | Reykjavik | 343,518 | 103,000 |
|
||||
+--------------------+---------------------+---------------+---------------+
|
||||
| Norway | Oslo | 5,372,191 | 323,802 |
|
||||
+--------------------+---------------------+---------------+---------------+
|
||||
| Sweden | Stockholm | 10,313,447 | 450,295 |
|
||||
+====================+=====================+===============+===============+
|
||||
| Total | | 27,376,022 | 1,258,336 |
|
||||
+====================+=====================+===============+===============+
|
||||
|
||||
: States belonging to the *Nordics.* {#nordics source="wikipedia" .float}
|
||||
^D
|
||||
\begin{table}[]
|
||||
\centering
|
||||
\caption{States belonging to the
|
||||
\emph{Nordics.}}\label{nordics}\tabularnewline
|
||||
\begin{tabular}{@{}
|
||||
>{\centering\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2727}}
|
||||
>{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2857}}
|
||||
>{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2078}}
|
||||
>{\raggedright\arraybackslash}p{(\linewidth - 6\tabcolsep) * \real{0.2078}}@{}}
|
||||
\toprule\noalign{}
|
||||
\begin{minipage}[b]{\linewidth}\centering
|
||||
Name\footnotemark{}
|
||||
\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
|
||||
Capital
|
||||
\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
|
||||
Population\\
|
||||
(in 2018)\strut
|
||||
\end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
|
||||
Area\\
|
||||
(in km\textsuperscript{2})\strut
|
||||
\end{minipage} \\
|
||||
\midrule\noalign{}
|
||||
Denmark & Copenhagen & 5,809,502 & 43,094 \\
|
||||
Finland & Helsinki & 5,537,364 & 338,145 \\
|
||||
Iceland\footnotemark{} & Reykjavik & 343,518 & 103,000 \\
|
||||
Norway & Oslo & 5,372,191 & 323,802 \\
|
||||
Sweden & Stockholm & 10,313,447 & 450,295 \\
|
||||
\midrule\noalign{}
|
||||
Total & & 27,376,022 & 1,258,336 \\
|
||||
\bottomrule\noalign{}
|
||||
\end{tabular}
|
||||
\end{table}
|
||||
\addtocounter{footnote}{-1}
|
||||
\footnotetext{In English.}
|
||||
\addtocounter{footnote}{1}
|
||||
\footnotetext{Brrr.}
|
||||
|
||||
```
|
||||
Reference in New Issue
Block a user