DSSSLへの手引き


目次

はじめに ▼
 必要な知識 ▼
 必要なツールと資料 ▼
レッスン 1−最初の一歩 ▼
レッスン 2−余白の追加 ▼
レッスン 3 ▼
レッスン 4 ▼
レッスン 5−変数の追加 ▼
レッスン 6−異なる順序での要素の表示 ▼
レッスン 7−スタイルを用いて ▼
レッスン 8 ▼
レッスン 9−表の作成 ▼
おわりに ▼

はじめに

 Daniel M. Germán氏が著わした“A tutorial on DSSSL”の全訳を掲載します。この訳は1999年2月8日版に基づきます。訳の文責は岸 和孝にあります。この手引きは,DSSSLの具体的なスタイル指定をシェイクスピアの「ハムレット」を題材にしてケーススタディしたものです。この手引きを読む前に,Schemeの知識を必要としない,Paul Prescod氏が著したDSSSL入門(原題:Introduction to DSSSL)を読むことをお勧めします。

 著者Daniel M. Germán氏へ,この手引きの翻訳・掲載を快諾していただいたことに感謝します。

必要な知識

 この手引きを読むには,次の知識が必要です。

  • SGMLに関する基本的な知識。
  • Schemeに関する基本的な知識。

必要なツールと資料

 この手引きでケーススタディを行うには,次のツールと資料が必要です。

  • James Clark氏のJadeがあなたのマシンに適切にインストールされていること。Jadeはhttp://www.jclark.comからダウンロードできます。
  • 戯曲のための,Jon Bosak氏の文書型定義play.dtd
  • play.dtd(hamlet.xml)を用いてJon Bosak氏によってタグ付けされたシェイクスピアの「ハムレット」(hamlet.xml)。Jon Bosak氏によってタグ付けされた戯曲の他にも利用できます。
  • RTFブラウザー(Word,Word Viewer,または,RTFをインポートする,どんなワードプロセッサーもそれを行ないます)。
  • DSSSL標準規格書。

 この手引きの目的は,DSSSLの基本を紹介することです。私たちは(Jon Bosak氏から送られてきたplay.dslに基づいて)戯曲のためのDSSSLスタイルシートを作り上げます。

 あなたは,このケーススタディで使う文書型定義,スタイルシート,結果のRTFファイルを一括してtutorial.zipとしてダウンロードできます。

レッスン 1

最初の一歩

 私たちは,すでにSGMLファイルとそのDTDを持っています。最初のステップは,どんなフォーマットもなしに,戯曲のすべてのテキストをRTFファイルとして生成することです。

  • ソース:myplay01.dsl
  • 結 果:hamlet01.rtf

ソースの重要部分


 ; これは,特定のフォーマットなしに戯曲のテキストを出力します。
 (root
   (make simple-page-sequence
     (process-children)
   )
 )
 

ソースの説明

  • makeは,最初に指定されたメンバーがsimple-page-sequenceクラスの流し込みオブジェクト〔flow object〕である流し込みオブジェクト列指定〔sosofo〕を返却する手続きです。
  • simple-page-sequence流し込みオブジェクトは,ページ領域の列を生成します。
  • process-childrenは,現ノードの子供の処理の結果である流し込みオブジェクト列指定〔sosofo〕を返却します。

 RTFファイルは,文字列だけです。どんな余白〔margin〕もなく,どんな段落もありません。それはフォントファミリー,フォントサイズ,ページサイズなどについてJadeの省略時値を用います。

レッスン 2

余白の追加

  • ソース:myplay02.dsl
  • 結 果:hamlet02.rtf

ソースの重要部分

 
 (root
   (make simple-page-sequence
 ; 余白
     left-margin:   1in
     right-margin:  1in
     top-margin:    1in
     bottom-margin: 1in
     (process-children)
   )
 )
 

ソースの説明

  • これは,作られていたsofofoの特質〔characteristics〕のための値を指定します。
  • simple-page-sequence属性の完全なリストについては標準規格書12.6.3節を参照して下さい。
  • 単位がインチであることに注目して下さい。なお,それらは,cm,mm,m,pt,picaでも指定できます。

レッスン 3

 私たちは,SGMLファイルにおいて要素に出会うように,フォーマットを追加しながら,トップダウンで仕事をします。

  • ソース:myplay03.dsl
  • 結 果:hamlet03.rtf

ソースの重要部分

 
 (element (PLAY TITLE)       ; PLAYのTITLE
   (make paragraph
     quadding:     'center
     font-size:    18pt
     line-spacing: 18pt
     font-weight:  'bold
     keep-with-next?: #t
     (process-children)
   )
 )
 

