Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add option to render Markdown inside <div> blocks #488

Closed
asadovsky opened this issue Sep 17, 2014 · 22 comments · Fixed by #1135
Closed

Add option to render Markdown inside <div> blocks #488

asadovsky opened this issue Sep 17, 2014 · 22 comments · Fixed by #1135
Labels
category: mixed content L1 - broken Valid usage causes incorrect output OR a crash AND there is no known workaround for the issue

Comments

@asadovsky
Copy link

Hi,

First: thanks for writing this fantastic library!

My issue: I'm using Markdown in documentation for a project, and would like to use <div> tags inside of the Markdown to specify that certain sections should be hidden (or otherwise stylized).

For example:

# Title

This is some text.

<div class="toggle-hide">
## Hidden section

A hidden paragraph.
</div>

This text is visible.

Unfortunately, the Markdown content inside the <div> does not get rendered -- it's copied verbatim into the output.

Is there any way to configure marked.js to render Markdown inside of <div> tags? If not: can you point me in the right direction for how to add such an option? Or: can you recommend some alternate strategy for hiding (or toggling visibility of) sections of content?

Thanks!

@octalmage
Copy link

Weird you're right! I guess marked skips certain elements.

You could loop through the elements that have your class, grab the markdown, process the markdown, then replace the contents! Wouldn't be that difficult with jQuery and you wouldn't need to modify marked.

@asadovsky
Copy link
Author

I'm using a static site generator and don't want to run JS on the client side at render time.
I could run marked in 2 passes as part of site generation (similar to what you suggest), but that's still somewhat of a hassle, especially since it'd require modifying the site generator tool, which I didn't write.

@jeffwilcox
Copy link

FYI, Markdown specifically skips processing Markdown within block-level HTML; please refer to http://daringfireball.net/projects/markdown/syntax#html

@derberg
Copy link

derberg commented Oct 3, 2014

but some times you want to have a nice styled panel and use in it some markdown like below

<div class="panel warning">
some random text

``` json
{
"att1": "val1",
"att2": "val2"
}
```
</div>

and it is not entirely true that markdown doesn't work in html block as the markdown emphasis work normally. Looking on above sample, if I would but "test" in between of asterisk "test" that would be rendered to bold. Also the code block above is rendered like it would be a one line code. So something works there. And that would be super cool to have it fully working.
There is a sanitize option to ignore HTML, there could be an option to have markdown in html blocks working :)

@SimonCropp
Copy link

anyone know the line to hack in the js to make this work?

@ivan-kleshnin
Copy link

Reliable Markdown parsing inside HTML is a must. But this will require to remove "indented block = code block" rule entirely, as nested HTML tags are always indented... As GFM style is so much better I think that removal will only improve everything. It was always a fail in original Markdown design to treat indented text as code.

@derberg
Copy link

derberg commented Jan 15, 2015

I love Markdown, but if things like support for markdown in between divs will not be available, markdown will start loosing his position in favour of https://github.com/asciidoctor/asciidoctor.js

@tombola
Copy link

tombola commented Feb 24, 2015

I know this is a bit of a specific case, but I have been trying to get round this for my (jekyll) github pages.

My requirement was to wrap a markdown-ed paragraph in a div so I could style it as a panel. In the end I just created an empty, classed div in front of the paragraph and used a sibling selector .myclass + p to reference (and style) the following paragraph.

I realise this is an unholy and specific workaround, but I thought I would share.

@sh1989
Copy link

sh1989 commented Nov 17, 2016

This feels like quite a common use case - it would be nice if there was some built in liquid template that could do this for you, although we'll need to ensure that markdown is subsequently parsed and outputted correctly within that liquid block.

@franzheidl
Copy link

Some markdown parsers/implementations allow this:

<div markdown="1">
    #Heading 1
</div>

This would be rendered as

<div>
    <h1>Heading 1</h1>
</div>

It would be great if marked would support this, too.

@schlichtanders
Copy link

just stumbled upon this div case

