require 'fileutils' def epub(args = nil, body = nil) api.tty "======== Entering epub" out = api.format(api.args[0]) src = api.args[1] api.tty "======== epub: src = #{src}" @cover = api.args[2] if ::File.directory?(src) files = ::Dir["#{src}/*"].grep /\.html$/ files = files.sort # why is this necessary now? cmd = "cat #{files.join(' ')} >TEMP.html" system(cmd) else raise "Not supported yet" end cmd = "ebook-convert " cmd << "TEMP.html #{out}.epub " cmd << "--cover #@cover " if @cover system(cmd) system("links -dump TEMP.html >/tmp/links.out") str = `wc -w /tmp/links.out` nw = str.split[0] puts "Approx words: #{nw}" # ::FileUtils.rm("TEMP.html") end def hardbreaks(args = nil, body = nil) @hard = false @hard = true unless api.args.first == "off" api.optional_blank_line end def hardbreaks? @hard end def credit(args = nil, body = nil) # really just a place marker in source api.optional_blank_line end # These are duplicated. Remove safely def h1(args = nil, body = nil); api.out html.tag(:h1, api.data); return true; end def h2(args = nil, body = nil); api.out html.tag(:h2, api.data); return true; end def h3(args = nil, body = nil); api.out html.tag(:h3, api.data); return true; end def h4(args = nil, body = nil); api.out html.tag(:h4, api.data); return true; end def h5(args = nil, body = nil); api.out html.tag(:h5, api.data); return true; end def h6(args = nil, body = nil); api.out html.tag(:h6, api.data); return true; end def alpha_columns(args = nil, body = nil) n = api.args.first.to_i # FIXME: what if it's missing? words = [] api.body do |line| words << line.chomp end words.sort! api.out "" words.each_slice(n) do |w| items = w.map {|x| "#{x}" } api.out "" end api.out "
" + items.join("") + "
" api.optional_blank_line end # def comment # api.body { } # ignore body # end def _errout(*args) ::STDERR.puts *args end def _nbsp(n) " "*n end def _slug(str) s2 = str.chomp.strip.gsub(/[?:,()'"\/]/,"").gsub(/ /, "-").downcase # _errout "SLUG: #{str} => #{s2}" s2 end # FIXME duplicated? def image(args = nil, body = nil) name = api.args[0] api.out "" api.optional_blank_line end def figure(args = nil, body = nil) name = api.args[0] num = api.args[1] title = api.args[2..-1].join(" ") title = api.format(title) api.out "" api.out "
Figure #{num} #{title}
" api.optional_blank_line end def xchapterN(args = nil, body = nil) @chapter = api.args.first.to_i @sec = @sec2 = 0 title = api.data.split(" ",2)[1] @toc << "
#@chapter #{title}
" api.data = _slug(title) next_output api.out "#{@chapter}. #{title}" api.out <<-HTML

Chapter #{@chapter}

#{title}

\n HTML api.optional_blank_line end def chapter(args = nil, body = nil) @chapter += 1 @sec = @sec2 = 0 title = api.data # .split(" ",2)[1] _errout("Chapter #@chapter: #{title}") @toc << "
#@chapter #{title}
" api.data = _slug(title) next_output api.out "#{@chapter}. #{title}" api.out <<-HTML

Chapter #{@chapter}

#{title}

\n HTML api.optional_blank_line end def sec(args = nil, body = nil) @sec += 1 @sec2 = 0 @section = "#@chapter.#@sec" title = api.data.dup @toc << "#{_nbsp(3)}#@section #{title}
" api.data = _slug(api.data) next_output api.out "

#@section #{title}

\n" api.optional_blank_line rescue => err api.tty "#{err}\n#{err.backtrace.join("\n")}" ::STDERR.puts "#{err}\n#{err.backtrace.join("\n")}" exit end def subsec(args = nil, body = nil) @sec2 += 1 @subsec = "#@chapter.#@sec.#@sec2" title = api.data.dup @toc << "#{_nbsp(6)}#@subsec #{title}
" api.data = _slug(api.data) next_output api.out "

#@subsec #{title}

\n" api.optional_blank_line end def definition_table(args = nil, body = nil) title = api.data wide = "95" delim = " :: " api.out "
" lines = api.body(true) lines.map! {|line| api.format(line) } lines.each do |line| cells = line.split(delim) api.out "" cells.each.with_index do |cell, i| width = (i == 0) ? "width=15%" : "" api.out " " end api.out "" end api.out "
#{cell}


" api.optional_blank_line end def table2(args = nil, body = nil) title = api.data wide = "90" extra = api.args[2] delim = " :: " api.out "
" lines = api.body(true) lines.map! {|line| api.format(line) } lines.each do |line| cells = line.split(delim) percent = (100/cells.size.to_f).round api.out "" cells.each do |cell| api.out " " end api.out "" end api.out "
#{cell}


