Support Markdown editing within rails app - ruby-on-rails

I allow my users to create assignments and distribute them to their employees. Assignments have a attribute called description. Instead of users filling out a plain text field to create a description I want to give them a editable markdown supported box to fill in. exactly like the one I'm filling out now. I've never built anything like this out before, but I'm wondering if there is a Ruby gem or plugin that will help me out with this?

I can recommend you SimpleMDE javascript markdown editor. In this case you don't need a ruby gem for markdown because SimpleMDE can generate html version for you. You need to just save in your database both versions - markdown and html.
We have table assignments with two fields description to keep a markdown version and description_html to keep a html version of a question. As far you create common rails assignments' form and bind simplemde instance to description textarea. For description_html create hidden field tag:
<%= f.hidden_field :description_html %>
<%= f.textarea :description %>
On any change simplemde will save a html version to description_html hidden field:
var simplemde = new SimpleMDE({ element: $("#MyID")[0] });
simplemde.codemirror.on("change", function(){
# set a html to a hidden field
$('#description_html_id_CHANGE_IT').val(simplemde.getHtmlValue());
});

I suggest you use github's gem for that: https://github.com/github/markup
First install a couple of gems:
github/markup
html-pipeline
nokogiri
nokogiri-diff
Then try the following:
require "github/markup"
require 'html/pipeline'
require 'nokogiri'
require 'nokogiri/diff'
filename = ARGV.first
puts GitHub::Markup.render(filename, File.read(filename)).strip.force_encoding("utf-8")

Related

Ruby Mechanize Gem find fields without names

I’m trying to use the mechanize gem to scrape a page that is behind a login. However for the site i am using, they don’t name their username or password fields in the html. I’ve searched the Mechanize documentation, but i cannot fins the code to enter textin a field without using the field name. Is there a way to find the 5th element on the page, or the first text box?
If you have liberty to use other gem then why don't you try using Nokogiri Gem.
It is very flexible where you can use either css selector OR can use XPath selector to search specific elements.
You can use
agent = Mechanize.new
page = agent.get(<yourpage>)
form = page.forms[<index of form>]
form.fields[<index of field>].value = '<your value>' # setting the values
form.fields[<index of field2>].value = '<your value2>'# setting the values
page2 = form.submit # submitting the form

Pass multiline html string(markdown text) from rails to javascript

