lib/liquidoc.rb in liquidoc-0.4.0 vs lib/liquidoc.rb in liquidoc-0.5.0
- old
+ new
@@ -2,10 +2,11 @@
require 'yaml'
require 'json'
require 'optparse'
require 'liquid'
require 'asciidoctor'
+require 'asciidoctor-pdf'
require 'logger'
require 'csv'
require 'crack/xml'
require 'fileutils'
@@ -38,10 +39,12 @@
@attributes_file = @attributes_file_def
@pdf_theme_file = 'theme/pdf-theme.yml'
@fonts_dir = 'theme/fonts/'
@output_filename = 'index'
@attributes = {}
+@passed_attrs = {}
+@verbose = false
@logger = Logger.new(STDOUT)
@logger.level = Logger::INFO
@logger.formatter = proc do |severity, datetime, progname, msg|
"#{severity}: #{msg}\n"
@@ -86,11 +89,23 @@
when "migrate"
inclusive = true
inclusive = step.options['inclusive'] if defined?(step.options['inclusive'])
copy_assets(step.source, step.target, inclusive)
when "render"
- @logger.warn "Render actions not yet implemented."
+ if defined?(step.data)
+ attrs = ingest_attributes(step.data)
+ else
+ attrs = {}
+ end
+ validate_file_input(step.source, "source")
+ doc = AsciiDocument.new(step.source)
+ doc.add_attrs!(attrs)
+ builds = step.builds
+ for bld in builds
+ build = Build.new(bld, type) # create an instance of the Build class; Build.new accepts a 'bld' hash & action 'type'
+ asciidocify(doc, build) # perform the liquify operation
+ end
when "deploy"
@logger.warn "Deploy actions not yet implemented."
else
@logger.warn "The action `#{type}` is not valid."
end
@@ -167,15 +182,14 @@
class BuildConfigStep
def initialize step
@@step = step
- @@logger = Logger.new(STDOUT)
if (defined?(@@step['action'])).nil?
- @logger.error "Every step in the configuration file needs an 'action' type declared."
raise "ConfigStructError"
end
+ validate()
end
def type
return @@step['action']
end
@@ -198,11 +212,19 @@
def builds
return @@step['builds']
end
- def self.validate reqs
+ def validate
+ case self.type
+ when "parse"
+ reqs = ["data,builds"]
+ when "migrate"
+ reqs = ["source,target"]
+ when "render"
+ reqs = ["source,builds"]
+ end
for req in reqs
if (defined?(@@step[req])).nil?
@@logger.error "Every #{@@step['action']}-type in the configuration file needs a '#{req}' declaration."
raise "ConfigStructError"
end
@@ -214,38 +236,51 @@
class Build
def initialize build, type
@@build = build
@@type = type
- required = []
- case type
- when "parse"
- required = ["template,output"]
- when "migrate"
- required = ["source,target"]
- when "render"
- required = ["index,output"]
- end
- for req in required
- if (defined?(req)).nil?
- raise ActionSettingMissing
- end
- end
end
def template
@@build['template']
end
def output
@@build['output']
end
- def index
- @@build['index']
+ def style
+ @@build['style']
end
+ def doctype
+ @@build['doctype']
+ end
+
+ def backend
+ @@build['backend']
+ end
+
+ def attributes
+ @@build['attributes']
+ end
+
+ def validate
+ reqs = []
+ case self.type
+ when "parse"
+ reqs = ["template,output"]
+ when "render"
+ reqs = ["output"]
+ end
+ for req in required
+ if (defined?(req)).nil?
+ raise "ActionSettingMissing"
+ end
+ end
+ end
+
end #class Build
class DataSrc
# initialization means establishing a proper hash for the 'data' param
def initialize datasrc
@@ -307,10 +342,41 @@
def pattern
@@datasrc['pattern']
end
end
+class AsciiDocument
+ def initialize map, type='article'
+ @@index = map
+ @@attributes = {}
+ @@type = type
+ end
+
+ def index
+ @@index
+ end
+
+ def add_attrs! attrs
+ raise "InvalidAttributesFormat" unless attrs.is_a?(Hash)
+ self.attributes.merge!attrs
+ end
+
+ def attributes
+ @@attributes
+ end
+
+ def type
+ @@type
+ end
+end
+
+class AsciiDoctorConfig
+ def initialize out, type, back
+
+ end
+end
+
# ===
# Action-specific procs
# ===
# PARSE-type build procs
# ===
@@ -449,11 +515,11 @@
if File.directory?(src)
FileUtils.cp_r(src, dest)
else
FileUtils.cp(src, dest)
end
- @logger.info "Copied assets."
+ @logger.info "Copied #{src} to #{dest}."
rescue Exception => ex
@logger.warn "Problem while copying assets. #{ex.message}"
raise
end
end
@@ -462,37 +528,58 @@
# RENDER-type procs
# ===
# Gather attributes from a fixed attributes file
# Use _data/attributes.yml or designate as -a path/to/filename.yml
-def get_attributes attributes_file
- if attributes_file == nil
- attributes_file = @attributes_file_def
- end
+def ingest_attributes attributes_file
validate_file_input(attributes_file, "attributes")
begin
attributes = YAML.load_file(attributes_file)
return attributes
rescue
@logger.warn "Attributes file invalid."
end
end
-# Set attributes for direct Asciidoctor operations
-def set_attributes attributes
- unless attributes.is_a?(Enumerable)
- attributes = { }
+def derive_backend type, out_file
+ case File.extname(out_file)
+ when ".pdf"
+ backend = "pdf"
+ else
+ backend = "html5"
end
- attributes["basedir"] = @base_path
- attributes.merge!get_attributes(@attributes_file)
- attributes = '-a ' + attributes.map{|k,v| "#{k}='#{v}'"}.join(' -a ')
- return attributes
+ return backend
end
-# To be replaced with a gem call
-def publish pub, bld
- @logger.warn "Publish actions not yet implemented."
+def asciidocify doc, build
+ @logger.debug "Executing Asciidoctor render operation for #{build.output}."
+ to_file = build.output
+ back = derive_backend(doc.type, build.output)
+ if back == "pdf" # pass optional style file and set a default pdf-fontsdir
+ unless defined?(build.style).nil?
+ doc.add_attrs!({"pdf-style"=>build.style})
+ end
+ end
+ # Add attributes from config file build section
+ doc.add_attrs!(build.attributes.to_h)
+ # Add attributes from command-line -a args
+ doc.add_attrs!(@passed_attrs)
+ @logger.debug "Final pre-parse attributes: #{doc.attributes}"
+ # Perform the aciidoctor convert
+ Asciidoctor.convert_file(
+ doc.index,
+ to_file: to_file,
+ attributes: doc.attributes,
+ require: "pdf",
+ backend: back,
+ doctype: build.doctype,
+ safe: "server",
+ sourcemap: true,
+ verbose: @verbose,
+ mkdirs: true
+ )
+ @logger.info "Rendered file #{to_file}."
end
# ===
# Text manipulation Classes, Modules, filters, etc
# ===
@@ -580,18 +667,17 @@
# From the root directory of your project:
# $ liquidoc --help
command_parser = OptionParser.new do|opts|
opts.banner = "Usage: liquidoc [options]"
- opts.on("-a PATH", "--attributes-file=PATH", "For passing in a standard YAML AsciiDoc attributes file. Default: #{@attributes_file_def}") do |n|
- @assets_path = n
+ opts.on("-a KEY=VALUE", "For passing an AsciiDoc attribute parameter to Asciidoctor. Ex: -a basedir=some/path -a custom_var='my value'") do |n|
+ pair = {}
+ k,v = n.split('=')
+ pair[k] = v
+ @passed_attrs.merge!pair
end
- opts.on("--attr=STRING", "For passing an AsciiDoc attribute parameter to Asciidoctor. Ex: --attr basedir=some/path --attr imagesdir=some/path/images") do |n|
- @passed_attrs = @passed_attrs.merge!n
- end
-
# Global Options
opts.on("-b PATH", "--base=PATH", "The base directory, relative to this script. Defaults to `.`, or pwd." ) do |n|
@data_file = @base_dir + n
end
@@ -619,10 +705,11 @@
@template_file = @base_dir + n
end
opts.on("--verbose", "Run verbose") do |n|
@logger.level = Logger::DEBUG
+ @verbose = true
end
opts.on("--stdout", "Puts the output in STDOUT instead of writing to a file.") do
@output_type = "stdout"
end
@@ -637,10 +724,9 @@
command_parser.parse!
# Upfront debug output
@logger.debug "Base dir: #{@base_dir}"
@logger.debug "Config file: #{@config_file}"
-@logger.debug "Index file: #{@index_file}"
# ===
# Execute
# ===