Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

longtable not compatible with 2-column LaTeX documents #1023

Open
nrnrnr opened this issue Oct 14, 2013 · 72 comments
Open

longtable not compatible with 2-column LaTeX documents #1023

nrnrnr opened this issue Oct 14, 2013 · 72 comments

Comments

@nrnrnr
Copy link

nrnrnr commented Oct 14, 2013

For some time I have been using pandoc to create two-column PDF documents via LaTeX. (This can be accomplished with some abuse of the fontsize variable.) However, in the transition from 1.9.x to 1.11.1, all tables appear to have become longtable environments, and when presented with two-column format, longtable falls over:

pandoc: Error producing PDF from TeX source.
! Package longtable Error: longtable not in 1-column mode.

See the longtable package documentation for explanation.
Type  H <return>  for immediate help.
 ...                                              

l.267 \begin{longtable}

I see in past issues that the transition from ctable to longtable was decided on a while back, but I really hate to lose the ability to create two-column documents, which I use heavily. I also understand the issue of wanting to stick with relatively standard LaTeX packages.

Is it possible that the old ctable back end could be resurrected via some kind of command-line option? It sounds horrible, but I can't think of a better solution.

@nrnrnr
Copy link
Author

nrnrnr commented Oct 14, 2013

Regarding the possibility of using longtable in 2-column documents, I found this thread on a Stack Exchange site, but it is not promising: http://tex.stackexchange.com/questions/39686/longtable-alternative-for-twocolumn-documents

@scmbradley
Copy link

I have a related issue that probably isn't worth opening another issue ticket for. Rather than a "resurrect ctable" solution, I'd prefer an option that just turns tables into very basic tabular environments. Or maybe a new style of markdown (or some sort of in-text flag) that outputs basic tabulars.

@scmbradley
Copy link

As a workaround, one can pandoc into tex and then use sed (or whatever) to replace all instances of longtable with tabular or ctable or whatever other environment you want...

@nrnrnr
Copy link
Author

nrnrnr commented Jan 22, 2014

@scmbradley is it really that simple?

@dsoto
Copy link

dsoto commented May 27, 2014

@nrnrnr @scmbradley From what I can tell, if you use tabular, you also have to add table environments. I can do this manually, but I don't see a way to do it with the template.

@daroczig
Copy link

It would be indeed very useful if ctable, longtable or other similar environments would not be hard-coded, but the user could pass it e.g. via a pandoc option.

@terceiro
Copy link
Contributor

I solved this by using this tip: replacing longtable with supertabular made it work for me.

@dtinth
Copy link

dtinth commented Mar 19, 2015

When replacing longtable with supertabular, you may get error about undefined command \endhead. Simply remove that from the LaTeX source.

To center the table, wrap them between \begin{center} and \end{center}.

Here's the code I add to the build process (in Ruby). result is the conversion result from Pandoc (actually generated from ipython nbconvert):

result.gsub!('\begin{longtable}', '\begin{center}\begin{supertabular}')
result.gsub!('\endhead', '')
result.gsub!('\end{longtable}', '\end{supertabular}\end{center}')

@nvasilakis
Copy link

Hey everyone, sorry for resurrecting this one -- do we have any way of resolving this beyond using sed? In theory, it should be able to just amend the latex template -- but the latex template does not seem to allow edits to the table structure. Any ideas?

@jgm
Copy link
Owner

jgm commented Aug 18, 2015

If there were no other differences, you could do a
renewenvironment in the template, and redefine longtable
as table. E.g.

\let\longtable\table
\let\endlongtable\endtable

But there are some differences between the two environments,
e.g. as regards handling of footnotes, so this probably
won't work in general. (It might work sometimes.)

+++ Nikos Vasilakis [Aug 17 15 20:32 ]:

Hey everyone, sorry for resurrecting this one -- do we have any way of
resolving this beyond using sed? In theory, it should be able to just
amend the latex template -- but the latex template does not seem to
allow edits to the table structure. Any ideas?


Reply to this email directly or [1]view it on GitHub.

References

  1. longtable not compatible with 2-column LaTeX documents #1023 (comment)

@nvasilakis
Copy link

Thanks John! This does not work though, I think because the generated table code has a number extra stuff -- for instance: ! LaTeX Error: Unknown float optionc'.`.

