試験コード

一部未実装

 #!/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(&#39;<&#39;,&#39;<&#39;).gsub(&#39;>&#39;,&#39;>&#39;).gsub(&#39;&&#39;,&#39;&&#39;).gsub(&#39;quot;&#39;,&#39;""&#39;)
       if   /(today|>>|<<|[0-9\+\-\*\/])+/.match(c)
 	eval(c.gsub(&#39;today&#39;){&#39;Date::today&#39;}).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="&timestamp="+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(&#39;.&#39;)} #{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 &#39;contents&#39;
 	%Q(<!-- contents -->)
       when &#39;img&#39;
 	%Q(<img src="#{a}">)
       when &#39;line&#39;
 	%Q(<hr class="line">)
       when &#39;calendar&#39;
 	week=[&#39;日&#39;,&#39;月&#39;,&#39;火&#39;,&#39;水&#39;,&#39;木&#39;,&#39;金&#39;,&#39;土&#39;]
 	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(&#39;</td><td>&#39;)}</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 &#39;calendarw&#39;
 	week=[&#39;日&#39;,&#39;月&#39;,&#39;火&#39;,&#39;水&#39;,&#39;木&#39;,&#39;金&#39;,&#39;土&#39;]
 	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=&#39;/wiki/&#39;
   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