quarto-dev / quarto-cli

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

Figure rendered inside a table in MS Word when using fig-cap #4004

Open cscheid opened 1 year ago

cscheid commented 1 year ago

It'd be nice to change how this is laid out for the reasons pointed out, but we currently hard code that decision.

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

Originally posted by **jtrecenti** January 17, 2023 Hi! Thank you very much for developing Quarto. It is awesome. I was trying to tweak table styles in MS Word (painful, but needed) when I realized that this code: ``` --- title: "Untitled" format: docx --- Lets's see @fig-aaa. ```{r} #| label: fig-aaa #| fig-cap: a nice figure. plot(1:10) ``` generates this document: ![image](https://user-images.githubusercontent.com/1425970/213029492-7b20fb86-3247-4baf-9f60-700f2b276a63.png) Note the "+" sign on the top left of the image and the table styling options at the top menu, indicating that we are inside a table. So, apparently, when we use `fig-cap:`, it wraps the figure and the caption inside a 1-cell table. Two questions 1. Is this the desired behavior? 2. Is it possible to turn it off? Thanks!
cscheid commented 1 year ago

@rich-iannone tagging you here because you might know more about our options for laying out tables and captions in Docx. We can try and figure this out this later

cderv commented 1 year ago

I believe there is definitely another solution to this using OpenXML raw block and inline, probably with Custom Style.

For reference a quick research:

Out of curiosity, I looked into R Markdown solutions. This is how it works in the R Markdown ecosystem with officedown

---
title: "Untitled"
output: officedown::rdocx_document
---

Let's see Figure \@ref(fig:fig-aaa).

```{r}
#| label: fig-aaa
#| fig-cap: a nice figure.
plot(1:10)

![image](https://user-images.githubusercontent.com/6791940/213431744-3b1dab51-0423-4645-aaa5-1d06e3b542a6.png)

It is using openxml raw block for the image and caption, with a Div to set Custom Style to Image caption. This is powered by R 📦 **officer** which handles processing docx. 

<details>
<summary>intermediate `.md` file that will be converted by Pandoc </summary>

_Note: they are using Word bookmark feature for the cross referencing BTW. That is why the openxml is a bit more complex too_

````markdown
---
title: "Untitled"
output: 
  officedown::rdocx_document:
    keep_md: true
---

Let's see Figure `<w:hyperlink w:anchor="fig-aaa"><w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"><w:rPr/><w:fldChar w:fldCharType="begin" w:dirty="true"/></w:r><w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"><w:rPr/><w:instrText xml:space="preserve" w:dirty="true"> REF fig-aaa \h</w:instrText></w:r><w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"><w:rPr/><w:fldChar w:fldCharType="end" w:dirty="true"/></w:r></w:hyperlink>`{=openxml}.