" api.optional_blank_line end def simple_table(args = nil, body = nil) title = api.data delim = " :: " api.out "" lines = api.body(true) maxw = nil lines.each do |line| # api.format(line) cells = line.split(delim) wide = cells.map {|x| x.length } maxw = [0] * cells.size maxw = maxw.map.with_index {|x, i| [x, wide[i]].max } end sum = maxw.inject(0, :+) maxw.map! {|x| (x/sum*100).floor } lines.each do |line| cells = line.split(delim) api.out "" cells.each.with_index do |cell, i| api.out " " end api.out "" end api.out "
" + "#{cell}
" api.optional_blank_line end def table(args = nil, body = nil) @table_num ||= 0 @table_num += 1 title = api.data delim = " :: " api.out "
" lines = api.body(true) maxw = nil lines.each do |line| api.format(line) cells = line.split(delim) wide = cells.map {|x| x.length } maxw = [0] * cells.size maxw = maxw.map.with_index {|x, i| [x, wide[i]+2].max } end sum = maxw.inject(0, :+) maxw.map! {|x| (x/sum*100).floor } lines.each do |line| cells = line.split(delim) api.out "" cells.each.with_index do |cell, i| api.out " " end api.out "" end api.out "
" + "#{cell}
" @toc << "#{_nbsp(8)}Table #@chapter.#@table_num #{title}
" # _next_output(_slug("table_#{title}")) api.out "Table #@chapter.#@table_num    #{title}

" api.optional_blank_line end def toc!(args = nil, body = nil) _debug "Closing TOC" @toc.close api.optional_blank_line rescue => err puts @parent.body @parent.body = "" _errout "Exception: #{err.inspect}" end def toc2(args = nil, body = nil) file = api.args[0] @toc.close ::File.write(file, <<-EOS)

Fake (non-hyperlinked) Table of Contents

EOS system("cat toc.tmp >>#{file}") api.optional_blank_line end def missing(args = nil, body = nil) @toc << "#{_nbsp(8)}TBD: #{api.data}
" stuff = api.data.empty? ? "" : ": #{api.data}" api.out "
[Material missing#{stuff}]
\n " api.optional_blank_line end def TBC(args = nil, body = nil) @toc << "#{_nbsp(8)}To be continued...
" api.out "
To be continued...
" api.optional_blank_line end def note(args = nil, body = nil) api.out "
Note: " api.out api.data api.out "
\n " api.optional_blank_line end def quote(args = nil, body = nil) api.out "
" api.body {|line| api.out line } api.out "
" api.optional_blank_line rescue => err ::STDERR.puts "#{err}\n#{err.backtrace}" exit end def init_booktool @_file_num = 0 @toc_file = "toc.tmp" @toc = ::File.new(@toc_file, "w") @chapter = -1 end ########### def outdir(args = nil, body = nil) @_outdir = api.args.first # @output = STDOUT @output = nil api.optional_blank_line end def outdir!(args = nil, body = nil) # FIXME ? @_outdir = api.args.first raise "No output directory specified" if @_outdir.nil? raise "No output directory specified" if @_outdir.empty? system("rm -f #@_outdir/*.html") api.optional_blank_line end def _append(name) @_outdir ||= "." @output.close unless @output == STDOUT @output = File.open(@_outdir + "/" + name, "a") @output.puts "\n\n" end def append(args = nil, body = nil) file = api.args[0] _append(file) end def close_output(args = nil, body = nil) return if @output == STDOUT @_outdir ||= "." @output.puts "\n\n" @output.puts @parent.body @output.close @parent.body = "" # See bin/livetext @output = STDOUT end def _prep_next_output(args) *title = args # _next_output(tag, num) title = title.join(" ") slug = _slug(title) @_file_num += 1 fname = "#{'%03d' % @_file_num}-#{slug}.html" fname end def next_output(args = nil, body = nil) args ||= api.args fname = _prep_next_output(args) @_outdir ||= "." unless @output.nil? @output.puts "\n\n" @output.puts @parent.body @parent.body = "" @output.close unless @output == STDOUT end fname = @_outdir + "/" + fname @output = File.open(fname, "w") api.optional_blank_line end def output(args = nil, body = nil) name = api.args.first _debug "Redirecting output to: #{name}" # _output(name) @_outdir ||= "." # FIXME @output.puts "\n\n" @output.puts @parent.body @parent.body = "" @output.close unless @output == STDOUT fname = @_outdir + "/" + name #; STDERR.puts "--- _output: fname = #{fname.inspect}" @output = File.open(fname, "w") #; STDERR.puts "---- @out = #{@output.inspect}" end def columns(args = nil, body = nil) api.out "

\n" api.body.to_a.each do |line| if line.start_with?("##col") api.out "
" elsif line.start_with?("##row") api.out "
" else api.out line end end api.out "
\n
" end def quote(args = nil, body = nil) api.out "
" lines = api.body.to_a # STDERR.puts "-----------------------------------------------------" # STDERR.puts lines.inspect lines.each {|line| api.out line } api.out "
" end