How to take history of COPD . Long case

Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Reading File
Reading File
Reading File
I now have comprehensive textbook content. Let me compile the full, structured long-case COPD history guide:

How to Take a History in COPD — Long Case

A complete COPD long case history is structured around the following domains. Cover each systematically before moving to examination.

1. Presenting Complaint

State the predominant symptom(s) — usually one or more of:
  • Breathlessness (dyspnoea)
  • Chronic cough
  • Sputum production
  • Wheeze
  • Chest tightness

2. History of Presenting Complaint (HPC)

A. Dyspnoea

The cardinal symptom. Explore in full:
  • Onset — Gradual over years is typical; acute onset suggests exacerbation
  • Duration — How long has it been present?
  • Progression — Slowly worsening over years (hallmark of COPD)
  • Exertional threshold — What activity provokes it? (climbing stairs, walking on flat, dressing, at rest?)
  • Orthopnoea/PND — Ask specifically; more typical of heart failure but can coexist
  • Quantify disability using the MRC Dyspnoea Scale:
GradeDescription
1Breathless only with strenuous exercise
2Short of breath when hurrying on the level or walking up a slight hill
3Walks slower than most people of same age due to breathlessness, or has to stop for breath when walking at own pace
4Stops for breath after walking ~100 m or after a few minutes
5Too breathless to leave the house, or breathless when dressing/undressing
Tip: Ask about the "shopping trolley sign" — less breathless when pushing a trolley/cart than walking freely (due to tripod positioning). This is very specific for COPD.

B. Cough

  • Onset and duration — Chronic productive cough for ≥3 months in ≥2 consecutive years = chronic bronchitis
  • Character — Productive vs. dry
  • Time pattern — Morning cough ("morning ritual"), worse in winter
  • Triggers — Cold air, smoke, exercise

C. Sputum

  • Volume — How much per day? (teaspoon, tablespoon, egg cup)
  • Colour — White/grey (stable), yellow/green (infection/exacerbation), rusty (pneumococcal infection), pink frothy (pulmonary oedema — important differential)
  • Haemoptysis — Always ask; if present, consider lung cancer, bronchiectasis, TB. Clubbing is not a feature of COPD — its presence should prompt investigation for malignancy or pulmonary fibrosis

D. Wheeze

  • Persistent or episodic?
  • Response to bronchodilators (helps differentiate from asthma)

E. Chest Pain/Tightness

  • Pleuritic pain? (pneumothorax, pleurisy)
  • Central tightness (cor pulmonale, ischaemic heart disease)

3. Exacerbation History

Critical in COPD long cases:
  • Frequency — How many exacerbations per year?
  • Triggers — URTI, environmental, seasonal
  • Symptoms of exacerbation — Increased dyspnoea, increased cough, change in sputum quantity or purulence
  • Severity — Treated at home? GP visit? A&E? ICU?
  • Hospitalisations — Number, dates, whether intubated or on NIV (BiPAP)
  • Steroid/antibiotic courses — Home supply? "Rescue pack"?

4. Risk Factor History (Aetiology)

Smoking History — Most Important

  • Type — Cigarettes, cigars, pipe, shisha, e-cigarettes
  • Pack-year history = (cigarettes per day ÷ 20) × years smoked
    e.g., 20 cigarettes/day for 30 years = 30 pack-years
  • Current smoker or ex-smoker — If ex, when did they stop?
  • Passive/secondhand smoke — Childhood exposure, occupational

Occupational Exposure

Always ask occupation(s) systematically:
  • Dust — Coal miners, gold miners, cotton textile workers
  • Fumes/chemicals — Welding, painting, agriculture
  • Duration of exposure — Years, intensity
  • Use of protective equipment (PPE)

Indoor/Biomass Fuel Exposure

  • Burning of wood, dung, crop residue for cooking/heating (common in low-income settings)
  • Poorly ventilated kitchens

Childhood History

  • Recurrent lower respiratory tract infections in childhood
  • Premature birth (poor lung development = reduced lung reserve)
  • Severe asthma

Environmental/Outdoor Pollution

  • Urban vs. rural, industrial area

Alpha-1 Antitrypsin (A1AT) Deficiency

  • Ask about family history of emphysema, especially in non-smokers
  • Young age at onset (<45 years), lower lobe predominant emphysema
  • Associated liver disease (cirrhosis)

5. Past Medical History

Ask specifically about:
  • Asthma or childhood wheeze (overlap syndrome ACOS)
  • Previous tuberculosis — Can cause airflow obstruction
  • Recurrent chest infections / bronchiectasis
  • Heart disease — Ischaemic heart disease, heart failure (key comorbidity and differential for dyspnoea)
  • Pulmonary hypertension / cor pulmonale — Ankle swelling, raised JVP
  • Osteoporosis — Common in COPD, worsened by steroids
  • Diabetes, metabolic syndrome
  • Lung cancer — Strong shared risk factor with smoking
  • Anxiety/depression — Very common comorbidity; significantly impairs quality of life

6. Drug History

  • Current inhalers — SABA (salbutamol), LABA (salmeterol, formoterol), LAMA (tiotropium, umeclidinium), ICS (fluticasone, budesonide), combination inhalers (LABA/LAMA, LABA/ICS, triple therapy)
  • Inhaler technique and compliance — Ask the patient to demonstrate
  • Oral medications — Theophylline, roflumilast, azithromycin prophylaxis
  • Long-term oral steroids — Doses, duration, side effects
  • Home nebulisers
  • Home oxygen / NIV
  • Medications that can worsen respiratory disease — Beta-blockers (use cardioselective if needed), NSAIDs (avoid), ACE inhibitors (cause cough — may be confused with COPD cough)
  • Allergy history

7. Oxygen and NIV History

  • Long-term oxygen therapy (LTOT) — Prescribed? Hours per day (ideally >15 hours)? Portable vs. concentrator?
  • Non-invasive ventilation (BiPAP/CPAP) — For hypercapnic respiratory failure
  • Ambulatory oxygen

8. Functional History and Quality of Life

Use the COPD Assessment Test (CAT) to quantify impact (score 0–40):
DomainAsked
Cough frequencyNever → all the time
Sputum/phlegmNone → chest completely full
Chest tightnessNone → very tight
Breathlessness on exertionNot breathless → very breathless on one flight of stairs
Activity limitation at homeNot limited → very limited
Confidence leaving homeConfident → not confident at all
Sleep qualitySleeps soundly → does not sleep due to lung condition
Energy levelsLots of energy → no energy
Also ask:
  • Activities of daily living (ADLs) — Can they shower, dress, cook independently?
  • Exercise tolerance — What is the patient's current maximum walking distance?
  • Mobility aids — Wheelchair, rollator?
  • Social participation — Work, hobbies, going out

9. Social History

  • Smoking status (if not already asked)
  • Alcohol — Can affect response to infection and drug compliance
  • Occupation — Current or retired; occupational exposure (see above)
  • Housing — Stairs, heating, dampness/mould, rural vs. urban
  • Social support — Lives alone? Who are the carers?
  • Benefits/income — Disease impact on employment
  • Travel — Air travel (requires oxygen if PaO₂ borderline)

10. Family History

  • COPD or emphysema in relatives — Especially early-onset or non-smokers → suspect A1AT deficiency
  • Asthma — First-degree relatives
  • Lung cancer
  • Maternal tobacco use during pregnancy — Increases childhood risk

11. Systems Review (Relevant Positives/Negatives)

SystemAsk About
RespiratoryHaemoptysis, pleuritic pain, snoring/OSA (overlap syndrome)
CardiovascularAnkle oedema (cor pulmonale), palpitations (AF common in COPD), chest pain
NeurologicalHeadaches on waking (CO₂ retention), confusion
MusculoskeletalBack pain (vertebral fractures from osteoporosis/steroids), muscle weakness
NutritionalWeight loss (sarcopenia in emphysema), anorexia
PsychiatricDepression, anxiety (very common; affects exacerbation risk)
ENTChronic sinusitis, nasal polyps (asthma overlap)

12. Key Differential Diagnoses to Screen For in History

While taking the history, keep these differentials in mind and ask questions to exclude them:
ConditionDistinguishing Features in History
AsthmaOnset in childhood/young adult, episodic wheeze, atopy, family history, fully reversible
Heart failureOrthopnoea, PND, pink frothy sputum, cardiac risk factors
BronchiectasisLarge volumes of mucopurulent sputum daily, recurrent infections, childhood infections
TBNight sweats, weight loss, contact history, foreign travel
Lung cancerHaemoptysis, weight loss, hoarseness, smoking history
Pulmonary fibrosisDry cough, clubbing, fine crackles, autoimmune disease

13. Closing the History — Summarise the GOLD Classification Context

After the history, you should be able to stage the patient's COPD using the GOLD ABE Framework (2023 update):
  • Symptoms: CAT score or MRC grade
  • Exacerbation history: ≥2 moderate or ≥1 hospitalisation = high-risk group E
  • Spirometry: Confirm with FEV₁/FVC <0.7 post-bronchodilator; then GOLD 1–4 by % predicted FEV₁
GOLD GradeFEV₁ % Predicted
1 (Mild)≥80%
2 (Moderate)50–79%
3 (Severe)30–49%
4 (Very Severe)<30%

Quick Summary Checklist for COPD Long Case History

  • Presenting symptoms (dyspnoea, cough, sputum, wheeze) — onset, severity, progression
  • MRC dyspnoea grade
  • CAT score questions
  • Exacerbation history (frequency, hospitalisations, NIV/intubation)
  • Smoking — pack-year history, current vs. ex-smoker
  • Occupational, indoor, environmental exposures
  • Childhood history (infections, premature birth)
  • Family history (A1AT, asthma, lung disease)
  • Past medical history (especially cardiac disease, asthma, TB)
  • Drug history (inhalers with compliance, oxygen, steroids)
  • Functional and QoL impact
  • Social history (living situation, support, occupation)
  • Systems review (cor pulmonale symptoms, depression, weight loss)
  • Differentials excluded by history

Sources: Goldman-Cecil Medicine, p. 2902–2921 | The Washington Manual of Medical Therapeutics, pp. 310–313 | Harrison's Principles of Internal Medicine 22E | Fishman's Pulmonary Diseases and Disorders

Create a quick reference PDF for COPD history-taking

Reading File
Running Command

ls -la /home/daytona/workspace/ 2>/dev/null && mkdir -p /home/daytona/workspace/copd-pdf

Writing File

~/copd-pdf/generate_copd_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import PageBreak

OUTPUT = "/home/daytona/workspace/copd-pdf/COPD_History_Quick_Reference.pdf"

# ── Colour palette ──────────────────────────────────────────────────────────
NAVY       = colors.HexColor("#1A3A5C")
TEAL       = colors.HexColor("#1B7A8E")
LIGHTBLUE  = colors.HexColor("#E8F4F8")
MIDBLUE    = colors.HexColor("#BEE0EA")
ORANGE     = colors.HexColor("#E67E22")
LIGHTORANGE= colors.HexColor("#FDF2E9")
RED        = colors.HexColor("#C0392B")
GREEN      = colors.HexColor("#1E8449")
LIGHTGREEN = colors.HexColor("#E9F7EF")
GREY       = colors.HexColor("#F2F3F4")
DARKGREY   = colors.HexColor("#566573")
WHITE      = colors.white
BLACK      = colors.HexColor("#1C2833")

# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_style = S("Title",
    fontName="Helvetica-Bold", fontSize=20, textColor=WHITE,
    alignment=TA_CENTER, spaceAfter=4, leading=24)

