module Markdown class Opts def output_path=(value) @output_path = value end def output_path @output_path ||= '.' end end # class Opts class Gen include TextUtils::Filter # include filters such as comments_percent_style, etc. (see textutils gem) attr_reader :logger attr_reader :opts def initialize @logger = Logger.new(STDOUT) @logger.level = Logger::INFO @opts = Opts.new end def create_doc( fn ) dirname = File.dirname( fn ) basename = File.basename( fn, '.*' ) extname = File.extname( fn ) logger.debug "dirname=#{dirname}, basename=#{basename}, extname=#{extname}" if opts.output_path == '.' # expand output path in current dir outpath = File.expand_path( dirname ) else # expand output path in user supplied dir and make sure output path exists outpath = File.expand_path( opts.output_path ) FileUtils.makedirs( outpath ) unless File.directory? outpath end logger.debug "outpath=#{outpath}" # todo: add a -c option to commandline? to let you set cwd? # change working dir to sourcefile dir (that is, dirname); push working folder/dir newcwd = File.expand_path( dirname ) oldcwd = File.expand_path( Dir.pwd ) unless newcwd == oldcwd logger.debug "oldcwd=>#{oldcwd}<, newcwd=>#{newcwd}<" Dir.chdir( newcwd ) end inname = "#{basename}#{extname}" outname = "#{basename}.html" logger.debug "inname=#{inname}, outname=#{outname}" puts "*** #{inname} (#{dirname}) => #{outname} (#{(opts.output_path == '.') ? dirname : opts.output_path})..." content = File.read( inname ) # step 1) run (optional) preprocessing text filters Markdown.filters.each do |filter| mn = filter.tr( '-', '_' ).to_sym # construct method name (mn) content = send( mn, content ) # call filter e.g. include_helper_hack( content ) end # step 2) convert light-weight markup to hypertext content = Markdown.new( content ).to_html ## todo: add Markdown.lib_options inspect/dump to banner banner =< EOS out = File.new( File.join( outpath, outname ), "w+" ) #### out << banner out << content out.flush out.close ## pop/restore working folder/dir unless newcwd == oldcwd logger.debug "oldcwd=>#{oldcwd}<, newcwd=>#{newcwd}<" Dir.chdir( oldcwd ) end end # method create_doc def has_markdown_extension?( fn ) dirname = File.dirname( fn ) basename = File.basename( fn, '.*' ) extname = File.extname( fn ) logger.debug "dirname=#{dirname}, basename=#{basename}, extname=#{extname}" return false if extname.empty? # no extension Markdown.extnames.include?( extname.downcase ) end def find_file_with_markdown_extension( fn ) dirname = File.dirname( fn ) basename = File.basename( fn, '.*' ) extname = File.extname( fn ) logger.debug "dirname=#{dirname}, basename=#{basename}, extname=#{extname}" Markdown.extnames.each do |e| newname = File.join( dirname, "#{basename}#{e}" ) logger.debug "File.exists? #{newname}" return newname if File.exists?( newname ) end # each extension (e) nil # not found; return nil end def find_files( file_or_dir_or_pattern ) filtered_files = [] # assume pattern if includes * or ? or {} or [] if file_or_dir_or_pattern =~ /[*?{}\[\]]/ puts "searching glob pattern '#{file_or_dir_or_pattern}'..." Dir.glob( file_or_dir_or_pattern ).each do |file| if File.directory?( file ) # skip (sub)directories puts " skipping folder '#{file}'..." next else if has_markdown_extension?( file ) logger.debug " adding file '#{file}'..." filtered_files << file else puts " skipping file '#{file}'..." end end end elsif File.directory?(file_or_dir_or_pattern) puts "searching folder '#{file_or_dir_or_pattern}'..." Dir.entries( file_or_dir_or_pattern ).each do |entry| next if entry == '.' || entry == '..' # silently skip current and up dirs if file_or_dir_or_pattern == '.' file = entry else # add dir (if not working dir) file = File.join( file_or_dir_or_pattern, entry ) end if File.directory?( file ) # skip (sub)directories puts " skipping folder '#{file}'..." next else if has_markdown_extension?( file ) logger.debug " adding file '#{file}'..." filtered_files << file else puts " skipping file '#{file}'..." end end end else # assume it's a single file (check for missing extension) if File.exists?( file_or_dir_or_pattern ) file = file_or_dir_or_pattern if has_markdown_extension?( file ) logger.debug " adding file '#{file}'..." filtered_files << file else puts " skipping file '#{file}'..." end else # check for existing file w/ missing extension file = find_file_with_markdown_extension( file_or_dir_or_pattern ) if file.nil? puts " skipping missing file '#{file_or_dir_or_pattern}{#{Markdown.extnames.join(',')}}'..." else logger.debug " adding file '#{file}'..." filtered_files << file end end end filtered_files end # find_files def run( args ) opt=OptionParser.new do |cmd| cmd.banner = "Usage: markdown [options] files_or_dirs" cmd.on( '-o', '--output PATH', 'Output Path' ) { |path| opts.output_path = path } # todo: find different letter for debug trace switch (use v for version?) cmd.on( "-v", "--verbose", "Show debug trace" ) do logger.datetime_format = "%H:%H:%S" logger.level = Logger::DEBUG end ## todo: add markdown.lib options (e.g. extensions,etc) usage =<#{args.join(',')}<" # if no file args given; default to working folder (that is, .) args = ['.'] if args.length == 0 args.each do |arg| files = find_files( arg ) files.each do |file| create_doc( file ) end end puts "Done." end # method run end # class Gen end # module Markdown