ソースの説明

  • 最初の印刷可能な要素は,戯曲の表題です。文書型定義を見ると,TITLEが異なる要素の内側で生じうることに気付きます。したがって,それがTITLEの直接の子孫〔descendent〕である場合に,私たちは表題にだけ注目します。
  • (PLAY TITLE)は,この規則が前述した状況に適用することを指定します。
  • makeは,その場合においてクラスparagraphの流し込みオブジェクト列指定を作り出します。
  • 12.6.6節は,そのクラスで利用できる特質の記述を含みます。

レッスン 4

ソースの重要部分

 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; 重要なこと
 ;
 (element (FM)
   (make paragraph
     font-size:    8pt
     line-spacing: 8pt
 ; 左右の字下げ
     start-indent: 5cm
     end-indent:   5cm
 ; 直前の間隔
     space-before:.5cm
 ; 直後の間隔
     space-after: .5cm
     (process-children)
   )
 )
 

ソースの説明

  • この場合,FMについての定義が文脈に関係なく(前のレッスンと比較して)常に用いられます。
  • 左右の字下げ〔indentation〕,直前や直後の間隔開け〔spacing〕などの他の特質が用いられます。

レッスン 5

保守性〔maintainability〕を高めるための変数の追加

ソースの重要部分

 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; 定数の追加
 (define *titleFontSize*  18pt)
 (define *fmFontSize*     (/ *titleFontSize* 2))
 (define *fmIndent*       3cm)
 (define *fmSpaceBefore*  .5cm)
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; 戯曲の表題
 (element (PLAY TITLE)
   (make paragraph
     quadding:        'center
     font-size:       *titleFontSize*
     line-spacing:    *titleFontSize*
     font-weight:     'bold
     keep-with-next?: #t
     (process-children)
   )
 )
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; 重要なこと
 ;
 (element (FM)
   (make paragraph
     font-size:    *fmFontSize*
     line-spacing: *fmFontSize*
 ; 左右の字下げ
     start-indent: *fmIndent*
     end-indent:   *fmIndent*
 ; 直前の間隔
     space-before: *fmSpaceBefore*
 ; 直後の間隔
     space-after:  *fmSpaceBefore*
     (process-children)
   )
 )
 
  • 変数の宣言は,特質の値を変更することを容易にします。
  • 他のものに依存した値を計算するために,式を用いることができます。

レッスン 6

その出現と異なる順序での要素の表示

ソースの重要部分

 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; PERSONAE
 (element PERSONAE
   (process-children)
 )
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; PERSONA
 (element PERSONA            ; 登場人物
   (make paragraph
     space-before: *personaSpaceBefore*
     start-indent: *personaIndent*
     (process-children)
   )
 )
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; PERSONAEの内側のTITLE
 (element (PERSONAE TITLE)
   (make paragraph
     font-size:    *personaetitleFontSize*
     line-spacing: *personaetitleFontSize*
     font-weight:  'bold
     keep-with-next?: #t
     (process-children)
   )
 )
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; PGROUP
 ; PGROUPの最後にあって,_the beginning_で表示されるグループ
 ; の記述を私たちは得なければなりません
 (define (*groupName*)
 ; 最初に,変数xにGRPDESCR内容を設定します。
   (let
     (
       (x
         (data 
           (select-elements 
             (children 
               (if (equal? (gi) "PGROUP") (current-node) (ancestor "PGROUP"))
             )
             '(GRPDESCR)
           )
         )
       )
     )
 
 ; 変数xが“.”で終わる場合,後者を落とし,“:”を連結します。
     (string-append
       (if
         (string=? 
           (substring x (- (string-length x) 1) (string-length x))
              "."
         )
         (substring x 0 (- (string-length x) 1))
         x
       )
       ":"
     )
   )
 )

 (element PGROUP
   (make paragraph
     start-indent: *personaIndent* 
     space-before: *textSpaceBefore*
     font-weight:  'bold
     (literal (*groupName*))
     (process-children)
   )
 )
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; PGROUPの内側のPERSONA
 (element (PGROUP PERSONA )
   (make paragraph
     space-before: *personaSpaceBefore*
     start-indent: *pgroupIndent*
     font-weight:  #f
     (process-children)
   )
 )
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; GRPDESCR
 ; それは引き出されましたが,無視します。
 (element GRPDESCR
   (empty-sosofo)
 )
 
  • PERSONAE,PERSONA,PERSONAの内側のTITLEは,さらにそれ以上のどんな注釈も必要としません。
  • PGROUPの場合において,目的は,GRPDESCRをつかんで,そしてそのようなグループの内側にあるPERSONAのにそれを置くことです。
  • PGROUPを処理する時,GRPDESCR を引き出すために,その内容の中へ掘り進まなければなりません。
  • それを行うために,関数groupNameを用います。
  • GroupNameはGRPDESCRの内容をxへ割り当てます。 xが“.”で終わる場合,後者を落とし,“:”を付け加えます。
  • (私はそれを利用したいと思いますが,方法がまだ分かりません。)
  • その値は,手続きliteralの内側で用いられます。

