/**
  * ヘッダ行に用いるフィールド名の一覧を生成します。
  * @param Dictionary $dictionary
  * @return string[]
  */
 protected function getFieldNames(Dictionary $dictionary) : array
 {
     // 各フィールド名について、全レコード中の最大数をそれぞれ取得
     foreach ($dictionary->getWords() as $word) {
         foreach ($word as $fieldName => $fields) {
             $fieldLengths[$fieldName] = max(count($fields), $fieldLengths[$fieldName] ?? 0);
         }
     }
     $fieldLengths += array_fill_keys(array_keys($dictionary->getMetadata()), 1);
     uksort($fieldLengths, function (string $a, string $b) : int {
         return $this->getColumnPosition($a) <=> $this->getColumnPosition($b);
     });
     // ヘッダを生成
     return array_merge(...array_map(function (string $fieldName, int $length) : array {
         return array_fill(0, $length, $fieldName);
     }, array_keys($fieldLengths), $fieldLengths));
 }
 /**
  * 辞書自体のタイトルと説明文を直列化します。Shift_JISに存在しない符号位置が含まれているタイトル、または説明文は存在しないものとして扱います。
  * @param Dictionary $dictionary
  * @param string $lineCommentString 行コメント文字。
  * @param string[]|null $brackets 開き括弧と閉じ括弧の配列。指定されていればタイトルをこの括弧で囲み、タイトル先頭の行コメント文字を省略します。
  * @return string 改行はCRLFを使用します。辞書にタイトルか説明文のいずれかが存在すれば、末尾に改行を2つ付けます。どちらも無ければ空文字列を返します。
  */
 protected function serializeMetadata(Dictionary $dictionary, string $lineCommentString = '//', array $brackets = null) : string
 {
     $metadata = $dictionary->getMetadata();
     if (isset($metadata['@title'])) {
         $shiftJisableTitle = $this->convertToShiftJISable($metadata['@title']);
         if ($this->isShiftJISable($shiftJisableTitle)) {
             $prefix = ($brackets ? '' : "{$lineCommentString} ") . ($brackets[0] ?? self::DEFAULT_BRACKETS[0]);
             $serialized[] = $prefix . str_replace("\n", "\r\n{$lineCommentString} " . str_repeat(' ', max(0, mb_strwidth($prefix) - mb_strwidth("{$lineCommentString} "))), $shiftJisableTitle) . ($brackets[1] ?? self::DEFAULT_BRACKETS[1]);
         }
     }
     if (isset($metadata['@summary'])) {
         $shiftJisableSummary = $this->convertToShiftJISable($metadata['@summary']['lml']);
         if ($this->isShiftJISable($shiftJisableSummary)) {
             $serialized[] = "{$lineCommentString} " . str_replace("\n", "\r\n{$lineCommentString} ", $shiftJisableSummary);
         }
     }
     return isset($serialized) ? implode("\r\n", $serialized) . "\r\n\r\n" : '';
 }