```r
plot(1:10)
<w:p><w:pPr><w:jc w:val="center"/><w:pStyle w:val="Figure"/></w:pPr><w:r><w:rPr/><w:drawing xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships"><wp:inline distT="0" distB="0" distL="0" distR="0"><wp:extent cx="4572000" cy="3657600"/><wp:docPr id="" name="" descr=""/><wp:cNvGraphicFramePr><a:graphicFrameLocks xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main" noChangeAspect="1"/></wp:cNvGraphicFramePr><a:graphic xmlns:a="http://schemas.openxmlformats.org/drawingml/2006/main"><a:graphicData uri="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:pic xmlns:pic="http://schemas.openxmlformats.org/drawingml/2006/picture"><pic:nvPicPr><pic:cNvPr id="" name=""/><pic:cNvPicPr><a:picLocks noChangeAspect="1" noChangeArrowheads="1"/></pic:cNvPicPr></pic:nvPicPr><pic:blipFill><a:blip cstate="print" r:embed="C:\Users\chris\AppData\Local\Temp\RtmpeQYKx8\file6e4813c36032.png"/><a:stretch><a:fillRect/></a:stretch></pic:blipFill><pic:spPr bwMode="auto"><a:xfrm><a:off x="0" y="0"/><a:ext cx="63500" cy="50800"/></a:xfrm><a:prstGeom prst="rect"><a:avLst/></a:prstGeom><a:noFill/></pic:spPr></pic:pic></a:graphicData></a:graphic></wp:inline></w:drawing></w:r></w:p>

::: {custom-style="Image Caption"}

<w:r><w:rPr><w:rFonts/><w:b w:val="true"/></w:rPr><w:t xml:space="preserve">Figure </w:t></w:r><w:bookmarkStart w:id="e3aed75f-d52c-4dc6-af35-61a41e0ab084" w:name="fig-aaa"/><w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"><w:rPr><w:rFonts/><w:b w:val="true"/></w:rPr><w:fldChar w:fldCharType="begin" w:dirty="true"/></w:r><w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"><w:rPr><w:rFonts/><w:b w:val="true"/></w:rPr><w:instrText xml:space="preserve" w:dirty="true">SEQ fig \* Arabic</w:instrText></w:r><w:r xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml"><w:rPr><w:rFonts/><w:b w:val="true"/></w:rPr><w:fldChar w:fldCharType="end" w:dirty="true"/></w:r><w:bookmarkEnd w:id="e3aed75f-d52c-4dc6-af35-61a41e0ab084"/><w:r><w:rPr><w:rFonts/><w:b w:val="true"/></w:rPr><w:t xml:space="preserve">: </w:t></w:r>{=openxml}a nice figure. :::


</details>

OpenXML is not easy - but that would allow us to output specifically for Docx and Pptx support. 
* By inserting some from our Lua filter
* Or post processing the rendered docx with the help of new Lua Module `pandoc.zip`
cscheid commented 1 year ago

Unfortunately, this layout choice is dependent on whether we have subfigures vs not (and we only want to change the single-figure setup). This means 1) it's a bigger change than we expected and 2) there's crossref consequences. I'm making the call to hold this until the crossref work is done.

achetverikov commented 1 year ago

This is unexpected behavior. In addition, tables have default margins so that the figures aren't rendered full width when they need to.

dkgaraujo commented 1 year ago

Adding fuel to the fire: even when someone does want to render an image inside a table, the table comes out without borders. I'll try to add a small reprex later.

ldecicco-USGS commented 5 months ago

I think this is related:

If I were to make a Word doc on it's own - I can paste in a figure, right click to add a caption, and insert a cross-reference into the text. Later, if I paste in another figure earlier in the document, I can click "!Update Field", and the figure numbers and cross references in the text all get updated.

If instead I generate a Word doc via Quarto and send that Word doc to my non-Quarto-friendly co-worker - they cannot paste in a figure, and click update. So that means if I've generated hundreds of tables/figures - there's no native MS Word way to update the caption numbers and cross referenced text. Yes, I could tell my co-worker that they need to send me their figure and I'll re-generate the whole thing, but in a real case, there could be massive back-and-forth contributions from both sides.

Basically, it's a much bigger challenge that I expected combining Quarto-generated Word content (specifically figure and table numbering and cross referencing) with native-generated Word content.

jacobdum commented 3 months ago

I agree with @ldecicco-USGS, current implementation of captions via quarto prevents manual updating of captions and/or table of figures/tables in Microsoft Word. It is possible to insert the associated bookmark that quarto saves the caption as, but in doing so inserts the entire table, not just the caption.

As a possible way around the table of figures/tables, could styles be set differently for a captioned image vs a captioned table? Currently quarto outputs both as Image Caption and doesn't allow for differentiation for the table of figures/tables fields, but separate styles would alleviate this.

juanar97 commented 1 week ago

Hi! Might be related as well, but when I'm trying to export a table using Quarto and kable(), the table and caption are both nested within another table cell. The problem with this is that the 'pin the header row' option does not work. Below is a picture of the table formatting (this one doesn't need pinning the header row).

Captura de pantalla 2024-07-09 a la(s) 13 42 29

I've tried stripping it out of the YAML metadata, using gt() and flextable() and haven't been able to overcome this problem. Any ideas?