jgm / pandoc

Universal markup converter
https://pandoc.org
Other
34.63k stars 3.38k forks source link

Figures in two-column mode in PDF do not scale correctly #9396

Closed vtraag closed 1 month ago

vtraag commented 9 months ago

Explain the problem.

When generating a two-column PDF, and specifying an explicit figure size using ![Example](example.png){width=100%} in markdown, the figure is scaled to the full text width, instead of the column width. The obtained result is

example

The desired result would be

screen-shot

The problem is the following. The generated LaTeX is

\begin{figure}
\centering
\includegraphics[width=1\textwidth,height=\textheight]{example.png}
\caption{Example}
\end{figure}

The problem here is that it uses \textwidth to scale the figure. It would be more useful if this would scale using \linewidth instead, which adapts to the width where the figure is inserted.

Minimal example This minimal example does contain more text, in order to clarify the problem when rendering to PDF. Use the following code in `example.md`: ```md --- title: "Testing two-columns" author: Vincent Traag classoption: - twocolumn --- # Example Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean et bibendum leo. Pellentesque accumsan in sapien et viverra. Donec porta urna turpis, non elementum est pulvinar sit amet. Nullam et dolor turpis. Duis justo lorem, lacinia quis ligula quis, ullamcorper lobortis mauris. Cras volutpat, urna quis bibendum cursus, leo sapien tincidunt ipsum, ac aliquet lorem arcu at sem. Suspendisse turpis justo, congue vestibulum lorem sed, placerat facilisis orci. Fusce a vehicula ex, faucibus viverra arcu. Nulla blandit auctor purus sit amet gravida. Pellentesque bibendum sapien scelerisque, consectetur tellus et, vehicula mauris. In lacus ante, efficitur ut accumsan nec, semper nec ipsum. Aenean ultrices porta maximus. ![Example](example.png){width=100%} Quisque pulvinar bibendum arcu. Pellentesque fringilla volutpat odio, vel malesuada quam consectetur vulputate. Morbi ante neque, sollicitudin ut pulvinar a, imperdiet vitae lectus. Ut rutrum risus at purus iaculis commodo. Sed finibus odio ac mollis efficitur. Donec sit amet mi tempor, vestibulum urna a, ornare sem. Nunc posuere quis tellus in fermentum. Phasellus ornare dapibus finibus. Nunc congue rhoncus nunc vel egestas. Nunc eget massa velit. Ut a ex est. Ut sed cursus orci. Ut pharetra neque lectus, sit amet aliquam odio venenatis id. Praesent efficitur nibh sed urna malesuada, quis blandit justo placerat. Nulla enim diam, congue quis accumsan a, accumsan euismod orci. Sed porttitor nisl id suscipit posuere. Aliquam vulputate euismod mauris nec elementum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. In nulla massa, faucibus sed nibh elementum, dapibus elementum sapien. Mauris dictum leo non elit pellentesque lobortis. Suspendisse dapibus dolor id augue luctus, sed scelerisque quam lacinia. Curabitur placerat mi a justo commodo rutrum. Aenean volutpat auctor tellus in volutpat. Phasellus ut semper augue, nec eleifend metus. Curabitur rutrum ligula vel sapien porttitor, porttitor porttitor elit scelerisque. Suspendisse sit amet ullamcorper libero. Ut rutrum efficitur cursus. Nam egestas lacinia lacus nec eleifend. Mauris luctus eros eget enim viverra feugiat. Nulla odio metus, scelerisque at nisl vitae, consectetur vestibulum mauris. Interdum et malesuada fames ac ante ipsum primis in faucibus. Cras sodales, mauris quis malesuada facilisis, elit sem iaculis sapien, non placerat tortor arcu vitae elit. Donec suscipit purus non ultricies tincidunt. Donec rutrum diam ac ullamcorper aliquet. Curabitur sit amet ex sed sapien mattis tincidunt et ac dui. Nulla laoreet massa quis pulvinar laoreet. Nam vel neque felis. Cras lacinia viverra purus non ornare. Praesent consequat dolor sagittis feugiat consequat. Donec tempor ultricies tortor id mollis. Nam pulvinar gravida blandit. Suspendisse euismod hendrerit erat sit amet placerat. Duis pharetra venenatis tortor ac tincidunt. Donec rhoncus porttitor magna. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis viverra varius ante nec suscipit. Suspendisse imperdiet lacus vel mauris euismod accumsan. Mauris eu laoreet orci. ``` Convert the file using `pandoc example.md -o example.pdf`.

