# A1. PSML 1.0 Scene ショートリファレンス

PSML (Peko Scenario Markup Language) は PVNS で実行されるシナリオを記述するためのマークアップ言語です。

PSML は XML アプリケーションであり、PSML 1.0 ではシーンデータを記述するためのタグセットとして PSML 1.0 Scene を定義しています。PSML 1.0 Scene の XML namespaces URI は次の通りです。

http://tsukuba-bunko.org/ns/psml-scene

## A1.1 基本

### A1.1.1 PSML-Scene の基本構造

PSML 1.0 Scene では、`scene` をルート要素として、`head` 要素、`body` 要素により大きく二つのブロックに分けられます。

以下に、典型的な PSML 1.0 Scene 文書の例を示します。

    <?xml version="1.0" encoding="Shift_JIS"?>
    <!DOCTYPE scene PUBLIC "-//Tsukuba Bunko//DTD PSML Scene 1.0//EN"
        "http://softlab.tsukuba-bunko.org/dtd/psml10-scene.dtd">
    <scene xmlns="http://tsukuba-bunko.org/ns/psml-scene">
      <head>
        <title>シーン 1</title>
        <flow-mapping>
          <scene-ref if="flagA">scene003.xml</scene-ref>
          <scene-ref>scene002.xml</scene-ref>
        </flow-mapping>
        <property name="canvas.text.view-type" value="full" />
      </head>
      <body>
        <stage>
          <enter name="alto" looks="alto01.png" />
        </stage>
        <text>
          <p>　これは PSML 1.0 Scene のサンプルです。</p>
        </text>
      </body>
    </scene>

図A1.1.1: PSML 1.0 Scene 文書の例

`head` タグに囲まれた部分は、この PSML 1.0 Scene 文書(シーンデータ) が表すシーンの情報を記述したヘッダブロックになります。ヘッダブロックには、シーンのタイトル、このシーンが終わった後で次に遷移するシーン、その他、キャンバスに対してシーン固有の設定を行うためのプロパティ設定が記述されます。

`body` タグで囲まれた部分は、シーンの本文になります。シーンの本文には、シーンを構成する文章要素、舞台要素、選択肢要素がシーンの流れに沿って順番に記述されます。各シーン要素の内容は、それぞれ PSML 1.0 Scene の `text` タグ、`stage` タグ、`select` タグによって囲まれた部分に記述されます。

以下に、PSML 1.0 Scene で定義される各タグについて、その解説を示します。

### A1.1.2 空白文字と空文字列の取り扱い

ここで「空白文字」と呼ぶのは次の 2 種類の文字です。

- 半角空白 `(U+0020)`
- ISO 制御文字 `(U+0000〜U+001F, U+007F〜U+009F)`

また、「空文字列」とは、長さが 0 である文字列のことを指します。

これら空白文字・空文字列の取り扱いについては、次のように定義します。

#### A1.1.2.1 属性値

まず、属性値が空文字列だった場合、属性が省略されたものとして処理します。

空文字列ではない場合、属性値に含まれる全ての ISO 制御文字、および、属性値の先頭と最後の半角スペースを除去します。この結果、空文字列になった場合は「妥当性エラー」(警告)になります。

#### A1.1.2.2 内容モデルが #PCDATA である要素に含まれる文字列

内容モデルが #PCDATA である要素は次の通りです。

- title
- scene-ref

これらの要素に含まれる文字列に対しては、文字列に含まれる全ての ISO 制御文字、および、文字列の先頭と最後の半角スペースを除去します。この結果、空文字列になった場合は「妥当性エラー」(警告)になります。

#### A1.1.2.3 内容モデルが混合モデルである要素に含まれる文字列

内容モデルが混合モデルである要素は次の通りです。

- p
- item ＊現在のバージョンでは #PCDATA です。

これらの要素に含まれる文字列に対しては、文字列に含まれる全ての ISO 制御文字を除去します。この結果、空文字列になった場合は、空文字列のまま処理します。

## A1.2 タグリファレンス

### A1.2.1 構造

