Teknik Makale

PDFlibPas ile Delphi'de PDF'ten Markdown ve DOCX'e Dönüşüm

PDFlibPas, Office otomasyonu olmadan PDF içeriğini iki düzenlenebilir biçime dönüştürür. ExportPageMarkdown ve ExportDocumentMarkdown, çıkarımla üretilmiş başlıklar, sıralı ve sırasız listeler ile boru işaretli tablolar içeren anlamlı Markdown döndürürken, SaveDOCXToFile ve SaveDOCXToStream paragraflar, başlıklar, yerel liste numaralandırması, tespit edilmiş tablolar, yazı tipi biçimlendirmesi, sayfa sonları ve konumlandırılmış PNG görüntüleri içeren bir WordprocessingML paketi yazar

Her ikisi de tamamen Pascal içinde, bir sunucuda, kurulu Word olmadan ve COM olmadan çalışır. Bu özelliğin bir masaüstü aracında değil bir PDF kütüphanesinde bulunmasının nedeni de bu kısıtlamadır

"PDF'ten Word'e" dönüşüm neden gerçekten zordur?

Çünkü bir PDF sayfası paragraf içermez. İçinde, üreticinin yazdığı sırayla glif dizilerini koordinatlara yerleştiren metin gösterme operatörleri bulunur ve iki dizinin aynı cümleye, hatta aynı liste öğesine ait olduğunu belirtme zorunluluğu yoktur. Biçim, basılı bir sayfayı tam olarak tanımlamak için tasarlanmıştır ve bunu, sayfayı üreten yapıyı atarak başarır

Bu yüzden her dönüştürücü, üretecin attığı şeyi yeniden inşa etmek zorundadır. Satır gruplaması, dikey boşluktan ve taban çizgisi hizalamasından gelir. Paragraf sınırları, boşluk değişikliklerinden ve girintiden gelir. Bir başlık, yazı tipi gövdeden daha büyük veya daha kalın olan ve sonrasındakinden ayrışan bir satırdır. Bir liste, bir madde işareti veya sayı düzeniyle başlayan bir paragraf dizisidir. Bir tablo, kenarları satırlar ve sütunlar boyunca hizalanan metin bloklarından oluşan bir ızgaradır. Bunların her biri bir çıkarımdır ve çıkarım, sıradan tipografik kurallara uyan belgelerde iyi, uymayanlarda ise vasat bir sonuç anlamına gelir

Etiketlenmiş PDF'ler, hem de büyük bir istisnadır. Belge bir yapı ağacı taşıdığında, paragraf, başlık, liste ve tablo rolleri tahmin edilmek yerine kayıtlıdır; etiketlenmiş PDF erişilebilirlik yapısında anlatılan erişilebilirlik çalışmasının dönüşüm kalitesinde de karşılığını vermesinin nedeni budur. Üreticiyi siz kontrol ediyorsanız, çıktınızı etiketlemek, onu daha sonra dönüştürmek zorunda kalacak herkes için yapabileceğiniz en yüksek getirili tek şeydir

Markdown dışa aktarımı, sayfa sayfa

Markdown yolu, hedefin bir metin hattı olduğu durumlarda başvurulacak yoldur: bir belgelendirme sitesi, bir arama dizini, bir asistan için bir alım korpusu. Seçenekler bir bit maskesidir: PDF_MARKDOWN_INCLUDE_PAGE_MARKERS, PDF_MARKDOWN_DETECT_HEADINGS, PDF_MARKDOWN_PRESERVE_STYLES, ve üçünü birleştiren PDF_MARKDOWN_DEFAULT

var
  Pdf: TPDFlib;
  Md: WideString;
begin
  Pdf := TPDFlib.Create;
  try
    Pdf.LoadFromFile('handbook.pdf', '');

    // Tek bir sayfa, bir dize olarak
    Md := Pdf.ExportPageMarkdown(1, PDF_MARKDOWN_DEFAULT);

    // Bir sayfa aralığı, BOM olmadan UTF-8 olarak diske akıtılır
    Pdf.SaveMarkdownToFile('1-40',
      PDF_MARKDOWN_DETECT_HEADINGS or PDF_MARKDOWN_PRESERVE_STYLES,
      'handbook.md');
  finally
    Pdf.Free;
  end;
end;

Sayfa işaretçileri, alım işinde kendini kanıtlar. Geldiği sayfayı taşıyan bir metin parçası kesin olarak alıntılanabilir ve alıntıyı takip eden bir okuyucu, iddianın gerçekten bulunduğu yere iner. Markdown insan tarafından okunmak üzere üretiliyorsa bunları kapatın, çünkü kaynak düzenden gelen sayfa sınırları burada gürültüdür

Akış giriş noktaları büyük belgeler için önem taşır. SaveMarkdownToStream ve SaveMarkdownToFile, UTF-8'i bir seferde bir sayfa yazar ve tam çıktıyı arabelleğe almaz; bu yüzden 900 sayfalık bir kılavuz önce belleğe 900 sayfalık bir dizi olarak yüklenmez. Bayt sırası işaretinin yokluğu da bilinçlidir: bir Markdown dosyasındaki bir BOM, şaşırtıcı sayıda statik site üretecini ve fark aracını karıştırır

