Search code examples
ruby-on-railsherokuredcarpetcoderay

How can I use RedCarpet without CodeRay to implement markdown in my blogs?


So I have patiently tried for some time to work with CodeRay gem to implement markdown in my blogs. It worked for awhile, but then it would break my blog page with a 500 error.

The CodeRay.scan was identified as the culprit:

class CodeRayify < Redcarpet::Render::HTML
        def block_code(code, language)
            CodeRay.scan(code, language).div
        end
    end

but even after I refactored the code to look like this:

class CodeRayify < Redcarpet::Render::HTML
        def block_code(code, language)
            CodeRay.scan(code, language || :text).div
        end
    end

I am still having the same problem even though I make sure that I do not have backticks at the beginning of the sentence and that I am implementing markdown correctly in my blogs.

I get errors like this:

2017-11-28T23:22:11.456525+00:00 app[web.1]: I, [2017-11-28T23:22:11.456458 #4]  INFO -- : [d03d5e9e-c3c3-4117-85db-d80bd30d9178] Completed 500 Internal Server Error in 38ms (ActiveRecord: 8.5ms)
2017-11-28T23:22:11.457321+00:00 app[web.1]: F, [2017-11-28T23:22:11.457251 #4] FATAL -- : [d03d5e9e-c3c3-4117-85db-d80bd30d9178]
2017-11-28T23:22:11.457384+00:00 app[web.1]: F, [2017-11-28T23:22:11.457321 #4] FATAL -- : [d03d5e9e-c3c3-4117-85db-d80bd30d9178] ActionView::Template::Error (Invalid id given: console.log("Hello!");```):
2017-11-28T23:22:11.457592+00:00 app[web.1]: F, [2017-11-28T23:22:11.457534 #4] FATAL -- : [d03d5e9e-c3c3-4117-85db-d80bd30d9178]     4:
2017-11-28T23:22:11.457593+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178]     5:     <% render partial: 'blogs/admin_actions', locals: {blog: blog} %>
2017-11-28T23:22:11.457595+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178]     6:
2017-11-28T23:22:11.457595+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178]     7:     <p><% markdown blog.body %></p>
2017-11-28T23:22:11.457596+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178]     8:
2017-11-28T23:22:11.457597+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178]     9:  </div><!-- /.blog-post -->
2017-11-28T23:22:11.457648+00:00 app[web.1]: F, [2017-11-28T23:22:11.457586 #4] FATAL -- : [d03d5e9e-c3c3-4117-85db-d80bd30d9178]
2017-11-28T23:22:11.457718+00:00 app[web.1]: F, [2017-11-28T23:22:11.457654 #4] FATAL -- : [d03d5e9e-c3c3-4117-85db-d80bd30d9178] app/helpers/blogs_helper.rb:8:in `block_code'
2017-11-28T23:22:11.457719+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178] app/helpers/blogs_helper.rb:23:in `render'
2017-11-28T23:22:11.457720+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178] app/helpers/blogs_helper.rb:23:in `markdown'
2017-11-28T23:22:11.457721+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178] app/views/blogs/_blog.html.erb:7:in `_app_views_blogs__blog_html_erb__2572357733169721276_60667300'
2017-11-28T23:22:11.457721+00:00 app[web.1]: [d03d5e9e-c3c3-4117-85db-d80bd30d9178] app/views/blogs/index.html.erb:5:in `_app_views_blogs_index_html_erb__3522254122931434539_63043240'

This is how I am writing markdown on my Javascript blog:

Below are examples of four primitive data types that lay the foundation for all JavaScript programs. Primitive data types, as their name implies, are the simplest built-in forms of data. For example:

```javascript
console.log('New York City');
console.log(40.7);
console.log(true);
console.log(null);
```

This is the correct way to do it, why do I get an error? According to heroku logs in the past, this is the problem:

CodeRay.scan(code, language).div

but even if I change it to this:

CodeRay.scan(code, language || :text).div

I still get the same problem. So I am wondering how can I just implement RedCarpet into this code below without CodeRay:

module BlogsHelper
    def gravatar_helper user
        image_tag "https://www.gravatar.com/avatar/#{Digest::MD5.hexdigest(user.email)}", width: 60
    end

    class CodeRayify < Redcarpet::Render::HTML
        def block_code(code, language)
            CodeRay.scan(code, language || :text).div
        end
    end

    def markdown(text)
        coderayify = CodeRayify.new(filter_html: true, hard_wrap: true)

        options = {
            fenced_code_blocks: true,
            no_intra_emphasis: true,
            autolink: true,
            lax_html_blocks: true,
        }

        markdown_to_html = Redcarpet::Markdown.new(coderayify, options)
        markdown_to_html.render(text).html_safe
    end

    def blog_status_color blog
        'color: red;' if blog.draft?
    end
end

Solution

  • The issue may not be with Coderay or RedCarpet. It may just be a data issue. This error ActionView::Template::Error (Symbol or String expected, but NilClass given.) means that it's expecting content but not getting any at all, so it could be a data validation issue or something like that.

    So you may need to troubleshoot your data validation issue or go with an alternative like CKEditor.