add summary script so i can see progress and authorship
[progit-mk.git] / latex / makepdf
blobff9b9f512cb9db9e82df289c6d70fa95d2033f82
1 #!/usr/bin/env ruby
2 # -*- coding: utf-8 -*-
3 require 'fileutils'
4 require 'open3'
5 require 'erb'
6 require 'yaml'
8 include FileUtils, Open3
9 alias :pipe :popen3
11 $here = File.expand_path(File.dirname(__FILE__))
12 $root = File.join($here, '..')
13 $outDir = File.join($root, 'pdf')
15 def figures(&block)
16 begin
17 Dir["#$root/figures/18333*.png"].each do |file|
18 cp(file, file.sub(/18333fig0(\d)0?(\d+)\-tn/, '\1.\2'))
19 end
20 block.call
21 ensure
22 Dir["#$root/figures/18333*.png"].each do |file|
23 rm(file.gsub(/18333fig0(\d)0?(\d+)\-tn/, '\1.\2'))
24 end
25 end
26 end
28 def usage
29 puts <<USAGE
30 Usage:
31 makepdf [OPTION...] LANGUAGE [LANGUAGE 2...]
33 Options:
34 -d, --debug prints TeX and other output
35 USAGE
36 exit
37 end
39 def command_exists?(command)
40 ENV['PATH'].split(/:/).map do |path|
41 File.executable?("#{path}/#{command}")
42 end.inject{|a, b| a || b}
43 end
45 def replace(string, &block)
46 string.instance_eval do
47 alias :s :gsub!
48 instance_eval(&block)
49 end
50 string
51 end
53 def verbatim_sanitize(string)
54 string.gsub('\\', '{\textbackslash}').
55 gsub('~', '{\textasciitilde}').
56 gsub(/([\$\#\_\^\%])/, '\\\\' + '\1{}')
57 end
59 def pre_pandoc(string, config)
60 replace(string) do
61 # Pandoc discards #### subsubsections #### - this hack recovers them
62 s /\#\#\#\# (.*?) \#\#\#\#/, 'SUBSUBSECTION: \1'
64 # Turns URLs into clickable links
65 s /\`(http:\/\/[A-Za-z0-9\/\%\&\=\-\_\\\.]+)\`/, '<\1>'
66 s /(\n\n)\t(http:\/\/[A-Za-z0-9\/\%\&\=\-\_\\\.]+)\n([^\t]|\t\n)/, '\1<\2>\1'
68 # Process figures
69 s /Insert\s18333fig\d+\.png\s*\n.*?\d{1,2}-\d{1,2}\. (.*)/, 'FIG: \1'
70 end
71 end
73 def post_pandoc(string, config)
74 replace(string) do
75 space = /\s/
77 # Reformat for the book documentclass as opposed to article
78 s '\section', '\chap'
79 s '\sub', '\\'
80 s /SUBSUBSECTION: (.*)/, '\subsubsection{\1}'
82 # Enable proper cross-reference
83 s /#{config['fig'].gsub(space, '\s')}\s*(\d+)\-\-(\d+)/, '\imgref{\1.\2}'
84 s /#{config['tab'].gsub(space, '\s')}\s*(\d+)\-\-(\d+)/, '\tabref{\1.\2}'
85 s /#{config['prechap'].gsub(space, '\s')}\s*(\d+)(\s*)#{config['postchap'].gsub(space, '\s')}/, '\chapref{\1}\2'
87 # Miscellaneous fixes
88 s /FIG: (.*)/, '\img{\1}'
89 s '\begin{enumerate}[1.]', '\begin{enumerate}'
90 s /(\w)--(\w)/, '\1-\2'
91 s /``(.*?)''/, "#{config['dql']}\\1#{config['dqr']}"
93 # Typeset the maths in the book with TeX
94 s '\verb!p = (n(n-1)/2) * (1/2^160))!', '$p = \frac{n(n-1)}{2} \times \frac{1}{2^{160}}$)'
95 s '2\^{}80', '$2^{80}$'
96 s /\sx\s10\\\^\{\}(\d+)/, '\e{\1}'
98 # Convert inline-verbatims into \texttt (which is able to wrap)
99 s /\\verb(\W)(.*?)\1/ do
100 "{\\texttt{#{verbatim_sanitize($2)}}}"
103 # Ensure monospaced stuff is in a smaller font
104 s /(\\verb(\W).*?\2)/, '{\footnotesize\1}'
105 s /(\\begin\{verbatim\}.*?\\end\{verbatim\})/m, '{\footnotesize\1}'
107 # Shaded verbatim block
108 s /(\\begin\{verbatim\}.*?\\end\{verbatim\})/m, '\begin{shaded}\1\end{shaded}'
112 ARGV.delete_if{|arg| $DEBUG = true if arg == '-d' or arg == '--debug'}
113 languages = ARGV.select{|arg| File.directory?("#$root/#{arg}")}
114 usage if languages.empty?
116 $config = YAML.load_file("#$here/config.yml")
117 template = ERB.new(File.read("#$here/template.tex"))
119 missing = ['pandoc', 'xelatex'].reject{|command| command_exists?(command)}
120 unless missing.empty?
121 puts "Missing dependencies: #{missing.join(', ')}."
122 puts "Install these and try again."
123 exit
126 figures do
127 languages.each do |lang|
128 config = $config['default'].merge($config[lang]) rescue $config['default']
130 puts "#{lang}:"
131 markdown = Dir["#$root/#{lang}/*/*.markdown"].sort.map do |file|
132 File.read(file)
133 end.join("\n\n")
135 print "\tParsing markdown... "
136 latex = pipe('pandoc -p --no-wrap -f markdown -t latex') do |stdin, stdout|
137 stdin.write(pre_pandoc(markdown, config))
138 stdin.close
139 post_pandoc(stdout.read, config)
141 puts "done"
143 print "\tCreating main.tex for #{lang}... "
144 dir = "#$here/#{lang}"
145 mkdir_p(dir)
146 File.open("#{dir}/main.tex", 'w') do |file|
147 file.write(template.result(binding))
149 puts "done"
151 abort = false
153 puts "\tRunning XeTeX:"
154 cd($root)
155 3.times do |i|
156 print "\t\tPass #{i + 1}... "
157 pipe("xelatex -output-directory='#{dir}' '#{dir}/main.tex' 2>&1") do |_, stdout|
158 unless $DEBUG
159 if ~ /^!\s/
160 puts "failed with:\n\t\t\t#{$_.strip}"
161 puts "\tConsider running this again with --debug."
162 abort = true
163 end while stdout.gets and not abort
164 else
165 STDERR.print while stdout.gets rescue abort = true
168 break if abort
169 puts "done"
172 unless abort
173 print "\tMoving output to progit.#{lang}.pdf... "
174 mv("main.pdf", "#$root/progit.#{lang}.pdf")
175 puts "done"