subtitle_style = S("Subtitle",
    fontName="Helvetica", fontSize=10, textColor=MIDBLUE,
    alignment=TA_CENTER, spaceAfter=2)

section_header = S("SecHdr",
    fontName="Helvetica-Bold", fontSize=9.5, textColor=WHITE,
    alignment=TA_LEFT, leftIndent=4, leading=13)

body = S("Body",
    fontName="Helvetica", fontSize=8.5, textColor=BLACK,
    leading=12, spaceAfter=2)

body_bold = S("BodyBold",
    fontName="Helvetica-Bold", fontSize=8.5, textColor=BLACK,
    leading=12, spaceAfter=2)

bullet = S("Bullet",
    fontName="Helvetica", fontSize=8.5, textColor=BLACK,
    leading=12, leftIndent=10, firstLineIndent=-8, spaceAfter=1.5)

bullet_bold = S("BulletBold",
    fontName="Helvetica-Bold", fontSize=8.5, textColor=NAVY,
    leading=12, leftIndent=10, firstLineIndent=-8, spaceAfter=1.5)

small = S("Small",
    fontName="Helvetica", fontSize=7.5, textColor=DARKGREY,
    leading=10, spaceAfter=1)

small_italic = S("SmallItalic",
    fontName="Helvetica-Oblique", fontSize=7.5, textColor=DARKGREY,
    leading=10, spaceAfter=1)

table_hdr = S("TblHdr",
    fontName="Helvetica-Bold", fontSize=8, textColor=WHITE,
    alignment=TA_CENTER, leading=11)

table_cell = S("TblCell",
    fontName="Helvetica", fontSize=8, textColor=BLACK,
    leading=11)

table_cell_bold = S("TblCellBold",
    fontName="Helvetica-Bold", fontSize=8, textColor=BLACK,
    leading=11)

warn = S("Warn",
    fontName="Helvetica-BoldOblique", fontSize=8.5, textColor=RED,
    leading=12, leftIndent=8, spaceAfter=2)

tip = S("Tip",
    fontName="Helvetica-Oblique", fontSize=8, textColor=GREEN,
    leading=11, leftIndent=8, spaceAfter=2)

# ── Helper flowables ─────────────────────────────────────────────────────────

def section_box(title, bg=NAVY):
    """Coloured section header bar."""
    data = [[Paragraph(f"▌  {title}", section_header)]]
    t = Table(data, colWidths=[178*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
        ("RIGHTPADDING",  (0,0), (-1,-1), 4),
        ("ROWBACKGROUNDS",(0,0), (-1,-1), [bg]),
    ]))
    return t

def mini_box(title, bg=TEAL):
    """Smaller sub-header."""
    data = [[Paragraph(f"  {title}", S("mhdr",
        fontName="Helvetica-Bold", fontSize=8.5, textColor=WHITE,
        alignment=TA_LEFT, leading=12))]]
    t = Table(data, colWidths=[178*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 4),
    ]))
    return t

def sp(h=3):
    return Spacer(1, h*mm)

def hr():
    return HRFlowable(width="100%", thickness=0.5, color=MIDBLUE, spaceAfter=2)

