In Markdown, is there a way to stop images from being wrapped with <p> tags?
Asked Answered
Z

4

17

I'm using Jekyll and all my posts are in .md format for convenience. The problem is that the generator is automatically wrapping every line in paragraph tags.

line

<img>

line

becomes

<p>line</p>

<p><img></p>

<p>line</p>

and this means that my images are restricted to the width I've set for my paragraphs, which is messing up my styles.

Any ideas what I can do to avoid this? I've tried both html syntax and markdown syntax for the images but nothing seems to work.

Thanks!

Zaria answered 27/6, 2014 at 15:54 Comment(2)
If you can't avoid the <p> getting used, then redefine <p> to be as blank as possible. Create a new tag to replace <p> for where it's intended to be used and styled.Jerrelljerri
I don't want to destroy semantics entirely, though :) Any other options specifically with jekyll?Zaria
H
11

I don't think so. The original Markdown spec says:

A paragraph is simply one or more consecutive lines of text, separated by one or more blank lines.

It might be possible to come up with some nifty CSS to fix your styling issues though.

Or you could try this hack (works in Pandoc):

line

<div><img></div>

line
Highminded answered 27/6, 2014 at 16:21 Comment(0)
T
11

Images are inline elements, intended to reside within a block-level element like a paragraph. Markdown parsers are therefore correcting your ‘mistake’ and wrapping the img inside a paragraph tag.

Wrapping your img tag inside an appropriate block-level element, like figure should prevent this behaviour. Eg:

<figure><img src=""></figure>

If you want to automate things a little and you are not planning to generate your site on Github pages (where plugins are not allowed) then you can make use of a plugin to assist in this and make image insertion in your posts easier. I'm using a modified version of this plugin:

https://github.com/opattison/jekyll-figure-image-tag/blob/master/figure_image_tag.rb

Triturate answered 2/7, 2014 at 8:35 Comment(0)
D
1

As other's have said, images are inline elements and Markdown parsers will force them to be wrapped in block level elements. The currently accepted answer is hacky: it looks messy in your markdown, is not robust/extensible, and is not easily modifiable. I use Middleman for my blog and created a partial for my images that does everything I could want an image to do. I assume/hope Jekyll has partials as well and that this answer, although varying from Jekyll in syntax, will still be relevant to you.

Note that I prefix my image links if they don't begin with "http://", "https:/" or "/". This is because I have a solid organizational structure for my blog's images, and makes it simpler when using this partial, I just need the image name and no other parts of its path.

Here is the partial:

partials/_image.erb

<%
#initialize local variables in case they were not included
caption ||= ""
alt ||= ""
classes ||= ""

#strip '.html' extension off article link to get name of folder
url = current_article.url
url_without_ext = url[0..url.length-6]

#determine if image has an exact link or belongs to "/images/blog/CURRENT_ARTICLE_NAME/"
prefix = src[0..6]
if prefix != "http://" and prefix != "https:/" and src[0] !="/" then
  #image belongs to "/images/blog/CURRENT_ARTICLE_NAME/" - add prefix to src
  src = "/images#{url_without_ext}/#{src}"
end
%>

<!-- Use Kramdown's 'nomarkdown' tag so that this figure is not wrapped in a 'p' tag in the blog pages that use this partial -->
{::nomarkdown}
<figure class="<%= classes %>">
  <!-- Show the image and link to the full resolution on click-->
  <a target="_blank" href="<%= src %>" >
    <img src="<%= src %>" alt="<%= alt %>">
  </a>

  <figcaption><%= caption %></figcaption>
</figure>
{:/}

And call this partial like so

No prefix will be added:

<%= partial "partials/image.erb", locals: {
    src: "/images/icons/tech/atom.svg",
    alt: "Atom",
    classes: "icon" } %>

Prefix will be added:

<%= partial "partials/image.erb", locals: {
    src: "my-lovely-dog.svg",
    alt: "Dog",
    caption: "Woof woof!",
    classes: "icon" } %>

I keep this partial up to date here (in case I add/edit any of it).

Dorsy answered 8/1, 2017 at 0:53 Comment(0)
B
0

Here's some javascript that'll unwrap them for you:

const allPTags = document.querySelectorAll("p");

allPTags.forEach((elem) => {
    if (elem.innerText === "" && elem.childNodes.length === 1 && elem.childNodes[0].tagName === "IMG") {
        elem.parentNode.insertBefore(elem.childNodes[0], elem);
        elem.remove();
    }
});
Biodegradable answered 4/5, 2021 at 23:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.