構造要素
要素名 | scene
親要素 | なし
内容モデル | head, body
説明 | 必須。PSML シーンデータのルート要素。
要素名 | head
親要素 | scene
内容モデル | title, flow-mapping, property*
説明 | 必須。シーンデータのヘッダ情報ブロックを定義する。
要素名 | body
親要素 | scene
内容モデル | (text | stage | select | flag | scene-flow)+
説明 | 必須。シーンデータの本文ブロックを定義する。
ヘッダ情報
要素名 | title
親要素 | head
内容モデル | #PCDATA
説明 | 必須。このシーンのタイトルを定義する。シーンのタイトルは、PVNS のメインウィンドウのタイトルバーに表示される。
要素名 | flow-mapping
親要素 | head
内容モデル | (scene-ref)+
説明 | このシーンの処理が終了後に遷移するシーンを決定するための、フラグの状態と遷移先シーン名のマッピングを記述する。
要素名 | scene-ref
親要素 | flow-mapping
内容モデル | #PCDATA
説明 | シーン終了後に遷移するシーンへの参照を記述する。
属性 | if この `scene-ref` に記述されたシーンに遷移する場合のフラグ状態を表す、フラグ条件式。フラグ条件式の記述については、共通属性 test の項目を参照。省略された場合、デフォルト遷移先として扱う。
要素名 | property
親要素 | head
内容モデル | Empty
説明 | このシーン固有のプロパティを設定する。設定可能なプロパティは、「5.6 シーン固有のカスタマイズ」を参照。設定を行うプロパティは次の二つの属性により指定する。
属性 | name シーン固有の設定を行うプロパティ名。 value シーン固有の設定を行うプロパティの値。 file プロパティ名と値のペアを記述した、プロパティファイル名。プロパティファイルはシーンデータと同じ場所に配置される。`name` 属性が定義されていた場合、この属性は無視される。
本文
要素名 | text
親要素 | body
内容モデル | (p | np | wait)+
説明 | シーン本文の文章要素の内容(台詞やナレーションなどの文章、ページ操作)を記述する。
属性 | test 共通属性 test の項目を参照。
要素名 | stage
親要素 | body
内容モデル | (enter | action | exit | background | show-slide | hide-slide | at-once | play-bgm | play-se | stop-bgm | stop-se | wait)+
説明 | シーン本文の舞台要素の内容(役者への指示、背景・スライド操作・サウンド効果)を記述する。
属性 | test 共通属性 test の項目を参照。
要素名 | select
親要素 | body
内容モデル | item+
説明 | プレイヤーに提示する選択肢を記述する。
属性 | name 必須。シナリオ中で選択肢を一意に識別する名前を指定する。 description この選択肢の説明。 scope この選択肢により設定されるフラグのスコープを指定する。`scene`, `session`, `system` のいずれかを選択して指定する。省略された場合、`session` が使用される。 test 共通属性 test の項目を参照。

### A1.2.2 文章要素