def tbl(data, col_widths, style_extras=None, bg_header=NAVY):
    ts = [
        ("BACKGROUND",    (0,0), (-1,0), bg_header),
        ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
        ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",      (0,0), (-1,-1), 8),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, GREY]),
        ("GRID",          (0,0), (-1,-1), 0.4, colors.HexColor("#D5D8DC")),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("RIGHTPADDING",  (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
        ("ALIGN",         (0,0), (-1,0), "CENTER"),
    ]
    if style_extras:
        ts.extend(style_extras)
    t = Table(data, colWidths=col_widths)
    t.setStyle(TableStyle(ts))
    return t

# ── Build content ─────────────────────────────────────────────────────────────

def build():
    doc = SimpleDocTemplate(
        OUTPUT,
        pagesize=A4,
        leftMargin=16*mm, rightMargin=16*mm,
        topMargin=14*mm, bottomMargin=14*mm,
        title="COPD History Quick Reference",
        author="Orris Medical"
    )

    story = []

    # ── TITLE BANNER ──────────────────────────────────────────────────────────
    banner_data = [[
        Paragraph("COPD HISTORY TAKING", title_style),
        Paragraph("Quick Reference — Long Case", subtitle_style),
    ]]
    banner = Table([[
        Paragraph("COPD HISTORY TAKING", title_style),
    ],[
        Paragraph("Quick Reference — Long Case", subtitle_style),
    ]], colWidths=[178*mm])
    banner.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), NAVY),
        ("TOPPADDING",    (0,0), (-1,-1), 8),
        ("BOTTOMPADDING", (0,0), (-1,-1), 8),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
        ("RIGHTPADDING",  (0,0), (-1,-1), 6),
    ]))
    story.append(banner)
    story.append(sp(3))

    # ── PRESENTING COMPLAINT + HPC ────────────────────────────────────────────
    story.append(section_box("1. PRESENTING COMPLAINT & HISTORY OF PRESENTING COMPLAINT"))
    story.append(sp(1))

    # Two-column layout: Dyspnoea + Cough/Sputum
    left = [
        Paragraph("<b>DYSPNOEA</b> (Cardinal Symptom)", body_bold),
        Paragraph("• Onset — gradual over years (typical) vs. acute (exacerbation)", bullet),
        Paragraph("• Duration &amp; progression", bullet),
        Paragraph("• Exertional threshold — stairs? flat ground? dressing?", bullet),
        Paragraph("• Orthopnoea / PND (suggests HF overlap)", bullet),
        Paragraph("• 'Shopping trolley sign' — less breathless pushing a cart<br/>"
                  "  <i>(tripod position, specific for COPD)</i>", bullet),
        sp(2),
        Paragraph("<b>MRC Dyspnoea Scale</b>", body_bold),
    ]
    mrc_data = [
        [Paragraph("Grade", table_hdr), Paragraph("Description", table_hdr)],
        [Paragraph("1", table_cell), Paragraph("Breathless only with strenuous exercise", table_cell)],
        [Paragraph("2", table_cell), Paragraph("Short of breath hurrying on flat or slight hill", table_cell)],
        [Paragraph("3", table_cell), Paragraph("Walks slower than peers due to breathlessness", table_cell)],
        [Paragraph("4", table_cell), Paragraph("Stops for breath after ~100 m or a few minutes", table_cell)],
        [Paragraph("5", table_cell), Paragraph("Too breathless to leave house / breathless dressing", table_cell)],
    ]
    left.append(tbl(mrc_data, [12*mm, 63*mm]))

    right = [
        Paragraph("<b>COUGH</b>", body_bold),
        Paragraph("• Onset &amp; duration — chronic ≥3 months/yr for ≥2 yrs = chronic bronchitis", bullet),
        Paragraph("• Character — productive vs. dry", bullet),
        Paragraph("• Morning cough ('morning ritual')", bullet),
        Paragraph("• Worse in winter / cold air", bullet),
        sp(2),
        Paragraph("<b>SPUTUM</b>", body_bold),
        Paragraph("• Volume per day (teaspoon / tablespoon / egg cup)", bullet),
        Paragraph("• Colour: white/grey = stable; yellow/green = infection; rust = pneumococcal; pink frothy = pulm. oedema", bullet),
        sp(2),
        Paragraph("<b>HAEMOPTYSIS</b>", body_bold),
        Paragraph(
            "⚠ Clubbing is NOT a feature of COPD. "
            "If present → investigate for lung cancer or pulmonary fibrosis.", warn),
        sp(2),
        Paragraph("<b>WHEEZE &amp; CHEST TIGHTNESS</b>", body_bold),
        Paragraph("• Wheeze — persistent or episodic? Response to bronchodilators?", bullet),
        Paragraph("• Chest tightness — pleuritic? Central? (cor pulmonale, IHD)", bullet),
    ]

    two_col = Table([[left, right]], colWidths=[89*mm, 89*mm])
    two_col.setStyle(TableStyle([
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",   (0,0), (-1,-1), 3),
        ("RIGHTPADDING",  (0,0), (-1,-1), 3),
        ("TOPPADDING",    (0,0), (-1,-1), 2),
        ("BOTTOMPADDING", (0,0), (-1,-1), 2),
    ]))
    story.append(two_col)
    story.append(sp(2))

    # ── EXACERBATION HISTORY ──────────────────────────────────────────────────
    story.append(section_box("2. EXACERBATION HISTORY", bg=TEAL))
    story.append(sp(1))
    ex_data = [
        [Paragraph("Ask About", table_hdr), Paragraph("Details", table_hdr)],
        [Paragraph("Frequency", table_cell_bold), Paragraph("How many per year?", table_cell)],
        [Paragraph("Triggers", table_cell_bold), Paragraph("URTI, environmental, seasonal", table_cell)],
        [Paragraph("Symptoms", table_cell_bold), Paragraph("↑ dyspnoea, ↑ cough, change in sputum quantity or purulence", table_cell)],
        [Paragraph("Severity", table_cell_bold), Paragraph("Treated at home? GP visit? A&amp;E? ICU admission?", table_cell)],
        [Paragraph("Hospitalisations", table_cell_bold), Paragraph("Number, dates, intubated or on NIV (BiPAP)?", table_cell)],
        [Paragraph("Rescue pack", table_cell_bold), Paragraph("Home supply of steroids/antibiotics?", table_cell)],
    ]
    story.append(tbl(ex_data, [38*mm, 140*mm], bg_header=TEAL))
    story.append(sp(2))

    # ── RISK FACTORS ──────────────────────────────────────────────────────────
    story.append(section_box("3. RISK FACTOR HISTORY (AETIOLOGY)", bg=ORANGE))
    story.append(sp(1))

    rf_left = [
        Paragraph("<b>SMOKING — Most Important</b>", body_bold),
        Paragraph("• Type: cigarettes, pipe, cigars, shisha, e-cigarettes", bullet),
        Paragraph("• <b>Pack-year = (cigs/day ÷ 20) × years smoked</b>", bullet_bold),
        Paragraph("  e.g. 20/day × 30 years = 30 pack-years", small_italic),
        Paragraph("• Current smoker or ex-smoker (when stopped?)", bullet),
        Paragraph("• Passive/secondhand smoke exposure", bullet),
        sp(2),
        Paragraph("<b>OCCUPATIONAL EXPOSURE</b>", body_bold),
        Paragraph("• Coal mining, gold mining, cotton textile dust", bullet),
        Paragraph("• Welding fumes, solvents, agricultural dust", bullet),
        Paragraph("• Duration (years), intensity, use of PPE", bullet),
        Paragraph("• Ask about ALL past occupations systematically", bullet),
    ]

    rf_right = [
        Paragraph("<b>INDOOR / BIOMASS FUEL</b>", body_bold),
        Paragraph("• Wood, dung, crop residue burning for cooking/heating", bullet),
        Paragraph("• Poorly ventilated kitchens (common in LMICs)", bullet),
        sp(2),
        Paragraph("<b>CHILDHOOD HISTORY</b>", body_bold),
        Paragraph("• Recurrent lower RTIs in childhood", bullet),
        Paragraph("• Premature birth (poor lung development)", bullet),
        Paragraph("• Severe asthma history", bullet),
        sp(2),
        Paragraph("<b>ALPHA-1 ANTITRYPSIN (A1AT) DEFICIENCY</b>", body_bold),
        Paragraph("• Family history of emphysema in non-smokers", bullet),
        Paragraph("• Onset &lt;45 years, lower-lobe predominant emphysema", bullet),
        Paragraph("• Associated liver disease (cirrhosis)", bullet),
        Paragraph("• All COPD patients should be screened at least once", bullet),
    ]

    rf_two = Table([[rf_left, rf_right]], colWidths=[89*mm, 89*mm])
    rf_two.setStyle(TableStyle([
        ("VALIGN",  (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",  (0,0), (-1,-1), 3),
        ("RIGHTPADDING", (0,0), (-1,-1), 3),
        ("TOPPADDING",   (0,0), (-1,-1), 2),
        ("BOTTOMPADDING",(0,0), (-1,-1), 2),
    ]))
    story.append(rf_two)
    story.append(sp(2))

    # ── PAST MEDICAL HISTORY ──────────────────────────────────────────────────
    story.append(section_box("4. PAST MEDICAL HISTORY"))
    story.append(sp(1))

    pmh_data = [
        [Paragraph("Condition", table_hdr), Paragraph("Why It Matters", table_hdr)],
        [Paragraph("Asthma / childhood wheeze", table_cell_bold), Paragraph("ACOS (Asthma-COPD Overlap Syndrome)", table_cell)],
        [Paragraph("Tuberculosis", table_cell_bold), Paragraph("Can cause airflow obstruction", table_cell)],
        [Paragraph("Recurrent chest infections / bronchiectasis", table_cell_bold), Paragraph("Differential; concurrent condition", table_cell)],
        [Paragraph("Heart failure / IHD", table_cell_bold), Paragraph("Key comorbidity and differential for dyspnoea", table_cell)],
        [Paragraph("Pulmonary hypertension / cor pulmonale", table_cell_bold), Paragraph("Ankle swelling, raised JVP, RVF signs", table_cell)],
        [Paragraph("Osteoporosis", table_cell_bold), Paragraph("Common in COPD; worsened by steroids", table_cell)],
        [Paragraph("Lung cancer", table_cell_bold), Paragraph("Shared smoking risk factor; haemoptysis", table_cell)],
        [Paragraph("Anxiety / depression", table_cell_bold), Paragraph("Very common; impairs QoL, ↑ exacerbation risk", table_cell)],
    ]
    story.append(tbl(pmh_data, [72*mm, 106*mm]))
    story.append(sp(2))

    # ── DRUG HISTORY ──────────────────────────────────────────────────────────
    story.append(section_box("5. DRUG HISTORY", bg=TEAL))
    story.append(sp(1))

    dh_left = [
        Paragraph("<b>INHALERS (ask patient to demonstrate technique)</b>", body_bold),
        Paragraph("• SABA — salbutamol, terbutaline", bullet),
        Paragraph("• LABA — salmeterol, formoterol, indacaterol", bullet),
        Paragraph("• LAMA — tiotropium, umeclidinium, glycopyrronium", bullet),
        Paragraph("• ICS — fluticasone, budesonide, beclomethasone", bullet),
        Paragraph("• Combinations: LABA/LAMA, LABA/ICS, Triple therapy", bullet),
        Paragraph("• Compliance and frequency of use", bullet),
        sp(2),
        Paragraph("<b>OTHER RESPIRATORY DRUGS</b>", body_bold),
        Paragraph("• Theophylline, roflumilast, azithromycin prophylaxis", bullet),
        Paragraph("• Oral steroids — dose, duration, side effects", bullet),
        Paragraph("• Home nebulisers", bullet),
    ]

    dh_right = [
        Paragraph("<b>OXYGEN &amp; NIV</b>", body_bold),
        Paragraph("• LTOT: prescribed? Hours/day (goal &gt;15h)?", bullet),
        Paragraph("• Portable O₂ vs. concentrator", bullet),
        Paragraph("• NIV (BiPAP) — for hypercapnic respiratory failure", bullet),
        Paragraph("• Ambulatory oxygen", bullet),
        sp(2),
        Paragraph("<b>DRUGS THAT WORSEN RESPIRATORY DISEASE</b>", body_bold),
        Paragraph("⚠ Beta-blockers — use cardioselective if required", warn),
        Paragraph("⚠ NSAIDs — avoid if possible", warn),
        Paragraph("⚠ ACE inhibitors — cause cough (may mimic COPD cough)", warn),
        sp(2),
        Paragraph("<b>ALLERGIES</b>", body_bold),
        Paragraph("• Drug name + type of reaction", bullet),
    ]

    dh_two = Table([[dh_left, dh_right]], colWidths=[89*mm, 89*mm])
    dh_two.setStyle(TableStyle([
        ("VALIGN",  (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",  (0,0), (-1,-1), 3),
        ("RIGHTPADDING", (0,0), (-1,-1), 3),
    ]))
    story.append(dh_two)
    story.append(sp(2))

    # ── SOCIAL HISTORY + FUNCTIONAL ───────────────────────────────────────────
    story.append(section_box("6. SOCIAL &amp; FUNCTIONAL HISTORY", bg=colors.HexColor("#6C3483")))
    story.append(sp(1))

    soc_left = [
        Paragraph("<b>SOCIAL HISTORY</b>", body_bold),
        Paragraph("• Smoking (if not already asked)", bullet),
        Paragraph("• Alcohol intake", bullet),
        Paragraph("• Current / past occupation (exposure history)", bullet),
        Paragraph("• Housing — stairs, heating, dampness/mould", bullet),
        Paragraph("• Social support — lives alone? Who are the carers?", bullet),
        Paragraph("• Employment impact / disability benefits", bullet),
        Paragraph("• Air travel — needs oxygen assessment if PaO₂ borderline", bullet),
    ]

    soc_right = [
        Paragraph("<b>FUNCTIONAL IMPACT (QoL)</b>", body_bold),
        Paragraph("• ADLs — can patient shower, dress, cook independently?", bullet),
        Paragraph("• Maximum walking distance", bullet),
        Paragraph("• Mobility aids (rollator, wheelchair)", bullet),
        Paragraph("• Hobbies, work, social participation", bullet),
        sp(2),
        Paragraph("<b>CAT SCORE DOMAINS (0–40)</b>", body_bold),
        Paragraph("Cough | Sputum | Chest tightness | Breathlessness | Activity at home | Confidence leaving home | Sleep | Energy", small),
        Paragraph("Score ≥10 = significant impact on QoL", small_italic),
    ]

    soc_two = Table([[soc_left, soc_right]], colWidths=[89*mm, 89*mm])
    soc_two.setStyle(TableStyle([
        ("VALIGN",  (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",  (0,0), (-1,-1), 3),
        ("RIGHTPADDING", (0,0), (-1,-1), 3),
    ]))
    story.append(soc_two)
    story.append(sp(2))

    # ── FAMILY HISTORY + SYSTEMS ──────────────────────────────────────────────
    fam_sys_left = [
        section_box("7. FAMILY HISTORY", bg=colors.HexColor("#1E8449")),
        sp(1),
        Paragraph("• COPD or emphysema — especially early-onset / non-smokers", bullet),
        Paragraph("  → Suspect <b>A1AT deficiency</b>", bullet),
        Paragraph("• Asthma (first-degree relatives)", bullet),
        Paragraph("• Lung cancer", bullet),
        Paragraph("• Maternal tobacco use during pregnancy", bullet),
    ]

    fam_sys_right = [
        section_box("8. SYSTEMS REVIEW", bg=colors.HexColor("#1E8449")),
        sp(1),
        Paragraph("• <b>CVS:</b> Ankle oedema (cor pulmonale), palpitations (AF), chest pain", bullet),
        Paragraph("• <b>Neuro:</b> Morning headaches, confusion (CO₂ retention)", bullet),
        Paragraph("• <b>MSK:</b> Back pain (vertebral fractures / steroids), muscle weakness", bullet),
        Paragraph("• <b>Nutrition:</b> Weight loss, anorexia (sarcopenia in emphysema)", bullet),
        Paragraph("• <b>Psych:</b> Depression, anxiety (very common in COPD)", bullet),
        Paragraph("• <b>ENT:</b> Chronic sinusitis, nasal polyps (asthma overlap)", bullet),
        Paragraph("• <b>Sleep:</b> Snoring / OSA (obesity-hypoventilation overlap)", bullet),
    ]

    fam_sys = Table([[fam_sys_left, fam_sys_right]], colWidths=[89*mm, 89*mm])
    fam_sys.setStyle(TableStyle([
        ("VALIGN",  (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",  (0,0), (-1,-1), 0),
        ("RIGHTPADDING", (0,0), (-1,-1), 3),
        ("TOPPADDING",   (0,0), (-1,-1), 0),
        ("BOTTOMPADDING",(0,0), (-1,-1), 0),
    ]))
    story.append(fam_sys)
    story.append(sp(3))

    # ── DIFFERENTIALS ─────────────────────────────────────────────────────────
    story.append(section_box("9. KEY DIFFERENTIALS TO EXCLUDE IN HISTORY", bg=RED))
    story.append(sp(1))
    diff_data = [
        [Paragraph("Condition", table_hdr), Paragraph("Distinguishing History Features", table_hdr)],
        [Paragraph("Asthma", table_cell_bold), Paragraph("Young onset, episodic wheeze, atopy, family history, fully reversible, responds well to ICS", table_cell)],
        [Paragraph("Heart Failure", table_cell_bold), Paragraph("Orthopnoea, PND, pink frothy sputum, cardiac risk factors, bilateral ankle oedema", table_cell)],
        [Paragraph("Bronchiectasis", table_cell_bold), Paragraph("Large volumes of mucopurulent sputum daily, recurrent infections, childhood lung disease", table_cell)],
        [Paragraph("Tuberculosis", table_cell_bold), Paragraph("Night sweats, weight loss, haemoptysis, contact history, foreign travel/endemic area", table_cell)],
        [Paragraph("Lung Cancer", table_cell_bold), Paragraph("Haemoptysis, significant weight loss, hoarseness, new finger clubbing, heavy smoker", table_cell)],
        [Paragraph("Pulmonary Fibrosis", table_cell_bold), Paragraph("Dry cough, clubbing, fine velcro crackles, autoimmune disease, occupational exposure (birds)", table_cell)],
    ]
    story.append(tbl(diff_data, [38*mm, 140*mm], bg_header=RED))
    story.append(sp(3))

    # ── GOLD STAGING REMINDER ─────────────────────────────────────────────────
    story.append(section_box("10. GOLD STAGING REMINDER (Confirm with Spirometry)", bg=ORANGE))
    story.append(sp(1))

    gold_left = [
        Paragraph("<b>GOLD SPIROMETRIC GRADES</b>", body_bold),
        Paragraph("(Post-bronchodilator FEV₁/FVC &lt;0.7)", small),
        sp(1),
    ]
    gold_grade_data = [
        [Paragraph("Grade", table_hdr), Paragraph("Severity", table_hdr), Paragraph("FEV₁ % Predicted", table_hdr)],
        [Paragraph("1", table_cell), Paragraph("Mild", table_cell), Paragraph("≥ 80%", table_cell)],
        [Paragraph("2", table_cell), Paragraph("Moderate", table_cell), Paragraph("50–79%", table_cell)],
        [Paragraph("3", table_cell), Paragraph("Severe", table_cell), Paragraph("30–49%", table_cell)],
        [Paragraph("4", table_cell), Paragraph("Very Severe", table_cell), Paragraph("< 30%", table_cell)],
    ]
    gold_left.append(tbl(gold_grade_data, [15*mm, 30*mm, 40*mm], bg_header=ORANGE))

    gold_right = [
        Paragraph("<b>GOLD ABE GROUPS (2023)</b>", body_bold),
        Paragraph("(Symptoms + Exacerbation Risk)", small),
        sp(1),
    ]
    gold_grp_data = [
        [Paragraph("Group", table_hdr), Paragraph("Criteria", table_hdr)],
        [Paragraph("A", table_cell), Paragraph("0–1 moderate exacerbations, no hospitalisation; low symptoms (CAT &lt;10)", table_cell)],
        [Paragraph("B", table_cell), Paragraph("0–1 moderate exacerbations, no hospitalisation; high symptoms (CAT ≥10)", table_cell)],
        [Paragraph("E", table_cell), Paragraph("≥2 moderate exacerbations OR ≥1 hospitalisation (regardless of symptoms)", table_cell)],
    ]
    gold_right.append(tbl(gold_grp_data, [12*mm, 75*mm], bg_header=ORANGE))

    gold_two = Table([[gold_left, gold_right]], colWidths=[89*mm, 89*mm])
    gold_two.setStyle(TableStyle([
        ("VALIGN",  (0,0), (-1,-1), "TOP"),
        ("LEFTPADDING",  (0,0), (-1,-1), 3),
        ("RIGHTPADDING", (0,0), (-1,-1), 3),
    ]))
    story.append(gold_two)
    story.append(sp(3))

    # ── CHECKLIST ─────────────────────────────────────────────────────────────
    story.append(section_box("QUICK CHECKLIST", bg=colors.HexColor("#2C3E50")))
    story.append(sp(1))

    checks = [
        ("Presenting symptoms", "Dyspnoea, cough, sputum, wheeze — onset, severity, progression"),
        ("MRC Grade", "Quantify exertional breathlessness (1–5)"),
        ("Exacerbation history", "Frequency, hospitalisations, NIV, rescue packs"),
        ("Smoking", "Pack-year history, current vs. ex-smoker"),
        ("Occupational / indoor / environmental exposure", "All jobs, biomass fuels, PPE"),
        ("Childhood history", "Recurrent RTIs, premature birth"),
        ("Family history", "A1AT, asthma, lung disease, maternal smoking"),
        ("Past medical history", "Cardiac disease, asthma, TB, depression"),
        ("Drug history", "Inhalers with technique, oxygen, steroids, harmful drugs"),
        ("Functional impact / QoL", "ADLs, walking distance, CAT score"),
        ("Social history", "Housing, support, employment, travel"),
        ("Systems review", "Cor pulmonale, CO₂ retention, weight loss, mood"),
        ("Differentials excluded", "Asthma, HF, bronchiectasis, TB, lung cancer, PF"),
    ]

    check_data = [[
        Paragraph("✓", S("chk", fontName="Helvetica-Bold", fontSize=9,
                         textColor=GREEN, alignment=TA_CENTER, leading=11)),
        Paragraph(f"<b>{c[0]}</b>", table_cell_bold),
        Paragraph(c[1], table_cell),
    ] for c in checks]
    check_data.insert(0, [
        Paragraph("", table_hdr),
        Paragraph("Domain", table_hdr),
        Paragraph("Key Points", table_hdr),
    ])
    chk_tbl = Table(check_data, colWidths=[7*mm, 55*mm, 116*mm])
    chk_tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), colors.HexColor("#2C3E50")),
        ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
        ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",      (0,0), (-1,-1), 8),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [LIGHTGREEN, WHITE]),
        ("GRID",          (0,0), (-1,-1), 0.4, colors.HexColor("#D5D8DC")),
        ("TOPPADDING",    (0,0), (-1,-1), 3),
        ("BOTTOMPADDING", (0,0), (-1,-1), 3),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
        ("ALIGN",         (0,0), (-1,-1), "LEFT"),
    ]))
    story.append(chk_tbl)
    story.append(sp(3))

    # ── FOOTER ────────────────────────────────────────────────────────────────
    footer_data = [[
        Paragraph(
            "<i>Sources: Goldman-Cecil Medicine | Washington Manual of Medical Therapeutics | "
            "Harrison's Principles of Internal Medicine 22E | Fishman's Pulmonary Diseases &amp; Disorders | "
            "GOLD 2023 Guidelines</i>",
            S("ftr", fontName="Helvetica-Oblique", fontSize=7, textColor=DARKGREY,
              alignment=TA_CENTER, leading=10)
        )
    ]]
    footer = Table(footer_data, colWidths=[178*mm])
    footer.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,-1), GREY),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 6),
    ]))
    story.append(footer)

    doc.build(story)
    print(f"PDF created: {OUTPUT}")

