#!/usr/bin/env ruby
# coding: utf-8
load 'pandoc.rb'
class Pass0
def initialize
@line = ''
end
def getline
@line = $stdin.readline
end
def is_md
@line.start_with? "#"
end
def section_md
section = ""
while @line.start_with? "#"
section += @line.sub(/^# ?/, '')
getline
end
$stdout.puts "\n\n#{Pandoc::load('markdown', section).to('mediawiki')}\n\n"
end
def is_hd
not /(.*[^<])<<\s*([^<]\S+)/.match(@line).nil?
end
def section_hd
m = /(.*[^<])<<\s*([^<]\S+)/.match(@line)
return if m.nil?
prefix = m[1]
eot = m[2]
getline
body = ""
while @line != "#{eot}\n"
body += @line
getline
end
getline
body = body.gsub(/\\(.)/, '\1')
$stdout.puts "\n\n{{hc|#{prefix}|#{body.chomp}}}\n\n"
end
def is_hs
not /(.*[^<])<<<\'(.*)/.match(@line).nil?
end
def section_hs
m = /(.*[^<])<<<\'(.*)/.match(@line)
return if m.nil?
prefix = m[1]
body = m[2] + "\n"
getline
while not @line.end_with? "'\n"
body += @line
getline
end
body += @line.sub(/'$/, '')
getline
body = body.gsub("'\\''", "'")
$stdout.puts "\n\n{{hc|#{prefix}|#{body.chomp}}}\n\n"
end
def section_sh
section = ""
while true
if is_md
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
section_md
section = ""
elsif is_hd
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
section_hd
section = ""
elsif is_hs
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
section_hs
section = ""
elsif @line == "postamble\n"
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
return
else
if @line.start_with? 'add-unit '
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
$stdout.puts "f* {{ic|/#{@line.sub('add-unit ', '').chomp}}}"
section = ""
getline
next
end
m = /^ln -s (.*) (\S*)$/.match(@line)
if not m.nil?
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
$stdout.puts "f* {{ic|/#{m[2]}}}: {{ic|-> #{m[1]}}}"
section = ""
getline
next
end
if @line == "preamble\n" or @line == "postamble" or @line.start_with? 'install -d'
getline
next
end
if @line.start_with? 'netctl-enable '
$stdout.puts "\n\n{{bc|#{section.chomp}}}\n\n" unless section.gsub("\n", '') == ""
unit="netctl@#{`systemd-escape -- #{@line.sub(/^netctl-enable /, '')}`.chomp}.service"
$stdout.puts "f* {{ic|/etc/systemd/system/#{unit}}}"
$stdout.puts "f* {{ic|/etc/systemd/system/multi-user.target.wants/#{unit}}}"
getline
next
end
m = /^depends\+?=\((.*)\)/.match(@line)
if not m.nil?
m[1].split(/\s+/).each do |pkg|
$stdout.puts "p* {{ic|#{pkg}}}"
end
getline
next
end
if @line == "depends+=(\n"
getline
while @line != ")\n"
@line.sub(/#.*/, '').split(/\s+/).find_all{|x|not x.empty?}.each do |pkg|
$stdout.puts "p* {{ic|#{pkg}}}"
end
getline
end
getline
next
end
m = /^conflicts\+?=\((.*)\)/.match(@line)
if not m.nil?
$stdout.puts "p* group:{{ic|base}} except for {{ic|#{m[1]}}}"
getline
next
end
section += @line
getline
end
end
end
def run
while @line != "preamble\n"
getline
end
getline
section_sh
end
end
def pass0
Pass0.new.run
end
def pass1
exec('sed', '-r',
'-e', 's@^\{\{hc\|add-file (-\S+ )*([^|]*)\|(.*)\}\}$@f* {{ic|/\2}}: {{ic|\3}}@',
'-e', 's@^\{\{hc\|add-file (-\S+ )*([^|]*)\|@f* {{ic|/\2}}\n&@',
:in=>$stdin, :out=>$stdout)
end
class Pass2
def initialize
@pfix = ''
@ffix = ''
@body = ''
end
def flush
if @pfix != ''
$stdout.puts 'Packages installed:'
$stdout.puts @pfix.split("\n").sort.join("\n")
end
if @ffix != ''
$stdout.puts 'Files affected:'
$stdout.puts @ffix.split("\n").sort.join("\n")
end
$stdout.puts @body
@pfix = ''
@ffix = ''
@body = ''
end
def run
$stdin.each_line do |line|
if line.start_with? "p*"
@pfix += line[1,line.length]
elsif line.start_with? "f*"
@ffix += line[1,line.length]
elsif line.start_with? '='
flush
$stdout.puts line
else
@body += line
end
end
flush
end
end
def pass2
Pass2.new.run
end
def pass3
exec('cat', '-s', :in=>$stdin, :out=>$stdout)
end
# just a utility function for making pipelines
def pipeline(p, i, o)
ret = []
if i == :pipe
r, w = IO.pipe
i = r
ret.push(w)
end
if o == :pipe
r, w = IO.pipe
o = w
ret.push(r)
end
pid = fork {
$stdin = i
$stdout = o
ret.each{|fd| fd.close}
p.call
}
i.close
o.close
ret.unshift(pid)
return ret
end
def main
# ./pass0 | ./pass1 | ./pass2 | ./pass3
_, p0 = pipeline(Proc.new{pass0}, $stdin, :pipe )
_, p1 = pipeline(Proc.new{pass1}, p0 , :pipe )
_, p2 = pipeline(Proc.new{pass2}, p1 , :pipe )
_ = pipeline(Proc.new{pass3}, p2 , $stdout)
Process.waitall
end
main