Page 1 of 1

Conditionalizing PDF output based on a map's @outputclass

Posted: Wed Jun 03, 2020 2:10 am
by chrispitude
Hi everyone,

We have a few different document types (books, release notes, installation notes) that require slightly different PDF formatting. So far I've had good results setting an @outputclass attribute on the <bookmap>:

Code: Select all

<bookmap outputclass="install_notes">
then using that as a CSS selector to tweak certain styles:

Code: Select all

div[outputclass~="install_notes"] > article[class ~= 'topic/topic']:first-of-type > *[class~="topic/title"]::after {
  display: block;
  content: "Version " oxy_xpath('//div[contains(@class, " bookmap/bookmeta ")]/div[@keyref = "Release"]//text()')
      " (" oxy_xpath('//div[contains(@class, " bookmap/bookmeta ")]/div[@keyref = "Date"]//text()') ")";
}
I can *almost* get PDF metadata to be conditional, but the title is stubbornly refusing to do so. In my testcase, I define

Code: Select all

  /* try to undo css/print/p-meta.css? */
  *[class ~= "front-page/front-page-title"] *[class ~= "topic/title"] { -oxy-pdf-meta-title: unset !important; }
  *[class ~= "front-page/front-page"] *[class ~= "bookmap/booktitle"] > *[class ~= "bookmap/mainbooktitle"] { -oxy-pdf-meta-title: unset !important; }


  div[class~="bookmap"][outputclass~="A"] {
    -oxy-pdf-meta-title: "A1";
    -oxy-pdf-meta-author: "A2";
    -oxy-pdf-meta-description: "A3";
  }
  div[class~="bookmap"][outputclass~="B"] {
    -oxy-pdf-meta-title: "B1";
    -oxy-pdf-meta-author: "B2";
    -oxy-pdf-meta-description: "B3";
  }
  div[class~="bookmap"]:not([outputclass]) {
    -oxy-pdf-meta-title: "1";
    -oxy-pdf-meta-author: "2";
    -oxy-pdf-meta-description: "3";
  }
but somehow I can't get my applied title to win in the PDF metadata:

image.png
image.png (5.66 KiB) Viewed 4535 times

Has anyone else run into this before? Testcase attached:
chemistry_conditional_pdf_metadata.zip
(25.43 KiB) Downloaded 354 times

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Wed Jun 03, 2020 9:16 am
by Dan
We are not yet supporting the 'unset' CSS identifier. I added an issue, we will try to implement it.
Until then, use an oxy_xpath as value for the default selectors:

Code: Select all

 *[class ~= "front-page/front-page-title"] *[class ~= "topic/title"] { -oxy-pdf-meta-title: oxy_xpath(..); }
 *[class ~= "front-page/front-page"] *[class ~= "bookmap/booktitle"] > *[class ~= "bookmap/mainbooktitle"] { -oxy-pdf-meta-title:  oxy_xpath(..); }
Many regards,
Dan

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Wed Jun 03, 2020 1:42 pm
by chrispitude
Hi Dan,

The

Code: Select all

unset
properties were there to see if the default properties were overriding my attempt to set the title.

The problem is that I cannot get the

Code: Select all

-oxy-pdf-meta-title
to apply in this code:

Code: Select all

  div[class~="bookmap"][outputclass~="A"] {
    -oxy-pdf-meta-title: "A1";
    -oxy-pdf-meta-author: "A2";
    -oxy-pdf-meta-description: "A3";
  }
  div[class~="bookmap"][outputclass~="B"] {
    -oxy-pdf-meta-title: "B1";
    -oxy-pdf-meta-author: "B2";
    -oxy-pdf-meta-description: "B3";
  }
  div[class~="bookmap"]:not([outputclass]) {
    -oxy-pdf-meta-title: "1";
    -oxy-pdf-meta-author: "2";
    -oxy-pdf-meta-description: "3";
  }
Or did I misunderstand what you suggested that I do?

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Thu Jun 04, 2020 8:50 am
by Dan
Please see:

https://www.oxygenxml.com/doc/versions/ ... aqz_j2j_wz

-oxy-pdf-meta-title
It is used to extract the publication title.
If this CSS selector matches multiple elements, only the first element in the document order will be used to extract the title.