build()
Running Command

cd /home/daytona/workspace/copd-pdf && python generate_copd_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/copd-pdf/COPD_History_Quick_Reference.pdf

Your PDF is ready:

COPD History Quick Reference

PDF Document · PDF

The single-page A4 quick reference includes:
SectionContents
1. HPCDyspnoea (MRC scale table), cough, sputum, wheeze, haemoptysis warning
2. Exacerbation HistoryFrequency, triggers, severity, hospitalisations, NIV/intubation
3. Risk FactorsPack-year formula, occupational exposure, biomass fuel, A1AT deficiency
4. Past Medical HistoryKey comorbidities and why each matters
5. Drug HistoryInhaler classes, O₂/NIV, harmful drugs (beta-blockers, NSAIDs, ACEi)
6. Social & FunctionalADLs, CAT score domains, housing, support
7–8. Family & Systems ReviewA1AT flags, cor pulmonale, CO₂ retention, depression
9. DifferentialsAsthma, HF, bronchiectasis, TB, lung cancer, PF with distinguishing features
10. GOLD StagingGOLD 1–4 (FEV₁) + ABE groups (2023)
Checklist13-point visual checklist for the exam

How will i exclude cor pulmonale

Finding Sources
Finding Sources
Reading File
Reading File
Finding Sources
Reading File
Finding Sources
I now have all the content needed. Here is the comprehensive answer:

Excluding Cor Pulmonale in a COPD Long Case

Cor pulmonale = right ventricular hypertrophy/failure caused by pulmonary hypertension secondary to lung disease. In COPD, it develops via chronic alveolar hypoxia → pulmonary vasoconstriction → vascular remodeling → ↑ pulmonary vascular resistance → RV pressure overload → RV failure.
You exclude (or confirm) it across three levels: history → examination → investigations.

1. HISTORY — Symptoms That Suggest Cor Pulmonale

Ask specifically:
SymptomHow to Ask
Ankle swelling"Have you noticed swelling of your ankles or legs?" "Is it worse at the end of the day?"
Progressive dyspnoeaDisproportionate breathlessness beyond what the COPD severity would explain
Fatigue / exercise intoleranceLow-output RV failure causes profound fatigue
Presyncope / syncopeFrom reduced cardiac output; suggests severe PH
Abdominal distension / discomfortHepatic congestion from elevated right atrial pressure
Anorexia / nauseaGut congestion
PalpitationsAF and supraventricular arrhythmias are common (right atrial enlargement + hypoxaemia + bronchodilators)
Key point: Peripheral oedema in COPD patients is poorly correlated with resting right atrial pressure — it may also reflect RAAS activation from hypoxia, not just RV failure. Do not use ankle swelling alone to confirm or exclude cor pulmonale.

2. EXAMINATION — Signs to Look For

Vital Signs

  • SpO₂ — Hypoxia (SpO₂ <88%) is the main driver; chronic hypoxia must be present
  • Tachycardia — RV compensation / hypoxia / arrhythmia
  • Cyanosis — Central (lips/tongue) from hypoxia; peripheral (extremities) from low cardiac output

JVP (Jugular Venous Pressure)

  • Elevated JVP — the single most reliable bedside sign of raised right atrial pressure
  • Look for prominent 'a' wave (RVH, decreased RV compliance)
  • Look for prominent 'v' wave + pulsatile liver → tricuspid regurgitation (TR), a complication of longstanding cor pulmonale

