`\textwidth` wide images in two-column document?
Is it possible to optionally use the \begin{figure*} environment to span a figure's width over the whole \textwidth instead of \columnwidth if we have a two column document?
Thanks!
Perhaps we could make this sensitive to an attribute on the figure environment.
But it's also easy to postprocess and just replace figure{ with figure*{.
I think an attribute would be great to have more control and to mix text wide and column wide figures.
Or we extend the parsing of the width attribute by an option pagewidth or full-width or similar.
Would this need a new pandoc release or can attributes be added and parsed by LUA filters?
See #9259 for discussion.
Hi @jgm and @jankap a few weeks ago I was thinking about a similar problem, but trying alternative approach. My approach was to generate this change in the latex template based on redefining the environment to include floats (using figure*/table* instead of figure/table if twocolumn is true).
First of all it would be necessary to include twocolumn: true as a separate variable of the metadata file. Then we should include this option separately for the documentclass in the template, with something like:
\documentclass[
$if(fontsize)$%
$fontsize$,%
$endif$%
$if(papersize)$%
$papersize$paper,%
$endif$%
$if(twocolumn)$%
twocolumn,%
$endif$%
$for(classoption)$%
$classoption$$sep$,%
$endfor$%
]{$documentclass$}%
Finally, it would be necessary to redefine the environment that is used when floats are present. This is where I found problems to solve the problem in an elegant way. The problem is that it is not possible to redefine the figure/table environment to be figure*/table* because "figure*" uses "figure" and therefore a loop is generated in the definition of the environment. Therefore, it is not possible to use something like:
$if(twocolumn)$
\renewenvironment{figure}{\begin{figure*}}{\end{figure*}}
\renewenvironment{table}{\begin{table*}}{\end{table*}}
$endif$
Alternatively, I found a less elegant solution. The point is to define a new environment that takes float/float* as its definition depending on the presence of twocolumn. The problem is that you then need to have in the floats a call to a custom environment (I used figurenew/tablenew for this example). It is a similar approach to what is currently done with the definition of \cireproc for citations. Applying this approach would therefore require a change of the pandoc latex writer and perhaps adds unnecessary complexity. The code would look like this:
$if(twocolumn)$
\newenvironment{figurenew}{begin{figure*}}{end{figure*}}
\newenvironment{tablenew}{begin{table*}}{end{table*}}
$else$
\newenvironment{figurenew}{figurenew}{figure}{figure}{figurenew}.
\newenvironment{tablenew}{begin{table}}{end{table}}
$endif$
What do you think of this approach?
Hey,
as mentioned by @jgm I'm trying to solve a similar task (as part of other more complex ones); see #9259
I have written a working Lua filter to partly use figure* environment in Latex output, when converting from Markdown to Latex or PDF:
The starred envrionment is invoked as follows: If you insert an image in Markdown, you can pass the attribute starred=true. This will wrap only the current image inside a figure* environment.
E.g. use {starred=true} to create a starred figure which spans both columns in a twocolumn document.
Here is the Lua code which should be invoked using the -L filter.lua flag:
if FORMAT:match 'latex' then
function Figure (elem)
local starred = elem.content[1].content[1].attributes['starred']
if starred == "true" then
return {
pandoc.RawInline('latex', '\\begingroup\n\\RenewEnvironmentCopy{figure}{figure*}'),
elem,
pandoc.RawInline('latex', '\\endgroup')
}
else
return elem
end
end
end
As explanation: In the Latex backend the particular figure is wrapped into a local group using begingroup and endgroup. Inside that group I redefine the regular figure environment as figure*, so that we don't have to mofify the output of a pandoc.Figure itself which is rather complex (as I know now). I use the Latex macro \RenewEnvironmentCopy which is only part of the Kernel since 2023. Thus, you need an up-to-date Latex installation. If you're using an older Latex version substitute the mentioned macro with e.g. \\renewenvironment{figure}{\\begin{figure*}}{\\end{figure*}}, but this might be not as robust as the other variant.
Furthermore, the group might influence the floating ability of the starred figure. But that shouldn't weigh to much if you place the image command near the paragraph you reference it.
I didn't know about the RenewEnvironmentCopy command! This makes it easier for the approach I proposed. I think this could be incorporated into pandoc just by modifying the template and would allow to have two-column outputs with few changes. Wouldn't this approach be better instead of using custom filters?
It would only be necessary to add in the template the following:
$if(twocolumn)$
\RenewEnvironmentCopy{figure}{figure}
\RenewEnvironmentCopy{table}{table*}
$endif$
And modifying the class call:
\documentclass[
$if(fontsize)$%
$fontsize$,%
$endif$%
$if(papersize)$%
$papersize$paper,%
$endif$%
$if(twocolumn)$%
twocolumn,%
$endif$%
$for(classoption)$%
$classoption$$sep$,%
$endfor$%
]{$documentclass$}%
@estedeahora your approach would make the redefinition global, so every figure environment would be interpreted as figure*. If you only need full textwidth figures, that's fine.
My filter allows you to choose for every single image if its only column width or textwidth. That's more flexible but a tiny bit more typing.
Of course, I understand the difference. Beyond that, I think it would be a good change for the pandoc template, as it would allow to have two-column documents natively. I understand that in most cases two-column documents require all floats to be double width.
That might be an option for pandoc. My case is a little different. I'm programming a publishing workflow for a journal. Its layout isnt set in two columns but instead one text area with a very broad outer margin. Regular figures are just spanning the textwidth, but some very big figures should span textwidth+marginparsep+marginparwidth for which I use the figure* environment. Thus, I need a more flexible approach.
If you only need textwidth figures in a twocolumn document I would go with your solution too. Its simply less code to be processed.
What do you think @jgm? Do you think it could be a PR for the latex template?
Probably not, because this affects all figures and tables globally, and (I gather from the discussion above) some people might want these in a column.
I understand that in most cases two-column documents require all floats to be double width.
I don't think that's true, at least in my field. I'm writing an IEEE paper and usually only one overview figure is full width and the rest has column width, so both is required and therefore a global redefinition does not work.
@lukeflo I'll test your filter, looks like the solution I need.
Thanks for the good discussion, all!
@lukeflo I'd just like to confirm that your solution works beautifully! Just added the lua filter and called it. The code in markdown is
{#fig:results_1 width=100% starred=true}
@jankap Thanks for your feedback. It looks really good. I'm happy that it worked out that way!!