I recommend using the selectors that match the first title (from the front page, the ones you tried to unset), but change the property value. You can collect it using an XPath that matches the bookmap with the correct outputclass. You can use complex if/else structures inside XPath if needed. Of course, when we will have the unset implemented, the approach you tried first will be usable. We will notify you when this will be ready.

Many regards,
Dan

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Thu Jun 04, 2020 1:46 pm
by chrispitude
Hi Dan,

I did read that documentation. In the following CSS selectors, there is only one bookmap element, and only one of the bookmap conditions will be true for any given document (outputclass is A, B, or not set), so there will only be a single match:

Code: Select all

div[class~="bookmap"][outputclass~="A"] {...}
div[class~="bookmap"][outputclass~="B"] {...}
div[class~="bookmap"]:not([outputclass]) {...}
Doesn't this meet the requirements?

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Thu Jun 04, 2020 1:47 pm
by chrispitude
Hi Dan,

Also, the tool is not using any of my definitions. It's using something else and I can't figure out where it's coming from.

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Thu Jun 04, 2020 3:08 pm
by chrispitude
Hi Dan, I see what you are saying now. This indeed works!

Code: Select all

  div[class~="bookmap"][outputclass~="A"] *[class ~= "front-page/front-page"] {
    -oxy-pdf-meta-title: "A1";
    -oxy-pdf-meta-author: "A2";
    -oxy-pdf-meta-description: "A3";
  }
  div[class~="bookmap"][outputclass~="B"] *[class ~= "front-page/front-page"] {
    -oxy-pdf-meta-title: "B1";
    -oxy-pdf-meta-author: "B2";
    -oxy-pdf-meta-description: "B3";
  }
  div[class~="bookmap"]:not([outputclass]) *[class ~= "front-page/front-page"] {
    -oxy-pdf-meta-title: "1";
    -oxy-pdf-meta-author: "2";
    -oxy-pdf-meta-description: "3";
  }
What confuses me is that my original bookmap selector is first in document order versus the default selector in p-meta.css, so I expected it to win:

Code: Select all

<div class="- map/map bookmap/bookmap map bookmap A" outputclass="A">
	<div class="- front-page/front-page front-page ">
		<div class="- front-page/front-page-title front-page-title ">
			<div class="- topic/title bookmap/booktitle title booktitle ">
				<span class="- topic/ph bookmap/mainbooktitle ph mainbooktitle ">Map A</span>  </div>
		</div>
	</div>
so I think there is still some kind of bug or unexplained behavior here, but I have an engineering solution so I'm good to go. Thank you!!

- Chris

Re: Conditionalizing PDF output based on a map's @outputclass

Posted: Mon Jun 29, 2020 2:28 pm
by chrispitude
Hi everyone,

There was indeed a bug with conditional PDF metadata when the cover page was suppressed. This bug will be fixed in the next release of the PDF Chemistry publishing engine.

Here is the CSS we will use to conditionalize our PDF data for our books (no @outputclass on map) and release notes:

Code: Select all

@media print {
  /* books (no @outputclass on map) */
  div[class~="bookmap"] {
    -oxy-pdf-meta-title: oxy_xpath('//div[contains(@class, " front-page/front-page-title ")]//text()');
    -oxy-pdf-meta-author: 'My Company, Inc.';
    -oxy-pdf-meta-description: "Version " oxy_xpath('//div[contains(@class, " bookmap/bookmeta ")]/div[@keyref = "Release"]//text()') ", "
             oxy_xpath('//div[contains(@class, " bookmap/bookmeta ")]/div[@keyref = "Date"][1]//text()');
  }

  /* release notes */  
  div[class~="bookmap"][outputclass ~= "release_notes"] {
    -oxy-pdf-meta-title: oxy_xpath('//div[contains(@class, " front-page/front-page-title ")]//text()') " "
        "Version " oxy_xpath('//div[contains(@class, " bookmap/bookmeta ")]/div[@keyref = "Release"]//text()');
    -oxy-pdf-meta-author: 'My Company, Inc.';
    -oxy-pdf-meta-description: unset;
  }
}
Defining @outputclass on the top-level map/bookmap element is a great way to customize the PDF output to the document type without resorting to map specializations for differentiation.

Thanks to the SyncroSoft team for the testcase analysis and fix!