esperecyan/dictionary-php

従来の辞書形式と「主に単語で答えるゲームにおける汎用的な辞書形式」の構文解析、直列化を行う API を提供します。

v0.9.2 2020-01-26 00:41 UTC

README

次のゲームの辞書を構文解析し、相互に変換できるようにする API を提供します。

Inteligenceωの辞書で画像・音声ファイルへのパスが含まれる場合、 そのファイルが含まれるフォルダをdatファイルと一緒にアーカイブする必要があります。 同名のファイルが含まれる辞書 (同名のファイルを別々のフォルダに分けて格納したアーカイブ) は取り扱えません。

<?php
require_once 'vendor/autoload.php';

use esperecyan\dictionary_php as dictionary;

$file = new \SplTempFileObject();
$file->fwrite(mb_convert_encoding(<<<'EOD'
% 選択問題
Q,2,,../images/sun.mp4
A,1,地球,カロン,太陽,\seikai

Q,0,仲間外れはどれでしょう
A,1,リンゴ,\seikai,ゴリラ,ラクダ,ダチョウ,\explain=選択肢を表示しなければ問題が成立しない場合。

% 答えが複数あり、どれか1つを選択すれば正解になる場合
Q,0,食べ物はどれでしょう (答えが複数ある場合はどれが1つだけ選択)
A,1,リンゴ,\seikai,ゴリラ,ラッパ,パン,\seikai

% 答えが複数あり、すべて選択する必要がある場合
Q,0,同じ種類のものを選びましょう
A,3,リンゴ,\seikai,ゴリラ,ラッパ,パン,\seikai

% 並べ替え問題
q,0,しりとりが成立するように並べ替えてください
% 問題行と解答行の間のコメント行と空行

a,2,リンゴ,1,パン,4,ゴリラ,2,ラッパ,3
EOD
, 'Windows-31J', 'UTF-8'));

$parser = new dictionary\Parser(null, '選択・並べ替え問題.txt');
$dictionary = $parser->parse($file);

$serializer = new dictionary\serializer\GenericDictionarySerializer();
$serializer->response($dictionary);

上の例の出力は以下となります。

text,image,answer,answer,description,specifics,question,option,option,option,option,type,@title
太陽,local/sun.png,太陽,,,,,地球,カロン,太陽,,selection,選択・並べ替え問題
リンゴ,,リンゴ,,選択肢を表示しなければ問題が成立しない場合。,,仲間外れはどれでしょう,リンゴ,ゴリラ,ラクダ,ダチョウ,selection,
「リンゴ」か「パン」,,リンゴ,パン,,,"食べ物はどれでしょう (答えが複数ある場合はどれが1つだけ選択)",リンゴ,ゴリラ,ラッパ,パン,selection,
「リンゴ」と「パン」,,リンゴ,パン,,require-all-right=,同じ種類のものを選びましょう,リンゴ,ゴリラ,ラッパ,パン,selection,
"リンゴ → ゴリラ → ラッパ → パン",,,,,,しりとりが成立するように並べ替えてください,リンゴ,ゴリラ,ラッパ,パン,selection,

インストール

composer require esperecyan/dictionary-php

Composer のインストール方法については、Composer のグローバルインストール - Qiitaなどをご覧ください。

要件

パブリックAPI

class esperecyan\dictionary_php\Parser(string $from = null, string $filename = null, string $title = null)

構文解析器。

string $from = null

変換元の辞書形式。キャッチフィーリング きゃっちま Inteligenceω クイズ Inteligenceω しりとり ピクトセンス 汎用辞書 のいずれか。

指定されていないか間違った値が指定されていれば、$filename から判断します。 その場合のInteligenceωについては、コメント行、空行を除く最初の行が Q, で始まるか否かで、クイズとしりとりを判別します。

string $filename = null

変換元のファイル名。

string $title = null

辞書のタイトル。

指定されていなければ、$filename から判断します。

汎用辞書形式で @title フィールドが存在する場合、この指定は無視されます。

Dictionary esperecyan\dictionary_php\Parser#parse(SplFileInfo $file, bool $header = null, string[] $filenames = [])

SplFileInfo $file

変換元のファイルをSplFileInfo、またはその派生クラスで与えます。

bool $header = null

変換元のファイルが 汎用辞書 の場合、ヘッダ行が存在すれば true、存在しなければ false、不明なら null を指定します。

string[] $filenames = []

変換元のファイルが 汎用辞書 の場合、$file にZIPファイルを与える代わりに、$file にCSVファイルを与えこの引数にファイル名のリストを与えることで、 「画像・音声・動画ファイルを含む場合のファイル形式」の構文解析できます。

例外 esperecyan\dictionary_php\exception\SyntaxException

SyntaxException#getMessage() から、ユーザーに示すエラーメッセージを取得できます。

