跳到內容
getnextpdf.com

Pro 版本

Projection — 深入參考

本頁是 Pro Projection 模組的深入參考,記錄公開的 tokenize、emit 與 round-trip 介面、intent 閘門,以及內容串流的來回往返(round-trip)語意。ContentProjectionWriter 會將 PDF 內容串流解析為一個扁平、有序的符記清單,再把符記清單重新序列化為一個新的內容串流。此模型是單向的:發射(emission)會產生一個新的串流,絕不會就地編輯原件。

**注意。**此處的「projection」指的是內容串流符記投影(content-stream token projection),而非座標或地理空間投影。

此能力隨 NextPDF Pronextpdf/pro)出貨,並以 Pro 層級的授權封套啟用。未持有該權利的部署不會載入此能力的類別。比較版本並取得授權

不存在個別功能的授權旗標。這是一項 Pro 版本能力。發射另外還需要一個明確的 ProjectionIntent 引數,由型別系統強制要求,而非授權開關。

Terminal window
composer require nextpdf/pro:^3

此模組位於 NextPDF\Pro\Projection 命名空間。ContentProjectionWriter 上的所有操作皆為靜態。

符號參數預設行為回傳拋出或失敗於備註
ContentProjectionWriter::tokenizestring $contentStream將串流解析為扁平、有序的符記清單;正規化空白、丟棄註解、跳過無法辨識的位元組list<ContentToken>無;格式錯誤或控制位元組會被跳過,而非拒絕唯讀;不需要 intent。
ContentProjectionWriter::emitlist<ContentToken> $tokens, ProjectionIntent $intent將符記序列化為一個新的內容串流;輸出與 intent 值無關string本體中無;缺少引數或非 ProjectionIntent 引數會在型別邊界失敗Intent 是呼叫端的閘門,而非執行期開關。
ContentProjectionWriter::roundTripstring $contentStream先 tokenize、再原樣重新發射;驗證閘門string輸出並非位元組逐一相同;運算子序列與運算元值會被保留。
ContentToken::__constructContentTokenType $type, string|int|float|bool|null $value = null建構一個不可變的符記;不進行任何驗證ContentToken無;型別不相容的 $value 會在型別邊界失敗readonlytypevalue 為公開。
ContentToken::isTextOperator回報該符記是否為文字運算子(BT、ET、Tj、TJ、Td、TD、Tm、T*、Tf、Tc、Tw、Tz、TL、Tr、Ts、'"bool無;對於非運算子符記回傳 false
ContentToken::isTextShowingOperator回報該符記是否為顯示文字運算子(Tj、TJ、'"bool無;對於非運算子符記回傳 false文字運算子的子集。
ContentTokenType—(字串背景列舉)列舉符記判別子:LiteralString、HexString、Number、Name、Operator、ArrayBegin、ArrayEnd、DictBegin、DictEnd、Boolean、Null背景值為穩定識別碼。
ProjectionIntent—(純列舉)列舉兩種允許的發射 intent:Sanitization、SteganographicEmbedding沒有通用 case,因此靜態分析會標示未宣告的使用。
public static function tokenize(string $contentStream): array
public static function emit(array $tokens, ProjectionIntent $intent): string
public static function roundTrip(string $contentStream): string
enum ProjectionIntent
{
case Sanitization;
case SteganographicEmbedding;
}
public function __construct(
public ContentTokenType $type,
public string|int|float|bool|null $value = null,
) {}
public function isTextOperator(): bool
public function isTextShowingOperator(): bool

ContentProjectionWriter::tokenize($contentStream) 會將串流解析為一個扁平、有序的 list<ContentToken>。它涵蓋字面字串、十六進位字串、名稱、數字、陣列與字典分隔符、布林值、null 以及運算子。空白與註解會被消耗並丟棄;無法辨識的位元組會推進游標而不產生符記。此處理是唯讀的,不需要 intent。

emit($tokens, $intent) 會將符記清單序列化回內容串流位元組,並需要一個 ProjectionIntent。intent 僅是呼叫端的宣告:無論傳入哪個 case,發射出的位元組都相同。數字會保留其整數/浮點數區別——整數原樣發射,浮點數最多發射六位小數並修剪尾端的零。字面字串會被重新轉義,十六進位字串以大寫十六進位發射,名稱會帶著其開頭的斜線(solidus)。每個運算子後面會接一個換行;陣列與字典分隔符會抑制相鄰的分隔字元。

roundTrip($contentStream) 會先 tokenize、再原樣重新發射。它是驗證閘門:在信任任何「修改並發射」序列之前,先確認一個乾淨的結果。輸出與輸入並非位元組逐一相同——空白會被正規化、註解會消失——但運算子序列與運算元值會被保留。

ProjectionIntent 恰好只有兩個 case:Sanitization(具破壞性、不可逆的遮蔽)與 SteganographicEmbedding(隱藏酬載嵌入)。沒有通用 case,因此靜態分析能標示任何缺少已宣告、已知目的的發射。ContentToken 是一個不可變的 readonly 值,攜帶一個 type 判別子與一個已解碼的 valueisTextOperator()isTextShowingOperator() 會分類運算子符記,並對每個非運算子符記回傳 false

  • 在任何「修改並發射」序列之前,先確認一次乾淨的來回往返。將失敗的來回往返視為停止條件。
  • Sanitization intent 是不可逆的。已移除的符記不會出現在輸出中,且無法從輸出復原。
  • Intent 不會改變輸出。emit() 對任一 case 都產生相同的位元組;該引數是呼叫端的閘門。遮蔽與隱寫編輯是由呼叫端在發射前變更符記清單來套用。
  • 發射器會正規化空白並丟棄註解,因此即使是未修改的來回往返,與原件進行位元組層級比對也會有差異。
  • 浮點運算元最多格式化為六位小數,然後再修剪。需要更高精度的值會在發射時被四捨五入;整數則是精確的。
  • 輸入時會解碼的字面字串轉義包含 \n\r\t\b\f、經轉義的分隔符,以及最多三位、夾限為一個位元組的八進位轉義。
  • 位數為奇數的十六進位字串在輸入時會以尾端零補齊,符合 ISO 十六進位字串規則。
  • 格式錯誤或控制位元組會被跳過,而非拒絕;tokenize() 對非預期輸入不會拋出例外。
  • 本模組不進行任何密碼學運算,也未定義任何 FIPS 特定行為。

符記化會將串流視為以標準 PDF 物件語法表達的運算子與運算元序列,依 ISO 32000-2:2020, 8.2。位元組到符記的分組遵循 ISO 32000-2:2020, 7.2 的詞法字元類別。奇數長度的十六進位字串會將最後一位補為零,依 ISO 32000-2:2020, 7.3.4.3。這些條款記錄在本頁的引用紀錄中。

這些陳述描述的是相對於所引用條款的能力。NextPDF 未持有任何一致性認證,且對某條款的支援並非認證主張。

  • 自模組 1.10.0 版起可用;三項操作皆為 ContentProjectionWriter 上的靜態進入點。
  • Tokenize 與 emit 的複雜度與內容串流長度呈線性。沒有公布的吞吐量數據;請以具代表性的串流自行量測。
  • 扁平符記模型——每個詞法元素一個符記,而非依運算子分組——正是能進行精準編輯(例如調整 TJ 陣列中的單一數字)的關鍵。依運算子分組的表示形式位於 Pro 樹的其他地方,不在本頁範圍內。
  • ContentToken 是不可變的。請透過建構新符記來組成修改後的清單,而非變更既有符記。
  • 在你的管線中保留來回往返閘門:通過的 roundTrip() 是本模組在任何破壞性編輯之前所圍繞設計的前提條件。

本頁僅記錄外部可觀察的行為與受支援的公開 API 介面。內部命名空間路徑、輔助類別、機制表格、runbook 檔名與工單前綴皆不在範圍內。