lierdakil / pandoc-crossref

Pandoc filter for cross-references
https://lierdakil.github.io/pandoc-crossref/
GNU General Public License v2.0
936 stars 74 forks source link

Subfigures conflict with ruled float style #382

Open kohenkatz opened 1 year ago

kohenkatz commented 1 year ago

By default, this package applies the ruled style to code blocks. I want to apply the same style to tables and figures. I have some figures which have subfigures.

I followed the instructions from the float package to use these commands to apply the style:

\floatstyle{ruled}
\restylefloat{figure}
\restylefloat{table}

However, applying this style causes all subfigure references to be off by one.

Here is an example document that reproduces this error:

---
subfigGrid: true
lof: true
---

\floatstyle{ruled}
\restylefloat{figure}
\restylefloat{table}

# My first chapter

This is an intro chapter. It references [@fig:example1], [@fig:example2a] and also [@fig:example2b].

![Image 1](image.png){#fig:example1}

<div id="fig:example2">
![Image 2a](image.png){#fig:example2a width=45%}
![Image 2b](image.png){#fig:example2b width=45%}

Example with subfigures
</div>

Here is the build command I used:

pandoc --filter=pandoc-crossref --citeproc --standalone --pdf-engine=xelatex -o sample.pdf sample.md

Here is the rendered output, which shows references in the text to 1a and 1b instead of 2a and 2b:

image

How can I resolve this apparent conflict between pandoc-crossref and the restylefloat command?

kohenkatz commented 1 year ago

I should note that this is with v0.3.14.0 and pandoc v2.19.2, because some of my other filters still require pandoc 2.x.

lierdakil commented 1 year ago

Took me a while to figure out what's going on, but this is basically a quirk of subfig package. You need \captionsetup[figure]{position=bottom}, because pandoc-crossref will put the figure caption after subfigures, and subfig will attach different code to the caption depending on where it expects to see it (before or after subfigures).

I'm contemplating setting this automatically, but this also affects caption spacing, which may lead to more subtle issues, so I'm tempted to opt for "if you write raw tex you know what you're doing" approach. What do you think?

Also, side note, generally you'd want to put setup into header-includes, in this case, wrapped in \AtEndPreamble, e.g.:

---
header-includes: |
  \AtEndPreamble{%
  \floatstyle{ruled}
  \restylefloat{figure}
  \restylefloat{table}
  \captionsetup[figure]{position=bottom}
  }
---
kohenkatz commented 1 year ago

@lierdakil Thanks for the quick reply. The "if you write raw TeX you know what you're doing" approach makes sense to me, though it would be good to document this tweak.

I will test this in my document today.

Thanks for the tip about header-includes. In my actual document, I'm putting these commands into the template itself (which had to be customized anyway for my university's requirements), and for the example that demonstrates the issue, I just did it as simply as possible.

kohenkatz commented 1 year ago

Someone on the tex.stackexchange.com site figured out a way to do it and keep the subfigure captions on the bottom, by replacing subfig with subcaption.

subfig.sty

\ProvidesPackage{subfig}[2023/03/20 v1.0 subfig -> subcaption]
\expandafter\let\csname ver@subfig.sty\endcsname\@undefined % needed for older versions of subcaption package
\RequirePackageWithOptions{subcaption}
\endinput
lierdakil commented 1 year ago

That seems a somewhat brittle hack.

The issue AFAIU isn't that the caption is on the bottom of figures, but rather that subfig thinks it's on the top (because ruled style typesets captions on the top). Now that highlights the fact that subfig is a bit of a bodge in more ways than one, but the workaround itself is relatively simple if a bit obscure.

There's an argument for switching pandoc-crossref to use subcaption altogether (there's even #182 asking for that, now that I think about it). I guess I'll give it some thought.