Class DCModelThumbnail
In: dcmodel-thum.rb
Parent: Object

DCModelThumbnail

 「dcmodel お絵描きサムネイル HTML 作成スクリプト」の作成用のクラス

Methods

Constants

COPYRIGHT = "GFD Dennou Club"   CopyRight
INFO_DELIMITER = ":"   項目の区切り文字

Attributes

copyright  [RW]  copyright
css  [RW]  スタイルシートファイル
ext_list  [RW]  画像ファイルとして認識する拡張子
figdir  [RW]  絵のあるディレクトリ名。カレントディレクトリから "#{@figdir}" の場所を探査する。
figtable_num  [RW]  横にならべるファイル数
headlimit  [RW]  接頭子制限 @headlimit = "figure_head"。 これにより、@headlimit に当てはまらないものは無視される
html_author  [RW]  html の作成者情報 (ユーザアカウント名)
img_height  [RW]  画像ファイルサイズ (高さ)
img_width  [RW]  画像ファイルサイズ (幅)
index  [RW]  作成されるサムネイルのファイル名 (拡張子除く)
index_ext  [RW]  作成されるサムネイルの拡張子名
infofile  [RW]  情報ファイル, $PWD/${infofile}
message  [RW]  本体。サムネイルの部分よりも上に出力される。 この変数自体は Array オブジェクトで、その内部に String オブジェクトが 格納される。
rd2_path  [RW]  rd2 ファイルのパス
rd2htmlextlib  [RW]  rd2-ext-lib へのライブラリのパス
title  [RW]  html ヘッダのタイトル
tmp  [RW]  テンポラリファイル置き場 (UNIX 系ならば変える必要なし)

Public Class methods

これを呼ぶことで、最低限必要な情報が生成される。 最終的には DCModelThumbnail.create メソッドを呼ぶことで ファイルが作成される。

[Source]

     # File dcmodel-thum.rb, line 235
235:   def initialize()
236:     #
237:     # copyright
238:     #
239:     @copyright = COPYRIGHT
240: 
241:     # html の置き場・ファイル名・拡張子。カレントディレクトリから
242:     #
243:     #    "#{@index}#{index_ext}" 
244:     #
245:     #に置かれる。
246:     @index     = "../htmlname"
247:     @index_ext = ".htm"
248: 
249:     # 絵のあるディレクトリ名。カレントディレクトリから 
250:     # "#{@figdir}" の場所を探査する。
251:     @figdir = "../figdir"
252: 
253:     # 情報ファイル, $PWD/${infofile}
254:     @infofile = File.basename(@index).chomp.strip + ".txt"
255: 
256:     # 画像ファイルとして認識する拡張子
257:     @ext_list = ["gif", "png", "jpg", "jpeg"]
258: 
259:     # 接頭子制限 @headlimit = "figure_head"。
260:     # これにより、@headlimit に当てはまらないものは無視される
261:     @headlimit = ""
262: 
263:     # スタイルシートファイル
264:     @css    = "/GFD_Dennou_Club/ftp/arch/dcmodel/htmltools/dcmodel.css"
265: 
266:     # rd2 ファイルのパス
267:     @rd2_path = "/usr/bin/rd2"
268: 
269:     # rd2-ext-lib へのライブラリのパス
270:     @rd2htmlextlib = "/GFD_Dennou_Club/ftp/arch/dcmodel/lib"
271: 
272:     # テンポラリファイル置き場 (UNIX 系ならば変える必要なし)
273:     @tmp     = "/tmp"
274: 
275:     # 画像ファイルサイズ
276:     @img_width  = 200
277:     @img_height = 150
278: 
279:     # 横にならべるファイル数
280:     @figtable_num = 3
281: 
282:     # html の作成者情報 (ユーザアカウント名)
283:     @html_author = username_from_gid
284: 
285:     # html ヘッダタイトル
286:     @title  = "タイトル"
287: 
288:     # 本体 (サムネイルの部分よりも上にメッセージ)
289:     @message = Array.new
290:     @message << "=begin\n[((<\303\317\265\345\316\256\302\316\305\305\307\276\266\346\263\332\311\364|URL:http://www.gfd-dennou.org>))]\n[((<dcmodel|URL:http://www.gfd-dennou.org/arch/dcmodel>)) |\n((<dcmodel-tools|URL:http://www.gfd-dennou.org/arch/dcmodel/bin>))]\n\n= \#{@title}\n\n== \314\334\274\241\n\n=== \303\346\314\334\274\241\n\n* \245\352\245\271\245\310\n* \276\256\271\340\314\334\n\n* ((<\276\360\312\363\245\325\245\241\245\244\245\353\244\330\244\316\245\352\245\363\245\257|URL:thum/htmlname.txt>))\n* \262\350\301\374\245\325\245\241\245\244\245\353\244\330\244\316\245\352\245\363\245\257((<URL:figdir>))\n=end\n\n"
291:     @message << "=begin RT\ncaption = \311\275\245\306\245\271\245\310\n\n, \277\315\264\326, == , \270\244 , ==\n||  , \303\313  , \275\367 ,\245\252\245\271,\245\341\245\271\n\nx  , 1.0 , 2.0, 1.1, 1.2\ny  , 0.4 , 0.5, 0.3, 0.1\n\n=end\n"
292:     @message << "<br>\n\274\302\270\263\300\337\304\352\244\312\244\311\244\317\244\263\244\263\244\313\275\361\244\255\271\376\244\340.  <br>\n\244\263\244\263\244\313\275\361\244\244\244\277\312\270\273\372\244\317\245\273\245\363\245\277\245\352\245\363\245\260\244\265\244\354\244\306\244\267\244\336\244\246.  <br>\n\244\301\244\347\244\303\244\310\263\346\271\245\260\255\244\244. <br><br>\n<table BORDER=\\\\\"0\\\\\" cellspacing=\\\\\"10\\\\\" align=\\\\\"center\\\\\">\n<tr><td><small>\n\245\306\241\274\245\326\245\353\244\362\244\265\244\351\244\313\272\356\244\303\244\306\244\275\244\316\303\346\244\313\275\361\244\255\271\376\244\340. <br>\n\244\275\244\246\244\271\244\353\244\310\244\263\244\363\244\312\264\266\244\270.\n</small></td></tr></table>\n<br><br>\n[<a href =\\\\\"http://www.gfd-dennou.org/arch/dcmodel\\\\\">HOME</a>]\n<hr>\n"
293: 
294:     debug(@message)
295:   end