レッスン 7

スタイルを用いて

ソースの重要部分

 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; Scndescr
 (define *sceneStyle*        ; すべての場面の記述のためのスタイル
   (style
     quadding:     'center
     font-size:    (+ *textFontSize* 4pt)
     line-spacing: *textFontSize*
     font-weight:  #f
     font-posture: 'italic
     start-indent: *sceneIndent*
     end-indent:   *sceneIndent*
   )
 )
 (element SCNDESCR
   (make paragraph
     use:          *sceneStyle*
     space-before: *sceneSpaceBefore*
     (process-children)
   )
 )
 
  • SCNDESCRで利用されたスタイル*sceneStyle*の定義に注目して下さい。

レッスン 8

ソースの重要部分

 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; STAGEDIR
 ;
 (element STAGEDIR               
   (make paragraph
     font-posture: 'italic
 ; それが行か発言の内側にあるならば,space-beforeを置かない。
 ; そうでなければ,ある間隔で飛ばします。
     space-before: (if 
                     (or
                       (equal? (gi (parent)) "LINE")
                       (equal? (gi (parent)) "SPEECH")
                     )
                     0pt
                     *textFontSize*
                  )
 ; 突然発言しないように囲みます。
     (literal "[")           
     (process-children)
     (literal "]")
   )
 )
 

レッスン 9

表の作成

ソースの重要部分

 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; SPEECH
 (element SPEECH                ; 1人以上の話し手による行の集合
   (make table                  ; 複数の話し手に適応するために表を用います。
     space-before: (/ *textFontSize* 2)
     may-violate-keep-after?: #t
     (make table-column       ; 話し手の欄が限られることを保証します。
       column-number: 1
       width: *speakerWidth*
     )
     (make table-cell         ; すべての話し手を集めます。
       (make paragraph
         (with-mode *speechSpeaker*
           (process-matching-children "SPEAKER")
         )
       )
     )
     (make table-cell         ; すべての行と指示を集めます。
       (process-children)
     )
   )
 )
 
 (mode *speechSpeaker*        ; 一つの欄の中にすべての話し手を集めます。
   (element SPEAKER           ; 複数であることを示すためにアンパサンドで分離します。
     (if
       (= (child-number) 1)
       (make sequence
         font-posture: 'italic
         (process-children)
       )
       (make sequence
         font-posture: 'italic
         (literal " & ")
         (process-children)
       )
     )
   )
   (default                   ; 安全装置−これを誘発してはいけません。
     (empty-sosofo)
   )
 )
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ; SPEAKER
 ; これはspeechSpeakerモードで注目したので,標準モードでは無視します。
 (element SPEAKER             ; これはモードだけで,誘発してはいけません。
   (empty-sosofo)
 )
 (element LINE                ; 与えられた話し手集合のためのすべての行
   (make paragraph
     (process-children)
   )
 )
 
  • クラスtableの使用に注目して下さい。各SPEECHについて表を作ります。最初の欄はSPEAKERと次の彼か彼女の行を含みます。
  • 最初の欄を満たすために,モード(*speechSpeaker*)を用います。このモードは,型 SPEAKERの子供要素〔children elements〕だけで利用されます。
  • SPEAKERは集められ,それらが一つ以上あるならば,“&”を挿入します。
  • SPEAKERが*speechSpeaker*の内側にあることに注目したので,process-childrenの処理中にそれを飛ばすためにempty-sosofoを用います。

おわりに

 DSSSLは複雑な言語です。私はその概要を簡単に述べただけです。この手引きを理解したからといって油断しないで下さい。その点で,何をなすべきかの印象を持つべきです。さらに,標準規格書をよく理解すべきです。

 成功を祈ります!

 この手引きへの批評があれば,どうかdmg@csg.uwaterloo.caへ送って下さい。

 © 1997 Daniel M. Germán

(1999年3月記)


(c)1999 JAGAT