Class: Docfu::Pdf
- Inherits:
-
BaseOutput
- Object
- BaseOutput
- Docfu::Pdf
- Defined in:
- lib/docfu/outputs/pdf.rb
Instance Method Summary collapse
- #create_output_dir ⇒ Object
- #generate(languages, debug) ⇒ Object
- #output_dir ⇒ Object
- #post_pandoc(string, cfg) ⇒ Object
- #pre_pandoc(string, cfg) ⇒ Object
- #replace(string, &block) ⇒ Object
- #required_commands ⇒ Object
- #tex_template ⇒ Object
- #verbatim_sanitize(string) ⇒ Object
Methods inherited from BaseOutput
#check_missing_commands, #check_valid_project, #command_exists?, #config, #contains_config_yaml?, #contains_info_yaml?, #figures, #info, #not_a_project_error, #project_home
Instance Method Details
#create_output_dir ⇒ Object
76 77 78 |
# File 'lib/docfu/outputs/pdf.rb', line 76 def create_output_dir FileUtils.mkdir_p(output_dir) end |
#generate(languages, debug) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/docfu/outputs/pdf.rb', line 7 def generate(languages, debug) create_output_dir unless File.exists? output_dir figures do languages.each do |lang| cfg = config['default'].merge(config[lang]) rescue config['default'] template = ERB.new(IO.read(tex_template), 0, '<>') puts "#{lang}:" markdown = Dir["#{project_home}/#{lang}/*/*.md"].sort.map do |file| File.read(file) end.join("\n\n") print " Parsing markdown... " latex = IO.popen('pandoc -p --no-wrap -f markdown -t latex', 'w+') do |pipe| pipe.write(pre_pandoc(markdown, cfg)) pipe.close_write post_pandoc(pipe.read, cfg) end puts "done" print " Creating main.tex for #{lang}... " dir = "#{project_home}/#{lang}" mkdir_p(dir) File.open("#{dir}/main.tex", 'w') do |file| file.write(template.result(binding)) end puts "done" abort = false puts "Running XeTeX:" cd(project_home) 3.times do |i| print " Pass #{i + 1}... " IO.popen("xelatex -output-directory=\"#{output_dir}\" \"#{dir}/main.tex\" 2>&1") do |pipe| unless debug if ~ /^!\s/ puts "failed with:\n #{$_.strip}" puts " Consider running this again with --debug." abort = true end while pipe.gets and not abort else STDERR.print while pipe.gets rescue abort = true end end break if abort puts "done" end unless abort print " Moving output to #{info['title'].split(' ').join('_')}.#{lang}.pdf... " ["aux", "log", "out", "toc"].each { |f| rm "#{output_dir}/main.#{f}" } mv("#{project_home}/main.pdf", "#{output_dir}/#{info['title'].split(' ').join('_')}.#{lang}.pdf") puts "done" end File.delete("#{dir}/main.tex") end end end |
#output_dir ⇒ Object
72 73 74 |
# File 'lib/docfu/outputs/pdf.rb', line 72 def output_dir "#{project_home}/pdf" end |
#post_pandoc(string, cfg) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 |
# File 'lib/docfu/outputs/pdf.rb', line 129 def post_pandoc(string, cfg) replace(string) do space = /\s/ # Reformat for the book documentclass as opposed to article s('\section', '\chap') s('\sub', '\\') s(/SUBSUBSECTION: (.*)/, '\subsubsection{\1}') # Enable proper cross-reference s(/#{cfg['fig'].gsub(space, '\s')}\s*(\d+)\-\-(\d+)/, '\imgref{\1.\2}') s(/#{cfg['tab'].gsub(space, '\s')}\s*(\d+)\-\-(\d+)/, '\tabref{\1.\2}') s(/#{cfg['prechap'].gsub(space, '\s')}\s*(\d+)(\s*)#{cfg['postchap'].gsub(space, '\s')}/, '\chapref{\1}\2') # Miscellaneous fixes s(/FIG: (.*)/, '\img{\1}') s('\begin{enumerate}[1.]', '\begin{enumerate}') s(/(\w)--(\w)/, '\1-\2') s(/``(.*?)''/, "#{cfg['dql']}\\1#{cfg['dqr']}") # Typeset the maths in the book with TeX s('\verb!p = (n(n-1)/2) * (1/2^160))!', '$p = \frac{n(n-1)}{2} \times \frac{1}{2^{160}}$)') s('2\^{}80', '$2^{80}$') s(/\sx\s10\\\^\{\}(\d+)/, '\e{\1}') # Convert inline-verbatims into \texttt (which is able to wrap) s(/\\verb(\W)(.*?)\1/ ,'\\texttt{\2}') # s(/\\verb(\W)(.*?)\1/) do # "{\\texttt{#{verbatim_sanitize($2)}}}" # end # Style Tables s(/ctable\[pos = H, center, botcap\]\{..\}/ , 'ctable[pos = ht!, caption = ~ ,width = 130mm, center, botcap]{lX}') # Shaded verbatim block s(/(\\begin\{verbatim\}.*?\\end\{verbatim\})/m, '\begin{shaded}\1\end{shaded}') # Ensure monospaced stuff is in a smaller font # s(/(\\verb(\W).*?\2)/, '{\footnotesize\1}') # s(/(\\begin\{verbatim\}.*?\\end\{verbatim\})/m, '{\footnotesize\1}') end end |
#pre_pandoc(string, cfg) ⇒ Object
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/docfu/outputs/pdf.rb', line 98 def pre_pandoc(string, cfg) replace(string) do # Pandoc discards #### subsubsections #### - this hack recovers them s(/\#\#\#\#\# (.*?) \#\#\#\#\#/, 'PARAGRAPH: \1') s(/\#\#\#\# (.*?) \#\#\#\#/, 'SUBSUBSECTION: \1') # Turns URLs into clickable links s(/\`(http:\/\/[A-Za-z0-9\/\%\&\=\-\_\\\.\(\)\#]+)\`/, '<\1>') s(/(\n\n)\t(http:\/\/[A-Za-z0-9\/\%\&\=\-\_\\\.\(\)\#]+)\n([^\t]|\t\n)/, '\1<\2>\1') # Match table in markdown and change them to pandoc's markdown tables s(/(\n(\n\t([^\t\n]+)\t([^\t\n]+))+\n\n)/) do first_col=20 t = $1.gsub(/(\n?)\n\t([^\t\n]+)\t([^\t\n]+)/) do if $1=="\n" # This is the header, need to add the dash line $1 << "\n " << $2 << " "*(first_col-$2.length) << $3 << "\n " << "-"*18 << " " << "-"*$3.length else # Table row : format the first column as typewriter and align $1 << "\n `" << $2 << "`" + " "*(first_col-$2.length-2) << $3 end end t << "\n" end # Process figures s(/Insert\s18333fig\d+\.png\s*\n.*?\d{1,2}-\d{1,2}\. (.*)/, 'FIG: \1') end end |
#replace(string, &block) ⇒ Object
84 85 86 87 88 89 90 |
# File 'lib/docfu/outputs/pdf.rb', line 84 def replace(string, &block) string.instance_eval do alias :s :gsub! instance_eval(&block) end string end |
#required_commands ⇒ Object
68 69 70 |
# File 'lib/docfu/outputs/pdf.rb', line 68 def required_commands ['pandoc', 'xelatex'] end |
#tex_template ⇒ Object
80 81 82 |
# File 'lib/docfu/outputs/pdf.rb', line 80 def tex_template "#{Docfu::Skeleton.templates_location}/book.tex" end |
#verbatim_sanitize(string) ⇒ Object
92 93 94 95 96 |
# File 'lib/docfu/outputs/pdf.rb', line 92 def verbatim_sanitize(string) string.gsub('\\', '{\textbackslash}'). gsub('~', '{\textasciitilde}'). gsub(/([\$\#\_\^\%])/, '\\\\' + '\1{}') end |