I had some late night inspiration yesterday and hacked out basic support for importing existing PDFs into prawn. This essentially allows you to have a template PDF that you can add content to.
At this stage it's rough, but in simple cases as least it seems to work quite well.
The code is in the templates branch of my fork (http://github.com/yob/prawn/tree/templates) and it depends on a PDF::Reader gem from the pdf-reader/hash branch being installed.
It works by passing the template file path into the ObjectStore constructor. The ObjectStore then just imports all the objects from the source file and then uses the existing info and root dictionaries for the current document.
On Thu, Nov 5, 2009 at 7:31 PM, James Healy <ji...@deefa.com> wrote:
> Hi Folks,
> I had some late night inspiration yesterday and hacked out basic support > for importing existing PDFs into prawn. This essentially allows you to > have a template PDF that you can add content to.
> At this stage it's rough, but in simple cases as least it seems to work > quite well.
> The code is in the templates branch of my fork > (http://github.com/yob/prawn/tree/templates) and it depends on a > PDF::Reader gem from the pdf-reader/hash branch being installed.
> It works by passing the template file path into the ObjectStore > constructor. The ObjectStore then just imports all the objects from the > source file and then uses the existing info and root dictionaries for > the current document.
Nice work! That's a great idea, just importing the old objects. With some of the work Greg and I did with reopening old pages, and Daniel Nelson's work on stamps, we're heading toward a few very flexible ways to reuse content.
Brad Ediger wrote: > Nice work! That's a great idea, just importing the old objects. With > some of the work Greg and I did with reopening old pages, and Daniel > Nelson's work on stamps, we're heading toward a few very flexible ways > to reuse content.
> I fixed some spec failures and minor typos here:
Thanks for the patch, clearly I was tired and had just been hacking at ObjectStore to get something working. I've merged the patch and added a few extra ObjectStore specs.
Being able to re-open old pages will be the killer feature here. Without that, I'd have to change this importing API to let users import the file 1 page at a time after each start_new_page().
-- James Healy <ji...@deefa.com> Fri, 06 Nov 2009 14:27:30 +1100
On Thu, Nov 5, 2009 at 9:28 PM, James Healy <ji...@deefa.com> wrote:
> Being able to re-open old pages will be the killer feature here. Without > that, I'd have to change this importing API to let users import the file > 1 page at a time after each start_new_page().
As usual, less magic in Prawn. Here's Greg's quick proof-of-concept code from back when we were hacking at LoneStar RubyConf:
On Thu, Nov 5, 2009 at 9:48 PM, Brad Ediger <b...@bradediger.com> wrote: > On Thu, Nov 5, 2009 at 9:28 PM, James Healy <ji...@deefa.com> wrote:
>> Being able to re-open old pages will be the killer feature here. Without >> that, I'd have to change this importing API to let users import the file >> 1 page at a time after each start_new_page().
> As usual, less magic in Prawn. Here's Greg's quick proof-of-concept > code from back when we were hacking at LoneStar RubyConf:
Brad Ediger wrote: > > As usual, less magic in Prawn. Here's Greg's quick proof-of-concept > > code from back when we were hacking at LoneStar RubyConf:
One thing we need to be careful of is the page state. Things like the y cursor and margins that are currently setup in start_new_page may need to reinitialized when we move to an existing page.
-- James Healy <ji...@deefa.com> Fri, 06 Nov 2009 15:13:46 +1100
On Thu, Nov 5, 2009 at 10:15 PM, James Healy <ji...@deefa.com> wrote:
> One thing we need to be careful of is the page state. Things like the y > cursor and margins that are currently setup in start_new_page may need > to reinitialized when we move to an existing page.
Full ack. We deliberately ignored those things so far -- for example, transactions give you no guarantees about your y position or any other context but the ink on the page. Good call on the margins though.
If you or anyone else wanted to enumerate all of the page state bits that make up a "context", that would help in more places than just here.
On Thu, Nov 5, 2009 at 10:15 PM, James Healy <ji...@deefa.com> wrote:
> Brad Ediger wrote: >> > As usual, less magic in Prawn. Here's Greg's quick proof-of-concept >> > code from back when we were hacking at LoneStar RubyConf:
> One thing we need to be careful of is the page state. Things like the y > cursor and margins that are currently setup in start_new_page may need > to reinitialized when we move to an existing page.
Oh, and just to clarify, that code is about as bleeding-edge as it gets. I had just merged my ObjectStore changes and Greg and I were sitting in an airport talking about go_to_page, when he started typing furiously and saying things like "Hey, I'll bet it would be as simple as... Well what do you know!"
On Thu, Nov 5, 2009 at 11:22 PM, Brad Ediger <b...@bradediger.com> wrote:
> On Thu, Nov 5, 2009 at 10:15 PM, James Healy <ji...@deefa.com> wrote:
>> Brad Ediger wrote: >>> > As usual, less magic in Prawn. Here's Greg's quick proof-of-concept >>> > code from back when we were hacking at LoneStar RubyConf:
>> One thing we need to be careful of is the page state. Things like the y >> cursor and margins that are currently setup in start_new_page may need >> to reinitialized when we move to an existing page.
> Oh, and just to clarify, that code is about as bleeding-edge as it > gets. I had just merged my ObjectStore changes and Greg and I were > sitting in an airport talking about go_to_page, when he started typing > furiously and saying things like "Hey, I'll bet it would be as simple > as... Well what do you know!"
I will probably sneak go_to_page into Prawn 0.6 as a private function so as to enable page numbering. Then we can debug it and think about how it ought to work in the real sense for 0.7.
I've updated both the experimental branches on PDF::Reader and Prawn so
they now support significantly more documents.
As far as I can tell, *most* documents should work as templates. The
ObjectStore just starts at the source document's Root catalog and
recurses down the object graph, importing everything it finds. Any
objects not referred to by the object graph will not be imported.
There are a few classes of source document that will almost definitely
not work. Two that come to mind are encrypted files and files with
stream xref tables.
If anyone can find other documents that fail, please send me a copy
off list so I can check what's going wrong.
-- James Healy <ji...@deefa.com> Sun, 08 Nov 2009 00:04:46 +1100
> I had some late night inspiration yesterday and hacked out basic support
> for importing existing PDFs into prawn. This essentially allows you to
> have a template PDF that you can add content to.
> At this stage it's rough, but in simple cases as least it seems to work
> quite well.
> The code is in the templates branch of my fork
> (http://github.com/yob/prawn/tree/templates) and it depends on a
> PDF::Reader gem from the pdf-reader/hash branch being installed.
> It works by passing the template file path into the ObjectStore
> constructor. The ObjectStore then just imports all the objects from the
> source file and then uses the existing info and root dictionaries for
> the current document.
> Theres a sample document at http://gir.deefa.com/template.pdf that has
> the fancy_tables.pdf reference file with some added content.
> It's far from being ready to merge, but it proves that we should be
> able to get something working.
> -- James Healy <ji...@deefa.com> Fri, 06 Nov 2009 12:24:14 +1100