Ast: árvore semântica de documentos e serialização
Visão geral
Seção intitulada “Visão geral”O módulo Ast fornece a árvore de sintaxe abstrata (AST) semântica de documentos do engine. Ele modela um documento como uma hierarquia de nós tipados: Document, Section, Heading, Paragraph, List, Table, Figure, Code e FormField. O modelo registra caixas delimitadoras e âncoras de citação, e serializa tudo como JavaScript Object Notation (JSON) versionado. A camada de marcação de acessibilidade usa essa árvore para produzir uma árvore de estrutura.
Estabilidade: experimental. Esta é uma superfície de modelo interna. Suas classes não oferecem garantias de interface de programação de aplicações (API) pública congelada por versão. O conjunto de nós e os atributos de nó podem mudar. O esquema de serialização tem versionamento independente (
AstDocument::CURRENT_SCHEMA_VERSION = '1.0.0'). O serializador detecta e rejeita um esquema incompatível, de modo que o JSON da AST persistido mantém um contrato estável mesmo quando a API em memória muda.
Instalação
Seção intitulada “Instalação”composer require nextpdf/core:^3Visão geral conceitual
Seção intitulada “Visão geral conceitual”Aqui, uma AST representa a estrutura lógica de um documento. Ela não é uma árvore de sintaxe de parser para um único formato de entrada. AstDocument é o contêiner. Ele contém o AstNode raiz (que deve ser NodeType::Document), uma versão de esquema, um hash do arquivo Portable Document Format (PDF) de origem e uma contagem de páginas. Ele rejeita construções inválidas, incluindo versão de esquema vazia, contagem de páginas inferior a um ou tipo de raiz incorreto.
AstNode é o nó recursivo. NodeType enumera os tipos semânticos. Um nó carrega filhos, um BoundingBox opcional, conteúdo de texto opcional e atributos validados por NodeAttributeSchema. A API do nó oferece suporte a derivação imutável. withBboxAndText() retorna um novo nó. deepClone() copia uma subárvore. NodeId representa a identidade como objeto de valor. CitationAnchor vincula um nó a uma localização de origem para rastreabilidade. AstNodeCollection é um conjunto Countable/IteratorAggregate com filtragem por ofType().
AstSerializer é a fronteira de persistência. serialize() grava um AstDocument em JSON. deserialize() o lê de volta. canDeserialize() e extractSchemaVersion() permitem que você verifique a compatibilidade antes da análise, fazendo com que uma incompatibilidade de esquema seja uma condição detectada em vez de resultar em um carregamento corrompido. AstDocument::estimateTokenCount() ajuda a dimensionar o conteúdo para processamento posterior limitado por tokens.
Superfície da API
Seção intitulada “Superfície da API”| Classe | Membros principais | Função |
|---|---|---|
AstDocument | toJson(), nodeCount(), estimateTokenCount(), CURRENT_SCHEMA_VERSION | Contêiner raiz; valida o tipo da raiz e o esquema |
AstNode | addChild(), children(), childCount(), totalNodeCount(), withBboxAndText(), deepClone() | Nó semântico recursivo |
NodeType (enum) | Document, Heading, Table, Figure, FormField, … | Tipo de nó semântico |
AstNodeCollection | add(), count(), isEmpty(), ofType(), toArray() | Conjunto iterável de nós, filtrável por tipo |
AstSerializer | serialize(), deserialize(), canDeserialize(), extractSchemaVersion() | Persistência JSON versionada |
BoundingBox | toArray(), equals() | Objeto de valor de geometria (comparação por epsilon) |
NodeId / CitationAnchor | toString(), equals(), toArray() | Identidade de nó e âncora de rastreabilidade de origem |
NodeAttributeSchema | validação de atributos | Esquema para atributos de nó |
Execute composer docs:generate-api-php -- --module=Ast para gerar a tabela PHPDoc completa.
Exemplo de código — Início rápido
Seção intitulada “Exemplo de código — Início rápido”Construa uma árvore pequena e, em seguida, serialize-a.
<?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 */);Exemplo de código — Produção
Seção intitulada “Exemplo de código — Produção”Faça round-trip de uma AST persistida de forma defensiva. Verifique a compatibilidade do esquema antes de desserializar JSON não confiável.
<?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); }}Casos extremos & pegadinhas
Seção intitulada “Casos extremos & pegadinhas”AstDocumentexige que o nó raiz sejaNodeType::Document. Uma árvore com qualquer outra raiz lança uma exceção durante a construção.AstNode::withBboxAndText()edeepClone()retornam novas instâncias. Os mutadores de nó disponíveis (addChild()) modificam o nó. Os auxiliares de derivação, não. Saiba qual método você está chamando.- Sempre proteja
deserialize()comcanDeserialize()para JSON de origem externa. Uma incompatibilidade de versão de esquema é uma condição esperada e detectável. estimateTokenCount()é uma estimativa para dimensionar o processamento posterior, não uma contagem exata do tokenizador. Não a trate como autoritativa.BoundingBox::equals()é uma comparação por epsilon (padrão 0.001). A igualdade exata de ponto flutuante não é o contrato.
Desempenho
Seção intitulada “Desempenho”A construção e a travessia da árvore são O(n) em relação à contagem de nós. A serialização é linear em relação ao tamanho da árvore. O perfil de reprodutibilidade é bitwise. A mesma árvore é serializada para os mesmos bytes JSON, o que mantém o esquema estável como contrato de persistência. A carga de trabalho de referência padrão permanece bem dentro do orçamento de 1500 ms de tempo de parede / 64 MB de pico.
Notas de segurança
Seção intitulada “Notas de segurança”AstSerializer::deserialize() analisa JSON que pode ter sido persistido ou transmitido. Valide primeiro a compatibilidade com canDeserialize(). Trate o conteúdo de texto e os atributos da árvore desserializada como strings não confiáveis quando eles voltarem a entrar na aplicação ou forem renderizados. O módulo em si não realiza nenhuma input/output (I/O) e não incorpora dados externos. Consulte o modelo de ameaças do engine em /modules/core/security/.
Conformidade
Seção intitulada “Conformidade”Este módulo não faz nenhuma afirmação normativa sobre a especificação PDF. A AST semântica é uma abstração interna do engine. Ela não implementa um modelo de documento padronizado cujas cláusulas precisem ser citadas. Onde a AST alimenta a marcação de acessibilidade, a conformidade PDF/UA e de PDF marcado da saída é documentada e validada em /modules/core/accessibility/ e /modules/core/conformance/, não aqui.
Consulte também
Seção intitulada “Consulte também”- Módulo Accessibility — usa a AST para construir a árvore de estrutura.
- Módulo Inspect — inspeciona o layout e a estrutura.
- Módulo HTML — fornece uma fonte de estrutura de documento.
- Visão geral de Conformidade