Public Instance methods

HTML ファイルの最終的な作成メソッド。最後にこのメソッドを呼ぶことで 作業が完了する。

overwrite に false を与えると、上書きを禁止する。

quiet を true にするとエラーを除く全てのメッセージが表示されなくなる。

verbose を true にすると作業の進捗状況がメッセージとして出力される。

err を true にした場合、意図しない動作が起きた場合にすぐに エラーを起こす。

[Source]

      # File dcmodel-thum.rb, line 913
 913:   def create(overwrite=true, quiet=nil, verbose=true, err=true)
 914: 
 915:     #
 916:     # サムネイルファイル名
 917:     #
 918:     index_file_name = @index.chomp.strip  +
 919:                       @index_ext.chomp.strip
 920: 
 921:     #
 922:     # 元ファイル削除 (overwrite が nil の場合はエラー)
 923:     #
 924:     if File.exist?(index_file_name)
 925:       if overwrite then
 926:         File.delete(index_file_name)
 927:       else
 928:         raise ArgumentError, "Error : \"#{index_file_name}\" exist already.\n"
 929:       end
 930:     end
 931: 
 932: 
 933:     #
 934:     # infofile の作成 (既に存在する場合はそのまま)。
 935:     # DCModelThumbnail.info_make メソッドを呼ぶ
 936:     #
 937:     status = info_make(@figdir, @infofile, @ext_list,
 938:                        @headlimit, nil, nil,
 939:                        true, err)
 940:     if verbose then
 941:       if /create/ =~ status
 942:         $stdout.print "  Message : Infofile \"#{@infofile}\" is created.\n"
 943:       elsif /exist/ =~ status
 944:         $stdout.print "  Message : Infofile \"#{@infofile}\" is already exist.\n"
 945:       end
 946:     end
 947: 
 948:     #
 949:     # @message が Array オブジェクト以外の場合はエラーを返す。
 950:     #
 951:     if !@message.instance_of?(Array) then
 952:       warn_or_err(
 953:                   "\"message\" must be Array Object. " +
 954:                   "Please \"message = Array.new\" initially.\n", 
 955:                   true, nil, ArgumentError)
 956:     end
 957: 
 958:     #
 959:     # infofile から情報の取得。
 960:     # DCModelThumbnail.info_get メソッドを呼ぶ。
 961:     #
 962:     info_list = info_get(@infofile, @headlimit, nil, quiet, err)
 963:     #
 964:     # infofile からの情報のうち、画像ファイル名を "title" にしている
 965:     # ものに関して @title に上書きして、info_list から除く。
 966:     #
 967:     # infofile からの情報のうち、画像ファイル名を "message" にしている
 968:     # ものに関して @message に追加して、info_list から除く。
 969:     #
 970:     info_list_buff = Array.new
 971:     info_list.each{ |info_part|
 972:       if /title/ =~ info_part['fig_name']
 973:         @title = info_part['comment']
 974:       elsif /message/ =~ info_part['fig_name']
 975:         @message << info_part['comment']
 976:       else
 977:         info_list_buff << info_part
 978:       end
 979:     }
 980:     info_list = Array.new
 981:     info_list << info_list_buff
 982:     info_list.flatten!          # 配列の平滑化 (1次元配列化)
 983: 
 984:     $stdout.print "  Message : Get information from \"#{@infofile}\".\n" if verbose
 985: 
 986:     #
 987:     # @message のフォーマットを解析し、HTML に変換する。
 988:     #
 989:     html_message = Array.new
 990:     @message.each{ |mess|
 991:       format = format_parser(mess)
 992: 
 993:       if /rd/ =~ format then
 994:         html_buff = rd2html(mess, true)
 995:       elsif /rt/ =~ format then
 996:         html_buff = rd2html(mess, true)
 997:       else
 998:         html_buff = mess
 999:       end
1000: 
1001:       html_message << html_buff if html_buff
1002:       debug(html_message)
1003:     }
1004:     debug(html_message)
1005: 
1006: 
1007:     # 初期化
1008:     html_entire = ""
1009: 
1010:     # ヘッダ部分
1011:     $stdout.print "  Message : Generate HTML Header...." if verbose
1012:     html_entire << html_header 
1013:     $stdout.print "  done.\n" if verbose
1014: 
1015:     # 本文
1016:     $stdout.print "  Message : Insert body messages...." if verbose
1017:     html_message.each { |message|
1018:       html_entire << message
1019:     }
1020:     $stdout.print "  done.\n" if verbose
1021: 
1022:     # サムネイル部分
1023:     $stdout.print "  Message : Generate Thumbnail Lists...." if verbose
1024:     html_entire << html_thum(info_list, quiet, true)
1025:     $stdout.print "  done.\n" if verbose
1026: 
1027:     # フッタ部分
1028:     $stdout.print "  Message : Generate HTML Footer...." if verbose
1029:     html_entire << html_footer
1030:     $stdout.print "  done.\n" if verbose
1031: 
1032:     # ファイルの書きだし
1033:     $stdout.print "  Message : Output to #{index_file_name}...." if verbose
1034:     ifile = open(index_file_name, "w")
1035:     ifile.print html_entire
1036:     ifile.close
1037:     $stdout.print "  Successfull. \n" if verbose
1038:   end

