Can you mark different chapters as different colour for me
cd /home/daytona/workspace/attachments/e7652656-f793-4bf8-91a8-8457a2b65ced/ && python3 -c " import pdfplumber with pdfplumber.open('I have all the text Now Ill categorize every quest.pdf') as pdf: print(f'Total pages: {len(pdf.pages)}') for i, page in enumerate(pdf.pages[:5]): print(f'--- Page {i+1} ---') text = page.extract_text() if text: print(text[:500]) print() "
python3 -c " import pdfplumber with pdfplumber.open('/home/daytona/workspace/attachments/e7652656-f793-4bf8-91a8-8457a2b65ced/I have all the text Now Ill categorize every quest.pdf') as pdf: for i, page in enumerate(pdf.pages): print(f'=== PAGE {i+1} ===') text = page.extract_text() if text: print(text) print() "
python3 -c " import pdfplumber with pdfplumber.open('/home/daytona/workspace/attachments/e7652656-f793-4bf8-91a8-8457a2b65ced/I have all the text Now Ill categorize every quest.pdf') as pdf: for i, page in enumerate(pdf.pages): print(f'=== PAGE {i+1} words sample ===') words = page.extract_words() for w in words[:30]: print(w) print() break "
mkdir -p /home/daytona/workspace/colored-pdf && python3 << 'EOF' import pdfplumber import fitz # PyMuPDF import re pdf_path = '/home/daytona/workspace/attachments/e7652656-f793-4bf8-91a8-8457a2b65ced/I have all the text Now Ill categorize every quest.pdf' # Chapter color map (RGB 0-1 scale for highlights) CHAPTER_COLORS = { 'Upper Limb': (0.68, 0.85, 1.0), # light blue 'Head & Neck': (0.72, 1.0, 0.72), # light green 'Neuroanatomy': (1.0, 0.85, 0.5), # light orange 'Thorax': (1.0, 0.75, 0.75), # light red/pink 'Abdomen': (0.85, 0.7, 1.0), # light purple 'Pelvis': (1.0, 0.95, 0.6), # light yellow 'Lower Limb': (0.6, 1.0, 0.9), # light cyan/teal 'Embryology': (1.0, 0.8, 0.9), # light pink/rose 'Histology': (0.9, 0.9, 0.7), # light olive/tan 'General Histology': (0.9, 0.9, 0.7), # same as Histology } def get_chapter(text): for key in CHAPTER_COLORS: if key.lower() in text.lower(): return key # Check aliases if 'neuro' in text.lower(): return 'Neuroanatomy' if 'embryo' in text.lower(): return 'Embryology' if 'histo' in text.lower(): return 'Histology' return None # Open with pdfplumber to get words with positions with pdfplumber.open(pdf_path) as plumb_pdf: all_page_words = [] for page in plumb_pdf.pages: words = page.extract_words() all_page_words.append(words) page_heights = [p.height for p in plumb_pdf.pages] print("Pages:", len(all_page_words)) print("Words on page 1:", len(all_page_words[0])) # Now identify lines on each page with their chapter # Group words into lines by their 'top' coordinate (within tolerance) def group_into_lines(words, tol=2): lines = {} for w in words: top = round(w['top']) # Find existing line within tolerance matched = None for lt in lines: if abs(lt - top) <= tol: matched = lt break if matched is None: lines[top] = [] matched = top lines[top].append(w) return dict(sorted(lines.items())) for pi, words in enumerate(all_page_words): lines = group_into_lines(words) print(f"\n--- Page {pi+1} lines ---") for top, ws in lines.items(): line_text = ' '.join(w['text'] for w in ws) chapter = get_chapter(line_text) print(f" top={top:.1f}: [{chapter}] {line_text[:80]}") EOF
python3 -c "import pymupdf; print('pymupdf ok')" 2>&1; python3 -c "import pdf2image; print('pdf2image ok')" 2>&1; python3 -c "from reportlab.pdfgen import canvas; print('reportlab ok')" 2>&1; python3 -c "import pdfrw; print('pdfrw ok')" 2>&1
python3 -c "from pypdf import PdfReader, PdfWriter; print('pypdf ok')" 2>&1; python3 -c "import pdfplumber; print('pdfplumber ok')" 2>&1; python3 -c "from reportlab.lib import colors; from reportlab.platypus import Table; print('reportlab full ok')" 2>&1
~/colored-pdf/build_colored_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
)
from reportlab.lib.colors import HexColor
OUTPUT = '/home/daytona/workspace/colored-pdf/anatomy_questions_colored.pdf'
# โโ Chapter color palette โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
CHAPTER_COLORS = {
'Upper Limb': HexColor('#AED6F1'), # sky blue
'Head & Neck': HexColor('#A9DFBF'), # soft green
'Neuroanatomy': HexColor('#FAD7A0'), # warm orange
'Thorax': HexColor('#F1948A'), # salmon/red
'Abdomen': HexColor('#D7BDE2'), # lavender
'Pelvis': HexColor('#F9E79F'), # yellow
'Lower Limb': HexColor('#A2D9CE'), # teal
'Embryology': HexColor('#F8C8D4'), # rose
'Histology': HexColor('#D5E8D4'), # olive green
}
CHAPTER_TEXT_COLOR = {k: colors.black for k in CHAPTER_COLORS}
def chapter_color(chapter_key):
for k, c in CHAPTER_COLORS.items():
if chapter_key and k.lower() in chapter_key.lower():
return c
return HexColor('#FFFFFF')
# โโ All categorized questions โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
# Format: (question_label, question_text, chapter_category)
PAPER1 = [
# label, question, chapter
('1a', 'Nerve traversing lower triangular intermuscular space (Radial nerve)', 'Upper Limb'),
('1b', 'Functional component of glossopharyngeal nerve', 'Neuroanatomy'),
('1c', 'Buccinator muscle pierced by (Parotid duct)', 'Head & Neck'),
('1d', 'Left superior intercostal vein drains into', 'Thorax'),
('1e', 'Characteristic feature of fibrocartilage', 'Histology'),
('1f', 'Surface modification on epididymis cells (Stereocilia)', 'Histology'),
('1g', 'Safety muscle of tongue (Genioglossus)', 'Head & Neck'),
('1h', 'Axillary nerve accompanied by which artery', 'Upper Limb'),
('1i', 'Temporal lobe contains (Primary auditory area)', 'Neuroanatomy'),
('1j', 'Anterior part of interventricular septum supplied by', 'Thorax'),
('2', 'Parotid gland (Gross anatomy, Nerve supply, Relations, Applied)', 'Head & Neck'),
('3a', 'Typical intercostal space', 'Thorax'),
('3b', 'Middle ear', 'Head & Neck'),
('3c', 'Circle of Willis', 'Neuroanatomy'),
('3d', 'Brachial plexus', 'Upper Limb'),
('4a', 'Surgical anatomy of thyroidectomy', 'Head & Neck'),
('4b', 'Winging of scapula', 'Upper Limb'),
('5a', 'Fibrous skeleton of heart', 'Thorax'),
('5b', 'Fourth ventricle of brain', 'Neuroanatomy'),
('5c', 'Nerve supply of tongue', 'Head & Neck'),
('5d', "Down's syndrome", 'Embryology'),
('6a', 'T.S. of Midbrain at level of superior colliculus', 'Neuroanatomy'),
('6b', 'Sensory & motor innervations of scalp', 'Head & Neck'),
]
PAPER2 = [
('1a', "Trendelenberg's sign โ Gluteus medius/minimus weakness", 'Lower Limb'),
('1b', 'Developmental component of inferior vena cava (except)', 'Embryology'),
('1c', 'Lymphatics of anterior abdominal wall above umbilicus', 'Abdomen'),
('1d', 'Ovarian artery branch of (Abdominal aorta)', 'Abdomen'),
('1e', 'Pelvic diaphragm formed by (Levator ani + Coccygeus)', 'Pelvis'),
('1f', 'Correct sequence of embryonic fertilization events', 'Embryology'),
('1g', 'Glomerulus is (Capillary tuft)', 'Abdomen'),
('1h', 'Muscle that unlocks the knee joint (Popliteus)', 'Lower Limb'),
('1i', 'Structures through aortic opening of diaphragm (except)', 'Thorax'),
('1j', 'Branch/es of external iliac artery', 'Abdomen'),
('2', 'Urinary bladder (Gross anatomy, Relations, Innervation, Applied)', 'Pelvis'),
('3a', 'Placental barrier', 'Embryology'),
('3b', 'Fetal heart', 'Embryology'),
('3c', 'Layers of retina', 'Head & Neck'),
('3d', 'Epiploic foramen', 'Abdomen'),
('4a', 'Referred pain in appendicitis', 'Abdomen'),
('4b', 'Atrial septal defects', 'Embryology'),
('5a', 'Thoraco-abdominal diaphragm', 'Thorax'),
('5b', 'Factors maintaining longitudinal arch of foot', 'Lower Limb'),
('5c', 'Portal vein (course, relations, tributaries)', 'Abdomen'),
('5d', 'Deep perineal pouch', 'Pelvis'),
('6a', 'Differentiation of thyroid gland', 'Embryology'),
('6b', 'Relations of hip joint', 'Lower Limb'),
]
# โโ Build the PDF โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=1.8*cm, rightMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm,
)
styles = getSampleStyleSheet()
title_style = ParagraphStyle(
'Title2', parent=styles['Title'],
fontSize=16, spaceAfter=6, textColor=HexColor('#1A1A2E'),
)
subtitle_style = ParagraphStyle(
'Subtitle', parent=styles['Normal'],
fontSize=10, textColor=HexColor('#555555'), spaceAfter=14,
)
section_style = ParagraphStyle(
'SectionHead', parent=styles['Heading1'],
fontSize=13, textColor=HexColor('#1A1A2E'),
spaceBefore=14, spaceAfter=4,
borderPad=4,
)
cell_style = ParagraphStyle(
'Cell', parent=styles['Normal'],
fontSize=9.5, leading=13,
)
# โโ Legend โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
def build_legend():
legend_data = []
for name, col in CHAPTER_COLORS.items():
swatch = Table([['']], colWidths=[1.2*cm], rowHeights=[0.45*cm])
swatch.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), col),
('BOX', (0,0), (-1,-1), 0.5, colors.grey),
]))
legend_data.append([swatch, Paragraph(name, cell_style)])
# Arrange in 2 columns
rows = []
for i in range(0, len(legend_data), 2):
row_left = legend_data[i]
row_right = legend_data[i+1] if i+1 < len(legend_data) else ['', '']
rows.append(row_left + row_right)
t = Table(rows, colWidths=[1.5*cm, 6*cm, 1.5*cm, 6*cm])
t.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 4),
('RIGHTPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 3),
('TOPPADDING', (0,0), (-1,-1), 3),
]))
return t
# โโ Question table โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
def build_question_table(rows_data):
# Header row
header = [
Paragraph('<b>Q#</b>', cell_style),
Paragraph('<b>Question / Topic</b>', cell_style),
Paragraph('<b>Chapter</b>', cell_style),
]
table_rows = [header]
row_bg_colors = [HexColor('#1A1A2E')] # header color
for label, question, chapter in rows_data:
bg = chapter_color(chapter)
table_rows.append([
Paragraph(f'<b>{label}</b>', cell_style),
Paragraph(question, cell_style),
Paragraph(chapter, cell_style),
])
row_bg_colors.append(bg)
t = Table(table_rows, colWidths=[1.0*cm, 10.5*cm, 4.5*cm], repeatRows=1)
style_cmds = [
('BACKGROUND', (0,0), (-1,0), HexColor('#1A1A2E')),
('TEXTCOLOR', (0,0), (-1,0), colors.white),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('ALIGN', (0,0), (-1,-1), 'LEFT'),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#BBBBBB')),
('ROWBACKGROUNDS', (0,1), (-1,-1), None), # will override below
]
# Apply per-row background colors
for i, bg in enumerate(row_bg_colors[1:], start=1):
style_cmds.append(('BACKGROUND', (0,i), (-1,i), bg))
t.setStyle(TableStyle(style_cmds))
return t
# โโ Build story โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
story = []
story.append(Paragraph("Anatomy Paper-I & II (2024)", title_style))
story.append(Paragraph("All questions categorized by anatomical chapter/topic", subtitle_style))
story.append(Paragraph("Colour Legend", section_style))
story.append(build_legend())
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width='100%', thickness=1, color=HexColor('#CCCCCC')))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Paper I โ Questions", section_style))
story.append(build_question_table(PAPER1))
story.append(Spacer(1, 0.6*cm))
story.append(Paragraph("Paper II โ Questions", section_style))
story.append(build_question_table(PAPER2))
story.append(Spacer(1, 0.6*cm))
doc.build(story)
print("Done! Saved to:", OUTPUT)
python3 /home/daytona/workspace/colored-pdf/build_colored_pdf.py
~/colored-pdf/build_colored_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/colored-pdf/build_colored_pdf.py'
python3 /home/daytona/workspace/colored-pdf/build_colored_pdf.py
anatomy questions colored
PDF Document ยท PDF
| Color | Chapter |
|---|---|
| ๐ต Sky Blue | Upper Limb |
| ๐ข Soft Green | Head & Neck |
| ๐ Warm Orange | Neuroanatomy |
| ๐ด Salmon/Red | Thorax |
| ๐ฃ Lavender | Abdomen |
| ๐ก Yellow | Pelvis & Perineum |
| ๐ฉต Teal | Lower Limb |
| ๐ธ Rose/Pink | Embryology |
| ๐ซ Olive Green | Histology |