#!/usr/bin/ruby
$script_call = $0 + " " + ARGV.join(" ")
$key="%DRC%"
$infile="src/drc/drc/built-in-macros/drc.lym"
$loc = "about/drc_ref"
$outfiles="src/lay/lay/doc"
$title="DRC Reference"
def create_ref(s)
if s =~ /(.*)#(.*)/
"#{s}"
else
"#{s}"
end
end
def create_class_doc_ref(s)
"#{s}"
end
def escape(s)
s.gsub("&", "&").
gsub("<", "<").
gsub(">", ">").
gsub(/\\([\w#]+)/) { create_ref($1) }.
gsub(/RBA::([\w#]+)/) { create_class_doc_ref($1) }
end
def unescape(s)
s.gsub("&", "&").gsub("<", "<").gsub(">", ">")
end
class DocItem
attr_accessor :brief
attr_accessor :synopsis
attr_accessor :name
attr_accessor :doc
def initialize(block)
@paragraphs = []
para = nil
self.synopsis = []
in_code = false
block.each do |b|
if in_code
if b =~ /@\/code/
in_code = false
end
para.push(b)
elsif b =~ /^@brief\s+(.*?)\s*$/
self.brief = $1
elsif b =~ /^@name\s+(.*?)\s*$/
self.name = $1
elsif b =~ /^@synopsis\s+(.*?)\s*$/
self.synopsis.push($1)
elsif b =~ /^@scope/
# ignore scope commands
elsif b =~ /^\s*$/
para && @paragraphs.push(para)
para = nil
else
para ||= []
para.push(b)
if b =~ /@code/
in_code = true
end
end
end
para && @paragraphs.push(para)
end
def produce_doc
if @paragraphs.empty?
return ""
end
doc = "
\n"
@paragraphs.each_with_index do |p, i|
i > 0 && doc += "
\n"
p.each do |pp|
doc += escape(pp).
gsub(/\\@/, "&at;").
gsub(/\s*@code\s*/, "
").
gsub(/\s*@\/code\s*/, "").
gsub(/@img\((.*)\)\s*/) { "
" }.
gsub(/@\/img\s*/, "").
gsub(/@(\w+)\s*/) { "<" + $1 + ">" }.
gsub(/@\/(\w+)\s*/) { "" + $1 + ">" }.
gsub(/&at;/, "@")
doc += "\n"
end
end
doc += "\n"
end
end
class Scope < DocItem
def initialize(block)
super(block)
@items = {}
end
def add_doc_item(block)
item = DocItem::new(block)
@items[item.name] = item
end
alias :super_produce_doc :produce_doc
def produce_doc
doc = <
HEAD
doc += "\n"
doc += "" + escape(self.brief) + "\n"
doc += "\n"
doc += super_produce_doc
doc += "\n"
@items.keys.sort.each do |item_key|
item = @items[item_key]
item.name || raise("Missing @name for item #{item_key}")
item.brief || raise("Missing @brief for item #{item_key}")
doc += "\"" + escape(item.name) + "\" - " + escape(item.brief) + "
\n"
doc += "\n"
doc += ""
if ! item.synopsis.empty?
doc += "Usage:
\n"
doc += "\n"
item.synopsis.each do |s|
doc += "- " + escape(s) + "
\n"
end
doc += "
\n"
end
doc += item.produce_doc
end
doc += "\n"
doc
end
end
class Collector
def add_block(block)
if block.find { |l| l =~ /^@scope/ }
# is a scope block
@scopes ||= {}
@current_scope = Scope::new(block)
@scopes[@current_scope.name] = @current_scope
else
@current_scope && @current_scope.add_doc_item(block)
end
end
def produce_doc
@scopes.keys.sort.each do |k|
suffix = k.downcase
outfile = $outfiles + "/" + $loc + "_" + suffix + ".xml"
File.open(outfile, "w") do |file|
file.write(@scopes[k].produce_doc)
puts "---> #{outfile} written."
end
end
end
def produce_index
outfile = $outfiles + "/" + $loc + ".xml"
File.open(outfile, "w") do |file|
doc = <
HEAD
doc += "\n"
doc += "#{escape($title)}\n"
doc += "\n"
doc += "\n"
@scopes.keys.sort.each do |k|
suffix = k.downcase
doc += "\n"
end
doc += "\n"
doc += "\n"
file.write(doc)
end
puts "---> Index file #{outfile} written."
end
end
collector = Collector::new
File.open($infile, "r") do |file|
block = nil
file.each_line do |l|
l = unescape(l)
if l =~ /^\s*#\s*#{$key}/
block = []
elsif l =~ /^\s*#\s*(.*)\s*$/
block && block.push($1)
elsif l =~ /^\s*$/
block && collector.add_block(block)
block = nil
end
end
end
collector.produce_doc
collector.produce_index