Precordial Examination

  • Parasternal heave — RV hypertrophy (hand over left sternal edge)
  • Loud P₂ — Pulmonary hypertension (listen at pulmonary area 2nd ICS left)
  • Right ventricular S₃ — RV failure
  • TR murmur — Pansystolic at left sternal edge, louder on inspiration (Carvallo's sign)

Abdomen

  • Hepatomegaly — tender, pulsatile (if TR present)
  • Ascites — late sign of severe RHF

Peripheries

  • Pitting ankle/leg oedema — bilateral, pitting, dependent
  • Look up to the sacrum (if patient is bed-bound)
Signs you would NOT expect in simple COPD but suggest cor pulmonale:
  • Raised JVP
  • Parasternal heave
  • Loud P₂
  • TR murmur
  • Hepatomegaly + pulsatile liver

3. INVESTIGATIONS — How to Confirm/Exclude

Bedside

TestCor Pulmonale Finding
SpO₂ / ABGPaO₂ <8 kPa (60 mmHg), PaCO₂ ↑ (late), respiratory acidosis
ECGRight axis deviation, P pulmonale (tall peaked P in II >2.5 mm), RVH (dominant R in V1, deep S in V5/V6), RBBB, S₁Q₃T₃ pattern

Bloods

TestFinding
FBCPolycythaemia (Hb ↑) — compensatory response to chronic hypoxia
U&EMay show diuretic effects; hyponatraemia in severe failure
BNP / NT-proBNPElevated in RV failure
LFTsRaised in hepatic congestion (↑ ALP, bilirubin)
Venous bicarbonate↑ suggests chronic CO₂ retention

Imaging

ModalityFinding
Chest X-rayProminent pulmonary arteries (>16 mm right descending PA), enlarged hilar vessels, RV enlargement (obliteration of retrosternal space on lateral), peripheral pruning of vessels
ECG-gated CXR (PA)Cardiomegaly with RV dominance
Echocardiogram (Key investigation)RV enlargement + hypertrophy, elevated tricuspid regurgitant jet velocity (TRJV >2.8 m/s suggests PH), septal flattening/D-shaped LV in systole, estimated RVSP >35 mmHg
Cardiac MRIGold standard for RV volume/function; used when echo is inconclusive

Definitive Diagnosis

  • Right heart catheterisation (RHC) — the gold standard; demonstrates mean pulmonary artery pressure (mPAP) ≥25 mmHg at rest (or ≥20 mmHg by updated ESC criteria 2022). Required when echocardiogram is inconclusive or before specific PAH-targeted therapy.

Summary: Practical Approach in Long Case

History: Ankle oedema, worsening dyspnoea, syncope, abdominal distension
    ↓
Examination: Elevated JVP, parasternal heave, loud P₂, TR murmur,
             hepatomegaly, pitting oedema
    ↓
ECG: Right axis deviation, P pulmonale, RVH pattern
    ↓
CXR: Prominent pulmonary arteries, RV enlargement
    ↓
Echo: RV hypertrophy, TRJV, estimated RVSP
    ↓
ABG: Confirm hypoxia/hypercapnia (the primary driver)
    ↓
RHC (if needed): mPAP ≥20–25 mmHg = confirmed
Important caveat: Physical findings of venous engorgement and RV hypertrophy are late signs — by the time they are clinically obvious, significant PH is already established. Echocardiography is the most practical non-invasive tool and should be performed early in any COPD patient with unexplained worsening dyspnoea or oedema.

Sources: Fuster & Hurst's The Heart 15th Ed., pp. 1773–1777 | Fishman's Pulmonary Diseases & Disorders, p. 734

Can u make reference pdf of history taking of hepatitis, CKD

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Finding Sources
Reading File
Finding Sources
Reading File
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Writing File

~/copd-pdf/generate_hep_ckd_pdf.py

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm
from reportlab.lib.styles import ParagraphStyle
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT

OUTPUT = "/home/daytona/workspace/copd-pdf/Hepatitis_CKD_History_Quick_Reference.pdf"

# ── Palette ──────────────────────────────────────────────────────────────────
NAVY      = colors.HexColor("#1A3A5C")
TEAL      = colors.HexColor("#117A65")
AMBER     = colors.HexColor("#B7770D")
RED       = colors.HexColor("#922B21")
PURPLE    = colors.HexColor("#6C3483")
BLUE2     = colors.HexColor("#1A5276")
GREEN     = colors.HexColor("#1E8449")
DARKGREY  = colors.HexColor("#566573")
GREY      = colors.HexColor("#F2F3F4")
LIGHTGREY = colors.HexColor("#FDFEFE")
MIDGREY   = colors.HexColor("#D5D8DC")
WHITE     = colors.white
BLACK     = colors.HexColor("#1C2833")
LIGHTYELLOW = colors.HexColor("#FEF9E7")
LIGHTBLUE = colors.HexColor("#EAF2FF")
LIGHTRED  = colors.HexColor("#FDEDEC")
LIGHTGREEN= colors.HexColor("#E9F7EF")

PW = 178 * mm  # usable page width

# ── Style factory ────────────────────────────────────────────────────────────
def S(name, **kw):
    return ParagraphStyle(name, **kw)

title_s   = S("T", fontName="Helvetica-Bold",   fontSize=18, textColor=WHITE,  alignment=TA_CENTER, leading=22)
sub_s     = S("Su", fontName="Helvetica",        fontSize=9,  textColor=colors.HexColor("#AED6F1"), alignment=TA_CENTER, leading=12)
sechdr_s  = S("SH", fontName="Helvetica-Bold",   fontSize=9.5,textColor=WHITE,  alignment=TA_LEFT, leading=13)
body_s    = S("B",  fontName="Helvetica",         fontSize=8.5,textColor=BLACK,  leading=12, spaceAfter=2)
bold_s    = S("BB", fontName="Helvetica-Bold",    fontSize=8.5,textColor=BLACK,  leading=12, spaceAfter=2)
bul_s     = S("Bu", fontName="Helvetica",         fontSize=8.5,textColor=BLACK,  leading=12, leftIndent=10, firstLineIndent=-8, spaceAfter=1.5)
buld_s    = S("Bd", fontName="Helvetica-Bold",    fontSize=8.5,textColor=NAVY,   leading=12, leftIndent=10, firstLineIndent=-8, spaceAfter=1.5)
warn_s    = S("W",  fontName="Helvetica-BoldOblique", fontSize=8.5, textColor=RED, leading=12, leftIndent=8, spaceAfter=2)
tip_s     = S("Ti", fontName="Helvetica-Oblique", fontSize=8,  textColor=TEAL,  leading=11, leftIndent=8, spaceAfter=2)
small_s   = S("Sm", fontName="Helvetica",         fontSize=7.5,textColor=DARKGREY, leading=10, spaceAfter=1)
smit_s    = S("Si", fontName="Helvetica-Oblique", fontSize=7.5,textColor=DARKGREY, leading=10, spaceAfter=1)
th_s      = S("Th", fontName="Helvetica-Bold",    fontSize=8,  textColor=WHITE,  alignment=TA_CENTER, leading=11)
tc_s      = S("Tc", fontName="Helvetica",         fontSize=8,  textColor=BLACK,  leading=11)
tcb_s     = S("Tcb",fontName="Helvetica-Bold",    fontSize=8,  textColor=BLACK,  leading=11)
ftr_s     = S("Ft", fontName="Helvetica-Oblique", fontSize=7,  textColor=DARKGREY, alignment=TA_CENTER, leading=10)

# ── Helpers ───────────────────────────────────────────────────────────────────
def sp(h=3):
    return Spacer(1, h*mm)

def sec(title, bg=NAVY):
    d = [[Paragraph(f"▌  {title}", sechdr_s)]]
    t = Table(d, colWidths=[PW])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), bg),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
        ("RIGHTPADDING",  (0,0),(-1,-1), 4),
    ]))
    return t

def tbl(data, cw, bg=NAVY, extra=None):
    ts = [
        ("BACKGROUND",    (0,0),(-1,0), bg),
        ("TEXTCOLOR",     (0,0),(-1,0), WHITE),
        ("FONTNAME",      (0,0),(-1,0), "Helvetica-Bold"),
        ("FONTSIZE",      (0,0),(-1,-1), 8),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY]),
        ("GRID",          (0,0),(-1,-1), 0.4, MIDGREY),
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 5),
        ("RIGHTPADDING",  (0,0),(-1,-1), 5),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
        ("ALIGN",         (0,0),(-1,0),  "CENTER"),
    ]
    if extra:
        ts.extend(extra)
    t = Table(data, colWidths=cw)
    t.setStyle(TableStyle(ts))
    return t

def two_col(left_items, right_items, lw=89, rw=89):
    t = Table([[left_items, right_items]], colWidths=[lw*mm, rw*mm])
    t.setStyle(TableStyle([
        ("VALIGN",        (0,0),(-1,-1), "TOP"),
        ("LEFTPADDING",   (0,0),(-1,-1), 3),
        ("RIGHTPADDING",  (0,0),(-1,-1), 3),
        ("TOPPADDING",    (0,0),(-1,-1), 2),
        ("BOTTOMPADDING", (0,0),(-1,-1), 2),
    ]))
    return t

def banner(main, sub, bg):
    t = Table([[Paragraph(main, title_s)], [Paragraph(sub, sub_s)]], colWidths=[PW])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), bg),
        ("TOPPADDING",    (0,0),(-1,-1), 8),
        ("BOTTOMPADDING", (0,0),(-1,-1), 8),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
    ]))
    return t

def checklist_table(rows, bg_hdr=colors.HexColor("#2C3E50"), row_colors=None):
    data = [[Paragraph("✓", S("c", fontName="Helvetica-Bold", fontSize=9, textColor=GREEN, alignment=TA_CENTER, leading=11)),
             Paragraph("Domain", th_s),
             Paragraph("Key Points", th_s)]]
    for r in rows:
        data.append([
            Paragraph("□", S("cb", fontName="Helvetica-Bold", fontSize=9, textColor=DARKGREY, alignment=TA_CENTER, leading=11)),
            Paragraph(f"<b>{r[0]}</b>", tcb_s),
            Paragraph(r[1], tc_s),
        ])
    rc = row_colors or [LIGHTGREEN, WHITE]
    t = Table(data, colWidths=[7*mm, 55*mm, 116*mm])
    t.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,0), bg_hdr),
        ("TEXTCOLOR",     (0,0),(-1,0), WHITE),
        ("FONTNAME",      (0,0),(-1,0), "Helvetica-Bold"),
        ("FONTSIZE",      (0,0),(-1,-1), 8),
        ("ROWBACKGROUNDS",(0,1),(-1,-1), rc),
        ("GRID",          (0,0),(-1,-1), 0.4, MIDGREY),
        ("TOPPADDING",    (0,0),(-1,-1), 3),
        ("BOTTOMPADDING", (0,0),(-1,-1), 3),
        ("LEFTPADDING",   (0,0),(-1,-1), 5),
        ("VALIGN",        (0,0),(-1,-1), "MIDDLE"),
    ]))
    return t

