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

numbers of subfigures are off by one #392

Open jkittner opened 1 year ago

jkittner commented 1 year ago

sorry - I missclicked and submitted the issue too early.

this reproduces it

<div id="fig:coolFig">

![caption a](coolfiga.png){#fig:cfa width=30%}

![caption b](coolfigf.png){#fig:cfb}

Cool figure!

</div>

<div id="fig:niceFig">

![caption a](coolfiga.png){#fig:nfa width=30%}

![caption b](coolfigf.png){#fig:nfb}

Nice figure!

</div>

reference cool fig:

- entire cool fig [@fig:coolFig]
- sub fig a of cool fig [@fig:cfa]
- sub fig d cool fig [@fig:cfb]

reference nice fig:

- entire nice fig [@fig:niceFig]
- sub fig a of nice fig [@fig:nfa]
- sub fig d nice fig [@fig:nfb]

As you can see, the figure numbers itself are correct, but the sub figures are off by one grafik

jkittner commented 1 year ago

okay, I did a little more digging and it seems to be related with how you setup caption. When setting figureposition=top it is off by one, with figureposition=bottom it is correct.

\usepackage[
  font={stretch=1.2,small},
  textfont={color=caption-color},
  figureposition=top,
  skip=2mm,
  labelfont=bf,
  singlelinecheck=false,
  justification=$if(caption-justification)$$caption-justification$$else$raggedright$endif$
]{caption}

I remember this being quite a mess and having some sort of design flaw...

I'm not sure if this can actually be handled in any way?

lierdakil commented 1 year ago

Did pandoc change the latex template at some point? Because pandoc-crossref doesn't do this kind of caption setup... Ugh. That's pretty annoying, there seems to be no good way to test for regressions like this.

Yes, there's a design flaw with certain subfigure packages in latex, I remember having trouble with this a long time ago. Didn't touch latex in any meaningful capacity since, so not sure if e.g. switching to a different subfigure package would help. FWIW there's #182.

jkittner commented 1 year ago

I was using my own, modified template, so when using pandoc-crossref without any template or the default eisvogel template everything works as expected.

I got suspicious of what I was doing when I saw this test, which should catch any regression... https://github.com/lierdakil/pandoc-crossref/blob/master/test/m2m/subfigures-grid/input.md?plain=1 . but I'm still kinda surprised it gets the parent figure number right, but the subfigure ones not.

What I was also wondering is why the subfigures get no respective subfigure labels when placing them side by side i.e. like this

<div id="fig:niceFig">

![caption a](coolfiga.png){#fig:nfa width=49%}
![caption b](coolfigf.png){#fig:nfb width=49%}

Nice figure!

</div>

they do get the correct labels, if a third one, on a separate line is present

lierdakil commented 1 year ago

I was using my own, modified template, so when using pandoc-crossref without any template or the default eisvogel template everything works as expected.

Ah, I see. You got me worried for a minute there that it's broken by default and I need to scramble to make a patch-release.

test, which should catch any regression

Yeah, see, the problem is, this test checks that Markdown and raw LaTeX outputs match the expectation after applying pandoc-crossref, but it doesn't check that rendered LaTeX is correct, as there's no way in general to compare PDFs, at least not without jumping through a lot of hoops.

kinda surprised it gets the parent figure number right, but the subfigure ones not.

I've spent some time refreshing my memories of this mess, and basically here's the gist of it:

So... figurecaption=top is not the way to place figure captions at the top, it's just saying to caption and any dependent packages "hey, I'm going to place captions at the top of my floats, please adjust your internal workings accordingly". As pandoc will always place figure captions at the bottom, figurecaption=top doesn't work, it breaks spacing and (with pandoc-crossref) subfigure numbering.

why the subfigures get no respective subfigure labels when placing them side by side

They should? The example you've provided works fine with the default latex template, or at least it works as I would expect (ignore the fact there aren't actual images, I'm being a little lazy):

image

Could you elaborate on what you expect to happen and what actually happens?

lierdakil commented 1 year ago

To be clear, latex code for subfigures is generated by pandoc-crossref, so I can bodge something together to support figureposition=top for subfigures specifically. However, regular figures are handled by pandoc, and there's AFAICT no option to affect caption position, so stuff will sublty and not-so-subtly break anyway unless I basically reimplement latex writer (or at least significant parts of it), which I'd rather not do for obvious reasons.

jkittner commented 1 year ago

Could you elaborate on what you expect to happen and what actually happens?

the reproducer is this - the difference is whether the image is found or not

</div>

<div id="fig:niceFig_img_not_found">

![caption a](coolfiga.png){#fig:nfa width=33%}
![caption b](coolfigf.png){#fig:nfb width=33%}

Nice figure without images found

</div>

</div>

<div id="fig:niceFig_img_found">

![caption a](../t.png){#fig:nfc width=20%}
![caption b](../t.png){#fig:nfd width=20%}

Nice figure with images

</div>

<div id="fig:niceFig_img_found_three">

![caption a](../t.png){#fig:nfe width=20%}

![caption a](../t.png){#fig:nff width=20%}
![caption b](../t.png){#fig:nfg width=20%}

Nice figure with images

</div>

coming out like this: grafik

I build using docker

docker run --rm \
    --volume "$PWD/..:/data" \
    --user $(id -u):$(id -g) \
    --workdir /data/docs \
    pandoc/extra:latest-ubuntu \
    --filter pandoc-crossref \
    t.md \
    --output t.pdf
lierdakil commented 1 year ago

The exact snippet you provided renders fine on my end, despite stray </div>s, so the issue seems to be elsewhere:

image

For context:

$ pandoc-crossref --version
pandoc-crossref v0.3.16.0 git commit UNKNOWN (UNKNOWN) built with Pandoc v3.1.5, pandoc-types v1.23.0.1 and GHC 9.4.5
jkittner commented 1 year ago

okay, so I went down the entire rabbit hole and built everything from source in my own dockerfile:

FROM ubuntu:jammy

ENV DEBIAN_FRONTEND=noninteractive

RUN : \
    && apt-get update \
    && apt-get upgrade -y \
    && apt-get install -y \
        build-essential \
        curl \
        libffi-dev \
        libgmp-dev \
        libgmp10 \
        libncurses-dev \
        libncurses5 \
        libtinfo5 \
        libffi8ubuntu1 \
        zlib1g-dev \
        texlive-latex-base \
        texlive-fonts-recommended \
        texlive-fonts-extra \
        texlive-latex-extra \
        lmodern \
        pkg-config \
        ca-certificates \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

ENV BOOTSTRAP_HASKELL_NONINTERACTIVE=1

RUN curl --proto '=https' --tlsv1.2 -sSf https://get-ghcup.haskell.org | sh

ENV PATH="/root/.ghcup/bin:${PATH}"

RUN : \
    && ghcup install ghc 9.6.2 \
    && ghcup install cabal 3.10.1.0 \
    && ghcup install stack 2.11.1 \
    && cabal v2-update

RUN : \
    && cabal v2-install --install-method=copy pandoc pandoc-crossref --minimize-conflict-set \
    && cabal install pandoc-cli

ARG TEMPLATES_DIR=/.pandoc/templates

ENV PATH="/root/.cabal/bin:${PATH}"

RUN mkdir -p ${TEMPLATES_DIR} && \
    ln -s /.pandoc /root/.pandoc

ENTRYPOINT [ "/root/.cabal/bin/pandoc" ]

an guess what: everything works as expected: grafik

So the image pandoc/extra:latest-ubuntu is somewhat broken in regard to pandoc-crossref

it yields grafik

Sorry for wasting your time here. I was not expecting the docker image to be the problem and was hesitant to build the world from source...

Thank you so much for your time and effort here. Do you think it makes sense to report this upstream? Happy to hear your thoughts on this. Is it likely that it's just a crooked template?

lierdakil commented 1 year ago

I don't personally use pandoc/extra, but the description says it's using Eisvogel template. I never used it either, and I don't know if it's used by default, but if it is, there are a couple issues reporting incompatibilities: https://github.com/Wandmalfarbe/pandoc-latex-template/issues/304 https://github.com/Wandmalfarbe/pandoc-latex-template/issues/188. Probably it just needs some magic incantations in the preamble, but I currently don't have the bandwidth to investigate in detail, sorry.

If you only need LaTeX, chances are, you don't need pandoc-crossref, raw latex syntax will work. If you want to target multiple formats, and latex is a bit of an afterthought, pandoc-crossref will work out of the box with pandoc's default template. If you need fancy formatting in your latex output, you'll probably want to roll your own template by hand.