Я пытаюсь создать скрипт, который извлекает данные о событиях из Календаря Google и для каждого дня отображает события дней в двух столбцах с разрывами между ними, которые пропорциональны времени (чем больше времени между событиями, тем больше места между абзацами).Каждое событие представляет собой абзац Reportlab Platypus, и между ними есть разделители. Полный код здесь (скоро будет комментировано, обещаю).
Моя проблема в том, что я не могу рассчитать точное расстояние, необходимое для того, чтобы точно вписать каждый абзац в кадр: Iвсегда преувеличивать или недооценивать, независимо от формулы, последний абзац никогда не попадает точно в конец кадра.
Основной расчет начинается с add_events_to_frame ().Абзацы создаются для каждого события, и доступное пространство сохраняется, запрашиваются значения высоты разделителя и история, записанная на холст:
def add_events_to_frame(frame, events, canvas):
story = []
free_space = frame.height
for event in events:
paragraph = get_event_paragraph(event)
story.append(paragraph)
free_space -= paragraph.wrap(frame_width, frame_height)[1] - 1
real_story = []
if free_space > 0:
spaces = Collector.get_space_after(events, free_space)
for i, paragraph in enumerate(story):
real_story.append(paragraph)
real_story.append(Spacer(1, spaces[i] + 1))
frame.addFromList(real_story, canvas)
return frame
get_event_paragraph () выглядит следующим образом:
def get_event_paragraph(event, spaceAfter=0, borderPadding=2):
event_style = ParagraphStyle(
"event",
fontName="Times-Roman",
fontSize=5,
backColor=event['color'],
textColor='white',
leading=6,
borderPadding=borderPadding,
spaceAfter=spaceAfter + 2 * borderPadding
)
beginTime = event['start'].strftime("%H:%M")
endTime = event['end'].strftime("%H:%M")
eventStringList = [f"<b>{beginTime}-{endTime}</b>"]
eventStringList.append(event['summary'])
return Paragraph(' '.join(eventStringList), event_style)
И калькулятор высоты проставки:
def get_space_after(events, free_space):
"""
Calculate spaces between events in percentages based on sum of free time and constraints.
:param events:
:return:
"""
timesum = timedelta(seconds=1)
time_list = []
for i in range(len(events) - 1):
time_diff = events[i + 1]['start'] - events[i]['end']
timesum += time_diff
time_list.append(time_diff)
time_list.append(timedelta(hours=0))
spaces = []
for diff in time_list:
spaces.append(round(diff/timesum * free_space, 4))
return spaces
Я пробовал KeepInFrame (), но когда он работает, он оставляет дизайн неровным и уродливым.Также я попытался исключить отступы фрейма, отступы абзаца и пространство в 1px между абзацами из переменной free_space в различных комбинациях, но, опять же, нет точного соответствия.Что делать?