サンプルスクリプト出力用のメソッド。 この DCModelThumnail クラスに依存するサンプルスクリプトを 引数 filename という名前で出力する。実際には、このファイル を編集・実行することでサムネイルが作成される寸法である。

[Source]

      # File dcmodel-thum.rb, line 1227
1227:   def create_sample_rb(filename)
1228:     if !(str_and_notspace?(filename)) then
1229:       return warn_or_err("filename is invalid.\n",
1230:                          true, nil, ArgumentError)
1231:     end
1232:     
1233:     rb_file_body = "#!/usr/bin/env ruby\n#\n#= dcmodel thumnail generate ruby script\n#\n#  Editor :: \#{username_from_uid}\n#  Version:: \#{Time.now.strftime(\"%Y/%m/%d %H:%M:%S\")}\n#\n#== Overview\n#\n#This file is generate by following ruby script automatically.\n#\n#      \#{File.expand_path($0.to_s)}\n#\n#Please edit this file according to your purpose.\n#\n#== Usage\n#\n#\n##################################################\n\nrequire \"\#{File.expand_path($0.to_s)}\"\n\n######################################################\nif $0 == __FILE__ then\nthumb = DCModelThumbnail.new\n\n#  thumb.copyright = \"\#{@copyright}\"\nthumb.index     = \"\#{@index}\"\n#  thumb.index_ext = \"\#{@index_ext}\"\nthumb.infofile  = \"\#{@infofile}\"\n#  thumb.ext_list.push(\"bmp\")\n#  thumb.headlimit = \"headlimit_\"\n#  thumb.figdir    = \"\#{@figdir}\"\n#  thumb.css       = \"\#{@css}\"\n#  thumb.rd2_path  = \"\#{@rd2_path}\"\n#  thumb.rd2htmlextlib = \"\#{@rd2htmlextlib}\"\n#  thumb.img_width  = \#{@img_width}\n#  thumb.img_height = \#{@img_height}\n#  thumb.figtable_num = \#{@figtable_num}\n#  thumb.html_author  = \"\#{@html_author}\"\nthumb.title     = \"\#{@title}\"\nthumb.message   = Array.new\nthumb.message   << <<-MSG\n\#{@message[0]}\nMSG\n\nthumb.message   << <<-MSG\n\#{@message[1]}\nMSG\n\nthumb.message   << <<-MSG\n\#{@message[2]}\nMSG\nthumb.create\nend\n\n"
1234: 
1235:     #
1236:     # ファイルの作成
1237:     #
1238:     ifile = open(filename, "w")
1239:     ifile.print "#{rb_file_body}"
1240:     ifile.close
1241: 
1242:     #
1243:     # パーミッションの設定
1244:     #
1245:     File.chmod(0755, filename)
1246: 
1247:   end

mes で与えられる本文の行頭を解析し、その本文が HTML であるか、 RD であるか、RT であるのかを判別する。現在、以下のように判定している。

  • 行頭文字が「=begin」、「=begin RD」、「=begin rd」
    • RD のフォーマットであると判別
  • 行頭文字が「=begin RT」、「=begin rt」
    • RT のフォーマットであると判別
  • 上記以外
    • HTML フォーマットであると判別

返り値は "html", "rd", "rt" のいづれかである。なお、body に String オブジェクト以外、もしくは完全に空白のみが入っている場合、 nil を返す。

[Source]

      # File dcmodel-thum.rb, line 1057
1057:   def format_parser(body=nil)
1058:     debug(body)
1059:     if !(str_and_notspace?(body)) then
1060:       return warn_or_err("\"body\" is not String Object.\n")
1061:     end
1062: 
1063:     Kconv::toeuc(body)
1064:     body_parts = body.split("\n")
1065: 
1066:     body_parts.each{ |line|
1067:       next unless /\w+/e =~ line.chomp.strip
1068:       if /=begin\s+(rt)/ie =~ line.chomp.strip
1069:         return "rt"
1070:       elsif /=begin/ie =~ line.chomp.strip
1071:         return "rd"
1072:       elsif /=begin\s+(rd)/ie =~ line.chomp.strip
1073:         return "rd"
1074:       else
1075:         return "html"
1076:       end
1077:     }
1078:     return nil
1079:   end

フッター作成用メソッド。相当する文字列を返す。 DCModelThumbnail.html_header で得られる文字列で始まる HTML を 閉じることを想定している。

[Source]

     # File dcmodel-thum.rb, line 873
