SmartDocを使う

トップページに戻る


SmatDocは浅海 智晴さんが開発したXMLをベースにしたドキュメント生成ツールです。SmartDoc形式(XML)で書いたドキュメントを、HTML、LaTeX、JavaHelpに変換することができます。

環境構築

インストール

SmartDocはJavaで書かれたプログラムなので、実行にあたってはSmartDocの他にJava実行環境が必要です。JavaはSun MicrosystemsのJavaサイトや各種雑誌・書籍付属CD-ROM等から入手してください。JavaWorld誌には大抵毎号載っています。

SmartDocの入手

SmartDocのホームページからダウンロードします。2007年6月9日現在、正式版としてはバージョン1.1が最新です。ベータ版としては1.2b-20070604が公開されています。メンテナンスはバグフィックスを含めて1.2bで実施されているので、1.2bを使用するのがよいかもしれません。
http://www.smartdoc.jp/

インストール手順については上記サイトを参照してください。

メーリングリスト

SmartDocのメーリングリストがあります。

http://www.asahi-net.or.jp/~DP8T-ASM/java/tools/SmartDoc/ml_ja.html

メーリングリストの過去ログと検索ができます。(2005年4月30日現在公開中断しているようです)

http://sdocusersj.ml.nemui.org/maillist.html

Windows+Meadow+Cygwin32上での環境構築Tips

起動用スクリプト

SmartDocをインストールすると、2つの起動用ファイルがbinディレクトリに生成されます。

  1. sdoc
  2. sdoc.bat

 1.はUNIXシェルスクリプトで、2.はWindowsバッチファイルです。Cygwin32環境ではシェルスクリプトを使用するので、UNIX用シェルスクリプトを使います。
 このsdocのあるディレクトリを環境変数PATHへ追加します。

Meadow上でsdoc編集モードおよびsdocコマンドを実行する

設定

<SmartDocインストールディレクトリ>/etcの下に、sdoc-mode.elとsdoc-helper.elがあるので、これをMeadowのlispディレクトリ(<meadow>/site-lisp等)にコピーします。

次に、拡張子.sdocを読み込んだら自動的にsdoc-modeになるように.emacsに設定を追加します。

    (setq auto-mode-alist
        (append '(("\\.sdoc$" . sdoc-mode)) auto-mode-alist))
    (setq sgml-quick-keys t)
    (autoload 'sdoc-mode "sdoc-mode" nil t)

この設定でEmacs上でファイルを編集しようとするときに、DTDのないwell-formedな場合にタグで属性を記述するためにダブルクォーテーション"をキー入力すると、&;qtに置き換わってしまいます。そこで、拡張子がxmlのファイルを編集するときにはダブルクォーテーションのキーバインドを無効にします。

    (add-hook 'sdoc-mode-hook
        (lambda ()
            (when (string-match "\\.sdoc$" (buffer-name))
                (local-unset-key "\""))))

SmartDocファイル保存時に、自動的に<date>タグの中に更新日時を展開できるようにMeadow(Emacs)のtime-stamp機能と組み合わせます。「Meadow-紹介マニアMoinMoin」ページで公開されていたものを追加したものです。(日時フォーマットで曜日を削除し、時刻帯を追加するよう修正)
上記のadd-hookと合わせて一つのlambda式で記載しています。

(add-hook 'sdoc-mode-hook
    (lambda ()
        (when (string-match "\\.sdoc$" (buffer-name))
            (local-unset-key "\""))
        ;; "<date></date>"の自動更新
        (set (make-local-variable 'time-stamp-start) "<date>")
        (set (make-local-variable 'time-stamp-end) "</date>")
        (set (make-local-variable 'time-stamp-format) "%04Y/%02m/%02d %02H:%02M:%02S %Z")
        (set (make-local-variable 'time-stamp-line-limit) 30)
        ;; auto time-stamp
        (add-hook 'local-write-file-hooks 'time-stamp)
        (auto-fill-mode)))

Meadow 3で、C-c C-c(sdoc-comile)実行時に、以下のエラーが発生しました。仮対処としてとりあえず上記add-hookの中に、(setq compilation-read-command nil) を追記して回避しました。

sdoc-compile-all: Symbol's value as variable is void: compilation-read-command
キーバインド
C-c C-c バッファのSmartDoc文書に対してsdocコマンド実行
C-u C-c C-c プレビュー。プレインテキストでフォーマットされる。
C-c C-k ? sdoc-kill-content
C-c C-s C-p SmatDoc文書の雛形を生成する
C-c C-s C-e ? sdoc-use-entities
C-c C-s C-r ? sdoc-make-table-records
C-c C-s C-a ? sdoc-insert-internal-link
C-c C-s C-t ? sdoc-auto-id-title

SmartDoc文書を書く

はじめてのSmartDoc文書(Meadow編)

ステップ1 雛型生成

Meadowでsdoc-modeの設定をしていると、簡単にとっつけます。まずMeadowで作成したい文書ファイル名を開きます。たとえば、how2smartdoc.sdocを作成するとします。

  1. C-x C-f でミニバッファにhow2smartdoc.sdocと入力、新規ファイル編集に入ります。このとき、SmartDocモードになっていることを確認します。
  2. C-c C-s C-pでまず雛型を生成します。このとき、ミニバッファにおいてlanguage, encoding, titleを聞いてくるので入力します。
    language : ja
    encoding : Shift_JIS
    title : How to write a SmartDoc document
    と入力すると、SmartDocのXML文書の雛型が生成されます。下線部が入力したものです。
    C-c C-pで生成される雛型
    <?xml version='1.0' encoding='Shift_JIS' ?>
    
    <doc xml:lang='ja'>
    <head>
    <title>How to write a SmartDoc document</title>
    </head>
    <body>
    
    </body>
    </doc>
  3. あとは、<head>部や<body>部に随時コンテンツを書き込んでいきます。

ステップ2 head部の記述

head部では、雛型で生成されるtitleのほか、author, date, hp, email, abstractが記述できます。ステップ1で作成された雛型に追加して記述します。下記の例ではhead部で記述できる要素を一通り指定してみましたが、必須ではないので書かない要素があってもOKです。

head部を記述してみる
<?xml version='1.0' encoding='Shift_JIS' ?>

<doc xml:lang='ja'>
<head>
<title>How to write a SmartDoc document</title>
<author>これがauthorの記述です</author>
<date>これがdateの記述です</date>
<hp>http://this.is.hp-element/</hp>
<email>this.is@email.element</email>
<abstract>
ここにabstractの記述を書いています。abstractなので、
すこし長い文章を書いてみますが、面白いことが浮かばないので、
つまらないことをつらつら書いているだけになってしまいました。
</abstract>
</head>
<body>

</body>
</doc>

ステップ3 HTMLの生成

ステップ2の段階で、いったんSmartDocによる文書生成を実行してみます。Meadow上から、C-c C-cと打ちます。すると、sdocが起動されます。誤りがなければ、実行後how2smartdoc.htmlというHTMLファイルが生成されます。オプション指定をしていないので、デフォルトのHTML4形式のファイルになっています。
注)Meadowを起動するとき、環境変数PATHにsdocのあるディレクトリを指定しておく必要があります。

ステップ4 body部の記述(その1)

では、body部の記述に移ります。body部の構造は、TeXやHTMLのように章構造が文章の基本構造になります。

SmartDocのタグ 意味
part
chapter
section
subsection  :
subsubsection  :

実際に記述してみます。

body部を記述してみる。(head部はステップ2と同じなので省略)
<body>
<part title="これはpart要素です">
body部は、章構成が基本となっています。
一番大きなレベルはpartとなります。
partの見出しは、partタグの属性titleで指定しています。
<chapter title="これはchapter要素です">
part部の1つ下に位置するのがchapterです。
chapterの見出しもtite属性で指定します。
<section title="これはsection要素です">
chapter部の1つ下に位置するのがsectionです。
sectionの見出しもtitle属性で指定します。
<subsection title="これはsubsection要素です">
sectionの下にはsubsectionがあります。見出しは同様title属性で指定します。
<subsubsection title="これはsubsubsection要素です">
subsectionの下にはsubsubsectionがあります。ふうっ。
見出しは同様title属性です。
</subsubsection>
</subsection>
</section>
</chapter>
</part>
<appendix title="これはappendixです">
appendixというのがあったので記述してみました。
</appendix>
<chapter title="これはpartの外側に置いたchapterです">
このように、partタグの中に入れずに独立してchapterを置くこともできます。
</chapter>
<section title="これはpart,chapterの外側に置いたsectionです">
sectionも独立して置いてみました。
</section>
<subsection title="これはpart,chapter,sectionの外側に置いたsubsectionです">
subsectionも同じように独立して置いてみました。
今回はこんなもんです。
</subsection>
</body>
</doc>

これを、HTML形式に変換してみます。前回はMeadow上からC-c C-cでHTML4形式に変換してみましたが、今度はHTML3形式とHTML4形式の両方を生成してみます。

表を書く

表の書き方は何通りかあります。

まず下記のような表を生成したいとします。

外宇宙定期便就航表
航路 便名 所属
ガニメデ49 GSL101 ガニメデ宇宙旅客輸送
タイタン221 FSS233 フェデレーションスペース

表の記述(その1)

最も簡単なのは、カンマ","で区切った形を使うものでしょう。

<table title="外宇宙定期便就航表">
<thead>
航路,便名,所属
</thead>
<tbody>
ガニメデ49,GSL101,ガニメデ宇宙旅客輸送
タイタン221,FSS233,フェデレーションスペース
</tbody>
</table>

これだと、タグをそれほど書かなくても簡単に表を記述することができます。ただし、表のセルを連結するといったことができません。

表の記述(その2)

正式な書き方。タグをいちいち書くのがその1に比べると大変です。

<table title="外宇宙定期便就航表">
<thead>
<tr>
 <th>航路</th>
 <th>便名</th>
 <th>所属</th>
</tr>
</thead>
<tbody>
<tr>
 <td>ガニメデ49</td>
 <td>GSL101</td>
 <td>ガニメデ宇宙旅客輸送</td>
</tr>
<tr>
 <td>タイタン221</td>
 <td>FSS233</td>
 <td>フェデレーションスペース</td>
</tr>
</tbody>
</table>

では、なぜこの書き方をするかというと、複数セルを連結したり、表の中で文字を左・右・中寄せしたりして、複雑な表設定をおこなうことができるからです。

表の記述(その3)

下記のように、セルが複数連結した表を作成する

外宇宙航行船型式と採用会社
型式 グレード 所属
ファサード アルファ マーシャルスペース
ベータ ガニメデ宇宙旅客輸送
メメント フェデレーションスペース

HTMLのタグと同様、<th><td>に属性rowspan, colspanを使用する。

<table title="外宇宙航行船型式と採用会社">
<thead>
<tr>
 <th>型式</th>
 <th>グレード</th>
 <th>所属</th>
</tr>
</thead>
<tbody>
<tr>
 <td rowspan="2">ファサード</td>
 <td>アルファ</td>
 <td>マーシャルスペース</td>
</tr>
<tr>
 <td>ベータ/td>
 <td>ガニメデ宇宙旅客輸送</td>
</tr>
<tr>
 <td colspan="2">メメント</td>
 <td>フェデレーションスペース</td>
</tr>
</tbody>
</table>

表の記述(その4)

表に注記書きを付け加えます。<tnote>タグを使います。<tnote>タグの中には、<ul>もしくは<dl>を記述することができます。

<table title="外宇宙定期便就航表">
<thead>
航路,便名,所属
</thead>
<tbody>
ガニメデ49,GSL101,ガニメデ宇宙旅客輸送
タイタン221,FSS233,フェデレーションスペース
</tbody>
<tnote>
<ul>
<li>航路は木星・土星系のみ表記</li>
<li>便名は太陽系惑星航行機関コードによる</li>
</tnote>
</table>

図を書く

文章中に挿入する図と、独立した図と2つがあります。

独立した図

ガニメデ宇宙旅客輸送社の昨年の輸送実績を<a href="fig:lastyear1"/>に示します。

<figure id="fig:lastyear1" src="images/lastyear1.png"
 title="図1.1-1 実績(1)"/>

リンク

文章中に、ハイパーリンクを記述することができます。リンクには、文書内の要素(図・表・各見出し等)と、文書外(WebのURL等)とがあります。

文書内リンク

参考にしたアイテムは<a href="#参考">参考の節</a>に示します。

<section title="参考">
参考として、・・・

リンク先文書内要素のタグのtitle属性に記述した文字列に#をつけて指定することができます。または、リンク先文書内要素のタグにid属性を指定すると、そのid属性に記述した文字列に#をつけて指定します。

文書外リンク

<a href="http://www.asahi-net.or.jp/~DP8T-ASM/java/tools/SmartDoc/index_ja.html">SmatDocのホームページ</a>

参考文献

参考文献名を記述する

文章中では、ハイパーリンクで文献名を指定します。文章の最後に<bibliography>で文献を列挙します。

惑星間航行における太陽風利用については、<a href="#bok:planetsPhysics">
惑星間力学と太陽風</a>に詳しく述べられている。
:
<bibliography>
<book id="bok:planetsPhysics">
<author>Dr. Pedro Zabinsky</author>
<title>惑星間力学と太陽風</title>
<publisher>太陽系科学出版</publisher>
<year>2031</year>
</book>
:
</bibliography>
</body>
</doc>

文献の<book>タグのid属性で名前にbok:と付けているのは便宜上です。

プログラムのソースコード

SmartDocはプログラムのソースを記述する専用のタグを持っています。

<program title="MyJavaHello.java">
<![CDATA[
public class MyJavaHello {
    public static void main(String[] args) {
        System.out.println("Hello, Java World!");
    }
}
]]>
</program>

CDATAで囲んでいるのは、XMLファイルでは'<'や'>'を使用することができないためです。

ソースコードを外部ファイルから取り込む

プログラムのソースは変更頻度が高いので、コピー&ペーストでSmartDoc文書に取り込むよりは、外部ファイルからSmartDocコンパイル時に取り込む方がスマートです。

<program title="MyJavaHello.java" src="src/MyJavaHello.java" />
外部ファイルからソースコードの一部を取り込む

ソースコードの中から関数部分だけをSmartDoc文書に取り込むこともできます。javasrcKeywordで指定した正規表現にマッチした行を切り出します。ただし、その行に開き中括弧('{')があるときは、対応する閉じ中括弧('}')までのブロックを切り出します。

<program title="MyJavaHelloのmainメソッド" javasrcKeyword="void main" src="src/MyJavaHello.java" />

Javaのソースコードに色づけをしたい

Javaのソースコードに文法に応じた色づけをして見やすくします。

<program title="HelloWorld.java" normalizer="javasrc"
  javasrcSyntaxHilight="true">
<![CDATA[
public class HelloWorld {
  :
} // HelloWorld
]]>

折り返し桁数

デフォルトは75桁で折り返す設定となっています。変更する場合は、programタグのprogramWidth属性で指定します。

コマンドの実行と結果(コンソール表示)

SmartDocは、コンソール画面でのコマンド入力と結果表示を表現する専用のタグを持っています。

<console title="文字コードを指定してコンパイル">
D:\work&gt; javac -encoding EUCJIS jp/gr/java_conf/torutk/hello/HelloWorld.java
Hello, world!
D:\work&gt;
</console>

ソースコードと同様表示内で'<'、'>'や'&'などを使用するときは、<![CDATA[ 〜 ]]>で囲むとよいでしょう。

自動折り返しと折り返し記号と折り返し桁数指定

デフォルトでは1行65文字で折り返す設定となっています。折り返し記号はデフォルトでは' \'です。

折り返し記号を変更する場合、consoleContSymbol属性で指定します。

折り返し桁数を変更する場合、consoleWitdh属性で指定します。

<console title="文字コードを指定してコンパイル" consoleWitdh="128" consoleContSymbol=" |">
D:\work&gt; javac -encoding EUCJIS jp/gr/java_conf/torutk/hello/HelloWorld.java
Hello, world!
D:\work&gt;
</console>
プロンプト行折り返し時のユーザー入力部分の強調表示が継続行に反映されない問題

最新ベータ版(2006年11月29日版)を含めて上記問題があります。2007年6月4日版で解決されました。

プロンプト行とユーザー入力部分の強調表示

SmartDocは、コンソール画面に関して文字列からプロンプトを識別し、プロンプトの後ろから改行までをユーザー入力文字と認識してタグ付け(強調表示)します。

プロンプトの識別は、デフォルトでは1行目の行頭から>までとなります。これを別なプロンプト記号に変更する場合は、以下のどちらかの属性で指定します。

consolePrompt属性
例えば、bash等で'$'をプロンプト記号に用いている場合、consolePrompt="$ "のように指定します。
consolePromptRegex属性
正規表現でプロンプトを指定する場合、consolePromptRegex="[^#]*# "のように指定します。

2行目以降にプロンプト行がある場合、以下の属性を指定します。

consolePromptRange属性
2行目以降にプロンプトがある場合、consolePromptRange="*"のように指定します。
<console title="文字コードを指定してコンパイル" consolePrompt="$ " consolePromptRange="*">
work$ javac -encoding EUCJIS jp/gr/java_conf/torutk/hello/HelloWorld.java
work$ java jp.gr.java_conf.torutk.hello.HelloWorld
Hello, world!
work$
</console>

SmartDocのTips

文書サイズが大きくなったので、複数ファイルに分割したい

たとえば、節(section)ごとに別々のファイルに記述して、それらをまとめて1つのコンテンツとして扱うとします。

bookreview.sdoc
     |
   +--- oointro.sdoc
bookreview.sdoc(body部のみ抜粋)
<body>
<chapter title="オブジェクト指向開発技術">
<section src="oointro.sdoc">
</section>
</chapter>
</body>

まず、sectionタグの属性を通常のtitleではなく、src属性を指定して値には独立させるファイル名を記述します。そして、そのままsectionタグを閉じます。

oointro.sdoc
<?xml version='1.0' encoding='Shift_JIS' ?>

<doc xml:lang='ja'>
<head>
<title>オブジェクト指向入門関連書籍</title>
<author>高橋 徹</author>
<hp>http://www.alles.or.jp/~torutk/</hp>
<email>torutk@alles.or.jp</email>
<date></date>
</head>
<body>

<subsection title="オブジェクト指向がわかる本">
<subsubsection title="概要">
これからオブジェクト指向に取り組む人に、オブジェクト指向の
基本的な考え方を統一的に理解してもらうことを狙いとした本。
</subsubsection>
</subsection>
</body>
</doc>

分割されるファイルは、それ自身で完結したSmartDoc文書として記述します。ここでポイントは、分割の単位がsectionであり、これは上位のファイルでタグを記述しているので、分割されるファイルではsectionタグは書かずにその下のタグ〔この例ではsubsection)から使います。また、sectionタグのtitle属性は上位のファイルでは省略されてましたが、統合されるときには分割された文書のtitle要素を使います。

本来1つのファイルで書く場合
<body>
<chapter title="オブジェクト指向開発技術">
<section title="オブジェクト指向入門関連書籍">
</section>
</chapter>
</body>

生成されるHTMLファイルを分割したい

ある程度大きな文書を書いていると、HTMLではファイルサイズが大きくなりすぎてブラウザでの閲覧に適さなくなってきます。そのときは、生成されるHTMLを複数に分割します。分割する単位は文章の見出しで指定できます。HTML4.0, HTML3.2, JavaHelpのページ分割が有効になります。

-splitオプション。-split:[part|chapter|section|subsection|subsubsection]

ヘッダ・フッダに指定したファイルを取りこみたい

ヘッダとフッダに指定したファイルを取り込みます。prologueはタイトルの下に入ります。

<head>
<header>
<native locale="ja" src="header_ja.html" format="html" />
<native locale="en" src="header_en.html" format="html" />
</header>
<prologue>
<native locale="ja" src="prologue_ja.html" format="html" />
<native locale="en" src="prologue_en.html" format="html" />
</prologue>
<footer>
<native locale="ja" src="footer_ja.html" format="html" />
<native locale="en" src="footer_en.html" format="html" />
</footer>
</head>

HTMLの見出しに通し番号を振りたい

見出しに番号を振っていきます。

-html4.numberedTitleオプション

前書き、謝辞、後書き、などには番号をつけないでおきたいところです。この場合、属性にsequencable="false"を指定しておきます。

<chapter title="謝辞" sequencable="false">
ありがとう
</chapter>
<chapter title="導入編">
ここには通し番号が付けられます。
</chapter>

PDFファイルを生成したい

SmartDoc文書は標準ではHTML3/HTML4/LaTeX/JavaHelp形式の出力を行います。この他、プレインテキスト形式とPureSmartDoc XML形式があります。PDFファイルを生成する場合は、このいずれかの形式からPDF形式に変換することになります。

  1. SDOC文書をLaTeX形式で出力後、TeX環境にてLaTeX形式からDVI形式に変換し、DVI形式からPDF形式に変換する。必要なツールとしては、SmartDoc、LaTeX環境、dvipdfm。
  2. SDOC文書をXML形式(PureSmartDoc)で出力後、Apache FOを用いてPDF形式に変換する。必要なツールとしては、SmartDoc、Apache FOPsdoc2fo.xslファイル。
  3. SDOC文書をXML形式(PureSmartDoc)で出力後、iTextを用いてPDF形式に変換する。必要なツールとしては、SmartDoc、iTextSdoc2PDF

現時点でもっとも安定しているのは、1.のLaTeX経由かと思います。

LaTeX経由のPDF

LaTeXの入手とインストール

インターネットには豊富な情報があります。

PDFでしおりを作る場合、以下の指定を行う。
format=latex2e
toc=true
latex2e.driver=dvipdfm
latex2e.ref=HyperRefLaTeX2eRefHandler

Adobe Reader 6.0(Windows)では、しおりの日本語が化けてしまいます。これは、しおりの日本語がUnicodeでないといけないためです。LaTeXの中にout2uniというコマンドがあるので、これを使用します。以下のURLに対処方法が載っていました。

画像ファイルはPNG形式にしておく

<figure>要素でGIF形式を読み込むように記述していると、LaTeX形式に変換後TeX処理系でエラーが発生します。PNG形式ならOKでした。

表の中に<pre>や<program>は入れられない?

TeX処理系でエラーとなってしまいます。

表がはみ出てしまう

デフォルトではTeXは表のセルの文章を改行なしに組み立てるので、表がページをはみ出てしまいます。そこで、以下のいくつかのTipsを組み合わせて対処します。

  1. <table>要素の属性styleに、"width:100%"のような指定を追加する。
    表示有効範囲のN%に収まるように縮小します。ただし、セルの文章が長いと虫眼鏡が欲しくなるような大きさとなってしまう
  2. <table>要素の中に<colgroup>要素で束ねた<col>要素のwidth属性で各カラムの幅を指定する。
    以下は、3つの列がある表において、1つ目の列が10文字幅、2つ目の列が20文字幅、3つ目は幅指定なしの例。
    <table title="エアロック型式表">
      <colgroups>
        <col width="10em"/>
        <col width="20em"/>
        <col />
      </colgroups>
      <thead>
        :
      </thead>
      <tbody>
        :
      </tbody>
    </table>
    追記)IE6.0では、emという単位での指定ができません。Mozilla 1.4ではOKですが。そこで、%で指定するほうがよさそうです。ただ、%指定の場合、合計100%となるように指定してもLaTeXでは右側がページぎりぎりまで膨らむので、合計90%位になるようにするのがよさそう。
bibliography要素は、body要素の中に置かないとTeX系で処理できない

ということです。

bibliographyを記述したsdoc文書のLaTeX経由での日本語しおり使用PDF作成手順
  1. SmartDoc文書をsdocコマンドでLaTeX2e形式に変換する
    $ sdoc sample.sdoc
  2. 1.で生成されたtex文書をplatexコマンドで処理する
    $ platex sample
  3. 1.で生成されたbib文書をjbibtexコマンドで処理する
    $ jbibtex sample
  4. 1.で生成されたtex文書をplatexコマンドでもう一回処理する
    $ platex sample
  5. 1.で生成されたtex文書をplatexコマンドでさらにもう一回処理する
    $ platex sample
  6. 1.で生成されたtex文書をout2uniコマンドで処理する(PDFの日本語しおり対処)
    $ out2uni sample
  7. 1.で生成されたtex文書をplatexコマンドで処理する
    $ platex sample
  8. 5.で生成されたdvi文書をdvipdfmコマンドでPDF形式に変換する
    $ dvipdfm sample

トップページに戻る