# -*- mode: ruby ; coding: utf-8 -*- #= Generate HTML from RD # # Authors:: Youhei SASAKI # License:: Expat (a.k.a. MIT/X11) # $Lastupdate: 2014-10-28 17:43:54$ require 'rubygems' require 'rake' require 'yaml' require 'rd/rdfmt' require 'rd/rd2html-ext-lib' # require 'RMagick' # require 'image_size' require 'liquid' require 'pathname' require 'nkf' #== set BASE Directory # BASE = File.expand_path(File.dirname(__FILE__)) # #== load config.yaml # config = YAML::load_file("#{BASE}/config.yml") if config["base_path"] == nil config["base_path"] = "/library/dcmodel/htmltools/Webgen" end liquid = Hash.new liquid["site"] = config ###################################################################### # source files if config["recursive"] ALL_SRC_FILES = FileList["#{BASE}/**/*.rd"] elsif config["src"].nil? ALL_SRC_FILES = FileList["#{BASE}/*.rd"] else ALL_SRC_FILES = FileList["#{BASE}/*.rd"] config["src"].each do |s| ALL_SRC_FILES.include("#{BASE}/#{s}/*.rd") end end ###################################################################### # all target files GENERATED_FILES = []; ALL_SRC_FILES.each do |fpath| basename = fpath.gsub("\.rd", '') GENERATED_FILES.push basename + ".htm.ja" if config["lang"]["ja"] GENERATED_FILES.push basename + ".htm.en" if config["lang"]["en"] end ###################################################################### desc "Create/Update html files" task :default => GENERATED_FILES ###################################################################### # FileList["#{BASE}/**/*_thumbnail*"] if config["thumbnail"] desc "=> clobber" task :clean => :clobber desc "=> clobber" task :distclean => :clobber desc "clean all generated files" task :clobber do GENERATED_FILES.each {|fn| rm_r fn rescue nil} end #= 拡張子ルール # rule '.ja' => "%{\.htm$,.rd}X" do |t| puts "Update #{t} from #{t.source}" RD2Webgen.rdswap "#{t}", "#{t.source}", lang="ja", liquid end rule '.en' => "%{\.htm$,.rd}X" do |t| puts "Update #{t} from #{t.source}" RD2Webgen.rdswap "#{t}", "#{t.source}", lang="en", liquid end ###################################################################### private module RD2Webgen #== HEADER, FOOTER # # 外部から読み込めるようにも設定するが, 決め打ち様に # HEADER = <<-HEAD_EOF {{ site.title }}: {{ site.page_title }} {% if site.css %} {% endif %} {% if site.additional_head %} {{ site.additional_head }} {% endif %}
HEAD_EOF FOOTER = <<-FOOT_EOF
FOOT_EOF #== GC # # RMagick(ImageMagick) は結構メモリを喰うので, 明示的に GC しないと危険 # def self.run_gc fDisabled = GC.enable GC.start GC.disable if fDisabled end #== make thumbnail # # RD ファイル内の IMG リンクから画像のファイル名を取り出して, # thumbnail を作成する. 今の所 PNG 決め打ちであることに注意されたい. # # def self.make_rmagick_thumbnail(file, input) # @file = file # @input = input # scale = 0.3 # _src_base_path = File.dirname(@file) # @input.split("\n").each do |l| # if l =~ /\(\(<(.*)\|"IMG:(.*)">\)\)$/ # _alt_name = $1; _img_url = $2.gsub("./","") # unless _img_url =~/_thumbnail/ # _orig_img_path = File.join(_src_base_path, _img_url) # _thumb_img_name = "/" + File.basename(_img_url).gsub(/\.(.+?)$/, '_thumbnail.\1') # _thumb_img_path = File.join(_src_base_path, File.dirname(_img_url), _thumb_img_name) # unless File.exists?(_thumb_img_path) # puts "Create thumbnail #{_thumb_img_path} from #{_orig_img_path}" # img = Magick::Image.read(_orig_img_path).first # img.thumbnail!(scale) # img.format = "PNG" # File.open(_thumb_img_path, "w+"){|f| # f.puts img.to_blob # } # run_gc() # end # end # end # end # end # #== Rakefile の置き場所からの相対パスを計算する # def self.calc_relative_path(path, from) @path = Pathname.new(path) @from = Pathname.new(from) return @path.relative_path_from(@from).to_s end # #== Liquid テンプレートのコンパイル # def self.compile_liquid(liquid) @liquid = liquid header = Liquid::Template.parse(HEADER).render(@liquid) footer = Liquid::Template.parse(FOOTER).render(@liquid) return header, footer end #== RD ファイルの処理 # # 日英併記された RD ファイルから HTML ファイルを生成する # def self.rdswap(dest, file, lang, liquid, debug=nil) @file = file @dest = dest @contents = open(@file) @lang = lang @liquid = liquid @source = NKF.nkf('-w', @contents.read).gsub(/\r\n/, "\n") @contents.close # 必要に応じてサムネイルを作成 # make_rmagick_thumbnail(@file, @source) if @liquid["site"]["thumbnail"] # RD ファイルの処理 tree = RD::RDTree.new(@source, [RD::RDTree.tmp_dir], nil) visitor = RD::RD2HtmlDennouClubVisitor.new # visitor.install_ref_extension # tree.filter["RT"] = RD::RT_FILTER # visitor.include_suffix.push("RT") tree.filter["HTML"] = RD::INCLUDE_FILTER visitor.include_suffix.push("HTML") if @lang == "ja" tree.filter["JA"] = RD::RD_FILTER visitor.include_suffix.push("JA") tree.filter["HTMLJA"] = RD::INCLUDE_FILTER visitor.include_suffix.push("HTMLJA") @liquid["site"]["lang"] = "ja" elsif @lang == "en" tree.filter["EN"] = RD::RD_FILTER visitor.include_suffix.push("EN") tree.filter["HTMLEN"] = RD::INCLUDE_FILTER visitor.include_suffix.push("HTMLEN") @liquid["site"]["lang"] = "en" end begin result = visitor.visit(tree.parse) rescue puts "result: #{@dest} is empty." @liquid["site"]["page_title"] = "404 Not Found" _page_url = File.basename(@dest) @liquid["site"]["page_url"] = _page_url @liquid["site"]["mtime"] = File.mtime(@file).strftime("%Y/%m/%d") header, footer = compile_liquid(@liquid) open(@dest, "w+"){|f| f.puts header f.puts "

