Weird stray </p> (closing paragraph) tags

This is a post about this weird closing paragraph tag I am experiencing. The solution comes first, the questions in the end):

  • I have several shortcodes
  • The shortcodes contain valid HTML5 markup with block-tags on the outer side (either
    or )
  • Multiple shortcodes come after each other
  • BUG: the markdown processing adds a closing paragraph tag at the end of the list (only a closing tag, not an opening tag anywhere).
  • Sample:

    {{< activities >}}
    {{< onboardmenu >}}
    {{< enquiry >}}
    {{< cancellationterms >}}
    {{< packages >}}
    {{< call-to-action >}}
    

    (as I wrote, all shortcodes have (1) valid HTML and (2) block tags surrounding whatever happens in there.

    Result:

    The shortcodes are parsed correctly, but right behind the last closing tag of the call-to-action shortcode, I got my stray closing paragraph tag.

    The solution is easy:

    <div>
        {{< activities >}}
        {{< onboardmenu >}}
        {{< enquiry >}}
        {{< cancellationterms >}}
        {{< packages >}}
        {{< call-to-action >}}
    </div>
    

    Adding an extra block element around the group of tags will remove the stray-closing-p.

    My questions are:

    • who (Hugo, markdown, me) is making the wrong assumption?
    • why would the process add only the closing paragraph (there must be a bug in here somewhere)?
1 Like

I’d put my money on that being an issue in the shortcode parser in Hugo. We’ve had issues with this in the past.

I bet agsinst you. How much?

1 Like

What Hugo version are you using? I thought we added a good fix for this some Hugo versions back.

(about the money bet above; this may be shortcode related, but I wouldn’t blame the shortcode parser)

Right now I am using 0.49.2/extended. I never checked this specific code before that version. If you have a Bitbucket account I can let you on the repo to see the whole code.

This bug is still in Hugo v0.110.0. Fortunately the workaround presented here still works.

I am unable to reproduce the problem as originally described.

Try it:

git clone --single-branch -b hugo-forum-topic-14929 https://github.com/jmooring/hugo-testing hugo-forum-topic-14929
cd hugo-forum-topic-14929
hugo server

Tested with v0.110.0.

In the above example you can break it with:

Some text
{{< activities >}}
{{< onboardmenu >}}
{{< enquiry >}}

You need a blank line before the shortcode to end the paragraph.
This is fine:

Some text

{{< activities >}}
{{< onboardmenu >}}
{{< enquiry >}}

AFAIK, this isn’t a Hugo thing, it is a Markdown thing.

This:

Something
{{< activities >}}
{{< onboardmenu >}}
{{< enquiry >}}
{{< cancellationterms >}}
{{< packages >}}
{{< call-to-action >}}

Generates this:

<p>Something
  <div>layouts/shortcodes/activities.html</div>
  <div>layouts/shortcodes/onboardmenu.html</div>
  <div>layouts/shortcodes/enquiry.html</div>
  <div>layouts/shortcodes/cancellationterms.html</div>
  <div>layouts/shortcodes/packages.html</div>
  <div>layouts/shortcodes/call-to-action.html</div>
</p>

Which is expected due to the lack of blank lines between each entry.

But the original issue, “Weird stray </p> (closing paragraph) tags”, is no longer reproducible.

Also, when troubleshooting things like this, it is important to view source (trypically Ctrl+U) instead of using your browser’s dev tools. With the example above, Chrome’s dev tools displays this:

image

It is attempting to correct the HTML, because div elements are not allowed within p elements.

Well, that’s bizarre, I took the div wrapper out and the problem has stayed away. I did change some layout items to fix other HTML validation errors, I wonder if there’s some strange interaction going on there?

I wonder if there’s some strange interaction

I’m not sure what that would be. Perhaps you saw the closing tag and didn’t notice the opening tag.

If you took the div out and left a blank line a validation error might disappear because of that.

Even though the p tags are paired, it will fail validation if they are around a div.
Exact W3c validator phrase is:
Error : No p element in scope but a p end tag seen.

That error could easily be mistaken to mean there was an end tag but no start tag, in fact you get the same exact error if there really is a missing start tag.

So my guess is there was never a “weird closing </p> tag” - it was always a pair of p tags around stuff they shouldn’t be.

I think that’s it, yes. With no spaces between shortcodes, a succession of shortcodes get treated as a paragraph and wrapped in <p>…</p>. With blank lines between them, they don’t generate any paragraph tags at all. Which is kinda the opposite of what I’d expect, but I can make a note to tell the web dev team to be careful…

Not really. This is standard markdown behavior.

Able
was I
ere 
I saw
Elba.

Is rendered:

<p>Able was I ere I saw Elba.</p>

Yes, but

Able

was I

ere 

I saw

Elba.

is not rendered without any <p> tags. That’s the surprising part.

Yes, it is.

<p>Able</p>
<p>was I</p>
<p>ere</p>
<p>I saw</p>
<p>Elba.</p>

I’m not sure what you’re looking at…

Unless you indented your markdown 4 or more space, but that makes it a code block:

<pre><code>Able

was I

ere

I saw

Elba.
</code></pre>

Double negatives are hard to read!

Markdown will wrap pretty much everything in p tags. A single line of text is still a paragraph, just a short, one sentence, paragraph. Personally I don’t find it confusing but I suppose if you think of a “paragraph as a group of sentences” I get how it could be.

Just while we are on the topic of p tags and leaving lines in between.

If you use the new feature to not wrap images in p tags (so you can use figure elements for example) then you want to be careful to leave blank lines either side.
If you put two standard images with no line in between then they still get wrapped in a p tag.
i.e don’t do this:

![image1](image1.jpg)
![image2](image2.jpg)

do this:

![image1](image1.jpg)

![image2](image2.jpg)

There is a markdown linter for vscode, adding a ruleset to check I have blank lines around images is on my todo list.

Apparently I’m doing a terrible job of explaining what I find inconsistent and hence surprising. Let me give it one more try with an example you can render:

Empty lines between content-producing non-blank lines:

Activities

Onboard menu

Enquiry

Cancellation terms

Packages

Call to action

The above *does* wrap each piece of content in a paragraph element.

--------

Empty lines between content-producing non-blank lines:

{{< activities >}}

{{< onboardmenu >}}

{{< enquiry >}}

{{< cancellationterms >}}

{{< packages >}}

{{< call-to-action >}}

The above *does not* wrap each piece of content in a paragraph element.

My naive expectation would be that avoiding blank lines between things would be the way to avoid unwanted paragraphs, because blank lines are how Markdown indicates paragraph breaks. Whereas in fact, the way to avoid unwanted paragraph elements is to make sure you do have a blank line between each shortcode.

The normal lines of text are default markdown text, wrapping text as paragraphs makes sense.

Shortcodes are not wrapped so you choose what they do*. E.g. you don’t want to wrap figures in p tags for example in a figure shortcode.

*Including wrapping them in p tags if you wanted!

But they are. These get wrapped:

{{< activities >}}
{{< onboardmenu >}}
{{< enquiry >}}

That’s the problem. A sequence of shortcodes aren’t wrapped with paragraphs if you put Markdown paragraph breaks between them. If you don’t put Markdown paragraph breaks between them, they are wrapped in a paragraph. These two behaviors are inconsistent.

Is the rule that if you have two shortcodes in succession they count as a paragraph, but if you only have one shortcode it doesn’t?