Forum How do I...?

Using prince-script to get HTML code

idan66
Hey there :)

I've been using prince xml for a while and gotta say it helped me a lot

anyway I tried to do something quite simple the other day and couldnt get it to work....

I tried to get my javascript code to return some HTML tags (my main purpose was actually to return an image)

I simplified my code to these few lines so it will be as simple as I can think of

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <link href="ltr.css" rel="stylesheet" type="text/css" />
    <title></title>
    <style type="text/css">
        someContent {content: prince-script(coloredContent, counter(page))}
    </style>
    <script type="text/javascript">
        function coloredContent(num) {
            return "<span style='color:#ff0000'>Hello, world!</span>";
        }
    </script>
</head>
<body>
    <someContent></someContent>
</body>
</html>


What happens is that I get "Hello, world!" on my document and the html tags are not rendered (as expected) but the content doesnt seem to be colored. It looks like Prince ignores the tags and render only the text.
I'm sure I'm missing something here and this is probably the expected behavior but I wanna know if there's anything I can do to make this thing to work

Thanks, Idan. :)
mikeday
I'm afraid that isn't going to work; the return value of prince-script() functions is only treated as uninterpreted text. Did you want to choose a different image depending on the current page number?
idan66
Exactly :)

I need to choose a different pic for every page I have in my document

something like <img src="images/[page number].jpg"> for every page I have

Is there any other possible way I can achieve that?

Thanks :)
mikeday
That actually sounds a bit difficult. How many images do you have, and how complicated is the mapping from page number to image? You could use @page :left, :right, and :first to put different images in the margin boxes, but it may not be possible to put different images on every page unless we extend the prince-script() mechanism for generated content.
whitelynx
Sorry for reviving a thread more than a year old, but I'm running into a very similar issue. We're trying to migrate away from an old report system, so we need to generate reports and forms with the same capabilities. Our first iteration of the new system used PhantomJS, but we'd like to switch to Prince because of issues with page breaks in PhantomJS.

One of the requirements for these reports is that each page has a barcode in the footer that contains several important bits of information from the document, including the page number. We were able to implement this in PhantomJS using jquery-barcode, which generates a collection of CSS-styled elements to render the barcode; we just called the function to re-render the barcode for each page. However, I haven't been able to find a way to do this in Prince.

Even if the only way to do it was to have dynamic server-side barcode image generation, that would work for our purposes; however, we can't make the switch to Prince without this functionality. Would it be possible to allow prince-script() to return a DOM element, similar to how the CSS flow() function works? This would solve the issue quite well.
mikeday
The simplest way to do this would be to use a barcode font, then the text returned by prince-script() would be sufficient to generate the barcode. Otherwise, we could add a new mechanism to generate dynamic URLs, eg. prince-script-url() where the returned text is treated as an image URL. That would allow server-side barcode image generation. The final option would be the ability to generate arbitrary elements, however doing this on a per-page basis during typesetting is very complicated.
botovod
Coming back to the issue risen about 8 years ago. Seems that prince-script-url() has never been implemented.
Is there currently other way to interpret output of prince JS function as url?

It took me for a while to find that so I'll throw that here:
For now this problem can be partly solved by:
https://www.princexml.com/doc/10/paged/#page-rules - princexml v10 documentation reference
@page:nth(42) {
  @top-left{
       content: url()
   }
}
@page:first {
  @top-left{
       content: url()
   }
}


I would leave my findings here for other people since google give this page earlier, than official documentation.
If you want to stick your HTML in the header on all pages(not only text) then you might want to use the following approach:
@page {
  @top { 
      content: element(header)
   }
}
.header{
   position: running(header)
}

It literally takes an element and keeps inserting it as HTML to the top area untill next .header on a page is found
https://www.princexml.com/doc/paged/#copying-content-from-the-document - Current princexml docs

Edited by botovod