Created
April 20, 2014 13:05
-
-
Save emad-elsaid/11113733 to your computer and use it in GitHub Desktop.
Convert Ruby scripts to HTML and Markdown
first i have to say that my scripts will be a little longer
than ever, to be more verbose and less encrypted, so images associated with my posts will be cropped and linked to
full post on Github, post will contain an HTML version and code file.
this script will read ruby code and parse it and split it to…
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
# Author : Emad Elsaid (https://github.com/blazeeboy) | |
require 'pygmentize' # gem install pygmentize | |
require 'redcarpet' # gem install redcarpet | |
# consecutive lines of code | |
# should be highlighted using pygmentize | |
# and converter to markdown block simply | |
# using the markdown syntax for code | |
# used by github flavored markdown | |
class CodeBlock < Array | |
def to_html | |
Pygmentize.process join, :ruby | |
end | |
def to_md | |
"```ruby\n#{join}\n```" | |
end | |
alias_method :to_markdown, :to_md | |
end | |
# set of consecutive lines of comments | |
class CommentBlock < Array | |
# will use this Redcarpet renderer to convert | |
# markdown to html | |
@@renderer = Redcarpet::Markdown.new(Redcarpet::Render::HTML, | |
fenced_code_blocks: true, | |
disable_indented_code_blocks: true, | |
strikethrough: true, | |
superscript: true, | |
underline: true, | |
autolink: true ) | |
# use the renderer on the content | |
def to_html | |
@@renderer.render join("\n") | |
end | |
# convert the block to markdown format | |
# and also give it a full name alias | |
def to_md | |
join("\n") | |
end | |
alias_method :to_markdown, :to_md | |
end | |
# container class will have multiple blocks of | |
# comments and code | |
class CodeConverter < Array | |
# you should pass code when | |
# initializing new instance | |
# in order to parse it | |
def initialize( code ) | |
parse code | |
end | |
# add new line of code to the class | |
# it start new code block if the last block is | |
# not code block then adds the line of code | |
# to the last block | |
def add_code( line ) | |
self << CodeBlock.new unless last.is_a? CodeBlock | |
last << line | |
end | |
# add new comment line to the class | |
# it adds new comment block if the last block is not | |
# comments block then add the comment line to the block | |
def add_comment( line ) | |
self << CommentBlock.new unless last.is_a? CommentBlock | |
last << line | |
end | |
# parse code and put result to this class | |
# first insert a comment block then | |
# parse each line and add it according | |
# to the line type | |
def parse(code) | |
replace [CommentBlock.new] | |
code.lines.each do |line| | |
case | |
when line.strip.start_with?('# ') | |
add_comment line.strip[2..-1] | |
when line.strip.start_with?('#!') | |
add_code line | |
when line.strip.start_with?('#') | |
add_comment line.strip[1..-1] | |
else | |
add_code line | |
end | |
end | |
end | |
# convert each block to html | |
# and wrap it in a styled page | |
# if a file path passed it'll write output to it | |
# in all cases it'll return the output | |
def to_html(file = nil) | |
code = map.with_index do |block, i| | |
# each cell in resulted table | |
# will have a class same as the | |
# class name of teh block downcased | |
klass = block.class.to_s.downcase | |
# start table row or end it | |
# according to the current block index | |
prefix = i.even? ? '<tr>' : '' | |
suffix = i.odd? ? '</tr>' : '' | |
# produced block html | |
"#{prefix}<td class=\"section #{klass}\">#{block.to_html}</td>#{suffix}" | |
end | |
# add a closing cell if the code | |
# ends with comments lines | |
code << "<td></td></tr>" if last.is_a? CommentBlock | |
# here is the full page with embeded style | |
# i had to add the css here to make sure script stay as | |
# one file not multiple dependent files. | |
html = <<-EOT | |
<html> | |
<head> | |
<style> | |
body { background: #29281e; padding:0px; margin:0px; font-family: verdana, tahoma; font-size: 13px; } | |
.content{ border-collapse: collapse; } | |
.section{ padding: 5px; border-top: 1px solid #333; } | |
.commentblock{ width: 40%;text-align: right; vertical-align: top; font-size: 13px; color: #ddd; text-shadow: 1px 1px 0px black; } | |
.codeblock{ width: 60%; background: #29281e; border-left: 1px solid #333; padding-left: 10px; } | |
.commentblock a{ color: #fff; } | |
.codeblock pre{ white-space: pre-wrap; margin: 0px; } | |
.highlight { padding: 0px; font-size: 13px; } | |
div.highlight, div.highlight code, div.highlight pre { padding: 0px; }div.highlight code { padding: 0; }div.highlight .c { color: #75715e }div.highlight .err { color: #960050; background-color: #1e0010 }div.highlight .k { color: #66d9ef }div.highlight .l { color: #ae81ff }div.highlight .n { color: #f8f8f2 }div.highlight .o { color: #f92672 }div.highlight .p { color: #f8f8f2 }div.highlight .cm { color: #75715e }div.highlight .cp { color: #75715e }div.highlight .c1 { color: #75715e }div.highlight .cs { color: #75715e }div.highlight .ge { font-style: italic }div.highlight .gs { font-weight: bold }div.highlight .kc { color: #66d9ef }div.highlight .kd { color: #66d9ef }div.highlight .kn { color: #f92672 }div.highlight .kp { color: #66d9ef }div.highlight .kr { color: #66d9ef }div.highlight .kt { color: #66d9ef }div.highlight .ld { color: #e6db74 }div.highlight .m { color: #ae81ff }div.highlight .s { color: #e6db74 }div.highlight .na { color: #a6e22e }div.highlight .nb { color: #f8f8f2 }div.highlight .nc { color: #a6e22e }div.highlight .no { color: #66d9ef }div.highlight .nd { color: #a6e22e }div.highlight .ni { color: #f8f8f2 }div.highlight .ne { color: #a6e22e }div.highlight .nf { color: #a6e22e }div.highlight .nl { color: #f8f8f2 }div.highlight .nn { color: #f8f8f2 }div.highlight .nx { color: #a6e22e }div.highlight .py { color: #f8f8f2 }div.highlight .nt { color: #f92672 }div.highlight .nv { color: #f8f8f2 }div.highlight .ow { color: #f92672 }div.highlight .w { color: #f8f8f2 }div.highlight .mf { color: #ae81ff }div.highlight .mh { color: #ae81ff }div.highlight .mi { color: #ae81ff }div.highlight .mo { color: #ae81ff }div.highlight .sb { color: #e6db74 }div.highlight .sc { color: #e6db74 }div.highlight .sd { color: #e6db74 }div.highlight .s2 { color: #e6db74 }div.highlight .se { color: #ae81ff }div.highlight .sh { color: #e6db74 }div.highlight .si { color: #e6db74 }div.highlight .sx { color: #e6db74 }div.highlight .sr { color: #e6db74 }div.highlight .s1 { color: #e6db74 }div.highlight .ss { color: #e6db74 }div.highlight .bp { color: #f8f8f2 }div.highlight .vc { color: #f8f8f2 }div.highlight .vg { color: #f8f8f2 }div.highlight .vi { color: #f8f8f2 }div.highlight .il { color: #ae81ff } | |
</style> | |
</head> | |
<body> | |
<table class="content">#{code.join}</table> | |
</body> | |
</html> | |
EOT | |
# write output to file if a path is passed | |
# and return html | |
File.write file, html unless file.nil? | |
html | |
end | |
# Convert the analyzed code into Markdown | |
# this is easier than HTML as you'll need | |
# to convert each block to markdown and | |
# join them with new line | |
# write output to file if a path is passed | |
def to_md(file=nil) | |
md = map {|b| b.to_md }.join "\n" | |
File.write file, md unless file.nil? | |
md | |
end | |
alias_method :to_markdown, :to_md | |
end | |
# ## How to use ? | |
# create new Code Converter class with code | |
blocks = CodeConverter.new( File.read('/path/to/code/file.rb') ) | |
# and convert to html and markdown and save it to this file path | |
blocks.to_html '/path/to/html/code.html' | |
blocks.to_md '/path/to/md/markdown.md' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
#Hello, I am Danny Volk and I have created this project to Teach You about William A. Mitchell and Please refer to my slides for answers. Copy and paste the answers without the letters attached to the answers.
#Quick Answers :)
=begin
1A. An Astronaught
1B. A Dancer
1C. An Inventor
2A. Invent Tang
2B. Ride on the Hubble
2C. Invent the moon walk
3A. The Mercury Food Program
3B. Ride on the Hubble
3C. Invent the moon walk
=end
print "Who was William A. Mitchell?"
=begin
A. An Astronaught
B. A Dancer
C. An Inventor
=end
first_name = gets.chomp!
first_name.downcase!
print "What did William A. Mitchell do?"
=begin
A. Invented Tang
B. Rode on the Hubble
C. Invented the moon walk
=end
last_name = gets.chomp!
last_name.downcase!
print "Where was Willian A. Mitchells work implemented?"
=begin
A. In Bruno Mar's Dancing
B. In The Mercury Food Program
C. In NASA Aeronautics
=end
city = gets.chomp!
city.upcase!
puts "You Said: William A. Mitchell was #{first_name} who #{last_name} and whos work was implemented In #{city}."
puts "The Correct Answer was: William A. Mitchell was an inventor who invented tang and whos work was implemented In THE MERCURY FOOD PROGRAM."
#Thank you for taking my quiz and Amazing Work. -Danny