Forum How do I...?

controlling when princeScript is rendered

dsusco
I have a simple function that returns a string, I'm using this in my CSS to set an element's content. The string is changed over the course of the document as scripts are executed. The content just get's the string's initial value though. Anyway around that? Either in how/where I do the Prince.addScriptFunc or via something else?
mikeday
You could pass in the page counter to the script function, and then not use it. That would force Prince to delay executing the function until later, and call it every time, rather than just calling it once and reusing the value.
dsusco
I'll give that a shot.

I was already checking to see when the last bit of JSON was rendered so I knew when to generate by table of contents. I added a jQuery call to that to append my print CSS to the head. That worked but seemed a little hacky.
arthurattwell
Is it still possible to pass a page counter to a prince-script function to force Prince to call it for each document, rather than reusing an initial value from the first document?

I've not been able to make that work with Prince 11.4, but perhaps I'm misunderstanding how it works.
mikeday
It definitely works within one document, but I doubt it will work across multiple documents, as each input document gets its own JavaScript environment.
arthurattwell
That's what I expected. However, in the minimal example attached, the second document gets the value from the first, as if both documents share a Javascript environment. Am I doing something wrong here?

(This is a minimal example. In my full use case, I'm using prince-script because I need to transform the string with regex.)
  1. doc1.html0.4 kB
  2. doc2.html0.4 kB
  3. headers.js0.2 kB
  4. out.pdf36.0 kB
  5. styles.css0.1 kB
mikeday
That's a bit confusing, it's clearly calling the function twice, and passing in counter(page) shows the page number is updating as expected, but it seems to be getting the same document reference each time. I will investigate further.
arthurattwell
Thanks. I'd love to know more, though no rush.

In my case, I could work around this issue by getting the string I need with string-set, and then passing that to the prince-script:

body {
  string-set: data-header attr(data-header);
}
@page {
  @top {
    content: prince-script(header, string(data-header));
  }
}
mikeday
Right, string-set is probably the best option here. I think the current situation is a bit muddled, as only the JavaScript environment from the first document is used during typesetting when the headers and footers are generated. Arguably it would be more sensible to use the JavaScript environment for the current document being typeset, although that could itself cause confusing behaviour in some cases I suspect.

We are going to be doing more work on these issues later in the year when we attempt to support the JavaScript two-pass process entirely within Prince, the beginnings of document reflow. However running JavaScript across multiple documents is always going to be a bit tricky as it's something that other web user agents do not support.