| name | pdf-calendar-parsing |
| description | Extract calendar events, blocks, and time slots from PDF calendar files using pdfplumber |
PDF Calendar Parsing Skill
Overview
This skill covers extracting calendar events and time blocks from PDF calendar documents using pdfplumber, a Python library for extracting text and tables from PDF files.
Installation
pip install pdfplumber
Key Concepts
How pdfplumber Works
- Opens PDF files and extracts text with position information
- Can identify text bounding boxes (x0, y0, x1, y1 coordinates)
- Supports extracting tables and structured data
Calendar Grid Extraction
For a calendar with hourly/time-based layout:
- Extract all text from the PDF with position data
- Identify time labels (hours on the left axis)
- Identify event blocks by text content and bounding boxes
- Calculate event duration by comparing Y-coordinates
Code Examples
Basic PDF Opening
import pdfplumber
with pdfplumber.open('/root/calendar.pdf') as pdf:
page = pdf.pages[0]
text = page.extract_text()
print(text)
Extracting Text with Positions
import pdfplumber
with pdfplumber.open('/root/calendar.pdf') as pdf:
page = pdf.pages[0]
for char in page.chars:
print(f"Text: {char['text']}, X: {char['x0']}, Y: {char['y0']}")
Identifying Calendar Events
import pdfplumber
def extract_calendar_events(pdf_path):
with pdfplumber.open(pdf_path) as pdf:
page = pdf.pages[0]
text_data = page.extract_text_with_layout()
words = page.extract_words()
events = []
for word in words:
if word['text'] not in ['12am', '1am', '2am']:
events.append({
'text': word['text'],
'x0': word['x0'],
'y0': word['y0'],
'x1': word['x1'],
'y1': word['y1']
})
return events
Time Extraction from Layout
def extract_time_labels(page):
"""Extract hour labels from calendar time axis"""
words = page.extract_words()
time_labels = {}
for word in words:
text = word['text']
if any(text.endswith(suffix) for suffix in ['am', 'pm']):
y_position = word['y0']
time_labels[text] = y_position
return sorted(time_labels.items(), key=lambda x: x[1])
Calculating Block Duration
def get_block_duration(y_start, y_end, time_lines, interval_minutes=15):
"""
Calculate duration of a calendar block
time_lines: list of (time_string, y_position) tuples, sorted by y
interval_minutes: minutes between adjacent horizontal lines
"""
start_time = None
end_time = None
for i, (time_str, y_pos) in enumerate(time_lines):
if y_pos <= y_start and (i+1 >= len(time_lines) or time_lines[i+1][1] > y_start):
start_time = time_str
if y_pos <= y_end and (i+1 >= len(time_lines) or time_lines[i+1][1] >= y_end):
end_time = time_str
return start_time, end_time
Common Pitfalls
- Y-coordinates increase downward in PDFs (unlike normal coordinate systems)
- Text extraction might include artifacts or formatting characters
- Font sizes and positions can vary; use threshold matching
- Event blocks may have overlapping text; use grouping strategies
Best Practices
- Always verify extracted text against visual inspection
- Sort time labels by Y-coordinate to create accurate mapping
- Use relative positioning (Y-coordinates) to determine time ranges
- Store both start and end times for accuracy
- Validate extracted times are within expected calendar hours