quarto-dev / quarto-cli

Open-source scientific and technical publishing system built on Pandoc.
https://quarto.org
Other
3.99k stars 328 forks source link

`fig-align` code cell option not supported in Typst #8767

Open mcanouil opened 9 months ago

mcanouil commented 9 months ago

Discussed in https://github.com/quarto-dev/quarto-cli/discussions/8766

Originally posted by **psads-git** February 17, 2024 Please, consider the following `quarto` document. The figure is not being centered. Am I doing something wrong? Thanks! ```` --- format: typst jupyter: python3 --- ```{python} #| echo: false #| fig-align: center import matplotlib.pyplot as plt import numpy as np # Data for plotting t = np.arange(0.0, 2.0, 0.01) s = 1 + np.sin(2 * np.pi * t) fig, ax = plt.subplots() ax.plot(t, s) ax.set(xlabel='time (s)', ylabel='voltage (mV)', title='About as simple as it gets, folks') ax.grid() plt.show() ``` ````
cderv commented 9 months ago

FWIW this what is produced in .typ

#block[
#block[
#align(center)[
#box(width: 363.75pt, image("index_files/figure-typst/cell-2-output-1.svg"))
]
]
]

and this usage of align for a box does not seem to work

We are adding this https://github.com/quarto-dev/quarto-cli/blob/ef60098748efbebbea4ad64e2b7008cda80abe85/src/resources/filters/quarto-post/typst.lua#L138-L157

So we should probably consider this a bug.

Also img has probably changed in pandoc 3.1.9 following this change: https://github.com/jgm/pandoc/commit/a67223c44219c5a6b2154a06dffedecdd26e925e

Typst writer: add #box around image to make it inline. (https://github.com/jgm/pandoc/pull/9149) An #image by itself in typst is a block-level element. To force images to be inline (as they are in pandoc), we need to add a box with an explicit width. When a width is not given in image attributes, we compute one from the image itself, when possible.

Related to these pandoc issues

cderv commented 9 months ago

changed in pandoc 3.1.9

Nope - we added fig-align after and more recently

So this is not fully working.

gordonwoodhull commented 9 months ago

As with the Typst table centering issue #8797, we need to either not add the two #blocks, or apply the centering at the top block associated with the figure.

I'm looking at these, any opinions are welcome.

One thing I have to sort out is that centering already seems to be the default, but our #blocks are causing them to align left.

cscheid commented 9 months ago

One thing I have to sort out is that centering already seems to be the default, but our #blocks are causing them to align left.

Right. And centering, I think, is a feature we would like to be consistent across formats (since it is for PDF and HTML right now).

The Pandoc AST shows this at the end of the processing:

  - t: "Div"
    attr: "('', ['cell'], ['execution_count,1'])"
    content:
      - t: "Div"
        attr: "('', ['cell-output', 'cell-output-display'], [])"
        content:
          - t: "Plain"
            content:
              - t: "RawInline"
                format: "typst"
                text: "#align(center)["
          - t: "Plain"
            content:
              - t: "Image"
                attr: "('', [], [])"
                caption: []
                src: "8767_files/figure-typst/cell-2-output-1.svg"
                title: ""
          - t: "Plain"
            content:
              - t: "RawInline"
                format: "typst"
                text: "]"

Each of those divs is becoming a block, and there's one block too many. The question is which we drop and why.

cscheid commented 9 months ago

Each of those divs is becoming a block, and there's one block too many.

I take it back - a local experiment shows that Typst needs both divs to be removed in order for the figure to display properly.

Furthermore, our trace shows that the #align()[] call is being introduced by src/resources/filters/quarto-post/typst.lua:138--157.

We should experiment with this and understand typst's layout algorithm well before coming up with a solution, but I think the problem we're seeing is that typst blocks need to be "top-level" for their alignment to work. For example, they might have some mechanism of justifying the widths of nested blocks so that "align" only makes sense if the parent block is wide enough.

In terms of our own AST, we already strip some divs from the output in some cases, see src/resources/filters/quarto-finalize/descaffold.lua. It might simply be that we need to annotate the div.cell and div.cell-output-display elements with .quarto-scaffold in Typst, so that they're not emitted in the final output.

gordonwoodhull commented 9 months ago

Yes, I think it may be centering within the parent block (or if none, the page), but I'll experiment some more to be sure, and compare with how LaTeX and HTML deal with this.

Agree centering should be consistent between formats.

Thanks for the pointers!

gordonwoodhull commented 5 months ago

I initially picked up this issue because it looked simple and I thought it would be a good way to learn about layout. I was correct about the second assumption. 😉

I made some progress back in March before switching to Typst CSS. It turns out we need to replace #show figure as described in typst/typst#1409

We have other reasons we need to do that e.g. cap-location: margin. I'll be focusing on Typst Layout in v1.6 so I will take care of this then.