I am using Ruby's RDiscount to convert markdown to HTML.
The markdown documents contain links (or images) that are relative to the path of the markdown file itself.
Is there a way for me to tell RDiscount that it should prepend all relative links with a string (folder) of my choice?
I am trying to achieve an effect similar to how GitHub shows images in README - where the files are looked for in the same directory as the README.
Here is an example code:
require 'rdiscount'
markdown = "![pic](image.png)\n\n[link](somewhere.html)"
doc = RDiscount.new(markdown)
# I would like to do something here, like:
# doc.base_link_path = 'SOMEFOLDER'
html = doc.to_html
puts html
# actual output =>
# <p><img src="image.png" alt="pic" /></p>
# <p>link</p>"
# desired output =>
# <p><img src="SOMEFOLDER/image.png" alt="pic" /></p>
# <p>link</p>"
I looked at the RDiscount class documentation but did not find anything like this.
Related
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:
A word of warning up front: I do not know even the ruby basics, but I'm trying to learn more and more of the world of shell scripting this year.
I saw this Vimeo video of Ben Schwarz and immediately thought that I'd like to use such a tool to debug my sass and haml files.
So this is a call to help me to grasp the concept of Sinatra.
What I want is a simple way to output the code of my index.html to check if all the haml magic was applied correctly - so it should function as a source viewer that gives me live updates. I'd prefer it if Sinatra simply looked at the files that LiveReload already rendered (c.f. index.html) in my project folder.
Update: This is a screenshot of the Vimeo Video. It shows just the raw CSS output of a Sass file. This is what I'd like to have for my Haml and Sass code, or better for the output files that are already rendered by LiveReload as HTML and CSS.
I looked at the source file from #benschwarz at his github, but I wasn't even with his own example I'm only getting the standard: "Sinatra doesn’t know this ditty." So transferring this to work with html is still out of my reach.
What I did so far:
I setup my project as usual in ~/Sites/projectname
I setup RVM and install all the gems I need
Sass, Compass, Haml - the output gets compiled via LiveReload
Sinatra
I created myapp.rb in ~/Sites/projectname with the following content:
# myapp.rb
require 'sinatra'
set :public_folder, '/'
get '/' do
File.read(File.join('public', 'index.html'))
end
Whatever, I fired up Sinatra and checked http://localhost:4567/ – this didn't work because I do not know how to set the public_folder to ~/Sites/projectname.
Afterthoughts:
So I went on to search the net, but my limited knowledge of Ruby put my attempt of an successful research to an immediate halt.
Here are some sites I stumpled upon which are obvioulsy close to the solution I need, but… like I told you in the first sentence: if the solution was a book, I'd need the "For Dummies" version.
https://bitbucket.org/sulab/genelist_store/src/30fc0ba390b9/idea8/idea8.rb
Serving static files with Sinatra
http://www.sinatrarb.com/intro
Obvioulsy the reference documentation of Sinatra would help me, but I don't speak the language, hence, I don't get the lingo.
About public folder:
The public_folder is relative to your app file myapp.rb. If you have a public folder inside the projectname folder, this is your public folder. If you have your css, js and image files in another folder, say, includes under project_name, then you need to change the line:
# Actually, you need to remove the line above from myapp.rb as it is.
# The line means that the public folder which is used to have css, js and
# image files under '/' and that means that even myapp.rb is visible to everyone.
set :public_folder, '/'
# to:
set :public_folder, File.dirname(__FILE__) + '/includes'
And that will serve up css, js and/or image files from the project_name/includes folder instead of project_name/public folder.
Reading the html file:
Reading the html files does not depend on the public folder settings. These need not be inside the public folder.
get '/' do
File.read(File.dirname(__FILE__) + '/index.html')
# This says that the app should read the index.html
# Assuming that both myapp.rb and index.html are in the same folder.
# incase the html files are inside a different directory, say, html,
# change that line to:
# File.read(File.dirname(__FILE__) + '/html/index.html')
# Directory structure sample:
# project_name
# | - myapp.rb
# | - index.html (and not html/index.html etc.)
# | /public (or includes incase the css, js assets have a different location)
# | | /css
# | | /js
# | | /images
end
To get the html output inside the browser
After the file is read, typically, this will be your string: "<html><head></head><body></body></html>"
Without escaping the string, the browser renders the html string as html (no pun) and that's why you won't see any text. To escape the html, you can use the CGI class provided by Ruby (hat tip). So, in the end, this will be your snippet:
get '/' do
CGI::escapeHTML(File.read(File.dirname(__FILE__) + 'index.html'))
end
But that will spit out the html file in a single line. To clean it up,
# myapp.rb
get '/' do
#raw_html = CGI::escapeHTML(File.read(File.dirname(__FILE__) + 'index.html'))
end
# Using inline templates to keep things simple.
# get '/' do...end gets the index.erb file and hence, in the inline template,
# we need to use the ## index representation. If we say get '/home' do...end,
# then the inline template will come under ## home. All the html/erb between
# two "##"s will be rendered as one template (also called as view).
# The <%= #raw_html %>spews out the entire html string read inside the "get" block
__END__
## index
<html>
<head></head>
<body>
<pre>
<%= #raw_html %>
</pre>
</body>
</html>
If you're trying to render an index.html file, I would try storing it in the /views directory with an .erb extension. Or use an inline template. Here is a great resource
I want to include image in yard-genereted documentation, but can't find anywhere how to do this... Does anyone know how to do this?
You can just add <img /> tag to your documentation:
# Blah-blah
#
# <img src=img/1.png />
# #param [String] blah
# #return [String] blah
def foo(bar)
end
Use rdoc-image: links:
# Gets foo.
#
# rdoc-image:img/1.png
def foo(bar)
"foo"
end
is rendered by YARD into
<p>Gets foo.</p>
<p><img src="img/1.png"></p>
The rdoc-images: also works in standalone *.rdoc files.
Depending on your markup format you may have to use another mechanism. For instance, if you use Markdown, the syntax is ![Alt text](/path/to/img.jpg). In RDoc, an img tag should work, but you can check if they have added a special markup syntax for this. Note that RDoc probably (not sure) doesn't like XHTML, you should use with no ending /.
I need to retrieve all the links to text files in an HTML document, I don't know what the best way to do this is but, I have tried the following in ruby...
line.scan(/<a href="([\w+:\/.-]*.txt)/)
but I am not sure if this expression covers all possible links pointing to text file, I am wondering if there are some built-in regular expressions for this? or if anyone knows of a better way to retrieve all links to a text file in a huge webpage.
This will walk through the HTML and find all hrefs with a '.txt' extension:
#!/usr/bin/env ruby
require 'nokogiri'
html = <<EOT
<html>
<head><title>foo</title></head>
<body>
text file
jpg file
text file 2
</body>
</html>
EOT
doc = Nokogiri::HTML(html)
puts doc.search('a').select { |n| n['href'][/\.txt$/] }.map{ |n| n['href'] }
> file.txt
> file2.txt
It's using Nokogiri to parse the content, which really is a lot more bullet-proof than trying to use regex.
Try this (captures all txt files, not just links):
html.scan(/[^\s"']+\.txt/)
To capture links to text files only:
html.scan(/<a [^<>\n]*?href=["']([^\s"']+\.txt)["'][^<>\n]*?>.*?<\/a>/m)
How do I include a ruby code file, as is, into RDoc?
I have an example.rb file that documents how to use my gem and I would like to include that as one of the files like the README.rdoc and HISTORY.rdoc.
I've already figured out how to convert the ruby source code into HTML using the Syntax gem but I can't figure out how to make RDoc include the file without parsing it.
When I tell RDoc to include the html file it isn't listed and if I fake it out by using rdoc or txt as the file extension it doesn't display properly (the file is still actually html).
I've got a solution that works it's just incredibly ugly. There has got to be a better way to do this that's native to rdoc but I don't see it.
Here's what I have in my Rakefile:
# Build rdocs
require 'rake/rdoctask'
require 'syntax/convertors/html'
rdoc_dir = 'rdoc'
# This is rdoc1 but it doesn't work unless you DON'T wrap it in a task
# Generate html files from example ruby files
convertor = Syntax::Convertors::HTML.for_syntax "ruby"
replacement_key = "REPLACE_THIS_TEXT_WITH_PROPER_HTML"
# Create dummy files
Dir.glob('examples/*.rb').each do |file|
File.open("#{file}.txt", "w") do |dummy_file|
dummy_file.write(replacement_key)
end
end
# Call the rdoc task
Rake::RDocTask.new(:rdoc2) do |rdoc|
rdoc.rdoc_dir = rdoc_dir
rdoc.title = "pickled_optparse #{version}"
rdoc.rdoc_files.include('README*')
rdoc.rdoc_files.include('HISTORY*')
rdoc.rdoc_files.include('examples/*.txt')
rdoc.rdoc_files.include('lib/**/*.rb')
end
task :rdoc3 do
# Now use a hammer to replace the dummy text with the
# html we want to use in our ruby example code file.
html_header = File.read('rake_reqs/html_header.html')
Dir.glob('examples/*.rb').each do |file|
html_ruby = convertor.convert(File.read(file))
rdoc_file = "#{rdoc_dir}/examples/#{File.basename(file,".rb")}_rb_txt.html"
fixed_html = File.read(rdoc_file).gsub!(replacement_key, "#{html_header}#{html_ruby}")
File.open(rdoc_file, "w") {|f| f.write(fixed_html)}
File.delete("#{file}.txt")
end
end
task :rdoc => [:rdoc2, :rdoc3]
Sorry I can't give you an actual answer but I'm looking at sdoc myself.
You can install the gem from ruby gems.