# ════════════════════════════════════════════════════════════════════════════
# BUILD
# ════════════════════════════════════════════════════════════════════════════
def build():
    doc = SimpleDocTemplate(
        OUTPUT, pagesize=A4,
        leftMargin=16*mm, rightMargin=16*mm,
        topMargin=14*mm, bottomMargin=14*mm,
        title="Hepatitis & CKD History Quick Reference",
        author="Orris Medical"
    )
    story = []

    # ════════════════════════════════════════════════════════════════════════
    # PAGE 1 — HEPATITIS
    # ════════════════════════════════════════════════════════════════════════
    story.append(banner(
        "HEPATITIS — HISTORY TAKING",
        "Quick Reference — Long Case   |   Acute & Chronic Hepatitis (A/B/C/D/E + Autoimmune + Alcoholic)",
        colors.HexColor("#6E2C00")
    ))
    story.append(sp(2))

    # ── 1. Presenting Complaint ──────────────────────────────────────────────
    story.append(sec("1. PRESENTING COMPLAINT", bg=colors.HexColor("#6E2C00")))
    story.append(sp(1))
    story.append(Paragraph(
        "Common presenting symptoms: <b>jaundice</b>, fatigue, right-upper-quadrant (RUQ) pain, "
        "nausea/vomiting, anorexia, dark urine, pale stools, pruritus, abdominal distension. "
        "Many patients are <b>asymptomatic</b> and diagnosed incidentally on LFTs.",
        body_s))
    story.append(sp(2))

    # ── 2. HPC ───────────────────────────────────────────────────────────────
    story.append(sec("2. HISTORY OF PRESENTING COMPLAINT", bg=colors.HexColor("#873600")))
    story.append(sp(1))

    hpc_left = [
        Paragraph("<b>JAUNDICE</b>", bold_s),
        Paragraph("• Onset — sudden (acute hepatitis) vs. gradual (chronic/cirrhosis)", bul_s),
        Paragraph("• Duration and progression", bul_s),
        Paragraph("• Fluctuating (haemolytic/Gilbert's) vs. persistent", bul_s),
        Paragraph("• Associated dark urine + pale stools (cholestatic pattern)", bul_s),
        Paragraph("• Pruritus — suggests cholestasis (biliary obstruction or PBC)", bul_s),
        sp(2),
        Paragraph("<b>PAIN</b>", bold_s),
        Paragraph("• RUQ/epigastric — dull ache = hepatitis; sharp/colicky = biliary", bul_s),
        Paragraph("• Onset, radiation (to right shoulder = biliary)", bul_s),
        Paragraph("• Relation to food (biliary colic)", bul_s),
        sp(2),
        Paragraph("<b>SYSTEMIC SYMPTOMS</b>", bold_s),
        Paragraph("• Fatigue, malaise (often presenting complaint in chronic hepatitis)", bul_s),
        Paragraph("• Anorexia, nausea, vomiting, weight loss", bul_s),
        Paragraph("• Fever, arthralgia, rash — prodrome of Hep A/B", bul_s),
        Paragraph("• Low-grade fever vs. rigors (suggests cholangitis)", bul_s),
    ]

    hpc_right = [
        Paragraph("<b>COMPLICATIONS / ADVANCED DISEASE</b>", bold_s),
        Paragraph("• Abdominal distension — ascites (portal hypertension / liver failure)", bul_s),
        Paragraph("• Haematemesis / melaena — oesophageal varices", bul_s),
        Paragraph("• Easy bruising / prolonged bleeding — coagulopathy", bul_s),
        Paragraph("• Confusion / drowsiness / sleep inversion — hepatic encephalopathy", bul_s),
        Paragraph("• Ankle swelling — hypoalbuminaemia or portal HTN", bul_s),
        sp(2),
        Paragraph("<b>SPECIFIC TO ACUTE HEPATITIS</b>", bold_s),
        Paragraph("• Pre-icteric phase: flu-like illness 1–2 weeks before jaundice", bul_s),
        Paragraph("• Icteric phase: jaundice, dark urine, pale stools, RUQ discomfort", bul_s),
        Paragraph("• Resolution vs. fulminant hepatic failure (encephalopathy, coagulopathy)", bul_s),
        sp(2),
        Paragraph("<b>SPECIFIC TO CHRONIC HEPATITIS</b>", bold_s),
        Paragraph("• Insidious fatigue, vague RUQ discomfort for months–years", bul_s),
        Paragraph("• Features of cirrhosis: gynecomastia, testicular atrophy, spider naevi", bul_s),
        Paragraph("• Hepatocellular carcinoma screen: weight loss, worsening RUQ pain", bul_s),
    ]

    story.append(two_col(hpc_left, hpc_right))
    story.append(sp(2))

    # ── 3. Risk Factors / Aetiology ──────────────────────────────────────────
    story.append(sec("3. RISK FACTOR HISTORY — AETIOLOGY", bg=AMBER))
    story.append(sp(1))

    rf_data = [
        [Paragraph("Type", th_s), Paragraph("Route", th_s), Paragraph("Key Risk Factors to Ask", th_s)],
        [Paragraph("Hep A", tcb_s), Paragraph("Faeco-oral", tc_s),
         Paragraph("Travel to endemic areas, contaminated food/water, raw seafood, poor sanitation", tc_s)],
        [Paragraph("Hep B", tcb_s), Paragraph("Parenteral / sexual / vertical", tc_s),
         Paragraph("IV drug use (shared needles), unprotected sex, multiple partners, blood transfusion pre-1990s, tattoos/piercings, healthcare worker, born to HBsAg+ mother, needlestick", tc_s)],
        [Paragraph("Hep C", tcb_s), Paragraph("Parenteral (mainly)", tc_s),
         Paragraph("IV drug use (most common), blood transfusion pre-1992, haemodialysis, tattoos, needlestick, sexual contact (lower risk)", tc_s)],
        [Paragraph("Hep D", tcb_s), Paragraph("Parenteral (requires HBV)", tc_s),
         Paragraph("Co-infection or superinfection with HBV; same risk factors as Hep B", tc_s)],
        [Paragraph("Hep E", tcb_s), Paragraph("Faeco-oral", tc_s),
         Paragraph("Travel to South/East Asia, Central America, Africa; undercooked pork; immunosuppressed patients (chronic HEV)", tc_s)],
        [Paragraph("Alcoholic", tcb_s), Paragraph("Toxin", tc_s),
         Paragraph("Alcohol intake: units/week, duration, type; CAGE/AUDIT score; binge pattern", tc_s)],
        [Paragraph("Autoimmune", tcb_s), Paragraph("Autoimmune", tc_s),
         Paragraph("Female sex, personal/family history of autoimmune disease (thyroid, IBD, T1DM, SLE)", tc_s)],
        [Paragraph("NASH/MASH", tcb_s), Paragraph("Metabolic", tc_s),
         Paragraph("Obesity, T2DM, hyperlipidaemia, metabolic syndrome, rapid weight loss, TPN", tc_s)],
        [Paragraph("Drug-induced", tcb_s), Paragraph("Hepatotoxin", tc_s),
         Paragraph("All drugs incl. OTC, herbal/supplements, paracetamol dose, isoniazid, methotrexate, statins, antiepileptics, antiretrovirals", tc_s)],
        [Paragraph("Genetic", tcb_s), Paragraph("Inherited", tc_s),
         Paragraph("Haemochromatosis (Irish/Northern European, joint pain, diabetes, skin bronzing), Wilson's disease (young patient, neuropsychiatric), A1AT deficiency", tc_s)],
    ]
    story.append(tbl(rf_data, [16*mm, 40*mm, 122*mm], bg=AMBER))
    story.append(sp(1))
    story.append(Paragraph(
        "⚠ Always ask: <b>alcohol history</b> (quantify in units/week), <b>full drug history including herbals</b>, "
        "<b>sexual history</b>, <b>IV drug use</b> (non-judgmentally), <b>travel history</b>, <b>tattoos/piercings</b>, "
        "<b>blood products received</b> (when, where).",
        warn_s))
    story.append(sp(2))

    # ── 4. Past Medical History ──────────────────────────────────────────────
    story.append(sec("4. PAST MEDICAL HISTORY", bg=BLUE2))
    story.append(sp(1))
    pmh_left = [
        Paragraph("<b>Liver disease history</b>", bold_s),
        Paragraph("• Previous jaundice (post-op, in pregnancy, childhood)", bul_s),
        Paragraph("• Prior hepatitis diagnosis — acute or chronic", bul_s),
        Paragraph("• Cirrhosis, portal hypertension, varices, ascites", bul_s),
        Paragraph("• Liver biopsy — when, result?", bul_s),
        Paragraph("• Hepatocellular carcinoma", bul_s),
        sp(2),
        Paragraph("<b>Metabolic / systemic</b>", bold_s),
        Paragraph("• Diabetes mellitus, obesity, hyperlipidaemia (NASH risk)", bul_s),
        Paragraph("• Autoimmune conditions (AIH, IBD, thyroid disease)", bul_s),
        Paragraph("• Coeliac disease (abnormal LFTs)", bul_s),
    ]
    pmh_right = [
        Paragraph("<b>Surgical / procedural history</b>", bold_s),
        Paragraph("• Cholecystectomy, biliary surgery (biliary stricture)", bul_s),
        Paragraph("• Blood transfusions — pre-1992 (HCV risk)", bul_s),
        Paragraph("• Organ transplant (immunosuppression → chronic HBV/HCV)", bul_s),
        Paragraph("• Haemodialysis history (HCV risk)", bul_s),
        sp(2),
        Paragraph("<b>HIV status</b>", bold_s),
        Paragraph("• HIV co-infection accelerates HBV/HCV progression to cirrhosis", bul_s),
        Paragraph("• Antiretroviral therapy can cause hepatotoxicity", bul_s),
    ]
    story.append(two_col(pmh_left, pmh_right))
    story.append(sp(2))

    # ── 5. Drug History ──────────────────────────────────────────────────────
    story.append(sec("5. DRUG HISTORY", bg=PURPLE))
    story.append(sp(1))
    story.append(Paragraph(
        "List <b>all medications</b> — prescribed, OTC, herbal, and illicit. Ask about dose and duration. "
        "Common hepatotoxic agents include:",
        body_s))
    drug_data = [
        [Paragraph("Category", th_s), Paragraph("Examples", th_s), Paragraph("Pattern", th_s)],
        [Paragraph("Analgesics", tc_s), Paragraph("Paracetamol (↑ dose), NSAIDs", tc_s), Paragraph("Hepatocellular", tc_s)],
        [Paragraph("Antibiotics", tc_s), Paragraph("Flucloxacillin, co-amoxiclav, isoniazid, nitrofurantoin", tc_s), Paragraph("Hepatocellular / cholestatic", tc_s)],
        [Paragraph("Statins", tc_s), Paragraph("All statins", tc_s), Paragraph("Hepatocellular (usually mild)", tc_s)],
        [Paragraph("Antiepileptics", tc_s), Paragraph("Phenytoin, sodium valproate, carbamazepine", tc_s), Paragraph("Hepatocellular", tc_s)],
        [Paragraph("Chemotherapy", tc_s), Paragraph("Methotrexate, azathioprine", tc_s), Paragraph("Fibrosis / hepatocellular", tc_s)],
        [Paragraph("Herbal/supplements", tc_s), Paragraph("Kava, comfrey, green tea extract", tc_s), Paragraph("Variable — often underreported", tc_s)],
        [Paragraph("Alcohol", tc_s), Paragraph("Ethanol", tc_s), Paragraph("Steatosis → hepatitis → cirrhosis", tc_s)],
    ]
    story.append(tbl(drug_data, [30*mm, 74*mm, 74*mm], bg=PURPLE))
    story.append(sp(2))

    # ── 6. Social, Family, Systems ───────────────────────────────────────────
    soc_fam_left = [
        sec("6. SOCIAL HISTORY", bg=TEAL),
        sp(1),
        Paragraph("• <b>Alcohol</b> — units/week, years, type; CAGE/AUDIT score", bul_s),
        Paragraph("• <b>IV drug use</b> — past or present, sharing needles", bul_s),
        Paragraph("• <b>Sexual history</b> — partners, unprotected intercourse, MSM", bul_s),
        Paragraph("• <b>Travel</b> — endemic regions for Hep A/E (South Asia, Africa)", bul_s),
        Paragraph("• <b>Tattoos/piercings</b> — where, sterile technique?", bul_s),
        Paragraph("• <b>Occupation</b> — healthcare worker (needlestick risk)", bul_s),
        Paragraph("• <b>Immigration background</b> — HBV endemic countries (SE Asia, Sub-Saharan Africa)", bul_s),
        Paragraph("• <b>Household contacts</b> — HBV/HCV infected family members?", bul_s),
        Paragraph("• <b>Vaccination history</b> — Hep A / Hep B vaccinated?", bul_s),
    ]
    soc_fam_right = [
        sec("7. FAMILY HISTORY", bg=TEAL),
        sp(1),
        Paragraph("• Liver disease, cirrhosis, liver cancer", bul_s),
        Paragraph("• <b>Haemochromatosis</b> — Northern European ancestry; joint/cardiac disease", bul_s),
        Paragraph("• <b>Wilson's disease</b> — young patient, neurological symptoms", bul_s),
        Paragraph("• <b>A1AT deficiency</b> — emphysema + liver disease", bul_s),
        Paragraph("• Autoimmune diseases in family (AIH risk)", bul_s),
        sp(1),
        sec("8. SYSTEMS REVIEW", bg=GREEN),
        sp(1),
        Paragraph("• <b>GI:</b> Abdominal pain, change in bowel habit, melaena/haematemesis", bul_s),
        Paragraph("• <b>Neuro:</b> Confusion, personality change, sleep inversion → encephalopathy", bul_s),
        Paragraph("• <b>MSK:</b> Joint pains (Hep B prodrome, haemochromatosis)", bul_s),
        Paragraph("• <b>Skin:</b> Jaundice, spider naevi, palmar erythema, leuconychia, purpura", bul_s),
        Paragraph("• <b>Endocrine:</b> Gynaecomastia, loss of body hair, menstrual irregularity", bul_s),
        Paragraph("• <b>Renal:</b> Oedema (hypoalbuminaemia), hepatorenal syndrome", bul_s),
    ]
    story.append(two_col(soc_fam_left, soc_fam_right, lw=88, rw=90))
    story.append(sp(2))

    # ── Differentials ─────────────────────────────────────────────────────────
    story.append(sec("9. KEY DIFFERENTIALS TO EXCLUDE", bg=RED))
    story.append(sp(1))
    diff_data = [
        [Paragraph("Diagnosis", th_s), Paragraph("Distinguishing History Features", th_s)],
        [Paragraph("Biliary obstruction (stone/cancer)", tcb_s), Paragraph("Colicky RUQ pain radiating to shoulder, fluctuating jaundice, pale stools/dark urine, itching, weight loss (cancer)", tc_s)],
        [Paragraph("Alcoholic hepatitis", tcb_s), Paragraph("Heavy alcohol intake, recent binge, fever, tender hepatomegaly, coagulopathy", tc_s)],
        [Paragraph("Non-alcoholic steatohepatitis", tcb_s), Paragraph("Obesity, T2DM, metabolic syndrome, no/minimal alcohol, incidental LFT rise", tc_s)],
        [Paragraph("Haemolytic jaundice", tcb_s), Paragraph("Family history, anaemia, dark urine without pale stools, fluctuating, no hepatic symptoms", tc_s)],
        [Paragraph("Hepatocellular carcinoma", tcb_s), Paragraph("Background cirrhosis, weight loss, worsening ascites, ↑ AFP, RUQ mass", tc_s)],
        [Paragraph("Primary biliary cholangitis", tcb_s), Paragraph("Middle-aged woman, severe pruritus, fatigue, autoimmune disease, AMA positive", tc_s)],
    ]
    story.append(tbl(diff_data, [50*mm, 128*mm], bg=RED))
    story.append(sp(2))

    # ── Checklist ─────────────────────────────────────────────────────────────
    story.append(sec("HEPATITIS HISTORY CHECKLIST", bg=colors.HexColor("#2C3E50")))
    story.append(sp(1))
    hep_checks = [
        ("Presenting symptom", "Jaundice, fatigue, RUQ pain, dark urine, pale stools, pruritus"),
        ("Onset & course", "Acute vs. chronic; complications (encephalopathy, variceal bleed, ascites)"),
        ("Viral risk factors", "IV drug use, sexual history, blood products, tattoos, travel, needlestick"),
        ("Alcohol history", "Units/week, years drinking, CAGE/AUDIT score"),
        ("Drug & herbal history", "All medications including OTC, herbal, supplements — dose & duration"),
        ("Metabolic risk", "Obesity, T2DM, hyperlipidaemia, metabolic syndrome (NASH)"),
        ("Autoimmune screen", "Personal/family autoimmune disease history"),
        ("Genetic causes", "Family history of haemochromatosis, Wilson's, A1AT"),
        ("Past medical history", "Previous jaundice, liver disease, biliary surgery, HIV, dialysis"),
        ("Family history", "Liver disease, genetic disorders, HBV/HCV in household"),
        ("Vaccination history", "Hep A and B vaccination status"),
        ("Systems review", "Encephalopathy, GI bleeding, skin signs, renal, musculoskeletal"),
        ("Differentials excluded", "Biliary obstruction, haemolysis, HCC, PBC, alcoholic hepatitis"),
    ]
    story.append(checklist_table(hep_checks, bg_hdr=colors.HexColor("#6E2C00"), row_colors=[LIGHTYELLOW, WHITE]))
    story.append(sp(2))

    # ════════════════════════════════════════════════════════════════════════
    # PAGE BREAK → CKD
    # ════════════════════════════════════════════════════════════════════════
    story.append(PageBreak())

    story.append(banner(
        "CHRONIC KIDNEY DISEASE (CKD) — HISTORY TAKING",
        "Quick Reference — Long Case   |   CKD Stages 1–5 Including ESRD / Renal Replacement Therapy",
        colors.HexColor("#154360")
    ))
    story.append(sp(2))

    # ── 1. Presenting Complaint ───────────────────────────────────────────────
    story.append(sec("1. PRESENTING COMPLAINT", bg=colors.HexColor("#154360")))
    story.append(sp(1))
    story.append(Paragraph(
        "CKD is often <b>asymptomatic until late stages</b> — many patients are diagnosed incidentally on blood tests. "
        "Pain in the renal region and reduced urine output are <b>NOT</b> typical features of CKD. "
        "When symptoms do occur, they reflect the uraemic syndrome.",
        body_s))
    story.append(Paragraph(
        "⚠ Ask specifically: Was this an incidental finding? Or were there symptoms prompting testing?",
        warn_s))
    story.append(sp(2))

    # ── 2. HPC ───────────────────────────────────────────────────────────────
    story.append(sec("2. HISTORY OF PRESENTING COMPLAINT — URAEMIC SYNDROME", bg=colors.HexColor("#1A5276")))
    story.append(sp(1))

    uraemic_data = [
        [Paragraph("System", th_s), Paragraph("Symptoms to Ask About", th_s), Paragraph("Notes", th_s)],
        [Paragraph("General", tcb_s), Paragraph("Fatigue, malaise, weakness, weight loss, anorexia", tc_s), Paragraph("Often earliest symptoms; non-specific", tc_s)],
        [Paragraph("GI", tcb_s), Paragraph("Nausea, vomiting, hiccups, metallic taste in mouth, anorexia", tc_s), Paragraph("Uraemic gastritis and gastroparesis", tc_s)],
        [Paragraph("Neurological", tcb_s), Paragraph("Confusion, drowsiness, asterixis, seizures (severe); restless legs at night; muscle cramps", tc_s), Paragraph("Uraemic encephalopathy; peripheral neuropathy", tc_s)],
        [Paragraph("Cardiovascular", tcb_s), Paragraph("Breathlessness, orthopnoea, ankle swelling, chest pain", tc_s), Paragraph("Fluid overload, LVH, pericarditis (friction rub)", tc_s)],
        [Paragraph("Haematological", tcb_s), Paragraph("Pallor, fatigue, dyspnoea on exertion, easy bruising/bleeding", tc_s), Paragraph("Normochromic normocytic anaemia (↓EPO); platelet dysfunction", tc_s)],
        [Paragraph("Skin", tcb_s), Paragraph("Pruritus (generalised, severe), sallow/yellow-brown skin", tc_s), Paragraph("Uraemic frost (very late, rare now); calcium-phosphate deposition", tc_s)],
        [Paragraph("Bone/MSK", tcb_s), Paragraph("Bone pain, fractures, muscle weakness, proximal myopathy", tc_s), Paragraph("Renal osteodystrophy (↓vit D, ↑PTH, ↑phosphate)", tc_s)],
        [Paragraph("Urological", tcb_s), Paragraph("Nocturia (early; loss of concentrating ability), oliguria, haematuria, frothy urine (proteinuria)", tc_s), Paragraph("Haematuria → glomerulonephritis, cancer, stones", tc_s)],
        [Paragraph("Sleep / psych", tcb_s), Paragraph("Restless leg syndrome, insomnia, depression, cognitive impairment", tc_s), Paragraph("Very common; QoL impact", tc_s)],
    ]
    story.append(tbl(uraemic_data, [28*mm, 88*mm, 62*mm], bg=colors.HexColor("#1A5276")))
    story.append(sp(2))

    # ── 3. Risk Factors / Aetiology ──────────────────────────────────────────
    story.append(sec("3. RISK FACTOR HISTORY — CAUSES OF CKD", bg=AMBER))
    story.append(sp(1))

    ckd_cause_left = [
        Paragraph("<b>MOST COMMON CAUSES (ask first)</b>", bold_s),
        Paragraph("• <b>Diabetes mellitus</b> — type, duration, glycaemic control (HbA1c), proteinuria onset, diabetic retinopathy (marker of nephropathy)", bul_s),
        Paragraph("• <b>Hypertension</b> — duration, BP control, medications; may cause OR be caused by CKD", bul_s),
        Paragraph("• <b>Glomerulonephritis</b> — haematuria, proteinuria, nephrotic/nephritic syndrome, previous biopsy", bul_s),
        Paragraph("• <b>Renovascular disease</b> — atherosclerotic risk factors, flash pulmonary oedema, resistant hypertension", bul_s),
        sp(2),
        Paragraph("<b>OBSTRUCTIVE / STRUCTURAL</b>", bold_s),
        Paragraph("• BPH / prostate cancer — hesitancy, nocturia, poor flow", bul_s),
        Paragraph("• Recurrent renal calculi — previous stones, haematuria, colicky pain, metabolic causes", bul_s),
        Paragraph("• Recurrent UTIs / reflux nephropathy", bul_s),
        Paragraph("• Congenital — horseshoe kidney, duplex system", bul_s),
    ]

    ckd_cause_right = [
        Paragraph("<b>SYSTEMIC DISEASES</b>", bold_s),
        Paragraph("• SLE / vasculitis — arthralgia, rash, pleuritis, sinusitis, haemoptysis", bul_s),
        Paragraph("• Amyloidosis — chronic inflammatory disease, myeloma, weight loss", bul_s),
        Paragraph("• Multiple myeloma — back pain, anaemia, hypercalcaemia (age >40 + unexplained CKD)", bul_s),
        Paragraph("• Sickle cell disease — sickling crises, chronic haemolysis", bul_s),
        sp(2),
        Paragraph("<b>HEREDITARY</b>", bold_s),
        Paragraph("• <b>Polycystic kidney disease (ADPKD)</b> — family history, loin pain, hypertension, haematuria, liver cysts, cerebral aneurysm", bul_s),
        Paragraph("• <b>Alport's syndrome</b> — haematuria, sensorineural deafness, ocular defects, family history", bul_s),
        Paragraph("• <b>Fabry's disease</b> — neuropathic pain, angiokeratomas, cardiac disease", bul_s),
        sp(2),
        Paragraph("<b>NEPHROTOXIC EXPOSURE</b>", bold_s),
        Paragraph("• NSAIDs, COX-2 inhibitors (chronic use)", bul_s),
        Paragraph("• Contrast nephropathy history", bul_s),
        Paragraph("• Lithium — therapeutic levels, duration", bul_s),
        Paragraph("• Heavy metals (lead, cadmium) — occupational", bul_s),
        Paragraph("• Previous cisplatin / aminoglycoside use", bul_s),
        Paragraph("• Aristolochic acid (herbal medicines)", bul_s),
    ]
    story.append(two_col(ckd_cause_left, ckd_cause_right))
    story.append(sp(2))

    # ── 4. Past Medical History ──────────────────────────────────────────────
    story.append(sec("4. PAST MEDICAL HISTORY", bg=BLUE2))
    story.append(sp(1))
    pmh2_data = [
        [Paragraph("Condition", th_s), Paragraph("Why It Matters", th_s)],
        [Paragraph("Diabetes mellitus", tcb_s), Paragraph("Most common cause of CKD in developed world; check duration, complications, glycaemic control", tc_s)],
        [Paragraph("Hypertension", tcb_s), Paragraph("Cause and consequence of CKD; control critical to slow progression", tc_s)],
        [Paragraph("Cardiovascular disease", tcb_s), Paragraph("IHD, heart failure, stroke — major comorbidity and cause of death in CKD", tc_s)],
        [Paragraph("Previous AKI", tcb_s), Paragraph("Risk factor for CKD; prior AKI episodes, cause, severity, recovery", tc_s)],
        [Paragraph("Urological history", tcb_s), Paragraph("Stones, UTIs, BPH, reflux, haematuria, previous operations", tc_s)],
        [Paragraph("Preeclampsia", tcb_s), Paragraph("CKD risk factor; also haematuria / proteinuria in pregnancy", tc_s)],
        [Paragraph("Hepatitis B / C / HIV", tcb_s), Paragraph("Membranous/MPGN nephropathy; immunosuppression affects management", tc_s)],
        [Paragraph("Gout", tcb_s), Paragraph("Urate nephropathy; shares risk factors with CKD", tc_s)],
    ]
    story.append(tbl(pmh2_data, [45*mm, 133*mm], bg=BLUE2))
    story.append(sp(2))

    # ── 5. Drug History ──────────────────────────────────────────────────────
    story.append(sec("5. DRUG HISTORY — NEPHROTOXIC AGENTS & RENAL DOSING", bg=PURPLE))
    story.append(sp(1))
    ckd_drug_left = [
        Paragraph("<b>NEPHROTOXIC DRUGS TO IDENTIFY</b>", bold_s),
        Paragraph("• NSAIDs (ibuprofen, diclofenac) — chronic use", bul_s),
        Paragraph("• COX-2 inhibitors", bul_s),
        Paragraph("• Lithium — check levels and duration", bul_s),
        Paragraph("• Calcineurin inhibitors (ciclosporin, tacrolimus)", bul_s),
        Paragraph("• Aminoglycosides — past IV courses", bul_s),
        Paragraph("• Contrast agents — previous AKI after imaging?", bul_s),
        Paragraph("• Proton pump inhibitors — interstitial nephritis", bul_s),
        Paragraph("• Phosphate-containing bowel preps", bul_s),
        Paragraph("• Herbal medicines (aristolochic acid)", bul_s),
    ]
    ckd_drug_right = [
        Paragraph("<b>CURRENT MEDICATIONS FOR CKD</b>", bold_s),
        Paragraph("• ACE inhibitor / ARB — renoprotective; dose?", bul_s),
        Paragraph("• <b>SGLT2 inhibitor</b> — dapagliflozin, empagliflozin (renoprotective in DKD)", bul_s),
        Paragraph("• Diuretics — loop (furosemide), thiazide", bul_s),
        Paragraph("• Phosphate binders — sevelamer, calcium carbonate", bul_s),
        Paragraph("• Vitamin D analogues — alfacalcidol, calcitriol", bul_s),
        Paragraph("• EPO / ESAs — darbepoetin, erythropoietin", bul_s),
        Paragraph("• Antihypertensives — target BP &lt;130/80 in CKD+proteinuria", bul_s),
        Paragraph("• Bicarbonate supplementation — for metabolic acidosis", bul_s),
        Paragraph("• Allopurinol — for hyperuricaemia", bul_s),
    ]
    story.append(two_col(ckd_drug_left, ckd_drug_right))
    story.append(sp(2))

    # ── 6. RRT History ───────────────────────────────────────────────────────
    story.append(sec("6. RENAL REPLACEMENT THERAPY (RRT) HISTORY — IF APPLICABLE", bg=colors.HexColor("#117A65")))
    story.append(sp(1))
    rrt_left = [
        Paragraph("<b>DIALYSIS</b>", bold_s),
        Paragraph("• Type: Haemodialysis (HD) or Peritoneal dialysis (PD)", bul_s),
        Paragraph("• HD: frequency (3×/week), duration, unit or home-based", bul_s),
        Paragraph("• Access: arteriovenous fistula (AVF), tunnelled line, PD catheter", bul_s),
        Paragraph("• Complications: infections, access failure, hypotension on HD", bul_s),
        Paragraph("• Adequacy: Kt/V, fluid removal, residual renal function", bul_s),
    ]
    rrt_right = [
        Paragraph("<b>TRANSPLANT</b>", bold_s),
        Paragraph("• Date, donor (living/deceased), type of match", bul_s),
        Paragraph("• Current immunosuppression: tacrolimus, mycophenolate, prednisolone", bul_s),
        Paragraph("• Rejection episodes — acute or chronic", bul_s),
        Paragraph("• Complications: infections, malignancy, calcineurin toxicity", bul_s),
        Paragraph("• Current eGFR of transplant kidney", bul_s),
        Paragraph("• Listed for re-transplant?", bul_s),
    ]
    story.append(two_col(rrt_left, rrt_right))
    story.append(sp(2))

    # ── 7. Social + Family + Systems ─────────────────────────────────────────
    soc2_left = [
        sec("7. SOCIAL HISTORY", bg=TEAL),
        sp(1),
        Paragraph("• Occupation — nephrotoxic exposures (lead, cadmium, solvents)", bul_s),
        Paragraph("• Diet — high protein, salt, potassium, phosphate intake", bul_s),
        Paragraph("• Fluid intake and management", bul_s),
        Paragraph("• Smoking — accelerates CKD progression and CVD risk", bul_s),
        Paragraph("• Alcohol — NSAID + alcohol = nephrotoxic combination", bul_s),
        Paragraph("• Exercise tolerance and functional status", bul_s),
        Paragraph("• Transport to dialysis unit (if on HD)", bul_s),
        Paragraph("• Social support / carer involvement", bul_s),
        Paragraph("• Employment impact / disability", bul_s),
    ]
    soc2_right = [
        sec("8. FAMILY HISTORY", bg=TEAL),
        sp(1),
        Paragraph("• CKD in family members — same or different cause", bul_s),
        Paragraph("• <b>ADPKD</b> — autosomal dominant; ask about each parent", bul_s),
        Paragraph("• <b>Alport's syndrome</b> — X-linked; family deafness/haematuria", bul_s),
        Paragraph("• Diabetes, hypertension in family (risk factors)", bul_s),
        Paragraph("• Shared environmental nephrotoxin exposure", bul_s),
        sp(1),
        sec("9. SYSTEMS REVIEW", bg=GREEN),
        sp(1),
        Paragraph("• <b>CVS:</b> IHD, LVH, pericarditis (friction rub = uraemia), AF", bul_s),
        Paragraph("• <b>Neuro:</b> Peripheral neuropathy, restless legs, encephalopathy", bul_s),
        Paragraph("• <b>Eyes:</b> Diabetic retinopathy, hypertensive retinopathy", bul_s),
        Paragraph("• <b>Bone:</b> Fractures, bone pain (renal osteodystrophy)", bul_s),
        Paragraph("• <b>Psych:</b> Depression, cognitive impairment (very common)", bul_s),
        Paragraph("• <b>Sexual:</b> Erectile dysfunction, menstrual irregularity (uraemia)", bul_s),
    ]
    story.append(two_col(soc2_left, soc2_right, lw=88, rw=90))
    story.append(sp(2))

    # ── CKD Staging Reminder ─────────────────────────────────────────────────
    story.append(sec("10. CKD STAGING — KDIGO 2024 (eGFR + Albuminuria)", bg=AMBER))
    story.append(sp(1))
    ckd_stage_data = [
        [Paragraph("Stage", th_s), Paragraph("eGFR (mL/min/1.73m²)", th_s), Paragraph("Severity", th_s)],
        [Paragraph("G1", tc_s), Paragraph("≥ 90", tc_s), Paragraph("Normal or high (kidney damage markers present)", tc_s)],
        [Paragraph("G2", tc_s), Paragraph("60–89", tc_s), Paragraph("Mildly decreased", tc_s)],
        [Paragraph("G3a", tc_s), Paragraph("45–59", tc_s), Paragraph("Mildly to moderately decreased", tc_s)],
        [Paragraph("G3b", tc_s), Paragraph("30–44", tc_s), Paragraph("Moderately to severely decreased", tc_s)],
        [Paragraph("G4", tc_s), Paragraph("15–29", tc_s), Paragraph("Severely decreased — prepare for RRT", tc_s)],
        [Paragraph("G5", tc_s), Paragraph("< 15", tc_s), Paragraph("Kidney failure (ESRD) — RRT or conservative management", tc_s)],
    ]
    story.append(tbl(ckd_stage_data, [13*mm, 50*mm, 115*mm], bg=AMBER))
    story.append(sp(1))
    story.append(Paragraph(
        "Albuminuria categories: A1 &lt;30 mg/g (normal–mildly increased), A2 30–300 mg/g (moderately increased), "
        "A3 &gt;300 mg/g (severely increased). Higher albuminuria = faster progression. "
        "Combine G and A categories for full staging (e.g. G3bA2).",
        smit_s))
    story.append(sp(2))

    # ── CKD Checklist ─────────────────────────────────────────────────────────
    story.append(sec("CKD HISTORY CHECKLIST", bg=colors.HexColor("#2C3E50")))
    story.append(sp(1))
    ckd_checks = [
        ("Presenting complaint", "Incidental vs. symptomatic; uraemic symptoms: fatigue, nausea, pruritus, restless legs"),
        ("Uraemic syndrome review", "GI, neuro, CVS, haematological, skin, bone, urological, sleep symptoms"),
        ("Cause of CKD", "Diabetes, hypertension, GN, renovascular, obstructive, hereditary, systemic disease"),
        ("Nephrotoxic drug history", "NSAIDs, lithium, contrast, aminoglycosides, herbal medicines"),
        ("Current CKD medications", "ACEi/ARB, SGLT2i, diuretics, phosphate binders, EPO, vitamin D"),
        ("Past medical history", "Diabetes, hypertension, AKI, urological, preeclampsia, cardiovascular"),
        ("RRT history", "Type of dialysis (HD/PD), access, frequency; transplant history and immunosuppression"),
        ("Family history", "ADPKD, Alport's, diabetes, hypertension, shared toxin exposure"),
        ("Social history", "Occupation, diet, smoking, fluid management, transport to dialysis"),
        ("Systems review", "CVS (IHD, pericarditis), eyes (retinopathy), neuro (neuropathy), bone, psych"),
        ("CKD staging", "eGFR value, albuminuria category — G and A staging"),
        ("Differentials", "AKI vs. CKD, obstructive uropathy, myeloma (age >35 with unexplained CKD + anaemia)"),
    ]
    story.append(checklist_table(ckd_checks, bg_hdr=colors.HexColor("#154360"), row_colors=[LIGHTBLUE, WHITE]))
    story.append(sp(3))

    # ── Footer ────────────────────────────────────────────────────────────────
    footer_d = [[Paragraph(
        "<i>Sources: Harrison's Principles of Internal Medicine 22E | Barash Clinical Anesthesia 9e | "
        "Sleisenger &amp; Fordtran's GI and Liver Disease | Goldman-Cecil Medicine | "
        "Tietz Textbook of Laboratory Medicine | KDIGO CKD Guidelines 2024</i>",
        ftr_s)]]
    footer = Table(footer_d, colWidths=[PW])
    footer.setStyle(TableStyle([
        ("BACKGROUND",    (0,0),(-1,-1), GREY),
        ("TOPPADDING",    (0,0),(-1,-1), 4),
        ("BOTTOMPADDING", (0,0),(-1,-1), 4),
        ("LEFTPADDING",   (0,0),(-1,-1), 6),
    ]))
    story.append(footer)

    doc.build(story)
    print(f"PDF created: {OUTPUT}")

