lib/mdoc.rb in mdoc-0.0.3 vs lib/mdoc.rb in mdoc-0.0.5

- old
+ new

@@ -1,2 +1,143 @@ -require 'mdoc/parser' -require 'mdoc/convert' +require 'mdoc/version' +require 'mdoc/options' +require 'mdoc/meta' +require 'mdoc/document' +require 'mdoc/document/kramdown' +require 'mdoc/processor' +require 'mdoc/processor/smart_code_block' +require 'mdoc/processor/add_title' +require 'mdoc/processor/add_toc' +require 'mdoc/pipeline' +require 'mdoc/writer' + +# individual processors + +module Mdoc + extend self # act as a class + + # entry point of the application, for each source files + # read, process and write out to converted file + def execute! + load_defaults unless @opts + + opts.s_files.each do |sname| + Dir[sname].each { |fname| convert!(fname) } + end + end + + ## convert single file + def convert!(fname, doc_type = nil) + doc = prepare_doc(fname, doc_type) + + # apply pipeline of processors + pli = default_pipeline(doc) + yield pli if block_given? # receive user supplied processors + + pli.writer = find_writer(doc) unless pli.writer + pli.apply!(doc) + doc # return doc + end + + # attr accessor for opts + def opts + load_defaults unless @opts + @opts + end + + def prepare_doc(fname, doc_type) + doc_type = find_doc_type(fname) unless doc_type + doc = doc_type.new(fname) + # template + doc.tpl_file = find_tpl_file + + # output file + doc.out_file = find_out_file(fname) unless opts.no_output + doc + end + + # from several directory + # rubocop:disable MethodLength + def find_tpl_file + # add default search directory + ipath = File.expand_path(File.dirname(__FILE__) + '/../templates') + opts.tpl_directories << ipath unless opts.tpl_directories.include?(ipath) + rpath = File.expand_path('./templates') + opts.tpl_directories << rpath unless opts.tpl_directories.include?(rpath) + + opts.template = 'default.' + opts.template unless opts.template =~ /\./ + cand, buf = [], nil + opts.template.split('.').reverse.each do |b| + buf = buf ? b + '.' + buf : b + cand.unshift buf + end + + cand.each do |pt| + opts.tpl_directories.each do |d| + tpl = d + '/' + pt + '.erb' + return tpl if File.exists?(tpl) + end + end + + raise 'no template file found for ' + opts.template + nil + end + # rubocop:enable MethodLength + + def find_out_file(fname) + return opts.output if opts.output + ext = '.' + opts.template.split('.')[-1] + fname =~ /\.\w{2,5}$/ ? fname.gsub(/\.\w+$/, ext) : fname + ext + end + + # get class from keyword and module under Mdoc name space + def get_class(cname, mdl = Processor) + begin + mdl.const_get(cname.split(/[\,\_]/).map { |p| p.capitalize }.join) + rescue NameError + return nil + end + end + + def get_processor(pn) + pname = pn.is_a?(String) ? pn : pn.class + pn = get_class(pn) if pn.is_a?(String) # for string name + raise "not a valid class: #{pname.to_s}" unless pn + raise "not a processor: #{pname.to_s}" unless pn < Mdoc::Processor + + pn + end + + # from file name (esp. extensions), determine source file document type + def find_doc_type(f) + case f + when /\.(md|markdown)/ + Document::Kramdown + else Document + end + end + + # get a list of processors into a pipline + def default_pipeline(doc) + pli = Pipeline.new default_processors + opts.processors.each { |p| pli.append p } + opts.no_processors.each { |p| pli.remove p } + pli + end + + def default_processors + %w[ + add_toc + add_title + smart_code_block + ] + end + + def find_writer(doc) + case opts.template + when /pandoc\.\w+$/ + Writer::Pandoc + else Writer + end + end +end +