Regex Tips / RubyをHTMLに変換するRuby Script

Powered by dKingyo Windows Server | Perl | Java | Graphic Gems | HTML

Ruby正規表現勉強がてらにruby2html.rbを作ってみた。
via Ruby Magic―Rubyで極める正規表現
処理はかなりいい加減であるので理解願いたい。
続きを読む

ちなみに今回は

ソースコードを色付けして記述する(シンタックス・ハイライト)

を使わずにこのスクリプト自身が出力したソースコードを掲載する事にした。


#!/usr/local/bin/ruby

=begin
ruby2html.rb

ruby2htmlというソフトが無かったので作ってみた。
だけど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.new

str = 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
end

end

=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 + line

if 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

と言う事で今回のPIECEは
Ruby構文に関する正規表現

コメント複数行 =begin([^*])*?=end
変数の文字列化 #\{.*\}
コメント1行 #.*
ダブルクォーテーション ".*?"/
正規表現 \/.*\/
クラス内変数 \@\w*