873:   def html_footer()
874:     # @index のディレクトリから見た、生成スクリプトの相対的な位置
875:     generator = relative_str("#{$0}", @index)
876: 
877:     # @index のディレクトリから見た、情報ファイルの相対的な位置
878:     infofile  = relative_str(@infofile, @index)
879: 
880:     #
881:     # フッターとして書き出し
882:     #
883:     html_footer = "<hr size=\"1\">\n<center>\n<small>\nThis page is generated by <a href=\\\"\#{generator}\\\">\#{generator}</a>\nand <a href=\\\"\#{infofile}\\\">\#{infofile}</a>\n(\#{Time.now.strftime(\"%Y/%m/%d %H:%M:%S\")} \#{username_from_uid})<br>\nCopyright &copy; \#{@copyright} \#{Time.now.strftime(\"%Y\")}\n</small>\n</center>\n</body>\n</html>\n"
884:     return html_footer
885:   end

HTML のヘッダ部分の作成メソッド。相当する文字列を返す。 作成した HTML は DCModelThumbnail.html_footer で得られる文字列で 閉じられることを想定している。

[Source]

     # File dcmodel-thum.rb, line 642
642:   def html_header()
643:     # @index のディレクトリから見た、生成スクリプトの相対的な位置
644:     generator = relative_str("#{$0}", @index)
645: 
646:     # @index のディレクトリから見た、css の相対的な位置
647:     css       = relative_str(@css, @index)
648: 
649:     header = "<?xml version=\"1.0\" encoding=\"euc-jp\" ?>\n<!DOCTYPE html\nPUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\"\n\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n<html lang=\"ja\" xmlns=\"http://www.w3.org/1999/xhtml\">\n<head>\n<title>\#{@title}</title>\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=x-euc-jp\" />\n<meta name=\"Author\" content=\"\#{@html_author}\" />\n<meta name=\"robots\" content=\"noindex,nofollow\" />\n<meta name=\"robots\" content=\"noarchive\" />\n<meta name=\"generator\" content=\"\#{generator}\" />\n<link href=\"\#{css}\" type=\"text/css\" rel=\"stylesheet\" />\n</head>\n<body>\n"
650:     return header
651:   end

HTML のサムネイル部分 (画像の数に応じて繰り返す部分) を作成するメソッド。 相当する文字列を返す。info_list には DCModelThumbnail.info_get で 取得される形式の情報ファイルが与えられる。

それ以外の形のデータが与えられる場合には警告を発して nil を返す。 ただし、err に true を与えると、エラーが生じる。 quiet が true の場合には警告メッセージも表示しない。

内部で DCModelThumbnail.html_thum_parts を呼び、各要素はそちらで 作成する。

[Source]

     # File dcmodel-thum.rb, line 682
682:   def html_thum(info_list=nil, quiet=nil, err=nil)
683: 
684:     #
685:     # 引数に与えられたデータの検証
686:     #
687:     if !array_and_notzero?(info_list) then
688:       return warn_or_err(
689:                          "\"info_list\" is invalid.\n",
690:                          err, quiet, ArgumentError)
691:     end
692: 
693:     #
694:     # table タグを作成
695:     #
696:     html_table = ""
697: 
698:     html_table = "<table border=\"0\" cellspacing=\"10\" align=\"center\">\n"
699: 
700:     #
701:     # 中身を作成
702:     #
703:     info_list.size.times{ |num|
704:       html_table << html_thum_parts(info_list, num, quiet, err)
705:     }
706: 
707:     #
708:     # もしも、info_list.size が @figtable_num で割り切れない場合、
709:     # 残り分の空白 td を作成する
710:     #
711:     remain = @figtable_num - (info_list.size % @figtable_num)
712:     td_width   = (100 / @figtable_num).truncate.to_s + "%"  # 一つの td の幅
713: 
714:     if !(remain == 0) then
715:       remain.times{ |time|
716:         html_table << "<td width=\"\#{td_width}\" valign=\"top\">\n&nbsp;\n</td>\n"
717:       }
718:       html_table << "</tr>\n"
719:     end
720: 
721:     #
722:     # /table タグを作成
723:     #
724:     html_table << "</table>\n"
725: 
726:     return html_table
727:   end

HTML のサムネイル部分の内部 (テーブルの1要素毎) を作成するメソッド。 相当する文字列を返す。info_list には DCModelThumbnail.info_get で 取得される形式の情報ファイルを、num には何番目のデータなのかを 示す Numerical オブジェクトを与える。

それ以外の形のデータが与えられる場合には警告を発して nil を返す。 ただし、err に true を与えると、エラーが生じる。 quiet が true の場合には警告メッセージも表示しない。

[Source]

     # File dcmodel-thum.rb, line 754
