Skip to content

Instantly share code, notes, and snippets.

@PrimaryFeather
Created June 2, 2017 08:09
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save PrimaryFeather/f8ca38e21600e4d053ada6510022fef9 to your computer and use it in GitHub Desktop.
Starling Handbook Rakefile
require 'fileutils'
REQUIREMENTS = "-r asciidoctor-diagram"
MANUAL_INDEX = "src/index-manual.adoc"
PREVIEW_INDEX = "src/index-preview.adoc"
HANDBOOK_INDEX = "src/index-handbook.adoc"
OUT_FOLDER = "out"
Encoding.default_external = Encoding::UTF_8
Encoding.default_internal = Encoding::UTF_8
def random_string(length=8)
rand(36**length).to_s(36)
end
def fix_epub_links(folder)
section_chapters = {}
files = Dir[folder + "/**/*.adoc"]
# Find all available sections and remember the chapters they are in
files.each do |file|
regex = /^={1,3}.*?(\w+.*)$/
chapter_id = File.dirname(file).split(File::SEPARATOR).pop.gsub('-', '_')
File.read(file).scan regex do |match|
section_name = match[0].strip
section_chapters[section_name] = chapter_id
end
end
# Now find all <<cross references>> and extend them to the `link:chapter.xhtml#section[label]`
# syntax. That will make it possible to link between chapters. W00t!
files.each do |file|
regex = /<<(.+)>>/
contents = File.read(file).gsub regex do |match|
link_parts = $1.split(',').map do |x| x.strip end
link_text = link_parts[1] || link_parts[0]
section_name = link_parts[0]
chapter_id = section_chapters[section_name]
section_id = section_name.downcase.gsub(/\W+/, '_').chomp('_')
if (chapter_id)
if (chapter_id == section_id)
"link:++_#{chapter_id}.xhtml++[#{link_text}]"
else
"link:++_#{chapter_id}.xhtml#_#{section_id}++[#{link_text}]"
end
else
match # leave this one unchanged (could be chapter-internal reference)
end
end
File.open(file, "w") do |f| f.puts contents end
end
end
def build_ebook(format='epub3')
if (format == 'kf8')
kindlegen_path = `which kindlegen`.strip
raise 'Required `kindlegen` is not installed or not part of the PATH' if kindlegen_path.empty?
end
# Epub does not allow images outside the source directory,
# so we do all the work in a temporary folder.
build_folder = OUT_FOLDER + "/build-" + random_string
begin
FileUtils.mkdir_p build_folder
FileUtils.cp_r "src/.", build_folder
FileUtils.cp_r "img/", build_folder + "/images"
fix_epub_links build_folder
sh "KINDLEGEN=#{kindlegen_path} " +
"asciidoctor-epub3 #{REQUIREMENTS} -D #{OUT_FOLDER} -a ebook-format=#{format} " +
"-a imagesdir=images -a epub3-stylesdir=../../styles/epub -a ebook-validate " +
"-o handbook.epub #{build_folder}/index-handbook.adoc"
FileUtils.rm_f "#{OUT_FOLDER}/handbook-kf8.epub"
ensure
FileUtils.rm_rf build_folder
end
end
task :default => 'handbook:build_html'
namespace :handbook do
desc "Create an HTML version of the book"
task :build_html do
sh "asciidoctor -b html5 #{REQUIREMENTS} -D #{OUT_FOLDER} -o handbook.html #{HANDBOOK_INDEX} "
end
desc "Create a PDF version of the book"
task :build_pdf do
sh "asciidoctor-pdf #{REQUIREMENTS} -D #{OUT_FOLDER} -o handbook.pdf #{HANDBOOK_INDEX}"
end
desc "Create a print-ready PDF version for Blurb"
task :build_pdf_blurb do
stylesdir = File.absolute_path("styles/pdf")
sh "asciidoctor-pdf #{REQUIREMENTS} -D #{OUT_FOLDER} -o handbook-blurb.pdf " +
"-a pdf-stylesdir=#{stylesdir} -a pdf-style=blurb -a media=prepress #{HANDBOOK_INDEX}"
end
desc "Create a PDF preview of the handbook"
task :build_pdf_preview do
sh "asciidoctor-pdf #{REQUIREMENTS} -D #{OUT_FOLDER} -o handbook-preview.pdf #{PREVIEW_INDEX}"
end
desc "Create an EPUB version of the book"
task :build_epub do
build_ebook
end
desc "Create a KF8/MOBI version of the book"
task :build_mobi do
build_ebook 'kf8'
end
desc "Create a zip-package containing PDF, EPUB and MOBI files"
task :package => [:build_pdf, :build_epub, :build_mobi] do
FileUtils.cd OUT_FOLDER do
`zip handbook.zip handbook.pdf handbook.epub handbook.mobi`
end
end
end
namespace :manual do
desc "Create the HTML manual"
task :build_html do
sh "touch #{MANUAL_INDEX}" # fixes 'updated_at'
sh "asciidoctor -b html5 #{REQUIREMENTS} -D #{OUT_FOLDER} -o manual.html #{MANUAL_INDEX}"
end
desc "Create a PDF version of the manual"
task :build_pdf do
sh "asciidoctor-pdf #{REQUIREMENTS} -D #{OUT_FOLDER} -o manual.pdf #{MANUAL_INDEX}"
end
end
desc "Remove all output files"
task :clean do
Dir["#{OUT_FOLDER}/*"].each do |f|
FileUtils.remove_entry(f)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment