15 poin oleh GN⁺ 2025-08-04 | 5 komentar | Bagikan ke WhatsApp
  • Parsing PDF idealnya bekerja berdasarkan urutan dan struktur yang jelas, tetapi file nyata sering kali tidak mengikuti spesifikasi ini
  • Berbagai error dan ketidaksesuaian muncul saat mencari pointer cross-reference (xref) dan offset
  • Dalam praktiknya, banyak masalah muncul karena data yang tidak perlu sebelum header PDF atau posisi pointer dan offset yang salah
  • Ada juga banyak kasus ketika tabel xref PDF itu sendiri tidak jelas atau salah format
  • Karena itu, viewer utama menambahkan implementasi logika tambahan untuk mendukung file PDF nonstandar

Pendekatan ideal terhadap parsing PDF

  • Secara teori, parsing PDF berjalan melalui langkah-langkah yang tetap
    • Mencari komentar header versi di awal file
    • Mencari pointer cross-reference (xref)
    • Mengumpulkan semua offset objek
    • Mencari dictionary trailer untuk mengakses keseluruhan struktur katalog

Pengenalan objek PDF

  • Objek PDF adalah unit yang membungkus dan menyimpan berbagai elemen PDF seperti angka, string, dictionary, dan lain-lain
  • Setiap objek berada di antara marker "obj/endobj"
  • Objek saling terhubung melalui referensi tidak langsung (indirect reference, misalnya: "16 0 R")
  • Cara objek dipisahkan di dalam file bersifat bebas, tetapi beberapa jenis objek wajib berupa referensi tidak langsung

Mencari offset cross-reference

  • Dalam struktur PDF terdapat tabel cross-reference (xref), yang berfungsi sebagai indeks lokasi objek
  • Di akhir file, posisi byte tertentu dinyatakan sebagai pointer melalui sintaks "startxref"
  • Pointer ini menunjuk lokasi xref, tetapi ada perbedaan antara spesifikasi dan file nyata. Misalnya, marker "%EOF" seharusnya berada di baris terakhir, tetapi pada PDF dunia nyata bisa berada di mana saja dalam 1.024 byte terakhir
  • Pada file nyata ditemukan berbagai variasi seperti kesalahan format pointer (startref dan sebagainya), tidak adanya line break, dan lain-lain

Mencari offset objek

  • Tabel xref terdiri dari "xref", nomor awal objek, dan jumlah objek secara berurutan, lalu offset/generation number/status tiap objek (n atau f) dicatat per baris
  • Tabel xref bisa berjumlah lebih dari satu, atau saling terhubung melalui entri /Prev

Menelusuri lokasi dictionary trailer

  • Di atas marker startxref terdapat dictionary trailer, yang berisi metadata penting untuk menemukan objek root
  • Berdasarkan objek root, interpretasi seluruh struktur dapat dimulai

Lingkungan nyata: masalah-masalah tak terduga

  • Banyak file yang tidak mematuhi spesifikasi PDF, sehingga sulit ditangani dengan parser umum

  • Kasus kegagalan yang umum saat menelusuri pointer cross-reference

    • Pointer tidak berada di akhir file atau 1.024 byte terakhir
    • Salah ketik (startref dan sebagainya)
    • Format yang tidak lazim
  • Dalam investigasi terhadap 3.977 sampel PDF nyata, sekitar 0,5% memiliki kesalahan deklarasi xref

Konten PDF dimulai pada offset yang bukan 0

  • Jika ada data sampah (junk) sebelum header, semua offset byte akan bergeser sehingga posisi startxref menjadi meleset
  • Offset harus dihitung ulang berdasarkan posisi header, dan kedua posisi perlu diperiksa
  • Ini mencakup sekitar 50% dari seluruh error

Pointer xref menunjuk ke tengah tabel xref

  • Offset yang ditentukan bisa saja bergeser ke tengah isi tabel xref
  • Ditemukan pada sekitar 5 dari 3.977 sampel

Pointer berada di dekat xref

  • Sering kali pointer tidak tepat, tetapi hanya meleset sebesar spasi atau karakter newline tepat sebelum atau sesudah xref

Pointer benar, tetapi offset xref salah

  • Offset yang tercatat di tabel xref itu sendiri bisa salah
  • Sebagian objek mungkin benar, sementara sisanya memiliki error offset

Pointer pertama normal, tetapi offset sebelumnya (/Prev) aneh

  • Ada banyak kasus ketika pointer /Prev yang dibuat saat PDF dimodifikasi menyimpan nilai yang salah (misalnya 0)

Format tabel xref tidak normal

  • Ada berbagai kasus seperti "xref" dan angka yang menempel tanpa line break, jumlah entri yang lebih banyak daripada objek yang dideklarasikan, atau data sampah di tengah tabel
  • Kasus-kasus seperti ini banyak dilaporkan sebagai issue di PdfPig dan lainnya

Kesimpulan

  • Menurut spesifikasi, parsing PDF seharusnya diproses dalam urutan yang terstruktur, tetapi banyak file nyata tidak seperti itu sehingga berbagai masalah parsing pun muncul
  • Viewer PDF untuk penggunaan nyata pada dasarnya menyertakan fitur untuk memperluas dukungan terhadap PDF nonstandar
  • Ringkasan kali ini hanya membahas sebagian parsing yang termasuk dalam spesifikasi PDF (22 halaman dari total 1300 halaman)

5 komentar

 
mhj5730 2025-08-06

Ringkasan kali ini hanya membahas parsing sebagian kecil dari spesifikasi PDF (22 halaman dari total 1300 halaman) <- ... 1300 halaman, luar biasa sekali...

 
kaydash 2025-08-05

Wow..

 
spp00 2025-08-05

PDF, terus terang saja, adalah format yang ramah untuk dibaca manusia karena sebisa mungkin mempertahankan tata letak buatan manusia, dan benar-benar buruk untuk dipadukan dengan mesin.

 
reagea0 2025-08-05

