As @robsonsobral commented in the original issue #1025 that added this "functionality", this is really non-standard, confusing behaviour. Why was it added in? More importantly, can it be removed, or put behind a config option?
For context, refer to this commit be627fa718d23278aeb53da5651a8a4a1be14c27. Hugo manually strips the leading and trailing paragraph tags, thereby rendering the markdownify function useless for any string that contains block level markdown.
This can cause major bugs! For example, if your yaml frontmatter looks like this:
somekey: |
This is a **valid** markdown paragraph.
This is another **valid** markdown paragraph. And it's *still valid yaml!*
someotherkey: 2
markdownify will output the following, incorrect HTML, where the opening tag for the first paragraph, and closing tag for the last paragraph are missing!
This is a <strong>valid</strong> markdown paragraph.</p>
<p>This is another <strong>valid</strong> markdown paragraph. And it's <em>still valid yaml!</em>
You are right, that was a bad idea -- I'm not sure what I was thinking.
Or, thinking about it -- I'm not sure. The main use case for markdownify is for titles etc. and not blocks of test, and it is easier to add p tags than it is to remove it from a template.
Can we have a parameter for that? Something like inlineOnly, which will allow only inline level elements, like b, strong, em, a...
it is easier to add p tags than it is to remove it from a template
Not always.
and it is easier to add p tags than it is to remove it from a template.
It's actually a lot harder. Especially when you have non-<p> elements that begin or end the string.
Perhaps markdownifyBlock & markdownifyInline functions? As mentioned, I see the use-case for inline markdown styles in headers, but calling the function markdown and then producing non-standard output is highly confusing.
Here is what we need:
markdownify must continue to work as inlineblock option/actionpartialCached, I don't like that very much.markdownify "block" isn't very pretty, eitherstrings.trimLeft etc.) that could fit into this, i.e. markdownify.blockNot sure if the . is allowed there, but something similar ...
Thoughts?
@moorereason @digitalcraftsman @spf13
markdownify standard? I don't know.
Non standards behaviors should die in fire. Hugo is young yet. I think it's still time to deprecate markdownify and create a new standard function. With a bad name, of course. "markdownify" is a great name. markdownIt? toMarkdown?
Thank you all for your attention.
Non standards behaviors should die in fire
What standard? The markdownify standard???
Yeap. Which is the same as the Markdown Extra and others markdown libs. To remove the p tags is a non standard behavior.
Sometimes we need to output just inline markdown, but this case is the exception, not the default.
No, that is not a standard. The markdownify standard becomes whatever WE document that it does.
is this issue still without solution?
I'm using multiline toml syntax to create little blocks of content that needs to be markdownified and I'm encountering issues with the first paragraph not wrapped in <p>.
I think the main goal of markdownify is to add the correct html tags to build up a content block.
maybe the solution could be to create a new function called something like beautify that does the things markdownify does today, and roll back markdownify to the original behaviour.
@bep what do you think? is this issue currently being considered or is abandoned?
thank you!
@bep what do you think? is this issue currently being considered or is abandoned?
It is not closed, so it's not abandoned.
This makes things a little difficult -- in the past, one could always wrap the transform (e.g. <p>{{ x | markdownify }}</p>) if you wanted it to appear as a paragraph, and it would work with a single paragraph or with multiple.
Now, depending on whether the transformed text has multiple paragraphs, it ends up as <p>...</p> or <p><p>...</p><p>...</p></p>, and I can't figure out a way to fix that from within a template. Any suggestions on a workaround?
@noonat , I'm sorry. I don't understand you. What happened this time?
I am not sure if I understand you correctly @noonat, but @bep posted something similar somewhere else, and I used that in order to always wrap my text in either a single <p> tag or multiple:
{{ $markdown := .intro | markdownify }}
{{ if not ( strings.Contains $markdown "<p>" ) }}
<p>{{ $markdown }}</p>
{{ else }}
{{ $markdown }}
{{ end }}
Just replace .intro with your own.
I hate to necro this issue back from the dead, but the provided solution doesn't work in all cases. For example, if my markdown is # only a heading, this will produce
<p>
<h1 id="only-a-heading">only a heading</h1>
</p>
Which is not at all what one would generally expect, and is quite difficult to try to fix.
Edit: It also isn't valid HTML since a paragraph element cannot contain a heading element.
I'm also going to chip in, as it feels like a very odd decision to strip the <p> (or simply don't add it) when the input for the Hugo pipe markdownify.
"content": {
"text1": "Liquorice cake cake jelly jelly beans. Candy oat cake oat cake oat cake sesame snaps. Croissant cotton candy carrot cake cake brownie wafer chupa chups chocolate.",
"text2": "Liquorice cake cake jelly jelly beans.\n\nCandy oat cake oat cake oat cake sesame snaps. Croissant cotton candy carrot cake cake brownie wafer chupa chups chocolate."
}
{{ with .content.text1 }}
<div class="c-content">
{{ . | markdownify }}
</div>
{{ end }}
{{ with .content.text2 }}
<div class="c-content">
{{ . | markdownify }}
</div>
{{ end }}
Currently:
<div class="c-content">
Liquorice cake cake jelly jelly beans. Candy oat cake oat cake oat cake sesame snaps. Croissant cotton candy carrot cake cake brownie wafer chupa chups chocolate.
</div>
<div class="c-content">
<p>Liquorice cake cake jelly jelly beans.</p>
<p>Candy oat cake oat cake oat cake sesame snaps. Croissant cotton candy carrot cake cake brownie wafer chupa chups chocolate.</p>
</div>
Expected:
<div class="c-content">
<p>Liquorice cake cake jelly jelly beans. Candy oat cake oat cake oat cake sesame snaps. Croissant cotton candy carrot cake cake brownie wafer chupa chups chocolate.</p>
</div>
<div class="c-content">
<p>Liquorice cake cake jelly jelly beans.</p>
<p>Candy oat cake oat cake oat cake sesame snaps. Croissant cotton candy carrot cake cake brownie wafer chupa chups chocolate.</p>
</div>
I hope it is something that will reconsider for you to reopen the issue, and implement a fix or add an option to enable the expected behavior 馃槂
Dropping some links aswell:
https://discourse.gohugo.io/t/markdownify-dosnt-add-paragraph-html-tag-on-string-input/18592
https://discourse.gohugo.io/t/markdownify-and-paragraphs/15883
https://discourse.gohugo.io/t/first-paragraph-with-markdownify-not-being-wrapped-with-p-tag/6259/2
Here's an improved version of @imjasonmiller's code - it will add missing <p> tags if there's no <p> or <hx> tags but will ignore other tags such as <span> or <em>:
(Copying my solution from the forum, I hope that's OK.)
{{- $markdown := .Inner | markdownify -}}
{{ if not ( findRE "<[h|p][^>]*>" $markdown ) }}
<p>{{ $markdown }}</p>
{{ else }}
{{ $markdown }}
{{ end }}
```
Most helpful comment
I am not sure if I understand you correctly @noonat, but @bep posted something similar somewhere else, and I used that in order to always wrap my text in either a single
<p>tag or multiple:Just replace
.introwith your own.