However, I am now thinking: wouldn't a solution based on detecting supertabular work? For example, in LaTeX.hs source (intended mostly as pseudocode -- my haskell is rusty):

  return ( if ("supertabular" `isInfixOf` (writerTemplate opts)) then
           ( "\\begin{supertabular}[c]" <>
                braces ("@{}" <> colDescriptors <> "@{}")
           $$ capt
           $$ headers
           $$ vcat rows'
           $$ "\\end{supertabular}"
          )
         else -- normal old behavior
           ( "\\begin{longtable}[c]" <>
                braces ("@{}" <> colDescriptors <> "@{}")
                -- the @{} removes extra space at beginning and end
           $$ capt
           $$ "\\toprule"
           $$ headers
           $$ endhead
           $$ vcat rows'
           $$ "\\bottomrule"
           $$ "\\end{longtable}"
           )
         )

@jgm
Copy link
Owner

jgm commented Aug 18, 2015

I don't really like making behavior sensitive to what's in
the template in the way you describe.

What about doing what I suggested, but with supertabular
instead of table? Does that work? Note that the midline,
topline, bottomline are from booktabs and should still work
with supertabular, I think.

+++ Nikos Vasilakis [Aug 17 15 23:23 ]:

Thanks John! This does not work though, I think because the generated
table code has a number extra stuff -- for instance: ! LaTeX Error:
Unknown float optionc'.`.

However, I am now thinking: wouldn't a solution based on detecting
supertabular work? For example, in LaTeX.hs source (intended mostly as
pseudocode -- my haskell is rusty):

return ( if ("supertabular" isInfixOf (writerTemplate opts)) then
( "\begin{supertabular}[c]" <>
braces ("@{}" <> colDescriptors <> "@{}")
$$ capt
$$ headers
$$ vcat rows'
$$ "\end{supertabular}"
)
else -- normal old behavior
( "\begin{longtable}[c]" <>
braces ("@{}" <> colDescriptors <> "@{}")
-- the @{} removes extra space at beginning and end
$$ capt
$$ "\toprule"
$$ headers
$$ endhead
$$ vcat rows'
$$ "\bottomrule"
$$ "\end{longtable}"
)
)


Reply to this email directly or [1]view it on GitHub.

References

  1. longtable not compatible with 2-column LaTeX documents #1023 (comment)

@nvasilakis
Copy link

Changing the lines you suggested to:

\let\longtable\supertabular
\let\endlongtable\endsupertabular

while adding:

\usepackage{supertabular}
\usepackage{booktabs}

..still doesn't work:

! Undefined control sequence.
<recently read> \endhead

My goal is to have tables in two-column latex documents. Do you use a different way to achieve a similar result in your documents?

Regarding the psudo-patch I proposed, I know it's not optimal, it's just to get people going until a proper solution gets in. Another simple idea might be to just default to supertabular or xtab.

@jgm
Copy link
Owner

jgm commented Aug 18, 2015

+++ Nikos Vasilakis [Aug 18 15 10:45 ]:

My goal is to have tables in two-column latex documents. Do you use a different way to achieve a similar result in your documents?

I've never tried this.

Regarding the psudo-patch I proposed, I know it's not optimal, it's just to get people going until a proper solution gets in. Another simple idea might be to just default to supertabular or xtab.

The problem is that if we do support it in some versions,
people will have documents that depend on this behavior,
and we'll have to keep it or make breaking changes.

One possibility would be to check for twocolumn in the
classoption variable, and use a regular table environment
if so. But, as I recall, there are still some issues
relating to different handling of footnotes in table and
longtable -- maybe other things too.

What are the advantages of supertabular or xtab over table?

@iamaziz
Copy link

iamaziz commented Nov 29, 2015

As a workaround, someone (thanks!) has created a filter for using tabular instead of longtable in twocolumn environment (e.g. IEEEtrans, after some struggle I finally find a solution!! I tried it and it works), check it out here:

https://groups.google.com/forum/#!msg/pandoc-discuss/RUC-tuu_qf0/h-H3RRVt1coJ

To use it:

e.g.
$ pandoc SORUCE -o OUT.tex --filter table-filter.py

@jgm
Copy link
Owner

jgm commented Nov 29, 2015

I tried this, and there are a number of issues with
this filter, though it may be fine for simple cases:

  1. The filter crashes if you have a table without headers.

  2. Because the filter removes Table elements from the
    AST, the latex writer won't include

    \usepackage{booktabs}

in the header; you'll need to add this yourself through
-H or a custom template, or by doing -V tables.

  1. Relative column widths are not kept, so tables with long
    cell contents will stretch beyond page width.
  2. Finally, footnotes don't work in these tables.

I'd be open to adding an option to pandoc to use regular
tabular, if I could figure out how to make notes work
properly, etc.

+++ Aziz Alto [Nov 29 15 02:52 ]:

As a workaround, someone (thanks!) has created a filter for using
tabular instead of longtable in twocolumn environment (e.g. IEEEtrans,
after some struggle I finally find a solution!! I tried it and it
works), check it out here:

