[reportlab-users] Truncating a flowable to fit a frame

127 views
Skip to first unread message

Lele Gaifax

unread,
Dec 19, 2020, 3:09:20 AM12/19/20
to reportl...@lists2.reportlab.com
Hi,

an app of mine produces a periodic newsletter, mostly composed by a set of
fixed size frames that are filled with some flowable content. The "editor"
user has the responsibility of tweaking the content to make it fit in each
frame.

Now I'm asked about a different approach, where the content for some of those
"areas" may be arbitrarily long, and the system automatically truncates each
flowable as soon as the related frame is full, possibly leaving some space at
the bottom to add something like 'See <a href="here">full content here</a>'.

A brute force implementation would be something like:

story = [....]
fits = False
while not fits:
flowable = SomeFlowable(story)
if frame.add(flowable, canvas):
break
story = replace_some_trailing_text_with_ellipsis(story)

I suspect that a slightly better way could use the split() method on the
flowable, maybe passing it the height of the frame corrected to leave space
for the hyperlink.... I will try to understand the logic used for example by
PTOContainer().

Any hint would be appreciated!

Thanks in advance and best wishes,
ciao, lele.
--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
le...@metapensiero.it | -- Fortunato Depero, 1929.

_______________________________________________
reportlab-users mailing list
reportl...@lists2.reportlab.com
https://pairlist2.pair.net/mailman/listinfo/reportlab-users

Robin Becker

unread,
Dec 19, 2020, 4:22:41 AM12/19/20
to reportlab-users, Lele Gaifax
There's a KeepInFrame class in flowables.py which can truncate

def __init__(self, maxWidth, maxHeight, content=[], mergeSpace=1, mode='shrink',
name='',hAlign='LEFT',vAlign='BOTTOM', fakeWidth=None):

you set maxWidth maxHeight to match the dimensions of the real frame; mode='truncate'; your flowables go in the content
list. You could make this into a flowable which lies about it's wrap and leaves enough space for your see here content.

A possible alternative is to mess with the PTOContainer class and lie about its split. Normally it splits into

A [lead part + trailer] and another PTO. If I read you correctly you would just return an empty second part.

So something like this

class MyTruncator(PTOContainer):
def split(self, availWidth, availHeight):
S = PTOContainer.split(self, availWidth, availHeight)
return [S[0]] if len(S)==2 else S

I'm not sure if that actually works, but the intent is to drop the remainder after splitting.

Merry Christmas to one and all

On 19/12/2020 08:09, Lele Gaifax wrote:
> Hi,
>
> an app of mine produces a periodic newsletter, mostly composed by a set of
> fixed size frames that are filled with some flowable content. The "editor"
> user has the responsibility of tweaking the content to make it fit in each
> frame.
>
> Now I'm asked about a different approach, where the content for some of those
> "areas" may be arbitrarily long, and the system automatically truncates each
> flowable as soon as the related frame is full, possibly leaving some space at
> the bottom to add something like 'See <a href="here">full content here</a>'.
>
> A brute force implementation would be something like:
>
........
>
> Thanks in advance and best wishes,
> ciao, lele.
>


--
Robin Becker

Lele Gaifax

unread,
Dec 19, 2020, 8:22:29 AM12/19/20
to reportl...@lists2.reportlab.com
Thank you Robin, I will surely try out your suggestions and report back,
starting from KeepInFrame that I completely overlooked!

bye, lele.


--
nickname: Lele Gaifax | Quando vivrò di quello che ho pensato ieri
real: Emanuele Gaifas | comincerò ad aver paura di chi mi copia.
le...@metapensiero.it | -- Fortunato Depero, 1929.

_______________________________________________

Reply all
Reply to author
Forward
0 new messages