11ty / eleventy

A simpler site generator. Transforms a directory of templates (of varying types) into HTML.
https://www.11ty.dev/
MIT License
17.13k stars 493 forks source link

Render <img> within <figure> rather than <p> in Markdown? #541

Closed danchristian closed 5 years ago

danchristian commented 5 years ago

My CMS outputs a raw markdown string. Images are inline and Markdown parses will force them to be wrapped in block elements. How can I get Eleventy to render images within <figure> rather than <p> tags?

Current <p><img></p>

Desired <figure><img></figure>

kleinfreund commented 5 years ago

You can write HTML in Markdown:

# H1

<figure>
  <img ...>
  <figcaption>...</figcaption>
</figure>
jevets commented 5 years ago

I'm in agreement with @kleinfreund.

But for posterity, you could add a markdown plugin, maybe this https://www.npmjs.com/package/markdown-it-implicit-figures

And see the Eleventy docs on adding markdown plugins https://www.11ty.io/docs/languages/markdown/#add-your-own-plugins

zachleat commented 5 years ago

(Thank you everyone for your replies here!)

This is an automated message to let you know that a helpful response was posted to your issue and for the health of the repository issue tracker the issue will be closed. This is to help alleviate issues hanging open waiting for a response from the original poster.

If the response works to solve your problem—great! But if you’re still having problems, do not let the issue’s closing deter you if you have additional questions! Post another comment and I will reopen the issue. Thanks!

disklosr commented 5 years ago

@kleinfreund that defeats the purpose of markdown. I solved this same problem using a markdown-it plugin (implicit-figures)

ghost commented 3 years ago

You can also use, for example (with Liquid), | replace on the {{ content }} - like so...

{{ content | replace: "<p><img", "<figure><img" | replace: "></p>", "</figure></p>" }}
writhisdown commented 3 years ago

thanks @mrdanielschwarz for the simple solution!

The built-in replace filter can swap out the "p" tag for any tag of your choosing, keeping your markdown simple

this worked for me inside my template file

{{ content | replace("<p><img", "<figure><img") | replace("></p>", "></figure>") | safe }}

ghost commented 3 years ago

Happy to help @writhisdown.

You can also replace <p> with absolutely nothing, if you want your images inline.

michelvanheest commented 1 year ago

For future visitors, this did the trick:

thanks @mrdanielschwarz for the simple solution!

The built-in replace filter can swap out the "p" tag for any tag of your choosing, keeping your markdown simple

this worked for me inside my template file

{{ content | replace("<p><img", "<figure><img") | replace("></p>", "></figure>") | safe }}

pdehaan commented 1 year ago

@michelvanheest I'm not sure those replace() filters will work as expected.

For example, if I have the following input file:

---
layout: custom.njk
---

text with ![](img.png)

![](fig.png)

works with links too:

[![](fig.png)](page.html)

*Peter* is __neat__

and a custom layout file of _includes/custom.njk that looks like this:

<main>
{{ content | replace("<p><img", "<figure><img") | replace("></p>", "></figure>") | safe }}
</main>

Then my output HTML file looks like this:

<main>
  <p>text with <img src="img.png" alt=""></figure>
  <figure><img src="fig.png" alt=""></figure>
  <p>works with links too:</p>
  <p><a href="page.html"><img src="fig.png" alt=""></a></figure>
  <p><em>Peter</em> is <strong>neat</strong></figure>
</main>

So it looks like it's aggressively adding </figure> tags where it shouldn't. You might want to look into something like https://www.npmjs.com/package/markdown-it-image-figures:

const implicitFigures = require("markdown-it-image-figures");

/**
 * @param {import("@11ty/eleventy/src/UserConfig")} eleventyConfig
 * @returns {ReturnType<import("@11ty/eleventy/src/defaultConfig")>}
 */
module.exports = function (eleventyConfig) {
  eleventyConfig.amendLibrary("md", mdLib => mdLib.use(implicitFigures));

  return {
    dir: {
      input: "src",
      output: "www",
    }
  };
};

OUTPUT

<main>
  <p>text with <img src="img.png" alt=""></p>
  <figure><img src="fig.png" alt=""></figure>
  <p>works with links too:</p>
  <figure><a href="page.html"><img src="fig.png" alt=""></a></figure>
  <p><em>Peter</em> is <strong>neat</strong></p>
</main>