Welcome Guest Search | Active Topics | Sign In | Register

About manual paging Options
nikfe
Posted: Monday, September 21, 2015 7:24:27 AM
Rank: Member
Groups: Member

Joined: 5/25/2015
Posts: 21
Hi

I have currently two problems where I cant get paging right.

First:

Code: HTML/ASPX
<!DOCTYPE html>
<html>
	<head>
		<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
		<title>Test</title>
	</head>
	<body>
		<div class="bigWrapper">
			<div class="divBeforeTitleWrapper"></div>
			<div class="titleWrapper">
				<h1>Template test 1</h1>
			</div>
			<div class="bodyWrapper">
				<p>P1</p>
				<p>P2</p>
				<p>P3</p>
			</div>
		</div>
		<div class="bigWrapper">
			<div class="divBeforeTitleWrapper"></div>
			<div class="titleWrapper">
				<h1>Template test 2</h1>
			</div>
			<div class="bodyWrapper">
				<p>P4</p>
				<p>P5</p>
				<p>P6</p>
			</div>
		</div>
	</body>
</html>

Code: CSS
p, .titleWrapper{
	page-break-inside: avoid;
}

//Opt 1
.titleWrapper{
	page-break-after: avoid;
}
//Opt 2
.bodyWrapper > p:first-child {
	page-break-before: avoid;
}

In my full scenario the "bigWrapper" is the repeating structure with slightly difrent content. I tested this very many difrent styles but in css there is one example that I think should be working.
1. rule: make sure that page break wont happen inside title or p elements.
2. rule: page break wont occure between titleWrapper and bodyWrapper. //This leads to situation that titleWrapper and bodyWrapper stay together (like wanted) AND bodyWrapper staying one piece (".bodyWrapper { page-break-inside: avoid; }") which is unwanted
3. rule: page break wont occure between bodyWrapper and first p //Not cause any visible effect

So the goal is to keep title wrapper with first element ("P1" in this case). And in my test I have placed so much content before first bigWrapper that natural break point should be between P1 and P2. Still I get always
A: it wont keep title and P1 together
B: it will keep whole bodyWrapper together



Second problem:
If I have table which has more content than there is space in page I am not able to get it right. This is actually scenario that at least one rule need to be broke.
Rules (priozed order):
1. Dont cut single row or heading
2. Dont separate heading from rows
3. Dont cut between element before table (in real scenario: dont break between title and table, if title exists)
4. Dont cut table

In practice last rule should be broke pretty often but not another ones.

I get this work with this css:
Code: CSS
//This works pretty well, even it shouldn't
td, th {
 	page-break-inside: avoid;
}

table {
 	page-break-before: avoid;
}


But in some cases its actually causing (in my opinion) extra page break (see image table1). Also that "dont break before table" also cause "dont break inside table" but in this scenario this is wanted behaviour and actually adding "dont break inside table" cause problems in some cases. So check see next css (and image table2).

Code: CSS
//I think this should work like last one
td, th, table {
 	page-break-inside: avoid;
}

table {
 	page-break-before: avoid;
}


Table image 1:


Table image 2:


Edit: So long story short, two problems:
A: "page-break-after/before" avoid cause also unwanted" page-break-inside avoid" behaviour.
B: In same cases I think I would need _priorized_ paging rules, any tips? Could be possible get some C# functionality to handle page breaking manually? Like with this kind of event: "bool OnPageBreak(HtmlElement ele)".
eo_support
Posted: Monday, September 21, 2015 10:12:13 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

You will need to adjust your HTML structure in order to achieve this. If you do not wish page break between the titleWrapper and p1, the only way is to create a non-breakable section that includes just that. This easiest way to create a non-breakable section is to put them into a single element and then apply page-break-inside:avoid. For example:

Code: HTML/ASPX
<div style="page-break-inside:avoid;">
    <div class="titleWrapper">
        <h1>Template test 1</h1>
    </div>
    <p>p1</p>
</div>


There are other indirect ways to do this but it can get very complicated and harder to troubleshoot. For example, the converter will always try to keep thead and the first tr together. So you can try something like this:

Code: HTML/ASPX
<table>
    <thead>
        <th>
            <div class="titleWrapper">
	        <h1>Template test 1</h1>
	    </div>        
        </th>
    </thead>
    <tr>
         <td>
            p1
         </td>
    </tr>
    <tr>
         <td>
            p2
         </td>
    </tr>
</table>


In this case p1 will alway stay together with the header row "Template test 1". However using thead will also cause the row to be repeated on every page. You can turn that off by setting HtmlToPdf.Options.RepeatHeaderAndFooter to false.

http://www.essentialobjects.com/doc/eo.pdf.htmltopdfoptions.repeattableheaderandfooter.aspx

Hope this helps. Please feel free to let us know if you still have any questions.

Thanks!
nikfe
Posted: Tuesday, September 22, 2015 8:15:52 AM
Rank: Member
Groups: Member

Joined: 5/25/2015
Posts: 21
Can you tell that what "page-break-after:avoid" means? Because its for sure means more than "dont break between A and B". Does it mean that "don't break _inside_ A and B and not between eather"?

