Can you mark different chapters as different colour for me

Reading File
Running Command

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() "

Running Command

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() "

Running Command

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 "

Running Command

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

Running Command

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

Running Command

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

Writing File

~/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)
Running Command

python3 /home/daytona/workspace/colored-pdf/build_colored_pdf.py

Editing File

~/colored-pdf/build_colored_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/colored-pdf/build_colored_pdf.py'
Running Command

python3 /home/daytona/workspace/colored-pdf/build_colored_pdf.py

The PDF was generated successfully. Here's your color-coded file:

anatomy questions colored

PDF Document ยท PDF

Here's how the chapters are color-coded:
ColorChapter
๐Ÿ”ต Sky BlueUpper Limb
๐ŸŸข Soft GreenHead & Neck
๐ŸŸ  Warm OrangeNeuroanatomy
๐Ÿ”ด Salmon/RedThorax
๐ŸŸฃ LavenderAbdomen
๐ŸŸก YellowPelvis & Perineum
๐Ÿฉต TealLower Limb
๐ŸŒธ Rose/PinkEmbryology
๐Ÿซ’ Olive GreenHistology
The PDF contains:
  • A colour legend at the top
  • Paper I questions table with all rows colour-highlighted by chapter
  • Paper II questions table with the same system
This is a shared conversation. Sign in to Orris to start your own chat.