summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharlotte Koch <charlotte@magentastripe.com>2024-06-09 15:34:28 -0700
committerCharlotte Koch <charlotte@magentastripe.com>2024-06-09 15:34:28 -0700
commit5ee36725a963de52b219069d7ae592110a994ac8 (patch)
tree6f96a2e1775ce7cb2266f0dfcfd8a01993faacf3
parent4ea0ee9a6d5e77ae9220625cffcdd7c3d6ea825f (diff)
Add willora(1) which can generate a project directory for you
-rwxr-xr-xbin/willora149
-rw-r--r--templates/CHAP01.adoc.erb10
-rw-r--r--templates/Makefile.erb33
-rw-r--r--templates/frontmatter.adoc.erb44
-rw-r--r--templates/part01.adoc.erb1
5 files changed, 237 insertions, 0 deletions
diff --git a/bin/willora b/bin/willora
new file mode 100755
index 0000000..9b3415d
--- /dev/null
+++ b/bin/willora
@@ -0,0 +1,149 @@
+#!/usr/bin/env ruby
+#
+# WilloraPDF command line tool
+# Charlotte Koch <charlotte@magentastripe.com>
+#
+
+require 'erb'
+require 'fileutils'
+
+########## ########## ##########
+
+class Willora
+ VERSION = "0.0.0a"
+ DEFAULT_TITLE = "My Cool Book"
+ DEFAULT_AUTHOR = "Allen Smithee"
+
+ attr_reader :errormsg
+
+ def initialize(**opts)
+ @opts = opts
+ @errormsg = nil
+ end
+
+ def main!
+ puts "WilloraPDF v#{VERSION}"
+
+ rv = 0
+
+ case @opts[:command]
+ when :new
+ rv = self.new_project
+ else
+ @errormsg = "unknown command: #{@opts[:command].inspect}"
+ rv = 1
+ end
+
+ return rv
+ end
+
+ def new_project
+ # Make sure the WilloraPDF base files seem OK.
+ _willorabase = File.join(__dir__, "..")
+ _templatedir = File.join(_willorabase, "templates")
+
+ #epubassetsdir = File.join(_willorabase, "epub-assets")
+ fontsdir = File.join(_willorabase, "fonts")
+ libdir = File.join(_willorabase, "lib")
+ mkdir = File.join(_willorabase, "mk")
+ scriptdir = File.join(_willorabase, "script")
+ themedir = File.join(_willorabase, "themes")
+
+ alldirs = [fontsdir, libdir, mkdir, themedir, scriptdir]
+
+ alldirs.each do |dir|
+ if not File.directory?(dir)
+ @errormsg = "cannot find required directory, WilloraPDF installation broken? (#{dir})"
+ return 1
+ end
+ end
+
+ # Fill in some gaps before we continue.
+ if !@opts[:nickname]
+ @errormsg = "New project requires a nickname"
+ return 1
+ end
+
+ if @opts[:nickname].split(/\s+/).length > 1
+ @errormsg = "Nickname cannot have any spaces"
+ return 1
+ end
+
+ @opts[:title] = DEFAULT_TITLE if !@opts[:title]
+ @opts[:author] = DEFAULT_AUTHOR if !@opts[:author]
+
+ # Create the new project directory and copy the files over.
+ realdestbase = File.join(@opts[:destination], @opts[:nickname])
+ FileUtils.mkdir_p(realdestbase, :verbose => true)
+
+ alldirs.each do |dir|
+ basename = File.basename(dir)
+ realdest = File.join(realdestbase, basename)
+ puts "#{basename} => #{realdest}"
+ FileUtils.copy_entry(dir, realdest)
+ end
+
+ # Fill it up with some new templatized files.
+ templates = {
+ "Makefile.erb" => "",
+
+ "CHAP01.adoc.erb" => "adoc",
+ "frontmatter.adoc.erb" => "adoc",
+ "part01.adoc.erb" => "adoc",
+ }
+
+ templates.each do |template, destname|
+ destdir = File.join(realdestbase, destname)
+ if not File.directory?(destdir)
+ FileUtils.mkdir_p(destdir, :verbose => true)
+ end
+ templatefile = File.join(_templatedir, template)
+ result = ERB.new(File.read(templatefile)).result(binding)
+ newfile = File.join(destdir, File.basename(template, ".erb"))
+ puts "GENERATE #{newfile}"
+ File.open(newfile, "w") do |fp|
+ fp.puts(result)
+ end
+ end
+
+ # Leftovers.
+ converter_class_orig = File.join(_willorabase, "lib", "willora_pdf_converter.rb")
+ converter_class_new = File.join(realdestbase, "lib", "this_pdf_converter.rb")
+ puts "#{converter_class_orig} => #{converter_class_new}"
+ FileUtils.copy_entry(converter_class_orig, converter_class_new)
+
+ puts "New project #{@opts[:nickname].inspect} is ready: #{realdestbase}"
+ return 0
+ end
+end
+
+########## ########## ##########
+
+if $0 == __FILE__
+ require 'optparse'
+
+ opts = {}
+
+ # Parse command-line parameters.
+ parser = OptionParser.new do |op|
+ op.on("-h", "--help") { opts[:command] = :help }
+ op.on("-n", "--new") { opts[:command] = :new }
+ op.on("--title TITLE") { |title| opts[:title] = title }
+ op.on("--nickname NAME") { |nick| opts[:nickname] = nick }
+ op.on("--author AUTHOR") { |author| opts[:author] = author }
+ op.on("--publisher PUBLISHER") { |publisher| opts[:publisher] = publisher }
+ op.on("--destination DIR") { |dir| opts[:destination] = File.expand_path(dir) }
+ end
+ parser.parse!(ARGV)
+
+ if opts[:command] == :help
+ puts(parser.to_s)
+ exit 0
+ end
+
+ # Do it.
+ w = Willora.new(**opts)
+ rv = w.main!
+ $stderr.puts("FATAL: #{w.errormsg}") if w.errormsg
+ exit rv
+end
diff --git a/templates/CHAP01.adoc.erb b/templates/CHAP01.adoc.erb
new file mode 100644
index 0000000..1123e41
--- /dev/null
+++ b/templates/CHAP01.adoc.erb
@@ -0,0 +1,10 @@
+// =====================================================================
+
+== Chapter 1
+
+Welcome to WilloraPDF! This is the beginning of a new chapter. You can
+actually make more than just PDFs with Willora, by the way.
+
+"Isn't it __just__ wonderful?`" my partner says in an exaggerated manner.
+
+"`Sure is, darling,`" I reassure them. "`Sure thing.`"
diff --git a/templates/Makefile.erb b/templates/Makefile.erb
new file mode 100644
index 0000000..bff4d4c
--- /dev/null
+++ b/templates/Makefile.erb
@@ -0,0 +1,33 @@
+NAME= <%= @opts[:nickname] %>
+PUBLISHER= <%= @opts[:publisher] %>
+THEME= this
+
+BUNDLE?= bundle32
+RUBY?= ruby32
+
+PAPERBACK_ISBN= 111-1-11111111-1-1
+HARDCOVER_ISBN= 222-2-22222222-2-2
+EPUB_ISBN= 333-3-33333333-3-3
+
+PAPERBACK_CATNO= MSM-00004
+HARDCOVER_CATNO= MSM-00005
+EPUB_CATNO= MSM-00006
+
+EPUB_REVDATE= 1970-01-01
+EPUB_SERIESNAME= <% @opts[:seriesname] %>
+
+COLOPHON_TEMPLATE= adoc/colophon-template.adoc.erb
+PAPERBACK_COLOPHON_FILE= colophon-paperback.adoc
+HARDCOVER_COLOPHON_FILE= colophon-hardcover.adoc
+EPUB_COLOPHON_FILE= colophon-epub.adoc
+
+########## ########## ##########
+
+CHAPTERS+= adoc/part01.adoc
+CHAPTERS+= adoc/CHAP01.adoc
+CHAPTERS+= adoc/backmatter.adoc
+
+########## ########## ##########
+
+.-include "mk/local.mk"
+.include "mk/willora.mk"
diff --git a/templates/frontmatter.adoc.erb b/templates/frontmatter.adoc.erb
new file mode 100644
index 0000000..7dd7dc4
--- /dev/null
+++ b/templates/frontmatter.adoc.erb
@@ -0,0 +1,44 @@
+= <%= @opts[:title] %>
+<%= @opts[:author] %>
+:nofooter:
+:reproducible:
+:pagenums:
+
+<%# =================================================================== %>
+
+[colophon%notitle%nonfacing]
+= Colophon
+
+(C) <%= Time.now.year.to_s %> <%= @opts[:publisher] %>
+
+All rights reserved.
+
+This is a work of fiction. Names, characters, places and incidents are
+the product of the author's imagination or are used fictitiously. Any
+resemblance to actual events, locales or persons, living or dead, is
+purely coincidental.
+
+Published by <%= @opts[:publisher] %>
+
+Printed by XXX THE PRINTER.
+
+Cover design by XXX THE ARTIST.
+
+Typeset in 12-point EB Garamond.
+
+First Edition
+
+// ISBN-13 <%# var["ISBN"] %>
+
+// Publisher Catalog Number <%# var["CATNO"] %>
+
+Learn more at the author's website: [.underline]#\https://charlotte-koch.com/#
+
+Learn more about the publisher: [.underline]#\https://magentastripe.com/#
+
+<%# =================================================================== %>
+
+[dedication%notitle]
+= Dedication
+
+image::dedication.pdf[page=3]
diff --git a/templates/part01.adoc.erb b/templates/part01.adoc.erb
new file mode 100644
index 0000000..88db084
--- /dev/null
+++ b/templates/part01.adoc.erb
@@ -0,0 +1 @@
+= Part I