Using Redcarpet Gem with .erb file - ruby

I am trying to pull up a markdown file from a database that I created. My server. rb file has the following:
get "/designers/:id" do
id = params[:id]
#content = conn.exec_params("SELECT * FROM articles_info WHERE id = $1",[id]).first
erb :raf
end
In that table is the following markdown information:
# **RAF SIMONS**
*THIS IS THE RAF SIMONS BIO* :blush:
*[Raf Link](http://rafsimons.com/)*
The .erb file works when I have plain text or the following in it:
<%= "#{#content["content"]}" %>
However it only prints the actual .md text as it is. So I have tried using Redcarpet to render the markdown file. The code is as follows in my .erb:
renderer = Redcarpet::Render::HTML.new
markdown = Redcarpet::Markdown.new(renderer)
<%= markdown.render(#content.content) %>
But I am getting the error:
ArgumentError at /designers/1
wrong number of arguments (0 for 1..3)
Which is stemming from the <%= line. I thought at first that the syntax was wrong, so I tried:
markdown.render <%= "#{#content["content"]} %>
However that did not change anything. I also tried adding in a method in the server.rb file, but that gave me more errors. I read through the entire documentation: https://github.com/vmg/redcarpet file but am not understanding where the error is coming from. Is it possible that I need extensions in order to make it work? I also tried:
markdown = Redcarpet::Markdown::new(renderer, extensions={})
But that didn't change anything. Not sure what else to try here! I know that it is tricky but I thought I had a handle on it and have now tried many different iterations and still am having trouble executing it. Any advice would be much appreciated!

Related

HAML::Engine, image is not rendering

I am using just Ruby (no rails) to make a gem that takes a yaml file as an input an it produces a pdf.
I am using pdfKit and Haml. In the haml file I need to render an image. When using pure HTML, PDFKit shows the image, but when using Haml::Engine and the haml file the image doesn't get rendered.
I have put the image, the .module and the haml file under one folder to make sure the issue is not the path.
In my gemspec I have the following
.
.
gem.add_development_dependency("pdfkit", "0.8.2")
gem.add_development_dependency("wkhtmltopdf-binary")
gem.add_development_dependency("haml")
The HTML that works:
<html>
<head>
<title>
junk
</title>
</head>
<body>
HI
<img src="watermark.png"/>
Bye
</body>
</html>
Haml version that doesn't work:
%html
%head
%title
junk
%body
HI
= img "watermark.png"
Bye
module:
require "pdfkit"
require "yaml"
require "haml"
require "pry"
.
.
junk = Haml::Engine.new(File.read("lib/abc/models/junk.haml")).render
kit2 = PDFKit.new(junk)
kit2.to_file("pdf/junk.pdf")
when using the html file, pdf renders the image, however, when I use the haml this is now my pdf looks like
and If I use
%img(src="watermark.png")
I get the following error when pdf is generated
Exit with code 1 due to network error: ContentNotFoundError
The PDF still gets generated, but the still looks like the image above.
So I am trying to see without using any rails, and img_tag, image_tag etc.. how would I just use the %img in haml file to render the proper image
Following is the output of junk, when I create #img = "watermark.png"
1 pry(DD)> junk
=> "<html>\n<head>\n<title>\njunk\n</title>\n</head>\n<body>\nHI\n<img src='watermark.png'>\nBye\n</body>\n</html>\n"
Replace the img tag %img(src=#img) still same result
I think this is not HAML issue, but wkhtmltopdf thing. Apparently it's not very good at handling relative urls to images. It should work with absolute path, for example:
%img(src="/home/user/junk/watermark.png")
To create an image tag in HAML you will need to use
%img(src="foo.png")
# or
%img{src: "foo.png"}
If you use
= img "watermark.png"
then you are calling the img method (if it exists), passing it "watermark.png" as argument and outputting the return value of that method in the generated HTML.
Honestly i'm not sure how that HTML template should work, when the HAML template that generates the same HTML does not. So I guess you run that script from different directories or so?
Anyways: Problem is, that you will need absolute paths for your files. Otherwise wkhtmltopdf will not be able to resolve your images.
You can use File.expand_path (see sample) for this, or write a custom helper.
I tried following:
Created two files:
/tmp/script.rb
/tmp/watermark.png
/tmp/template.haml
Where watermark.png is a screenshot I took from this question, script.rb is:
require "pdfkit"
require "haml"
template = File.read("template.haml")
html = Haml::Engine.new(template).render
File.write("template.html", html)
pdf = PDFKit.new(html)
pdf.to_file("output.pdf")
And template.haml is:
%html
%head
%title Something
%body
BEFORE
%img(src="#{File.expand_path(__dir__, "watermark.png")}")
AFTER
When I run this script like:
ruby-2.5.0 tmp$ ruby script.rb
Then the HTML that is generated is:
<html>
<head>
<title>Something</title>
</head>
<body>
BEFORE
<img src='/tmp/watermark.png'>
AFTER
</body>
</html>
And the generated PDF looks like:

Ruby - How to add EOF marker into a PDF file or otherwise bypass PDF::Reader::MalformedPDFError: PDF does not contain EOF marker

I'm using the Mechanize ruby gem to click a button on the web to download a PDF file and save it to the local file system.
URL = "www.my-site.com"
agent = Mechanize.new
agent.pluggable_parser.pdf = Mechanize::File # FYI I have also tried Mechanize::FileSaver and Mechanize::Download here
page = agent.get(URL)
form = page.forms.first
button = page.form.button_with(:value => "Some Button Text")
local_file = "path/to/file.pdf"
response = agent.submit(form, button)
response.save_as(local_file)
But when I try to read this PDF file using the PDF::Reader gem, I get an error "PDF does not contain EOF marker".
reader = PDF::Reader.new(local_file) # this also happens if I try to use PDF::Reader.new(response.body) and PDF::Reader.new(response.body_io) depending on the different pluggable_parser configurations mentioned above
#> PDF::Reader::MalformedPDFError: PDF does not contain EOF marker
I'm able to save the PDF locally and view it and it looks fine, but the PDF::Reader gem is complaining about it missing an EOF marker.
So my question is: is there a way I could add an EOF marker into the PDF or something to get around this error so I can parse the PDF?
Thanks.
Related (unanswered) question: PDF does not contain EOF marker (PDF::Reader::MalformedPDFError) with pdf-reader
Related Docs:
http://mechanize.rubyforge.org/Mechanize/File.html
http://mechanize.rubyforge.org/Mechanize/Download.html
http://mechanize.rubyforge.org/Mechanize/FileSaver.html
https://github.com/yob/pdf-reader
EDIT:
I found the EOF marker somewhere in the middle of the downloaded file contents, followed by some HTML-looking stuff that I can't seem to figure out how to get rid of. I want to isolate the PDF content and then parse that, but still running into issues. Here is the full script I am using:
https://gist.github.com/s2t2/c6766846d024edd696586b2bc7fee0bf
The issue seems to be with the website you're accessing: http://employmentsummary.abaquestionnaire.org
The add HTML data at the end of the response.
However, you could truncate the response by searching for the first substring %EOF and removing all the data after that.
i.e.:
pdf_data = result.body
pdf_data.slice!(0, pdf_data.index("%EOL").to_i + 4)
if(pdf_data.length <= 4)
# handle error
else
# save/send pdf_data
end

Rendering Error: RangeError: Maximum call stack size exceeded

I'm getting the following error generated from my default.html.eco layout when I attempt to render:
RangeError: Maximum call stack size exceeded
My docpad version is: v6.54.2, and the specific line causing it is this:
<%- #getBlock('scripts').add(['/vendor/foundation.min.js',
'/vendor/audiolib.js','/vendor/freqfinder.js','/vendor/modernizr.js']).toHTML() %>
If I remove this, I get a clean build.
Note that the styles block just above it renders just fine:
<%- #getBlock("styles").add(['/vendor/foundation.css']).toHTML() %>
So I decide to try truncating that list in the scripts block and it works:
<%- #getBlock("scripts").add(['/vendor/foundation.min.js']).toHTML() %>
Any ideas on how to work around this? I'll go file a bug if I'm not doing something wrong - new to docpad.
Do you have a line break in your code? It fails for me when I copy-paste from here to my layout file, but if I delete the line break between '/vendor/foundation.min.js', and '/vendor/audiolib.js' then it compiles as expected.
Alternatively, you could also a string of .add() commands like this:
<%- #getBlock('scripts').add('/vendor/foundation.min.js').add( '/vendor/audiolib.js').add('/vendor/freqfinder.js').add('/vendor/modernizr.js').toHTML() %>
That also comiples fine for me.
And a related note, in case anyone else comes across this error but doesn't have any line breaks: collection.add(null) now causes the same error message. So, if you're doing something like this:
<%- #getBlock("scripts").add( #getDocument().get('scripts') ).toHTML() %>
It will die if you don't have a scripts metadata field on every page.
The fix, however, is pretty simple:
<%- #getBlock("scripts").add( #getDocument().get('scripts') or [] ).toHTML() %>

Passing binding or arguments to ERB from the command line

I have been playing around with erb from the command line recently. I wanted to make a dirt simple erb template, for example the following:
<%- name = "Joe"; quality = "fantastic" -%>
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
This works if I run
erb -T - thatfile.erb
what I want to do is to make name and quality be passable from command line arguments, so that I could do something like:
./thatfile.erb "Bill" "super"
from the bash prompt and do the same thing.
I am aware that I could write a ruby script that would just read that template in and then use ERB.new(File.read("thatfile.erb")).result(binding), or writing the template after an END and doing likewise, but I'm looking for a more lightweight approach if it exists, because I don't want to write two files for each erb script that I create for this purpose.
Alternatively, you can use a ruby script and load it in as a library.
# vars.rb
#hello = 'kirk'
# template.html.erb
<div><%= #hello %></div>
$ erb -r './vars' template.html.erb
Please note that Ruby 2.2 and newer provide a much nicer solution that was implemented according to this:
erb var1=val1 var2=val2 my-template.erb
I went with the BASH command-line shortcut for environmental variables.
Outside:
STUFF=foo,bar erb input.html.erb >output.html
Inside:
<%
stuff = ENV['STUFF'].split(',')
%>
After a few minutes e-searching I determined the other solutions are all variations on "write the erb wrapper command yourself." Could be wrong, but I ain't going back.
If you are using unix, try following:
$ cat 1.erb
Hello. My name is <%= name %>. I hope your day is <%= quality %>.
$ (echo '<% name="Joe"; quality="fantastic" %>' && cat 1.erb) | erb
Hello. My name is Joe. I hope your day is fantastic.

How do I execute ruby template files (ERB) without a web server from command line?

I need ERB (Ruby's templating system) for templating of non-HTML files.
(Instead, I want to use it for source files such as .java, .cs, ...)
How do I "execute" Ruby templates from command line?
You should have everything you need in your ruby/bin directory. On my (WinXP, Ruby 1.8.6) system, I have ruby/bin/erb.bat
erb.bat [switches] [inputfile]
-x print ruby script
-n print ruby script with line number
-v enable verbose mode
-d set $DEBUG to true
-r [library] load a library
-K [kcode] specify KANJI code-set
-S [safe_level] set $SAFE (0..4)
-T [trim_mode] specify trim_mode (0..2, -)
-P ignore lines which start with "%"
so erb your_erb_file.erb should write the result to STDOUT.
(EDIT: windows has erb.bat and just plain "erb". The .bat file is just a wrapper for erb, which I guess should make the same command work pretty much the same on any OS)
See the prag prog book discussion (starts about half-way down the page).
Note also that Jack Herrington wrote a whole book about code generation that uses Ruby/ERB.
Write a ruby script that does it. The API documentation is here:
http://www.ruby-doc.org/stdlib/libdoc/erb/rdoc/
For example:
template = ERB.new File.read("path/to/template.erb"), nil, "%"
template.result(binding)
(Where binding is a binding with the #vars that the template needs.)
Another option would be to use ruby -e, since ERB itslef is so simple.
Something like:
ruby -rerb -e "puts ERB.new(File.read(<file name here>)).result"
However, I assume you have a context you want to render the template in. How are you expecting to get that context? As an example, check out:
ruby -rerb -e "hello = 'hello'; puts ERB.new('<%= hello %> world').result(binding)"
which will print out "hello world", using the top-level, where you defined the hello variable, as the binding.
If you can switch ERB to Erubis, your problem solving is as simple as:
require 'erubis'
template = File.read("sample_file.erb")
template = Erubis::Eruby.new(template)
template.result(:your_variable => "sample")
Found this question while trying to test my Puppet templates.
Ended with this solution:
Along your foo.erb create a file foo.vars.erb
Put all your template variables into that new file, e.g.:
<% #my_param="foo bar" %>
<% #another_param=123 %>
or (equivalent):
<%
#my_param="foo bar"
#another_param=123
%>
On command line run this:
cat foo.vars.erb foo.erb | erb
Your fully rendered template should now be printed to std-out. From there you check the output by hand, or you can take diff (or other tools) to compare it to a pre-rendered output.
I tried to comment on this, but comments link not available.
I'm using this:
template = ERB.new File.new("path/to/template.erb").read, nil, "%"
template.result(binding)
From the posting above: and I found what I think it might be a problem:
I'm creating DOS BATCH files like:
%JAVA_HOME%\bin\jar -xvf <%=inputfile%>...
And I found weird thing problem - I get this when I run with the code above:
Processing Template test.txt
erb):2:in `render': compile error (SyntaxError)
erb):2: syntax error, unexpected tSTRING_BEG, expecting $end
erbout.concat "\n"
^
from DBUser.rb:49:in `render'
from DBUser.rb:43:in `each'
from DBUser.rb:43:in `render'
from DBUser.rb:81
I tried the following, and got round my particular problem - not sure if this is the right answer for everybody ...
template = ERB.new File.new("path/to/template.erb").read
template.result(binding)

Resources