[1]https://groups.google.com/forum/#!msg/pandoc-discuss/RUC-tuu_qf0/h-H
3RRVt1coJ

To use it:
* copy the code from that link into some file table-filter.py
* Install [2]pandocfilters
* use the filter when you [3]convert you doc to latex,

e.g.
$ pandoc SORUCE -o OUT.tex --filter table-filter.py


Reply to this email directly or [4]view it on GitHub.

References

  1. https://groups.google.com/forum/#!msg/pandoc-discuss/RUC-tuu_qf0/h-H3RRVt1coJ
  2. https://github.com/jgm/pandocfilters#installing
  3. https://github.com/jgm/pandocfilters#what-are-pandoc-filters
  4. longtable not compatible with 2-column LaTeX documents #1023 (comment)

@iamaziz
Copy link

iamaziz commented Nov 30, 2015

That's right! however in my case the filter does work with IEEEtran class without any significant issue. I do use many simple tables (with headers) in my docs, and it's not feasible to convert them manually.

I add \usepackage{booktabs} to the header of the template I use. Also another option (instead of using booktabs) would be to replace \toprule, \bottomrule, and \midrule with \hline in the filter.py.

The tables with long cells work fine in the IEEEtran, but not in the other twocolumn document classes (e.g. IEEEconf, [twocolumn]{journal} ).

I have not tried the footnotes. Thank you.

@basus
Copy link

basus commented Dec 18, 2015

I would really like to see this get resolved without resorting to running external scripts and such. Since two-column formats are pretty common for LaTeX documents would it be possible to have a separate output mode for them as part of pandoc itself?

@jgm
Copy link
Owner

jgm commented Dec 19, 2015

I'd like to solve this too. What I need to know is how to reproduce our current table features using regular tabular. As noted above, two features that are a bit tricky are (a) footnotes in table cells and (b) relative widths in columns.

Once I've got this down, we could do several things. One option would be to have a command-line option to use regular tabular instead of longtable. Another would be to have tables inside a specially marked div treated specially (perhaps the special behavior should be longtable instead of regular tabular).

@basus
Copy link

basus commented Dec 20, 2015

I'd be willing to take a crack at this, possibly over the break. It looks like the relevant parts in the LaTeX writer are the functions blockToLatex (the Table case), tableRowToLatex and tableCellToLatex. I haven't used footnotes, either in markdown or pandoc, so I'll have to look into that.

@jgm
Copy link
Owner

jgm commented Dec 21, 2015

I'd have no trouble doing the Haskell bits. I just need to
know exactly what output to produce.

+++ Shrutarshi Basu [Dec 20 15 13:21 ]:

I'd be willing to take a crack at this, possibly over the break. It
looks like the relevant parts in the LaTeX writer are the functions
blockToLatex (the Table case), tableRowToLatex and tableCellToLatex. I
haven't used footnotes, either in markdown or pandoc, so I'll have to
look into that.


Reply to this email directly or [1]view it on GitHub.

References

  1. longtable not compatible with 2-column LaTeX documents #1023 (comment)

@01mf02
Copy link

01mf02 commented Apr 14, 2016

Hi, I have converted a multiline table example from the Pandoc user's guide to use tabular / table, and footnotes (courtesy of http://tex.stackexchange.com/a/35328) as well as relative widths seem to work.

The LaTeX code:

\documentclass{article}
\usepackage{hyperref}
\usepackage{tablefootnote}
\usepackage{booktabs}

