名前: nide 日時: 2003-01-20 15:18:25 IPアドレス: 160.11.72.*
>>15380 > 2つの DVI ファイルをくっつけるスクリプトは、面白そうだけれど、より難し > そう(必要に応じて、フォント番号をずらす必要があるので)。 面白そうなのでやってみました。但し、とりあえずは 入力DVIファイル全てのDVI id, DVI unit numerator/denominator, magnificationが一致している場合のみです。今回はGNU awk限定です。 下記のスクリプトがdvicat.awkだとして gawk -f dvicat.awk input1.dvi input2.dvi …(任意個) とすると、それらをくっつけたout.dvi(名前は固定。サンプル実装 なもんで)ができます。今回は内部でdvispcを自動的に呼び出します。 dvispcが異常終了したかどうかも(返り値で)ちゃんとチェックして います。 こういうものが数十行で書けてしまうわけですから、dvispcは結構便利 なツールだと思います。 ------------------------------------------------------------------------ BEGIN{ # GNU awk限定 (closeの返り値、delete arrayなど) for(i = 1; i < ARGC; i++){ # 全DVIファイル(のテキスト化)を読む incmd = "dvispc -a " ARGV[i] while(incmd | getline > 0) line[i, ++linec[i]] = $0 close_chk(incmd) } outcmd = "dvispc -x out.dvi" # outcmd = "cat" $0 = line[1, 1] # 最初のファイルのpre dvi_id = $2; dvi_info = $3 " " $4 " " $5 print $1 " " dvi_id " " dvi_info " 13 'dvicat output'" | outcmd for(i = 1; i < ARGC; i++){ # 各ファイルについて $0 = line[i, 1] # そのファイルのpre if($2 " " $3 " " $4 " " $5 != dvi_id " " dvi_info) info_diff_err() delete fntmap # フォント番号の新旧対応用配列 for(j = 2; (l = $0 = line[i, j]) !~ /^post\y/; j++){ if(/^fntdef/){ if(!($2 in fntdefs)){ # このfntdefは初登場 fntdefs[$2] = l } else if(fntdefs[$2] == l){ # このfntdefは前と同じ continue } else { # このfntdefは前と違う for(k = $2; k in fntdefs; k++); fntmap[$2] = k # フォント番号修正 $1 = "fntdef" fntdef_op(k); $2 = k l = fntdefs[$2] = $0 } } else if(sub(/^(fntnum|fnt%d )/, "")){ # $0が変わる if($1 in fntmap){ # フォント番号要修正 k = fntmap[$1] l = (k < 128) ? "fntnum"k : \ "fnt" fntdef_op(k) " " k } } print l | outcmd # DVIコマンド行を出力 } # 現在$0はそのファイルのpost if($3 " " $4 " " $5 != dvi_info) info_diff_err() if(maxh < $6) maxh = $6 if(maxw < $7) maxw = $7 if(maxstkdep < $8) maxstkdep = $8 totalpages += $9 # post_postのDVI_idもチェック $0 = line[i, linec[i]] if($3 != dvi_id) info_diff_err() } # 全体のpost以降を出力 print "post 0", dvi_info, maxh, maxw, maxstkdep, totalpages | outcmd for(i in fntdefs) print fntdefs[i] | outcmd print "post_post 0", dvi_id, "223 223 223 223" | outcmd close_chk(outcmd) } function fntdef_op(num){ return num < 256 ? 1 : num < 65536 ? 2 : num < 16777216 ? 3 : 4 } function info_diff_err(){ print "DVI information differs, can't treat these inputs" exit(1) } function close_chk(cmd){ # コマンドとのパイプのcloseのついでに返り値チェック if(close(cmd)){ printf "'%s' exited abnormally\n", cmd exit(1) } }
この書き込みへの返事: