Ast : arbre sémantique du document et sérialisation
En un coup d’œil
Section intitulée « En un coup d’œil »Le module Ast est l’arbre sémantique du document du moteur. Il modélise un document comme une hiérarchie de nœuds typés — Document, Section, Heading, Paragraph, List, Table, Figure, Code, FormField — avec des zones englobantes, des ancres de citation et une sérialisation JSON versionnée. La couche de balisage d’accessibilité s’en sert pour produire un arbre de structure.
Stabilité : expérimentale. Il s’agit d’une surface de modèle interne. Ses classes ne bénéficient pas de garanties d’API publique figées par version ; l’ensemble des nœuds ainsi que les attributs de nœud évoluent. Le schéma de sérialisation est versionné indépendamment (
AstDocument::CURRENT_SCHEMA_VERSION = '1.0.0'). Le sérialiseur peut détecter et rejeter un schéma incompatible, de sorte que le JSON d’AST persisté a un contrat stable même lorsque l’API en mémoire ne l’a pas.
Installation
Section intitulée « Installation »composer require nextpdf/core:^3Vue d’ensemble conceptuelle
Section intitulée « Vue d’ensemble conceptuelle »Ici, un AST est une abstraction sémantique de la structure logique d’un document, et non un arbre syntaxique produit par un analyseur pour un seul format d’entrée. AstDocument est le conteneur. Il contient le AstNode racine (qui doit être NodeType::Document), une version de schéma, une empreinte du PDF source et un nombre de pages. Il rejette toute construction invalide (version de schéma vide, nombre de pages inférieur à un, type de racine erroné).
AstNode est le nœud récursif. NodeType énumère les genres sémantiques. Un nœud contient des enfants, un BoundingBox optionnel, un contenu textuel optionnel et des attributs validés par schéma via NodeAttributeSchema. L’API de nœud est conçue pour la dérivation immuable. withBboxAndText() renvoie un nouveau nœud. deepClone() copie un sous-arbre. NodeId porte l’identité sous forme d’objet-valeur. CitationAnchor relie un nœud à un emplacement source pour la traçabilité. AstNodeCollection est un ensemble Countable/IteratorAggregate filtrable par ofType().
AstSerializer est la frontière de persistance. serialize() écrit un AstDocument en JSON. deserialize() le relit. canDeserialize() et extractSchemaVersion() permettent à un consommateur de vérifier la compatibilité avant l’analyse, de sorte qu’une incompatibilité de schéma reste une condition détectée plutôt qu’un chargement corrompu. AstDocument::estimateTokenCount() existe parce que l’arbre sert aussi à dimensionner le contenu pour un traitement aval borné par les jetons.
Surface d’API
Section intitulée « Surface d’API »| Classe | Membres clés | Rôle |
|---|---|---|
AstDocument | toJson(), nodeCount(), estimateTokenCount(), CURRENT_SCHEMA_VERSION | Conteneur racine ; valide le type de racine et le schéma |
AstNode | addChild(), children(), childCount(), totalNodeCount(), withBboxAndText(), deepClone() | Nœud sémantique récursif |
NodeType (énumération) | Document, Heading, Table, Figure, FormField, … | Genre de nœud sémantique |
AstNodeCollection | add(), count(), isEmpty(), ofType(), toArray() | Ensemble de nœuds itérable et filtrable par type |
AstSerializer | serialize(), deserialize(), canDeserialize(), extractSchemaVersion() | Persistance JSON versionnée |
BoundingBox | toArray(), equals() | Objet-valeur géométrique (comparaison epsilon) |
NodeId / CitationAnchor | toString(), equals(), toArray() | Ancre d’identité de nœud et de traçabilité de source |
NodeAttributeSchema | validation des attributs | Schéma pour les attributs de nœud |
Exécute composer docs:generate-api-php -- --module=Ast pour obtenir la table PHPDoc complète.
Exemple de code — Démarrage rapide
Section intitulée « Exemple de code — Démarrage rapide »Construis un petit arbre et sérialise-le.
<?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 */);Exemple de code — Production
Section intitulée « Exemple de code — Production »Effectue un aller-retour défensif sur un AST persisté, en vérifiant la compatibilité du schéma avant de désérialiser du JSON non fiable.
<?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); }}Cas limites & pièges
Section intitulée « Cas limites & pièges »AstDocumentexige que le nœud racine soitNodeType::Document. Un arbre avec toute autre racine lève une exception à la construction.AstNode::withBboxAndText()etdeepClone()renvoient de nouvelles instances. Les mutateurs de nœud existants (addChild()) mutent. Les assistants de dérivation, eux, ne mutent pas. Vérifie lequel tu appelles.- Protège toujours
deserialize()aveccanDeserialize()pour du JSON provenant de l’extérieur. Une incompatibilité de version de schéma est une condition détectable et attendue. estimateTokenCount()est une estimation destinée à dimensionner le traitement aval, pas un décompte exact de tokeniseur. Ne le considère pas comme faisant autorité.BoundingBox::equals()est une comparaison epsilon (0.001 par défaut). L’égalité exacte des flottants n’est pas le contrat.
Performance
Section intitulée « Performance »La construction et le parcours de l’arbre sont en O(n) par rapport au nombre de nœuds. La sérialisation est linéaire par rapport à la taille de l’arbre. Le profil de reproductibilité est bitwise. Un même arbre se sérialise vers les mêmes octets JSON, ce qui fait du schéma un contrat de persistance stable. La charge de référence par défaut reste largement dans le budget de 1500 ms en temps écoulé / 64 Mo en pic.
Notes de sécurité
Section intitulée « Notes de sécurité »AstSerializer::deserialize() analyse du JSON susceptible d’avoir été persisté ou transmis. Valide d’abord la compatibilité avec canDeserialize(). Considère le contenu textuel et les attributs de l’arbre désérialisé comme des chaînes non fiables lorsqu’ils réintègrent l’application ou sont rendus. Le module lui-même n’effectue aucune E/S et n’intègre aucune donnée externe. Consulte le modèle de menaces du moteur dans /modules/core/security/.
Conformité
Section intitulée « Conformité »Ce module n’affirme aucune revendication normative de spécification PDF. L’AST sémantique est une abstraction interne au moteur. Il n’implémente pas un modèle de document normalisé dont les clauses devraient être citées. Lorsque l’AST alimente le balisage d’accessibilité, la conformité PDF/UA et PDF balisé de la sortie est documentée et validée sur /modules/core/accessibility/ et /modules/core/conformance/, pas ici.
Voir aussi
Section intitulée « Voir aussi »- Module Accessibility — utilise l’AST pour construire l’arbre de structure.
- Module Inspect — inspection de la mise en page et de la structure.
- Module HTML — une source de structure documentaire.
- Aperçu de la conformité