\begin{document}
\begin{table}
\caption{Here's a multiline table without headers.}
\begin{tabular}{ c l r l }
\tabularnewline
\toprule
\toprule
\begin{minipage}[t]{0.15\columnwidth}\centering\strut
First
\strut\end{minipage} &
\begin{minipage}[t]{0.10\columnwidth}\raggedright\strut
row
\strut\end{minipage} &
\begin{minipage}[t]{0.20\columnwidth}\raggedleft\strut
12.0
\strut\end{minipage} &
\begin{minipage}[t]{0.31\columnwidth}\raggedright\strut
Example of a row that spans multiple lines.\tablefootnote{Footnotes also work.}
\strut\end{minipage}\tabularnewline
\begin{minipage}[t]{0.15\columnwidth}\centering\strut
Second
\strut\end{minipage} &
\begin{minipage}[t]{0.10\columnwidth}\raggedright\strut
row
\strut\end{minipage} &
\begin{minipage}[t]{0.20\columnwidth}\raggedleft\strut
5.0
\strut\end{minipage} &
\begin{minipage}[t]{0.31\columnwidth}\raggedright\strut
Here's another one. \tablefootnote{Another footnote.}Note the blank line between rows.
\strut\end{minipage}\tabularnewline
\bottomrule
\end{tabular}
\end{table}

\end{document}

@ickc
Copy link
Contributor

ickc commented Apr 27, 2016

Hi, will there be a command option/metadata variable for us to choose which kind of table will be used in LaTeX? From another thread it seems pandoc had changed the package it use for table but the old way wasn't kept. It would be nice if pandoc allow a choice of which conversion to use.

And is the use of table package open for discussion? I know that MultiMarkdown use tabulary, and probably tabularx has better footnote in table support (I once need to manually turn the tabulary table in mmd to a tabularx one). And I heard that tabu is supposed to be the newest and best package for table but haven't tried it yet.

@jgm
Copy link
Owner

jgm commented Apr 27, 2016

See #2384, #1023, and related discussions in pandoc-discuss.
I'd like to have a better solution here.

+++ ickc [Apr 26 16 22:56 ]:

Hi, will there be a command option/metadata variable for us to choose
which kind of table will be used in LaTeX? From another thread it seems
pandoc had changed the package it use for table but the old way wasn't
kept. It would be nice if pandoc allow a choice of which conversion to
use.

And is the use of table package open for discussion? I know that
MultiMarkdown use tabulary, and probably tabularx has better footnote
in table support (I once need to manually turn the tabulary table in
mmd to a tabularx one). And I heard that tabu is supposed to be the
newest and best package for table but haven't tried it yet.


You are receiving this because you commented.
Reply to this email directly or [1]view it on GitHub

References

  1. longtable not compatible with 2-column LaTeX documents #1023 (comment)

@01mf02
Copy link

01mf02 commented Apr 27, 2016

@jgm, what do you think about my solution? I think it should be fairly easy to adapt the existing table export code in pandoc to the format I proposed, and I do not see any problems with it.

@jgm
Copy link
Owner

jgm commented Jul 1, 2016

I've long had the goal of trying to stick to packages in the
texlive-latex-recommended subset on debian. (I'd rather
that users not have to download gigabytes of LaTeX just to
use regular tables.) Unfortunately, the tablefootnote
package is in texlive-latex-extra -- so that makes me
reluctant to use this approach.

In the end, it might still be worth considering. Maybe
we could have use of longtable or this approach be
configurable.

+++ Michael Färber [Apr 14 16 10:00 ]:

Hi, I have converted a multiline table example from the Pandoc user's
guide to use tabular / table, and footnotes (courtesy of
[1]http://tex.stackexchange.com/a/35328) as well as relative widths
seem to work.

The LaTeX code:

\documentclass{article}
\usepackage{hyperref}
\usepackage{tablefootnote}
\usepackage{booktabs}

\begin{document}
\begin{table}
\caption{Here's a multiline table without headers.}
\begin{tabular}{ c l r l }
\tabularnewline
\toprule
\toprule
\begin{minipage}[t]{0.15\columnwidth}\centering\strut
First
\strut\end{minipage} &
\begin{minipage}[t]{0.10\columnwidth}\raggedright\strut
row
\strut\end{minipage} &
\begin{minipage}[t]{0.20\columnwidth}\raggedleft\strut
12.0
\strut\end{minipage} &
\begin{minipage}[t]{0.31\columnwidth}\raggedright\strut
Example of a row that spans multiple lines.\tablefootnote{Footnotes also work.}
\strut\end{minipage}\tabularnewline
\begin{minipage}[t]{0.15\columnwidth}\centering\strut
Second
\strut\end{minipage} &
\begin{minipage}[t]{0.10\columnwidth}\raggedright\strut
row
\strut\end{minipage} &
\begin{minipage}[t]{0.20\columnwidth}\raggedleft\strut
5.0
\strut\end{minipage} &
\begin{minipage}[t]{0.31\columnwidth}\raggedright\strut
Here's another one. \tablefootnote{Another footnote.}Note the blank line between
rows.
\strut\end{minipage}\tabularnewline
\bottomrule
\end{tabular}
\end{table}

\end{document}


You are receiving this because you commented.
Reply to this email directly or [2]view it on GitHub

References

  1. http://tex.stackexchange.com/a/35328
  2. longtable not compatible with 2-column LaTeX documents #1023 (comment)

@01mf02
Copy link

01mf02 commented Jul 25, 2016

I understand. How about then leaving longtable as the default and creating a command-line option to use tablefootnote? This would not create a dependency for users that "just want some table", and if they need non-breaking tables desperately enough to use a new command-line option, they are probably also willing to depend on some extra package. :)

(At least I am desperate enough. The table situation is by far my greatest Pandoc problem by far.)

@lhoupert
Copy link

EDIT: Because this is kind of an eyesore, i wrote a filter to avoid putting raw latex in my markdown doc:

import pandocfilters as pf

def supertabular(key, value, format, meta):
  """
    NOTE: This filter expects a modification to the default template
  """
  if key == 'Table' and 'processed' not in value[0][1]:
    caption = value[1]
    cap = pf.stringify(caption) 
    cmd = f'\\renewcommand\\tcap{{{cap}}}'

    value[0][1].append('processed')
    value[1] = {'t': 'Caption', 'c': [None, []]}
    mytable = pf.elt('Table', len(value))
    return [pf.RawBlock('latex', cmd), mytable(*value)]

if __name__ == '__main__':
  pf.toJSONFilter(supertabular)

Thanks for your solution. It is working well for me. But I was wondering where do you define your filter?

@Bustel
Copy link

Bustel commented Mar 11, 2021

Thanks for your solution. It is working well for me. But I was wondering where do you define your filter?

Have a look at the --filter option in the User Guide. A filter can be any executable in a relative path, in $PATH, or you can put them in $DATADIR/filters, which for me is ~/.local/share/pandoc/filters. You can put custom templates and default settings there, too.

@lhoupert
Copy link

Thanks for your solution. It is working well for me. But I was wondering where do you define your filter?

Have a look at the --filter option in the User Guide. A filter can be any executable in a relative path, in $PATH, or you can put them in $DATADIR/filters, which for me is ~/.local/share/pandoc/filters. You can put custom templates and default settings there, too.

Thanks for your quite reply!

I tried adding your filter in a script named twocolumns_table_fix.py:

""" Pandoc filter to fix the issue with longtable not compatible
with 2-column latex documents

See https://github.com/jgm/pandoc/issues/1023#issuecomment-656769330

"""
import pandocfilters as pf

def supertabular(key, value, format, meta):
  """
    NOTE: This filter expects a modification to the default template
  """
  if key == 'Table' and 'processed' not in value[0][1]:
    caption = value[1]
    cap = pf.stringify(caption)
    cmd = f'\\renewcommand\\tcap{{{cap}}}'

    value[0][1].append('processed')
    value[1] = {'t': 'Caption', 'c': [None, []]}
    mytable = pf.elt('Table', len(value))
    return [pf.RawBlock('latex', cmd), mytable(*value)]

if __name__ == '__main__':
  pf.toJSONFilter(supertabular)

I also added the latex package supertabular in a separate file (supertabular.tex):

\usepackage{supertabular}
\newcommand\tcap{}
\renewenvironment{longtable}{\begin{center}\bottomcaption{\tcap}\begin{supertabular}}{\end{supertabular}\end{center}}
\renewcommand{\endhead}{}

My minimalist markdown file article.md is below:

---

---

### Test Table

| Tables        | Are           | Cool  |
| ------------- |:-------------:| -----:|
| col 3 is      | right-aligned | $1600 |
| col 2 is      | centered      |   $12 |
| zebra stripes | are neat      |    $1 |

<!-- \renewcommand\tcap{Table styles. \label{tab:1}} -->
Table: Table styles. \label{tab:1}

Seen in table \ref{tab:1}, Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

But when I run the command below:

pandoc article.md \
--citeproc \
--from=markdown+tex_math_single_backslash+tex_math_dollars+raw_tex \
--to=latex \
--output=build/article-print-doublecols.pdf \
--pdf-engine=xelatex \
-M classoption=twocolumn \
  --include-in-header="layout/supertabular.tex" \
--filter="layout/twocolumns_table_fix.py"

I got this error:

Error running filter layout/twocolumns_table_fix.py:
Error in $.blocks[4]: When parsing the constructor Caption of type Text.Pandoc.Definition.Caption expected Array but got Object.

Any idea why I got this error?

@SamKacer
Copy link

@Bustel thanks for sharing your workaround. As mentioned by @wuffi, when giving the table a caption in markdown, processing the resulting LaTeX results in an error with caption being outside of a float. Do you know if this can be fixed somehow?

@lhoupert
Copy link

lhoupert commented Mar 11, 2021

@Bustel thanks for sharing your workaround. As mentioned by @wuffi, when giving the table a caption in markdown, processing the resulting LaTeX results in an error with caption being outside of a float. Do you know if this can be fixed somehow?

@SamKacer Did you use the command below to set the caption?

\renewcommand\tcap{My Caption}

This worked for me

@SamKacer
Copy link

@lhoupert oh, right. I can't believe I missed that. I just copy pasted that in without actually reading it. that works fine. thanks for pointing that out

@Bustel
Copy link

Bustel commented Mar 12, 2021

I got this error:

Error running filter layout/twocolumns_table_fix.py:
Error in $.blocks[4]: When parsing the constructor Caption of type Text.Pandoc.Definition.Caption expected Array but got Object.

Any idea why I got this error?

Apparently something has changed in pandoc in the meantime and my filter is not correct anymore.
Luckily the fix to the fix is just one line:

-    value[1] = {'t': 'Caption', 'c': [None, []]}
+    value[1] = [None, []]

Then I had to remove your html comment from your example and then it worked for me. Almost.
pf.stringify just seems to remove raw latex from the caption so the reference does not work anymore but you might work around that with pandoc-crossref.

@lhoupert
Copy link

Thanks very much @Bustel for debugging me on this! I managed to find a solution to my problem without having to install other package :-)

The idea is to save the latex reference before "stringifyïng" the caption, so I created a short function for that (return_latex_ref) following @jgm stringyfy.py function. I added it below:

""" Pandoc filter to fix the issue with longtable not compatible
with 2-column latex documents

See https://github.com/jgm/pandoc/issues/1023#issuecomment-656769330

"""
import pandocfilters as pf
from pandocfilters import walk

def return_latex_ref(x):
    """Walks the tree x and returns the latex reference.
    """
    result = []

    def go(key, val, format, meta):
        if key in 'RawInline':
          if val[0] == 'tex' and '\\label' in val[1]:
            result.append(val[1])

    walk(x, go, "", {})
    return ''.join(result)

def supertabular(key, value, format, meta):
  """
    NOTE: This filter expects a modification to the default template
  """

  if key == 'Table' and 'processed' not in value[0][1]:
    caption = value[1]
    cap = pf.stringify(caption) + ' ' + return_latex_ref(caption)

    cmd = f'\\renewcommand\\tcap{{{cap}}}'

    value[0][1].append('processed')
    value[1] = [None, []]
    mytable = pf.elt('Table', len(value))
    
    return [pf.RawBlock('latex', cmd), mytable(*value)]

if __name__ == '__main__':
  pf.toJSONFilter(supertabular)

@ldanielcano
Copy link

@lhoupert solution works for me. The only thing I'd like is the possibility of using default pandoc-cross-ref notation {#tbl:name}. I'm new to these filter stuff so I don't know how to do it 😅

|     | Grosor [mm] | Factor de reducción |
|-----|-------------|---------------------|
| HVL |        10.1 |                   2 |
| QVL |          19 |                   4 |
| TVL |        29.9 |                  10 |

: Valores de HVL, QVL y TVL reportados \label{tbl:name}

This works [@tbl:name].

@ldanielcano
Copy link

ldanielcano commented Jun 23, 2021

There is a new error: Missing number, treated as zero

It happens when the size the table is bigger than the width of the column. The next couple of lines appear in the latex output once the above condition is triggered.

\begin{longtable}[]{@{}
  >{\raggedright\arraybackslash}p{(\columnwidth - 2\tabcolsep) * \real{0.35}}
  >{\raggedright\arraybackslash}p{(\columnwidth - 2\tabcolsep) * \real{0.22}}@{}}\real{0.22}}@{}}

