Regex Tips / RubyをHTMLに変換するRuby Script
Powered by dKingyo Windows Server | Perl | Java | Graphic Gems | HTML
Rubyの正規表現勉強がてらにruby2html.rbを作ってみた。
via Ruby Magic―Rubyで極める正規表現
処理はかなりいい加減であるので理解願いたい。
続きを読む
ちなみに今回は
ソースコードを色付けして記述する(シンタックス・ハイライト)
を使わずにこのスクリプト自身が出力したソースコードを掲載する事にした。
と言う事で今回のPIECEは
#!/usr/local/bin/ruby=begin
ruby2html.rbruby2htmlというソフトが無かったので作ってみた。
だけどrb2htmlというソフトならあった・・・
rubyのソースコードをHTML形式としてファイルに出力するex.
ruby ruby2html.rb ruby2html.rb output.html
ruby ruby2html.rb yourfile.rb=end
input_f = $*[0]
output_f =$*[1]
fi = open(input_f,"r")str = String.new
os = String.newstr = fi.read
reg = /BEGIN|class\s|ensure|nil|self|when\s|END|def\s|\
false|not|super|while|alias|defined?|for\s|\
\sor\s|then|yield|\sand\s|\sdo|if\s|redo|true|begin|\
else|\sin\s|rescue|undef|break|elsif|module|\
retry|unless|case|end|next|return|until/
class Output
def default_undo_output(s)
return "#{s}"
end
def comment_undo_output(s)
return "<font color=green>#{s}</font>"
end
def string_undo_output(s)
return "<font color=firebrick>#{s}</font>"
end
def regex_undo_output(s)
return "<font color=darkviolet>#{s}</font>"
end
def atmark_undo_output(s)
return %Q(<font color=red>#{s}</font>)
end
end
=begin
いろいろと置換して予約語の置換中にひっかからないようにする
けっこう即席のむちゃくちゃな処理・・・
Rubyの構文仕様がもっと複雑だったらこの方法ではいい感じには出来なかった。不具合・・・と言うか仕様
/".*?"/
のように正規表現内にダブルクォーテーション等は上手く色分けできません。
=end
class Replace
def initialize(reg,reged)
@regex_str = reg
@regexed_str = reged
@arr
end
attr_accessor :arr
attr_reader :regex_str, :regexed_str
# google:5.13 副作用が起こるのはどんな時ですかを参照
def get_regexed_str(i)
return %Q(#{@regexed_str}) + sprintf("%08d",i)
end
def replace_target(target)
a = Array.new
i = 0
target.gsub!(@regex_str){|s|
a.push(s)
ts = get_regexed_str(i)
i = i+1
# p ts
s = ts
}
#p "a " + "#{a.length}"
@arr = a.clone
#p "arr " + "#{arr.length}"#print @regex_str ,"\t","replace","\t", "#{arr.length}","\n"
return a
end
def undo_target(target,callback)
count = 0
for i in 0..@arr.length - 1 do
#p i
ts = get_regexed_str(i)
#p ts
target.gsub!(ts){|s|
count = count + 1
s = callback.call(@arr[i])
}
end
#print @regex_str,"\t","undo","\t","#{count}" ,"\n"
if arr.length != count then
raise "count of replace and undo is different."
else
print @regex_str,"\t\t\t\t","count","\t","#{count}" ,"\n"
end
endend
=begin
str.gsub(/%Q\(.*?\)/){|s|
p s
}
=end#tag replace
os = String.new
str.each{|line|
line.gsub!("<","<")
line.gsub!(">",">")
line.gsub!("\t"," ");
os = os + line
}
str = os
#The classification of elements is substituted.
comment_tag_r = Replace.new(/=begin([^*])*?=end/,"DKINGYO_comment_tag_")
to_str_r = Replace.new(/#\{.*\}/,"DKINGYO_to_str_")
comment_r = Replace.new(/#.*/,"DKINGYO_comment_")string_r = Replace.new(/".*?"/,"DKINGYO_string_")
regex_r = Replace.new(/\/.*\//,"DKINGYO_regex_")
atmark_r = Replace.new(/\@\w*/,"DKINGYO_atmark_var_")
to_str_r.replace_target(str)
string_r.replace_target(str)
regex_r.replace_target(str)
comment_r.replace_target(str)
comment_tag_r.replace_target(str)
atmark_r.replace_target(str)os = String.new
state = 0
str.each{|line|
if 0==state then
if nil != line.index("=begin") then
state = 1
end
end
if 0==state then
line.gsub!(reg) {|s|
s = %Q(<font color=blue>#{s}</font>)
}
end
os = os + lineif 0!=state then
if nil != line.index("=end") then
state = 0
end
end
}
str = os# undo
defout = Output.new.method(:default_undo_output)
comout = Output.new.method(:comment_undo_output)
regout = Output.new.method(:regex_undo_output)
strout = Output.new.method(:string_undo_output)
atmout = Output.new.method(:atmark_undo_output)atmark_r.undo_target(str,atmout)
comment_tag_r.undo_target(str,comout)
comment_r.undo_target(str,comout)
regex_r.undo_target(str,regout)
string_r.undo_target(str,strout)
to_str_r.undo_target(str,defout)
str.each{|line|
line.gsub!("&","&")
line.gsub!("\"",""")
}
begin
fo = open(output_f,"w")
rescue
#recover
puts "<pre>"
puts str
puts "</pre>"
else
fo.puts "<pre>"
fo.puts str
fo.puts "</pre>"
fo.close
ensure
#must_to_do
end
exit
Ruby構文に関する正規表現
コメント複数行 =begin([^*])*?=end
変数の文字列化 #\{.*\}
コメント1行 #.*
ダブルクォーテーション ".*?"/
正規表現 \/.*\/
クラス内変数 \@\w*