pandoc
pandoc copied to clipboard
Link attributes on implicit figures
Hi, figures in their own paragraph get marked up to become implicit figures wrapped in a <figure>
element. Images can also receive link attributes. When inline it makes sense to apply the atribute to the <img>
, but I don't think this assumption is ideal for implicit figures:
> pandoc
{.nofloat}
<figure>
<img src="fig.png" alt="Fig. 1" class="nofloat" /><figcaption>Fig. 1</figcaption>
</figure>
I think it would be more useful to treat the containing <figure>
itself as the target for the attributes for implicit figures:
<figure class="nofloat" >
<img src="fig.png" alt="Fig. 1" /><figcaption>Fig. 1</figcaption>
</figure>
The implicit figure should treat image and caption as one "unit".
I see how this might be handy for the class and id attributes, but some attributes like e.g. width
and height
should probably continue to go in the img
tag...
Yes, the #id and .class are all that really should be applied to the implicit <figure>
.
One could be to apply at least the class to BOTH <img>
and <figure>
and then use CSS rules to override behaviour for each element even though they have the same class.
If there was a parent selector in CSS we could also target a <figure>
that was the parent a img.class but this is not possible I think...
Or maybe ![](){.myclass}
should be converted to:
<figure class="myclass-figure">
<img class="myclass">
</figure>
That is a neat solution!
I don't think an image class/id is necessary. The image can be targetted using css as follows:
figure.myclass > img
This keeps things simpler.
I am interested in having this feature for use with the pandoc-fignos/eqnos/tablenos filters.
@tomduck that is how it probably should have been from the beginning but I think doing that now would wreak havoc in many documents.
@mb21 would you accept a PR adding a class to the figure with "Figure" appended to the given class name?
@madgen, I still think that approach would work for us, but @jgm merges pull request.
P.S. In light of https://github.com/jgm/pandoc/pull/4009 it should probably be myclass-figure
(i.e. append -figure
)
The proposed solution handles class
but not id
. What about id
?
I find the -figure
suffixed classes a bit inelegant. I'd rather move all the classes and the id to the figure, but I'm worried that this would break things that work now.
@jgm I agree it is inelegant but sadly it certainly would break existing documents. I can amend #4269 to behave the same way with IDs if you like?
Meanwhile for others struggling with this, here's an ugly JS workaround based on @mb21's solution to the problem.
var figures =
Array.prototype.slice.call(document.getElementsByClassName("figure"),0)
.concat(
Array.prototype.slice.call(document.getElementsByTagName("figure"),0));
for (var i = 0; i < figures.length; i++) {
var figure = figures[i];
var imgs = figure.getElementsByTagName("img");
if (imgs.length > 0) {
classes = imgs[0].classList;
for (var j = 0; j < classes.length; j++) {
figure.classList.add(classes[j] + "-figure");
}
}
}
I find the
-figure
suffixed classes a bit inelegant. I'd rather move all the classes and the id to the figure, but I'm worried that this would break things that work now.
I'm afraid those are the only two options that come to my mind.
Hi, I thought I could work around the issue using a small filter but the problem (as far as I understand) was that there is no placeholder for such information inside Image.
Though the output contains figure
and figcaption
, the native data is Image
and there is no placeholder for the class data to move into.
I don't know much about the internals but is it possible to have kind of "container attribute" field or similar inside Image data structure so that it ensures backward functionality as well as providing some extensibility?
With a bit of additional field, the following command may be able to put hello
class to there.(no loss of information!)
pandoc -f html -t native
<figure class="hello"><img src="foo.png"><figcaption>bar</figcaption></figure>
[Para [Image ("",[],[]) [Str "bar"] ("foo.png","fig:")]] --> today
[Para [Image ("",[],[], ["hello"]) [Str "bar"] ("foo.png","fig:")]] --> with modification
In reverse scenario, pandoc can still push those information to img
element as usual(to keep the behavior) and a small filter can move that information to its intended place if necessary. The following is just an example. (probably, the actual implementation would be different)
pandoc -f markdown -t native
![](){.hello}
[Para [Image ("",["hello"],[]) [] ("","")]] <-- today
[Para [Image ("",["hello"],[], []) [] ("","")]] <-- with modification, a filter can move that to new location like below
[Para [Image ("",[],[], ["hello"]) [] ("","")]]
I started using Pandoc recently for epub3 generation and it gives me a lot of fun and pain :) This is my first comment and please pardon my showing gratitude in issue thread.
Thank you @jgm. My highest respect to you.
Regards,
@minsu - when we get around to adding an explicit Figure element (#3177), this issue will go away. That's the right AST change to solve the problem. In the mean time, one must use ~~filters and the like...~~ (EDIT: of course you're right, filters don't really help).
EDIT: a better workaround is to use a fenced div.
::: {.figclass}
{.imgclass}
:::
This will give you (in epub/html)
<div class="figclass">
<figure>
<img class="imgclass"...
and you can use CSS .figclass figure
to style the figure.
@jgm, Thanks for your suggestions.
Just ended up with regex hacks on xhtmls and rezipping the files.(A Korean ebook to be published on 14th. Pandoc rocks.) Fenced divs seem Swiss army knives for sure and I didn't know that I could put markdown inside(!). Great~
Best,
After reading relevant threads and having used Pandoc for epub3 generation, I think having a separate Figure element won't solve the problem clearly. Here is my thought about the situation and 2-cent proposal to solve this problem and others without adding Figure
or similar.
background
First of all, the intention of attaching attributes to the markdown syntax is vague and I think it is reasonable to attach those attributes to img
as before.
Also, though having a separate element per necessity is of some use, but on going trend is custom element for better javascript control and custom presentation. Most markup languages don't support this custom element trend. and the following proposal may turn out to serve various cases.
add custom element designation to fenced divs
Fenced divs are .. just div
s but I think it would be great if we can specify the element itself (default is div
). Even for EPUB3, there are various recommendations that specify exact elements for specific purposes. So how about adding one more syntax to the {}
? As far as I understand the most basic text pattern wasn't assigned yet and it is just "letters" without #
, .
, =
. Here is an example for the figure case:
::::: {figure .class1 .class2 attr1=val1}
{.imgcls}
::: {figcaption}
Fig.1 Hello Image
:::
:::::
this translates into (thanks to nested divs!)
<figure class="class1 class2" attr=val1>
<img class="imgcls" src="hello.jpg" alt="Hello">
<figcaption>Fig. 1 Hello Image</figcaption>
</figure>
I understand that this may be too much verbosity but this may open great opportunity to filters and those who use Pandoc for precise HTML construction(not only the presentation but the details of structure and elements) Also, we don't have to concern about figure
with markdown image markup. I think the actual problem was due to translating images into figure blocks, which is nice but not consistent.
EDIT. For example, EPUB3 recommends to put short description in alt
and to put a detailed description in figcaption
. Also for Aria accessibility, it is also recommended to role
in img element and to blank alt
if the image itself is not important. In these various cases, simple div
s don't help much.
Best,
Minsu
@minsu You present an alternative proposal, but you don't say why you think a Figure element in the AST would solve the problem. (EDIT: a Figure element could be rendered to HTML in exactly the way you describe above, and the role
attribute could even be added.)
The alternative proposal is nice in many ways. One drawback is that it requires the use of English words (figure
, figcaption
), which is something we've tried to avoid in designing pandoc's syntax. Other writers would also have to be taught what to do with these words.
@jgm First of all, sorry about my unclear proposal that may have confused you.
My proposal is not specific to Figure
element but to change "fenced divs" to "custom element defaulting to div" element. It is not specific to figure
element but is more general mechanism for custom element. So, in summary:
- No
Figure
AST element for![](){}
markup. - Keep {} attributes to
img
element as before. (no sudden change of interpretation) - Extend fenced divs to let users designate specific element including custom element if
div
is not what he/she wants. - Even for EPUB3 conversion, the default behavior is not to have
figure
container automatically but it faithfully converts toimg
element and attach all properties to it. - No English word learning barrier involved. I guess.
This will incur a few drawbacks but may open good opportunity for filters. If applied correctly, this generic Div
AST element may be more widely used in handling wrapping scenarios as well like automatically adding Div
element if necessary. For example, even if fenced divs are not used in figure
issue, Pandoc may be able to wrap it with generic Div
element with element designation of figure
and putting another Div
element of figcaption
that will translate into figure
, figcaption
element in EPUB3 generation accordingly. Also, converting from HTML, if unknown element is met, Pandoc may create this generic Div
element with that specific element name with all the supplied attributes in it.
for example, Instead of:
pandoc -f html -t native
<address class="hello">Hi</address>
[Plain [Str "Hi"]]
this can be translated into:
pandoc -f html -t native
<address class="hello">Hi</address>
[Div [Str "Hi"] ..["hello"] ... ['address']] <-- `hello`, `address`are saved somewhere.
Regards,
With the new CSS :has pseudo-class it's possible to target the parent element like the following:
Markdown
{.nofloat}
HTML
<figure>
<img src="fig.png" alt="Fig. 1" class="nofloat"/><figcaption>Fig. 1</figcaption>
</figure>
CSS
figure:has(img.nofloat) {
/* Styles for <figure> with an <img class="nofloat"> inside */
}