# coding: utf-8 # Rakefile for Markdown documents. DIRMAP_MD = '.dirmap.md' HTML2PDF = "wkhtmltopdf -B 1cm -L 1.5cm -R 1.5cm -T 1.5cm -s A4 --encoding UTF-8 " TEX2IMAGE = "tex2image" #IMAGEMAGICK = "convert -alpha deactivate -density 144x144" IMAGEMAGICK = "convert -alpha deactivate -density 72x72" INKSCAPE = "inkscape" PDFTK = "pdftk" ALL_PDF = "all.pdf" require "pp" require "fileutils" require "pathname" require "tempfile" require "rake/clean" ## .dirmap.md # dirmap コマンドは必ず実行なので task タスク。 # これを file にすると存在するときに実行されない。 # 生成物の .dirmap.md から task タスクへの依存を設定すると、 # .dirmap.md に依存する file タスクに「必ず実行」が伝播して必ず実行になってしまう。 # DIRMAP_MD というファイルに対する file タスクへの依存として扱うことで、 # .dirmap.md に依存する file タスクに「必ず実行」が伝播するのを防いでいる。 desc "update .dirmap.md if directory changed." file DIRMAP_MD => :dirmap_command task :dirmap_command do #sh "dirmap --kakasi --index-link" sh "dirmap --kakasi --noindex=ignore" end def generate_html(html_file) md_file = html_file.ext("md") md_path = Pathname.new( md_file) dirpath = md_path.dirname src = FileList[md_file, DIRMAP_MD] #pp html_file #pp DIRMAP_MD, md_file #exit file html_file => [DIRMAP_MD, md_file] do puts "Update: #{md_file} -> #{html_file}" side_lines = `pandoc #{DIRMAP_MD}`.split("\n") side_lines.unshift "" line = `pandoc -s -N --toc -c madowu.css --mathjax --filter pandoc-crossref #{md_file}` lines = line.split("\n") end_body = lines.index('') lines.insert(end_body, side_lines) lines.flatten # -N = --number-sections # -s = --standalone File.open(html_file, "w") {|io| io.puts lines} end end ## *.html md_files = FileList["*.md"] html_files = md_files.ext("html") html_tasks = [] html_files.each do |html_file| generate_html( html_file ) html_tasks << html_file end CLEAN.include(DIRMAP_MD, html_files) desc "make *.html from *.md" task :md2html => [DIRMAP_MD, * html_tasks] # recursive だと、サブディレクトリの Rakefile も # recursive ターゲットを持っているという前提が必要。 desc "execute 'rake' in all subdirs with Rakefile" rakefiles = FileList["**/Rakefile"] dirs = rakefiles.map{|path| Pathname.new(path).dirname.to_s} #dirs.delete_if {|i| i == '.' } dirs.map!{|path| File.absolute_path(path)} task :subdir do dirs.each do |dir| puts "■" + dir Dir.chdir dir system "rake" end end DST_FILES = {} ##rule_src2dst('fig' , 'rb' , 'png' ) { |src, dst| sh "ruby #{src}" } desc "convert from rb to png" png_files = [] FileList["fig*.rb"].each do |src_file| dst_file = src_file.ext('png') basename = File.basename(src_file, ".rb") src_files = FileList["#{basename}.*"] - ["#{basename}.png"] subfigs = (FileList["#{basename}?.rb"] - ["#{basename}.png"]).map{|v| File.basename(v, File.extname(v)) }.sort.uniq.map{|v| v + '.png'} file dst_file => (src_files + subfigs )do sh "ruby #{src_file}" end png_files << dst_file end task "rb2png".to_sym => png_files DST_FILES['png'] ||= [] DST_FILES['png'] += png_files CLEAN.include(FileList["fig*.png"]) ############################################################ ## extension rules ## src_exts: array of the extentions that the destination file depends on. ## src_exts[0] is used as a 'src' of rake target. ## 'prefix' indicates head string of filenames. ## 出力以外の全ての拡張子に依存していると見做す。 def rule_src2dst(prefix , src_ext, dst_ext) desc "convert from #{src_ext} to #{dst_ext}" dst_files = [] FileList["#{prefix.to_s}*.#{src_ext}"].each do |src_file| dst_file = src_file.ext(dst_ext) basename = File.basename(src_file, ".#{src_ext}") src_files = FileList["#{basename}*"] - ["#{basename}.#{dst_ext}"] src_files.select!{|path| FileTest.exist? path } file dst_file => src_files do yield(src_file, dst_file) end dst_files << dst_file end task "#{src_ext}2#{dst_ext}".to_sym => dst_files DST_FILES[dst_ext] ||= [] DST_FILES[dst_ext] += dst_files CLEAN.include(FileList["#{prefix.to_s}*.#{dst_ext}"]) end rule_src2dst('fig', 'svg' , 'png' ) { |src, dst| #svg は直接 png にすると、透明背景で余白ありになる。 eps_file = Tempfile.new.path sh "#{INKSCAPE} -T -z -E #{eps_file} #{src}" sh "#{IMAGEMAGICK} #{src} #{dst}" FileUtils.rm eps_file } rule_src2dst('fig' , 'eps' , 'png' ) { |src, dst| sh "#{IMAGEMAGICK} #{src} #{dst}"} #rule_src2dst('anim', 'zsh' , 'gif' ) { |src, dst| sh "zsh #{src}"} #rule_src2dst('fig' , 'zsh' , 'png' ) { |src, dst| sh "zsh #{src}"} #rule_src2dst('fig' , 'sh' , 'png' ) { |src, dst| sh "sh #{src}"} #rule_src2dst('fig', 'dot' , 'png') {|src, dst| sh "dot -Tpng #{src} -o #{dst}"} #rule_src2dst('fig', 'circo', 'png') {|src, dst| sh "circo -Tpng #{src} -o #{dst}"} #rule_src2dst('fig', 'fdp' , 'png') {|src, dst| sh "fdp -Tpng #{src} -o #{dst}"} #rule_src2dst('fig', 'neato', 'png') {|src, dst| sh "neato -Tpng #{src} -o #{dst}"} #rule_src2dst('fig', 'sfdp' , 'png') {|src, dst| sh "sfdp -Tpng #{src} -o #{dst}"} #rule_src2dst('fig', 'twopi', 'png') {|src, dst| sh "twopi -Tpng #{src} -o #{dst}"} #rule_src2dst('fig', 'tex' , 'png') {|src, dst| sh "#{TEX2IMAGE} #{src}" } #rule_src2dst('fig', 'rb' , 'eps') {|src, dst| sh "ruby #{src} --eps"} #rule_src2dst(nil , 'html' , 'pdf' ) { |src, dst| sh "#{HTML2PDF} #{src} #{dst}"} rule_src2dst(nil , 'md' , 'pdf' ) { |src, dst| generate_html(src) sh "#{HTML2PDF} #{src.ext("html")} #{dst}" } ## gnuplot は本来 eps を作るため、という位置付けにすべきだが、 ## この Rakefile では HTML 作りが主目的なので png を生成するようにする。 ##rule_src2dst('plt' , 'eps', 'fig' ) { |src, dst| sh "gnuplot ./#{src}"} #rule_src2dst('fig', 'plt' , 'png') { |src, dst| # pltfile = src # epsfile = src.ext('eps') # pngfile = src.ext('png') # sh "gnuplot ./#{pltfile}" # sh "#{IMAGEMAGICK} #{epsfile} #{pngfile}" # #CLEAN.include(epsfile) # FileUtils.rm epsfile #} #### pov ## pov ファイルは基本的に pov ではなく zsh や rb で作成するようにする。 ## 理由は、コマンドラインオプションじゃないと指定できないものがあるため。(解像度など) ## gif を生成したり png を生成したり、拡張だけからは不明瞭なため。 ## E.g., 幅、高さ、アニメーションの Clock など。 #rule_src2dst(['pov', 'inc'] , 'png', 'fig') { |srcs, dst| sh "povray -D #{srcs[0]}"} #rule_src2dst(['pov'] , 'png', 'fig') { |srcs, dst| sh "povray -D #{srcs[0]}"} #rule_src2dst(%w(zsh ini pov inc), 'gif', 'anim') { |srcs, dst| sh "zsh #{srcs[0]}"} ############################################################ desc "generate #{ALL_PDF} including #{} files." pdf_files = html_files.ext("pdf") pdf_files.delete "index.pdf" pdf_files.unshift "index.pdf" pdf_files.delete ALL_PDF figures = FileList["fig*"] task :pdf => ALL_PDF #file ALL_PDF => [:default, * pdf_files, * figures] do file ALL_PDF => [*png_files, * html_files, * pdf_files, * figures] do sh "#{PDFTK} #{pdf_files} output #{ALL_PDF}" end ############################################################ #task :all => [:md2html, :subdir] #task :default => [:md2html, :tex2png, :svg2png, # :dot2png, :circo2png, :fdp2png, :neato2png, :sfdp2png, :twopi2png, # :zsh2png, :zsh2gif, :plt2png, :rb2png] task :default => [:md2html, :svg2png, :eps2png, :rb2png] #task :default => [:md2html, :svg2png, :rb2png] # 基本方針として、html を生成するのをデフォルトとする。 # :eps2png は、rb2eps と rb2png の関係に干渉する # :plt2eps