Comments
Description
Transcript
印刷と配布という問題 FSWikiのPDF生成機能
11回 WikiとPDF 第 換について解説します.具体的な方法としてPerlやRubyなどの スクリプトを利用する方法などを取り上げます. TEXT 今回は「印刷」の観点からWikiをフォーカスし,Wiki→PDF変 竹添直樹(TAKEZOE Naoki) yomoyomo(YOMOYOMO) TEXT=NTTデータ先端技術㈱ 竹添直樹(TAKEZOE Naoki) 印刷と配布という問題 Wikiは,簡単な書式で記述されたプレーンテキス キュメントをWikiで記述しているケースもあります. トからHTMLを生成することができます.書式が Webでドキュメントを公開するだけであればこれ Wikiごとに異なるという問題はあるものの,いずれ でも良いのですが,実際の開発プロジェクトでは電 のWikiを利用する場合でもHTMLの複雑かつ冗長な 子データとして顧客に納品する必要がある場合も多 マークアップを意識せずに文章を記述できるので, いことと思います.Wikiのページに記述した内容を 書式に慣れさえすれば効率的に文章の入力が可能で 納品に適したファイル形式に変換することができれ す.インターネット上ではWikiのこういった特徴を ばWiki上でドキュメントの執筆を行うこともできる 活かし,情報サイトなどでWikiをCMSとして使った のではないでしょうか. り,ドキュメントをWikiで執筆したりするケースが 増えてきています. というわけで印刷と配布,この2つの問題をクリア する方法があれば業務でもよりWikiを活用することが 一方で,業務でWikiを利用することを考えた場合, できそうです.そこですぐに思い付くのは,何といっ 「印刷」と「配布」いう点が大きな問題になります. てもPDF(Portable Document Format)でしょう. 情報の電子化やペーパーレス化ということが言われ PDFについてはすでに皆さんもよくご存知かと思 はじめてずいぶん経ちますが,現在でもやはり紙と いますが,Adobeによって開発された電子文書のフ いう媒体は避けて通れないところがあります. ォーマットで,無償で提供されているAdobeReader もちろんWebブラウザからWikiページをそのまま を使用することで閲覧が可能です.PDFはOSや環境 印刷することは可能ですが,Webブラウザの印刷機 が異なっても元のドキュメントを正確に再現できる 能ではきれいな出力を得ることはなかなか難しいも ため,文書の印刷や配布に適したファイル形式とし のです.また,オープンソースプロジェクトではド て広く利用されています. FSWikiのPDF生成機能 筆者の開発しているFreeStyle Wiki(以下FSWiki, 能など独自の機能を搭載していました. http://fswiki.poi.jp/)はWikiのページをPDF Wikiの書式はHTMLと異なりますが,一定の書式 として出力することが可能です(図1).FSWikiは に従って記述されたテキストであることには変わり Perlによる高機能なWikiクローンですが,当初はオン ありません.Wikiエンジンはそれらの書式にしたが ラインでドキュメントを執筆するためのツールとし ってテキストを解析し,HTMLを生成しているわけ て開発されました.そのためテキストの装飾機能は です(図2).FSWikiでは解析部分はそのままで, 最低限に留める一方で,初期の段階からPDF生成機 HTMLを生成している部分だけを取り替えることが 104 - Software Design Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. 図1●●●FSWikiのPDF生成機能 PDFメニューを選択すると PDFとして出力 図2●●●WikiエンジンによるHTMLへの変換 図3●●●FSWikiでは生成部分を取り替えられるようになっている HTML HTMLに変換 Wikiページ 変換 HTML Wikiページ Wiki エンジン HTML ジェネレータ パーサ PDF ジェネレータ PDF PDFに変換 できるようになっており,これを利用してPDFの生 成を行っています(図3) . 大量のページを一括変換したい場合などに便利です. また,このスクリプトはローカルに存在するテキ なお,FSWikiではコマンドラインからWiki形式の ストファイルだけでなく,稼動しているFSWikiから テキストファイルをPDFやHTMLに変換するための ネットワーク経由でPDFやHTMLを生成することも FSWikiToolsというスクリプトも公開されています. 可能です. PDFJ FSWikiではPDFを生成するためにPDFJというラ イブラリを使用しています.PDFJは,中島靖氏によ ィレクトリ配下にあるモジュール群です.これらを @INCに含まれているパスに置いておけばOKです. って開発されている日本語PDFを生成するための なお,PDFJで欧文のハイフネーションを行う場合 Perlモジュールです.非常に扱いやすいAPIを備えて はTex::Hyphenモジュールが必要になります. おり,Perlスクリプトから簡単にPDFを作成するこ CPANからインストールするか,PDFJ同様アーカイ とができるのが特徴です. ブをダウンロードして展開しておきます. PDFJのインストール●●● ●●● PDFを生成してみよう●●● ●●● PDFJはPure Perlなモジュールなので,とくに難 では,さっそくPDFJを使用して簡単なPDFを生成 しいインストール作業は必要ありません.http:// してみましょう.ソースコードはリスト1,生成され hp1.jonex.ne.jp/˜nakajima.yasushi/から最新 たPDFは図4のようになります.なお,このスクリプ 版のアーカイブを取得し,適当なディレクトリに展 トはPDFJの最新の安定版であるPDFJ-0.88で動作 開します.PDFJを自分のPerlスクリプトから使用す 確認を行っています. る際に最低限必要になるのはPDFJ.pmと,PDFJデ PDFJではPDFJ::Docオブジェクトを基点に段落や Jun. 2006 - 105 Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. リスト1●●●PDFJを使用してPDFを生成するPerlスクリプト 図4●●●PDFJを利用して出力したPDF use strict; use PDFJ qw(EUC); # 用紙のサイズ(A4)と余白 my $width = 595; my $height = 842; my $margin = 72; # 表示領域のサイズ(用紙サイズから両端の余白を引いたもの) my $display_width = $width - $margin * 2; my $display_height = $height - $margin * 2; 図5●●●画像を埋め込んだPDF # 文書オブジェクトを作成 my $doc = PDFJ::Doc->new(1.2, $width, $height); # 使用するフォント my $font = $doc->new_font('Ryumin-Light', 'EUC-H', 'Times-Roman'); # フォントサイズ=20の段落を作成 my $para1 = Paragraph( Text("PDFJでPDF生成", TStyle(font => $font, fontsize => 20)), PStyle(size => $display_width, align => 'w', linefeed => 20) ); # フォントサイズ=10の段落を作成 my $para2 = Paragraph( Text("PDFJを使うと簡単にPDFを生成することができます。", TStyle(font => $font, fontsize => 10)), PStyle(size => $display_width, align => 'w', linefeed => 20) ); # 2つの段落を含むブロックを作成 my $block = Block('V', $para1, $para2, BStyle(align => 'c')); # 文書に新しいページを作成しブロックを表示 my $page = $doc->new_page; $block->show($page, $margin, $height - $margin); # ファイルに保存 $doc->print('sample_1.pdf'); 表1●●●PDFJで表示可能なオブジェクト 名前 テキスト クラス名 PDFJ::Text 段落 画像 PDFJ::Paragraph PDFJ::Image 図形 PDFJ::Shape ブロック PDFJ::Block リスト2●●●JPEG画像の表示 # フォントサイズ=20の段落を作成 my $para1 = Paragraph( Text("JPEG画像を表示", TStyle(font => $font, fontsize => 20)), PStyle(size => $width - $margin * 2, align => 'w', linefeed => 20) ); # 埋め込む画像ファイル名 my $image_file = 'fswiki.jpg'; # Imageオブジェクトを作成 my $img = $doc->new_image( 'fswiki.jpg', # 画像ファイル名 178, 60, # 画像のサイズ 178, 60, # 表示するサイズ 0); # マージン # 2つの段落を含むブロックを作成 my $block = Block('V', $para1, $img, BStyle(align => 'c')); # 文書に新しいページを作成しブロックを表示 my $page = $doc->new_page; $block->show($page, $margin, $height - $margin); 説明 文字列を表示するためのオブジェクト.Textオブジェクト自体には行の折り返し機能は なく,Paragraphオブジェクトに格納することで折り返しを行うことができる テキストに対して行の長さ,行送り,配置等を指定して1つの段落として表示するもの 画像を表示するためのオブジェクト.JPEG形式のみサポートしており,表示サイズ を指定することができる 直線,矩形,多角形,円,楕円,ベジェ曲線を組み合わせて図形を作成する.図形内に文字 を表示することもできる 表示可能なオブジェクトを並べて表示するためのコンテナ.1方向に並べる配列ブロック,縦横に 並べる行列ブロック,木構造のツリーブロックがあり,ブロックを入れ子にすることもできる テキスト,イメージといったオブジェクトを追加して みましょう.ソースコードはリスト2,生成された いくことでPDFを構築していきます.PDFJで表示可 PDFは図5のようになります.PDFJではJPEG形式 能なオブジェクトには表1のようなものがあります. の画像のみサポートされています.ここではローカ この他にもテキストや段落の書式を指定するため のオブジェクトや,入力フォームを表示するための オブジェクトが用意されています. ルに存在するファイルを指定していますが,URLで アクセス可能な画像を指定することも可能です. ローカルファイルを指定した場合はPDF内に画像 データが埋め込まれますが,URLを指定した場合は 画像の埋め込み●●● ●●● 少し高度な例として,PDFにイメージを表示して 画像データの埋め込みは行われず,閲覧時にURLに アクセスします.そのためサーバ上の画像ファイル 106 - Software Design Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. が削除されてしまった場合や,ネットワークに接続 ています.自動的に改ページを行う例をリスト3に していないマシンでPDFを閲覧した場合など,画像 示します. が表示されない場合もあります. このようにPDFJを使うと,Perlスクリプトから比 較的容易にPDFを生成することができます.PDFJに 改ページの処理●●● ●●● PDFJでは改ページを行うためにはスクリプト中で my $page = $doc->new_page; として新しいページを追加しなければなりません.し 関するより詳細な情報は,PDFJのマニュアル (http://hp1.jonex.ne.jp/˜nakajima.yasushi/ PDFJ.jp.html)を参照してください. XPDFJ かし帳票などのように予めサイズが決まったものなら PDFJにはXML形式で記述された原稿からPDFを ばいざ知らず,Wikiページやドキュメントなどのよう 生成することのできるXPDFJというモジュールも付 に何行あるかわからない文章をPDF化する場合に, 属しています.HTMLタグに近いタグを定義したマ プログラムでフォントサイズと用紙のサイズを計算し クロが用意されていますので,PDFJのAPIを覚えな ながら改ページを行うのは至難の業です. くてもPDFを生成することができます.興味のある PDFJでは,ブロックや段落がページ内に収まら 方はぜひお試しください.なお,XPDFJの利用にあ ない場合に自動的に改ページを行う機能が用意され たってはXML::Parserモジュールが必要になります. Perl以外の言語でのPDF生成 FSWikiはPerlで記述されていることもあり, ロードページ(http://www.pdflib.com/jp/ PDFを生成するためのライブラリとしてPDFJを使 products/pdflib/download/)からRuby用のアー 用していますが,もちろん他の言語向けにもPDF カイブを取得します. を生成するためのライブラリが存在します.ここで は代表的なPDF生成ライブラリとしてPDFlibと ¡PDFlib-6.0.3-Windows-Ruby.zip(Windowsの場合) ¡PDFlib-6.0.3-Linux-Ruby.tar.gz(Linuxの場合) iTextを紹介します. ダウンロードしたアーカイブを展開し,bind/ruby ●●● RubyでPDF●●● ディレクトリにあるPDFlib.soをRubyスクリプトか RubyではPDFlib(http://www.pdflib.com/jp/) ら参照できるできる場所にコピーしておきます(ス というライブラリを使用することができます. クリプトと同じ場所に置いておけばOKです).リス PDFlibはC,C++,Java,Perl,PHP,Pythonな ト4はPDFlibを使用したRubyスクリプトの例です. ど非常に多くの言語に対応したPDF生成ライブラリ 生成されたPDFは図6のようになります. で,最近になってRubyもサポートされるようになり ここではPDFlibをRubyから使用する例を挙げまし ました.非商用での利用であれば,生成されたPDF たが,他の言語から利用する場合でも概ね同じよう にロゴが入るものの無料で利用することができます. な感覚で扱うことができます. 商用利用の場合はライセンスの購入(1CPUあたり7 万3,500円)が必要になります. RubyからPDFlibを使用するには,PDFlibのダウン なお,Rubyに関してはPDF::Writer (http://ruby-pdf.rubyforge.org/pdf-writer/) というオープンソースのPDF生成ライブラリも存在 します.そのままでは日本語を扱うことができませ リスト3●●●改ページの例 my $block = Block('V', @paras, BStyle(align => 'c')); for my $part ($block->break($display_height)){ my $page = $doc->new_page; $part->show($page, $margin, $height - $margin); } んが,中村のりつぐ氏によるパッチ(http:// blade.nagaokaut.ac.jp/cgi-bin/ scat.rb/ruby/ruby-list/41372)を適用すること で日本語の表示が可能になります. Jun. 2006 - 107 Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. リスト4●●●PDFlibを使用してPDFを生成するRubyスクリプト リスト5●●●iTextを使用してPDFを生成するJavaプログラム require 'PDFlib' import java.io.FileOutputStream; begin # A4サイズ width = 595 height = 842 margin = 72 import com.lowagie.text.Document; import com.lowagie.text.Font; import com.lowagie.text.PageSize; import com.lowagie.text.Paragraph; import com.lowagie.text.pdf.BaseFont; import com.lowagie.text.pdf.PdfWriter; p = PDFlib.new # ドキュメントの開始 if (p.begin_document("sample.pdf", "") == -1) raise "Error: " + p.get_errmsg end p.begin_page_ext(width, height, "") font = p.load_font("HeiseiMin-W3", "EUC-H", "") # フォントサイズ=20 p.setfont(font, 20) p.set_text_pos(margin, height - margin) p.show("PDFlibでPDFを生成") # フォントサイズ=10 p.setfont(font, 10) p.continue_text("PDFlibはC, C++, Java, PHP, Perl, Ruby等、様々な言語に対応しています。") p.continue_text "このPDFはRubyスクリプトから出力されたものです。" p.end_page_ext("") p.end_document("") public class ITextExample { public static void main(String[] args) throws Exception { // A4サイズの文書オブジェクトを作成 Document doc = new Document(PageSize.A4); PdfWriter.getInstance(doc, new FileOutputStream("sample.pdf")); // 出力開始 doc.open(); // 日本語フォントの設定 BaseFont bf = BaseFont.createFont("HeiseiMin-W3", "UniJIS-UCS2-HW-H",false); // 大きなフォントで段落を追加 Paragraph para1 = new Paragraph("iTextでPDF生成",new Font(bf, 20)); doc.add(para1); // 小さなフォントで段落を追加 Paragraph para2 = new Paragraph( "iTextはオープンソースのJava用PDF生成ライブラリです。\n"+ "シンプルなAPIで扱いやすいのが特徴です。", new Font(bf, 10)); doc.add(para2); // 出力終了 doc.close(); } } rescue Exception => e print e.backtrace.join("\n") + "\n" + e.to_s end 図6●●●PDFlibを利用して出力したPDF 図7●●●iTextを利用して出力したPDF Documentオブジェクトに対してさまざまなオブジ ●●● JavaでPDF●●● iTextは,Javaで利用可能なオープンソース ェクトを追加していきます.iTextの場合は Documentオブジェクトに段落を追加していくと, (MPLおよびLGPL)のPDF生成ライブラリで ページに収まりきらなくなった時点で自動的に改ペ す..NET Framework版(http://www.ujihara. ージされます.APIもシンプルで使いやすい印象を受 jp/iTextdotNET/ja/)も存在します. けます. http://sourceforge.net/project/show これらのライブラリを利用することで,FSWiki以 files.php?group_id=15255から次の2つのファイ 外のWikiにもPDF生成機能を組み込むことができる ルをダウンロードし,クラスパスに含めておきます. かもしれません.もし既存のWikiへの組み込みが難 ¡itext-1.4.jar ¡iTextAsian.jar(日本語を扱う場合に必要) しい場合でも,多くのWikiではページの内容をテキ ストファイルで管理していますから,外部ツールと して変換処理を行うスクリプトを記述すればWikiペ リスト5はiTextを使用して簡単なPDFを生成する 例です.生成されたPDFは図7のようになります. 処理の基本的な流れはPDFJの場合と同じで, ージをPDFに変換することが可能でしょう.Wikiの 書式はシンプルなので,解析そのものは難しいこと ではありません. 108 - Software Design Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. PDFを生成するもう1つのアプローチ さて,FSWikiでは自前でPDF生成機能を提供し アプリケーションの印刷ダイアログでプリンタと ていますが,WikiのページをPDF化するための方 してPrimoPDFを指定すると印刷内容がPDFとし 法としては別のアプローチもあります.それはプリ て保存されます(図9) .保存先の指定時にPDFの ンタドライバとして動作するタイプのPDF生成コ プロパティや閲覧に必要なパスワードなどを指定す ンバータを利用する方法です.Windows環境で無 ることも可能です. 償で利用可能なソフトウェアとしては次のようなも のがあります. ¡CutePDF Writer (http://www.acrosoftware.com/products/cutepdf/Writer.asp) ¡PrimoPDF(http://www.primopdf.com/) ¡クセロPDF(http://xelo.jp/xelopdf/) FSWikiのPDF生成機能にはプラグインが出力し た内容のうち,一部をPDF化できないといった制 約がありますが,プリンタドライバ方式であれば Webブラウザで表示している内容をそのままPDF 化することが可能になります.しかし,きちんとし た出力を得るには,CSSなどを工夫して印刷に適 した表示になるよう工夫しておく必要があります. 本稿ではPrimoPDFを試してみることにします. インストールは,Webサイトからダウンロードした インストーラを実行するだけですが,今回試した PrimoPDF 2.0では,そのままでは日本語が文字化 けしてしまうので,初期設定を行う必要があります. ①スタートメニューから「プリンタとFAX」を選択 ②「PrimoPDF」というプリンタが追加されている ので右クリックして「プロパティ」を選択 ③プロパティダイアログが表示されるので「全般」 タブの「印刷設定」をクリック ④印刷設定ダイアログが表示されるので「レイア ウト」タブの「詳細設定」をクリック ⑤詳細オプションダイアログが表示されるので一番 下の「PostScript Options」の中の「TrueType Font Download Option」を「Outline」に変更(図8) 図8●●●PrimoPDFの詳細オプション ●●● CSSの利用●●● CSSではメディアタイプによってスタイルを切 り替えることができます. たとえばFSWikiでは,リスト6のようなCSSに よって印刷時はサイドバーやメニューを非表示にす るといった制御が可能になります.このCSSによ って図10のようなページが印刷時には図11のよう になります.これはPDFに出力する場合だけでな く,Webブラウザの印刷機能で直接紙に印刷した 場合にも有効です. ただし,プリンタドライバ方式のPDF生成ソフ トウェアはあくまで印刷イメージをそのままPDF に落とすだけなので,ページ中に含まれているリン クなどは欠落してしまいますし,見出しに対するし おりも作成されません.また,PDF上でテキスト 図9●●●印刷ダイアログでPrimoPDFを選択 Jun. 2006 - 109 Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. 図10●●●Webブラウザで閲覧している場合 検索やテキスト選択ができない場合もあります.ド キュメントをPDF化するという手段としてはやや 力不足と言えるかもしれません. リスト6●●●印刷時のCSSの例 @media print { div.sidebar { display: none; } div.main { margin-left: 0px; } div.adminmenu { display: none; } 図11●●●印刷プレビュー(CSSによって不要な部分が非 表示になっている) div.footer { display: none; } h1 { display: none; } div.header { display: none; } div.comment { display: none; } } PDF以外のフォーマットへの変換 もちろんコードさえ書けばWikiのページをPDF 図12●●●Wordの作成結果 以外のフォーマットへ変換することも可能です.た とえば,ActivePerlであればWindowsのOLEを利 用することができますから,Microsoft Wordのフ ァイルに変換するということも考えられるでしょう (顧客にWikiで執筆したドキュメントを納品する場 合はPDFよりもWord形式のほうが望ましいことも あるかもしれません) . 参考までにActivePerlでWordファイルを生成す る例を稿末のリスト7に,生成されたWordファイ ルを図12に示しておきます. おわりに WikiページをPDFやWordといった形式のドキュ メントに変換することでWikiの活用の幅がより広が ることは間違いありません.まずはFSWikiのPDF 生成機能に触れてみてください.s 110 - Software Design Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd. リスト7●●●Win32::OLEを使用してWordファイルを生成するPerlスクリプト use strict; use Win32::OLE qw(in with); use Win32::OLE::Const 'Microsoft Word'; my $word = Win32::OLE->new('Word.Application', 'Quit'); my $doc = $word->Documents->Add; my $sel = $word->Selection; # フォントを大きくしてセンタリング $sel->Font->{Size} = 20; $sel->ParagraphFormat->{Alignment} = 1; $sel->TypeText('Hello Word!'); # 改行を2つ挿入 $sel->TypeParagraph; $sel->TypeParagraph; # センタリングとフォントの大きさを元に戻してイタリックにする $sel->ParagraphFormat->{Alignment} = 0; $sel->Font->{Size} = 10; $sel->Font->{Italic} = 1; $sel->TypeText('Win32::OLEモジュールを使用してWordファイルを生成するサンプルです。'); # 保存して終了 $doc->SaveAs('C:\test.doc'); $word->Quit(); yomoyomoのWikiばなし TEXT yomoyomo 第11回 Wiki的オープンソース情報共有サイトSWiK 2005年夏にSourceLabsが始めた,オープンソ てもその状況に何ら変わりはありません.日本発の ースプロジェクトの情 報 共 有 サイトS W i K Wikiエンジンの海外への輸出(http://wikibana. (http://swik.net/)が,とくに2006年に入りト socoda.net/wiki.cgi?Wiki%be%ae%cf%c3 ラフィックを伸ばしています.この種のコミュニティ %2fVol%2e6)を考えた場合,これは由々しき事 サイトはすでにいくつもありますが,SWiKはWeb 態と言えます.海外における普及を目指すWikiエン サイトの外観が今風なだけでなく,タグ付けに対応し ジンの開発者,コミュニティメンバには,最低限の英 ておりFreshmeatといった既存サービスと比べ検索 語ページを揃えるとともに,SWiKにページを作られ 性に優れています. ることをお勧めします. そして何より, 誰でも情報を追加, 編集できる SWiKは“The Open Source Wiki”を自称 Wiki的機能が,他の同種のサイトと差別化していま していますが,筆者はこのWebサイトをWikiと呼ぶ す.しかもSWiKでは入力項目が固定化されており, ことに少しためらいを感じます.その一番の理由は, 参加の敷居が低いのも利点と言えます. 先に利点として挙げた入力項目の固定化にあるので しかし残念なことに,日本人が主要な開発者であ るオープンソースソフトウェアに関して言うと,SWiK すが,その功罪については本連載の最終回となる次 回で触れたいと思います. に登録されている数は少なく,Wikiエンジンに限っ Jun. 2006 - 111 Reprint without permission prohibition Copyright (c) 2005-2006 All Rights Reserved by Gijutsu-Hyohron Co., Ltd.