Makinede Office olmadan DOCX

DOCX yazıcısı paketin kendisini üretir: ham Deflate olarak CRC denetimleriyle yazılmış ZIP girdileri, WordprocessingML parçaları ve bunları birbirine bağlayan ilişkiler. Hiçbir şey Word'ü çağırmaz; bu, dönüşümün başsız bir sunucuda, bir servis hesabı içinde, bir kapsayıcıda, Office otomasyonunun lisanssız, kararsız veya yasak olduğu her yerde çalışabileceği anlamına gelir

var
  Pdf: TPDFlib;
  Target: TFileStream;
begin
  Pdf := TPDFlib.Create;
  Target := TFileStream.Create('handbook.docx', fmCreate);
  try
    Pdf.LoadFromFile('handbook.pdf', '');
    Pdf.SaveDOCXToStream('1-40',
      PDF_DOCX_INCLUDE_IMAGES or PDF_DOCX_DETECT_HEADINGS or
      PDF_DOCX_PRESERVE_STYLES or PDF_DOCX_PRESERVE_PAGE_BREAKS,
      Target);
  finally
    Target.Free;
    Pdf.Free;
  end;
end;

Görüntü verisi, sonunda toplanıp eklenmek yerine her sayfa işlendikçe yazılır; bu yüzden tepe bellek kullanımı tüm belgeyi değil tek bir sayfayı izler. Açık sayfa sırası korunur ve seçili PDF sayfası işlem sonrasında geri yüklenir; bu, dışa aktarımın başka nedenlerle bir sayfanın seçili olduğu daha uzun bir işin içinde tek bir adım olduğu durumlarda önem taşır

Belirlenimci paketleme size ne kazandırır?

Bayt bayt tekrarlanabilirlik. Aynı seçeneklerle aynı girdinin iki dönüşümü aynı paketi üretir; bu, değişimi tespit etmek için çıktıyı özetleyebileceğiniz, üretilen bir belgenin iki derlemesini karşılaştırabileceğiniz ve aynı girdinin farklı bir eser ürettiğinden endişe etmeden agresif bir şekilde önbellekleyebileceğiniz anlamına gelir

Office otomasyonu bunu vaat edemez. Zaman damgaları, revizyon kimlikleri ve makineye bağlı meta veriler gömer; bu yüzden aynı belge iki kez dönüştürüldüğünde özetlemeyi bozan şekillerde farklılaşır. Tekrarlanabilir derlemeler için belirlenimci PDF kimlikleri'nde ele alınan akıl yürütme de aynıdır: çıktı tekrarlanabilir olduğunda, doğrulama bir incelemeye değil bir karşılaştırmaya dönüşür

Çıktı nerede iyi, nerede değil

Bu konuda kullanıcılarınıza dürüst olun, çünkü dönüşüm kalitesi dönüştürücüden çok girdiyle değişir. Etiketlenmiş PDF'ler ve temiz üretilmiş iş belgeleri, faturalar, raporlar, sözleşmeler, iyi dönüşür: başlıklar başlık olarak iner, tablolar hayatta kalır, listeler Word içinde doğru şekilde yeniden numaralanır. İki sütunlu akademik düzenler, sütun geometrisi düzenliyse kabul edilebilir şekilde dönüşür. Sayfa sonlarını aşan tablolar çıkarımla yeniden birleştirilir ve bazen bölünür. Metnin okuma sırası yerine görsel etki için yerleştirildiği yoğun tasarlanmış pazarlama materyali kötü dönüşür ve hiçbir miktarda çıkarım bunu düzeltmez

Taranmış belgeler tamamen ayrı bir durumdur. Tek büyük bir görüntü olan bir sayfa hiçbir metin nesnesi içermez; bu yüzden bir metin katmanı var olana kadar dışa aktarılacak hiçbir şey yoktur. Bunu üreten OCR yolu bir seçenek değil bir ön koşuldur. Büyük bir toplu işi çalıştırmadan önce bir düzine temsili dosyayı örnekleyin ve çıktıya bakın; sayfaların gerçekte neyi içerdiğini görmek için önce metin arama ve sayfa öğesi numaralandırmasında anlatıldığı gibi sayfa öğelerini numaralandırmayı da değerlendirin

Asistan ve alım hatları için Markdown yolu genellikle daha iyi hedeftir: başlıklar parça sınırları haline gelir, tablolar boru işaretli tablolar olarak okunaklı kalır ve sayfa işaretçileri her parçaya alıntılanabilir bir konum verir. İnsan düzenlemesi için cevap DOCX'tir, çünkü kullanıcının istediği metin değil onu değiştirebilme yeteneğidir

PDFlibPas, eşleşen DLL ve ActiveX arayüzlerine sahip bir Delphi, C++Builder ve Lazarus PDF kütüphanesidir; bu yüzden aynı dışa aktarma çağrıları C#, C++ veya betik yazma ortamlarından da kullanılabilir. Tam belgeler ve bir deneme sürümü PDFlibPas Delphi PDF kütüphane sayfasındadır