Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Explicit Figure element in Block #3177

Open
jgm opened this issue Oct 23, 2016 · 64 comments · May be fixed by jgm/pandoc-types#83
Open

Explicit Figure element in Block #3177

jgm opened this issue Oct 23, 2016 · 64 comments · May be fixed by jgm/pandoc-types#83

Comments

@jgm
Copy link
Owner

jgm commented Oct 23, 2016

Currently we represent figures in the AST using this hack: a figure is an Image whose title attribute starts with fig: and which is by itself in a Para.

Short of a full-featured figure environment in the AST, it would make sense to move to a less hacky representation: a Div with class figure containing the image (which need not have a title starting with fig:). This would involve changes to readers and writers.

Indeed, if we did this, we could support figures containing multiple images, via explicit Divs.

@jgm
Copy link
Owner Author

jgm commented Oct 23, 2016

Another advantage is that attributes could be added explicitly to the Div.

<div class="figure floatRight">
![my image](img.jpg){.imageclass}
</div>

See #3094.

@hrehfeld
Copy link

hrehfeld commented Oct 24, 2016

Seconded, I just spent an hour figuring out why multiple images in a paragraph don't create a figure. Is there any way to create a figure with multiple images right now? (I guess creating Rawblocks will work?)

Relevant code is here? https://github.com/jgm/pandoc/blob/master/src/Text/Pandoc/Writers/HTML.hs#L450 Why is the match only for one image and not multiple ones in the first place?

@jgm
Copy link
Owner Author

jgm commented Oct 25, 2016

If multiple images were allowed, which one would form the figure's caption? (There is only one caption.) What would determine how the images are arrayed in the figure? In retrospect, some kind of more explicit syntax for figures would have been desirable, and maybe that's the direction we should move in.

@hrehfeld
Copy link

hrehfeld commented Oct 25, 2016

Layout: Hm, I only use html and latex backends, but both of those handle multiple images in a figure in a reasonable way without extra specification. However, in latex IIRC it makes a difference if there is a SoftBreak between images (break vs. no break). IMHO it would be up to the writer/backend to break up figures if multiple images are not supported.

Caption: None unless explicitely stated? That's legal in both html and latex iirc. However I believe Paras do not support extra data like attrs, so that a div or figure node would be easier.

@jgm
Copy link
Owner Author

jgm commented Oct 25, 2016

+++ Hauke Rehfeld [Oct 24 16 16:42 ]:

Seconded, I just spent an hour figuring out why multiple images in a
paragraph don't create a figure. Is there any way to create a figure
right now (I guess creating Rawblocks will work?)

You can paste the images together into one image, I suppose,
or use a filter.

Relevant code is here?
[1]https://github.com/jgm/pandoc/blob/master/src/Text/Pandoc/Writers/HT
ML.hs#L450 Why is the match only for one image and not multiple ones in
the first place?

Good question. I suppose that since I'm in a field where
pictorial figures aren't used much, I didn't realize how
common figures with multiple images and a single caption
are.

But how would it work to allow a paragraph with multiple
images (and nothing else) to form a figure? From which
image would the figure's caption be taken? What determines
how the images are arranged in the figure (side by side,
in a square, etc.)?

Really we need a more explicit syntax for figures if this
kind of thing is going to be allowed.

@jgm
Copy link
Owner Author

jgm commented Feb 26, 2017

I think we need an explicit Block element for Figure.

@jgm jgm added the AST change label Feb 26, 2017
@mb21
Copy link
Collaborator

mb21 commented Feb 26, 2017

The question is whether this figure element should only contain images, or if it should be a general floating-container more analogous to the LaTeX \begin{figure} and HTML5 figure elements (emphasis added):

Usually a <figure> is an image, illustration, diagram, code snippet, etc., that is referenced in the main flow of a document, but that can be moved to another part of the document or to an appendix without affecting the main flow.

If so, the figure element should contains a caption (multiple paragraphs allowed) and arbitrary block content:

Figure Attr [Block] [Block]

@jgm
Copy link
Owner Author

jgm commented Feb 26, 2017 via email

@jgm jgm added this to the pandoc 2.0 milestone Aug 15, 2017
@jgm
Copy link
Owner Author

jgm commented Aug 20, 2017

Development on figures branch for pandoc, pandoc-types.

@jgm
Copy link
Owner Author

jgm commented Aug 20, 2017

Thinking about about explicit Markdown syntaxes for figures.

