require "pygments" require "redcarpet" require 'logger' require_relative 'solr' module Publisher class Markdown attr_accessor :is_markdown_file, :convert_to_html_filename, :ops, :log def initialize(ops = {}) @ops = { :output_style_sheet => 'style.css' } @ops.merge! ops @is_markdown_file = lambda { |file| File.extname(file) == '.mmd' } @convert_to_html_filename = lambda { |filename| File.basename(filename, File.extname(filename)) + ".html" } @log = Logger.new('log.txt') if level = @ops[:debug_level] @log.level = level else @log.level = Logger::INFO end end def copy_src_if_newer(read_dir, write_dir) @log.info "Copying all files from: #{read_dir}, to: #{write_dir}, if they are newer in from dir." return unless Dir.exists? read_dir FileUtils.mkdir write_dir unless Dir.exists? write_dir Dir.foreach read_dir do |curr_file| read = File.absolute_path(File.join(read_dir,curr_file)) next if File.directory? read write = File.absolute_path(File.join(write_dir,curr_file)) FileUtils.cp_r read, write_dir if file_newer? read, write @log.debug "Copied from: #{read}, to: #{write}" end end def insert_css_link(file_list) style_info = '' prepend_string style_info, file_list end def prepend_string(string, file_list) file_list.each do |file| contents = File.open(file,'r'){|f| f.read } tmp_file = file + '.tmp' File.open(tmp_file, 'w'){|f| f.write string + contents} FileUtils.rm_f file FileUtils.mv tmp_file, file end end def copy_files_to_dir(to_dir, file_list) @log.debug "Copy to: #{to_dir}. Files: #{file_list}" FileUtils.mkdir to_dir unless File.exists? to_dir raise "#{to_dir} is not a directory" unless File.directory? to_dir static_file_list = [] file_list.each do |file| FileUtils.cp file, to_dir static_file_list.push File.absolute_path(File.join(to_dir, File.basename(file))) end return static_file_list end def copy_solr_search_files ops, to_dir search_files = ops[:solr_search_files] solr_search_files_dir = ops[:solr_search_files_dir] @log.debug "Copying solr search files from: #{solr_search_files_dir}, to: #{to_dir}" search_files.each do |file| from = File.join(solr_search_files_dir, file) FileUtils.cp from, to_dir end end def process_files(from_dir = @ops[:src_dir], to_dir = @ops[:target_dir]) # Files for searching newer_files = get_newer_src_files from_dir, to_dir, @is_markdown_file, @convert_to_html_filename converted_files = convert_mmd_files newer_files, to_dir send_to_indexer converted_files, @ops[:search_category] copy_solr_search_files @ops, to_dir copy_src_if_newer File.join(from_dir, 'images'), File.join(to_dir, 'images') write_stylesheet from_dir, to_dir # Now static only files static_dir = to_dir + "_static" static_file_list = copy_files_to_dir static_dir, converted_files copy_src_if_newer File.join(from_dir, 'images'), File.join(static_dir, 'images') insert_css_link static_file_list write_stylesheet from_dir, static_dir create_index static_dir end def send_to_indexer(file_list, search_category) uploader = Solr::Upload.new(ops) file_list.each do |file| contents = File.open(file,'r'){ |f| f.read } extension = File.extname file file_name = File.basename file, extension @log.debug "Indexing the following: #{file_name}" uploader.upload_file file_name, contents, file_name, search_category end end def create_index(dir) files = File.join dir,'*.html' index = Dir.glob [files] index.sort! { |a,b| a.downcase <=> b.downcase } file = File.open(File.join(dir,"index.html"), 'w') file.write("") file.close() end def write_stylesheet(read_dir,write_dir) contents = File.open(File.join(read_dir, @ops[:style_sheet]), "rb"){|f| f.read} css = Pygments.css File.open(File.join(write_dir,@ops[:output_style_sheet]), 'w') {|f| f.write(css + "\n" + contents) } end def convert_mmd_files(files_to_convert, target_dir) markdown = Redcarpet::Markdown.new(HTMLwithPygments, :fenced_code_blocks => true, :tables => true, :autolink => true, :with_toc_data => true) converted_files = [] files_to_convert.each do |file| log.info "Working on file: " + file contents = File.open(file, "r"){|f| f.read} contents = contents.remove_non_ascii html = markdown.render(contents.force_encoding('US-ASCII')) log.debug "Converted markdown" target_file = get_target_file file, target_dir, @convert_to_html_filename write_file html, target_file converted_files.push target_file end return converted_files end def write_file( contents, out_file ) File.open(out_file, 'w') { |f| f.write contents } end def get_target_file(src_filename, target_dir, make_target_filename = nil) if make_target_filename target_file_name = make_target_filename.call src_filename else target_file_name = src_filename end target_file = File.absolute_path target_file_name, target_dir end def get_newer_src_files(src_dir, target_dir, is_wanted_src_file = nil, make_target_filename = nil) newer_src_files = [] Dir.foreach(src_dir) do |curr_file| next if File.directory? curr_file if is_wanted_src_file next unless is_wanted_src_file.call curr_file end target_file = get_target_file(curr_file, target_dir, make_target_filename) src_file = File.absolute_path curr_file, src_dir newer_src_files.push src_file if file_newer? src_file, target_file end return newer_src_files end def file_newer?(first_file, second_file) first_file_ts = File.stat(first_file).mtime return true unless File.exist?(second_file) second_file_ts = File.stat(second_file).mtime if second_file_ts > first_file_ts return false else return true end end end #--------------------------------------- class HTMLwithPygments < Redcarpet::Render::HTML attr_accessor :ops, :log def initialize(options = {}) super @ops = {:log_filename => 'log.txt'} @ops.merge! options @log = Logger.new(@ops[:log_filename]) if level = @ops[:debug_level] @log.level = level else @log.level = Logger::INFO end $toc1 = "" $last_header_level = 0 $last_header_count = 0 $header = Array.new() 0.upto(6) { |i| $header[i] = 0 } end def block_code(code, language) Pygments.highlight(code, :lexer => language) end def get_header_label( header_level ) index = header_level - 1 $header[index] = $header[index] + 1 header_level.upto($header.length - 1) { |i| $header[i] = 0 } header_string = "" 0.upto(header_level - 1) { |i| if i == header_level - 1 header_string += $header[i].to_s @log.debug "Header String: #{header_string}. Header Entry: #{$header[i]}" else header_string += $header[i].to_s + "." end } @log.info "processed: " + header_string return header_string end def set_less_significant_to_zero(header_level) 10.times {|i| p i+1} end def header(text, header_level) header_label = get_header_label(header_level) id = text.gsub(" ", "_") unless text.nil? $toc1 += "
#{header_label} - #{text}

\n" return "\n#{header_label} - #{text}\n" end def postprocess(full_document) temp = $toc1 $toc1 = "" 0.upto(6) { |i| $header[i] = 0 } return temp + full_document end end end class String def remove_non_ascii(replacement="") self.force_encoding('ASCII-8BIT').gsub(/[\x80-\xff]/,replacement) end end