754:   def html_thum_parts(info_list=nil, num=nil, quiet=nil, err=nil)
755:     #
756:     # 引数に与えられたデータの検証
757:     #
758:     if !array_and_notzero?(info_list) then
759:       return warn_or_err(
760:                          "\"info_list\" is invalid.\n",
761:                          err, quiet, ArgumentError)
762:     end
763: 
764:     if !num.kind_of?(Integer)
765:       return warn_or_err(
766:                          "\"num\" is not integer.\n",
767:                          err, quiet, ArgumentError)
768:     end
769: 
770:     #
771:     # info_list からデータの取得
772:     #
773:     fig_name        = info_list[num]['fig_name'] # 画像ファイル名
774:     comment         = info_list[num]['comment']  # コメント
775:     align           = info_list[num]['align']    # 文字寄せ
776:     fig_name_nohead = info_list[num]['fig_name_nohead'] # 省略画像ファイル名
777:     format          = info_list[num]['format']   # comment のフォーマット
778:     debug(fig_name, comment, align, fig_name_nohead)
779: 
780:     #
781:     # format から、comment の変換処理
782:     #
783:     if /rd/ =~ format then
784:       comment_buff = rd2html(comment)
785:     elsif /rt/ =~ format then
786:       comment_buff = rd2html(comment)
787:     else
788:       comment_buff = "#{comment}"
789:     end
790:     comment = "#{comment_buff}"
791: 
792:     #
793:     # @index からの相対的な @figdir の設定
794:     #
795:     rel_figdir = relative_str(@figdir, @index)
796: 
797:     #
798:     # テーブルの配置によって <tr> のつけたしをおこなう。
799:     # (num はゼロからスタートすることに注意)
800:     # 左端 : @figtable_num * n       (remainder == 0)
801:     # 右端 : @figtable_num * n - 1   (remainder == @figtable - 1)
802:     #
803:     remainder  = num % @figtable_num    # 余り
804:     figtable_1 = @figtable_num - 1      # 列数 - 1
805:     td_width   = (100 / @figtable_num).truncate.to_s + "%"  # 一つの td の幅
806:     debug(num, remainder, figtable_1, @figtable_num, td_width)
807: 
808:     html_table_part  = ""
809: 
810:     # 左端用の <tr> タグ
811:     if remainder == 0 then
812:       html_table_part = "<tr valign=\"center\">\n"
813:     end
814: 
815:     # 画像ファイル名が "label" の場合には comment をそのまま書き出す。
816:     if /^label$/ =~ fig_name_nohead.chomp.strip then
817:       html_table_part << "<td align=\"\#{align}\" width=\"\#{td_width}\" valign=\"center\">\n<small>\n\#{comment}\n</small>\n</td>\n"
818: 
819:     # 画像ファイル名が存在しない場合は空白を書き出す。
820:     elsif !(str_and_notspace?(fig_name_nohead)) then
821:       html_table_part << "<td align=\"\#{align}\" width=\"\#{td_width}\" valign=\"top\">\n&nbsp;\n</td>\n"
822: 
823:     # 上記以外の場合には、絵の縮小版とそのリンクを張り込む
824:     else
825:       html_table_part << "<td align=\"center\" width=\"\#{td_width}\" valign=\"top\">\n<a href=\"\#{rel_figdir}/\#{fig_name}\">\n<img src=\"\#{rel_figdir}/\#{fig_name}\" border=\"1\" width=\"\#{@img_width.to_s}\" height=\"\#{@img_height.to_s}\">\n</a>\n<br>\n<div align=\"\#{align}\">\n<small>\n\#{fig_name_nohead}<br>\n\#{comment}<br><br>\n</small>\n</div>\n</td>\n"
826:     end
827: 
828:     # 右端用の </tr> タグ
829:     if remainder == figtable_1 then
830:       html_table_part << "</tr>\n"
831:     end
832: 
833:     return html_table_part
834:   end

DCModelThumbnail.info_make によって作成される「情報ファイル」 infofile から画像ファイル名とコメント、および修飾情報を取り出し、 Array[Hash, …] にして返す。 各要素の Hash にはキーに値の種類の文字列を格納してある。 以下は現在 Hash のキーとして取得されるものである。

  * fig_name
    * ファイル名である。1 つ目の区切り文字
      (DCModelThumbnail.info_make の INFO_DELIMITER 参照)
      よりも前の文字列をこのキーの値として取得する。なお、
      引数 headlimit が与えられる場合、情報ファイルの文字列の
      頭に headlimit を付加する。
  * fig_name_nohead
    * fig_name と同様にファイル名である。ただし、こちらは
      引数 headlimit が与えられる場合でも、情報ファイルから得られる
      文字列のみを格納する。
  * comment
    * サムネイルの個々の画像の下に付加されるコメントである。
      2 つ目の区切り文字以降の文字列がこのキーの値として取得される。
      なお、デフォルトでは改行文字までをコメントとして読み込むが、
      将来的には修飾情報に "m" が入る場合、"{" と "}" の間の文字
      を読み込むようにする予定である。(改行文字も含める)。
  * align
    * コメントの文字寄せ情報である。1つ目と2つ目の区切り文字の間に
      下記の文字列を入れることで、下記のそれに対応する値が格納される。
      なお、デフォルトでは "center" が格納される。
      * "<" : 左寄せを示し、値に "left" を格納する。
      * ">" : 右寄せを示し、値に "right" を格納する。
  * format
    * フォーマットの情報である。
      下記の文字列を入れることで、下記のそれに対応する値が格納される。
      なお、デフォルトでは "html" が格納される。
      * "r" : RD フォーマットであることを示す。
      * "t" : RT フォーマットであることを示す。
  * line
    * 情報ファイルの該当情報の「行数」が格納される。
      複数行が指定される場合は "4-10" というように格納される。

delimiter (String オブジェクト) は情報ファイルの 画像ファイル名・修飾情報・コメントの区切り文字を設定する ものであり、デフォルトは定数 INFO_DELIMITER にて設定されている。 一応変更できるようになっているが、原則的に変更しない 事を薦める。

quiet を真にすると、ファイルがない際にもメッセージを表示しない。

err を真にすると、ファイルが見つからない際にエラー処理をする。

[Source]

     # File dcmodel-thum.rb, line 541