@PaulEibensteiner
Copy link

Kind of off topic, but for anyone just trying to get a long table from pandoc to span over two columns, wrap it in begin{table*} and end{table*} and change all occurences of \columnwidth to \linewidth. Works with crossref, custom column width etc. Just took me 4hrs+ to find this out.

@PowerUser64
Copy link

PowerUser64 commented Apr 12, 2022

I just found a solution to this on the TeX stack exchange. If you include a header file that looks like this:

\makeatletter
\let\oldlt\longtable
\let\endoldlt\endlongtable
\def\longtable{\@ifnextchar[\longtable@i \longtable@ii}
\def\longtable@i[#1]{\begin{figure}[t]
\onecolumn
\begin{minipage}{0.5\textwidth}
\oldlt[#1]
}
\def\longtable@ii{\begin{figure}[t]
\onecolumn
\begin{minipage}{0.5\textwidth}
\oldlt
}
\def\endlongtable{\endoldlt
\end{minipage}
\twocolumn
\end{figure}}
\makeatother

You can just redefine the \longtable command, which seems to solve the issue well.

Source: https://tex.stackexchange.com/a/224096

This could have some side effects I don't know about, but everything seems fine from what I can see.

@jasonhartline
Copy link

None of the recommended solutions above worked for me. I do not want my tables to float. And mysteriously a solution I had from a few years back is now broken and giving a \noalign error that I cannot sort out. I put this in the preamble:

\renewenvironment{longtable}{\begin{center}\begin{tabular}}{\end{tabular}\end{center}}
\def\endhead{}
\renewcommand{\toprule}[2]{\hline}
\renewcommand{\midrule}[2]{\hline}
\renewcommand{\bottomrule}[2]{\hline}

And it is working again. I suppose my tables will not work across pagebreaks, but I also do not use long tables.

PS. One of the early comments in this thread confuses table with tabular and gets a odd message about a float because of it.

@jankap
Copy link

jankap commented Nov 27, 2023

None of the proposals above do work for me though :/ I can't use tables in Pandoc anymore. I have to use a two-column template.

Original error is ! Package longtable Error: longtable not in 1-column mode.

Tryin to use tabular:

\usepackage{longtable}
\usepackage{booktabs}

% fix longtable in 2-col mode from https://tex.stackexchange.com/questions/161431/how-to-solve-longtable-is-not-in-1-column-mode-error
\renewenvironment{longtable}{\begin{center}\begin{tabular}}{\end{tabular}\end{center}}
\renewcommand{\endhead}{}
\renewcommand{\toprule}[2]{\hline}
\renewcommand{\midrule}[2]{\hline}
\renewcommand{\bottomrule}[2]{\hline}

results in ! Undefined control sequence. \LT@echunk ->\crcr \LT@save@row \cr \egroup \global \setbox \LT@gbox \lastbo... l.898 \endlastfoot

BTW, the table is as simple as

| test | haha |
| ---- | ---- |
| 1    | 1    |
| 2    | 3    |

which gets converted to

\begin{longtable}[]{@{}ll@{}}
\toprule\noalign{}
test & haha \\
\midrule\noalign{}
\endhead
\bottomrule\noalign{}
\endlastfoot
1 & 1 \\
2 & 3 \\
\end{longtable}

No idea what I could do :(

@sfulham
Copy link

sfulham commented Feb 21, 2024

I just found a solution to this on the TeX stack exchange. If you include a header file that looks like this:

\makeatletter
\let\oldlt\longtable
\let\endoldlt\endlongtable
\def\longtable{\@ifnextchar[\longtable@i \longtable@ii}
\def\longtable@i[#1]{\begin{figure}[t]
\onecolumn
\begin{minipage}{0.5\textwidth}
\oldlt[#1]
}
\def\longtable@ii{\begin{figure}[t]
\onecolumn
\begin{minipage}{0.5\textwidth}
\oldlt
}
\def\endlongtable{\endoldlt
\end{minipage}
\twocolumn
\end{figure}}
\makeatother

You can just redefine the \longtable command, which seems to solve the issue well.

Source: https://tex.stackexchange.com/a/224096

This could have some side effects I don't know about, but everything seems fine from what I can see.

Yeah I tried that, however it doesn't align properly in my document.
image

EDIT: Fixed by moving the \onecolumn lines down one line each

@sfulham
Copy link

sfulham commented Feb 21, 2024

Found kind of an acceptable workaround for my situation using a custom IEEEtran template. I added the following to my template:

\usepackage{supertabular}
\newcommand\tcap{}
\renewenvironment{longtable}{\begin{center}\bottomcaption{\tcap}\begin{supertabular}}{\end{supertabular}\end{center}}
\renewcommand{\endhead}{}

And now before every table i just insert this inline latex:

\renewcommand\tcap{My Caption}

EDIT: Because this is kind of an eyesore, i wrote a filter to avoid putting raw latex in my markdown doc:

import pandocfilters as pf

def supertabular(key, value, format, meta):
  """
    NOTE: This filter expects a modification to the default template
  """
  if key == 'Table' and 'processed' not in value[0][1]:
    caption = value[1]
    cap = pf.stringify(caption) 
    cmd = f'\\renewcommand\\tcap{{{cap}}}'

    value[0][1].append('processed')
    value[1] = {'t': 'Caption', 'c': [None, []]}
    mytable = pf.elt('Table', len(value))
    return [pf.RawBlock('latex', cmd), mytable(*value)]

if __name__ == '__main__':
  pf.toJSONFilter(supertabular)

Currently trying this method, however I get AttributeError: 'dict' object has no attribute 'append' on the value[0][1] line. Updating to latest version caused same issue as previous people had, however was solved with fix provided. However, now I get Undefined control sequence for \endlastfoot. Removing this line solves the problem, however requires removing it every time I run pandoc. Also the solution for the caption also seems to break pandoc-crossref

@mclearc
Copy link

mclearc commented Mar 5, 2024

I have tried all the options here and various other things (like Lua filters) and nothing seems to work. Would really love to see a fix that is at least compatible with simple tables in a two-column format! :)

@jasonhartline
Copy link

None of the proposals above do work for me though :/ I can't use tables in Pandoc anymore. I have to use a two-column template.

Original error is ! Package longtable Error: longtable not in 1-column mode.

Tryin to use tabular:

\usepackage{longtable}
\usepackage{booktabs}

% fix longtable in 2-col mode from https://tex.stackexchange.com/questions/161431/how-to-solve-longtable-is-not-in-1-column-mode-error
\renewenvironment{longtable}{\begin{center}\begin{tabular}}{\end{tabular}\end{center}}
\renewcommand{\endhead}{}
\renewcommand{\toprule}[2]{\hline}
\renewcommand{\midrule}[2]{\hline}
\renewcommand{\bottomrule}[2]{\hline}

results in ! Undefined control sequence. \LT@echunk ->\crcr \LT@save@row \cr \egroup \global \setbox \LT@gbox \lastbo... l.898 \endlastfoot

BTW, the table is as simple as

| test | haha |
| ---- | ---- |
| 1    | 1    |
| 2    | 3    |

which gets converted to

\begin{longtable}[]{@{}ll@{}}
\toprule\noalign{}
test & haha \\
\midrule\noalign{}
\endhead
\bottomrule\noalign{}
\endlastfoot
1 & 1 \\
2 & 3 \\
\end{longtable}

No idea what I could do :(

@jankap I got your code to work by adding to the above:

\renewcommand{\endlastfoot}{}

@jankap
Copy link

jankap commented May 15, 2024

I'm currently using LaTeX with https://ctan.org/pkg/tabularray in markdown to render my tables in two-col mode...

@SichangHe
Copy link

For anyone who just wants the normal tabular, this is a Pandoc filter ChatGPT wrote that seems to do just that: https://github.com/SichangHe/JSphere/blob/6dd9bc1cabc84644cbde6e3441251837b421031c/table_workaround_filter.lua

I don't know how to do table* intelligently when the table is too long, but I guess at that point I might as well write LaTeX.

No idea why Pandoc reinvents the table. Hopes this helps someone though.

@achimbo
Copy link

achimbo commented Nov 17, 2024

OK, I messed around with https://gist.github.com/wgroeneveld/9dbeb0d0b60c6cb5d8dfe9b938c5e94e?permalink_comment_id=5150542#gistcomment-5150542 and ended up with the following panflute filter that respects spaces and verbatim in tables, and works with cross referencing and citations:

import sys

from panflute import *

def replace_longtables_with_tabular(elem, doc):
    try:
        def get_text(item):
            if isinstance(item, Str):
                return item.text.replace('_', r'\_')
            elif isinstance(item, Plain):
                return ''.join([get_text(i) for i in item.content])
            elif isinstance(item, ListContainer):
                return ''.join([get_text(i) for i in item])
            elif isinstance(item, Code):
                return '\\verb|' + (item.text) + '|'
            elif isinstance(item, RawInline):
                return item.text
            elif isinstance(item, Cite):
                return ''.join(stringify(elem) for elem in item.content)
            elif str(item) == 'Space':
                return ' '
            else:
                return str(item)

        def caption():
            if elem.caption and elem.caption.content:
                return '\\caption{' + get_text(elem.caption.content) + '}\n' + \
                    '\\label{tbl:' + get_text(elem.caption.content).replace(' ', r'-').translate(str.maketrans("", "", "();,.")) + '}\n'
            return ''

        def tabular():
            return '\\begin{tabular}{' + 'l' * elem.cols + '}\n\\hline\n'

        def headers():
            if elem.head and elem.head.content:
                return ' & '.join([get_text(cell.content) for cell in elem.head.content[0].content]) + '\\\\\n\\hline\n'
            return ''

        def items():
            rows = []
            for body in elem.content:
                for row in body.content:
                    rows.append(' & '.join([get_text(cell.content) for cell in row.content]) + '\\\\')
            return '\n'.join(rows) + '\n'

        result = '\\begin{table*}[t]\n\\centering\n' + \
                 caption() + \
                 tabular() + \
                 headers() + \
                 items() + \
                 '\\hline\n\\end{tabular}\n\\end{table*}'

        print("Table processed successfully", file=sys.stderr)
        return RawBlock(result, 'latex')
    except Exception as e:
        print(f"Error processing table: {str(e)}", file=sys.stderr)
        return elem


def prepare(doc):
    pass

def action(elem, doc):
    if doc.format != 'latex':
        return None

    if isinstance(elem, Table):
        print("Table found!", file=sys.stderr) 
        return replace_longtables_with_tabular(elem, doc)

    return None

def finalize(doc):
    pass

# keep this structure: see http://scorreia.com/software/panflute/guide.html
def main(doc=None):
    return run_filter(action,
                         prepare=prepare,
                         finalize=finalize,
                         doc=doc)


if __name__ == '__main__':
    main()

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests