diff --git a/data/templates/default.latex b/data/templates/default.latex index 169661582..c567278e3 100644 --- a/data/templates/default.latex +++ b/data/templates/default.latex @@ -255,6 +255,9 @@ $highlighting-macros$ $endif$ $if(tables)$ \usepackage{longtable,booktabs,array} +$if(multirow)$ +\usepackage{multirow} +$endif$ \usepackage{calc} % for calculating minipage widths $if(beamer)$ \usepackage{caption} diff --git a/pandoc.cabal b/pandoc.cabal index 8a4faa3e1..4a893d672 100644 --- a/pandoc.cabal +++ b/pandoc.cabal @@ -299,6 +299,7 @@ extra-source-files: test/tables.xwiki test/tables/*.html4 test/tables/*.html5 + test/tables/*.latex test/tables/*.native test/tables/*.jats_archiving test/testsuite.txt diff --git a/src/Text/Pandoc/Writers/AnnotatedTable.hs b/src/Text/Pandoc/Writers/AnnotatedTable.hs index 48c9d61f2..3f69496a9 100644 --- a/src/Text/Pandoc/Writers/AnnotatedTable.hs +++ b/src/Text/Pandoc/Writers/AnnotatedTable.hs @@ -1,8 +1,12 @@ {-# LANGUAGE BangPatterns #-} {-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE FlexibleContexts #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} +{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TupleSections #-} +{-# LANGUAGE UndecidableInstances #-} {- | Module : Text.Pandoc.Writers.AnnotatedTable @@ -45,6 +49,7 @@ import Data.Generics ( Data import Data.List.NonEmpty ( NonEmpty(..) ) import GHC.Generics ( Generic ) import qualified Text.Pandoc.Builder as B +import Text.Pandoc.Walk ( Walkable (..) ) -- | An annotated table type, corresponding to the Pandoc 'B.Table' -- constructor and the HTML @\@ element. It records the data @@ -298,3 +303,21 @@ fromBodyRow (BodyRow attr _ rh rb) = fromCell :: Cell -> B.Cell fromCell (Cell _ _ c) = c + +-- +-- Instances +-- +instance Walkable a B.Cell => Walkable a Cell where + walkM f (Cell colspecs colnum cell) = + Cell colspecs colnum <$> walkM f cell + query f (Cell _colspecs _colnum cell) = query f cell + +instance Walkable a B.Cell => Walkable a HeaderRow where + walkM f (HeaderRow attr rownum cells) = + HeaderRow attr rownum <$> walkM f cells + query f (HeaderRow _attr _rownum cells) = query f cells + +instance Walkable a B.Cell => Walkable a TableHead where + walkM f (TableHead attr rows) = + TableHead attr <$> walkM f rows + query f (TableHead _attr rows) = query f rows diff --git a/src/Text/Pandoc/Writers/LaTeX.hs b/src/Text/Pandoc/Writers/LaTeX.hs index 6a4e3ba69..2281290c0 100644 --- a/src/Text/Pandoc/Writers/LaTeX.hs +++ b/src/Text/Pandoc/Writers/LaTeX.hs @@ -48,6 +48,7 @@ import Text.Pandoc.Writers.LaTeX.Types (LW, WriterState (..), startingState) import Text.Pandoc.Writers.Shared import Text.Printf (printf) import qualified Data.Text.Normalize as Normalize +import qualified Text.Pandoc.Writers.AnnotatedTable as Ann -- | Convert Pandoc to LaTeX. writeLaTeX :: PandocMonad m => WriterOptions -> Pandoc -> m Text @@ -154,6 +155,7 @@ pandocToLaTeX options (Pandoc meta blocks) = do defField "documentclass" documentClass $ defField "verbatim-in-note" (stVerbInNote st) $ defField "tables" (stTable st) $ + defField "multirow" (stMultiRow st) $ defField "strikeout" (stStrikeout st) $ defField "url" (stUrl st) $ defField "numbersections" (writerNumberSections options) $ @@ -716,9 +718,9 @@ blockToLaTeX (Header level (id',classes,_) lst) = do hdr <- sectionHeader classes id' level lst modify $ \s -> s{stInHeading = False} return hdr -blockToLaTeX (Table _ blkCapt specs thead tbodies tfoot) = +blockToLaTeX (Table attr blkCapt specs thead tbodies tfoot) = tableToLaTeX inlineListToLaTeX blockListToLaTeX - blkCapt specs thead tbodies tfoot + (Ann.toTable attr blkCapt specs thead tbodies tfoot) blockListToLaTeX :: PandocMonad m => [Block] -> LW m (Doc Text) blockListToLaTeX lst = diff --git a/src/Text/Pandoc/Writers/LaTeX/Table.hs b/src/Text/Pandoc/Writers/LaTeX/Table.hs index 5299efa37..9dd66c8a3 100644 --- a/src/Text/Pandoc/Writers/LaTeX/Table.hs +++ b/src/Text/Pandoc/Writers/LaTeX/Table.hs @@ -16,6 +16,7 @@ module Text.Pandoc.Writers.LaTeX.Table ) where import Control.Monad.State.Strict import Data.List (intersperse) +import Data.List.NonEmpty (NonEmpty ((:|))) import Data.Text (Text) import qualified Data.Text as T import Text.Pandoc.Class.PandocMonad (PandocMonad) @@ -23,102 +24,196 @@ import Text.Pandoc.Definition import Text.DocLayout ( Doc, braces, cr, empty, hcat, hsep, isEmpty, literal, nest , text, vcat, ($$) ) -import Text.Pandoc.Shared (splitBy) +import Text.Pandoc.Shared (blocksToInlines, splitBy, tshow) import Text.Pandoc.Walk (walk) -import Text.Pandoc.Writers.Shared (toLegacyTable) 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, stNotes, stTable) ) + ( LW, WriterState (stBeamer, stExternalNotes, stInMinipage, stMultiRow + , stNotes, stTable) ) import Text.Printf (printf) +import qualified Text.Pandoc.Builder as B +import qualified Text.Pandoc.Writers.AnnotatedTable as Ann tableToLaTeX :: PandocMonad m => ([Inline] -> LW m (Doc Text)) -> ([Block] -> LW m (Doc Text)) - -> Caption -> [ColSpec] -> TableHead -> [TableBody] -> TableFoot + -> Ann.Table -> LW m (Doc Text) -tableToLaTeX inlnsToLaTeX blksToLaTeX blkCapt specs thead tbody tfoot = do - let (caption, aligns, widths, heads, rows) = - toLegacyTable blkCapt specs thead tbody tfoot - -- simple tables have to have simple cells: - let isSimple = \case - [Plain _] -> True - [Para _] -> True - [] -> True - _ -> False - let widths' = if all (== 0) widths && not (all (all isSimple) rows) - then replicate (length aligns) - (1 / fromIntegral (length aligns)) - else widths - (captionText, captForLof, captNotes) <- getCaption inlnsToLaTeX False caption - let toHeaders hs = do contents <- tableRowToLaTeX blksToLaTeX True aligns hs - return ("\\toprule" $$ contents $$ "\\midrule") +tableToLaTeX inlnsToLaTeX blksToLaTeX tbl = do + let (Ann.Table _attr caption _specs thead tbodies tfoot) = tbl + CaptionDocs capt captNotes <- captionToLaTeX inlnsToLaTeX caption let removeNote (Note _) = Span ("", [], []) [] removeNote x = x - firsthead <- if isEmpty captionText || all null heads - then return empty - else ($$ text "\\endfirsthead") <$> toHeaders heads - head' <- if all null heads - then return "\\toprule" - -- avoid duplicate notes in head and firsthead: - else toHeaders (if isEmpty firsthead - then heads - else walk removeNote heads) - let capt = if isEmpty captionText - then empty - else "\\caption" <> captForLof <> braces captionText - <> "\\tabularnewline" - rows' <- mapM (tableRowToLaTeX blksToLaTeX False aligns) rows - let colDescriptors = - (if all (== 0) widths' - then hcat . map literal - else (\xs -> cr <> nest 2 (vcat $ map literal xs))) $ - zipWith (toColDescriptor (length widths')) aligns widths' + firsthead <- if isEmpty capt || isEmptyHead thead + then return empty + else ($$ text "\\endfirsthead") <$> + headToLaTeX blksToLaTeX thead + head' <- if isEmptyHead thead + then return "\\toprule" + -- avoid duplicate notes in head and firsthead: + else headToLaTeX blksToLaTeX + (if isEmpty firsthead + then thead + else walk removeNote thead) + rows' <- mapM (rowToLaTeX blksToLaTeX BodyCell) $ + mconcat (map bodyRows tbodies) <> footRows tfoot modify $ \s -> s{ stTable = True } notes <- notesToLaTeX <$> gets stNotes - return $ "\\begin{longtable}[]" <> - braces ("@{}" <> colDescriptors <> "@{}") - -- the @{} removes extra space at beginning and end - $$ capt - $$ firsthead - $$ head' - $$ "\\endhead" - $$ vcat rows' - $$ "\\bottomrule" - $$ "\\end{longtable}" - $$ captNotes - $$ notes + return + $ "\\begin{longtable}[]" <> + braces ("@{}" <> colDescriptors tbl <> "@{}") + -- the @{} removes extra space at beginning and end + $$ capt + $$ firsthead + $$ head' + $$ "\\endhead" + $$ vcat rows' + $$ "\\bottomrule" + $$ "\\end{longtable}" + $$ captNotes + $$ notes -toColDescriptor :: Int -> Alignment -> Double -> Text -toColDescriptor _numcols align 0 = - case align of - AlignLeft -> "l" - AlignRight -> "r" - AlignCenter -> "c" - AlignDefault -> "l" -toColDescriptor numcols align width = - T.pack $ printf - ">{%s\\arraybackslash}p{(\\columnwidth - %d\\tabcolsep) * \\real{%0.2f}}" - align' - ((numcols - 1) * 2) - width - where - align' :: String - align' = case align of - AlignLeft -> "\\raggedright" - AlignRight -> "\\raggedleft" - AlignCenter -> "\\centering" - AlignDefault -> "\\raggedright" +-- | Creates column descriptors for the table. +colDescriptors :: Ann.Table -> Doc Text +colDescriptors (Ann.Table _attr _caption specs thead tbodies tfoot) = + let (aligns, widths) = unzip specs -tableRowToLaTeX :: PandocMonad m - => ([Block] -> LW m (Doc Text)) - -> Bool - -> [Alignment] - -> [[Block]] - -> LW m (Doc Text) -tableRowToLaTeX blockListToLaTeX header aligns cols = do - cells <- mapM (tableCellToLaTeX blockListToLaTeX header) $ zip aligns cols - return $ hsep (intersperse "&" cells) <> " \\\\ \\addlinespace" + defaultWidthsOnly = all (== ColWidthDefault) widths + isSimpleTable = all (all isSimpleCell) $ mconcat + [ headRows thead + , concatMap bodyRows tbodies + , footRows tfoot + ] + + relativeWidths = if defaultWidthsOnly + then replicate (length specs) + (1 / fromIntegral (length specs)) + else map toRelWidth widths + in if defaultWidthsOnly && isSimpleTable + then hcat $ map (literal . colAlign) aligns + else (cr <>) . nest 2 . vcat . map literal $ + zipWith (toColDescriptor (length specs)) + aligns + relativeWidths + where + toColDescriptor :: Int -> Alignment -> Double -> Text + toColDescriptor numcols align width = + T.pack $ printf + ">{%s\\arraybackslash}p{(\\columnwidth - %d\\tabcolsep) * \\real{%0.2f}}" + (T.unpack (alignCommand align)) + ((numcols - 1) * 2) + width + + isSimpleCell (Ann.Cell _ _ (Cell _attr _align _rowspan _colspan blocks)) = + case blocks of + [Para _] -> True + [Plain _] -> True + [] -> True + _ -> False + + toRelWidth ColWidthDefault = 0 + toRelWidth (ColWidth w) = w + +alignCommand :: Alignment -> Text +alignCommand = \case + AlignLeft -> "\\raggedright" + AlignRight -> "\\raggedleft" + AlignCenter -> "\\centering" + AlignDefault -> "\\raggedright" + +colAlign :: Alignment -> Text +colAlign = \case + AlignLeft -> "l" + AlignRight -> "r" + AlignCenter -> "c" + AlignDefault -> "l" + +data CaptionDocs = + CaptionDocs + { captionCommand :: Doc Text + , captionNotes :: Doc Text + } + +captionToLaTeX :: PandocMonad m + => ([Inline] -> LW m (Doc Text)) + -> Caption + -> LW m CaptionDocs +captionToLaTeX inlnsToLaTeX (Caption _maybeShort longCaption) = do + let caption = blocksToInlines longCaption + (captionText, captForLof, captNotes) <- getCaption inlnsToLaTeX False caption + return $ CaptionDocs + { captionNotes = captNotes + , captionCommand = if isEmpty captionText + then empty + else "\\caption" <> captForLof <> + braces captionText <> "\\tabularnewline" + } + +type BlocksWriter m = [Block] -> LW m (Doc Text) + +headToLaTeX :: PandocMonad m + => BlocksWriter m + -> Ann.TableHead + -> LW m (Doc Text) +headToLaTeX blocksWriter (Ann.TableHead _attr headerRows) = do + rowsContents <- mapM (rowToLaTeX blocksWriter HeaderCell . headerRowCells) + headerRows + return ("\\toprule" $$ vcat rowsContents $$ "\\midrule") + +-- | Converts a row of table cells into a LaTeX row. +rowToLaTeX :: PandocMonad m + => BlocksWriter m + -> CellType + -> [Ann.Cell] + -> LW m (Doc Text) +rowToLaTeX blocksWriter celltype row = do + cellsDocs <- mapM (cellToLaTeX blocksWriter celltype) (fillRow row) + return $ hsep (intersperse "&" cellsDocs) <> " \\\\ \\addlinespace" + +-- | Pads row with empty cells to adjust for rowspans above this row. +fillRow :: [Ann.Cell] -> [Ann.Cell] +fillRow = go 0 + where + go _ [] = [] + go n (acell@(Ann.Cell _spec (Ann.ColNumber colnum) cell):cells) = + let (Cell _ _ _ (ColSpan colspan) _) = cell + in map mkEmptyCell [n .. colnum - 1] ++ + acell : go (colnum + colspan) cells + + mkEmptyCell :: Int -> Ann.Cell + mkEmptyCell colnum = + Ann.Cell ((AlignDefault, ColWidthDefault):|[]) + (Ann.ColNumber colnum) + B.emptyCell + +isEmptyHead :: Ann.TableHead -> Bool +isEmptyHead (Ann.TableHead _attr []) = True +isEmptyHead (Ann.TableHead _attr rows) = all (null . headerRowCells) rows + +-- | Gets all cells in a header row. +headerRowCells :: Ann.HeaderRow -> [Ann.Cell] +headerRowCells (Ann.HeaderRow _attr _rownum cells) = cells + +-- | Gets all cells in a body row. +bodyRowCells :: Ann.BodyRow -> [Ann.Cell] +bodyRowCells (Ann.BodyRow _attr _rownum rowhead cells) = rowhead <> cells + +-- | Gets a list of rows of the table body, where a row is a simple +-- list of cells. +bodyRows :: Ann.TableBody -> [[Ann.Cell]] +bodyRows (Ann.TableBody _attr _rowheads headerRows rows) = + map headerRowCells headerRows <> map bodyRowCells rows + +-- | Gets a list of rows of the table head, where a row is a simple +-- list of cells. +headRows :: Ann.TableHead -> [[Ann.Cell]] +headRows (Ann.TableHead _attr rows) = map headerRowCells rows + +-- | Gets a list of rows from the foot, where a row is a simple list +-- of cells. +footRows :: Ann.TableFoot -> [[Ann.Cell]] +footRows (Ann.TableFoot _attr rows) = map headerRowCells rows -- For simple latex tables (without minipages or parboxes), -- we need to go to some lengths to get line breaks working: @@ -144,11 +239,14 @@ displayMathToInline :: Inline -> Inline displayMathToInline (Math DisplayMath x) = Math InlineMath x displayMathToInline x = x -tableCellToLaTeX :: PandocMonad m - => ([Block] -> LW m (Doc Text)) - -> Bool -> (Alignment, [Block]) - -> LW m (Doc Text) -tableCellToLaTeX blockListToLaTeX header (align, blocks) = do +cellToLaTeX :: PandocMonad m + => BlocksWriter m + -> CellType + -> Ann.Cell + -> LW m (Doc Text) +cellToLaTeX blockListToLaTeX celltype annotatedCell = do + let (Ann.Cell _specs _colnum cell) = annotatedCell + let (Cell _attr align rowspan colspan blocks) = cell beamer <- gets stBeamer externalNotes <- gets stExternalNotes inMinipage <- gets stInMinipage @@ -167,15 +265,30 @@ tableCellToLaTeX blockListToLaTeX header (align, blocks) = do modify $ \st -> st{ stInMinipage = True } cellContents <- blockListToLaTeX blocks modify $ \st -> st{ stInMinipage = inMinipage } - let valign = text $ if header then "[b]" else "[t]" - let halign = case align of - AlignLeft -> "\\raggedright" - AlignRight -> "\\raggedleft" - AlignCenter -> "\\centering" - AlignDefault -> "\\raggedright" + let valign = text $ case celltype of + HeaderCell -> "[b]" + BodyCell -> "[t]" + let halign = literal $ alignCommand align return $ "\\begin{minipage}" <> valign <> braces "\\linewidth" <> halign <> cr <> cellContents <> cr <> "\\end{minipage}" modify $ \st -> st{ stExternalNotes = externalNotes } - return result + when (rowspan /= RowSpan 1) $ + modify (\st -> st{ stMultiRow = True }) + let inMultiColumn x = case colspan of + (ColSpan 1) -> x + (ColSpan n) -> "\\multicolumn" + <> braces (literal (tshow n)) + <> braces (literal $ colAlign align) + <> braces x + let inMultiRow x = case rowspan of + (RowSpan 1) -> x + (RowSpan n) -> let nrows = literal (tshow n) + in "\\multirow" <> braces nrows + <> braces "*" <> braces x + return . inMultiColumn . inMultiRow $ result + +data CellType + = HeaderCell + | BodyCell diff --git a/src/Text/Pandoc/Writers/LaTeX/Types.hs b/src/Text/Pandoc/Writers/LaTeX/Types.hs index a76388729..d598794ad 100644 --- a/src/Text/Pandoc/Writers/LaTeX/Types.hs +++ b/src/Text/Pandoc/Writers/LaTeX/Types.hs @@ -31,6 +31,7 @@ data WriterState = -- be parameter , stVerbInNote :: Bool -- ^ true if document has verbatim text in note , stTable :: Bool -- ^ true if document has a table + , stMultiRow :: Bool -- ^ true if document has multirow cells , stStrikeout :: Bool -- ^ true if document has strikeout , stUrl :: Bool -- ^ true if document has visible URL link , stGraphics :: Bool -- ^ true if document contains images @@ -61,6 +62,7 @@ startingState options = , stOptions = options , stVerbInNote = False , stTable = False + , stMultiRow = False , stStrikeout = False , stUrl = False , stGraphics = False diff --git a/test/Tests/Old.hs b/test/Tests/Old.hs index aca2d05d0..cf0396d0a 100644 --- a/test/Tests/Old.hs +++ b/test/Tests/Old.hs @@ -58,7 +58,7 @@ tests pandocPath = ] , testGroup "latex" [ testGroup "writer" - (writerTests' "latex" ++ lhsWriterTests' "latex") + (extWriterTests' "latex" ++ lhsWriterTests' "latex") , testGroup "reader" [ test' "basic" ["-r", "latex+raw_tex", "-w", "native", "-s"] "latex-reader.latex" "latex-reader.native" diff --git a/test/tables/nordics.latex b/test/tables/nordics.latex new file mode 100644 index 000000000..d1a0b4aed --- /dev/null +++ b/test/tables/nordics.latex @@ -0,0 +1,26 @@ +\begin{longtable}[]{@{} + >{\centering\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.30}} + >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.30}} + >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.20}} + >{\raggedright\arraybackslash}p{(\columnwidth - 6\tabcolsep) * \real{0.20}}@{}} +\caption{States belonging to the \emph{Nordics.}}\tabularnewline +\toprule +Name & Capital & \vtop{\hbox{\strut Population}\hbox{\strut (in 2018)}} & +\vtop{\hbox{\strut Area}\hbox{\strut (in +km\textsuperscript{2})}} \\ \addlinespace +\midrule +\endfirsthead +\toprule +Name & Capital & \vtop{\hbox{\strut Population}\hbox{\strut (in 2018)}} & +\vtop{\hbox{\strut Area}\hbox{\strut (in +km\textsuperscript{2})}} \\ \addlinespace +\midrule +\endhead +Denmark & Copenhagen & 5,809,502 & 43,094 \\ \addlinespace +Finland & Helsinki & 5,537,364 & 338,145 \\ \addlinespace +Iceland & Reykjavik & 343,518 & 103,000 \\ \addlinespace +Norway & Oslo & 5,372,191 & 323,802 \\ \addlinespace +Sweden & Stockholm & 10,313,447 & 450,295 \\ \addlinespace +Total & & 27,376,022 & 1,258,336 \\ \addlinespace +\bottomrule +\end{longtable} diff --git a/test/tables/planets.latex b/test/tables/planets.latex new file mode 100644 index 000000000..9457b6821 --- /dev/null +++ b/test/tables/planets.latex @@ -0,0 +1,36 @@ +\begin{longtable}[]{@{}cclrrrrrrrrl@{}} +\caption{Data about the planets of our solar system.}\tabularnewline +\toprule +\multicolumn{2}{l}{} & Name & Mass (10\^{}24kg) & Diameter (km) & Density +(kg/m\^{}3) & Gravity (m/s\^{}2) & Length of day (hours) & Distance from Sun +(10\^{}6km) & Mean temperature (C) & Number of moons & Notes \\ \addlinespace +\midrule +\endfirsthead +\toprule +\multicolumn{2}{l}{} & Name & Mass (10\^{}24kg) & Diameter (km) & Density +(kg/m\^{}3) & Gravity (m/s\^{}2) & Length of day (hours) & Distance from Sun +(10\^{}6km) & Mean temperature (C) & Number of moons & Notes \\ \addlinespace +\midrule +\endhead +\multicolumn{2}{l}{\multirow{4}{*}{Terrestrial planets}} & Mercury & 0.330 & +4,879 & 5427 & 3.7 & 4222.6 & 57.9 & 167 & 0 & Closest to the +Sun \\ \addlinespace +& & Venus & 4.87 & 12,104 & 5243 & 8.9 & 2802.0 & 108.2 & 464 & 0 +& \\ \addlinespace +& & Earth & 5.97 & 12,756 & 5514 & 9.8 & 24.0 & 149.6 & 15 & 1 & Our +world \\ \addlinespace +& & Mars & 0.642 & 6,792 & 3933 & 3.7 & 24.7 & 227.9 & -65 & 2 & The red +planet \\ \addlinespace +\multirow{4}{*}{Jovian planets} & \multirow{2}{*}{Gas giants} & Jupiter & 1898 +& 142,984 & 1326 & 23.1 & 9.9 & 778.6 & -110 & 67 & The largest +planet \\ \addlinespace +& & Saturn & 568 & 120,536 & 687 & 9.0 & 10.7 & 1433.5 & -140 & 62 +& \\ \addlinespace +& \multirow{2}{*}{Ice giants} & Uranus & 86.8 & 51,118 & 1271 & 8.7 & 17.2 & +2872.5 & -195 & 27 & \\ \addlinespace +& & Neptune & 102 & 49,528 & 1638 & 11.0 & 16.1 & 4495.1 & -200 & 14 +& \\ \addlinespace +\multicolumn{2}{l}{Dwarf planets} & Pluto & 0.0146 & 2,370 & 2095 & 0.7 & +153.3 & 5906.4 & -225 & 5 & Declassified as a planet in 2006. \\ \addlinespace +\bottomrule +\end{longtable} diff --git a/test/tables/students.latex b/test/tables/students.latex new file mode 100644 index 000000000..680a539d3 --- /dev/null +++ b/test/tables/students.latex @@ -0,0 +1,23 @@ +\begin{longtable}[]{@{} + >{\raggedright\arraybackslash}p{(\columnwidth - 2\tabcolsep) * \real{0.50}} + >{\raggedright\arraybackslash}p{(\columnwidth - 2\tabcolsep) * \real{0.50}}@{}} +\caption{List of Students}\tabularnewline +\toprule +Student ID & Name \\ \addlinespace +\midrule +\endfirsthead +\toprule +Student ID & Name \\ \addlinespace +\midrule +\endhead +\multicolumn{2}{l}{Computer Science} \\ \addlinespace +3741255 & Jones, Martha \\ \addlinespace +4077830 & Pierce, Benjamin \\ \addlinespace +5151701 & Kirk, James \\ \addlinespace +\multicolumn{2}{l}{Russian Literature} \\ \addlinespace +3971244 & Nim, Victor \\ \addlinespace +\multicolumn{2}{l}{Astrophysics} \\ \addlinespace +4100332 & Petrov, Alexandra \\ \addlinespace +4100332 & Toyota, Hiroko \\ \addlinespace +\bottomrule +\end{longtable}