#!/usr/bin/ruby
# author: YOSHIDA Kazuhiro (moriq)
# mailto: moriq@moriq.com
# require 'opname'
require File.dirname(__FILE__.gsub(/\\/,'/')) + '/../lib/opname'
def html_escape(s)
s.gsub!( /&/, "&" )
s.gsub!( /, "<" )
s.gsub!( />/, ">" )
s.gsub!( /"/, """ )
s
end
def html_anchor(src, cap)
%!#{cap}!
end
def space_split(src)
src.strip!
pos = src.index(' ')
if pos then [src[0...pos], src[pos+1..-1]] else [src, src] end
end
class Pi
SURFIX = 'pi'
UP = {
:item => "
\n",
:enum => "\n",
:defi => "\n",
}
DOWN = {
:item => "
\n",
:enum => "\n",
:defi => "\n",
}
def reset
@lev = 0
@stack = []
@line_env = :section
@title = ''
@author = ''
@mailto = ''
@header = ''
@footer = ''
@text = ''
end
def initialize
reset
end
attr :title
attr :author
attr :mailto
attr :header
attr :footer
def levdown(lev)
# (@lev-1).downto(lev){|i| @text<<' '*i<\n"
end
@line_env = :item
lev+= 1
levmove lev, @line_env
cap = $'.chomp
# @text<<' '*lev<<"#{cap}\n"
@text<<"*"*lev<<" #{cap}\n"
@lev = lev
when /^\+ /
if @line_env == :text
# @text<<' '*@lev<<"
\n"
end
@line_env = :enum
lev+= 1
levmove lev, @line_env
cap = $'.chomp
# @text<<' '*lev<<"#{cap}\n"
@text<<"#"*lev<<" #{cap}\n"
@lev = lev
when /^\: /
if @line_env == :text
# @text<<' '*@lev<<"
\n"
end
@line_env = :defi
lev+= 1
levmove lev, @line_env
cap = $'.chomp
if lev == 1
# name = Opname.op2name(Opname.method_str(cap.strip))
# @text<<' '*lev<<%!#{cap}\n!
@text<<"!!! "<<%!#{cap.split(/::/).join('-')}\n!
else
# @text<<' '*lev<<%!#{cap}\n!
@text<<": "<<%!#{cap}!
@text<<": "
end
# @text<<' '*lev<<"\n" # for IE
@lev = lev
else
if /\S/ =~ line
cap = string.chomp
cmp = lev <=> @lev
if cmp == -1
levdown lev
else
levup lev, :defi
end
# @text<<' '*lev
case cmp
when 0
@text<<"\n" if [:item, :enum, :text].include? @line_env
when 1
# @text<<""
else
@text<<"\n" if lev > 0
end
@line_env = :text
@text<"
end
end
@text<<"\n"
end
end
def parse_line(line)
if /^----$/ =~ line
levdown 0
@line_env = :section
@text<<"
"
return
end
trans_word(line)
case line
when /^header:/
levdown 0
_text = @text
@text = @header
while line = @srcfile.gets
break if ~ /^end\b/
# parse_line(line)
end
levdown 0
@text = _text
when /^footer:/
levdown 0
_text = @text
@text = @footer
while line = @srcfile.gets
break if ~ /^end\b/
# parse_line(line)
end
levdown 0
@text = _text
when /^title:/
@title = $'.strip
when /^author:/
@author = $'.strip
when /^mailto:/
@mailto = $'.strip
when /^(\d+\.)+/
@line_env = :section
sec = ($&.length)/2
marker = '!'*sec
cap = $'.chomp.strip
levdown 0
@text<<"#{marker} #{cap.split(/::/).join('-')}\n"
else
trans_line(line)
end
end
def append_line(line)
case line
when /^include:/
src, *opt = $'.strip.split(/,/)
begin
dirname = File.dirname(@srcname)
text = open(File.join(dirname, src.strip)).read
rescue
text = "(fail to include #{src})"
end
text.gsub!(/.{76}/, "\\0\\\n") if opt.include? 'wrap'
# html_escape(text) if opt.include? 'escape'
@text<<"\t"<\n%
while line = @srcfile.gets
break if /^--/ =~ line
# html_escape(line)
append_line(line)
end
# @text<<"\n"
end
def parse_text
parse_plain('text')
end
def parse_ruby
parse_plain('ruby')
end
def parse_code
parse_plain('code')
end
def parse_html
while line = @srcfile.gets
break if /^--/ =~ line
append_line(line)
end
end
def parse
while @srcfile.gets
case $_
when /^ *--([a-z_]+)/
kind = $1
~ /^( )*/
indent = $&
string = $'
lev = (indent.length)/2
# levdown lev
cmp = lev <=> @lev
if cmp == -1
levdown lev
else
levup lev, :defi
end
# @text<<' '*lev
case cmp
when 0
@text<<"\n" if [:item, :enum, :text].include? @line_env
when 1
# @text<<""
else
@text<<"\n" if lev > 0
end
eval "parse_#{kind}"
@line_env = :heredoc
else
parse_line($_)
end
end
levdown 0
end
def nav_apply
return if @srcname.nil?
dirname = File.dirname(@srcname)
tree_fn = dirname + '/nav.dat'
return if !test ?e, tree_fn
tree = IO.readlines tree_fn
tlev = []
tcap = []
tcap_up = []
cnt = 0
tree.each { |i|
i.chomp!
/^ */ =~ i
indent, string = $&, $'
cap, cap_up = string.split
lev = indent.length / 2
tlev[cnt] = lev
tcap[cnt] = cap
tcap_up[cnt] = cap_up
cnt+= 1
}
return if cnt == 0
cur = tcap.rindex(@capc)
if cur.nil?
$stderr.print "not found node '#@capc' in nav.dat\n"
cur = 0
end
if tcap_up[cur].nil?
cnt = cur
begin
break if cnt == 0
cnt-= 1
end while tlev[cnt] >= tlev[cur]
end
top = tcap.empty? ? 'top' : html_anchor(tcap[0], 'top')
up = html_anchor(tcap_up[cur] || tcap[cnt], 'up')
prev = cur == 0 ? 'prev' : html_anchor(tcap[cur-1], 'prev')
ncxt = cur == tcap.size-1 ? 'next' : html_anchor(tcap[cur+1], 'next')
nav = <