Sinatra で Code Viewer を作る(Ruby)
code_viewer.rb
require 'sinatra' require 'sinatra/reloader' require 'rouge' set :bind, '192.168.11.150' set :port, 16524 suffixes = {"rb" => "Ruby", "html" => "HTML", "css" => "CSS", "erb" => "ERB", "c" => "C", "cpp" => "Cpp", "py" => "Python", "go" => "Go"} types = %W(Base16 Colorful Github Gruvbox IgorPro Molokai Monokai MonokaiSublime Pastie ThankfulEyes Tulip) type_num = 3 formatter = Rouge::Formatters::HTML.new handle_dir = ->(dname) { dirs = [] files = [] Dir.chdir(dname) Dir.glob("*").sort.each do |fname| if File.directory?(fname) dirs << [fname, handle_dir.(fname)] else m = /\.(.*)/.match(fname) m = m ? m[1] : "" sf = suffixes[m] || "PlainText" lexer= eval("Rouge::Lexers::" + sf).new html = formatter.format(lexer.lex(File.read(fname))) rescue next files << [fname, html] end end Dir.chdir("..") {:dirs => dirs, :files => files} } sources = handle_dir.("user_codes") get '/' do @sources = sources @css_types = types @type_num = type_num erb :index end post '/' do type_num = params[:css_style].to_i redirect '/' end make_page = ->(h, path) { h[:dirs].each {|d| make_page.(d[1], path + d[0] + '/')} h[:files].each do |f| get path + f[0] do @html = f[1] @css_name = types[type_num].downcase erb :render end end } make_page.(sources, "/")
ディレクトリ views 内
index.erb
<!DOCTYPE html> <html lang="ja"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Code Viewer</title> <head> </head> <body> <h1>Code Viewer</h1> <form method="post"> <p>CSS Style <select name="css_style"> <% @css_types.each_with_index do |ty, i| %> <option value="<%= i %>"><%= ty %></option> <% end %> </select> <input type="submit" value="選択"> <span style="color: blue;"><%= @css_types[@type_num] %></span></p> </form> <% def handle(h, path) %> <ul> <% h[:dirs].each do |d| %> <li><%= d[0] %></li> <% handle(d[1], path + '/' + d[0]) %> <% end %> <% h[:files].each do |f| %> <li><a href="<%= path + '/' + f[0] %>" style="color: green;"><%= f[0] %></a></li> <% end %> </ul> <% end %> <% handle(@sources, "") %> </body> </html>
render.erb
<!DOCTYPE html> <html lang="ja"> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Code Viewer</title> <head> <link rel="stylesheet" type="text/css" href="/css/<%= @css_name %>.css"> <style type="text/css"> pre.highlight { font-family: Courier New, Consolas, monospace; font-size: 100%; padding: 10px; line-height: 1.1em; white-space: pre-wrap; } </style> </head> <body> <pre class="highlight"> <%= @html %> </pre> </body> </html>