$from 説明・例
共通 ファイル形式、符号化方式が間違っている。
共通 1つのフィールドの文字数が多過ぎる。
共通 (汎用辞書以外) 汎用辞書 に直列化可能なお題が一つも存在しなかった。
汎用辞書 辞書全体の容量が大き過ぎる。
汎用辞書 空のCSVファイルである。
汎用辞書 ヘッダ行に text というフィールドが存在しない。
汎用辞書 ヘッダ行を超えるフィールド数の行が存在する。
汎用辞書 textフィールドが存在しない行がある。
汎用辞書 画像ファイルの容量が大き過ぎる。
汎用辞書 音声ファイルの容量が大き過ぎる。
汎用辞書 動画ファイルの容量が大き過ぎる。
汎用辞書 アーカイブに dictionary.csv という名前のファイルが含まれていない。
汎用辞書 アーカイブに含まれるファイルの名前が妥当でない。
汎用辞書 アーカイブに含まれるファイルの形式が間違っている。
汎用辞書 アーカイブに含まれるファイルの拡張子が正しくない。
汎用辞書 アーカイブに含まれるファイルの数が多過ぎる。
汎用辞書
ピクトセンス
符号化方式の検出に失敗した。
キャッチフィーリング 空行がある。
きゃっちま コメントの前にスペースがある。
Inteligenceω しりとり 表示名の直後に難易度 (数値) が存在する。
Inteligenceω しりとり 読み方にひらがな以外が含まれている。
Inteligenceω しりとり 読み方が設定されていないお題がある。
Inteligenceω クイズ 出題の種類が数値になっていない。
Inteligenceω クイズ 解答の種類が数値になっていない。
Inteligenceω クイズ 画像クイズ、音声クイズでファイルが指定されていない。
Inteligenceω クイズ 問題オプションの値が数値になっていない。
Inteligenceω クイズ 選択問題で \seikai の前に選択肢が存在しない。
Inteligenceω クイズ 解答オプション \bonus の値が数値になっていない。
Inteligenceω クイズ 解答オプションの前に解答本体が存在しない。
Inteligenceω クイズ 記述問題で、`
Inteligenceω クイズ 選択問題で \seikai が設定されていない。
Inteligenceω クイズ 問題行に対応する解答行が存在しない。
Inteligenceω クイズ 解答行より前に問題行が存在する。
Inteligenceω クイズ コメント、問題、解答のいずれにも該当しない行が存在する。
Inteligenceω クイズ アーカイブ中に同名のファイルが含まれている。
Inteligenceω クイズ アーカイブ中に、拡張子が .txt のファイルが2つ以上含まれている。
Inteligenceω クイズ アーカイブ中に、拡張子が .txt のファイル含まれていない。
Inteligenceω クイズ アーカイブに含まれるファイルの形式が、汎用辞書と互換性がない。
Inteligenceω クイズ アーカイブに含まれるファイルの拡張子が、汎用辞書と互換性がない。
Inteligenceω クイズ アーカイブに含まれるファイルの数が多過ぎる。
ピクトセンス ワードにひらがな以外が含まれている。
ピクトセンス 1ワードの文字数が多過ぎる。
ピクトセンス 辞書のワード数が少な過ぎる、または多過ぎる。
ピクトセンス 辞書全体の文字数が多過ぎる。

ロギング

esperecyan\dictionary_php\ParserPSR-3: Logger InterfacePsr\Log\LoggerAwareInterfaceを実装しています。

$from ログレベル 説明・例
共通 (汎用辞書以外) Psr\Log\LogLevel::ERROR 1つのお題が 汎用辞書 に直列化可能な形式ではなかった。
汎用辞書 Psr\Log\LogLevel::ERROR 符号化方式がUTF-8でない。
汎用辞書 Psr\Log\LogLevel::WARNING 辞書全体の容量が大きい。
汎用辞書 Psr\Log\LogLevel::WARNING 画像ファイルの容量が大きい。
汎用辞書 Psr\Log\LogLevel::WARNING 音声ファイルの容量が大きい。
汎用辞書 Psr\Log\LogLevel::WARNING 動画ファイルの容量が大きい。
汎用辞書 Psr\Log\LogLevel::WARNING アーカイブに含まれるファイルの数が多い。
ピクトセンス Psr\Log\LogLevel::ERROR 辞書名が空文字列である。
ピクトセンス Psr\Log\LogLevel::ERROR 辞書名が長過ぎる。

class esperecyan\dictionary_php\Serializer(string $to = '汎用辞書')

直列化器。

string $to = '汎用辞書'

変換先の辞書形式。キャッチフィーリング きゃっちま Inteligenceω クイズ Inteligenceω しりとり ピクトセンス 汎用辞書 のいずれか。

指定されていないか間違った値が指定されていれば、汎用辞書 になります。

string[] esperecyan\dictionary_php\Serializer#serialize(Dictionary $dictionary, bool|string $csvOnly = false)

次のような構造の連想配列で直列化したデータを返します。

  • [bytes] => 直列化したデータのバイナリ文字列
  • [type] => MIME型 (charsetパラメータなどをともなう)
  • [name] => ファイル名

Dictionary $dictionary

辞書。

bool|string $csvOnly = false

汎用辞書 Inteligenceω クイズ の場合、ZIPファイルの代わりにCSVファイル、txtファイルのみを返すときに真に設定します。 真の代わりに https://example.ne.jp/dictionaries/1/files/%s のような文字列を設定することで、%s をファイル名に置き換えて辞書ファイル中に記述します。

例外 esperecyan\dictionary_php\exception\SerializeExceptionInterface

SerializeExceptionInterface#getMessage() から、ユーザーに示すエラーメッセージを取得できます。 以下の例外はいずれも SerializeExceptionInterface を実装しています。

$to 例外 説明・例
共通 (汎用辞書以外) esperecyan\dictionary_php\exception\EmptyOutputException 該当の辞書形式に変換可能なお題が一つも存在しなかった。
汎用辞書 esperecyan\dictionary_php\exception\TooLargeOutputException 辞書全体の容量が大き過ぎる。
汎用辞書 BadMethodCallException $csvOnly が偽、かつ「画像・音声・動画ファイルを含む場合のファイル形式」をCSVファイルのみで構文解析していた場合。

ロギング

$to ログレベル 説明・例
共通 (汎用辞書以外) Psr\Log\LogLevel::ERROR 1つのお題が 汎用辞書 に直列化可能な形式ではなかった。
汎用辞書
ピクトセンス
Psr\Log\LogLevel::ERROR 符号化方式がUTF-8でない。
ピクトセンス Psr\Log\LogLevel::CRITICAL 辞書のワード数が少な過ぎる、または多過ぎる。
ピクトセンス Psr\Log\LogLevel::CRITICAL 辞書全体の文字数が多過ぎる。
ピクトセンス Psr\Log\LogLevel::ERROR 辞書名が長過ぎる。

class esperecyan\dictionary_php\Dictionary

辞書データ。

(string|string[]|float)[][][] esperecyan\dictionary_php\Dictionary#getWords()

次のような構造の多次元配列で表されたお題の一覧を返します。

  • [0] =>
    • [text] => array(文字列)
    • [image] => array(文字列)
    • [image-source] =>
      • [0] =>
        • [lml] => CommonMark (文字列)
        • [html] => HTML (文字列)
    • [audio] => array(文字列)
    • [audio-source] =>
      • [0] =>
        • [lml] => CommonMark (文字列)
        • [html] => HTML (文字列)
    • [video] => array(文字列, ……)
    • [video-source] =>
      • [0] =>
        • [lml] => CommonMark (文字列)
        • [html] => HTML (文字列)
    • [answer] => array(文字列, ……)
    • [description] => array(文字列)
    • [weight] => array(浮動小数点数)
    • [specifics] => array(文字列)
    • [question] => array(文字列)
    • [option] => array(文字列, ……)
    • [type] => array(文字列)
  • [1] => ……
  • [2] => ……
  • ……

(string|string[])[] esperecyan\dictionary_php\Dictionary#getMetadata()

次のような構造の多次元配列で表されたメタフィールドの一覧を返します。

  • [@title] => 文字列
  • [@summary] =>
    • [lml] => CommonMark (文字列)
    • [html] => HTML (文字列)
  • [@regard] => 文字列

FilesystemIterator esperecyan\dictionary_php\Dictionary#getFiles()

辞書に同梱されるファイルを返します。

esperecyan\dictionary_php\Dictionary#setFiles(FilesystemIterator $files)

辞書に同梱されるファイルを設定します。それぞれ同梱されるファイルとして妥当で、 かつすべてのファイル名とParser#parse()の第3引数$filenamesに与えたファイル名が一致している必要があります。

class esperecyan\dictionary_php\Validator()

辞書に同梱されるファイルのバリデータ。

string[] esperecyan\dictionary_php\Validator#correct(string|SplFileInfo $file, string $filename)

Serializer#serialize()の戻り値と同じ構造の戻り値を返します。

string|SplFileInfo $file

ファイルをバイナリ文字列、SplFileInfo、その派生クラスのいずれかで与えます。

string $filename

ファイル名。

例外 esperecyan\dictionary_php\exception\SyntaxException

SyntaxException#getMessage() から、ユーザーに示すエラーメッセージを取得できます。

説明・例
画像ファイルの容量が大き過ぎる。
音声ファイルの容量が大き過ぎる。
動画ファイルの容量が大き過ぎる。
ファイルの名前が妥当でない。
ファイルの形式が間違っている。
ファイルの拡張子が正しくない。

ロギング

esperecyan\dictionary_php\ValidatorPSR-3: Logger InterfacePsr\Log\LoggerAwareInterfaceを実装しています。

ログレベル 説明・例
Psr\Log\LogLevel::WARNING 画像ファイルの容量が大きい。
Psr\Log\LogLevel::WARNING 音声ファイルの容量が大きい。
Psr\Log\LogLevel::WARNING 動画ファイルの容量が大きい。

Contribution

Pull Request、または Issue よりお願いいたします。

セマンティック バージョニング

当ライブラリはセマンティック バージョニングを採用しています。 パブリックAPIは、上記のとおりです。

ライセンス

当スクリプトのライセンスは Mozilla Public License Version 2.0 (MPL-2.0) です。