Interestingly, it seems as the following indeed do render correctly:

  • bold and italics using **bold** and *italics
  • url syntax [link text](https://url.com)
  • maybe more

However others don't do so in my case:

  • headings #, ###
  • lists
    - ul1
    - ul2
    
    1. ol1
    1. ol2
    
  • probably more

@maxrahder
Copy link

maxrahder commented Apr 15, 2017

+1
Apparently, within a <div> or other block-level element, inline elements are still processed, but block-level md is ignored. (Here's a fiddle some nice person wrote, to let you experiment: http://www.javascriptoo.com/marked)

Basically, there's a crazy regex in block.html that simply skips over block elements entirely, where a "block element" is anything, like <foo>, that isn't an inline element.

I have this requirement too. I have some <div>s that I process in a special way -- mostly to add css dynamically. But I'd like the content to be processed like any other md. Proving some kind of flag on the div would work, or I don't mind writing something to help out the lexer if I knew what hooks are in the library.

@shalkam
Copy link

shalkam commented Jun 26, 2017

I don't know if I am doing it the right way, but here is how I got it work:
I've tested it with header tag and got it work, some other tags like image work by default

const marked = require('marked');
const renderer = new marked.Renderer();
const cheerio = require('cheerio');

renderer.html = function(html) {
  // marked has to be the first attribute
  const $ = cheerio.load(html);
  const markedDivs = $('div[marked]');
  if (markedDivs.length > 0) {
    // loop through all div tags with marked attribute
    for (var i = markedDivs.length - 1; i > -1; i--) {
      marked(markedDivs.eq(i).html(), function(err, html) {
        markedDivs.eq(i).html(html);
      });
    }
    html = $('body').html();
  }
  return html;
};
renderer.paragraph = function(text) {
  let isHtml = /<[a-z][\s\S]*>/i.test(text);
  if (isHtml) return text + '\n';
  else return '<p>' + text + '</p>\n';
};

module.exports = renderer;

@aoloe
Copy link

aoloe commented Dec 22, 2017

i don't know if i understand this request correctly, but after having checked parsedown, i've found that this is already supported:

erusev/parsedown-extra#14

i've activated markdown extra in grav and the markdown in a <div markdown="1">this is a __test__</div> was then correctly parsed.

@joshbruce joshbruce added help wanted L1 - broken Valid usage causes incorrect output OR a crash AND there is no known workaround for the issue labels Dec 23, 2017
@joshbruce
Copy link
Member

#985

@sbliven
Copy link

sbliven commented Dec 29, 2017

@aoloe Your test uses inline style, which was already established to work. Have you tried a heading or list with parsedown-extra?

@joshbruce I'm confused about the issue consolidation. This remains a limitation in marked, right? Should further discussion happen here or in #985?

@joshbruce
Copy link
Member

@sbliven: Fair question. See the conversation over here as well. #984

Continue discussion here. I'll reopen as it is, apparently a continuing issue. Still working out the kinks of the community coming back on line. Mind the gap. ;)

@joshbruce joshbruce reopened this Jan 5, 2018
@r0the
Copy link

r0the commented Jan 22, 2018

+1

I'm missing this feature. I think that the CommonMark HTML Blocks specification woudl be quite easy to implement. A raw HTML block basically starts with an HTML tag and ends with an empty line.

The following Markdown would be parsed as follows:

  • raw HTML block <div>*raw HTML*</div>
  • raw HTML block <div>
  • Markdown paragraph <p><b>Markdown</b></p>
  • raw HTML block </div>
<div>
*raw HTML*
</div>

<div>

*Markdown*

</div>

@sbliven
Copy link

sbliven commented Mar 26, 2018

@r0the I find the whitespace handling in HTML blocks to be surprising. It prevents using newlines to organize the HTML content in longer blocks. You also can't indent naturally:

<table>
    <tr><td>

**markdown**

    </td></tr>
</table>

Not only must the markdown be left-aligned, but the closing tags get treated as a codeblock due to the indentation. (example)

That said, it's probably easier to implement than the markdown=1 attribute.

@bennlich
Copy link

FWIW the implemented solution is to insert new lines around the content that you want to get parsed, as in this comment: #488 (comment)

@UziTech
Copy link
Member

UziTech commented Dec 24, 2023

Put a blank line around the html elements

<div class="hide">

# h1

</div>

demo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
category: mixed content L1 - broken Valid usage causes incorrect output OR a crash AND there is no known workaround for the issue
Projects
None yet
Development

Successfully merging a pull request may close this issue.