Some thoughts on printing with XWIKI

The PDF export aims to create a page-oriented output of XWiki pages. A number of practical problems come to light in the process.
For example:

  1. how to print a large table
  2. how to print graphics
    a) which have been created by Javascript and possibly even modified in the browser by input?
    b) which should appear in a better resolution when printed.
  3. how to get sensible page breaks?
  4. how to print in a different style?
  5. the scaling problem caused by the browser
  6. watermarks

Some things can be done with macros:

If the actual print job is to be generated via the browser, the document must first be displayed in “print preview” mode. (So branch into its macros using ’ request.xpage.equals(“print”) ').

To (1)
If tables are to be displayed by default in a macro call, for example

{{supertable}}
|= …
| … | …
{{/supertable}}

you can modify the output so that you break the table into individual blocks, as in Excel. (In my case the additional parameter to supertable is called ’printsplit="1-10 / 1,11- # 1-21 / 1,22-40" 'e.g.) to define row and column blocks).

to (2)
Constructions like

{{velocity}}
#set ($discard=$xwiki.linkx.use("data:text/css, @media print{ .noprint{ display:none;}} @media screen{ .noscreen {display:none; }}"
                               {'type': 'text/css', 'rel': 'stylesheet'}))
{{/velocity}}

and later

(% class="noprint" %)will not print (%%)
(% class="noscreen" %)does not appear on the screen(%%)

to (3)
Forcing page breaks with style specifications
Examples:

Page break after the table of contents - example

(% style="page-break-after:always;" %)
(((
{{toc start="4"/}}
)))

Page break now

> (% style="page-break-before:always;" %)

Prevent page break

(% style="page-break-inside:avoid;" %)
(((
.
. Stuff that should stay on the same page
.
)))

to (4)
You can change parts of the print style.
For example:

@media print { 
  page {
  height : 29.7cm;
  width : 21.0cm;
  margin-left: 1cm ;
  margin-right:0.8cm ;
}
  h1,h2,h3,h4 { color:red !important;}
  body { font-size:90%; }
  h1,h2,h3.h4 { page-break-after:avoid;}
  #back-top {display:none !important;}
  a[href^="/xwiki/bin/temp"]:after{content:"";}
  .breadcrumb { display:none !important;}
}

Unfortunately, the style specifications for "@media print" in the XWiki are not neatly placed in “print.css”, so that you can not cleanly replace @media specifications.

to (5)
The browser scales or cuts off information when printing.
In order to identify problem areas (tables or graphics) where the page becomes too wide, which means that the font would be reduced when “adjusting” later, you can create an overlay frame that shows these areas:

{{html clean="false"}}
<div style="width:184.6mm; height:50vh;border:1px solid red;position:fixed;bottom:25vh;z-index:9999"></div>
{{/html}}

to (6)
A watermark when printing provides

(% class="visible-print-block" 
     style="position:fixed;
           left:30px;
           top:300px;z-index:999;
           opacity:0.3;colour:grey;
           font-size:75pt;
           border:10pt solid grey;
           border-radius:20pt;
           padding:20pt;" %)Temporary(%%)

Basically, however, it should be said that in the draft “CSS Paged Module” (see
CSS Paged Media Module Level 3 )we will probably be offered print support in the browser in the future. Page-oriented output will then become easier.

It would be nice if these things could be easily accessed in the XWiki in the future.

Comments and hints are very welcome.

Norbert

Hi Norbert. Thanks for your thoughts and examples of solutions you’ve found to help manage what you print.

Are you referring to the PDF export using FOP (and then printing that PDF) or to the Print feature of XWiki (using the Browser print feature)?

Any suggestion about what should be done? Would you be able to provide a Pull Request to fix this?

Do you have any suggestion for this?

Thanks!

The remarks refer mainly to the Print feature (export to PDF) using the Browser. Some work with the exporting to PDF feature too.

Some additional remarks:

There exists a Javascript-Implementation of the CSS Paged Media Module: https://www.pagedjs.org/
It simulates the paged media mechanism, which hopefully will be done be the browser in the future.

As a proof of concept I built a (quick-and-dirty) integration of pagedjs into the XWiki.

The complete process is done by the browser ( a bit time consuming ) but it is working.
There are some problems with the XWiki print.css (for example when modifying colors)

The following demo page shows margins boxes as it is seen within browser print preview.

Testpage pagedjs 2021-09-28 19_17_04-Testseite 1 zu pagedPrinting - XWiki

The following CSS commands were used.

.document-info {display:none}

@media print{
@page {
    size: 160mm 200mm;
    margin: 30mm 30mm;
    bleed :20mm;
    marks : crop ;
}

	@page:nth(1) {
	    margin-left: 35mm;
    margin-right: 15mm;
		@top-left-corner{content:"top-left-corner";border:black dotted 1px;}
		@top-right{content:"top-right"; border:black dotted 1px;}
		@top-center{content:"top center"; border:black dotted 1px;}
		@top-left{content:"top left"; border:black dotted 1px;}
		@top-right-corner{content:"top-right-corner"; border:black dotted 1px;}

		@left-top{content:"left-top";border:black dotted 1px;}
		@left-middle{content:"left-middle";border:black dotted 1px;}
		@left-bottom{content:"left-bottom";border:black dotted 1px;}

		@right-top{content:"right-top";border:black dotted 1px;}
		@right-middle{content:"right-middle";border:black dotted 1px;}
		@right-bottom{content:"right-bottom";border:black dotted 1px;}

		@bottom-left-corner{content:"bottom-left-corner";border:black dotted 1px;}
		@bottom-right{content:"bottom-right"; border:black dotted 1px;}
		@bottom-center{content:"bottom center"; border:black dotted 1px;}
		@bottom-left{content:"bottom left"; border:black dotted 1px;}
		@bottom-right-corner{content:"bottom-right-corner"; border:black dotted 
        1px;font-size:100%;}
	}

@page:left {
    margin-left: 35mm;
    margin-right: 15mm;
    @bottom-left-corner{content:counter(page); font-size:150%;font-color:red;}
}

@page:right {
    margin-left: 15mm;
    margin-right: 35mm;
		@bottom-right-corner{content:counter(page); font-size:150%;}
}
}

I think a user interface could be an addtional action (e.g. “Paged Printing”) with a selection of prepared styles containing at least page sizes.

There are apparently still some conflicts with the XWiki-print style specifications, which cannot always be overwritten with “!important”.

It would also be nice if XWiki would store the heading in an additional (e.g.) “data-title” attribute in the generated h1…h6 html tags.

Norbert

Hello Norbert,

very nice work you did there, thanks for sharing it with us and the community!

Indeed, the main discussion to have around the print is whether we should have it done on the client side (by the browser) or on the server side.
Currently, the print button of XWiki points to a server side export, with the limitations that you mentioned.

Now, for the original discussion, there was already a proposal and an exchange in the past about this choice, where some community members shared some knowledge about that [xwiki-devs] [Proposal] Using the browser's print feature instead of our PDF Export for the UI - Vincent Massol - org.xwiki.devs - MarkMail . Note that this is from 4.5 years ago, so some information in there may not be very actual anymore.

In addition to that, an advantage of the server side print over client side print is that things would not necessarily need to be seen on the screen in order to obtain the pdf, but that’s also possible with javascript and XHR from the browser.

It’s very good news to know that Paged CSS was implemented in javascript, I have been looking for a print library server side that implemented it in the past when I tried to recode the print away from FOP and more towards modern ways of doing things, I’ll definitely have a look at it to see how/if we could use it.

Enjoy XWiki,
Anca