コンテンツにスキップ

Ast: セマンティック文書ツリーとシリアライズ

Ast モジュールは、エンジンのセマンティック文書ツリーです。文書を型付きノードの階層としてモデル化し、DocumentSectionHeadingParagraphListTableFigureCodeFormField に、境界ボックス、引用アンカー、バージョン管理された JSON シリアライズを備えます。アクセシビリティのタグ付けレイヤーは、この AST を利用して構造ツリーを生成します。

安定性: experimental。 これは内部モデルのサーフェスです。そのクラス群にはバージョン固定された公開 API の保証はなく、ノードセットおよびノードの属性は今後変化します。シリアライズスキーマ は独立してバージョン管理されます (AstDocument::CURRENT_SCHEMA_VERSION = '1.0.0')。シリアライザは互換性のないスキーマを検出して拒否できるため、永続化された AST JSON には安定したコントラクトがあります。メモリ内 API には同じ保証がない場合でもです。

Terminal window
composer require nextpdf/core:^3

ここでの AST は、文書の論理構造を表すセマンティックな抽象であり、単一の入力フォーマット向けのパーサ構文ツリーではありません。AstDocument はコンテナです。ルートの AstNodeNodeType::Document でなければなりません)、スキーマバージョン、ソース PDF のハッシュ、ページ数を保持します。無効な構築(スキーマバージョンが空、ページ数が 1 未満、ルート型が不正)は拒否されます。

AstNode は再帰的なノードです。NodeType はセマンティックな種類を列挙します。ノードは子ノード、任意の BoundingBox、任意のテキストコンテンツ、そして NodeAttributeSchema によりスキーマ検証された属性を持ちます。ノード API は、不変な派生を作るために設計されています。withBboxAndText() は新しいノードを返します。deepClone() はサブツリーをコピーします。NodeId は値オブジェクトとして同一性を表します。CitationAnchor はトレーサビリティのために、ノードをソース位置に結び付けます。AstNodeCollectionCountable/IteratorAggregate なセットで、ofType() によるフィルタリングが可能です。

AstSerializer は永続化の境界です。serialize()AstDocument を JSON に書き出し、deserialize() はそれを読み戻します。canDeserialize()extractSchemaVersion() により、コンシューマーはパース前に互換性を確認でき、スキーマの不一致を破損したロードではなく検出済みの条件として扱えます。AstDocument::estimateTokenCount() が存在するのは、このツリーが下流のトークン制限付き処理向けに、コンテンツサイズを見積もる用途にも使われるためです。

クラス主なメンバー役割
AstDocumenttoJson()nodeCount()estimateTokenCount()CURRENT_SCHEMA_VERSIONルートコンテナ。ルート型とスキーマを検証
AstNodeaddChild()children()childCount()totalNodeCount()withBboxAndText()deepClone()再帰的なセマンティックノード
NodeType(enum)DocumentHeadingTableFigureFormField、…セマンティックノードの種類
AstNodeCollectionadd()count()isEmpty()ofType()toArray()イテラブルかつ型フィルタ可能なノードセット
AstSerializerserialize()deserialize()canDeserialize()extractSchemaVersion()バージョン管理された JSON 永続化
BoundingBoxtoArray()equals()ジオメトリ値オブジェクト(イプシロン比較)
NodeId / CitationAnchortoString()equals()toArray()ノード同一性とソーストレーサビリティのアンカー
NodeAttributeSchema属性の検証ノード属性のスキーマ

完全な PHPDoc テーブルを確認するには、composer docs:generate-api-php -- --module=Ast を実行してください。

小さなツリーを構築し、シリアライズします。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Ast\AstNode;
use NextPDF\Ast\AstSerializer;
use NextPDF\Ast\NodeType;
$root = new AstNode(NodeType::Document);
$heading = new AstNode(NodeType::Heading);
$root->addChild($heading);
$root->addChild(new AstNode(NodeType::Paragraph));
echo "Nodes: {$root->totalNodeCount()}\n";
$json = (new AstSerializer())->serialize(/* an AstDocument wrapping $root */);

信頼できない JSON をデシリアライズする前にスキーマ互換性を確認し、永続化された AST を防御的にラウンドトリップします。

<?php
declare(strict_types=1);
require_once __DIR__ . '/../vendor/autoload.php';
use NextPDF\Ast\AstDocument;
use NextPDF\Ast\AstSerializer;
use Psr\Log\LoggerInterface;
final readonly class AstStore
{
public function __construct(
private AstSerializer $serializer,
private LoggerInterface $logger,
) {}
public function load(string $json): ?AstDocument
{
if (!$this->serializer->canDeserialize($json)) {
$this->logger->warning('AST JSON schema incompatible; rejected.', [
'found_schema' => $this->serializer->extractSchemaVersion($json),
'expected' => AstDocument::CURRENT_SCHEMA_VERSION,
]);
return null;
}
return $this->serializer->deserialize($json);
}
}
  • AstDocument はルートノードが NodeType::Document であることを要求します。それ以外のルートを持つツリーは、構築時に例外をスローします。
  • AstNode::withBboxAndText()deepClone() は新しいインスタンスを返します。既存ノードのミューテータ(addChild())は変更を加えます。派生ヘルパーは変更を加えません。どちらを呼び出しているかを把握してください。
  • 外部から取得した JSON については、常に deserialize()canDeserialize() でガードしてください。スキーマバージョンの不一致は、検出可能で想定された条件です。
  • estimateTokenCount() は下流処理のサイズ見積もりのための推定値であり、正確なトークナイザのカウントではありません。信頼できる値として扱わないでください。
  • BoundingBox::equals() はイプシロン比較です(既定値 0.001)。厳密な浮動小数点等価性はコントラクトではありません。

ツリーの構築とトラバーサルは、ノード数に対して O(n) です。シリアライズはツリーサイズに対して線形です。再現性プロファイルは bitwise です。同じツリーは同じ JSON バイト列にシリアライズされるため、スキーマは安定した永続化コントラクトになります。既定のリファレンスワークロードは、1500 ms の実時間/64 MB のピークという予算に十分収まります。

AstSerializer::deserialize() は、永続化または送信される可能性のある JSON をパースします。まず canDeserialize() で互換性を検証してください。デシリアライズされたツリーのテキストコンテンツと属性は、アプリケーションに再び取り込むときやレンダリングするときには、信頼できない文字列として扱ってください。モジュール自体は I/O を一切行わず、外部データを埋め込みません。エンジンの脅威モデルについては /modules/core/security/ を参照してください。

このモジュールは、PDF 仕様上の規範的主張を一切行いません。セマンティック AST はエンジン内部の抽象です。これは、条項を引用しなければならない標準化された文書モデルを実装するものではありません。AST がアクセシビリティのタグ付けに供給される場合、出力 の PDF/UA およびタグ付き PDF の準拠は /modules/core/accessibility/ および /modules/core/conformance/ で文書化・検証されており、このページでは扱いません。