Forum How do I...?

Running two-pass in Node wrapper

goldjam
Hi,

We are trying to achieve the same as in this post:

https://www.princexml.com/forum/topic/3228/how-getting-a-page-count-multiple-of-4

and as far as I can find, we do have to run Prince twice to achieve this.

However, we are running Prince from our project built in Node.js, using the Node wrapper (https://www.npmjs.com/package/prince) for Prince. I cannot find a simple way to call the two stage process from the Node wrapper.

As far as I can tell, in the first pass you use an append command in the CLI, ">>" to append the console log back into the source HTML. In the Node wrapper, we cannot pass an append call as an option, the wrapper only takes Prince CLI options.

I have managed to get it to work, but only with a lot of hacking of the Node wrapper, to get it to pass through the append command without turning it into an option, and to run Prince using a shell command rather than directly through child_process.

So we potentially have a solution going forward, albeit an ugly one, which we can tidy up for production. But before we do that, can I ask:

If the only way to run the two-pass solution is through a command using ">>", or if there is a Prince option that I have missed?

If we do have to use ">>", will it work on all OSs (I don't know too much about shell scripting)? We are currently building for Windows, but might want this to run on Linux servers in future.

If there is potentially a better way of doing this in Node than overriding the Node wrapper to make the changes above?


Thanks
mikeday
I think it can be done without changing the Node wrapper; Prince#execute() returns stdout and stderr fields so it should be possible to read log output from stderr, eg. if you log information by calling Log.data() from JavaScript in your document.
goldjam
Thanks for getting back to me.

That is a very interesting idea, I think I know how I can get that to work for this particular issue. If it works, I'll post back more details here.
John
Hello goldjam,

indeed, mikeday is right, whatever you log during the first run, will passed on to the callback and therefore can be used in the second run. While it can be cumbersome to develop and test, it's a very powerful possibility to add features. We are exploiting this to add to enable a 'basic' baseline grid etc.

greetings,
John
goldjam
Managed to get that working. Thanks for the suggestions.

I got the logged data out of the stdout field and was able to use this, interestingly I had to use console.log() to output the data, rather than Log.data().

To briefly summarise our solution, in case it is useful for anyone else:
  1. We run Prince the first time, with a script parameter to use a JavaScript file. In this file there is a "complete" event listener, which uses console.log to output the number of pages.
  2. From the Prince#execute call, we get the stdout field, parse it as a string, then extract the number of pages.
  3. In the Node app, we then see if the number of pages is a multiple of 4, if it is not then we run Prince a second time.
  4. On the second run, we pass a different JavaScript file in the script parameter, this script has an "onload" event which adds in an empty div with the appropriate page break css before the final page, which will force the correct number of page breaks.

The advantage of doing it this way is that we do not have to write out unnecessarily to the file system, by appending anything to source html file. Also, we only run Prince a second time when we need to, moving the logic into the Node app, rather than running Prince twice every time and running the logic in JavaScript in Prince.

This might not help with every implementation of the 2 pass approach, but it suited ours, and is key as we are generating a large run of pdfs and want to reduce the server burden as much as possible.

Thanks again.
shivaram
Is there any NodeWrapper JS two pass example?

For me the first pass produces a CSS, then I will pass the first pass CSS to the second pass?

Edited by shivaram

csant
Consider that the forthcoming release of Prince will have a new and more user-friendly implementation of the multi-pass approach - i.e. it will be enough to run Prince once!

You can try the latest Prince builds, and check the relevant documentation for the next version.