Pandoc version? pandoc 3.1.11.1 Features: +server +lua Scripting engine: Lua 5.4

Running Ubuntu 22.04.3 LTS

estedeahora commented 9 months ago

Have you seen issue 9268?

vtraag commented 9 months ago

No, I hadn't, I'll take a look, thanks!

But isn't this a slightly different issue? I have no intention (in this particular case) of using a two-column wide figure*.

AndyClifton commented 6 months ago

Maybe this helps? (With the assistance of ChatGPT) I wrote a lua filter that protects custom attributes in the image definition and includes them in the LaTeX output when converting markdown to latex.

This means that you can specify width = \linewidth in the image attributes to produce single-column images in a 2-column document that are correctly scaled, and it won't be overridden by the pandoc conversion process. You also won't get anything extra, like height=\linewidth, which currently makes images problematic when you convert from markdown to latex.

The filter looks like this, and I place it in a file custom_figure_attributes.lua in the directory.

custom_figure_attributes.lua

if FORMAT:match 'latex' then
    function Image(elem)
        -- Check if the element is an Image
        if elem.t == 'Image' then
            -- Retrieve the image source
            local src = elem.src

            -- Construct the LaTeX command to include the image with specified attributes
            local includeGraphicsCmd = "\\includegraphics"

            -- Append image attributes to the LaTeX command
            local attributes = {}
            for key, value in pairs(elem.attributes) do
                -- Skip 'src' attribute (already used in \includegraphics command)
                if key ~= 'src' then
                    table.insert(attributes, key .. '=' .. value)
                end
            end

            -- Join attributes with commas and enclose in square brackets
            if #attributes > 0 then
                includeGraphicsCmd = includeGraphicsCmd .. '[' .. table.concat(attributes, ',') .. ']'
            end

            -- Append image source to the LaTeX command
            includeGraphicsCmd = includeGraphicsCmd .. '{' .. src .. '}'

            -- Return the constructed LaTeX command as Inline elements
            return pandoc.RawInline('latex', includeGraphicsCmd)
        end

        -- Return the element unchanged if not an Image
        return elem
    end
end

my markdown file (content.md) includes the image like this:

![This is my caption.](path/to_image.png){width=0.95\linewidth test=true}

I call it using

pandoc content.md -o test.tex --lua-filter=custom_figure_attributes.lua

and it then gets converted into latex as follows:

\begin{figure}
\centering
\includegraphics[width=0.95\linewidth,test=true]{path/to_image.png}
\caption{This is my caption.}
\end{figure}

N.B.: the test... key is included to demonstrate that any attributes are simply copied. You should not do this in your documents!

I've confirmed that it works for markdown to PDF using

pandoc content.md -o test.pdf --lua-filter=custom_figure_attributes.lua

I'm sure I've missed a bunch of use cases, but this works for my purposes.

Edit: I've also confirmed that the above filter appears compatible with the pandoc-crossref filter.

SarahBarbosa commented 2 months ago

You can use \columnwidth instead of \textwidth:

\begin{figure}
\centering
\includegraphics[width=\columnwidth]{example.png}
\caption{Example}
\end{figure}
jgm commented 1 month ago

I am closing this; the issue has been fixed by the changes in pandoc 3.2.1.