vmg / redcarpet

The safe Markdown parser, reloaded.
MIT License
4.98k stars 524 forks source link

Mixing HTML and Markdown. #13

Open gryzzly opened 13 years ago

gryzzly commented 13 years ago

Is there an option to have both HTML and markdown processed within the same block? Example below doesn't work for me with these options (i.e. heading's being processed as it should, but "autolink" doesn't seem to work, and also title syntax doesn't):

in ruby:

Redcarpet.new(markup, :smart, :autolink, :fenced_code, :lax_htmlblock).to_html

example.mdown:

# Markdown

<dl>
  <dt>HTML</dt>
  <dd>http://link.not.processed</dd>
  <dd>[Link](http://not.processed)</dd>
</dl> 

Thanks.

vmg commented 13 years ago

Sup Misha,

No, at the moment there is no way to mix HTML blocks and Markdown. As the standard clearly states:

Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can’t use Markdown-style emphasis inside an HTML block.

Now, there are some (unofficial) Markdown extensions that allow the user to have MD inside of some tags (e.g. PHP-Markdown Extra allows you to declare tags with <tag markdown='1'> to enable Markdown processing for their inline contents), but we haven't found anything standardized enough, and we're reluctant to implement a random solution.

Either way, mixing HTML and Markdown is very often a bad idea, and source of plenty of ambiguous parsing and strange formatting. Is there anything specific you are trying to accomplish with this, or some other way we can make your life easier?

gryzzly commented 13 years ago

Hey Vicent, thanks for a fast reply. I'm great :-) and how are you?

What I have is basically a layout in HAML and content in Markdown and I believe that definition list is a perfectly fine structure to "write", that complies with what John Grubers' description of Markdown ( http://daringfireball.net/projects/markdown/syntax#html ) So I'd want to have a possibility to let the content be marked up (and styled appropriately afterwards) as a definition list, but as I found out previously on the redcarpet announcement blog post it's not quite possible for a sane technical reason (at least with syntax proposed by PHP Markdown Extra). But while marking up <dl> with HTML, I'd like to still enjoy :autolink or short nice mdown link syntax. Since this is for my own website, I can just code links in HTML. Just wanted to clarify I'm not missing something.

But actually when I think about it, there are plenty of cases when I'd want to mix HTML with Markdown, since the latter doesn't provide us with an option to have a class. For example, you want to have a simple "notice" block with pale-yellow background, so you'd want to give that paragraph a class. So we could either mix HTML with Markdown:

Lorem ipsum dolore set. Short paragraph like that.

<p class="notice">An important notice. [A link to important info](http://example.com)</p>

Which is pretty ugly. Or we could maybe extend Markdown (can we, how hard it'd be to add new syntax to redcarpet?):

Lorem ipsum dolore set. Short paragraph like that.

=> Arrow made of equals and greater than characters may represent a paragraph with class "notice" if I tell my program to parse it that way.

This looks better doesn't it. Or maybe in this case I'd better not use Markdown? (though it seems to me that I'd want to use it, if I may have just a few customizations like that).

I've built a website for a client where there was one simple cutomization, where I needed simple wrapper element with a class <div class="horizontal"><%= yield -%></div> several times and all the rest of the content was most usual plain HTML (headings, paragraphs, links etc.). And my client did want to have content in Markdown. I ended up mixing HTML and Markdown (unfortunately that website had to be built with PHP which allowed me to do that) and I didn't think about extending MD instead.

jcasimir commented 13 years ago

I just want to +1 this.

I'm writing a book using Markdown/Redcarpet, and it would be really nice to be able to add a class to a few paragraphs without losing the markdown processing of what's inside.

The markdown='1' is definitely inelegant, but I'd take it!

nybblr commented 12 years ago

I also would appreciate something like this -- I am using Markdown for a blogging app, and although the template is extremely standardized and tries to stick to best conventions, markdown simply doesn't have enough "semantic" levels. Notably, I am using the html5 <section> tags to separate the major sections of an article out, and within each are a number of which should be p tags. At the moment, whenever I have something like this:

<section>

Here is some text for the first paragraph.

And now paragraph two.

</section>

It is rendered as:

<p><section></p>
<p>Here is some text for the first paragraph.</p>
<p>And now paragraph two.</p>
<p></section></p>

When I would at the least expect (even without markdown interpolation)

<section>
Here is some text for the first paragraph.

And now paragraph two.
</section>

Ideally, markup within the block level element would yield:

<section>
<p>Here is some text for the first paragraph.</p>
<p>And now paragraph two.</p>
</section>

So in the first place, red carpet doesn't seem to recognize <section> as a block level element since it wraps it in p tags, but I thought this was resolved in pull request 27. In addition, as @jcasimir recommends, the ability to use markdown in block level tags would be invaluable, at least until markdown introduces syntax for further semantic breakdown. Other than lack of standard, is there some architectural issue that would prevent such a feature from being added as an option?

It seems this option would make markdown more applicable for slightly more advanced formatting. Maruku for instance has such an option, but unfortunately it is an unusable repo due to age.

On another note, is there an easy way to plug-into the parser? If the markdown="1" is not the best option, perhaps some custom syntax could be written for "section" tags (or some better candidate) but unfortunately my C skills are less than passable; where would one start to add custom wrapper tags?

~ Jonathan Martin

nottrobin commented 10 years ago

+1 I'd love to be able to put markdown inside HTML:

<section>

a new section
===

some section text
</section>
ianstormtaylor commented 10 years ago

+1 to this

silverhammermba commented 10 years ago

This would be excellent. @nybblr HTML5 elements used to work, but was randomly undone in 2d249cce6ea82da9ed14d75a7951f0f87c21bf95. I don't know why. I think issue #20 should be reopened.

enyo commented 10 years ago

I also have to stress the importance of this feature. Writing a post otherwise becomes a real pain. This is a typical workflow:

This really makes me reconsider if I want to use markdown at all, since I always dread having to rewrite it in HTML anyway.

l4ci commented 10 years ago

+1 on this for the same reason.

and other tags for styling.
rmetzger commented 10 years ago

+1

robin850 commented 10 years ago

Hello there,

You don't need to add :+1: to warn us about this feature ; if any ticket on the tracker is open, we will certainly take a look (unless we find that this would be too complicated to implement or this would lead to unexpected behaviors).

At the time being, we are trying to finish the last few things to get 3.1.0 out. Thanks for your comments anyway! :heart:

MartinThoma commented 10 years ago

@robin850 Ok, I've deleted my comment. Is there any other way for users to give you (the developers) feedback what issues matter to us?

robin850 commented 10 years ago

@MartinThoma : Actually this is just for future comments ; just a tiny advice but you are not obliged to follow this.

Is there any other way for users to give you (the developers) feedback what issues matter to us

We are generally conscious of the priority but it's sometimes hard to get a feature out because we develop Redcarpet during our spare-time. My initial comment was about the noise these comments would make for people watching the repository it's ok. I thought the recent comments were here to remind us about the ticket but we don't forget it and I would be really happy if Redcarpet could provide such feature. :-)

This would be nice if GitHub could provide a system for up/down votes but on the other hand, an opinion makes sense only when you argue so it's hard to have the best of both worlds here.

kernc commented 10 years ago

I find I normally subscribe to issues that interest me. Issue subscription stats, if made visible, can be fairly obvious yet silent :+1: votes.

doktorbro commented 10 years ago

This really makes me reconsider if I want to use markdown at all, since I always dread having to rewrite it in HTML anyway.

Markdown is not the right tool for your purposes. Stop using it.

enyo commented 10 years ago

How do you know that it's not the right tool for my purposes. It's exactly what I want, but with the ability to surround my markdown with HTML. Your comment is a bit obnoxious, especially without suggesting an alternative.

parkr commented 10 years ago

the ability to surround my markdown with HTML.

@enyo Did you check out Jekyll? You could stick your HTML in a layout and your markdown in each individual file and boom you're good. Either that or you'll just have to live with writing entirely HTML inside HTML.

enyo commented 10 years ago

@parkr yes. I'm actually talking about a jekyll site. I don't see why markdown in html should not be added (maybe with the markdown="1" html attribute)... Why must it be either 100% markdown, or none at all? Other markdown parsers didn't add it just for pure fun. After all, you can also write HTML in markdown.

I like to write my articles in markdown. I think writing **important** is much more concise than writing <strong>important</strong>. Lists and links without markdown are just a PITA.

But sometimes, you just need additional classes to give them additional styling or for JS interaction, or different elements like section. There is nothing wrong with that, and it shouldn't prevent me from using Markdown.

Of course, I could use another HTML preprocessor, like Jade, etc... but Markdown is just the cleanest of them all.

I could also use another markdown processor than redcarpet, but redcarpet provides everything I want, except for Markdown in HTML, so I'd love to see this feature being added.

mattr- commented 10 years ago

The current standard (John Gruber's original Markdown spec) clearly states that mixing Markdown into an HTML block level elements will not get processed:

Note that Markdown formatting syntax is not processed within block-level HTML tags. E.g., you can’t use Markdown-style emphasis inside an HTML block.

and this is what Redcarpet follows for the time being. If you're looking for a Markdown processor with an extension that will parse Markdown inside an HTML block, I highly suggest looking at another markdown processor, such as Kramdown, which does allow this sort of mixing.

MartinThoma commented 10 years ago

@enyo I had an similar issue (the need odd additional HTML for styling while I want to rely on markdown because of it's simplicity and readability). I solved it by creating liquid plugins. If you want, I'll later post a link to the source of one of them (I'm currently on mobile)

dolfelt commented 10 years ago

I'm using Middleman with RedCarpet 3.1.1 and wondering if there is a work around for this, or someway without HTML for me wrap Markdown in <div> tags with classes. Any help would be appreciated.

kernc commented 10 years ago

This issue, or at least the most common use case, is somewhat mitigated with GitHub switching to kramdown, which supports classes and other attributes. Yay! :cake:

parkr commented 10 years ago

This issue, or at least the most common use case, is somewhat mitigated with GitHub switching to kramdown, which supports classes and other attributes. Yay!

@kernc You could always use Kramdown, just specify markdown: kramdown in your configuration file!

enyo commented 10 years ago

Yup... I guess kramdown it is.

pienkowskip commented 10 years ago

I've written my own renderer which supports markdown in HTML-blocks. Here you are:

class RecursiveRenderer < Redcarpet::Render::HTML
  def block_html(raw_html)
    if (md = raw_html.match(/\<(.+?)\>(.*)\<(\/.+?)\>/m))
      open_tag, content, close_tag = md.captures
      "\n<#{open_tag}>\n#{render content}<#{close_tag}>\n"
    else
      raw_html
    end
  end

  def set_render(&block)
    @render = block
  end

  private
  def render(markdown)
    if @render.nil?
      markdown
    else
      @render.call(markdown)
    end
  end
end

And here is an usage:

renderer = RecursiveRenderer.new()
markdown = Redcarpet::Markdown.new(renderer)
renderer.set_render &markdown.method(:render)
markdown.render(input)

The problem is I can't access current markdown parser from renderer. So I did a setter of render method there. But it's so ugly! Any ideas how to do this better? Or how to access parser from renderer?

mxmzb commented 10 years ago

Now that 3.1 is out for a while, I really want to give a +1 to this issue.

I really think there can be some little space of freedom from the specification by John Gruber and the markdown library. It could be just an option (which would be off by default of course) and would help many people. You brought some GitHub flavored in already so Redcarpet isn't following the specs strictly anyway.

cboettig commented 10 years ago

Are there other widely used extensions of markdown that do not provide this extension? Certainly parsing markdown within divs is such a widely used option (it is the default behavior for pandoc, for instance) that "markdown is not the right tool" for such applications.

kylecordes commented 10 years ago

This feature, " you can’t use Markdown-style emphasis inside an HTML block" is, in my opinion, the single worst bit about markdown. In fact it is really one of the few bad things about markdown.

Can anyone suggest an alternative to redcarpet which supports a way to do that? But which is otherwise very similar in quality to redcarpet? (Of course I would much rather see red carpet support an extension to allow this, but I respect a decision to stick closely to a spec. Even though it does not work for me.)

silverhammermba commented 10 years ago

@kylecordes Kramdown. That feature is what made me ditch Redcarpet a while ago.

kylecordes commented 10 years ago

Thank you. I just switched to Kramdown, that took care of it. The practicality (I really need block tags to work) won out over the spec. So it goes.

Theby commented 9 years ago

I was trying to do this when I came out with this problem, I thought it was pretty lame that I could not use markdown within html tags but then I realize that there was an easy workaround that doesn’t need any extra gem or programming. I’m using Rails 4.1.1 and RedCarpet 3.2.0 and this is what I did:

At my application_helper.rb

def markdown(text)
        options = {
            filter_html:     false, 
            xhtml:            true,         
        }

        renderer = Redcarpet::Render::HTML.new(options)
        markdown = Redcarpet::Markdown.new(renderer, extensions = {})

        markdown.render(text).html_safe
    end

Then in my views I render a .md extension file like this:

<%= markdown(render file: "file.md") %>

So where is the trick? in the file.md where I do this:

## Title

some text

<section>
    <%= markdown("

#More markdown

rendered without any problem

") %>
</section>

It may not look that good to the eye, but man it is a simple approach and make you do some html customization to your markdown file.

Hope it helps.

molnarg commented 9 years ago

The CommonMark spec specifies markdown-in-html in a pretty elegant way. I believe that is the way redcarpet should implement it. See http://spec.commonmark.org/0.20/#html-blocks and http://spec.commonmark.org/0.20/#example-110 .

sdhull commented 8 years ago

The primary issue we were encountering was <p> tags being inserted in the middle of email templates we were writing with html & markdown. Paragraph tags being inserted between <tr>s obviously break layouts. The decision to use both (html & markdown) was legacy and we simply have too many templates to convert them all to be one way or the other at the moment.

Anyway eventually I fixed it by defining in a custom renderer:

def paragraph(text)
  if text.match(/\s*<.*>/) && !text.match(/\s*<a .*>/)
    text
  else
    "<p>#{text}<p>"
  end
end

EDIT: had to make sure it was still wrapping links in <p> tags. A bit hacky, but... :sweat_smile:

Sequoia commented 7 years ago

Is there not a plugin for this? The main issue here is people coming from Kramdown (e.g. Jekyll). If there were a plugin that did this the core parser could be left alone & kramdowners would have some path to follow.

julien-f commented 6 years ago

Hey, any news about this?

It would be really nice to have :)

9mm commented 1 year ago

Aye... getting so close and this gem is amazing then I find this. Has anyone else figured out a way to do this with a custom renderer?