콘텐츠로 이동

사용자 지정 레이아웃 엔진과 레이아웃 시점 텍스트 가로채기

NextPDF는 플러그형 레이아웃 엔진 인터페이스를 노출하지 않습니다. 공개 레이아웃 확장 계약은 TextPreprocessorInterface이며, 레이아웃 시점에 텍스트를 가로채는 지점을 제공합니다. 또한 콘텐츠 수명 주기 이벤트를 사용할 수 있으며, 이를 통해 레이아웃이 생성한 결과를 관찰할 수 있습니다.

Terminal window
composer require nextpdf/core:^3

레이아웃 파이프라인은 내부 구성 요소입니다. 여기에는 글리프 레이아웃, 글꼴 서브셋팅, ToUnicode CMap 출력, 구조 트리가 포함되며, NextPDF는 이를 대체할 수 없게 합니다. 안정적인 바이트 출력과 태그된 PDF 적합성은 하나의 통제된 빌드에 의존합니다.

NextPDF가 실제로 노출하는 것은 레이아웃 이전 지점인 TextPreprocessorInterface입니다. 구현체는 원시 텍스트를 받아 분할된 결과를 반환하며, 해당 텍스트가 글리프 레이아웃, 글꼴 서브셋팅, ToUnicode CMap 또는 구조 트리에 들어가기 전에 처리합니다. 이것이 레이아웃 엔진을 건드리지 않고 텍스트 콘텐츠를 변경하는, 지원되는 방법입니다.

이 계약의 소스 PHPDoc에는 엄격한 규칙이 명시되어 있습니다. 구현체는 레이아웃의 동작 방식을 변경해서는 안 됩니다. 줄 바꿈, 캐리지 리턴 또는 탭처럼 레이아웃에 영향을 주는 문자를 추가해서는 안 되며, 논리적 읽기 순서를 유지해야 합니다. 전처리기는 콘텐츠 교체만 명시할 뿐, 레이아웃 선택을 하지 않습니다. 이 규칙을 준수하십시오. 그렇지 않으면 안정적인 출력과 접근성이 손상됩니다.

레이아웃을 변경하지 않고 그 결과를 관찰하려면 액션 트리거 및 이벤트 리스너의 콘텐츠 수명 주기 이벤트를 사용하십시오. ContentRenderedEvent는 콘텐츠가 페이지에 그려진 후 발생합니다. FontLoadedEvent는 글꼴 패밀리와 스타일마다 한 번씩 발생합니다.

NextPDF\Contracts\TextPreprocessorInterface (안정, 1.9.0부터):

메서드반환값용도
process(string $text)TextPreprocessResult렌더링 파이프라인 전에 원시 텍스트를 변환하고, 수정(redaction) 메타데이터가 포함된 분할 결과를 반환합니다.

반환된 NextPDF\Contracts\TextPreprocessResult는 고정 값 객체입니다. 생성자 시그니처와 공개 속성은 안정적이며, 마이너 또는 패치 릴리스에서 변경되지 않습니다. 새 메서드는 추가될 수 있습니다.

이 작은 전처리기는 고정 토큰을 마스킹합니다. 레이아웃에 영향을 주는 문자를 추가하지 않고, 읽기 순서를 유지합니다.

<?php
declare(strict_types=1);
use NextPDF\Contracts\TextPreprocessorInterface;
use NextPDF\Contracts\TextPreprocessResult;
use NextPDF\Contracts\TextSegment;
final class TokenMaskingPreprocessor implements TextPreprocessorInterface
{
public function process(string $text): TextPreprocessResult
{
$masked = \str_replace('SECRET-TOKEN', '••••••••••••', $text);
return new TextPreprocessResult([
new TextSegment($masked, redacted: $masked !== $text),
]);
}
}

프로덕션 전처리기는 매칭 규칙을 한곳에 모아 둡니다. 잘못된 패턴이 있으면 안전 차단(fail closed)되며, 원본 텍스트를 절대 로그에 기록하지 않습니다.

<?php
declare(strict_types=1);
use NextPDF\Contracts\TextPreprocessorInterface;
use NextPDF\Contracts\TextPreprocessResult;
use NextPDF\Contracts\TextSegment;
use Psr\Log\LoggerInterface;
final class PatternRedactionPreprocessor implements TextPreprocessorInterface
{
/**
* @param non-empty-string $pattern A valid PCRE pattern for sensitive spans
*/
public function __construct(
private readonly string $pattern,
private readonly LoggerInterface $logger,
) {}
public function process(string $text): TextPreprocessResult
{
$result = \preg_replace($this->pattern, '[REDACTED]', $text);
if ($result === null) {
// Fail closed: never emit unredacted text on a pattern error.
$this->logger->error('Redaction pattern failed; substituting empty text');
return new TextPreprocessResult([new TextSegment('', redacted: true)]);
}
return new TextPreprocessResult([
new TextSegment($result, redacted: $result !== $text),
]);
}
}
  • 레이아웃 대체 불가. 박스 레이아웃, 줄 바꿈 또는 페이지 매김을 대체할 수 있는 계약은 없습니다. 서드파티 레이아웃 엔진을 연결하려는 요청은 설계상 범위를 벗어납니다.
  • 규칙 시행. process()에서 \n, \r 또는 \t를 추가하면 레이아웃이 손상되고 안정적인 출력이 깨집니다. 엔진은 이 규칙을 신뢰하며, 출력에 레이아웃에 영향을 주는 문자가 있는지 다시 검사하지 않습니다.
  • 읽기 순서. 세그먼트 순서를 변경하면 태그된 PDF 읽기 순서와 PDF/UA 적합성이 깨집니다.
  • 단일 책임. 전처리기는 콘텐츠 교체를 명시합니다. 관찰에는 수명 주기 이벤트를 사용하고, process()로 부작용을 일으키지 마십시오.

process()는 레이아웃 핫 패스에서 텍스트 런마다 한 번씩 실행됩니다. 메모리 사용량을 낮게 유지하십시오. 패턴은 호출할 때마다가 아니라 생성자에서 한 번 컴파일하십시오. 콘텐츠 수명 주기 이벤트는 바인딩된 리스너가 없으면 아무 비용도 발생시키지 않습니다.

TextPreprocessorInterface는 민감한 콘텐츠가 콘텐츠 스트림, 글꼴 서브셋 또는 메타데이터에 도달하기 이전에 이를 제거할 수 있는, 지원되는 위치입니다. 서브셋팅과 ToUnicode CMap 이전에 실행되므로, 수정된 글리프는 파일에 절대 들어가지 않습니다. 전처리기 실패는 안전 차단(fail-closed)으로 처리하고, 원본을 내보내는 대신 빈 텍스트 또는 마스킹된 텍스트를 사용하십시오.

이 페이지에는 규범적 서명 또는 보관(archival) 주장이 적용되지 않습니다. 읽기 순서 규칙은 이 계약을 태그된 PDF의 요구 사항에 맞춥니다. 태그 수준 적합성은 접근성 참조 문서에서 다룹니다.

NextPDF Pro는 일반적인 문서 유형에 맞게 조정된 PII 수정을 포함하여 프로덕션 텍스트 전처리 전략을 제공합니다. Core에서는 TextPreprocessorInterface를 직접 작성하거나, 동일한 공개 계약을 통해 검증된 유료 에디션 빌드를 사용합니다.

용어집은 텍스트 전처리기확장 지점을 정의합니다. 각 표준 정의는 게시된 용어집을 참조하십시오.