試験コード
一部未実装
#!/usr/bin/ruby -Ke require 'cgi' require 'date' class Xhtmlparser def initialize(data='',wikihome='/wiki/',footnum=1,footnote=[],caption=[],capnum=[1]*10) @data=data @wikihome,@footnum,@footnote,@caption,@capnum=wikihome,footnum,footnote,caption,capnum end def self.do_parse(data='',wikihome='/wiki/',footnum=1,footnote=[],caption=[],capnum=[1]*10) self.new(data,wikihome,footnum,footnote,caption,capnum).do_parse end def do_parse # #マクロ @data.gsub!(%r(<wiki:macro>[^<]*<wiki:cmd>(.+?)</wiki:cmd>[^<]*<wiki:name>(.+?)</wiki:name>[^<]*</wiki:macro>)){ c,p=$1,$2 c=c.gsub('<','<').gsub('>','>').gsub('&','&').gsub('quot;','""') if /(today|>>|<<|[0-9\+\-\*\/])+/.match(c) eval(c.gsub('today'){'Date::today'}).to_s.gsub(/([0-9]{4})-([0-9]{1,2})-([0-9]{1,2})/){ %Q(#{$1}/#{sprintf("%02d",$2.to_i)}/#{sprintf("%02d",$3.to_i)}) } else "###error macro #{c} ###" end } #URL @data.gsub!(%r(<wiki:url>[^<]*<wiki:uri>(.+?)</wiki:uri>[^<]*(?:<wiki:title>(.+?)</wiki:title>)?[^<]*</wiki:url>)m){ #url u=$1 u=$2 unless $2==nil %Q(<a href="#{$1}">#{u}</a>) } #Wikianchor @data.gsub!(%r(<wiki:anchor>[^<]*(?:<wiki:title>([^<]+)</wiki:title>)[^<]*(?:<wiki:name>([^<]+)</wiki:name>)[^<]*(?:<wiki:id>([^<]+)</wiki:id>)?[^<]*(?:<wiki:timestamp>([^<]+)</wiki:timestamp>)?[^<]*(?:<wiki:mode>([^<]+)</wiki:mode>)?[^<]*(?:<wiki:mtime>([^<]+)</wiki:mtime>)?[^<]*</wiki:anchor>)m){ # wiki anchor name,title,timestamp,mode,mtime,midasi=CGI::escape($2),$1,"","","","" midasi="#"+CGI::escape($3) if $3!=nil timestamp="×tamp="+CGI::escape($4) if $4!=nil mode="&mode="+CGI::escape($5) if $5!=nil mtime="&mtime="+CGI::escape($6) if $6!=nil arg = timestamp+mode+mtime arg = arg.sub!("&","?") if arg!="" %Q(<a href="#{@wikihome}#{name}#{arg}#{midasi}">#{title}</a>) } #sup @data.gsub!(%r(<wiki:sup>(.+?)</wiki:sup>)){ # sup f=@footnum @footnum+=1 @footnote.push(%Q(<a name="#{f}"><sup>*#{$1}</sup></a>)) %Q(<a href="#{f}"><sup>*#{f}</sup></a>) } #Caption @data.gsub!(%r(<wiki:caption>[^<]*<wiki:level>(.+?)</wiki:level>[^<]*<wiki:content>(.+?)</wiki:content>[^<]*<wiki:number>(.+?)</wiki:number>[^<]*</wiki:caption>)){ # caption @capnum[($1.to_i+1)..@capnum.size]=[1]*(@capnum.size-$1.to_i) cs=$2 if $3=="on" @capnum[$1.to_i]+=1 cs=%Q!#{@capnum[1..$1.to_i].map{|a|a-1}.join('.')} #{cs}! end @caption.push(cs) %Q(<h#{$1} class="caption"><a name="#{CGI::escape(cs)}">#{cs}</a></h#{$1} class="caption">) } #Command @data.gsub!(%r(<wiki:command>[^<]*<wiki:cmd>(.+?)</wiki:cmd>[^<]*<wiki:name>(.+?)</wiki:name>[^<]*<wiki:arg>(.*?)</wiki:arg>[^<]*</wiki:command>)){ c,n,a=$1,$2,$3 case c when 'contents' %Q(<!-- contents -->) when 'img' %Q(<img src="#{a}">) when 'line' %Q(<hr class="line">) when 'calendar' week=['日','月','火','水','木','金','土'] if %r!^(.+)-(\d{4})/(\d{1,2})/(\d{1,2})!.match(a) t,dt=$1,Date.new($2.to_i,$3.to_i,$4.to_i) eday=((fday=dt-dt.day+1)>>1)-1 r=%Q(<table class="calendar">\n<tr class="week"><td>#{week.join('</td><td>')}</td></tr>\n<tr>#{%Q(<td><br></td>)*(fday.wday)}) (fday).upto(eday){|d| r+=%Q(<td#{%Q( class="today") if Date.today==d}><a href="#{@wikihome}#{CGI::escape(t)}-#{d.year}/#{sprintf("%02d",d.mon)}/#{sprintf("%02d",d.day)}">#{sprintf("%2d",d.day)}</a></td>) r+="</tr>\n<tr>" if d.wday==6 } %Q(#{r}#{%Q(<td><br></td>)*(6-eday.wday)}</tr>\n</table class="calendar">) else "Error calender" end when 'calendarw' week=['日','月','火','水','木','金','土'] if %r!^(.+)-(\d{4})/(\d{1,2})/(\d{1,2})!.match(a) t,dt=$1,Date.new($2.to_i,$3.to_i,$4.to_i) r=%Q(<table class="calendarw">\n) (dt-dt.wday).upto(dt-dt.wday+6){|d| r+=%Q(<tr><td#{%Q( class="today") if Date.today==d}><a href="#{@wikihome}#{CGI::escape(t)}-#{d.year}/#{sprintf("%02d",d.mon)}/#{sprintf("%02d",d.day)}">#{d.mon}/#{d.day}</a>(#{week[d.wday]})</td></tr>\n) } %Q(#{r}</table class="calendarw">) else "Error calendarw" end end } @data end end if __FILE__==$0 # ライブラリテスト用コード data=STDIN.read # とりあえず標準入力からデータリード #定数 wikihome='/wiki/' footnum=1 footnote=[] caption=[] capnum=[1]*10 # puts Xhtmlparser.new(data,wikihome,footnum,footnote,caption,capnum).do_parse puts Xhtmlparser::do_parse(data,wikihome,footnum,footnote,caption,capnum) end