I have a markdown text saved in the databse and I want to show it as html to the user. I am using markdown.js as the processor and I pass the big multiline html string from rails to javascript by rendering a js.erb file from the controller.
But since it is multiline, the javascript becomes invalid. Is there any rails function which will take the whole string and assign it as a single line string to javascript variable. I cannot use html_safe also as some things might be escaped. What is the best way to handle markdown?
sample markdown
![enter image description here](https://encrypted-tbn2.gstatic.com/images?q=tbn:ANd9GcRiOb7-0qeyx73XuXNqzLpxgXTlf5UMrMnF5zm-UKn3wLaXCW0UUw "enter image title here")
Hello
If you render erb server-side anyway, you will probably be better rendering Markdown server-side as well. You can use Redcarpet for that.
Add gem redcarpet to your Gemfile.
Run bundle install
Use it:
text = "my _markdown_ *variable*"
markdown = Redcarpet::Markdown.new(Redcarpet::Render::HTML)
markdown.render(text)
It will be a good idea to save rendered HTML in the database, to save CPU time on re-rendering the same text every time you want to show it to client. So you can add something like this to your model:
class Article
# let's say that model has 'source' attributes with Markdown
# and we want to put resulting HTML into 'html' attribute
before_save :markdown
def markdown
self.html = Redcarpet::Markdown.new(Redcarpet::Render::HTML).render(source)
end
end

Rails 4: Disable automatic CSS sanitizing when using built-in HTML sanitize

I'm building an application that has a HTML GUI interface to create, move and edit boxes (div) inside a container div. These boxes get assigned inline styles when editing, these inline styles are saved to the database and are output in the views:
<%= sanitize raw(#slide.content) %>
I want to sanitize the HTML itself, to avoid someone hacking in, for instance, a script tag, through sending that by editing what's sent to the server when the boxes are saved.
Rails 4 has a helper method sanitize available through the class ActionView::Helpers::SanitizeHelper. When I use this with a test content value that contains a malicious <script> tag, the script gets removed just fine. But sanitizing the content also strips CSS properties inside the style tag that are necessary for the boxes, like top, left, position, etc.
In the linked documentation, it's stated that sanitize will automatically use the function sanitize_css when it comes across a style attribute:
sanitize_css(style)
Sanitizes a block of CSS code. Used by sanitize when it comes across a style attribute.
I do not want this behaviour of sanitize. How can I disable sanitize using sanitize_css, to sanitize the HTML, but not the CSS?
You can allow any attributes and tags you need, so rails will skip them.
sanitize raw(#slide.content), tags: %w(table tr td ul li), attributes: %w(style href title)
Speaking about CSS rules themselves, it's a bit harder to allow additional rules, but still possible. You can monkey patch the HTML::WhiteListSanitizer class (https://github.com/rails/rails/blob/c71c8a962353642ee44b5cc6ed68dc18322eea72/actionpack/lib/action_view/vendor/html-scanner/html/sanitizer.rb). There are several attributes that can help.
In your config/application.rb file:
config.action_view.sanitized_allowed_tags = nil
config.action_view.sanitized_allowed_attributes = nil
safe lists found here: loofah html5 safelist

Adding Markdown into my Rails 3 app

I am trying to add Markdown to my Rails 3 web app but am having problems.
I have tried rdiscount and markdownizer but either they're not working or I'm not writing the correct code for them.
The code I have at the moment to display a text field is <%=h simple_format (#user.desktopinfo) %>
I want to increase the functionality of this text by adding Markdown but I am unable to get it work, please help! :)
EDIT 2
Using markdownizer broke my app, so I am now using BlueCloth. Add bluecloth to the gem file and add this <%= raw BlueCloth.new(#user.desktopinfo).to_html %>
:)
EDIT
Actually, just trying again...
With markdownizer, with markdownize! :desktopinfo in the user model and <%= #user.rendered_desktopinfo %> on the page that shows the text, I get this: <h1>this is a h1</h1> on the text when I enter
this is a h1
============
so I am halfway there! How do I now turn this code into html?
Consider rdiscount which substitutes for bluecloth but is faster and better maintained.
Ryan Tomayko's comparison is a good write up regarding the different libraries for using markdown in Ruby.
You haven't really specified exactly what you are after, but I use bluecloth when working with markdown. You can add 'bluecloth' to your Gemfile.
To parse your markdown it is as simple as:
<%= raw BlueCloth.new(YOUR_MARKDOWN).to_html %>
You need the keyword raw. so the HTML is not escaped.
<%= raw #user.rendered_desktopinfo %>

Markdown to text/plain and text/html for multipart email

I’m looking for a solution to send DRY multipart emails in Rails. With DRY I mean that the content for the mail is only defined once.
I’ve thought about some possible solutions but haven’t found any existing implementations.
The solutions I’ve thought about are:
load the text from I18n and apply Markdown for the html mail and apply Markdown with a special output type for the text mail where
links are put in parenthesis after the link text
bold, italic and other formatting that doesn't make sense are removed
ordered and unordered lists are maintained
generate only the html mail and convert that to text according to the above conditions
Is there any available solution out there? Which one is probably the better way to do it?
In Chapter 4 of Crafting Rails Applications, Jóse Valim walks you through how to make a "merb" handler that uses markdown with interspersed erb and can compile to text and html. Then you make a mailer generator that generates a single merb template for each of your mail actions.
You can read an excerpt from that chapter on the page I linked you to. I highly recommend buying the book.
If you're interested in using my sorry version of what he describes in that book, you can slap this in your Gemfile:
gem 'handlers', :git => "git://github.com/chadoh/handlers.git"
Be warned that I barely know what I'm doing, that I'm not versioning that gem, and that I probably won't really even maintain it. Frankly, I wish I could find someone else who was doing a better job, but I've been unsuccessful in doing so. If you want to fork my project and be the person doing that better job, go for it!
This is a PITA, but is the only way to DRY mail such that you can support both HTML (multipart) & plaintext:
Put the html email copy in a partial file in your ActionMailer view directory with the following extension: _action.html.erb
Replace "action" with whatever action name you are using.
Then create 2 more files in the same directory:
action.text.html.erb and
action.text.plain.erb
In the text.html partial:
<%= render "action.html", :locals => {:html => true} %>
In the text.plain partial:
<% content = render "action.html", :locals => {:html => false} %>
<%= strip_tags(content) %>
That works for me, though it certainly makes me want to pay the monthly service for madmimi
Use the maildown gem.
This gems does the heavy lifting of allowing you to use email.md.erb instead of email.html.erb and email.text.erb. Write it once in a sane format and have it automatically display in HTML and in Plain Text. Win.
There are some intricacies here that you'll want to look at based on your use-case, but here's some of what we did to get it working well:
Create a maildown.rb initializer to setup some sane defaults:
Maildown.allow_indentation = true # Prevents code blocks from forming when using indentiation in markdown emails.
Maildown::MarkdownEngine.set_text do |text|
text.gsub( /{:.*}\n?/, "" ) # Removes Kramdown annotations that apply classes, etc. with `{: .class }`.
This allows you to use indents in your blocks, etc. But also precludes the ability to add indents in your Plain Text. It also removes Kramdown-specific annotation from Plain Text.
Then just replace your HTML and Plain Text files with a single .md.erb file and test it out to make sure it looks good in both versions.
Note, until you remove the .html.erb and .text.erb files, it will show those first before looking for a .md.erb file. This may actually be a nice feature if you ever needed to write separate formats for a specific email (maybe a marketing one that requires more complex formatting than Markdown can provide) without having to specify anything anywhere.
Works a treat.

Resources