now under construction

" f.puts footer } else result.each_line do |l| if l =~/

(.*)<\/h1>/ _page_title = $1.gsub(/(.*)<\/a>/, '\1') @liquid["site"]["page_title"] = _page_title end end _page_url = File.basename(@dest) @liquid["site"]["page_url"] = _page_url src_base_path = File.dirname(@file) rel_path = calc_relative_path(BASE, File.dirname(@dest)) # if @liquid["site"]["publish_base"] # @liquid["site"]["assets"] = @liquid["site"]["publish_base"] + "assets" # else # @liquid["site"]["assets"] = rel_path + "/assets" # end @liquid["site"]["mtime"] = File.mtime(@file).strftime("%Y/%m/%d") # Liquid テンプレートのコンパイル header, footer = compile_liquid(@liquid) # 出力 open(@dest, "w+"){|f| f.puts header f.puts result f.puts footer } end # 一次ファイルの削除 Dir.glob("#{RD::RDTree.tmp_dir}/rdtmp.#{$$}.*.*").each do |i| File.delete(i) end end end ###################################################################### # RD extension module RD class RD2HtmlDennouClubVisitor < RD::RD2HTMLExtVisitor def apply_to_Index(element, content) # str = content.join.gsub!(/(<|>|&)/) { # METACHAR.index($&) # } str = content.join.gsub(/</,"<").gsub(/>/,">") %Q[#{str}] end # remove "name" def apply_to_Headline(element, title) anchor = get_anchor(element) label = hyphen_escape(element.label) title = title.join("") %Q[#{title}] end # apply_to_Headline def apply_to_DescListItem(element, term, description) anchor = get_anchor(element.term) label = hyphen_escape(element.label) term = term.join("") if description.empty? %Q[
#{term}
] else %Q[
#{term}
\n] + %Q[
\n#{description.join("\n").chomp}\n
] end end # apply_to_DescListItem def apply_to_DocumentElement(element, contents) content = contents.join("\n") foottext = make_foottext snippet = "
\n#{content}\n
\n" if foottext foottext = foottext.gsub(/\A
/, '') foottext = "

Footnotes

\n#{foottext}" snippet << "
\n#{foottext}\n
\n" end snippet = "
\n#{snippet}
" snippet end # apply_to_DocumentElement end # RT_FILTER = RD::Filter.new(:target) do |inn, out| # out.print("=\begin RT\n") # inn.each do |line| # out.print(line) # end # out.print("\n=\end RT\n") # end #RT_FILTER HTML_FILTER = RD::Filter.new(:target) do |inn,out| out.print("=begin HTML\n") inn.each do |line| out.print(line) end out.print("=\n\end HTML\n") end #HTML_FILTER end # module RD::RD2HTMLExtVisitor::RefExtension # alias :old_ref_ext_IMG :ref_ext_IMG # private # def ref_ext_IMG(element, label, content) # return nil unless /^IMG:(.+)$/i =~ label # file = $1 # if @liquid["site"]["thumbnail"] # thumbnail = file.gsub(/(.*)\.(.+?)$/, '\1_thumbnail.\2') # ret = %Q[] # ret << %Q[#{content}] # ret << %Q[] # else # ret = %Q[#{content}] # end # end # end