If we had a native syntax for divs, we could treat any div with a following caption as a figure:

;--- {#foo .right}
![my image](img.jpg){.imageclass}
![second image](img2.jpg)
;---
^^  [This is the optional short caption.]
    This is the long caption. It can span multiple blocks. 
    Syntax like footnotes.  

    Subsequent paragraphs indented.  We automatically treat a
    div as a figure if it is followed by a caption.  Or is it
    too confusing if the caption comes outside the div?

Another possibility would be to have a special kind of marking for figures, like:

!--- {#foo .right}
![my image](img.jpg){.imageclass}
![second image](img2.jpg)

[This is the optional short caption.]
This is the long caption. It can span multiple blocks. 
Syntax like footnotes.  

In this version, all the Para elements at the end of the
structure are treated as the caption,
so we don't need an explicit syntax to mark the caption.
!---

I'm trying to avoid syntaxes that require you to use the word figure.

I like the ^^ syntax for attaching captions; we might want to use this for tables as well (INS: and code blocks) if we use it for this.

@jgm jgm changed the title Better handling of implicit figures Explicit Figure element in Block Aug 20, 2017
@jgm
Copy link
Owner Author

jgm commented Aug 20, 2017

TODO on figures branch on pandoc and pandoc-citeproc

  • Finish updating writers to handle Figure
  • Update readers
    • RST
    • Markdown
    • LaTeX
    • HTML
    • Org/Blocks
    • MediaWiki
  • Get everything to compile
  • Update tests
  • Update ToJSON, FromJSON instance in pandoc-types to include Figure, Caption
  • Update Arbitary in pandoc-types (it lacks Div, Figure, Span, probably others)
  • Markdown syntax, new extension?
  • Figure numbering and internal refs?

@jgm
Copy link
Owner Author

jgm commented Aug 20, 2017

Having second thoughts about the type now. I suspect that allowing ANY kind of block content inside a figure is not going to work well in many output formats. E.g. in docbook, only certain elements are allowed inside a figure element. http://tdg.docbook.org/tdg/4.5/figure.html

Perhaps instead the contents should be limited to a list of images (or perhaps a list of lists of images, so they can be organized on lines? -- though it may be better to let the layout happen automatically, given width information).

Perhaps listings could go in figures as well?

@jgm
Copy link
Owner Author

jgm commented Aug 20, 2017

I think I'm going to remove this from the 2.0 milestone as it still needs more thought.

@jgm jgm removed this from the pandoc 2.0 milestone Aug 20, 2017
@mb21
Copy link
Collaborator

mb21 commented Aug 21, 2017

Having second thoughts about the type now. I suspect that allowing ANY kind of block content inside a figure is not going to work well in many output formats.

I still think taking the most general approach in the AST makes sense. There are always going to be some formats that don't support certain things, but that should be handled by the respective writers and the AST design shouldn't be held up by those. It would be great to have a general block figure element to output to HTML/ePUB/LaTeX...

@mb21
Copy link
Collaborator

mb21 commented Aug 21, 2017

Concerning the caption syntax, I kind of prefer the second one, since it is clearly placed inside the figure/div element. A third variant:

;--- {#foo .right}
![my image](img.jpg){.imageclass}
![second image](img2.jpg)
;--
This is the long caption. It can span multiple blocks. 

Syntax like footnotes.  
;--
This is the optional short caption.
Since it's optional, it needs to go at the end in this syntax.
;---

@jgm
Copy link
Owner Author

jgm commented Aug 22, 2017

What kinds of things do people really put in figures, besides images?

@mb21
Copy link
Collaborator

mb21 commented Aug 23, 2017

Maybe the element I have in mind is more of a Float than a Figure.

Again the MDN extract posted above:

Usually a <figure> is an image, illustration, diagram, code snippet, etc., that is referenced in the main flow of a document, but that can be moved to another part of the document or to an appendix without affecting the main flow.

And from Wikibooks LaTeX/Floats:

Floats are containers for things in a document that cannot be broken over a page. LaTeX by default recognizes "table" and "figure" floats, but you can define new ones of your own (see Custom floats below). Floats are there to deal with the problem of the object that won't fit on the present page, and to help when you really don't want the object here just now.

Floats are not part of the normal stream of text, but separate entities, positioned in a part of the page to themselves (top, middle, bottom, left, right, or wherever the designer specifies). They always have a caption describing them and they are always numbered so they can be referred to from elsewhere in the text.

Usually it's tables and images that are floated, but it could also be source code, a poem, some sort of aside box etc. Even Docbook has a sidebar element.

Maybe the table AST element shouldn't have a caption, only the Figure element should have a caption. Current markdown table syntax with captions would be converted to Figure attr caption [Table a]. With the attr specifying whether the figure should float or be at that fixed position in the text, plus whether to list it in the list of figures/list of tables etc.

Summarizing, a Figure is an element that:

I think it would be great to have the figure type in the AST for pandoc 2.0. Writing the code for the writers and reference generators etc. can be done later.

@jgm
Copy link
Owner Author

jgm commented Aug 23, 2017 via email

@mb21
Copy link
Collaborator

mb21 commented Aug 26, 2017

I'm leaning currently towards the second option (general float/caption container). Use cases include floating more than just images (e.g. float two tables that share a caption), or having one figure with a caption, that contains subfigures (or images) with each having a caption, e.g:

It's probably true that it gets a bit trickier to consider all cases in all writers, but it is a more flexible option.

@Crissov
Copy link

Crissov commented Jul 6, 2020

Captions

Markdown and HTML (and MediaWiki etc.) support six heading levels, plain Latex supports up to seven named levels (\part, \chapter, \section, \subsection, \subsubsection, \paragraph, \subparagraph). Most authors reserve the top level for single use at the start of the document, i.e. as title (although HTML and Latex have different dedicated markup for them), if they use it at all. Most styles guides tell writers to avoid more than three heading levels, but in technical documents deeply nested hierarchies do occur. The general syntax could support deeper levels as well: just repeat the prefix (and optional postfix) character # more often.

My point is, captions could use the lowest heading level already available

###### Caption

![text](target) 

or another level could be introduced for them, systematically:

####### Caption

![text](target) 

Contents

In modern forum, blog and chat software and social websites, plain links are often automatically converted to informative “cards” by fetching metadata like title, author and cover image. Links to media files, audio and video recordings in particular, are also displayed with embedded playback controls. These can hardly be distinguished, conceptually, from traditional (floating) figures.

I therefore suggest that implicit figures shall support any number and combination of links ([foo](bar), [foo][baz], [foo][], [foo], <bar>) and embedded media (![foo](bar), ![foo][baz], ![foo][], ![foo]) as long as they are the only contents of a paragraph. In practice, authors will often put each one in a line of its own, but this, probably, cannot be relied upon.

A single, complex figure:

![text](target)
![text](target) 

Another single, complex figure:

![text](target)![text](target) 

Two simple figures:

![text](target)

![text](target) 

@lierdakil
Copy link
Contributor

lierdakil commented Jul 6, 2020

@Crissov Pandoc Markdown does not have a limit on header level. Additionally, many other formats don't either, and we want Pandoc Markdown to be (at least somewhat) interoperable with those. So that's a hard blocker to your proposal.

@hubgit
Copy link

hubgit commented Jul 14, 2020

It would be great to see support for figures as essentially wrappers that associate a caption with some content.

Both HTML and JATS XML allow a fairly wide range of content inside their <figure>/<fig> elements, including media, diagrams and equations, and it would be extremely useful if this was preserved when converting between formats.

@despresc
Copy link
Contributor

despresc commented Sep 5, 2020

Just to collect some thoughts from reading the thread above and looking through some of the supported formats:

There are two sorts of figures. One type is a floating captioned container, which would most easily have this type in Pandoc:

-- Caption from Table could be removed.
data Block
  = ...
  | Figure Attr Caption CaptionPos FigureWidth [Block]
  ...

-- A Figure with [Table...] or [CodeBlock...] content could be a
-- captioned table or listing (for numbering or in output, if there
-- are separate captions for those elements).
-- Not sure how the Figure and Table Attrs would be handed in 
-- HTML output in that case. Just use the Figure's? Or merge.

-- A Figure with [Plain [Image...]] content (or a Figure with 
-- a sequence of those figures as content) could be a 
-- gallery-type figure (the second kind).

-- Caption position is frequently customizable
data CaptionPos = CaptionBelow | CaptionAbove

-- The figure width is necessary for subfigures in many formats.
-- Handling it like Table columns (fractions of the enclosing
-- container width) should work.
data FigureWidth = FigureWidth Double | FigureWidthDefault

Some support for this type of figure, that I know of:

  • HTML5 has a <figure> with any sort of content, including nested tables and figures.
  • LaTeX has the figure environment for figures that can have a lot of block-like content in it, but not figures or tables. There is the popular subcaption package that allows for subfigures and subtables, but isn't designed for further nesting. (It seems subfigures can be nested, since they're implemented with minipage, but the caption numbering doesn't work properly). That package may also not work with some journals' templates, from what I've read.
  • DocBook has a <figure> element that allows a lot of block-like content, but forbids figures, tables, equations, and examples in it. DocBook 5.2 seems to have a <formalgroup> element for grouping figures (allowing for one level of figure/table nesting level like LaTeX).
  • JATS seems to support <fig-group> and <fig> elements that work sort of like the corresponding elements in DocBook 5.2, according to the archiving tag set.
  • ConTeXt has floating environments with optional captions, I think. Not sure how well they work when nested.

The other type of figure is like an image gallery: either a single captioned image, or a sequence of captioned images that can be collectively captioned. (There are also grid versions, but the sequence version seems more popular). This has the type:

-- Not sure if FigureWidth is desirable for Figure itself 
-- in this version (Table doesn't have it).
data Block
  = ...
  | Figure Attr Caption CaptionPos FigureWidth Figures
  ...

-- The [Inline] is for alt text like Image has, but this could be Text
-- instead, since the caption can be put into Caption.
data Figures
  = OneFigure Attr [Inline] Target
  | Gallery [Subfigure]

-- Same remarks on [Inline] vs Text for the alt text apply here
data Subfigure = Subfigure Attr Caption CaptionPos FigureWidth [Inline] Target

Some support for this type of figure:

  • Any of the formats that support the first kind of figure.
  • LaTeX also has the older subfig package that can handle this kind of gallery figure, which has the virtue of being more compatible with some journal templates, again from what I've read.
  • ConTeXt has combinations.
  • MediaWiki has galleries.

The first (container) type has the advantage of expressiveness, but most writers that support figures would need to decide how to deal with unsupported Figure use (mostly detecting and handling too-deep nesting).

The second (gallery) type has the advantage of not requiring the writers to come up with fallback strategies, certainly not as often. It's also a bit easier to deal with it (no detecting if a Figure represents a captioned Table or CodeBlock). But it is less expressive.

@despresc
Copy link
Contributor

despresc commented Sep 5, 2020

The second (gallery) version could be a grid, but I don't know how well that's supported in the outputs. Possibly support could be added with whatever native tables the output supported, if there wasn't native support for the grid version.

@hrehfeld
Copy link

hrehfeld commented Sep 7, 2020 via email

@despresc
Copy link
Contributor

despresc commented Sep 7, 2020

That is my understanding of HTML5 figures as well.

The figure element represents some flow content, optionally with a caption, that is self-contained (like a complete sentence) and is typically referenced as a single unit from the main flow of the document.

From the spec. Both it and MDN mention that it can be (or usually is) used for content that can be moved elsewhere without affecting the main flow of a document, and is best referenced in the text with a label like "Figure 7" so it can be moved. That's how floats are used in LaTeX, though LaTeX is much happier to move floats around by default than web browsers are figures, and will automatically put "Table 3" or "Figure 2" in the caption for you.

I also prefer the semantically cleaner container version of figures. Their recursive structure does mean that figures inside Pandoc may be nested more deeply than figures are allowed in the output, so it's important to know what extensions (LaTeX packages and the like) can be used in the outputs to deal with nested figures.

@despresc
Copy link
Contributor

despresc commented Sep 7, 2020

The HTML writer currently has to deal with the fact that HTML headings only go up to h6. Its fallback when encountering a Header past 6 is to render it as a paragraph with the heading class.

So, eventually, the writers that have depth-limited figures and tables could keep track of the current figure depth. If they encounter too-deep nesting, they could convert the Figure to a Div containing its body and a Div caption (with appropriate classes), then attempt to render that. Otherwise they would render figures (and tables and galleries) however they're supported in the output.

Initially, of course, every writer would need to fallback in this way, except for figures with [Table...] and [Plain [Image...]] content, which would be rendered as tables and figures currently are. Then better support (for figures, subfigures, subtables, and galleries) could be added to the relevant outputs.

@tarleb
Copy link
Collaborator

tarleb commented May 6, 2021

See #6782 for important info on accessibility.

@tarleb
Copy link
Collaborator

tarleb commented May 6, 2021

Noting that #5994 depends on this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Development

Successfully merging a pull request may close this issue.