require "techbook" require "asciidoctor" require "asciidoctor-pdf" require "asciidoctor-epub3" require "asciidoctor-diagram" require "listen" require "fileutils" module Techbook class Builder attr_accessor :basename, :pdf, :html, :epub, :mobi, :docbook, :output, :file, :path def self.run(pdf:, html:, epub:, mobi:, docbook:, output:, watch:) b = new pdf, html, epub, mobi, docbook, output b.build if watch Signal.trap("SIGINT") do puts "Bye :)".green exit end puts "Watching changes for #{output}".green listener = Listen.to(File.join(output, "book")) { b.build } listener.start sleep end end def initialize(pdf, html, epub, mobi, docbook, output) @pdf = pdf @html = html @epub = epub @mobi = mobi @docbook = docbook @output = output @basename = File.basename @output @book = File.join @output, "#{@basename}.asc" @path = File.join @output, "build" end def build puts "Building book...".yellow prepare generate_includes build_pdf build_html build_docbook build_epub build_mobi dist clean end private def prepare FileUtils.mkdir_p File.join(@path, "img") FileUtils.mkdir_p File.join(@path, "src") Dir.glob(File.join(@output, "book", "**", "img", "*")).each do |img| FileUtils.copy(img, File.join(@path, "img", File.basename(img))) end Dir.glob(File.join(@output, "book", "**", "src", "*")).each do |src| FileUtils.copy(src, File.join(@path, "src", File.basename(src))) end end def generate_includes content = File.read @book content = content.lines.reject { |line| line =~ /(include::|^\n)/ }.join Dir.glob(File.join(@output, "book", "*.asc")).sort.each do |file| next unless file =~ /[0-9]+\-/ content << "\ninclude::#{File.basename(file)}[]\n" end File.open(@book, "w") { |file| file.write(content) } end def build_pdf puts "[" + (@pdf ? "✓".green : "✕".red) + "] PDF" return unless @pdf Asciidoctor.convert_file @book, base_options.merge(backend: "pdf") end def build_html puts "[" + (@html ? "✓".green : "✕".red) + "] HTML" return unless @html Asciidoctor.convert_file @book, base_options.merge(backend: "html") end def build_docbook puts "[" + (@docbook ? "✓".green : "✕".red) + "] DOCBOOK" return unless @docbook Asciidoctor.convert_file @book, base_options.merge(backend: "docbook") end def build_epub puts "[" + (@epub ? "✓".green : "✕".red) + "] EPUB" return unless @epub Asciidoctor.convert_file @book, base_options.merge(backend: "epub3") end def build_mobi puts "[" + (@mobi ? "✓".green : "✕".red) + "] MOBI" return unless @mobi Asciidoctor.convert_file @book, base_options.merge(ebook_format: "kf8", backend: "epub3") end def base_options { safe: Asciidoctor::SafeMode::UNSAFE, base_dir: File.join(@output, "book"), to_dir: @path } end def dist FileUtils.mkdir_p File.join(@output, "dist", "img") FileUtils.mkdir_p File.join(@output, "dist", "src") FileUtils.copy_entry File.join(@path, "img"), File.join(@output, "dist", "img") FileUtils.copy_entry File.join(@path, "src"), File.join(@output, "dist", "src") FileUtils.copy File.join(@path, "#{@basename}.pdf"), File.join(@output, "dist") if @pdf FileUtils.copy File.join(@path, "#{@basename}.xml"), File.join(@output, "dist") if @docbook FileUtils.copy File.join(@path, "#{@basename}.html"), File.join(@output, "dist") if @html FileUtils.copy File.join(@path, "#{@basename}.epub"), File.join(@output, "dist") if @epub FileUtils.copy File.join(@path, "#{@basename}.mobi"), File.join(@output, "dist") if @mobi end def clean FileUtils.rm_rf @path end end end