keeps into account. git-svn-id: https://svn.apache.org/repos/asf/xmlgraphics/fop/trunk@360073 13f79535-47bb-0310-9956-ffa450edef68tags/fop-0_92-beta
@@ -57,109 +57,33 @@ public class BlockKnuthSequence extends KnuthSequence { | |||
return !sequence.isInlineSequence() && !isClosed; | |||
} | |||
/** | |||
* this and sequence are supposed to belong to the same LayoutManager, | |||
* which is stored in the positions of the elements in the sequences | |||
* @param sequence The sequence following this | |||
* @return whether this and the following sequence must be kept together | |||
*/ | |||
private boolean mustKeepWithNext(BlockKnuthSequence sequence) { | |||
/* // TODO read keep together correctly | |||
// for now, return false | |||
return BlockKnuthSequence.mustKeepTogether(this, sequence); | |||
*/ return false; | |||
} | |||
/** | |||
* the two sequences are supposed to belong to the same LayoutManager, | |||
* which is stored in the positions of the elements in the sequences | |||
* @param sequence1 The leading sequence | |||
* @param sequence2 The following sequence | |||
* @return whether the two sequences must be kept together | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthList#appendSequence(org.apache.fop.layoutmgr.KnuthSequence,) | |||
*/ | |||
public static boolean mustKeepTogether(BlockKnuthSequence sequence1, | |||
BlockKnuthSequence sequence2) { | |||
ListElement element1 = (ListElement) sequence1.get(sequence1.size() - 1); | |||
LayoutManager lm1 = (LayoutManager) element1.getLayoutManager(); | |||
ListElement element2 = (ListElement) sequence2.get(0); | |||
LayoutManager lm2 = (LayoutManager) element2.getLayoutManager(); | |||
if (!lm1.equals(lm2)) { | |||
throw new IllegalStateException | |||
("The two sequences must belong to the same LayoutManager"); | |||
} | |||
if (lm1 instanceof BlockLevelLayoutManager | |||
&& ((BlockLevelLayoutManager) lm1).mustKeepTogether()) { | |||
return true; | |||
} | |||
Position pos1 = element1.getPosition(); | |||
if (pos1 != null) { | |||
pos1 = pos1.getPosition(); | |||
if (pos1 != null) { | |||
lm1 = pos1.getLM(); | |||
if (lm1 instanceof BlockLevelLayoutManager | |||
&& ((BlockLevelLayoutManager) lm1).mustKeepWithNext()) { | |||
return true; | |||
} | |||
} | |||
} | |||
Position pos2 = element1.getPosition(); | |||
if (pos2 != null) { | |||
pos2 = pos2.getPosition(); | |||
if (pos2 != null) { | |||
lm2 = pos2.getLM(); | |||
if (lm2 instanceof BlockLevelLayoutManager | |||
&& ((BlockLevelLayoutManager) lm2).mustKeepWithPrevious()) { | |||
return true; | |||
} | |||
} | |||
} | |||
public boolean appendSequence(KnuthSequence sequence) { | |||
// log.debug("Cannot append a sequence without a BreakElement"); | |||
return false; | |||
/* From BlockStackingLM.getChangedKnuthElements | |||
// there is another block after this one | |||
if (bSomethingAdded | |||
&& (this.mustKeepTogether() | |||
|| prevLM.mustKeepWithNext() | |||
|| currLM.mustKeepWithPrevious())) { | |||
// add an infinite penalty to forbid a break between blocks | |||
returnedList.add(new KnuthPenalty(0, KnuthElement.INFINITE, false, | |||
new Position(this), false)); | |||
} else if (bSomethingAdded && !((KnuthElement) returnedList.getLast()).isGlue()) { | |||
// add a null penalty to allow a break between blocks | |||
returnedList.add(new KnuthPenalty(0, 0, false, new Position(this), false)); | |||
} | |||
*/ } | |||
} | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthList#appendSequence(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager) | |||
* @see KnuthList#appendSequence(KnuthSequence, boolean, BreakElement) | |||
*/ | |||
/** | |||
* this and sequence are supposed to belong to the same LayoutManager, | |||
* which is stored in the positions of the elements in the sequences | |||
*/ | |||
public boolean appendSequence(KnuthSequence sequence, LayoutManager lm) { | |||
public boolean appendSequence(KnuthSequence sequence, boolean keepTogether, | |||
BreakElement breakElement) { | |||
if (!canAppendSequence(sequence)) { | |||
return false; | |||
} | |||
/* // TODO disable because InlineLM.addAreas expects only NonLeafPostions; why? | |||
if (!mustKeepWithNext((BlockKnuthSequence) sequence)) { | |||
add(new KnuthPenalty(0, 0, false, new Position(lm), false)); | |||
if (keepTogether) { | |||
breakElement.setPenaltyValue(KnuthElement.INFINITE); | |||
add(breakElement); | |||
} else if (!((ListElement) getLast()).isGlue()) { | |||
breakElement.setPenaltyValue(0); | |||
add(breakElement); | |||
} | |||
*/ addAll(sequence); | |||
addAll(sequence); | |||
return true; | |||
} | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthList#appendSequenceOrClose(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager) | |||
*/ | |||
public boolean appendSequenceOrClose(KnuthSequence sequence, LayoutManager lm) { | |||
if (!appendSequence(sequence, lm)) { | |||
endSequence(); | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
} | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthSequence#endSequence() | |||
*/ |
@@ -27,6 +27,7 @@ import org.apache.fop.area.Block; | |||
import org.apache.fop.area.LineArea; | |||
import org.apache.fop.datatypes.Length; | |||
import org.apache.fop.fonts.Font; | |||
import org.apache.fop.layoutmgr.inline.InlineLayoutManager; | |||
import org.apache.fop.layoutmgr.inline.InlineLevelLayoutManager; | |||
import org.apache.fop.layoutmgr.inline.LineLayoutManager; | |||
import org.apache.fop.traits.MinOptMax; | |||
@@ -198,13 +199,15 @@ public class BlockLayoutManager extends BlockStackingLayoutManager | |||
* @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() | |||
*/ | |||
public boolean mustKeepTogether() { | |||
//TODO Keeps will have to be more sophisticated sooner or later | |||
// TODO Keeps will have to be more sophisticated sooner or later | |||
// TODO This is a quick fix for the fact that the parent is not always a BlockLevelLM; | |||
// eventually mustKeepTogether() must be moved up to the LM interface | |||
return (getParent() instanceof BlockLevelLayoutManager | |||
&& ((BlockLevelLayoutManager) getParent()).mustKeepTogether()) | |||
|| !getBlockFO().getKeepTogether().getWithinPage().isAuto() | |||
|| !getBlockFO().getKeepTogether().getWithinColumn().isAuto(); | |||
return (!getBlockFO().getKeepTogether().getWithinPage().isAuto() | |||
|| !getBlockFO().getKeepTogether().getWithinColumn().isAuto() | |||
|| (getParent() instanceof BlockLevelLayoutManager | |||
&& ((BlockLevelLayoutManager) getParent()).mustKeepTogether()) | |||
|| (getParent() instanceof InlineLayoutManager | |||
&& ((InlineLayoutManager) getParent()).mustKeepTogether())); | |||
} | |||
/** | |||
@@ -212,7 +215,7 @@ public class BlockLayoutManager extends BlockStackingLayoutManager | |||
*/ | |||
public boolean mustKeepWithPrevious() { | |||
return !getBlockFO().getKeepWithPrevious().getWithinPage().isAuto() | |||
|| !getBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); | |||
|| !getBlockFO().getKeepWithPrevious().getWithinColumn().isAuto(); | |||
} | |||
/** |
@@ -29,6 +29,7 @@ import org.apache.fop.area.Block; | |||
import org.apache.fop.fo.FObj; | |||
import org.apache.fop.fo.properties.CommonBorderPaddingBackground; | |||
import org.apache.fop.fo.properties.SpaceProperty; | |||
import org.apache.fop.layoutmgr.inline.InlineLayoutManager; | |||
import org.apache.fop.layoutmgr.inline.LineLayoutManager; | |||
import org.apache.fop.traits.MinOptMax; | |||
@@ -309,9 +310,8 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
if (mustKeepTogether() | |||
|| context.isKeepWithNextPending() | |||
|| childLC.isKeepWithPreviousPending()) { | |||
//Clear keep pending flag | |||
// Clear keep pending flag | |||
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); | |||
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); | |||
// add an infinite penalty to forbid a break between | |||
// blocks | |||
contentList.add(new BreakElement( | |||
@@ -368,11 +368,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
return returnList; | |||
}*/ | |||
} | |||
if (childLC.isKeepWithNextPending()) { | |||
//Clear and propagate | |||
childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); | |||
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING); | |||
} | |||
// propagate and clear | |||
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, childLC.isKeepWithNextPending()); | |||
childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); | |||
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); | |||
prevLM = curLM; | |||
} | |||
@@ -617,6 +616,10 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
} | |||
fromIndex = workListIterator.previousIndex(); | |||
/* | |||
* TODO: why are KnuthPenalties added here, | |||
* while in getNextKE they were changed to BreakElements? | |||
*/ | |||
// there is another block after this one | |||
if (bSomethingAdded | |||
&& (this.mustKeepTogether() | |||
@@ -732,8 +735,12 @@ public abstract class BlockStackingLayoutManager extends AbstractLayoutManager | |||
/** | |||
* @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether() | |||
*/ | |||
// default action: ask parentLM | |||
public boolean mustKeepTogether() { | |||
return false; | |||
return ((getParent() instanceof BlockLevelLayoutManager | |||
&& ((BlockLevelLayoutManager) getParent()).mustKeepTogether()) | |||
|| (getParent() instanceof InlineLayoutManager | |||
&& ((InlineLayoutManager) getParent()).mustKeepTogether())); | |||
} | |||
/** |
@@ -26,7 +26,8 @@ import org.apache.fop.layoutmgr.inline.KnuthInlineBox; | |||
/** | |||
* | |||
* Represents a list of inline Knuth elements. | |||
* If closed, it represents all elements of a Knuth paragraph. | |||
*/ | |||
public class InlineKnuthSequence extends KnuthSequence { | |||
@@ -63,9 +64,9 @@ public class InlineKnuthSequence extends KnuthSequence { | |||
} | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthSequence#appendSequence(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager) | |||
* @see org.apache.fop.layoutmgr.KnuthSequence#appendSequence(org.apache.fop.layoutmgr.KnuthSequence) | |||
*/ | |||
public boolean appendSequence(KnuthSequence sequence, LayoutManager lm) { | |||
public boolean appendSequence(KnuthSequence sequence) { | |||
if (!canAppendSequence(sequence)) { | |||
return false; | |||
} | |||
@@ -82,17 +83,14 @@ public class InlineKnuthSequence extends KnuthSequence { | |||
} | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthSequence#appendSequenceOrClose(org.apache.fop.layoutmgr.KnuthSequence, org.apache.fop.layoutmgr.LayoutManager) | |||
* @see KnuthSequence#appendSequence(KnuthSequence, boolean, BreakElement) | |||
*/ | |||
public boolean appendSequenceOrClose(KnuthSequence sequence, LayoutManager lm) { | |||
if (!appendSequence(sequence, lm)) { | |||
endSequence(); | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
public boolean appendSequence(KnuthSequence sequence, boolean keepTogether, | |||
BreakElement breakElement) { | |||
return appendSequence(sequence); | |||
} | |||
/* (non-Javadoc) | |||
* @see org.apache.fop.layoutmgr.KnuthSequence#endSequence() | |||
*/ | |||
@@ -108,9 +106,9 @@ public class InlineKnuthSequence extends KnuthSequence { | |||
KnuthBox prevBox = (KnuthBox) getLast(); | |||
if (prevBox.isAuxiliary() | |||
&& (size() < 4 | |||
|| !getElement(size()-2).isGlue() | |||
|| !getElement(size()-3).isPenalty() | |||
|| !getElement(size()-4).isBox() | |||
|| !getElement(size() - 2).isGlue() | |||
|| !getElement(size() - 3).isPenalty() | |||
|| !getElement(size() - 4).isBox() | |||
) | |||
) { | |||
// Not the sequence we are expecting |
@@ -65,22 +65,53 @@ public abstract class KnuthSequence extends ArrayList { | |||
/** | |||
* Append sequence to this sequence if it can be appended. | |||
* TODO In principle the LayoutManager can also be retrieved from the elements in the sequence. | |||
* @param sequence The sequence that is to be appended. | |||
* @param lm The LayoutManager for the Position that may have to be created. | |||
* @param keepTogether Whether the two sequences must be kept together. | |||
* @param breakElement The BreakElement that may be inserted between the two sequences. | |||
* @return whether the sequence was succesfully appended to this sequence. | |||
*/ | |||
public abstract boolean appendSequence(KnuthSequence sequence, LayoutManager lm); | |||
public abstract boolean appendSequence(KnuthSequence sequence, boolean keepTogether, | |||
BreakElement breakElement); | |||
/** | |||
* Append sequence to this sequence if it can be appended. | |||
* @param sequence The sequence that is to be appended. | |||
* @return whether the sequence was succesfully appended to this sequence. | |||
*/ | |||
public abstract boolean appendSequence(KnuthSequence sequence); | |||
/** | |||
* Append sequence to this sequence if it can be appended. | |||
* If that is not possible, close this sequence. | |||
* TODO In principle the LayoutManager can also be retrieved from the elements in the sequence. | |||
* @param sequence The sequence that is to be appended. | |||
* @param lm The LayoutManager for the Position that may have to be created. | |||
* @return whether the sequence was succesfully appended to this sequence. | |||
*/ | |||
public abstract boolean appendSequenceOrClose(KnuthSequence sequence, LayoutManager lm); | |||
public boolean appendSequenceOrClose(KnuthSequence sequence) { | |||
if (!appendSequence(sequence)) { | |||
endSequence(); | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
} | |||
/** | |||
* Append sequence to this sequence if it can be appended. | |||
* If that is not possible, close this sequence. | |||
* @param sequence The sequence that is to be appended. | |||
* @param keepTogether Whether the two sequences must be kept together. | |||
* @param breakElement The BreakElement that may be inserted between the two sequences. | |||
* @return whether the sequence was succesfully appended to this sequence. | |||
*/ | |||
public boolean appendSequenceOrClose(KnuthSequence sequence, boolean keepTogether, | |||
BreakElement breakElement) { | |||
if (!appendSequence(sequence, keepTogether, breakElement)) { | |||
endSequence(); | |||
return false; | |||
} else { | |||
return true; | |||
} | |||
} | |||
/** | |||
* Wrap the Positions of the elements of this sequence in a Position for LayoutManager lm. |
@@ -35,6 +35,8 @@ import org.apache.fop.fo.properties.CommonMarginInline; | |||
import org.apache.fop.fo.properties.SpaceProperty; | |||
import org.apache.fop.fonts.Font; | |||
import org.apache.fop.layoutmgr.BlockKnuthSequence; | |||
import org.apache.fop.layoutmgr.BlockLevelLayoutManager; | |||
import org.apache.fop.layoutmgr.BreakElement; | |||
import org.apache.fop.layoutmgr.KnuthBox; | |||
import org.apache.fop.layoutmgr.KnuthElement; | |||
import org.apache.fop.layoutmgr.KnuthSequence; | |||
@@ -196,6 +198,24 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
} | |||
} | |||
/** | |||
* @return true if this element must be kept together | |||
*/ | |||
// TODO Use the keep-together property on Inline as well | |||
public boolean mustKeepTogether() { | |||
return mustKeepTogether(this.getParent()); | |||
} | |||
private boolean mustKeepTogether(LayoutManager lm) { | |||
if (lm instanceof BlockLevelLayoutManager) { | |||
return ((BlockLevelLayoutManager) lm).mustKeepTogether(); | |||
} else if (lm instanceof InlineLayoutManager) { | |||
return ((InlineLayoutManager) lm).mustKeepTogether(); | |||
} else { | |||
return mustKeepTogether(lm.getParent()); | |||
} | |||
} | |||
/** @see org.apache.fop.layoutmgr.LayoutManager */ | |||
public LinkedList getNextKnuthElements(LayoutContext context, int alignment) { | |||
LayoutManager curLM; | |||
@@ -267,6 +287,9 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
} | |||
// get KnuthElements from curLM | |||
returnedList = curLM.getNextKnuthElements(childLC, alignment); | |||
if (returnList.size() == 0 && childLC.isKeepWithPreviousPending()) { | |||
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); | |||
} | |||
if (returnedList == null) { | |||
// curLM returned null because it finished; | |||
// just iterate once more to see if there is another child | |||
@@ -276,6 +299,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
continue; | |||
} | |||
if (curLM instanceof InlineLevelLayoutManager) { | |||
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); | |||
// "wrap" the Position stored in each element of returnedList | |||
ListIterator seqIter = returnedList.listIterator(); | |||
while (seqIter.hasNext()) { | |||
@@ -283,7 +307,7 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
sequence.wrapPositions(this); | |||
} | |||
if (lastSequence != null && lastSequence.appendSequenceOrClose | |||
((KnuthSequence) returnedList.get(0), this)) { | |||
((KnuthSequence) returnedList.get(0))) { | |||
returnedList.remove(0); | |||
} | |||
// add border and padding to the first complete sequence of this LM | |||
@@ -293,13 +317,21 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
} | |||
returnList.addAll(returnedList); | |||
} else { // A block LM | |||
// TODO For now avoid having two different block LMs in a single sequence | |||
if (curLM != lastChildLM && lastSequence != null) { | |||
lastSequence.endSequence(); | |||
} | |||
BlockKnuthSequence sequence = new BlockKnuthSequence(returnedList); | |||
sequence.wrapPositions(this); | |||
if (lastSequence == null || !lastSequence.appendSequenceOrClose(sequence, this)) { | |||
boolean appended = false; | |||
if (lastSequence != null) { | |||
if (lastSequence.canAppendSequence(sequence)) { | |||
BreakElement bk = new BreakElement(new Position(this), 0, context); | |||
boolean keepTogether = (mustKeepTogether() | |||
|| context.isKeepWithNextPending() | |||
|| childLC.isKeepWithPreviousPending()); | |||
appended = lastSequence.appendSequenceOrClose(sequence, keepTogether, bk); | |||
} else { | |||
lastSequence.endSequence(); | |||
} | |||
} | |||
if (!appended) { | |||
// add border and padding to the first complete sequence of this LM | |||
if (!borderAdded) { | |||
addKnuthElementsForBorderPaddingStart(sequence); | |||
@@ -307,6 +339,11 @@ public class InlineLayoutManager extends InlineStackingLayoutManager { | |||
} | |||
returnList.add(sequence); | |||
} | |||
// propagate and clear | |||
context.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, | |||
childLC.isKeepWithNextPending()); | |||
childLC.setFlags(LayoutContext.KEEP_WITH_NEXT_PENDING, false); | |||
childLC.setFlags(LayoutContext.KEEP_WITH_PREVIOUS_PENDING, false); | |||
} | |||
lastSequence = (KnuthSequence) returnList.getLast(); | |||
lastChildLM = curLM; |
@@ -1312,7 +1312,7 @@ public class LineLayoutManager extends InlineStackingLayoutManager | |||
* @see org.apache.fop.layoutmgr.BlockLevelLayoutManager#mustKeepTogether | |||
*/ | |||
public boolean mustKeepTogether() { | |||
return false; | |||
return ((BlockLevelLayoutManager) getParent()).mustKeepTogether(); | |||
} | |||
/** |
@@ -0,0 +1,66 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<!-- | |||
Copyright 2005 The Apache Software Foundation | |||
Licensed under the Apache License, Version 2.0 (the "License"); | |||
you may not use this file except in compliance with the License. | |||
You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. | |||
--> | |||
<!-- $Id$ --> | |||
<testcase> | |||
<info> | |||
<p> | |||
This test checks the value of the penalties between | |||
KnuthBlockBoxes in inline context, with and without keep conditions. | |||
</p> | |||
</info> | |||
<fo> | |||
<fo:root xmlns:fo="http://www.w3.org/1999/XSL/Format"> | |||
<fo:layout-master-set> | |||
<fo:simple-page-master master-name="normal" page-width="5in" page-height="5in"> | |||
<fo:region-body/> | |||
</fo:simple-page-master> | |||
</fo:layout-master-set> | |||
<fo:page-sequence master-reference="normal" white-space-collapse="true"> | |||
<fo:flow flow-name="xsl-region-body"> | |||
<fo:block><fo:inline>Before | |||
<fo:block id="b1" background-color="silver"><fo:inline>Before1 | |||
<fo:block id="b11" background-color="grey">A1=B1,</fo:block> | |||
<fo:block id="b12">C1=D1.</fo:block>after1</fo:inline></fo:block> | |||
<fo:block id="b2" background-color="lightgrey" keep-together.within-page="always"><fo:inline>Before2 | |||
<fo:block id="b21" background-color="grey">A2=B2,</fo:block> | |||
<fo:block id="b22">C2=D2.</fo:block>after2</fo:inline></fo:block> | |||
<fo:block id="b3" background-color="silver"><fo:inline>Before3 | |||
<fo:block id="b31" keep-with-next.within-page="always" background-color="grey">A3=B3,</fo:block> | |||
<fo:block id="b32">C3=D3.</fo:block>after3</fo:inline></fo:block>after</fo:inline></fo:block> | |||
</fo:flow> | |||
</fo:page-sequence> | |||
</fo:root> | |||
</fo> | |||
<checks> | |||
<element-list category="breaker"> | |||
<skip>5</skip> | |||
<!-- penalty between blocks b11 and b12, set by InlineLM in b1 --> | |||
<penalty w="0" p="0"/> | |||
<skip>6</skip> | |||
<!-- penalty between blocks b21 and b22, set by InlineLM in b2 --> | |||
<!-- keep-together.within-page="always" --> | |||
<penalty w="0" p="1000"/> | |||
<skip>6</skip> | |||
<!-- penalty between blocks b31 and b32, set by InlineLM in b3 --> | |||
<!-- keep-with-next.within-page="always" --> | |||
<penalty w="0" p="1000"/> | |||
<skip>5</skip> | |||
<skip>3</skip> | |||
</element-list> | |||
</checks> | |||
</testcase> |