5.3.4. スクリプトの作成

 スクリプトの作成方法を、具体例を使って説明します。

(a) ページレイアウト

 簡単なページレイアウトを表現するには、simple−page−sequence(単純ページ)流し込みオブジェクトクラスを使います。表紙と本文とは別のページレイアウトにするため、要素frontとbodyそれぞれに対してsimple−page−sequenceのmake式を記述します。

<表紙のページレイアウト>

 まず、frontのsimple−page−sequenceのmake式を作ります。simple−page−sequenceの特質では、用紙サイズ、余白、ヘッダ・フッタを指定することができます。
 例の文書の表記方向は横書きです。表記方向は特質writing−mode:によって指定することができます。
 writing−mode:のデフォルト値はleft−to−right(横書き)なので、この場合は指定する必要はありません。用紙サイズはA4とします。A4の幅と高さは、使いやすいように冒頭で*a4−height*と*a4−width*として定義しておきます。

(define *a4−width* 210mm)
(define *a4−height* 297mm)

 定義した*a4−height*と*a4−width*を特質page−height:とpage−width:に指定します。表紙の左右の余白は3cmなので、特質left−margin:とright−margin:に3cmを指定します。上下の余白は5cmなので、特質top−margin:とbottom−margin:に5cmを指定します。

(element front
  (make simple−page−sequence
        page−height: *a4−height*
        page−width: *a4−width*
        left−margin: 3cm
        right−margin: 3cm
        top−margin: 5cm
        bottom−margin: 5cm

<本文のページレイアウト>

 次に、bodyのsimple−page−sequenceのmake式を作ります。用紙サイズは表紙と同じです。本文ページの上下左右の余白は3cmなので、left−margin: 、right−margin:、top−margin: 、bottom−margin:にそれぞれ3cmを指定します。フッタの中央部分にページ番号を表示するため、特質center−footer:にページ番号を返すプロシージャ(page−number−sosofo)を指定します。また、footer−margin:でフッタの下の余白を指定します。

(element body
  (make simple−page−sequence
        page−height: *a4−height*
        page−width: *a4−width*
        left−margin: 3cm
        right−margin: 3cm
        bottom−margin: 3cm
        top−margin: 3cm
        footer−margin: 1cm
        center−footer: (page−number−sosofo)
        (process−children)))

<sequenceの使い方1>

 表紙と本文を1つの文書として扱うため、frontとbodyから作られるsimple−page−sequenceを1つのオブジェクトとしてまとめます。これにはsequence(列)流し込みオブジェクトクラスを使います。frontとbodyの上位要素reportの構成規則で、sequenceのmake式を記述します。プロシージャ(process−matching−children)を使ってfrontとbodyから作られるオブジェクトをsequenceの内容に指定します。

(element report
  (make sequence
        (process−matching−children "front")
        (process−matching−children "body")))

<sequenceの使い方2>

 表紙の内容であるタイトル、著者、日付の3つは、配置を中央揃えにし、フォントファミリーを明朝体にします。このように共通のスタイル指定項目を持つ複数の要素には、sequenceを使って特質を一括して指定することができます。
 title、author、dateの親要素frontに対してsequenceのmake式を記述します。frontに対してはすでにsimple−page−sequenceのmake式を記述してあるので、この中にさらにsequenceのmake式を記述します。ここで特質font−family−name:とquadding:を指定します。この値は、frontの子孫の要素すべてに継承されます。

(element front
  (make simple−page−sequence
        page−height: *a4−height*
        page−width: *a4−width*
        left−margin: 3cm
        right−margin: 3cm
        top−margin: 3cm
        bottom−margin: 3cm
        (make sequence
        font−family−name: "Ryumin Light"
        quadding: ’center)))

(b) テキストのスタイル指定

 paragraph(段落)流し込みオブジェクトクラスはどんな文書にも必ずといっていいほど使われます。文字列で構成されている要素はparagraphを使ってフォーマットします。paragraphは、テキスト(文字列)に対する組版指定を表現します。これは組版指定の中でも最も基本的なものです。テキストのスタイル指定に使う特質は以下の通りです。

font−family−name:         フォントファミリー名
font−size:                フォントサイズ
line−spacing:             行送り量(font−size:の1.5~2倍が適当)
font−weight:              フォントの太さ
quadding:                 行の揃え方
first−line−start−indent:  段落の第1行の行頭インデント量

 要素title、name、position、year、month、day、ctitle、sectitle、para、item、ftitle、 ttitle、cellは PCDATAを内容とします。これらはすべてparagraphのmake式を記述してフォーマットします。

<表紙の中の要素>

 表紙の中の要素title、name、position、year、month、dayから作るparagraphオブジェクトには、frontのsequenceによって一括指定した特質値が使われます。これについては「sequenceの使い方2」で説明しました。この値は、それぞれのparagraphのmake式で別の値を指定すれば上書きできます。

<タイトル>

 タイトルのスタイル指定項目は前余白5cm、フォントサイズ24pt、太字です。これは特質space−before:、font−size:、font−weight:を使って指定します。line−spacing:はfont−size: の値の1.5倍にします。

(element title
  (make paragraph
        space−before: 5cm
        font−size: 24pt
        line−spacing: 36pt
        font−weight: ’bold))

<著者>

 nameとpositionは、親要素authorでsequenceのmake式を記述し、まとめてフォントサイズと行送り量を指定します。space−before:は継承されない特質なので、それぞれのparagraphのmake式で指定します。

(element author
  (make sequence
        font−size: 16pt
        line−spacing: 24pt))

(element name
  (make paragraph
        space−before: 2cm))

(element position
  (make paragraph
        space−before: 1cm))

<日付>

 year、month、dayは個別の要素ですが、「○年○月○日」と表示するために1つのparagraphオブジェクトにします。この3つの親要素dateの構成規則でparagraphのmake式を記述しますが、その内容を、プロシージャ(process−matching−children)を使って、year、month、dayとします。そして、yearの後に「年」、monthの後に「月」、dayの後に「日」という文字列のオブジェクトをプロシージャ(literal)によって作ります。

(element date
  (make paragraph
        space−before: 1cm
        font−size: 16pt
        (process−matching−children "year")
        (literal "年")
        (process−matching−children "month")
        (literal "月")
        (process−matching−children "day")
        (literal "日")))

<本文の中の要素>

 本文の中の要素ctitle、sectitle、para、item、ftitle、ttitle、cellに対しても、sequenceを使って特質を一括指定します。上位要素chapterでsequenceのmake式を記述し、font−family−name:を”Ryumin Light”と指定します。

(element chapter
  (make sequence
        font−family−name: "Ryumin Light"))

<章見出し>

 章見出しは、前後の余白を1cmずつとるため、特質space−before:とspace−after:を1cmと指定します。font−size:、line−spaceing:、font−weight:、quadding:もスタイル指定項目にしたがって指定します。 章を新しいページから開始するには、break−before:に’pageを指定します。これにより章見出しの前で常に改ページが行われます。

(element ctitle
  (make paragraph
        break−before: ’page
        space−before: 1cm
        space−after: 1cm
        font−size: 18pt
        line−spacing: 27pt
        font−weight: ’bold
        quadding: ’start
        (literal (number−>string (ancestor−child−number "chapter")) " ")
        (process−children)))

 章見出しでは章のタイトルに章番号をつけて表示します。章番号は、ctitleの上位要素chapterの通し番号なので、プロシージャ(ancestor−child−number)でchapterの要素番号を求めます。この数をプロシージャ(number−>string)で文字列に変換します。プロシージャ(literal)でこの章番号と” “の空白文字を合わせて文字列のオブジェクトを作ります。その後にプロシージャ(process−children)でctitleの内容を入れることにより、「章番号空白章見出し」の形で章見出しを表示することができます。このように、要素の内容に通し番号のデータがなくても、要素の数を数えることによって通し番号を得ることができます。この方法だと章や節の数を変えた場合にも対応できます。

<節見出し>

 節見出しにも、スタイル指定項目にしたがって特質space−before:、font−size:、line−spacing:、quadding:を指定します。また、節見出しのフォントをゴシック体の太字とするため、font−family−name:に”GothicBBBMedium”、font−weight:にboldを指定します。節のタイトルにも章番号と同じ方法で節番号をつけます。

(element sectitle
  (make paragraph
        space−before: 1cm
        font−family−name: "GothicBBB Medium"
        font−size: 12pt
        line−spacing: 18pt
        font−weight: ’bold
        quadding: ’start
        (literal (number−>string (ancestor−child−number "section")) " ")
        (process−children)))

<段落>

 次に、本文の段落のスタイル指定を説明します。
 段落と箇条書きは同じフォントとフォントサイズにするので、この指定を再利用できるように本文用スタイルとして定義しておきます。定義したスタイルを使うには、make式の中でuse:にこのスタイル名を指定します。

(define *text−style*
  (style font−family−name: "Ryumin Light"
        font−size: 10pt
        line−spacing: 15pt
        quadding: ’justify))

 段落の第1行の行頭をインデントするには、特質first−line−start−indent:を指定します。例のスタイルでは見出しの直後の段落だけはインデントしないとしているので、段落の条件によって処理を変える必要があります。見出しの直後の段落とは、節の中で最初の段落ということです。first−line−start−indent:を最初の段落には指定せず、それ以外の段落に指定するスクリプトを作ります。if式を使い、最初の段落かそれ以外の段落かによって分岐を行います。

(element para
  (if (first−sibling? (current−node))
      (make paragraph
            use: *text−style*)
      (make paragraph
            first−line−start−indent: 10pt
            use: *text−style*)))

 プロシージャ(first−sibling? (current−node))でparaがそのノードの最初の要素であるかどうかを判定します。if式は(first−sibling?)が#tなら1つ目の式を、#fなら2つ目の式を実行します。ここでは、1つ目の式を*text−style*を使うparagraphのmake式とし、2つ目の式を*text−style*にfirst−line−start−indent:を加えたparagraphのmake式としています。このスクリプトにより、見出しの直後の段落を除く全ての段落に第1行をインデントするスタイルを与えることができます。

(element item
  (make paragraph
        use: *text−style*
        start−indent: 20pt
        (literal "・")
        (process−children)))

 加えて、箇条書き特有のスタイルを指定します。すべての行頭を2字分インデントするのは、特質start−indent:によって指定します。行頭に”・”をつけるのは、プロシージャ(literal)と(process−children)によって実現できます。この記述により要素itemの内容の頭に”・”をつけたものをフォーマットの対象とすることになります。

(c) 画像を表示するスクリプト

 画像を表示するにはexternal−graphic(外部グラフィック)流し込みオブジェクトクラスを使います。

<画像とタイトルをまとめる>

 display−group(行外グループ)流し込みオブジェクトクラスは、複数の行外オブジェクトをまとめる役割を持ちます。ここでは画像と画像のタイトルをまとめるのに使います。要素figureとftitleの内容を同じページに配置することを特質keep:によって指定します。

(element figure
  (make display−group
        keep: ’page

 画像の下に画像のタイトルを配置するため、最初にexternal−graphicのmake式、次に(process−matching−children “ftitle”)をdisplay−groupのmake式の中に記述します。

(make display−group
      keep: ’page
      (make external−graphic)
            (process−matching−children "ftitle"))

 external−graphicのmake式で、画像に対するスタイル指定を記述します。特質display?:でこのオブジェクトが行外であることを指定します。display−alignment:で画像を中央揃えで配置することを指定します。

(make external−graphic
      display?: #t
      display−alignment: ’center

 属性値の取り出し 要素figureは、file、width、heightの3つの属性を持っています。fileは画像ファイルの実体名、widthは画像の幅、heightは画像の高さを示しています。この3つの属性の値から、特質entity−system−id:、notation−system−id:、max−width:、max−height:に指定する値を作ります。この4つは順に画像のファイル名、表記法(形式)名、幅、高さを表します。
 let*式を使い、まず変数entity−name、width、heightにそれぞれ属性file、width、heightの値を代入します。属性値はプロシージャ(attribute−string)によって取り出すことができます。notation−nameにはentity−nameが示す実体の表記法名を代入します。プロシージャ(entity−notation)によって実体宣言から表記法名を取り出すことができます。

(let* ((entity−name (attribute−string "file"))
       (notation−name (entity−notation entity−name))
       (width (attribute−string "width"))
       (height (attribute−string "height")))

<画像のファイル名と形式>

 変数entity−nameとnotation−nameを画像のファイル名と表記法名を指定するのに使います。
 プロシージャ(entity−generated−system−id)を使ってentity−nameが示す実体の実体宣言で指定したファイル名を求めます。このファイル名を特質entity−system−id:に指定します。
 プロシージャ(notation−system−id)を使ってnotation−nameが示す表記法の表記法宣言で指定したシステム識別子を求めます。このシステム識別子をnotation−system−id:に指定します。

entity−system−id: (entity−generated−system−id entity−name)
notation−system−id: (notation−system−id notation−name)

<画像の大きさ>

 変数widthとheightを図の大きさを決定するのに使います。widthを(string−>number)で数値に変換してcm単位の長さにし、特質max−width:の値とします。heightも同様にcm単位の長さにしてmax−height:の値とします。さらにscale:にmaxを指定します。これにより、画像がmax−width:とmax−height:の値の大きさで画像がフォーマットされます。

scale: ’max
max−width: (* 1cm (string−>number width))
max−height: (* 1cm (string−>number height))

<画像のタイトルのフォーマット>

 画像のタイトルは番号をつけて「図1 タイトル」という形でフォーマットします。要素ftitleの内容はPCDATAなので、paragraphのmake式を記述します。画像のタイトルと表のタイトルはスタイルがほとんど共通なので、特質の指定を再利用できるようにキャプション用スタイルとして定義しておきます。

(define *caption−style*
  (style font−family−name: "GothicBBB Medium"
         font−size: 8pt
         line−spacing: 12pt
         font−weight: ’bold
         quadding: ’center))

 定義した*caption−style*をparagraphのmake式のuse:に指定します。

(element ftitle
  (make paragraph
        use: *caption−style*
        (literal "図"
                 (number−>string (element−number (parent (current−node))))
                 ". ")
        (process−children)))

 画像のタイトルの頭に番号を表示するスクリプトは、前に説明した章のタイトルに章の通し番号を付けるものと基本的なところは同じです。(parent (current−node))はftitleの親figureを示します。プロシージャ(element−number)は文書全体を通して要素figureの数を数えます。これにより、画像の通し番号が求められます。この番号を(number−>string)で文字列に変換し、プロシージャ(literal)で「図 番号. 」という内容の文字列オブジェクトを作ります。この後にプロシージャ(process−children)を記述することにより、画像のタイトルが「図 番号. タイトル」という形で表示されます。

(d) 表を作るスクリプト

 表をフォーマットするには表用流し込みオブジェクトクラス群を使います。例の文書の表はtable、column、row、cellの4つの要素を持っています。それに対応してtable(表)、table−column(表列)、table−row(表行)、table−cell(表セル)の4つのクラスを使います。

<表の本体>

 要素tableとttitleをまとめるのにdisplay−groupを使います。keep:を指定することにより、表と表のタイトルを同じページに配置します。表のタイトルを表の上に配置するため、display−groupのmake式として、最初に(process−matching−children “ttitle”)、その次にtableのmake式を記述します。tableのmake式の内容には、要素tableの子であるcolumnとrowをプロシージャ(process−matching−children)で指定します。表のスタイルを特質で指定します。display−alignment:で表を中央揃えで配置することを指定します。また、table−border:で表の枠線を指定します。

(element table
  (make display−group
        keep: ’page
        (process−matching−children "ttitle")
        (make table
              display−alignment: ’center
              table−border: #t
              (process−matching−children "column")
              (process−matching−children "row"))))

<表のタイトル>

 表のタイトルには、画像のタイトルと同じキャプション用スタイルを使います。paragraphのmake式でuse:に*caption−style*を指定します。表のタイトルに番号をつけて表示するため、表の通し番号を求めるスクリプトを作ります。これは画像のタイトルに番号をつけるスクリプトとしくみは全く同じです。

(element ttitle
  (make paragraph
        space−before: 1cm
        use: *caption−style*
        (literal "表"
                 (number−>string (element−number (parent (current−node))))
                 ". ")
        (process−children)))

<表の列>

 クラスtable−columnは、列の幅を決定するために使います。列の幅は特質width:を使って指定します。プロシージャ(attribute−string)でcolumnの属性widthから取り出した値をプロシージャ(string−>number)で数値に直し、cm単位にしたものをwidth: に指定します。

(element column
  (make table−column
        width: (* 1cm (string−>number (attribute−string "width")))))

<表の行>

 クラスtable−rowは、table−cellをグループ化する役割を持ちます。

(element row
  (make table−row))

<表セル>

 表セルはtable−cellを使ってフォーマットしますが、その内容のスタイルはparagraphを使って指定します。要素cellの属性colnum、rowspan、colspanの値を、特質column−number:、n−rows−spanned:、n−columns−spanned:を指定するのに使います。let式で、変数colnum 、rowspan、colspanにそれぞれ属性colnum、rowspan、colspanの値を代入します。属性から値を取り出すにはプロシージャ(attribute−string)を使います。

(let ((colnum (attribute−string "colnum"))
      (rowspan (attribute−string "rowspan"))
      (colspan (attribute−string "colspan")))

 table−cellのmake式で列番号を表す特質column−number:を指定し、セルがどの列に所属するかを決めます。これには変数colnumを使います。
 変数colnumから列番号を求めるプロシージャを定義します。

(define (col−number colnum)
  (if (or (not colnum) (string=? colnum ""))
      (child−number)
      (string−>number colnum)))

 if式で属性colnumが指定されているかどうかによって分岐を行います。属性colnumが指定されていなければ(not colnum)は#tになります。また属性colnumの値が空の場合、(string=? colnum “”)は#tになります。つまり、属性colnumが指定されていなければ、(or (not colnum) (string=?colnum ” “))は#tになり、(child−number)が返されます。属性colnumが指定されていれば、変数colnumに代入したその値を(string−>number)で数に変換して返します。
 定義したプロシージャ(col−number colnum)を使って特質column−number:を指定することにより、属性colnumが指定されている場合はその値がchild−number:の値として使われます。

column−number: (col−number colnum)

 行抜きをする場合は特質n−rows−spanned:に、列抜きをする場合はn−columns−spanned:に抜くセルの数を指定します。抜くセルの数は属性値を代入した変数rowspanとcolspanの値を使って指定します。
 変数rowspanまたはcolspanから抜くセルの数を求めるプロシージャを定義します。

(define (n−spanned span)
  (if (or (not span) (string=? span ""))
      1
      (string−>number span)))

 (col−number)と同様に、if式で属性rowspanまたはcolspanが指定されているかどうかによって分岐を行います。属性が指定されていなければ、(or (not colnum) (string=? colnum ” “))は#tになり、値1が返されます。指定されていれば、変数rowspanまたはcolspanの値を(string−>number)で数に変換して返します。
 定義したプロシージャ(n−spanned)を使って特質n−rows−spanned:とn−columns−spanned:を指定することにより、属性rowspanまたはcolspanが指定されている場合はその値が使われます。

n−rows−spanned: (n−spanned rowspan)
n−columns−spanned: (n−spanned colspan)

 表セルのその他のスタイルを特質で指定します。
 表内の境界線は、セルごとに特質で指定します。行の境界線は特質cell−before−row−border:またはcell−after−row−border:で指定します。列の境界線はcell−before−column−border:またはcell−after−column−border:で指定します。

cell−before−row−border: #t
cell−before−column−border: #t

 セル内の余白のサイズは特質cell−before−row−margin:、cell−after−row−margin:、cell−before−column−margin:、cell−after−column−margin:によって指定します。

cell−before−row−margin: 0.1cm
cell−after−row−margin: 0.1cm
cell−before−column−margin: 0.1cm
cell−after−column−margin: 0.1cm

 セル内容の文字列はparagraphのmake式でフォーマットします。スタイル指定は特質font−size:、line−spacing:、quadding:を使って行います。ここではフォントサイズ10pt、行送り15pt、中央揃えで配置と指定しています。

(make paragraph
      font−size: 10pt
      line−spacing: 15pt
      quadding: ’center))))

<<prev      next>>