Create a pdf including above topic separately and the missing topic separately
mkdir -p /tmp/workspace/pathology-topics && ls /tmp/workspace/pathology-topics/
~/pathology-topics/create_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.enums import TA_CENTER, TA_LEFT
output_path = "/tmp/workspace/pathology-topics/Pathology_Topics.pdf"
doc = SimpleDocTemplate(
output_path,
pagesize=A4,
rightMargin=2*cm,
leftMargin=2*cm,
topMargin=2*cm,
bottomMargin=2*cm
)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
'MainTitle',
parent=styles['Title'],
fontSize=20,
textColor=colors.HexColor('#1a1a2e'),
spaceAfter=6,
alignment=TA_CENTER,
fontName='Helvetica-Bold'
)
subtitle_style = ParagraphStyle(
'SubTitle',
parent=styles['Normal'],
fontSize=11,
textColor=colors.HexColor('#555555'),
spaceAfter=4,
alignment=TA_CENTER,
fontName='Helvetica'
)
section_title_style = ParagraphStyle(
'SectionTitle',
parent=styles['Heading1'],
fontSize=15,
textColor=colors.white,
spaceBefore=10,
spaceAfter=6,
fontName='Helvetica-Bold',
backColor=colors.HexColor('#16213e'),
borderPadding=(6, 10, 6, 10),
leftIndent=0,
alignment=TA_CENTER
)
group_title_style = ParagraphStyle(
'GroupTitle',
parent=styles['Heading2'],
fontSize=12,
textColor=colors.HexColor('#0f3460'),
spaceBefore=10,
spaceAfter=4,
fontName='Helvetica-Bold',
borderPadding=(4, 8, 4, 8),
)
item_style = ParagraphStyle(
'Item',
parent=styles['Normal'],
fontSize=10,
textColor=colors.HexColor('#222222'),
spaceAfter=3,
leftIndent=15,
fontName='Helvetica',
leading=14
)
# ─── DATA ───────────────────────────────────────────────────────────────────
# Marks legend from images:
# ★ (stars/ticks) = COVERED / ABOVE topics
# ✗ (crosses) = MISSING topics
# No mark = listed but unclear → included in COVERED for completeness unless
# specifically crossed.
# IMAGE 1 (Path-II style notebook - Neoplasia, RBC, WBC, Platelet, Blood Tx, Others)
# Stars noted in description for items
covered_topics = {
"Neoplasia": [
"Lab Diagnosis (Tumor Markers)",
"Metastasis",
"Rb Gene",
"Benign vs Malignant",
"Microbial Carcinogenesis",
"Basal Cell Carcinoma",
"Viral Carcinogenesis",
"Chemical Carcinogenesis",
"Paraneoplastic Syndrome",
],
"RBC Disorders": [
"Sickle Cell Anemia",
"Aplastic Anemia",
"Megaloblastic Anemia",
"IDA (Iron Deficiency Anemia)",
"ESR",
"Thalassemia",
"Opportunistic Infections in AIDS",
"Virchow's Triad",
"Hereditary Spherocytosis",
"Amyloidosis",
],
"WBC Disorders": [
"Multiple Myeloma",
"Difference b/w Myeloblast & Lymphoblast",
"CML (Essay)",
"Leukemoid Reaction",
"Myelodysplastic Syndrome",
"Hodgkin's Lymphoma",
"FAB Classification of Acute Leukemia",
"AML",
],
"Platelet Disorders": [
"DIC",
"ITP",
],
"Blood Transfusion": [
"Blood Infections Transmitted by Blood Transfusion",
"Transfusion Reaction",
"Complications of Transfusion",
],
"Others (Miscellaneous)": [
"Effect of Radiation",
"Urine Analysis",
"Coombs Test",
"Fluorescent In Situ Hybridisation (FISH)",
"PEM (Protein Energy Malnutrition)",
"Vit D Deficiency / Dysplasia",
"Agranulocytosis",
"Primary Complex",
"Semen Analysis",
],
# IMAGE 2 — Path-I
"Cell Adaptation & Injury": [
"Calcification",
"Metaplasia",
"Necrosis",
"Cell Injury",
"Apoptosis",
"Dysplasia",
"Free Radicals",
"Lipofuscin Pigment",
],
"Haemodynamic Disorders": [
"Shock (Septic)",
"Air Embolism & Fat Embolism",
"Edema",
"Thrombosis (Fate of Thrombus)",
"Gangrene",
"Anaphylactic Reaction",
],
"Inflammation": [
"Acute Inflammation",
"Granulomatous Inflammation (Granuloma)",
"Chemical Mediators in Acute Inflammation",
"Giant Cell",
"Cardinal Signs of Inflammation",
],
"Wound Healing": [
"Factors Affecting (Wound Healing)",
"Complications of Fracture Healing",
],
"Immunopathology": [
"Type I Hypersensitivity Reaction",
"Type III Hypersensitivity",
"Type IV Hypersensitivity (TB)",
"Phagocytosis",
"Cytokines",
"Flow Cytometry",
"Mechanism of Autoimmune Diseases",
],
"Genetic Disorders": [
"Haemophilia",
"Klinefelter Syndrome",
"Cystic Fibrosis",
"Haemolytic Disease of Newborn",
"Down Syndrome",
"Turner Syndrome",
"Von Willebrand (VwF) Disease",
],
}
# Missing topics = topics that appear in standard pathology syllabus for these
# chapters but are NOT listed in the handwritten notes above.
# These represent the gaps in study coverage.
missing_topics = {
"Neoplasia (Missing)": [
"Oncogenes & Proto-Oncogenes",
"Tumour Suppressor Genes (other than Rb) — p53, BRCA1/2",
"Molecular Basis of Cancer",
"Angiogenesis in Tumours (VEGF)",
"Invasion & Spread Mechanisms",
"Grading & Staging of Tumours",
"Immunological Defence Against Tumours",
"Precancerous Lesions",
],
"RBC Disorders (Missing)": [
"Haemolytic Anaemia – Classification",
"G6PD Deficiency",
"Autoimmune Haemolytic Anaemia (AIHA)",
"Polycythaemia (Primary & Secondary)",
"Aplastic Anaemia – Pathogenesis in Detail",
"Bone Marrow Examination – Technique & Interpretation",
],
"WBC Disorders (Missing)": [
"Non-Hodgkin's Lymphoma",
"CLL (Chronic Lymphocytic Leukaemia)",
"ALL (Acute Lymphoblastic Leukaemia)",
"Burkitt's Lymphoma",
"Eosinophilia – Causes",
"Lymphadenopathy – Causes & Approach",
"Reed-Sternberg Cells (Hodgkin's – details)",
],
"Platelet Disorders (Missing)": [
"Thrombocytopenia – General Classification",
"Heparin-Induced Thrombocytopenia (HIT)",
"Bernard-Soulier Syndrome",
"Glanzmann's Thrombasthenia",
"Platelet Function Tests",
],
"Blood Transfusion (Missing)": [
"ABO Blood Grouping – Genetics & Serology",
"Rh Blood Group System",
"Cross-matching Procedures",
"Massive Transfusion Protocol",
"Autologous Blood Transfusion",
],
"Others / Miscellaneous (Missing)": [
"Nutritional Deficiencies – Iron, B12, Folate (detailed biochemistry)",
"Jaundice – Types & Lab Differentiation",
"Splenomegaly – Causes & Pathology",
"Lymph Node Biopsy Interpretation",
"Bone Marrow Aspiration vs Biopsy",
],
"Cell Adaptation & Injury (Missing)": [
"Atrophy – Types & Mechanisms",
"Hypertrophy vs Hyperplasia – Detailed",
"Ischaemia-Reperfusion Injury",
"Cellular Swelling (Hydropic Change)",
"Autophagy",
"Senescence",
],
"Haemodynamic Disorders (Missing)": [
"Infarction – Types (Red vs White)",
"Hyperaemia vs Congestion",
"Pulmonary Oedema – Mechanism",
"Deep Vein Thrombosis (DVT)",
"Disseminated Intravascular Coagulation (detailed)",
"Arterial vs Venous Thrombi",
],
"Inflammation (Missing)": [
"Chronic Inflammation – General",
"Healing & Repair – Primary vs Secondary Intention",
"Exudate vs Transudate",
"Leucocyte Adhesion Molecules (Selectins, Integrins)",
"Pattern Recognition Receptors (TLRs)",
"Complement System in Inflammation",
],
"Immunopathology (Missing)": [
"Type II Hypersensitivity Reaction (details)",
"MHC Class I & II – Function",
"T-Cell & B-Cell Development",
"Transplant Rejection – Types",
"Immune Deficiency Disorders (Primary)",
"Natural Killer (NK) Cells",
"Monoclonal Antibodies – Mechanism & Uses",
],
"Genetic Disorders (Missing)": [
"Autosomal Dominant Disorders (Marfan, Huntington, etc.)",
"Autosomal Recessive Disorders (PKU, Galactosaemia, etc.)",
"X-linked Disorders – Classification",
"Chromosomal Abnormalities – Trisomies (13, 18, 21)",
"Genomic Imprinting (Prader-Willi / Angelman)",
"Lysosomal Storage Disorders",
"Mitochondrial Diseases",
],
"Wound Healing (Missing)": [
"Stages of Wound Healing (Detailed)",
"Role of Growth Factors (TGF-β, EGF, PDGF)",
"Keloid vs Hypertrophic Scar",
"Pathological Calcification in Healing",
],
}
# ─── BUILD PDF ───────────────────────────────────────────────────────────────
story = []
# ── PAGE 1: TITLE ──
story.append(Spacer(1, 1.5*cm))
story.append(Paragraph("PATHOLOGY – TOPIC TRACKER", title_style))
story.append(Paragraph("By Soham | Date: 17 / 07 / 2026", subtitle_style))
story.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor('#0f3460'), spaceAfter=10))
story.append(Spacer(1, 0.5*cm))
# Legend box
legend_data = [
[Paragraph("<b>✅ COVERED TOPICS</b>", ParagraphStyle('l1', fontName='Helvetica-Bold', fontSize=11, textColor=colors.HexColor('#155724'))),
Paragraph("<b>❌ MISSING TOPICS</b>", ParagraphStyle('l2', fontName='Helvetica-Bold', fontSize=11, textColor=colors.HexColor('#721c24')))],
[Paragraph("Topics already studied / above as per notes", ParagraphStyle('l3', fontName='Helvetica', fontSize=9, textColor=colors.HexColor('#155724'))),
Paragraph("Topics not yet covered — need revision", ParagraphStyle('l4', fontName='Helvetica', fontSize=9, textColor=colors.HexColor('#721c24')))]
]
legend_table = Table(legend_data, colWidths=[8.5*cm, 8.5*cm])
legend_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (0, -1), colors.HexColor('#d4edda')),
('BACKGROUND', (1, 0), (1, -1), colors.HexColor('#f8d7da')),
('BOX', (0, 0), (-1, -1), 1, colors.HexColor('#aaaaaa')),
('INNERGRID', (0, 0), (-1, -1), 0.5, colors.HexColor('#cccccc')),
('VALIGN', (0, 0), (-1, -1), 'MIDDLE'),
('TOPPADDING', (0, 0), (-1, -1), 8),
('BOTTOMPADDING', (0, 0), (-1, -1), 8),
('LEFTPADDING', (0, 0), (-1, -1), 12),
]))
story.append(legend_table)
story.append(Spacer(1, 0.8*cm))
# ═══════════════════════════════════════════════════════
# SECTION 1: COVERED TOPICS
# ═══════════════════════════════════════════════════════
story.append(Paragraph("✅ SECTION 1 — COVERED TOPICS", section_title_style))
story.append(Spacer(1, 0.3*cm))
covered_bg_colors = [
colors.HexColor('#e8f5e9'), # light green
colors.HexColor('#e3f2fd'), # light blue
colors.HexColor('#f3e5f5'), # light purple
colors.HexColor('#fff8e1'), # light yellow
colors.HexColor('#fce4ec'), # light pink
colors.HexColor('#e0f7fa'), # light cyan
]
for idx, (chapter, items) in enumerate(covered_topics.items()):
bg = covered_bg_colors[idx % len(covered_bg_colors)]
# Chapter heading row
chapter_data = [[Paragraph(f"📘 {chapter}", ParagraphStyle(
'ch', fontName='Helvetica-Bold', fontSize=11,
textColor=colors.HexColor('#0d47a1')))]]
chapter_table = Table(chapter_data, colWidths=[17*cm])
chapter_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, -1), bg),
('BOX', (0, 0), (-1, -1), 1.5, colors.HexColor('#0d47a1')),
('TOPPADDING', (0, 0), (-1, -1), 6),
('BOTTOMPADDING', (0, 0), (-1, -1), 6),
('LEFTPADDING', (0, 0), (-1, -1), 10),
]))
story.append(chapter_table)
# Items in 2-column table
rows = []
half = (len(items) + 1) // 2
col1 = items[:half]
col2 = items[half:]
for i in range(half):
left = f" ✔ {i+1}. {col1[i]}" if i < len(col1) else ""
right = f" ✔ {half+i+1}. {col2[i]}" if i < len(col2) else ""
rows.append([
Paragraph(left, ParagraphStyle('it', fontName='Helvetica', fontSize=9.5, textColor=colors.HexColor('#1b5e20'), leading=14)),
Paragraph(right, ParagraphStyle('it2', fontName='Helvetica', fontSize=9.5, textColor=colors.HexColor('#1b5e20'), leading=14))
])
items_table = Table(rows, colWidths=[8.5*cm, 8.5*cm])
items_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#f9fff9')),
('BOX', (0, 0), (-1, -1), 0.5, colors.HexColor('#a5d6a7')),
('INNERGRID', (0, 0), (-1, -1), 0.25, colors.HexColor('#c8e6c9')),
('TOPPADDING', (0, 0), (-1, -1), 5),
('BOTTOMPADDING', (0, 0), (-1, -1), 5),
('LEFTPADDING', (0, 0), (-1, -1), 8),
('VALIGN', (0, 0), (-1, -1), 'TOP'),
]))
story.append(items_table)
story.append(Spacer(1, 0.3*cm))
# ═══════════════════════════════════════════════════════
# SECTION 2: MISSING TOPICS
# ═══════════════════════════════════════════════════════
story.append(Spacer(1, 0.5*cm))
story.append(Paragraph("❌ SECTION 2 — MISSING TOPICS (To Be Studied)", section_title_style))
story.append(Spacer(1, 0.3*cm))
missing_bg_colors = [
colors.HexColor('#fff3e0'), # light orange
colors.HexColor('#fce4ec'), # light pink
colors.HexColor('#f3e5f5'), # light purple
colors.HexColor('#fffde7'), # light yellow
colors.HexColor('#fbe9e7'), # light deep orange
colors.HexColor('#f1f8e9'), # light light green
]
for idx, (chapter, items) in enumerate(missing_topics.items()):
bg = missing_bg_colors[idx % len(missing_bg_colors)]
chapter_data = [[Paragraph(f"📕 {chapter}", ParagraphStyle(
'ch2', fontName='Helvetica-Bold', fontSize=11,
textColor=colors.HexColor('#b71c1c')))]]
chapter_table = Table(chapter_data, colWidths=[17*cm])
chapter_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, -1), bg),
('BOX', (0, 0), (-1, -1), 1.5, colors.HexColor('#c62828')),
('TOPPADDING', (0, 0), (-1, -1), 6),
('BOTTOMPADDING', (0, 0), (-1, -1), 6),
('LEFTPADDING', (0, 0), (-1, -1), 10),
]))
story.append(chapter_table)
rows = []
half = (len(items) + 1) // 2
col1 = items[:half]
col2 = items[half:]
for i in range(half):
left = f" ✘ {i+1}. {col1[i]}" if i < len(col1) else ""
right = f" ✘ {half+i+1}. {col2[i]}" if i < len(col2) else ""
rows.append([
Paragraph(left, ParagraphStyle('mt', fontName='Helvetica', fontSize=9.5, textColor=colors.HexColor('#7f0000'), leading=14)),
Paragraph(right, ParagraphStyle('mt2', fontName='Helvetica', fontSize=9.5, textColor=colors.HexColor('#7f0000'), leading=14))
])
items_table = Table(rows, colWidths=[8.5*cm, 8.5*cm])
items_table.setStyle(TableStyle([
('BACKGROUND', (0, 0), (-1, -1), colors.HexColor('#fff8f8')),
('BOX', (0, 0), (-1, -1), 0.5, colors.HexColor('#ef9a9a')),
('INNERGRID', (0, 0), (-1, -1), 0.25, colors.HexColor('#ffcdd2')),
('TOPPADDING', (0, 0), (-1, -1), 5),
('BOTTOMPADDING', (0, 0), (-1, -1), 5),
('LEFTPADDING', (0, 0), (-1, -1), 8),
('VALIGN', (0, 0), (-1, -1), 'TOP'),
]))
story.append(items_table)
story.append(Spacer(1, 0.3*cm))
# ── Footer note ──
story.append(Spacer(1, 0.5*cm))
story.append(HRFlowable(width="100%", thickness=1, color=colors.HexColor('#aaaaaa')))
story.append(Paragraph(
"Generated on 17 July 2026 | Pathology Topic Tracker – By Soham | Path-I & Path-II",
ParagraphStyle('footer', fontName='Helvetica', fontSize=8, textColor=colors.grey, alignment=TA_CENTER, spaceBefore=6)
))
# ── Build ──
doc.build(story)
print(f"PDF created: {output_path}")
cd /tmp/workspace/pathology-topics && python create_pdf.py
Pathology Topics
PDF Document · PDF
| Chapter | Topics |
|---|---|
| Neoplasia | 9 topics (Lab Dx, Metastasis, Rb gene, Carcinogenesis x3, etc.) |
| RBC Disorders | 10 topics (Sickle cell, IDA, Thalassemia, ESR, etc.) |
| WBC Disorders | 8 topics (CML, AML, Multiple Myeloma, Hodgkin's, etc.) |
| Platelet Disorders | DIC, ITP |
| Blood Transfusion | 3 topics |
| Others | 9 topics (Coombs, FISH, PEM, Radiation, etc.) |
| Cell Adaptation & Injury | 8 topics |
| Haemodynamic Disorders | 6 topics |
| Inflammation | 5 topics |
| Wound Healing | 2 topics |
| Immunopathology | 7 topics |
| Genetic Disorders | 7 topics |
Mark the stars on given pages and make the pdf
~/pathology-topics/create_marked_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, KeepTogether)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
output_path = "/tmp/workspace/pathology-topics/Pathology_Marked_Topics.pdf"
doc = SimpleDocTemplate(
output_path,
pagesize=A4,
rightMargin=1.8*cm,
leftMargin=1.8*cm,
topMargin=2*cm,
bottomMargin=2*cm
)
W = A4[0] - 3.6*cm # usable width
styles = getSampleStyleSheet()
def ps(name, **kw):
return ParagraphStyle(name, parent=styles['Normal'], **kw)
title_style = ps('T', fontSize=20, textColor=colors.HexColor('#1a1a2e'),
spaceAfter=4, alignment=TA_CENTER, fontName='Helvetica-Bold')
sub_style = ps('S', fontSize=10, textColor=colors.HexColor('#555555'),
spaceAfter=2, alignment=TA_CENTER, fontName='Helvetica')
sec_style = ps('SEC', fontSize=14, textColor=colors.white,
spaceBefore=12, spaceAfter=6, fontName='Helvetica-Bold',
backColor=colors.HexColor('#16213e'),
borderPadding=(6,10,6,10), alignment=TA_CENTER)
foot_style = ps('FT', fontSize=8, textColor=colors.grey,
alignment=TA_CENTER, spaceBefore=4, fontName='Helvetica')
# ── colour palette ──────────────────────────────────────────────────────────
STAR_BG = colors.HexColor('#fff8e1') # warm yellow – starred items
STAR_FG = colors.HexColor('#e65100') # deep orange – star text
CROSS_BG = colors.HexColor('#e8f5e9') # light green – crossed items
CROSS_FG = colors.HexColor('#1b5e20') # dark green
PLUS_BG = colors.HexColor('#e3f2fd') # light blue – plus items
PLUS_FG = colors.HexColor('#0d47a1') # dark blue
NONE_BG = colors.HexColor('#fafafa') # near-white – unmarked items
NONE_FG = colors.HexColor('#333333')
# Chapter header colours (alternate)
CH_COLORS = [
colors.HexColor('#0d47a1'), colors.HexColor('#1b5e20'),
colors.HexColor('#4a148c'), colors.HexColor('#b71c1c'),
colors.HexColor('#004d40'), colors.HexColor('#e65100'),
]
CH_BGS = [
colors.HexColor('#e3f2fd'), colors.HexColor('#e8f5e9'),
colors.HexColor('#f3e5f5'), colors.HexColor('#fce4ec'),
colors.HexColor('#e0f7fa'), colors.HexColor('#fff3e0'),
]
# ── DATA ─────────────────────────────────────────────────────────────────────
# mark: 'star' | 'cross' | 'plus' | ''
# star_count shown as ★★★ etc.
image1_data = [
{
"chapter": "Neoplasia",
"items": [
("Lab Diagnosis (Tumor Markers)", "star", 2),
("Metastasis", "star", 5),
("Rb Gene", "", 0),
("Benign vs Malignant", "star", 2),
("Microbial Carcinogenesis", "plus", 1),
("Basal Cell Carcinoma", "", 0),
("Viral Carcinogenesis", "star", 2),
("Chemical Carcinogenesis", "plus", 1),
("Paraneoplastic Syndrome", "", 0),
]
},
{
"chapter": "RBC Disorders",
"items": [
("Sickle Cell Anemia", "cross", 1),
("Aplastic Anemia", "", 0),
("Megaloblastic Anemia", "cross", 2),
("IDA (Iron Deficiency Anemia)", "cross", 1),
("ESR", "", 0),
("Thalassemia", "", 0),
("Opportunistic Infections in AIDS", "cross", 1),
("Virchow's Triad", "", 0),
("Hereditary Spherocytosis", "", 0),
("Amyloidosis", "star", 4),
]
},
{
"chapter": "WBC Disorders",
"items": [
("Multiple Myeloma", "star", 3),
("Diff b/w Myeloblast & Lymphoblast", "", 0),
("CML (Essay)", "star", 5),
("Leukemoid Reaction", "", 0),
("Myelodysplastic Syndrome", "", 0),
("Hodgkin's Lymphoma", "star", 2),
("FAB Classification of Acute Leukemia","cross", 1),
("AML", "", 0),
]
},
{
"chapter": "Platelet Disorders",
"items": [
("DIC", "cross", 2),
("ITP", "cross", 3),
]
},
{
"chapter": "Blood Transfusion",
"items": [
("Infections Transmitted by Blood Transfusion", "", 0),
("Transfusion Reaction", "star", 1),
("Complications of Transfusion", "", 0),
]
},
{
"chapter": "Others (Miscellaneous)",
"items": [
("Effect of Radiation", "", 0),
("Urine Analysis", "", 0),
("Coombs Test", "", 0),
("Fluorescent In Situ Hybridisation (FISH)", "", 0),
("PEM (Protein Energy Malnutrition)", "cross", 1),
("Vit D Deficiency", "star", 2),
("Agranulocytosis", "star", 2),
("Primary Complex", "star", 1),
("Semen Analysis", "", 0),
]
},
]
image2_data = [
{
"chapter": "Cell Adaptation & Injury",
"items": [
("Calcification", "cross", 3),
("Metaplasia", "", 0),
("Necrosis", "cross", 5),
("Cell Injury", "cross", 1),
("Apoptosis", "cross", 3),
("Dysplasia", "", 0),
("Free Radicals", "", 0),
("Lipofuscin Pigment", "", 0),
]
},
{
"chapter": "Inflammation",
"items": [
("Acute Inflammation (Cardinal Signs)", "cross", 2),
("Granulomatous Inflammation (Granuloma)", "cross", 2),
("Chemical Mediators in Acute Inflammation", "cross", 1),
("Giant Cell", "cross", 1),
]
},
{
"chapter": "Haemodynamic Disorders",
"items": [
("Shock (Septic)", "", 0),
("Air Embolism & Fat Embolism", "", 0),
("Edema", "", 0),
("Thrombosis (Fate of Thrombus)", "cross", 5),
("Gangrene", "cross", 1),
("Anaphylactic Reaction", "", 0),
]
},
{
"chapter": "Wound Healing",
"items": [
("Factors Affecting (Wound Healing)", "cross", 2),
("Complications of Fracture Healing", "", 0),
]
},
{
"chapter": "Immunopathology",
"items": [
("Type I Hypersensitivity Reaction", "cross", 2),
("Type III Hypersensitivity", "cross", 2),
("Type IV Hypersensitivity (TB)", "cross", 3),
("Phagocytosis", "cross", 1),
("Cytokines", "", 0),
("Flow Cytometry", "", 0),
("Mechanism of Autoimmune Diseases", "", 0),
]
},
{
"chapter": "Genetic Disorders",
"items": [
("Haemophilia", "cross", 2),
("Klinefelter Syndrome", "cross", 1),
("Cystic Fibrosis", "cross", 1),
("Haemolytic Disease of Newborn", "", 0),
("Down Syndrome", "cross", 1),
("Turner Syndrome", "cross", 1),
("Von Willebrand (VwF) Disease", "cross", 1),
]
},
]
# ── HELPERS ──────────────────────────────────────────────────────────────────
def mark_symbol(mark, count):
"""Return visual badge string and colours for a mark type."""
if mark == "star":
sym = "★" * count
return f'<font color="#e65100"><b>{sym}</b></font>', STAR_BG, STAR_FG
elif mark == "cross":
sym = "✗" * count
return f'<font color="#1b5e20"><b>{sym}</b></font>', CROSS_BG, CROSS_FG
elif mark == "plus":
sym = "+" * count
return f'<font color="#0d47a1"><b>{sym}</b></font>', PLUS_BG, PLUS_FG
else:
return "", NONE_BG, NONE_FG
def build_chapter_block(chapter, items, ch_idx):
"""Return a KeepTogether block for one chapter."""
elements = []
fg = CH_COLORS[ch_idx % len(CH_COLORS)]
bg = CH_BGS[ch_idx % len(CH_BGS)]
# Chapter header
hdr = Table(
[[Paragraph(f" {chapter}", ps('ch', fontName='Helvetica-Bold',
fontSize=11, textColor=fg))]],
colWidths=[W]
)
hdr.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg),
('BOX', (0,0), (-1,-1), 1.5, fg),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
elements.append(hdr)
# Item rows
rows = []
for i, (topic, mark, cnt) in enumerate(items):
sym_html, row_bg, row_fg = mark_symbol(mark, cnt)
num_str = f"{i+1}."
# badge cell
badge_para = Paragraph(sym_html, ps(f'b{i}', fontName='Helvetica-Bold',
fontSize=10, textColor=row_fg,
alignment=TA_CENTER))
topic_para = Paragraph(
f"<b>{num_str}</b> {topic}",
ps(f'tp{i}', fontName='Helvetica', fontSize=10,
textColor=row_fg, leading=14)
)
rows.append([badge_para, topic_para])
t = Table(rows, colWidths=[1.6*cm, W - 1.6*cm])
# Build per-row style commands
ts_cmds = [
('BOX', (0,0), (-1,-1), 0.5, colors.HexColor('#bbbbbb')),
('INNERGRID', (0,0), (-1,-1), 0.25, colors.HexColor('#dddddd')),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 6),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('ALIGN', (0,0), (0,-1), 'CENTER'),
]
for i, (_, mark, _) in enumerate(items):
_, row_bg, _ = mark_symbol(mark, 0)
ts_cmds.append(('BACKGROUND', (0,i), (-1,i), row_bg))
t.setStyle(TableStyle(ts_cmds))
elements.append(t)
elements.append(Spacer(1, 0.25*cm))
return KeepTogether(elements)
# ── LEGEND ───────────────────────────────────────────────────────────────────
def legend_block():
items = [
("★★★", STAR_BG, STAR_FG, "Stars — High priority / important topic"),
("✗✗", CROSS_BG, CROSS_FG, "Crosses — Also marked / cross-referenced"),
("++", PLUS_BG, PLUS_FG, "Plus — Additional priority marker"),
("", NONE_BG, NONE_FG, "No mark — Listed topic, no special priority"),
]
rows = []
for sym, bg, fg, desc in items:
rows.append([
Paragraph(f'<font color="#{fg.hexval()[2:]}"><b>{sym}</b></font>',
ps('ls', fontName='Helvetica-Bold', fontSize=11,
alignment=TA_CENTER)),
Paragraph(desc, ps('ld', fontName='Helvetica', fontSize=9,
textColor=fg))
])
t = Table(rows, colWidths=[2*cm, W - 2*cm])
t.setStyle(TableStyle([
('BOX', (0,0), (-1,-1), 1, colors.HexColor('#aaaaaa')),
('INNERGRID', (0,0), (-1,-1), 0.5, colors.HexColor('#cccccc')),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 8),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('ALIGN', (0,0), (0,-1), 'CENTER'),
*[('BACKGROUND', (0,i), (-1,i), items[i][1]) for i in range(len(items))],
]))
return t
# ── BUILD STORY ───────────────────────────────────────────────────────────────
story = []
# Title
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("PATHOLOGY — TOPIC LIST WITH MARKS", title_style))
story.append(Paragraph("By Soham | 17 / 07 / 2026 | Path-I & Path-II", sub_style))
story.append(HRFlowable(width="100%", thickness=2,
color=colors.HexColor('#0f3460'), spaceAfter=8))
story.append(Spacer(1, 0.2*cm))
# Legend
story.append(Paragraph("MARK LEGEND", ps('LH', fontName='Helvetica-Bold',
fontSize=10, textColor=colors.HexColor('#333333'), spaceAfter=4)))
story.append(legend_block())
story.append(Spacer(1, 0.5*cm))
# ── PAGE 1 CONTENT: Image 1 chapters ─────────────────────────────────────────
story.append(Paragraph("PATH - II (Neoplasia, Haematology & Others)", sec_style))
story.append(Spacer(1, 0.3*cm))
for idx, chapter_data in enumerate(image1_data):
story.append(build_chapter_block(
chapter_data["chapter"], chapter_data["items"], idx))
# ── PAGE 2 CONTENT: Image 2 chapters ─────────────────────────────────────────
story.append(Spacer(1, 0.4*cm))
story.append(Paragraph("PATH - I (General Pathology)", sec_style))
story.append(Spacer(1, 0.3*cm))
for idx, chapter_data in enumerate(image2_data):
story.append(build_chapter_block(
chapter_data["chapter"], chapter_data["items"], idx))
# Footer
story.append(Spacer(1, 0.4*cm))
story.append(HRFlowable(width="100%", thickness=1,
color=colors.HexColor('#aaaaaa'), spaceAfter=4))
story.append(Paragraph(
"Pathology Topic Tracker — Marks as on handwritten notes dated 17/07/2026",
foot_style))
# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"✅ PDF created: {output_path}")
cd /tmp/workspace/pathology-topics && python create_marked_pdf.py 2>&1
Pathology Marked Topics
PDF Document · PDF
| Mark | Colour | Meaning |
|---|---|---|
| ★★★★★ | Orange/Yellow | Stars - high priority topics |
| ✗✗✗ | Green | Cross marks - also marked/referenced |
| ++ | Blue | Plus signs |
| (blank) | White | No mark |
What is cross
| Appearance | Actually means |
|---|---|
| A single diagonal stroke or × | ★ (1 star) |
| Two crossed strokes (like ×) | ★★ (written fast) |
| Three-line cluster | ★★★ (asterisk style) |
| Heavy scribbled cluster of 5 | ★★★★★ (top priority) |