Btw our content is pretty much user generated so we have direct control to highter semantic only but of course everykind of nasty post processing is possible. Still we need one model and that single model need to do ~perfect result with any user input (of course user input has to be somehow meaningfull).

And about table2: if we look just the table and we want prefer to keep it one piece and forget the rest it shouldn't lead that kind of paging. Currently algorithm seems to be for "break-inside: avoid" objects:
-Do you fit? If no, start from new page.

What I need: Content should be start from new page if that avoid page break from inside. And maybe page break from start is ok if it leads lesser amount of page breaks. If there is no effect to inside pagebreak count, pre page break should be avoided.
eo_support
Posted: Tuesday, September 22, 2015 9:39:42 AM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

"page-break-inside:avoid" means "don't beak between the top Y position and the bottom Y position of the element". For example, if you have the following HTML:

Code: HTML/ASPX
<div style="width:1px;height:100px;">
    div1
</div>
<div style="width:1px;height:100px;page-break-inside:avoid;">
    div 2
    <p>p1</p>
    <p>p2</p>
     ......
</div>
<div style="width:1px;height:100px;">
    div3
</div>


In the above code, the second DIV has "page-break-inside:avoid" and its output position is from y = 100px to y = 200px. So there will be no page break from 100px to 200px. For example, breaking at 150px would be a violation.

There are two additional attributes: page-break-before and page-break-after. Those are for page break between elements. For example, if you apply "page-break-before:always" on your table element, then the table will always start on a new page. So the simplest solution for you would be to apply both "page-break-before:always" and "page-break-inside:avoid" on your table element. Note that "page-break-inside:avoid" has other implications but it will probably be easier to explain those to you when you run into those implications.

Thanks!

nikfe
Posted: Tuesday, September 22, 2015 10:41:02 AM
Rank: Member
Groups: Member

Joined: 5/25/2015
Posts: 21
Hi

You slightly miss my point. "page-break-inside:avoid" is pretty clear to me but before/after wasn't. Since those seems to lead also "avoid inside break" (at least it seems to be on my tests). In another words these three seems to have same behaviour:

#elementA {
page-break-inside:avoid;
page-break-after:avoid;
}

#elementB {
page-break-after:avoid;
}

#elementC {
page-break-inside:auto; //Will be "ignored"
page-break-after:avoid;
}

And that wasn't guestion any more. Just saying (of course if that is wrong feel free to correct me).



But the next thing (or first). I asked from first post about some nested scenario and you told me to change structure. How ever this seems to work (simplified but same structure on hight level):
Code: HTML/ASPX
<style>
div{
border: 3px solid red;
}
</style>
<div style="width:100px;height:100px;">
    div1
</div>
<div style="width:100px;height:300px;page-break-after:avoid;">
    div2
</div>
<div style="width:150px;">
  <div style="width:100px;height:300px;page-break-before:avoid;"></div>
  <div style="width:100px;height:300px;page-break-inside:avoid;"></div>
  <div style="width:100px;height:300px;page-break-inside:avoid;"></div>
</div>


...Again just saying...

And finally the real guestion. I asked this same thing on last post but maybe I wasn't clear enought. So this was related the table thing and you offered "page-break-before: alway" even that I wanted just opposite: no page-break if its not actually do things any better. Simplest possible scenario (use with your demo: http://www.essentialobjects.com/Products/EOPdf/HtmlToPdf.aspx):

Code: HTML/ASPX
<style>
div{
border: 3px solid red;
}
</style>
<div style="width:100px;height:100px;">
    div1
</div>
<div style="width:100px;height:1100px;page-break-after:avoid;">
    div2
</div>


As you see div will be started from new page and it still be cutted. Result looks little bit hilarious since there is 2 pages with almost none of content and one full page. Since new page cant be avoided and extra page break dosen't improve scenario it should act like there wouldn't be "avoid page break".

So os it possible to avoid these extra page breaks? If not, then this is a feature reguest =)
eo_support
Posted: Tuesday, September 22, 2015 2:20:25 PM
Rank: Administration
Groups: Administration

Joined: 5/27/2007
Posts: 24,229
Hi,

"page-break-after:avoid" indeed have exactly the same effect as "page-break-inside:avoid" and "page-break-after:avoid" together. The logic is implemented as follow:

1. If element.PageMode is "page-break-inside:avoid", then a "paging lock" is applied from this element's top Y to bottom Y;
2. If element.PageMode is "page-break-after:avoid", then a "paging lock" is applied from this element's top Y to its next sibling's bottom Y;

As a result, this is indeed a better solution that what we previous suggested.

As to your second DIV example, in this case usually DIV2 would not be split --- except that when it won't fit in a whole page. If there is a single element with "page-break-inside: avoid" (the same as "page-break-after:avoid" in your example) that can not fit in an entire page, then it will start from a new page (so that it fits as much as possible in a single page) and the rest will be split to the next page regardless.

Hope this makes sense to you. Please feel free to let us know if you still have any questions.

Thanks!


You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.