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