lib/dokkit/resource/document.rb in dokkit-0.4.1 vs lib/dokkit/resource/document.rb in dokkit-0.4.2
- old
+ new
@@ -21,28 +21,16 @@
include FilenameHelper
# Includes the builtin extensions to be used by Document objects.
include Extension::Builtin
- # Set the default filters chain for commonly used output format.
- DEFAULT_FILTERS_CHAIN = {
- 'html' => ['erb', 'deplate-html'],
- 'latex' => ['erb', 'deplate-latex'],
- 'text' => ['erb', 'deplate-text']
- }
- DEFAULT_POST_FILTERS_CHAIN = {
- 'html' => ['erb'],
- 'latex' => ['erb'],
- 'text' => ['erb']
- }
- attr_reader :configuration
attr_reader :source_fn
attr_reader :basename, :name_noext, :dirname, :relativename
attr_reader :config_fns, :layout_fns, :target_fns
attr_reader :targets, :layouts, :deps
- attr_reader :default_config_ext, :default_format
- attr_accessor :default_configuration_value
+ attr_reader :default_config_ext, :default_format, :default_formatter
+ attr_accessor :configuration, :default_configuration_value
# Initialize a Document instance.
# +source_fn+:: is the file name of the document source file.
# +configuration+:: is the configuration hash to be associated with the document.
# +logger+:: is the logger instance.
@@ -64,27 +52,48 @@
@name_noext = File.join(@dirname, @basename)
# Get name relative to configuration.document_dir
@relativename = filename_helper(@name_noext, configuration[:document_dir], '')
- # Set defaults
+ # Set default configuration file extension
@default_config_ext = '.yaml'
+ # Set default output format
@default_format = 'html'
+ # Set default input formatter format
+ @default_formatter = 'deplate'
+ @default_configuration_value = 'not defined'
+
# yield self to an optional configuration block
yield self if block_given?
# Setup hashes
setup_header_configuration
- setup_configuration_hash(configuration.recursive_merge('layout' => @relativename))
+ @configuration = configuration.recursive_merge('layout' => @relativename)
setup_targets(@default_format)
# Configure the document
configure
+
+ @formatter = @configuration['formatter'] || @default_formatter
+
collect_all
end
+ def method_missing(meth)
+ if @configuration.has_key?(meth.to_s)
+ @configuration[meth.to_s]
+ else
+ @logger.warn("Configuration key '#{meth.to_s}' is not defined for #{source_fn}.")
+ @default_configuration_value
+ end
+ end
+
+ def get_binding
+ binding
+ end
+
# Read the configuration file +fn+ and return:
# * the resulting configuration hash
# * an array containing the names of the read config files
# If +fn+ contains configuration data in the
# header then this method extract it. Note that the method read
@@ -109,37 +118,37 @@
else
@logger.warn("Layout file '#{get_layout_filename(name, format)}' does not exists for '#{source_fn}'!")
end
end
- # Return the filters chain associated with the given format.
- def filters_for(format)
- if @targets.has_key?(format)
- if @targets[format].has_key?('filter')
- @targets[format]['filter']
- elsif DEFAULT_FILTERS_CHAIN.has_key?(format)
- DEFAULT_FILTERS_CHAIN[format]
- end
- elsif DEFAULT_FILTERS_CHAIN.has_key?(format)
- DEFAULT_FILTERS_CHAIN[format]
+ def default_filter_chain_for(formatter, format)
+ @configuration[:default_filter_chain][formatter][format]
+ end
+
+ def default_postfilter_chain_for(format)
+ @configuration[:default_postfilter_chain][format]
+ end
+
+ def has_format?(format)
+ @targets.has_key?(format)
+ end
+
+ # Return the filters chain associated with the given formatter and output format.
+ def filters_for(formatter, format)
+ if has_format?(format)
+ process_filter_key('filter', format, default_filter_chain_for(formatter, format))
else
- @logger.error("No defined filters chain for format '#{format}'!")
+ default_filter_chain_for(formatter, format)
end
end
# Return the post filters chain associated with the given format.
def post_filters_for(format)
- if @targets.has_key?(format)
- if @targets[format].has_key?('postfilter')
- @targets[format]['postfilter']
- elsif DEFAULT_POST_FILTERS_CHAIN.has_key?(format)
- DEFAULT_POST_FILTERS_CHAIN[format]
- end
- elsif DEFAULT_POST_FILTERS_CHAIN.has_key?(format)
- DEFAULT_POST_FILTERS_CHAIN[format]
+ if has_format?(format)
+ process_filter_key('postfilter', format, default_postfilter_chain_for(format))
else
- @logger.error("No defined post filters chain for format '#{format}'!")
+ default_postfilter_chain_for(format)
end
end
def target_for(format)
@targets[format][:target_fn]
@@ -150,38 +159,35 @@
end
def current_format
@current_format || @default_format
end
-
- def include(fn)
- @cache.add_dependency(source_fn, current_format, fn)
- erb = ERB.new(File.read(fn))
- erb.filename = fn
- erb.result
- end
-
+
# Render the document in the specified format.
def render(args = { })
@current_format = args[:format]
args = { :format => @default_format }.merge args
if args.has_key?(:document)
document = @resource_factory.get(:document, args[:document])
@cache.add_dependency(source_fn, args[:format], document.source_fn)
document.render(:format => args[:format])
else
- do_render!(args[:format])
+ do_render!(@formatter, args[:format])
end
end
# Return the content of the source document file.
def source
@source ||= read_source
end
private
+ def process_filter_key(key, format, default_filter_chain)
+ @targets[format].has_key?(key) ? @targets[format][key] : default_filter_chain
+ end
+
# Read the content of the source document file from disk.
def read_source
File.read(source_fn)
end
@@ -199,20 +205,10 @@
def merge_configuration_file(fn)
fn == @source_fn ? @configuration.recursive_merge!(@header_configuration) : @configuration.recursive_merge!(YAML::load_file(fn))
@config_fns << fn
process_config_configuration_key if @configuration.has_key?('config')
end
-
- # Setup configuration hash with initial value.
- def setup_configuration_hash(configuration)
- @default_configuration_value = "not defined"
- @configuration = Hash.new do |h, k|
- @logger.warn("Configuration key '#{k}' is not defined for #{source_fn}.")
- h[k] = @default_configuration_value
- end
- @configuration.merge! configuration
- end
def setup_header_configuration
@header_configuration = extract_configuration_from_source!
end
@@ -220,23 +216,23 @@
def setup_targets(format)
@targets[format] = { :target_fn => target_fn(format) }
end
# Render document in the given format.
- def do_render!(format)
+ def do_render!(formatter, format)
if @targets[format]
- render_source!(format)
+ render_source!(formatter, format)
render_all_layouts!(format)
else
@logger.error("Don't know how to render '#{source_fn}': format '#{format}' is unknown.")
end
@content_for_layout
end
# Produce output from source.
- def render_source!(format)
- @content_for_layout = apply_filters(@source, filters_for(format), format) unless @source.nil?
+ def render_source!(formatter, format)
+ @content_for_layout = apply_filters(@source, filters_for(formatter, format), format) unless @source.nil?
end
def render_layout!(layout_fn, format)
@content_for_layout = apply_filters(File.read(layout_fn), post_filters_for(format), format) unless File.read(layout_fn).nil?
end
@@ -270,11 +266,11 @@
def collect_layouts
@targets.each_key do |format|
@layouts[format] = []
process_layout_configuration_key(format)
-
+
@layouts[format].uniq!
@layouts[format].compact!
end
@layouts
end
@@ -300,12 +296,12 @@
def process_format_configuration_key(format)
format_key = format.keys.first
opts = format.values.first
if opts
ext = (opts['ext'] if opts.has_key?('ext')) || format_key
- filters = (opts['filter'] if opts.has_key?('filter')) || DEFAULT_FILTERS_CHAIN['html']
- post_filters = (opts['postfilter'] if opts.has_key?('postfilter')) || DEFAULT_POST_FILTERS_CHAIN['html']
+ filters = (opts['filter'] if opts.has_key?('filter')) || default_filter_chain_for(@formatter, 'html')
+ post_filters = (opts['postfilter'] if opts.has_key?('postfilter')) || default_postfilter_chain_for('html')
{ :target_fn => target_fn(ext.to_sym), 'filter' => filters, 'postfilter' => post_filters }
else
@logger.error("You must define format '#{format}'!")
end
end
@@ -377,10 +373,10 @@
filename_helper(@name_noext, @configuration[:document_dir], @configuration[:output_dir], ".#{format.to_s}")
end
# Apply filters on text to produce the given format.
def apply_filters(text, filters_chain, format)
- filters_chain.collect { |filter| @filter_factory.get(filter, binding) }.inject(text) { |s, f| f.filter(s) }
+ filters_chain.collect { |filter| @filter_factory.get(filter, self) }.inject(text) { |s, f| f.filter(s) }
end
end
end
end