Forum How do I...?

Include a horizontal line between divs on the same page

damartin
My document has multiple divs with a horizontal line between each. In my stylesheet I use a class on all divs except the last to set a bottom border. This achieves the horizontal line nicely between all divs for the web view.

When converting to PDF my requirement is to keep the horizontal line between divs on the same page (note that the divs don't break across pages). With the current stylesheet this leaves a horizontal line at the bottom of each page. I need to be able to either suppress the bottom border on the last div of each page, or start with no border and as the document is processed add the border between divs on the same page.

I though of using prince-script function, testing current div page and next div page. However prince-script only seems to be callable from style content attribute and any DOM modifications in the script don't seem to be visible to the layout engine (I tried adding a class to the div and also tried just adding the bottom-border style to the div).

Hoping someone can point me in the right direction.

Thanks
mikeday
I think this will require a two-pass process where you format the document with a border at the bottom of every div, then check the generated box tree with JavaScript and print a list of which divs don't need the border, then rerun Prince with CSS to disable the border on these divs (and force a page break after them, just to make sure no content from the next page tries to sneak back across!)
damartin
Thanks Mike, I had started to look at the two-pass process. Are there any good examples of using this with the Java wrapper?

thanks
David
damartin
Solved using the two-pass solution. The general approach I took is:

- use the setLog method to set a named log file
- added javascript to check the box model and modify my DOM as required
- I used the excellent notes in http://www.princexml.com/forum/topic/3814/absolutely-positioned-sidenotes?p=1#19092 as a basis for the Javascript, but wrote to the log rather than console
- In my program, read the log file and extract the dumped HTML source from the other log information. The javascript was included in the dumped HTML so I also weeded this out of the final HTML.
- Updated the HTML file with the new content as I needed the final HTML saved in the file for other purposes.
- Run Prince again on the modified HTML.

It would be really awesome if there was some way to write to a two-pass specific output file rather than the log, mimicking writing to the console. That would save parsing of the log file and writing back out.

The only gotcha I had along the way was that I started with XHTML and running Prince with xml input. Unfortunately the method of dumping the html source (html.innerHTML) doesn't produce well-formed XHTML. It wasn't crucial to have XHTML in my case so I resorted to running price with html input.

mikeday
There is actually a Log.data() method that takes two arguments, but the Java wrapper has not been extended to capture its output yet.
damartin
Yes, I found once I set the log output with setLog() then Log.data() currently writes to the log file and puts the first argument into the log file.

E.g. Log.data("starting dump", "some text");
produces a line with <datetime stamp> stats: starting dump: some text

I used that to separate my data from the other log messages to help with the parsing.
mikeday
Right, the next step is to support this in the PrinceEvents class, so you can capture it directly without needing to go through an external log file at all.
damartin
Interesting. Looking at PrinceEvent the current onMessage method has the description "This method will be called when a warning or error message is received from Prince."

Could I have used Log.warning() to do a similar thing?
mikeday
Yes! And add a distinctive prefix to the message. :D
damartin
Ah! Guess I'll try that tomorrow then. Thanks Mike.
damartin
Thanks again Mike for the help.

Final solution I have a custom implementation of the PrinceEvents interface. Using Log.warning() (with a distinctive prefix :)) and parsing the received message in code. Definitely easier than mucking around with the log file.



mikeday
Excellent, glad to hear it worked. :D