テキスト
要素名 | p
親要素 | text
内容モデル | (#PCDATA | wait)+
説明 | 台詞やナレーションなどの文章を記述する。`p`タグで囲まれたテキストは全て PVNS で表示される対象となるため、インデントは明示的に空白文字列などで指定する必要がある。また、表示できない文字（制御文字など）は使用してはならない。
属性 | flag この文章の表示が完了した段階で立てるセッションスコープ・フラグの、フラグ ID を指定する。フラグ ID については、`flag` 要素の `id` 属性の項目を参照。 test 共通属性 test の項目を参照。
ページ操作
要素名 | np
親要素 | text
内容モデル | Empty
説明 | 改ページを指示する。現在のページの内容は履歴管理に保存され、表示中の行は全てクリアされる。次の文章はクリアされたページの先頭から表示される。
属性 | test 共通属性 test の項目を参照。

### A1.2.3 舞台要素

Actor
要素名 | enter
親要素 | stage, at-once
内容モデル | Empty
説明 | 役者を舞台に登場させる。
属性 | name 必須。シナリオ中で役者を一意に識別する名前を指定する。 looks 必須。役者の表情を表示するための画像(立ち絵)のファイル名を指定する。 position 役者の舞台上の立ち位置を指定する。`left`, `center`, `right` のいずれかを選択して指定するか、直接舞台左端から画像の中心線までの距離をピクセル単位で指定する。省略された場合、`center` が使用される。 effect 登場時に使用する舞台効果名を指定する。省略された場合は、シーン固有のプロパティ、または、リソースで設定されたデフォルト値が使用される。 test 共通属性 test の項目を参照。
要素名 | action
親要素 | stage, at-once
内容モデル | Empty
説明 | 舞台上の役者に対し、表情および立ち位置の変更を指示する。
属性 | name 必須。変更を指示する役者名を指定する。 looks 役者の表情を表示するための画像(立ち絵)のファイル名を指定する。省略された場合、現在使用している画像がそのまま使用される。 position 役者の舞台上の立ち位置を指定する。指定の方法は enter に従う。省略された場合は、現在の立ち位置がそのまま使用される。 effect 変更時に使用する舞台効果名を指定する。省略された場合は、シーン固有のプロパティ、または、リソースで設定されたデフォルト値が使用される。 test 共通属性 test の項目を参照。
要素名 | exit
親要素 | stage, at-once
内容モデル | Empty
説明 | 役者を舞台から退場させる。
属性 | name 必須。舞台から退場させる役者名を指定する。 effect 退場時に使用する舞台効果名を指定する。省略された場合は、シーン固有のプロパティ、または、リソースで設定されたデフォルト値が使用される。 test 共通属性 test の項目を参照。
背景・スライド
要素名 | background
親要素 | stage, at-once
内容モデル | Empty
説明 | 舞台背景の変更を指示する。背景の内容は `image` 属性または `color` 属性を使用して指定する。
属性 | image 背景に使用する画像名を指定する。 color 背景に使用する色を指定する。色は色名または「#RRGGBB」の形式で使用する。`image` が指定された場合はこの属性の設定は無視される。 effect 背景変更時に使用する舞台効果名を指定する。省略された場合は、シーン固有のプロパティ、または、リソースで設定されたデフォルト値が使用される。 test 共通属性 test の項目を参照。
要素名 | show-slide
親要素 | stage, at-once
内容モデル | Empty
説明 | 舞台を覆い隠すスクリーンを用意し、スライドをスクリーンに描画する。
属性 | image スライドとして表示する画像名を指定する。 effect スライド描画時に使用する舞台効果名を指定する。省略された場合は、シーン固有のプロパティ、または、リソースで設定されたデフォルト値が使用される。 test 共通属性 test の項目を参照。
要素名 | hide-slide
親要素 | stage, at-once
内容モデル | Empty
説明 | スライドの投影を終了し、舞台を通常の状態に戻す。
属性 | effect 背景変更時に使用する舞台効果名を指定する。省略された場合は、シーン固有のプロパティ、または、リソースで設定されたデフォルト値が使用される。 test 共通属性 test の項目を参照。
グルーピング
要素名 | at-once
親要素 | stage
内容モデル | (enter | action | exit | background | show-slide | hide-slide)+
説明 | 同時に実行する、役者への指示、背景・スライド操作処理をグルーピングする。
属性 | effect 処理時に使用する舞台効果名を指定する。省略された場合は、`immediate` を使用する。 test 共通属性 test の項目を参照。
サウンド効果
要素名 | play-bgm
親要素 | stage
内容モデル | Empty
説明 | BGM を再生する。
属性 | id 必須。シナリオ中で、再生するBGMを一意に識別する ID を指定する。 clip 必須。再生する音楽クリップ名を指定する。＊現在指定可能なフォーマットは *.wav, *.au, *.mp3 の 3 種類です。 loop ループ再生するかどうかを `true` または `false` から指定する。省略された場合は `true` を使用する。 test 共通属性 test の項目を参照。
要素名 | play-se
親要素 | stage
内容モデル | Empty
説明 | SE(Sound Effect) の再生を指示する。
属性 | id 必須。シナリオ中で、再生する SE を一意に識別する ID を指定する。 clip 必須。再生する音楽クリップ名を指定する。＊現在指定可能なフォーマットは *.wav, *.au, *.mp3 の 3 種類です。 loop ループ再生するかどうかを `true` または `false` から指定する。省略された場合は `false` が指定されたものとして処理する。 test 共通属性 test の項目を参照。
要素名 | stop-bgm
親要素 | stage
内容モデル | Empty
説明 | BGM の再生を停止する。
属性 | id 必須。停止する BGM の ID を指定する。 test 共通属性 test の項目を参照。
要素名 | stop-se
親要素 | stage
内容モデル | Empty
説明 | SE の再生停止を指示する。
属性 | id 必須。停止する SE の ID を指定する。 test 共通属性 test の項目を参照。

### A1.2.4 選択肢要素

選択肢
要素名 | item
親要素 | select
内容モデル | #PCDATA
説明 | 選択肢の項目を記述する。`item` タグで囲まれたテキストが選択肢の項目として表示される。使用可能なテキストは p 要素に準じる。
属性 | id 必須。選択肢の中で一意に項目を識別する ID を指定する。 test 共通属性 test の項目を参照。

### A1.2.5 その他

その他
要素名 | wait
親要素 | text, stage, p
内容モデル | Empty
説明 | PVNS に対し、台詞やナレーション、舞台上でのアクションの途中で、表示を一旦停止することを指示する。PVNS は `dur` で指定された時間が経過するか、プレーヤーがキャンバス内を左クリックする、または Enter キーを押下するまで待機する。
属性 | dur 待機する最大時間。単位は [msec](ミリ秒)。省略した場合、プレイヤーがマウスの左ボタンをクリックするか、または Enter キーを押下するまで待機する。 test 共通属性 test の項目を参照。
要素名 | flag
親要素 | body
内容モデル | Empty
説明 | シーンの流れを制御するためのフラグを立てる、または、下ろす。
属性 | id 必須。操作対象となるフラグのフラグ ID。フラグ ID は、フラグ ID として使用できる文字 (XML の属性値として使用できる文字から「`,``(U+002C)`」「`[``(U+005B)`」「`]``(U+005D)`」の 3 文字を除いた文字) の１文字以上のシーケンスです。ただし、フラグ ID の最初の文字に「`!``(U+0021)`」を使用することはできません。なお、先頭以外の文字であれば「`!``(U+0021)`」を使用することが出来ます。 scope 必須。操作対象となるフラグのスコープを指定する。`scene`, `session`, `system` のいずれかを選択して指定する。省略された場合、`session` が使用される。 action フラグに対する操作が「立てる」の場合は `declare`、「下ろす」の場合は `undeclare` を指定する。省略された場合 `declare` を使用する。
要素名 | scene-flow
親要素 | body
内容モデル | Empty
説明 | PVNS にシーンの終了と、次のシーンへの遷移を指示する。
属性 | next-scene 非推奨。`flow-mapping` で定義される遷移先マッピングを使用せずに、直接遷移先シーン名を指定する場合に使用する。 test 共通属性 test の項目を参照。

## A1.3 共通属性

テスト
属性名 | test
親要素 | -
データ型 | CDATA
説明 | 要素を PSML プロセッサが評価(処理)するかどうかを判定するためのフラグ条件式を記述します。フラグ条件式の評価結果が「真」の場合、その要素を評価します。「偽」の場合は要素を評価せずに、次の要素の評価に移ります。なお、要素が「評価しない」になった場合、その子要素も「評価しない」になります。 テスト属性の値(testString)は、単一の式(expression)、または、「`[``(U+005B)`」「`]``(U+005D)`」で括られた式のリストです。 式は、一つ以上のフラグテスト(flagTest)がカンマ(「`,``(U+002C)`」)を区切り文字として列挙されたものとして記述されます。 フラグテストは、フラグ ID、または、「`!``(U+0021)`」を先頭に付加したフラグ ID です。フラグ ID のみの場合は、対応するフラグが立っていることを、「`!`」が先頭に付加されている場合は、対応するフラグが立っていないことを表します。 フラグが立っていることを表すフラグテストの場合、フラグ条件式評価時のシーンのコンテクストでフラグが立っている場合「真」、立っていない場合「偽」になります。 逆に、フラグが立っていないことを表すフラグテストの場合、シーンのコンテクストフラグが立っている場合「偽」、立っていない場合「真」になります。 式の評価結果は、式中に列挙された全フラグテストの評価結果の積になります。つまり、式中のすべてのフラグテストが「真」の場合「真」、フラグテストの中の一つでも「偽」の場合「偽」になります。 「`[``(U+005B)`」「`]``(U+005D)`」で括られた式リスト全体の評価結果は、リスト中のすべての式の評価結果の和になります。つまり、リスト中の式のいずれかが「真」の場合「真」に、すべての式が「偽」の場合「偽」になります。

## A1.4 PSML 1.0 DTD

PSML 1.0 Scene の DTD を示します。PSML 1.0 DTD は次の識別子で識別されます。

PUBLIC | `"-//Tsukuba Bunko//DTD PSML Scene 1.0//EN"`
SYSTEM | `http://softlab.tsukuba-bunko.org/dtd/psml10-scene.dtd`

    <!--
      Peko Scenario Markup Language 1.0 Scene DTD

      All Rights Reserved.
      Copyright (C) 1999-2003 by Tsukuba Bunko.

      This DTD module is identified by the follwing PUBLIC and SYSTEM identifiers:

      PUBLIC "-//Tsukuba Bunko//DTD PSML Scene 1.0//EN"
      SYSTEM "http://softlab.tsukuba-bunko.org/dtd/psml10-scene.dtd"

      $Id: psml.html,v 1.3 2003/12/11 14:35:50 ppoi Exp $
    -->

    <!--==================== Common Attributes =================================-->
    <!ENTITY % attr.test "test CDATA #IMPLIED">

    <!--==================== Utility Elements ==================================-->
    <!ELEMENT wait EMPTY>
    <!ATTLIST wait
      %attr.test;
      dur     CDATA #IMPLIED
    >

    <!ELEMENT flag EMPTY>
    <!ATTLIST flag
      %attr.test;
      id      CDATA #REQUIRED
      scope   (session|system)  "session"
      action    (declare|undeclare) "declare"
    >

    <!--==================== Text Section Contents =============================-->
    <!ENTITY % elements.text "p | np">

    <!ELEMENT text (%elements.text; | wait)+>
    <!ATTLIST text
      %attr.test;
    >

    <!ELEMENT p (#PCDATA | wait)*>
    <!ATTLIST p
      %attr.test;
      flag  CDATA #IMPLIED
    >

    <!ELEMENT np EMPTY>
    <!ATTLIST np
      %attr.test;
    >

    <!--==================== Stage Section Contents ============================-->
    <!ENTITY % actor.elements "enter | action | exit">
    <!ENTITY % background.elements "background | show-slide | hide-slide">
    <!ENTITY % sound.elements "play-bgm | play-se | stop-bgm | stop-se">

    <!ELEMENT stage (%actor.elements; | %background.elements; | %sound.elements; | at-once | wait)+>
    <!ATTLIST stage
      %attr.test;
    >

    <!ELEMENT enter EMPTY>
    <!ATTLIST enter
      %attr.test;
      name    CDATA #REQUIRED
      looks   CDATA #REQUIRED
      position  CDATA "center"
      effect    CDATA #IMPLIED
    >

    <!ELEMENT action EMPTY>
    <!ATTLIST action
      %attr.test;
      name    CDATA #REQUIRED
      looks   CDATA #IMPLIED
      position  CDATA #IMPLIED
      effect    CDATA #IMPLIED
    >

    <!ELEMENT exit EMPTY>
    <!ATTLIST exit
      %attr.test;
      name    CDATA #REQUIRED
      effect    CDATA #IMPLIED
    >

    <!ELEMENT background EMPTY>
    <!ATTLIST background
      %attr.test;
      image   CDATA #IMPLIED
      color   CDATA #IMPLIED
      effect    CDATA #IMPLIED
    >

    <!ELEMENT show-slide EMPTY>
    <!ATTLIST show-slide
      %attr.test;
      image   CDATA #REQUIRED
      effect    CDATA #IMPLIED
    >

    <!ELEMENT hide-slide EMPTY>
    <!ATTLIST hide-slide
      %attr.test;
      effect    CDATA #IMPLIED
    >

    <!ELEMENT at-once (%actor.elements; | %background.elements;)+>
    <!ATTLIST at-once
      %attr.test;
      effect    CDATA #IMPLIED
    >

    <!ELEMENT play-bgm EMPTY>
    <!ATTLIST play-bgm
      %attr.test;
      id      CDATA #REQUIRED
      clip    CDATA #REQUIRED
      loop    (true|false)  "true"
    >

    <!ELEMENT play-se EMPTY>
    <!ATTLIST play-se
      %attr.test;
      id      CDATA #REQUIRED
      clip    CDATA #REQUIRED
      loop    (true|false)  "false"
    >

    <!ELEMENT stop-bgm EMPTY>
    <!ATTLIST stop-bgm
      %attr.test;
      id      CDATA #REQUIRED
    >

    <!ELEMENT stop-se EMPTY>
    <!ATTLIST stop-se
      %attr.test;
      id      CDATA #REQUIRED
    >

    <!--==================== Select Section Contents ===========================-->
    <!ELEMENT select (item)+>
    <!ATTLIST select
      %attr.test;
      name    CDATA #REQUIRED
      description CDATA #IMPLIED
    >

    <!ELEMENT item (#PCDATA)>
    <!ATTLIST item
      %attr.test;
      id      CDATA #REQUIRED
      next-scene  CDATA #IMPLIED
      immediate (true|false)  "false"
    >

    <!--==================== Document Structure ================================-->
    <!ELEMENT scene (head, body)>
    <!ATTLIST scene
      xmlns   CDATA #IMPLIED
      xml:lang  CDATA #IMPLIED
    >

    <!ELEMENT head (title, next-scene?, property*)>

    <!ELEMENT body (text | select | stage | flag)+>

    <!ELEMENT title (#PCDATA)>

    <!ELEMENT next-scene (#PCDATA)>

    <!ELEMENT property EMPTY>
    <!ATTLIST property
      name  CDATA #IMPLIED
      value CDATA #IMPLIED
      file  CDATA #IMPLIED
    >