df2daf524d
Signed-off-by: Nico Schottelius <nico@manager.schottelius.org>
224 lines
7.2 KiB
Ruby
Executable file
224 lines
7.2 KiB
Ruby
Executable file
#!/usr/bin/env ruby
|
||
|
||
require 'misen/style-sgml'
|
||
require 'misen/util'
|
||
|
||
require 'getoptlong'
|
||
require 'fileutils'
|
||
require 'digest/sha1'
|
||
|
||
@version = '0.2'
|
||
@verbose = 0
|
||
@force = false
|
||
@outpath = "#{Dir.pwd}/generated"
|
||
@inpath = "#{Dir.pwd}/source"
|
||
@template = "#{Dir.pwd}/templates"
|
||
@default = 'default.html'
|
||
|
||
@datadir = "#{Dir.pwd}/data"
|
||
@filehash = Hash.new
|
||
|
||
def printMsg(prefix, msg, descriptor = $stdout)
|
||
descriptor.puts '%-12s %s' % [prefix + ':', msg]
|
||
end
|
||
|
||
def panic(msg)
|
||
printMsg('PANIC', msg, $stderr)
|
||
Kernel.exit(-1)
|
||
end
|
||
|
||
def error(msg)
|
||
printMsg('ERROR', msg, $stderr)
|
||
end
|
||
|
||
def warn(msg)
|
||
printMsg('WARNING', msg)
|
||
end
|
||
|
||
def info(msg)
|
||
printMsg('INFO', msg)
|
||
end
|
||
|
||
def debug(msg, verbosity = 1)
|
||
if(@verbose >= verbosity)
|
||
printMsg("DEBUG(#{verbosity})", msg, $stderr)
|
||
end
|
||
end
|
||
|
||
def generateMenu(dir, file = nil, level = 0)
|
||
debug("call generateMenu('#{dir}', '#{file}', #{level})")
|
||
template = '<ul<misen:class />>
|
||
<misen:menuentries>
|
||
<li><a href="<misen:url />"<misen:class />><misen:desc /></a><misen:menu /></li>
|
||
</misen:menuentries>
|
||
</ul>'
|
||
|
||
dir = dir + '/' if(!dir.empty? && dir[-1].chr != '/')
|
||
menu = File.new("#{dir}menu.def").readlines
|
||
|
||
data = Hash.new
|
||
menuentries = Array.new
|
||
|
||
menu.each { |x|
|
||
entry = x.split(/\s*\|\s*/, 2)
|
||
e = Hash.new
|
||
e[:class] = (file && dir + entry[0] == file ? ' class="active"' : '')
|
||
if(file && dir + entry[0] == file)
|
||
e[:class] = data[:class] = ' class="active"'
|
||
end
|
||
e[:url] = "/#{dir}#{entry[0]}" # TODO: make relative paths
|
||
e[:desc] = entry[1].strip
|
||
if(FileTest.directory?("#{dir}#{entry[0]}") && FileTest.exists?("#{dir}#{entry[0]}/menu.def"))
|
||
e[:menu] = generateMenu("#{dir}#{entry[0]}", file, level + 1)
|
||
end
|
||
menuentries << e
|
||
}
|
||
|
||
return '' if(menuentries.empty?)
|
||
|
||
data[:menuentries] = menuentries
|
||
|
||
return removeEmptyLine(Misen.expand_text(Misen::STYLE_SGML, template, data))
|
||
|
||
end
|
||
|
||
def generateFiles(dir = '')
|
||
debug("call generateFiles('#{dir}')")
|
||
dir = dir + '/' if(!dir.empty? && dir[-1].chr != '/')
|
||
Dir.foreach(dir.empty? ? '.' : dir) { |x|
|
||
next if(x =~ /^(\.|\.\.)$/)
|
||
|
||
if(x =~ /\.html$/)
|
||
if(!FileTest.exists?(@outpath + '/' + dir + x) || @filehash[dir + x] != Digest::SHA1.hexdigest(File.new(dir + x).read) || @force)
|
||
info("Transforming #{dir}#{x}")
|
||
data = {:style => getStylePath(dir) + 'style.css', :content => File.new("#{dir}#{x}").read, :menu => generateMenu('', dir + File.basename(x, '.html'))}
|
||
Dir.mkdir("#{@outpath}/#{dir}") if(!FileTest.exists?("#{@outpath}/#{dir}"))
|
||
File.open("#{@outpath}/#{dir}#{x}", "w") { |file|
|
||
file.print removeEmptyLine(Misen.expand_text(Misen::STYLE_SGML_EX, @source, data))
|
||
}
|
||
@filehash[dir + x] = Digest::SHA1.hexdigest(File.new(dir + x).read)
|
||
else
|
||
info("Nothing to do for #{dir}#{x}")
|
||
end
|
||
elsif(FileTest.directory?(dir + x))
|
||
begin
|
||
Dir.mkdir("#{@outpath}/#{dir}#{x}") if(!FileTest.exists?("#{@outpath}/#{dir}#{x}"))
|
||
rescue
|
||
panic("Could not create #{@outpath}/#{dir}#{x}: #{$!}")
|
||
end
|
||
generateFiles("#{dir}#{x}")
|
||
elsif(x !~ /(\.def|\.swp)$/)
|
||
if(!FileTest.exists?(@outpath + '/' + dir + x) || @filehash[dir + x] != Digest::SHA1.hexdigest(File.new(dir + x).read) || @force)
|
||
info("Copying file #{dir}#{x}")
|
||
FileUtils.cp(dir + x, @outpath + '/' + dir + x)
|
||
@filehash[dir + x] = Digest::SHA1.hexdigest(File.new(dir + x).read)
|
||
else
|
||
info("No need to copy #{dir}#{x}. Already latest.")
|
||
end
|
||
end
|
||
}
|
||
end
|
||
|
||
def removeEmptyLine(str)
|
||
str.split($/).collect{ |x| x =~ /^\s*$/ ? nil : x}.compact.join($/)
|
||
end
|
||
|
||
def getPath(path)
|
||
return path if(path[0].chr == '/')
|
||
return "#{Dir.pwd}/#{path}"
|
||
end
|
||
|
||
def getStylePath(dir)
|
||
newdir = ''
|
||
|
||
dir.split('/').each {
|
||
newdir += '../'
|
||
}
|
||
|
||
return newdir
|
||
end
|
||
|
||
def usage
|
||
info("Usage: #{File.basename(__FILE__)} [options]")
|
||
info('')
|
||
info('%20s %s' % ['--verbose, -v', 'Verbose output. Add v for more verbose output'])
|
||
info('%20s %s' % ['--inpath, -i', 'Specify where to search for input files [./source]'])
|
||
info('%20s %s' % ['--outpath, -o', 'Specify where to write the output files [./generated]'])
|
||
info('%20s %s' % ['--template, -t', 'Specify where to search for template files [./templates]'])
|
||
info('%20s %s' % ['--default, -d', 'The default template name [default.html]'])
|
||
info('%20s %s' % ['--force, -f', 'Force the new generating of all files [false]'])
|
||
info('%20s %s' % ['--help, -h', 'Print this screen'])
|
||
info('%20s %s' % ['--version, -V', 'Print the version and exit'])
|
||
end
|
||
|
||
puts "This is #{File.basename(__FILE__)} v#{@version} 2005 by Ren<65> Nussbaumer"
|
||
puts
|
||
|
||
opts = GetoptLong.new(
|
||
['--verbose', '-v', GetoptLong::OPTIONAL_ARGUMENT],
|
||
['--inpath', '-i', GetoptLong::REQUIRED_ARGUMENT],
|
||
['--outpath', '-o', GetoptLong::REQUIRED_ARGUMENT],
|
||
['--template', '-t', GetoptLong::REQUIRED_ARGUMENT],
|
||
['--default', '-d', GetoptLong::REQUIRED_ARGUMENT],
|
||
['--force', '-f', GetoptLong::NO_ARGUMENT],
|
||
['--help', '-h', GetoptLong::NO_ARGUMENT],
|
||
['--version', '-V', GetoptLong::NO_ARGUMENT]
|
||
)
|
||
|
||
opts.each { |arg,value|
|
||
case arg
|
||
when '--verbose'
|
||
@verbose += 1
|
||
value.each_byte { |x|
|
||
if(x.chr == 'v')
|
||
@verbose += 1
|
||
end
|
||
}
|
||
debug("Verbosity set to: #{@verbose}")
|
||
when '--inpath'
|
||
@inpath = getPath(value)
|
||
when '--outpath'
|
||
@outpath = getPath(value)
|
||
when '--template'
|
||
@template = getPath(value)
|
||
when '--default'
|
||
@default = value
|
||
when '--force'
|
||
@force = true
|
||
when '--help'
|
||
usage
|
||
Kernel.exit(0)
|
||
when '--version'
|
||
Kernel.exit(0)
|
||
else
|
||
warn("Unknown option #{arg}#{value && !value.empty? ? ('with value ' + value) : ''}")
|
||
end
|
||
}
|
||
|
||
debug("Current configuration:")
|
||
debug('%-10s %s' % ['Inpath:', @inpath])
|
||
debug('%-10s %s' % ['Outpath:', @outpath])
|
||
debug('%-10s %s' % ['Template:', @template])
|
||
debug('%-10s %s' % ['Default:', @default])
|
||
|
||
begin
|
||
Dir.mkdir(@inpath) if(!FileTest.directory?(@inpath))
|
||
Dir.mkdir(@outpath) if(!FileTest.directory?(@outpath))
|
||
Dir.mkdir(@template) if(!FileTest.directory?(@template))
|
||
Dir.mkdir(@datadir) if(!FileTest.directory?(@datadir))
|
||
rescue
|
||
panic("Could not create directory: #{$!}")
|
||
end
|
||
|
||
panic("#{@template}/#{@default} does not exist! Please create at least the default template.") if(!FileTest.exists?("#{@template}/#{@default}"))
|
||
|
||
@source = File.new("#{@template}/#{@default}").read
|
||
|
||
Dir.chdir(@inpath)
|
||
panic("Init directory needs a menu.def!") if(!FileTest.exists?('menu.def'))
|
||
|
||
@filehash = Marshal.load(File.new(@datadir + '/digest').read) if(FileTest.exists?(@datadir + '/digest'))
|
||
generateFiles
|
||
File.open(@datadir + '/digest', 'w') { |file|
|
||
file.print Marshal.dump(@filehash)
|
||
}
|