~/respiratory-notes/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import ListFlowable, ListItem
OUTPUT = "/home/daytona/workspace/respiratory-notes/Respiratory_Medicine_HighYield_Notes.pdf"
# ── Styles ──────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
NAVY = colors.HexColor("#1a3a5c")
TEAL = colors.HexColor("#1a7fa8")
GOLD = colors.HexColor("#e8a020")
LIGHT = colors.HexColor("#eaf4fb")
WHITE = colors.white
RED = colors.HexColor("#c0392b")
GREEN = colors.HexColor("#1e8449")
GREY_BG = colors.HexColor("#f5f5f5")
title_style = ParagraphStyle("TitleStyle", parent=styles["Title"],
fontSize=22, textColor=WHITE, alignment=TA_CENTER,
spaceAfter=4, fontName="Helvetica-Bold", leading=28)
subtitle_style = ParagraphStyle("SubtitleStyle", parent=styles["Normal"],
fontSize=11, textColor=LIGHT, alignment=TA_CENTER,
spaceAfter=2, fontName="Helvetica", leading=14)
h1_style = ParagraphStyle("H1", parent=styles["Heading1"],
fontSize=14, textColor=WHITE, fontName="Helvetica-Bold",
spaceAfter=0, spaceBefore=0, leading=18)
h2_style = ParagraphStyle("H2", parent=styles["Heading2"],
fontSize=11, textColor=NAVY, fontName="Helvetica-Bold",
spaceAfter=3, spaceBefore=6, leading=15)
h3_style = ParagraphStyle("H3", parent=styles["Heading3"],
fontSize=10, textColor=TEAL, fontName="Helvetica-Bold",
spaceAfter=2, spaceBefore=4, leading=13)
body_style = ParagraphStyle("Body", parent=styles["Normal"],
fontSize=9, textColor=colors.HexColor("#1c1c1c"),
fontName="Helvetica", spaceAfter=3, spaceBefore=1, leading=13)
bullet_style = ParagraphStyle("Bullet", parent=body_style,
leftIndent=14, bulletIndent=4, spaceAfter=2, leading=12)
note_style = ParagraphStyle("Note", parent=body_style,
backColor=colors.HexColor("#fffbea"),
borderPadding=(4, 6, 4, 6), textColor=colors.HexColor("#7d4e00"),
fontName="Helvetica-Oblique", fontSize=8.5)
source_style = ParagraphStyle("Source", parent=body_style,
fontSize=7.5, textColor=colors.grey, fontName="Helvetica-Oblique",
alignment=TA_CENTER)
# ── Helpers ──────────────────────────────────────────────────────────────────
def section_header(num, title):
"""Navy banner with white text."""
data = [[Paragraph(f"{num}. {title}", h1_style)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [4]),
]))
return t
def sub_header(text):
"""Teal left-border heading."""
data = [[Paragraph(text, h2_style)]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LINEAFTER", (0,0), (0,-1), 3, TEAL),
("LINEBEFORE", (0,0), (0,-1), 3, TEAL),
]))
return t
def bullet(text):
return Paragraph(f"• {text}", bullet_style)
def bold(text):
return f"<b>{text}</b>"
def colored_table(header_row, data_rows, col_widths=None):
"""Table with a navy header, zebra rows."""
all_rows = [header_row] + data_rows
if col_widths is None:
n = len(header_row)
col_widths = [17*cm / n] * n
t = Table(all_rows, colWidths=col_widths, repeatRows=1)
style = [
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("ALIGN", (0,0), (-1,-1), "LEFT"),
("FONTNAME", (0,1), (-1,-1), "Helvetica"),
("FONTSIZE", (0,1), (-1,-1), 8.5),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_BG]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#c0d0e0")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING",(0,0), (-1,-1), 6),
]
t.setStyle(TableStyle(style))
return t
def highlight_box(text, bg=colors.HexColor("#fff3cd"), border=GOLD):
data = [[Paragraph(text, ParagraphStyle("hb", parent=body_style,
fontSize=8.5, textColor=colors.HexColor("#5a3e00")))]]
t = Table(data, colWidths=[17*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LINEABOVE", (0,0), (-1,0), 2, border),
("LINEBELOW", (0,-1),(-1,-1), 2, border),
]))
return t
sp = lambda h=6: Spacer(1, h)
# ── Build Story ──────────────────────────────────────────────────────────────
story = []
# Cover Banner
cover_data = [[
Paragraph("HIGH-YIELD RESPIRATORY MEDICINE NOTES", title_style),
Paragraph("KUHS University & NEET PG Preparation", subtitle_style),
Paragraph("Based on: Harrison's Principles of Internal Medicine 22E (2025) & Murray & Nadel's Textbook of Respiratory Medicine", subtitle_style),
]]
cover_table = Table([[
Paragraph("HIGH-YIELD RESPIRATORY MEDICINE NOTES", title_style),
]], colWidths=[17*cm])
cover_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,-1), 18),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
]))
cover_sub = Table([[
Paragraph("KUHS University & NEET PG Preparation", subtitle_style),
]], colWidths=[17*cm])
cover_sub.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
]))
cover_sub2 = Table([[
Paragraph("Based on: Harrison's Principles of Internal Medicine 22E (2025) | Murray & Nadel's Textbook of Respiratory Medicine", subtitle_style),
]], colWidths=[17*cm])
cover_sub2.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 2),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
]))
story += [cover_table, cover_sub, cover_sub2, sp(14)]
# ============================================================
# SECTION 1: COMMUNITY-ACQUIRED PNEUMONIA
# ============================================================
story += [section_header("1", "COMMUNITY-ACQUIRED PNEUMONIA (CAP)"), sp(6)]
story += [sub_header("Definition & Classification"), sp(4)]
story += [
bullet("Pneumonia = infection of pulmonary <b>parenchyma</b>"),
bullet("Categories: <b>CAP</b> (community), <b>HAP</b> (hospital), <b>VAP</b> (ventilator-associated)"),
bullet("<b>HCAP (healthcare-associated) category is discontinued</b> — assess each patient individually for drug-resistant organism risk"),
sp(4),
]
story += [sub_header("Causative Organisms — HIGH YIELD"), sp(4)]
org_table = colored_table(
["Setting", "Organisms"],
[
["CAP (typical)", "S. pneumoniae (MC), H. influenzae, M. catarrhalis"],
["CAP (atypical)", "Mycoplasma, Chlamydophila pneumoniae, Legionella"],
["HAP / VAP", "Pseudomonas, MRSA, Klebsiella, Gram-negative rods"],
["Aspiration", "Anaerobes (Fusobacterium, Peptostreptococcus)"],
["Alcoholics", "Klebsiella pneumoniae (currant jelly sputum)"],
["Immunocompromised", "PCP (P. jirovecii), CMV, fungi"],
],
[6*cm, 11*cm]
)
story += [org_table, sp(6)]
story += [sub_header("CURB-65 Score — CAP Severity"), sp(4)]
story += [
highlight_box("<b>C</b> = Confusion | <b>U</b> = Urea >7 mmol/L | <b>R</b> = RR ≥30/min | <b>B</b> = BP <90 systolic | <b>65</b> = Age ≥65 yrs"),
sp(3),
]
curb_table = colored_table(
["Score", "Action"],
[
["0–1", "Outpatient treatment"],
["2", "Hospitalization"],
["≥3", "Consider ICU admission"],
],
[4*cm, 13*cm]
)
story += [curb_table, sp(6)]
story += [sub_header("Treatment"), sp(4)]
story += [
bullet("<b>Mild CAP (outpatient):</b> Amoxicillin OR azithromycin / doxycycline"),
bullet("<b>Moderate CAP (inpatient, non-ICU):</b> Beta-lactam + macrolide OR respiratory fluoroquinolone (levofloxacin / moxifloxacin)"),
bullet("<b>Severe CAP (ICU):</b> Beta-lactam + azithromycin OR beta-lactam + fluoroquinolone"),
bullet("<b>Legionella:</b> Fluoroquinolone or azithromycin"),
bullet("<b>Aspiration site:</b> Posterior segment RUL (upright) or superior segment RLL (supine)"),
sp(8),
]
# ============================================================
# SECTION 2: TUBERCULOSIS
# ============================================================
story += [section_header("2", "TUBERCULOSIS (TB)"), sp(6)]
story += [sub_header("Microbiology & Transmission"), sp(4)]
story += [
bullet("M. tuberculosis — obligate aerobe, slow-growing, <b>acid-fast bacillus (AFB)</b>"),
bullet("Transmission: <b>airborne</b> droplet nuclei (<5 microns)"),
bullet("Isolation: <b>negative-pressure room</b>, N95 respirator (filters 95% airborne particles)"),
bullet("IGRA preferred over TST for latent TB — higher PPV, not affected by BCG vaccination"),
sp(4),
]
story += [sub_header("Primary vs. Reactivation TB"), sp(4)]
tb_comp = colored_table(
["Feature", "Primary TB", "Reactivation TB"],
[
["Location", "Lower / middle lobe + hilar LN", "Apices (upper lobe) — classic"],
["Ghon complex", "Present (Ghon focus + hilar LN)", "Absent"],
["Cavitation", "Rare", "Common"],
["Immunity", "None / little", "Present"],
],
[5*cm, 6*cm, 6*cm]
)
story += [tb_comp, sp(6)]
story += [sub_header("First-Line Drug Side Effects — VERY HIGH YIELD"), sp(4)]
drug_table = colored_table(
["Drug", "Key Side Effects", "Monitor"],
[
["Isoniazid (H)", "Peripheral neuropathy (give B6/pyridoxine), hepatitis, lupus-like", "LFT, neurology"],
["Rifampicin (R)", "Orange discoloration urine/tears, hepatitis, CYP450 inducer (drug interactions)", "LFT"],
["Pyrazinamide (Z)", "Hyperuricemia, hepatitis, arthralgia", "Uric acid, LFT"],
["Ethambutol (E)", "Optic neuritis (red-green color blindness, ↓visual acuity)", "Visual acuity"],
],
[4*cm, 8.5*cm, 4.5*cm]
)
story += [drug_table, sp(4)]
story += [
highlight_box("<b>Standard regimen:</b> 2HRZE / 4HR — 2 months (INH + Rifampicin + Pyrazinamide + Ethambutol), then 4 months (INH + Rifampicin)"),
sp(4),
]
story += [sub_header("MDR-TB Treatment (WHO 2022)"), sp(4)]
mdr_table = colored_table(
["Group", "Drugs"],
[
["Group A (all 3 included)", "Levofloxacin/Moxifloxacin + Bedaquiline + Linezolid"],
["Group B (at least 1)", "Clofazimine, Cycloserine/Terizidone"],
["Group C (complete regimen)", "Ethambutol, Delamanid, Pyrazinamide, Carbapenems, Amikacin, PAS"],
],
[5*cm, 12*cm]
)
story += [mdr_table, sp(8)]
# ============================================================
# SECTION 3: ASTHMA
# ============================================================
story += [section_header("3", "ASTHMA"), sp(6)]
story += [sub_header("Definition & Pathophysiology"), sp(4)]
story += [
bullet("Chronic <b>inflammatory</b> airway disease with <b>airway hyperresponsiveness (AHR)</b> and reversible obstruction"),
bullet("Hallmark: episodic wheezing, dyspnea, chest tightness, cough — worse <b>nocturnal / early morning</b>"),
bullet("Mechanism: Mast cell → histamine, leukotrienes (LTC4, LTD4, LTE4), IL-4, IL-5, IL-13 → eosinophilic type 2 inflammation"),
bullet("Remodeling: subepithelial fibrosis, smooth muscle hypertrophy, goblet cell metaplasia"),
sp(4),
]
story += [sub_header("Diagnosis"), sp(4)]
story += [
bullet("Spirometry: FEV1/FVC <0.70 (obstructive pattern)"),
bullet("<b>Bronchodilator reversibility: ≥12% AND ≥200 mL increase in FEV1</b> post-bronchodilator"),
bullet("<b>Methacholine challenge</b>: PC20 <8 mg/mL = positive AHR (when spirometry is normal)"),
bullet("Peak flow variability >20% = suggestive of asthma"),
sp(4),
]
story += [sub_header("GINA Severity Classification"), sp(4)]
sev_table = colored_table(
["Severity", "Symptoms", "Night symptoms", "FEV1 % predicted"],
[
["Mild intermittent", "<2 days/week", "≤2/month", "≥80%"],
["Mild persistent", ">2 days/week, not daily", "3–4/month", "≥80%"],
["Moderate persistent", "Daily", ">1/week", "60–80%"],
["Severe persistent", "Continuous", "Frequent", "<60%"],
],
[4.5*cm, 4.5*cm, 3.5*cm, 4.5*cm]
)
story += [sev_table, sp(4)]
story += [sub_header("Treatment — Step-Up Approach"), sp(4)]
step_table = colored_table(
["Step", "Treatment"],
[
["Step 1", "As-needed SABA (salbutamol) OR low-dose ICS/formoterol PRN"],
["Step 2", "Low-dose ICS daily + SABA PRN"],
["Step 3", "Low-dose ICS/LABA daily"],
["Step 4", "Medium/high-dose ICS/LABA"],
["Step 5", "Add-on: LAMA, omalizumab (anti-IgE), mepolizumab/reslizumab (anti-IL-5), dupilumab (anti-IL-4Rα)"],
],
[3*cm, 14*cm]
)
story += [step_table, sp(4)]
story += [sub_header("Key Drug Facts — HIGH YIELD"), sp(4)]
story += [
bullet("<b>SABA (salbutamol):</b> First-line rescue; side effects — tremor, tachycardia"),
bullet("<b>ICS (budesonide, fluticasone):</b> Local effects — thrush (use spacer + gargle), hoarseness; systemic: osteoporosis, cataracts at high doses"),
bullet("<b>LABA (salmeterol, formoterol):</b> NOT monotherapy — risk of asthma death; always use with ICS"),
bullet("<b>Montelukast (CysLT1 antagonist):</b> Good for aspirin-exacerbated disease and exercise-induced; side effect — suicidal ideation (black box)"),
bullet("<b>Zileuton (5-LO inhibitor):</b> Raises liver enzymes (3%), inhibits CYP1A2"),
bullet("<b>Omalizumab (anti-IgE):</b> IgE ≥30 IU/mL + perennial allergen sensitization; reduces exacerbations 25–50%"),
sp(4),
]
story += [
highlight_box("<b>Samter's Triad (Aspirin-Exacerbated Respiratory Disease):</b> Asthma + Nasal Polyps + Aspirin Sensitivity → excess leukotrienes via COX-1 inhibition"),
sp(4),
highlight_box("<b>Status Asthmaticus:</b> Rising PaCO2 = dangerous sign (normal PaCO2 in acute asthma = early fatigue). Tx: IV salbutamol + ipratropium, IV Mg²⁺, IV steroids"),
sp(8),
]
# ============================================================
# SECTION 4: COPD
# ============================================================
story += [section_header("4", "COPD"), sp(6)]
story += [sub_header("Emphysema vs. Chronic Bronchitis"), sp(4)]
copd_comp = colored_table(
["Feature", "Emphysema", "Chronic Bronchitis"],
[
["Definition", "Destruction of alveolar walls", "Productive cough ≥3 months/yr × ≥2 yrs"],
["Mechanism", "Elastase-antielastase imbalance", "Mucous gland hypertrophy (Reid index >0.5)"],
["Body habitus", "Pink puffer (barrel chest, thin)", "Blue bloater (edematous, cyanotic)"],
["PaO2 / PaCO2", "Near normal / Low CO2", "Low O2 / High CO2"],
["Breath sounds", "Diminished throughout", "Ronchi / wheezing"],
["DLCO", "Reduced", "Normal or mildly reduced"],
],
[4.5*cm, 6.25*cm, 6.25*cm]
)
story += [copd_comp, sp(6)]
story += [sub_header("GOLD Staging (Post-Bronchodilator FEV1/FVC <0.70)"), sp(4)]
gold_table = colored_table(
["GOLD Grade", "Severity", "FEV1 % Predicted"],
[
["GOLD 1", "Mild", "≥80%"],
["GOLD 2", "Moderate", "50–79%"],
["GOLD 3", "Severe", "30–49%"],
["GOLD 4", "Very Severe", "<30%"],
],
[4*cm, 6*cm, 7*cm]
)
story += [gold_table, sp(6)]
story += [sub_header("Treatment — Survival-Improving Interventions"), sp(4)]
story += [
highlight_box("<b>Three interventions proven to improve survival in COPD:</b><br/>1. Smoking cessation (MOST IMPORTANT) | 2. Long-term O₂ therapy (PaO₂ ≤55 mmHg or SpO₂ ≤88%) | 3. Lung volume reduction surgery (LVRS) in selected emphysema"),
sp(4),
]
story += [
bullet("<b>LAMA</b> (tiotropium, aclidinium, glycopyrronium, umeclidinium) — reduces exacerbations more than LABA"),
bullet("<b>LABA</b> (salmeterol, indacaterol, formoterol, vilanterol)"),
bullet("<b>LABA + LAMA</b> combination > either alone"),
bullet("<b>Triple therapy</b> (LABA + LAMA + ICS) — reduces mortality in selected patients"),
bullet("<b>Roflumilast</b> (PDE4 inhibitor): frequent exacerbators with chronic bronchitis phenotype; side effects — weight loss, nausea, depression"),
bullet("<b>Azithromycin maintenance</b>: reduces exacerbations; check QT prolongation and hearing"),
bullet("<b>Controlled O₂</b> in AECOPD: target SpO₂ 88–92% to avoid CO₂ retention"),
sp(4),
]
story += [sub_header("Alpha-1 Antitrypsin Deficiency"), sp(4)]
story += [
bullet("MC genetic cause of COPD — <b>panacinar emphysema (lower lobe predominant)</b>"),
bullet("PiZZ genotype = severe deficiency; also causes liver disease (cirrhosis)"),
bullet("Treatment: AAT augmentation therapy"),
sp(8),
]
# ============================================================
# SECTION 5: PULMONARY EMBOLISM
# ============================================================
story += [section_header("5", "PULMONARY EMBOLISM (PE)"), sp(6)]
story += [sub_header("Virchow's Triad"), sp(4)]
story += [
highlight_box("<b>1. Stasis</b> (immobility, post-op, travel) | <b>2. Hypercoagulability</b> (malignancy, APS, OCP, pregnancy, thrombophilia) | <b>3. Endothelial injury</b> (surgery, trauma)"),
sp(4),
]
story += [sub_header("Investigations — HIGH YIELD"), sp(4)]
pe_inv = colored_table(
["Test", "Finding / Role"],
[
["ECG", "S1Q3T3 (deep S in I, Q in III, inverted T in III); sinus tachycardia most common"],
["D-dimer", "High sensitivity, low specificity — RULES OUT PE (high NPV) when negative"],
["CTPA", "GOLD STANDARD for diagnosis"],
["V/Q scan", "Use when CTPA contraindicated (contrast allergy, renal failure)"],
["Echo", "Dilated RV, McConnell sign (apical sparing of RV)"],
["ABG", "Hypoxemia + hypocapnia + respiratory alkalosis + increased A-a gradient"],
],
[4.5*cm, 12.5*cm]
)
story += [pe_inv, sp(4)]
story += [sub_header("Wells Score"), sp(4)]
wells_table = colored_table(
["Criterion", "Points"],
[
["DVT symptoms/signs", "3"],
["PE most likely diagnosis", "3"],
["HR >100/min", "1.5"],
["Immobilization/surgery in past 4 weeks", "1.5"],
["Prior DVT/PE", "1.5"],
["Hemoptysis", "1"],
["Malignancy", "1"],
["Score ≤4 = PE unlikely | Score >4 = PE likely", ""],
],
[13*cm, 4*cm]
)
story += [wells_table, sp(4)]
story += [sub_header("Treatment"), sp(4)]
story += [
bullet("<b>Anticoagulation:</b> DOACs (rivaroxaban, apixaban, edoxaban) preferred over LMWH/warfarin"),
bullet("<b>Massive PE (hemodynamically unstable):</b> Systemic thrombolysis (alteplase); catheter-directed thrombolysis; surgical embolectomy"),
bullet("<b>IVC filter:</b> When anticoagulation is contraindicated"),
sp(8),
]
# ============================================================
# SECTION 6: PLEURAL EFFUSION
# ============================================================
story += [section_header("6", "PLEURAL EFFUSION"), sp(6)]
story += [sub_header("Light's Criteria — VERY HIGH YIELD"), sp(4)]
story += [
highlight_box("<b>Exudate if ≥1 criterion met:</b><br/>1. Pleural fluid protein / serum protein >0.5<br/>2. Pleural fluid LDH / serum LDH >0.6<br/>3. Pleural fluid LDH > 2/3 upper limit of normal serum LDH"),
sp(4),
]
story += [sub_header("Transudate vs. Exudate"), sp(4)]
eff_table = colored_table(
["Feature", "Transudate", "Exudate"],
[
["Mechanism", "Hydrostatic/oncotic imbalance", "Local inflammation / injury"],
["Causes", "CHF (MC in USA), cirrhosis, nephrotic syndrome", "Pneumonia, malignancy, TB, PE"],
["Glucose", "Normal", "May be low (TB, malignancy, empyema)"],
["LDH", "Low", "High"],
],
[4.5*cm, 6.25*cm, 6.25*cm]
)
story += [eff_table, sp(4)]
story += [sub_header("Special Effusions"), sp(4)]
special_eff = colored_table(
["Type", "Key Features"],
[
["Empyema", "Pus; pH <7.2, glucose <60, very high LDH; mandates drainage (intercostal tube)"],
["Chylothorax", "Milky; triglycerides >110 mg/dL; caused by thoracic duct injury (trauma, malignancy)"],
["Hemothorax", "Hematocrit >50% of serum; trauma most common"],
["TB pleuritis", "Exudate; lymphocyte-predominant; ADA >40 IU/L (high sensitivity for TB)"],
],
[4.5*cm, 12.5*cm]
)
story += [special_eff, sp(8)]
# ============================================================
# SECTION 7: LUNG CANCER
# ============================================================
story += [section_header("7", "LUNG CANCER"), sp(6)]
story += [sub_header("Classification — HIGH YIELD"), sp(4)]
lc_table = colored_table(
["Type", "Location", "Key Features"],
[
["Squamous cell carcinoma", "Central", "Hilar mass, cavitation, paraneoplastic hypercalcemia (PTHrP), Pancoast tumor"],
["Adenocarcinoma", "Peripheral", "MC in non-smokers & women; EGFR/ALK mutations; hypertrophic osteoarthropathy"],
["Small cell (SCLC)", "Central", "Most aggressive; neuroendocrine; SIADH, Cushing (ectopic ACTH), Lambert-Eaton"],
["Large cell carcinoma", "Peripheral", "Poorly differentiated; diagnosis of exclusion"],
],
[4.5*cm, 3.5*cm, 9*cm]
)
story += [lc_table, sp(4)]
story += [sub_header("Paraneoplastic Syndromes — VERY HIGH YIELD"), sp(4)]
para_table = colored_table(
["Syndrome", "Associated Cancer"],
[
["SIADH (hyponatremia)", "SCLC"],
["Cushing syndrome (ectopic ACTH)", "SCLC"],
["Lambert-Eaton syndrome (proximal muscle weakness; VGCC antibodies)", "SCLC"],
["Hypercalcemia (PTHrP)", "Squamous cell carcinoma"],
["Hypertrophic osteoarthropathy (clubbing + periosteal new bone)", "Adenocarcinoma"],
["Superior vena cava (SVC) syndrome", "SCLC, Squamous cell"],
["Pancoast tumor (Horner + brachial plexopathy C8-T2)", "Squamous cell (apical)"],
],
[10*cm, 7*cm]
)
story += [para_table, sp(4)]
story += [
highlight_box("<b>Lambert-Eaton vs. MG:</b> Lambert-Eaton — improves with REPEATED effort (post-tetanic potentiation); proximal weakness; VGCC antibodies | MG — worsens with repeated effort; ACHR antibodies"),
sp(8),
]
# ============================================================
# SECTION 8: INTERSTITIAL LUNG DISEASES
# ============================================================
story += [section_header("8", "INTERSTITIAL LUNG DISEASES (ILD)"), sp(6)]
story += [sub_header("Key ILDs — Summary Table"), sp(4)]
ild_table = colored_table(
["Disease", "Key Feature", "HRCT Pattern"],
[
["IPF", "Elderly male, smoker; UIP pattern; poor prognosis; NO steroids", "Honeycombing + traction bronchiectasis (basal/subpleural)"],
["Sarcoidosis", "Non-caseating granulomas; bilateral hilar adenopathy; lupus pernio; erythema nodosum", "BHL + upper lobe infiltrates/nodules"],
["Hypersensitivity Pneumonitis", "Exposure-related: farmer's lung (actinomycetes), bird fancier's lung", "Ground glass + nodules; upper/mid zones"],
["NSIP", "Connective tissue diseases; better prognosis than IPF", "Ground glass opacity (basal, bilateral, symmetric)"],
],
[3.5*cm, 6.5*cm, 7*cm]
)
story += [ild_table, sp(4)]
story += [sub_header("IPF Treatment"), sp(4)]
story += [
bullet("<b>Pirfenidone</b> (TGF-β inhibitor) and <b>Nintedanib</b> (tyrosine kinase inhibitor) — both reduce rate of FVC decline"),
bullet("Lung transplant for advanced disease"),
bullet("<b>Avoid steroids in IPF</b> — worsens outcomes"),
sp(4),
]
story += [sub_header("Sarcoidosis Staging"), sp(4)]
sarc_table = colored_table(
["Stage", "Description"],
[
["Stage I", "Bilateral hilar adenopathy (BHL) only"],
["Stage II", "BHL + pulmonary infiltrates"],
["Stage III", "Pulmonary infiltrates only (no BHL)"],
["Stage IV", "Pulmonary fibrosis"],
],
[4*cm, 13*cm]
)
story += [sarc_table, sp(4)]
story += [
bullet("Hypercalcemia in sarcoidosis: macrophages produce 1,25-(OH)₂ vitamin D3"),
bullet("Treatment: corticosteroids if symptomatic or organ-threatening; stages I–II may remit spontaneously"),
sp(8),
]
# ============================================================
# SECTION 9: RESPIRATORY FAILURE & ARDS
# ============================================================
story += [section_header("9", "RESPIRATORY FAILURE & ARDS"), sp(6)]
story += [sub_header("Type I vs. Type II Respiratory Failure"), sp(4)]
rf_table = colored_table(
["Feature", "Type I (Hypoxemic)", "Type II (Hypercapnic)"],
[
["PaO2", "<60 mmHg", "<60 mmHg"],
["PaCO2", "Normal or low", ">45 mmHg"],
["A-a gradient", "Increased", "Normal (initially)"],
["Causes", "Pneumonia, PE, pulmonary edema, ARDS", "COPD, neuromuscular disease, chest wall"],
["Mechanism", "V/Q mismatch, shunt, diffusion impairment", "Alveolar hypoventilation"],
],
[4*cm, 6.5*cm, 6.5*cm]
)
story += [rf_table, sp(4)]
story += [sub_header("ARDS — Berlin Definition 2012"), sp(4)]
story += [
highlight_box("<b>ARDS Criteria:</b> Within 1 week of clinical insult | Bilateral opacities on CXR (not fully explained by fluid/cardiogenic) | Not fully explained by heart failure | PaO₂/FiO₂: Mild 200–300, Moderate 100–200, Severe <100"),
sp(4),
]
story += [
bullet("<b>Lung-protective ventilation:</b> Tidal volume 6 mL/kg ideal body weight, plateau pressure <30 cmH₂O"),
bullet("<b>Prone positioning:</b> For moderate-severe ARDS (PaO₂/FiO₂ <150) — reduces mortality"),
bullet("<b>PEEP:</b> To prevent atelectrauma"),
bullet("<b>Neuromuscular blockade</b> in severe cases"),
bullet("<b>Dexamethasone</b> in COVID-ARDS (RECOVERY trial)"),
sp(8),
]
# ============================================================
# SECTION 10: QUICK-FIRE HIGH-YIELD FACTS
# ============================================================
story += [section_header("10", "QUICK-FIRE HIGH-YIELD FACTS & MNEMONICS"), sp(6)]
qf_table = colored_table(
["High-Yield Fact", "Answer"],
[
["MC cause of CAP", "S. pneumoniae"],
["Atypical pneumonia — young adults, 'walking pneumonia'", "Mycoplasma pneumoniae"],
["Currant jelly sputum", "Klebsiella pneumoniae"],
["Legionella clues", "AC exposure, hyponatremia, diarrhea, raised LFTs; Urinary antigen test"],
["Samter's Triad", "Asthma + Nasal Polyps + Aspirin sensitivity"],
["Reid index >0.5", "Chronic bronchitis (mucous gland/bronchial wall ratio)"],
["DLCO reduced in", "Emphysema, IPF, PE; Normal/raised in asthma"],
["DLCO increased in", "Polycythemia, pulmonary hemorrhage"],
["Pleural ADA >40 U/L", "TB pleuritis (high sensitivity)"],
["PTHrP hypercalcemia in lung", "Squamous cell carcinoma"],
["SIADH in lung cancer", "SCLC"],
["Lambert-Eaton key feature", "Improves with repeated effort; VGCC antibodies"],
["PFT in restrictive disease", "FEV1/FVC normal or >70%; TLC reduced"],
["PFT in obstructive disease", "FEV1/FVC <0.70; TLC normal or increased (emphysema)"],
["IPF drugs (2)", "Pirfenidone, Nintedanib"],
["Mesothelioma", "Asbestos exposure; pleural plaques; epithelial type most common"],
["Goodpasture syndrome", "Anti-GBM antibodies; pulmonary hemorrhage + glomerulonephritis"],
["MC genetic cause of COPD", "Alpha-1 antitrypsin deficiency (PiZZ) — panacinar emphysema, lower lobes"],
["McConnell sign (Echo)", "RV apical sparing — classic for PE"],
["Normal PaCO2 in acute asthma", "Danger sign — indicates tiring patient (should be low normally)"],
],
[9*cm, 8*cm]
)
story += [qf_table, sp(10)]
# Footer / Source
story += [
HRFlowable(width="100%", thickness=1, color=TEAL),
sp(4),
Paragraph(
"Sources: Harrison's Principles of Internal Medicine, 22nd Edition (2025, McGraw-Hill) | "
"Murray & Nadel's Textbook of Respiratory Medicine, 2-Volume Set (Elsevier) | "
"Goldman-Cecil Medicine International Edition",
source_style
),
sp(2),
Paragraph(
"Prepared for KUHS University & NEET PG Preparation — July 2026",
source_style
),
]
# ── Build PDF ────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
rightMargin=2*cm,
leftMargin=2*cm,
topMargin=2*cm,
bottomMargin=2*cm,
title="High-Yield Respiratory Medicine Notes",
author="Medical Library — Harrison's 22E",
subject="KUHS & NEET PG Respiratory System",
)
def add_page_number(canvas, doc):
canvas.saveState()
canvas.setFont("Helvetica", 8)
canvas.setFillColor(colors.grey)
canvas.drawRightString(A4[0] - 2*cm, 1.2*cm, f"Page {doc.page}")
canvas.drawString(2*cm, 1.2*cm, "High-Yield Respiratory Medicine | KUHS & NEET PG")
canvas.restoreState()
doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)
print("PDF generated successfully:", OUTPUT)