#!/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