build()
Running Command

cd /home/daytona/workspace/copd-pdf && python generate_hep_ckd_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/copd-pdf/

Your 2-page PDF is ready:

Hepatitis CKD History Quick Reference

PDF Document · PDF


Page 1 — Hepatitis (burnt orange theme)
SectionContents
Presenting ComplaintJaundice, fatigue, RUQ pain, dark urine, pale stools, pruritus
HPCAcute vs. chronic features, complications (encephalopathy, varices, ascites)
Risk Factor TableHep A/B/C/D/E, alcoholic, autoimmune, NASH, drug-induced, genetic — routes & specific risk factors
Past Medical HistoryPrevious jaundice, biliary surgery, blood products, HIV, dialysis
Drug History TableHepatotoxic drug classes with patterns (hepatocellular/cholestatic)
Social, Family, SystemsAlcohol CAGE/AUDIT, IV drug use, sexual history, travel, vaccination, family genetic causes
DifferentialsBiliary obstruction, haemolysis, HCC, PBC, alcoholic hepatitis with distinguishing features
Checklist13-point exam checklist
Page 2 — CKD (navy/blue theme)
SectionContents
Uraemic Syndrome TableAll systems — GI, neuro, CVS, haematological, skin, bone, urological, sleep
Causes of CKDDM, HTN, GN, ADPKD, Alport's, SLE, myeloma, obstructive, nephrotoxins
Past Medical HistoryDiabetes, hypertension, AKI, cardiovascular, preeclampsia
Drug HistoryNephrotoxic drugs + current CKD medications (SGLT2i, ACEi, EPO, phosphate binders)
RRT HistoryHaemodialysis, peritoneal dialysis, transplant sections
Social, Family, SystemsDiet, fluid, occupation, ADPKD/Alport's family history
KDIGO StagingG1–G5 eGFR table + albuminuria A1–A3 explanation
Checklist12-point exam checklist
This is a shared conversation. Sign in to Orris to start your own chat.