Saya paham. Sebenarnya, saya juga tidak yakin apakah itu nyaman dibaca.. Terlalu berat dan tidak praktis.

 
GN⁺ 2025-08-04
Komentar Hacker News
  • Jawabannya jelas

    1. PDF mendukung pelampiran metadata dalam format apa pun yang diinginkan
    2. Semua perangkat lunak pembuat PDF harus melampirkan informasi yang sama dengan cara yang mudah dibaca mesin
    3. Dengan begitu, orang yang ingin mem-parsing PDF cukup melihat metadata
      Dalam praktiknya, nama saya Geoff, tetapi setengah dari parser resume mengenali nama saya secara terpisah sebagai "Geo" dan "ff"
      Ini terjadi karena cara teks dimasukkan ke dalam PDF, dan masalah ini terus muncul dari berbagai aplikasi sumber
    • Parsing PDF dan parsing konten PDF adalah dua hal yang sepenuhnya berbeda
      Parsing file PDF saja sudah merepotkan, tetapi karena PDF sendiri berbasis "menaruh sesuatu di posisi tertentu", bukan teks yang terdefinisi jelas di dalam kotak pembatas, untuk mengekstrak kata Anda harus menebak huruf mana yang termasuk bersama
      Jika ingin membantu parser resume, ada baiknya memperhatikan accessibility tree
      Tidak semua renderer PDF mengekspor PDF aksesibel, tetapi PDF aksesibel setidaknya bisa membantu membaca hal seperti nama dengan benar
      Masalah "ff" kemungkinan karena analis resume tidak bisa menangani karakter non-ASCII, misalnya ligatur
      Renderer PDF bisa diatur agar tidak membuat ligatur, tetapi ini bisa membuat tampilan teks jadi jelek

    • Rasanya terlalu banyak berharap pada kata "should"
      Kalau penggunaan PDF pada kenyataannya cukup bersifat memusuhi, sepertinya orang tidak akan berpikir sejauh itu
      Salah satu tujuan mengirim resume sebagai PDF memang agar perantara di tengah tidak bisa mengubahnya, dan "pengeditan" juga punya banyak alasan lain, seperti menutupi sesuatu dengan kotak di atas gambar, atau membuat tabel sebagai PDF alih-alih CSV agar lebih sulit dianalisis

    • Sebenarnya pendekatan ini kadang memang bekerja dengan baik, dan beberapa aplikasi sudah menggunakannya
      Hanya saja, masalah dua representasi (isi/metadata) yang tidak benar-benar cocok tetap ada

    • Ada juga pertanyaan tentang bagaimana dengan hasil scan tulisan tangan atau dokumen hasil scan lain jika scanner dan komputer rumahan biasa tidak punya dukungan OCR yang sempurna

    • Mungkin masalahnya memang karena ff dirender sebagai ligatur

  • Saya pendiri Tensorlake
    Kami membuat API parsing dokumen untuk developer
    Inilah alasan pendekatan Computer Vision benar-benar bekerja di lapangan untuk parsing PDF
    Hanya bergantung pada metadata di dalam file tidak skalabel untuk beragam sumber PDF
    Jadi pendekatannya adalah mengubah PDF menjadi gambar, lalu menerapkan model pengenalan layout terlebih dahulu, kemudian menjalankan model khusus seperti pengenalan teks dan tabel, lalu menggabungkan potongan-potongannya, sehingga menghasilkan output yang layak dipakai bahkan di bidang yang menuntut akurasi tinggi

    • Sekilas pendekatan ini terlihat konyol, tetapi sebenarnya terasa seperti solusi yang paling realistis
      PDF pada dasarnya dirancang untuk merepresentasikan layout yang dibaca manusia, bukan format yang dirancang agar bisa dibaca komputer, melainkan format yang berfokus pada tampilan yang bagus
      Karena itu, pendekatan yang meniru cara manusia membaca terasa masuk akal
      Meski begitu, tetap disayangkan bahwa selama lebih dari 30 tahun PDF belum berhasil menambahkan keterbacaan mesin
      Saya penasaran insentif apa yang kurang sehingga hal ini tidak pernah terwujud
      Kalau ada yang punya wawasan soal ini, saya ingin mendengarnya

    • Ada sisi yang agak lucu
      Mencetak PDF, memindainya, lalu mengirimkannya lewat email terasa seperti sesuatu yang pantas ditertawakan, tetapi dalam parsing PDF kita pada dasarnya melakukan hal yang sama
      Kenyataan bahwa pendekatan seperti itu diperlukan memang membuat frustrasi
      Dunia tidak mem-parsing HTML seperti itu

    • Saya salah satu pendiri Nutrient.io, sudah lebih dari 10 tahun menangani PDF
      Seperti browser web, viewer PDF harus menerima PDF dengan variasi yang sangat besar
      Karena PDF sudah sangat tua, pembuat file sering melakukan modifikasi sembarangan selama tampilannya baik-baik saja di viewer yang mereka pakai
      Karena itu perusahaan kami membuat AI document processing SDK (REST API yang menerima PDF sebagai input dan mengembalikan data terstruktur dalam JSON)
      Bukan hanya metode visual, dengan pengalaman pada preprocessing/postprocessing struktural kami bisa memberi hasil yang lebih baik baik dari sisi performa maupun biaya dibanding pendekatan vision murni
      Jika Anda tidak ingin repot memikirkan pemrosesan PDF secara langsung dan ingin fokus pada pekerjaan inti Anda, ini mungkin bisa membantu
      https://www.nutrient.io/sdk/ai-document-processing

    • Mumpung ada ahli struktur internal PDF di sini, saya punya pertanyaan
      Saya penasaran kenapa mupdf-gl (setidaknya pada desktop Linux standar) jauh lebih cepat daripada semua program lain
      Kecepatan pencarian pada PDF besar terasa jelas lebih unggul, dan saya selalu penasaran kenapa viewer lain tidak bisa secepat ini
      Kalau ada wawasan terkait, saya ingin mendengarnya

    • Pada akhirnya, Anda hanya mengalihdayakan pekerjaan parsing ke perangkat lunak yang dipakai saat merender PDF menjadi gambar

  • Sudah lama saya berpikir bahwa kita perlu keluar dari komunikasi dokumen yang terlalu berpusat pada layout
    Artinya, layout yang dipoles secara profesional itu sendiri sebenarnya lebih mirip kebiasaan lama, dan hampir tidak berhubungan dengan pemahaman terhadap konten yang sebenarnya
    Misalnya, dokumen yang dikirim ke berbagai lembaga regulator sering kali sangat tebal, dan untuk memenuhi aturan layout Anda akhirnya menghabiskan banyak waktu bekerja di Microsoft Word
    Untuk menjamin layout seperti ini, dokumen dikirim dalam format DOCX atau PDF, tetapi format-format ini sangat tidak cocok untuk program yang ingin mengekstrak atau mengolah isinya secara otomatis
    LLM memang bisa membaca file-file ini, tetapi biaya komputasinya jauh lebih besar dibanding file yang sederhana dan ramah mesin seperti teks, markdown, XML, JSON, dan sebagainya

    Sebagai alternatif, saya membayangkan kemungkinan menstandarkan format sederhana yang benar-benar 'machine-first' dan 'content-first' (misalnya berbasis JSON, XML, HTML)
    Cukup punya struktur minimal dan informasi embed gambar, lalu saat dibaca manusia, viewer app yang menyusunnya ulang agar enak dilihat
    Pemrosesan mesin akan jauh lebih mudah
    Meski format serupa seperti HTML/browser dan EPUB sudah ada, saya rasa sekarang waktunya menggantikan cara klasik
    Saya berharap revolusi LLM mendorong arah ini, dan semoga parsing PDF mahal nantinya hanya tersisa di pipeline lama

    • Saya setuju soal masalah PDF, tetapi apakah DOCX memang seburuk itu?
      Saya belum pernah membuat parser DOCX, tetapi karena DOCX berbasis XML dan tidak semua hal dipakukan ke koordinat absolut kecuali layout ditentukan secara eksplisit, dugaan saya jika JPEG nilainya 0, PDF 15, dan markdown 100, maka DOCX mungkin sekitar 80 dari sisi kemudahan
  • Menurut saya ini rangkuman yang sangat bagus, dan ada poin tambahan yang menarik bagi saya
    Rantai incremental-save: offset startxref pertama baik-baik saja, tetapi tautan /Prev yang ditambahkan berulang kali setiap kali Acrobat mengubah file sering menunjuk beberapa byte lebih pendek dari xref berikutnya
    Kebanyakan viewer (bahkan PDF.js, MuPDF, dan Adobe Reader) akan secara bodoh mencari token obj di seluruh file dan membangun ulang tabel baru, sedangkan parser yang taat spesifikasi justru meledak
    Jika Anda ingin menangani dokumen di dunia nyata yang telah dimodifikasi berulang kali oleh berbagai aplikasi, jalur pemulihan seperti ini wajib ada

    • Benar sekali, ini adalah salah satu kasus gagal yang sering saya lihat di kumpulan sampel
      Referensi sebelumnya, atau salah satu elemen dalam rantainya, sering menunjuk ke offset di luar file, offset 0, atau nilai yang salah
      Alasan saya menulis artikel itu adalah karena saya sedang merombak logika parsing awal di proyek saya, PdfPig
      Awalnya saya mem-porting kode Java PDFBox, tetapi saya ingin membuatnya lebih cepat dan lebih sederhana
      Logika baru akan memindai seluruh file jika ada satu saja tabel/stream xref yang terlewat, dan pada jalur pemulihan hanya mempercayai offset tersebut
      Namun hasilnya jelas lebih lambat dari sebelumnya, dan saya sulit yakin apakah perubahan ini benar-benar layak
      Saya sedang menelusuri berbagai kasus aneh (edge case) dengan test set berisi 10.000 file
      https://github.com/UglyToad/PdfPig/pull/1102
  • Rasanya ini akan mudah jika ada asumsi yang bekerja dan parser objek PDF yang memadai, tetapi kenyataannya sama sekali tidak begitu
    Situasi ini seperti neraka PDF
    PDF bukan spesifikasi, melainkan kesepakatan sosial, semacam 'vibes'
    Semakin Anda berjuang, semakin dalam Anda tenggelam, dan sekarang rasanya kita semua hidup di rawa yang jauh dari pandangan Tuhan
    Saya tertawa membaca ini

    • Ini bercanda seolah-olah tulisan ini ditulis oleh James Mickens
  • Untuk pertanyaan "Ingin mem-parsing PDF?", saya bisa mengatakan dengan tegas: sama sekali tidak
    Alasannya dijelaskan dengan baik di tulisan aslinya

    • Saya berharap bank saya menyediakan dokumen dalam format yang lebih mudah dibaca, tetapi sampai saat itu ya mau bagaimana lagi

    • Saya sudah pernah melakukan kesalahan itu, dan tidak berniat mengulanginya

  • Sebagai orang yang pernah menulis parser PDF, menurut saya PDF itu format yang benar-benar aneh
    Sepertinya desain dasarnya sebagai campuran biner dan teks yang melahirkan banyak keanehan ini
    Masalah offset xref yang sedikit meleset kemungkinan juga berasal dari bug saat menangani konversi line ending LF/CR
    Salah satu hal yang tidak disebut di tulisan adalah bahwa PDF modern (v1.5+) sering disimpan sebagai "xref stream" tanpa tabel xref teks biasa
    Pada v1.6 ke atas, objek itu sendiri juga bisa disimpan di dalam object stream

    • Saya juga agak heran pembahasannya tidak melampaui tabel xref sederhana hingga ke stream dan kompresi
      Awalnya terlihat tidak masalah, tetapi begitu objek yang Anda cari ternyata ada di dalam stream, dan stream itu sendiri memakai varian kompresi PNG, atau offset berada di xref stream yang dikompresi flate, segalanya jadi merepotkan
      Ditambah lagi berbagai versi dokumen bercampur, sehingga menentukan bagian mana yang paling mutakhir juga rumit
      Dokumen PDF 1.7 mudah ditemukan, tetapi sampai dua tahun lalu materi spesifikasi PDF 2.0 masih berada di balik paywall
  • PDF bukan format yang mempertimbangkan streaming
    Karena ada trailer dictionary di bagian akhir, file sulit diparsing sebelum seluruhnya dimuat
    Meski begitu, ada juga "streaming-capable PDF", jadi jika informasi yang dibutuhkan ada di bagian awal, halaman pertama bisa langsung dirender tanpa mengunduh seluruh file, walau sisanya belum tentu
    Sudah agak lama saya jauh dari dunia PDF, jadi mohon dimaklumi

    • Meski ada footer, selama situs web mendukung Range Request dan menggunakan header Content-Length dengan benar, PDF tetap bisa di-stream
      Reader streaming cukup melakukan permintaan HEAD, lalu meminta beberapa ratus byte terakhir file untuk mendapatkan pointer dan tabel, setelah itu melanjutkan mengambil sisanya
      Ini memang tidak cocok untuk PDF yang dibuat secara real-time, tetapi untuk web server yang cukup tua pun tambahan 1-2 round trip saja sudah cukup
      Memang sayangnya jarang ada yang benar-benar memperhatikan parser berbasis Range per file, tetapi secara teknis ini bukan sesuatu yang mustahil

    • Betul, ada format bernama Linearized PDF yang dirancang agar halaman pertama bisa ditampilkan cepat tanpa harus mengunduh seluruh file
      Perlu diketahui bahwa dalam ringkasannya, pendekatan itu dihilangkan karena membutuhkan banyak penjelasan tambahan

  • Salah satu proyek pertama yang saya coba setelah belajar Python adalah parser PDF
    Tujuannya mengekstrak peta secara otomatis untuk kampanye DnD, tetapi hasilnya gagal total, haha

  • Saya pernah menulis reader TIFF
    TIFF juga terkenal sebagai format yang mudah ditulis tetapi sulit dibaca
    Sepertinya PDF masuk ke kategori yang sama