541:   def info_get(infofile=nil, headlimit=nil, delimiter=nil, 
542:                quiet=nil, err=nil)
543: 
544:     # delimiter のセット
545:     if !(str_and_notspace?(delimiter)) then
546:       delimiter = INFO_DELIMITER
547:     end
548: 
549:     info_list = Array.new
550: 
551:     # ファイルが読み取れるかチェック
552:     if !(File.readable?(infofile)) then
553:         return warn_or_err("\"#{infofile}\" is not readable. \n",
554:                            err, quiet, ArgumentError)
555:     end
556: 
557:     # 実際にファイルを開く
558:     ifile = open(infofile, "r")
559: 
560:     line_num = 0
561:     ifile.each { |line|
562: 
563:       # 探索したデータの格納用配列とハッシュ
564:       info_part = Array.new
565:       info_hash = Hash.new
566: 
567:       # 行数を数える
568:       line_num += 1
569: 
570:       info_part = line.chomp.split(/#{delimiter}/, 3)
571:       info_hash['fig_name_nohead'] = info_part[0]
572:       info_hash['comment']         = info_part[2]
573:       info_hash['line']            = line_num.to_s
574: 
575:       # 行頭が "#" の場合はコメントアウトと考えて無視。
576:       if /^\s*#/ =~ info_part[0] then
577:         next
578:       end
579: 
580:       # info_hash['fig_name'] の設定
581:       if str_and_notspace?(headlimit) then
582:         info_hash['fig_name'] = headlimit.chomp.strip + info_part[0].chomp.strip
583:       else
584:         info_hash['fig_name'] = info_part[0]
585:       end
586: 
587:       #
588:       # 修飾子の解析 (万が一のことを考え、日本語も処理)
589:       #
590:       modifier = Kconv::toeuc(info_part[1].chomp.strip)
591: 
592:       #
593:       # 日本語らしきものが入っていたら警告またはエラー
594:       #
595:       if !(modifier == Kconv::toeuc(modifier)) ||
596:          !(modifier == Kconv::tojis(modifier)) ||
597:          !(modifier == Kconv::tosjis(modifier)) then
598: 
599:         warn_or_err(
600:                     "\"#{modifier}\" include 2 bite code, " +
601:                     "so this may not be parsed correctly.\n",
602:                     err, quiet, ArgumentError)
603:       end
604: 
605:       # 文字寄せ情報の解析
606:       if />/ =~ modifier.chomp.strip then
607:         info_hash['align'] = "right"
608:       elsif /</ =~ modifier.chomp.strip then
609:         info_hash['align'] = "left"
610:       else
611:         info_hash['align'] = "center"
612:       end
613: 
614:       # フォーマット情報の解析
615:       if /r/ =~ modifier.chomp.strip then
616:         info_hash['format'] = "rd"
617:       elsif /t/ =~ modifier.chomp.strip then
618:         info_hash['format'] = "rt"
619:       else
620:         info_hash['format'] = "html"
621:       end
622: 
623:       # 複数行を取得するかどうかの解析
624:       if /m/ =~ modifier.chomp.strip then
625:         warn_or_err(
626:                     "Still multi-line option is invalid.\n"
627:                     )
628:       end
629: 
630:       info_list.push(info_hash)
631:     }
632:     ifile.close
633: 
634:     return info_list
635:   end

画像ファイル名・修飾情報・コメントを含む「情報ファイル」を作成するための メソッド。

figdir (String オブジェクト) 内の拡張子 ext_list (Array オブジェクト) にヒットするファイル名 をリストにし、infofile (String オブジェクト) に書き出す。

headlimit (String オブジェクト) を渡すと、ファイル名の頭が headlimit にヒットするものだけを拾い、リストからはその部分を 取り除くようにする。

overwrite を true にすると、infofile が存在する場合でも 上書きする。また、quiet を true にすると警告メッセージを表示しない。

delimiter (String オブジェクト) は情報ファイルの 画像ファイル名・修飾情報・コメントの区切り文字を設定する ものであり、デフォルトは定数 INFO_DELIMITER にて設定されている。 一応変更できるようになっているが、原則的に変更しない 事を薦める。

ファイルを作成したときは "create", 既存のものがすでに存在する 場合には "exist" を返し、既存のものが無く、なおかつ作成に失敗 した場合は false を返す。

ここで作成されるファイルは DCModelThumbnail.info_get で取得される ファイルの雛形である。

[Source]

     # File dcmodel-thum.rb, line 403
403:   def info_make(figdir=nil, infofile=nil, ext_list=nil,
404:                 headlimit=nil, overwrite=nil, delimiter=nil,
405:                 quiet=nil, err=true)
406: 
407:     # infofile があり、overwrite が false の場合は終了。
408:     if File.exist?(infofile) && !overwrite then
409:       $stdout.print "[#{caller.first}] \n     Warning: Infofile \"#{infofile}\" already exist. So not generate infofile once again.\n" unless quiet
410:       return "exist"
411:     end
412: 
413:     # 引数の有効性の検証
414:     if !(str_and_notspace?(figdir)) then
415:       if err then
416:         raise ArgumentError, "Error: \"figdir\" is not specified. So \"infofile\" is not generated.\n. \n"
417:       elsif !quiet
418:         $stdout.print "[#{caller.first}] \n     Warning: \"figdir\" is not specified. So \"infofile\" is not generated.\n\n"
419:         return nil
420:       end
421: 
422:     elsif !(str_and_notspace?(infofile)) then
423:       if err then
424:         raise ArgumentError, "Error: \"infofile\" is not specified. So \"infofile\" is not generated.\n. \n"
425:       elsif !quiet
426:         $stdout.print "[#{caller.first}] \n     Warning: \"infofile\" is not specified. So \"infofile\" is not generated.\n\n"
427:         return nil
428:       end
429: 
430:     elsif !(array_and_notzero?(ext_list)) then
431:       if err then
432:         raise ArgumentError, "Error: \"ext_list\" is not specified. So \"infofile\" is not generated.\n. \n"
433:       elsif !quiet
434:         $stdout.print "[#{caller.first}] \n     Warning: \"ext_list\" is not specified. So \"infofile\" is not generated.\n\n"
435:         return nil
436:       end
437:     end
438: 
439:     # delimiter のセット
440:     if !(str_and_notspace?(delimiter)) then
441:       delimiter = INFO_DELIMITER
442:     end
443: 
444:     # headlimit の整形
445:     if !(str_and_notspace?(headlimit)) then
446:       headlimit = ""
447:     end
448: 
449:     # figdir から画像ファイル名一覧をとりだし, 配列 imgfiles へ代入
450:     imgfiles = Array.new
451:     Dir.foreach("#{figdir}") { |item|
452:       ext_list.each{ |ext|
453:         next if !(str_and_notspace?(ext))
454: 
455:         # ドットが付いていない場合はドットをつける
456:         if !(/^\.(.*)/ =~ ext) then
457:           ext = "." + ext.chomp.strip
458:         end
459: 
460:         # 拡張から有効か判定
461:         next unless /#{ext}$/i =~ item
462: 
463:         # headlimit から有効か判定
464:         if str_and_notspace?(headlimit) then
465:           if /^#{headlimit}(.+)$/ =~ item
466:             bodyname = $1
467:           else
468:             next
469:           end
470:         else
471:           bodyname = item
472:         end
473: 
474:         # imgfiles への格納
475:         #imgfiles.push( (File.basename(bodyname, ext) )  )
476:         imgfiles.push( bodyname )
477:       }
478:     }
479: 
480:     imgfiles = imgfiles.sort
481: 
482:     # infofile に書き込み
483:     ifile = open(infofile, "w")
484:     imgfiles.each{ |filename|
485:       ifile.print "#{filename}#{delimiter}#{delimiter}\n"
486:     }
487:     ifile.close
488: 
489:     return "create"
490:   end

引数 rd に与えられた文字列を rd2html を掛けた文字列として 返す。デフォルトでは "=begin" や "=end" が存在しない文字列を 想定している。この場合、rd 文字列を "=begin" と "=end" ではさまれたものとして自動的に解釈する。もしも "=begin" や "=end" が書き込まれた文字列を rd として与えたい場合は 引数 beginend を true にすること。返される html は <body> 以上と </body> 以下は省かれた本文部分のみである。

もしも rd2 コマンドが存在しない場合には nil を返す。

なお、現在は rd2html-ext-lib を必ず利用するようになっているので インスタンス変数 rd2htmlextlib を適宜設定しないとまともに 動かないので注意すること。

[Source]

      # File dcmodel-thum.rb, line 1096
1096:   def rd2html(rd=nil, beginend=nil, quiet=nil, err=nil)
1097:     debug(rd)
1098: 
1099:     if !(FileTest.executable?(@rd2_path)) then
1100:       return warn_or_err(
1101:                          "\"#{@rd2_path}\" is not excutable.\n",
1102:                          err, quiet, ArgumentError)
1103:     elsif !rd
1104:       return warn_or_err(
1105:                          "\"rd\" is invalid.\n",
1106:                          err, quiet, ArgumentError)
1107:     end
1108: 
1109:     debug(@rd2_path)
1110: 
1111:     # "=begin" や "=end" を消去するための処理
1112:     rd_body = ""
1113:     if beginend then
1114:       rd_parts = rd.split("\n")
1115:       debug(rd_parts)
1116:       rd_parts.each { |line|
1117:         if /\s*=begin\s+.*/ =~ line then
1118:           next
1119:         elsif /\s*=begin$/ =~ line then
1120:           next
1121:         elsif /\s*=end\s+.*/ =~ line then
1122:           next
1123:         elsif /\s*=end$/ =~ line then
1124:           next
1125:         else
1126:           rd_body << line + "\n"
1127:         end
1128:       }
1129:     else
1130:       rd_body = "#{rd}"
1131:     end
1132:     debug(rd_body)
1133: 
1134:     # rd で得られた文字列を /tmp/dcmodel-thum-$$.rd に一時的に格納
1135:     rdfile_tmp = @tmp + "/" + File.basename($0.to_s) + "-" + $$.to_s
1136:     debug(rdfile_tmp)
1137: 
1138:     tmpfile = open(rdfile_tmp, "w")
1139:     tmpfile.print "=begin\n"
1140:     tmpfile.print rd_body
1141:     tmpfile.print "\n=end\n"
1142:     tmpfile.close
1143: 
1144:     debug(open(rdfile_tmp){|io| io.read})
1145: #    print "#{open(rdfile_tmp){|io| io.read}}"
1146: 
1147: #    # ライブラリパスを $: に追加
1148: #    @rd2lib.each{ |path|
1149: #      next if !(str_and_notspace?(path))
1150: ##      $:.push(path)
1151: #      $:.unshift(path)
1152: #    }
1153: #    debug($:)
1154: 
1155:     #
1156:     # コマンドの文字列を整形
1157:     #
1158:     cmd  = "#{@rd2_path}"
1159:     cmd << " -r rd/rd2html-ext-lib"
1160:     cmd << " --with-css=#{@css}"
1161:     cmd << " --with-part=\'RT:rt\'"
1162:     cmd << " --with-part=\'HTML:html\'"
1163:     cmd << " --out-code=euc"
1164:     cmd << " --ref-extension"
1165:     cmd << " --native-inline"
1166:     cmd << " --head-element"
1167: #    cmd << " --headline-secno"
1168: #    cmd << " --enable-br"
1169: 
1170:     debug(cmd)
1171:     html_org = IO.popen("export RUBYLIB=#{@rd2htmlextlib} ; #{cmd} #{rdfile_tmp}").read
1172:     debug(html_org)
1173: 
1174:     html_body_each_line = html_org.split(/\n/)
1175:     debug(html_body_each_line)
1176: 
1177:     html_body = ""
1178:     bodyflag = false
1179:     html_body_each_line.each{ |line|
1180:       if /^.*<body.*$/ =~ line then
1181:         bodyflag  = true
1182:         next
1183:       elsif /^.*<\/body.*$/ =~ line
1184:         bodyflag  = false
1185:       else
1186:         html_body << line + "\n" if bodyflag
1187:       end
1188:     }
1189: 
1190:     # テンポラリファイルを削除
1191:     File.delete(rdfile_tmp)
1192: 
1193:     debug(html_body)
1194:     return html_body
1195:   end

target で与えられたパス (String オブジェクト) を from (String オブジェクト) から見た相対パスとして String オブジェクトで返す。 内部で Pathname クラスを利用している。 与えられるパスは絶対パスでも相対パスでもかまわない。

[Source]

      # File dcmodel-thum.rb, line 1203
1203:   def relative_str(target=nil, from=nil)
1204:     return nil    unless str_and_notspace?(target)
1205:     return target unless str_and_notspace?(from)
1206: 
1207:     from_dir     = File.dirname(from)
1208:     target_dir   = File.dirname(target)
1209:     target_base  = File.basename(target)
1210: 
1211:     from_ab_path   = Pathname.new(File.expand_path(from_dir))
1212:     target_ab_path = Pathname.new(File.expand_path(target_dir))
1213: 
1214:     target_re_path = target_ab_path.relative_path_from(from_ab_path)
1215: 
1216:     result = target_re_path.to_s + "/" + target_base
1217: 
1218:     return result
1219:   end

Private Instance methods

代入された変数が、配列で、且つゼロ配列ではないことを 調べるメソッド

[Source]

      # File dcmodel-thum.rb, line 1372
1372:   def array_and_notzero?(obj)
1373:     debug(obj)
1374: 
1375:     if obj.instance_of?(Array) && obj.size > 0 then
1376:       return true
1377:     else
1378:       return false
1379:     end
1380: 
1381:   end

デバッグ出力用メソッド。組み込み関数 $DEBUG が真の場合 (つまり、 プログラムを $ ruby -d ./xxxxxx.rb として呼び出した場合) に debug メソッドに代入された変数を出力する。

[Source]

     # File dcmodel-thum.rb, line 348
348:   def debug(*args)
349:     p [caller.first, *args] if $DEBUG
350:   end

代入された変数が、文字列で、且つ空白文字のみではないことを 調べるメソッド。日本語であっても、文字列が入っていれば true を返す。

[Source]

      # File dcmodel-thum.rb, line 1350
1350:   def str_and_notspace?(obj)
1351:     debug(obj)
1352: 
1353:     if !obj.instance_of?(String) then
1354:       return false
1355:     end
1356: 
1357:     # 日本語の文字列も対応できるように
1358:     Kconv::toeuc(obj)
1359: 
1360:     if /\w+/e =~ obj.chomp.strip then
1361:       return true
1362:     else
1363:       return false
1364:     end
1365:   end

引数 gid に対応するユーザ名 (ログイン名) を返す。 gid に nil を与えた場合はプロセスの gid に対応するユーザ名 (ログイン名) を返す。gid が無効なものである場合、エラーを返す。

[Source]

      # File dcmodel-thum.rb, line 1333
1333:   def username_from_gid(gid=nil)
1334:     unless gid
1335:       pw = Etc.getpwuid(Process.gid) or return nil
1336:     else
1337:       pw = Etc.getpwuid(gid) or return nil
1338:     end
1339: 
1340:     user_name = pw.name
1341:     return user_name
1342:   end

引数 uid に対応するユーザ名 (ログイン名) を返す。 uid に nil を与えた場合はプロセスの uid に対応するユーザ名 (ログイン名) を返す。uid が無効なものである場合、エラーを返す。

[Source]

      # File dcmodel-thum.rb, line 1316
1316:   def username_from_uid(uid=nil)
1317:     unless uid
1318:       pw = Etc.getpwuid(Process.uid) or return nil
1319:     else
1320:       pw = Etc.getpwuid(uid) or return nil
1321:     end
1322: 
1323:     user_name = pw.name
1324:     return user_name
1325:   end

警告またはエラー。 err が nil や false の場合、mes に与えられたメッセージを 警告として表示する。err が真の場合はそのメッセージの出力 と同時にエラーを発生させ、プログラムを終了させる。 errvar に変数を与えると、エラーの種類を指定できる。 quiet を true にすると、err が nil の場合、何も動作しなくなる。

[Source]

     # File dcmodel-thum.rb, line 361
361:   def warn_or_err(mes=nil, err=nil, quiet=nil, errvar=nil)
362:     return nil if !mes
363: 
364:     errvar = RuntimeError if !errvar
365: 
366:     if err then
367:       raise errvar, "Error: #{mes}"
368:     elsif !quiet
369:       $stdout.print "[#{caller.first}] \n     Warning: #{mes}"
370:       return nil
371:     end
372:   end

[Validate]