PDF editor pro UNIX / PDF editor for UNIX

Wiki : HowtoCreatePdfToWhatever

HomePage :: Categories :: PageIndex :: RecentChanges :: RecentlyCommented :: Login/Register

Howto create pdf to whatever conversion

The Pdf format is not meant for editing or simple text extraction etc. With some pdf files it is impossible to extract a word/line/column representation. Despite these limitations, most pdf files are "sane", so we can extract text and build words from letters, lines from words and finally columns from lines. Text output design in pdfedit allows adding arbitrary output formats very easily.

Class design


Code flow description

This is code flow diagram of pdftoxml

Page has convert function creates PageTextSource which actually does the transformation. It takes three template parameters and one function parameter. The three template parameters (WordEngine, LineEngine, ColumnEngine) are responsible for transformations from content stream operators (PdfOperator) to letters(PageSimpleFragment) to words(PageFragment) to lines(PageLine) and to finally to columns (PageColumn).
Currently there are simple implemenatations of these classes which are enough for many pdf files (SimpleWordEngine, SimpleLineEngine, SimpleColumnEngine).

Funcion convert flow description
  1. Firstly it creates PageTextSource class with the template parameters and uses it as functor to StateUpdater::updatePdfOperators function. It means that after each operator update the functor is called. It stores the formatting operators into PageSimpleFragment and when a text operator is encounters creates new PageSimpleFragment.
  2. Then it calls PageTextSource format method which does the transformation from letters to columns.
  3. Finally when the page is parsed into reasonable structures, output method is called which tries to build output format from
  4. all words
  5. from all columns (which contain lines, lines contain words, ...).

Output structure can decide whether to build the output from one or both possibilities. XmlOutputBuilder build xml from columns iterating through its lines, then words, and letters.

New formats

There are two things to be done to enable your new format.

1) Implement derived class from OutputBuilder which means implementing one or both build functions. For example declaration of XmlOutputBuilder class is

96 class XmlOutputBuilder : public OutputBuilder
97 {
99 private:
100     std::string _str;
102     //
103     // Building interface
104     //
105 public:
107     /** Build output from fragments. */
108     void build (PageColumnIterator it_s, PageColumnIterator it_e);
109     void build (PageFragmentIterator it_s, PageFragmentIterator it_e) {};
111     /** Get result without xml header and footer. */
112     std::string str () const
113         { return _str; }
115     //
116     // Static functions
117     //
118 public:
119     /** Get xml output. */
120     static std::string xml (const XmlOutputBuilder& out);
121 };

The implementation of build is in textoutputbuilder.cc.

2) Then call convert function with your builder class.
2.1) Probably implement new button, menu item .... as it is done with pdftoxml feature. Look in files below.

Files where to look

These are files where you find the conversion system. In src/kernel

These are files where you find menu item implementation in gui (item Tools->Pdf to xml). In src/gui

Implementation notes

Note: Transformations (letters to words, words to lines, lines to columns) are not heavily tested and are rather simple (some sorting functions are missing).
Note 2: The biggest limitations are fonts. The font specification is embedded in pdf file, but pdfedit (nor any other tool i am aware of) can extract these fonts. It is also due to the fact, that not every character must be present in the specification and the font is therefore not complete and usable.

Example - pdftoxml

See example pdftoxml: conversion from pdf to xml
See documentation: PDFedit design documentation

External links



There are 2 comments on this page. [Display comments]