Reputation: 6466
I'm trying to create a blog app that allows me to enter into a model object text that's a combination of HTML/ERB and MD, with some of it intended for literal publication and some for rendering/execution.
I would ideally just delineate the text I desired published as code with backticks or something a la Markdown/Redcarpet, and the rest of the HTML/ERB would get exectued. In other words, I want this (actual example, content irrelevant) text entered into my Post model:
Take a look at the below strangely named cow, and imagine sorting through all 93 packages of ground meat.
<%= image_tag('MeatUp Log.png', class: 'blog_photo') %>
Since every package was associated with a given user and had an expected and actual weight, butchers had to comb through long lists of cuts (for cows, as MeatUp broke them down, there were 22 different cuts, totaling hundreds of packages), to find the right one to update after they weighed it.
To simplify the process both visually and practically, I looked into a simple Javascript expand/collapse function, and ended up homebrewing a neater, more adaptable version from something I found in a blog.
<div class="codebox">
expand.js.coffee
```
jQuery ->
$('.cl .bundle').on 'click', (e) ->
e.preventDefault()
$collapse = $(@).closest('.collapse-group').find('.collapse')
$collapse.collapse 'toggle'
```
</div>
to look like this:
Instead. It currently looks like this:
Two problems here. 1) The ERB displays but is not rendered, even though it isn't surrounded by backticks. 2) The HTML disappears from the display but is also not rendered. It is there for formatting (the blue codebox above), but does not appear to be read.
I'm basically following the advice here to use Redcarpet for markdown and Pygments for code coloring, but I want to ensure that this process is as easy as possible, and that I can have both executed and none-executed code in there -- ideally through just using the backticks.
Tried taking out the ".html_safe" in my application_helper, but that just makes things go crazy:
class HTMLwithPygments < Redcarpet::Render::HTML
def block_code(code, language)
Pygments.highlight(code, lexer: language)
end
end
def markdown(text)
renderer = HTMLwithPygments.new(hard_wrap: true, filter_html: true)
options = {
autolink: true,
no_intra_emphasis: true,
fenced_code_blocks: true,
lax_html_blocks: true,
strikethrough: true,
superscript: true
}
Redcarpet::Markdown.new(renderer, options).render(text).html_safe // This guy
end
Any ideas?
EDIT -- I tried following the instructions here to just separate HTML by one line. That just causes the above disappearance problem. Is this an unavoidable function of Redcarpet? Should I scrap the MD idea? If so, any alternative suggestions for a simple post model into which I can feed both plaintext and ERB?
Upvotes: 2
Views: 342
Reputation: 6466
I came up with a solution that still feels a little hacky but works to my liking. I
A) Removed "filter_html: true" from the RedCarpet settings in my application_helper (a setting I had on by default following the above Railscast.
def markdown(text)
renderer = HTMLwithPygments.new(hard_wrap: true)
options = {
nowrap: true,
autolink: true,
no_intra_emphasis: true,
fenced_code_blocks: true,
lax_html_blocks: true,
strikethrough: true,
superscript: true
}
Redcarpet::Markdown.new(renderer, options).render(text).html_safe
end
B) I wrapped each segment of to-be-executed HTML (other than links and images -- so just styling HTML, I guess) in a block that allowed it to be rendered. Found docs on that here.
C) I got rid of ERB. Seems to me that RedCarpet isn't really made for rendering ERB, so I converted all the ERB I needed into HTML (it's a blogpost, so this wasn't a problem, though this solution isn't exactly scalable). All my link_to's I turned into regular HTML links.
D) I had to do some tinkering around with precise indentation, etc, but it works out. So now I can fill a Post object with something like the below, and have it turn into blue-formatted code boxes with pygments formatting, and functional CSS'd links and images. Works for me, though it's still about 15% more headache than I'd ideally like. If anyone comes up with a better idea, do let me know:
Some markdown text.
More markdown text with a nicely rendered <a href="#" title="title" class="stylin">link</a> in it.
<img src="image.png">
And some code in a stylized codebox:
<notextile><div class="codebox">example.html.erb</notextile>
```html
<h4>This works!</h4>
<p>Well enough for now, at least</p>
<small>Any improvements you can think of would be appreciated</small>
```
<notextile></div>
</notextile>
At any rate, that's my "answer" for now, though if any of you can think of a better one, let me know.
Upvotes: 1