Create me pdf of Arterial Blood Gas Analysis interpretation and four major ABG disorders- metabolic acidosis and alkalosis, respiratory acidosis and alkalosis with Mixed disorders, cause, pathophysiology and management in shortnote form based on Sanjay pandya book for fluid management and tintinalli book for emergency medicine
mkdir -p /tmp/workspace/abg-pdf && ls /tmp/workspace/abg-pdf/
~/abg-pdf/generate_abg_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.lib import colors
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether, PageBreak
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
# ── page setup ──────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
"/tmp/workspace/abg-pdf/ABG_Analysis_Short_Notes.pdf",
pagesize=A4,
rightMargin=1.8*cm, leftMargin=1.8*cm,
topMargin=2*cm, bottomMargin=2*cm,
)
W, H = A4
styles = getSampleStyleSheet()
# ── colour palette ───────────────────────────────────────────────────────────
DARK_BLUE = colors.HexColor("#1A3A6B")
MID_BLUE = colors.HexColor("#2766B5")
LIGHT_BLUE = colors.HexColor("#D6E4F7")
TEAL = colors.HexColor("#006D77")
TEAL_LIGHT = colors.HexColor("#E0F4F5")
RED = colors.HexColor("#C0392B")
RED_LIGHT = colors.HexColor("#FDECEA")
GREEN = colors.HexColor("#1A7A4A")
GREEN_LIGHT = colors.HexColor("#E8F8EF")
ORANGE = colors.HexColor("#D35400")
ORANGE_LIGHT= colors.HexColor("#FEF5EC")
PURPLE = colors.HexColor("#6C3483")
PURPLE_LIGHT= colors.HexColor("#F5EEF8")
GREY_BG = colors.HexColor("#F2F3F4")
WHITE = colors.white
BLACK = colors.HexColor("#1C1C1C")
GOLD = colors.HexColor("#F4C430")
# ── custom paragraph styles ───────────────────────────────────────────────────
def PS(name, parent="Normal", **kw):
return ParagraphStyle(name, parent=styles[parent], **kw)
title_style = PS("DocTitle",
fontSize=22, leading=28, textColor=WHITE,
alignment=TA_CENTER, fontName="Helvetica-Bold",
spaceAfter=4)
subtitle_style = PS("DocSubtitle",
fontSize=12, leading=16, textColor=colors.HexColor("#BFD7F5"),
alignment=TA_CENTER, fontName="Helvetica",
spaceAfter=2)
source_style = PS("DocSource",
fontSize=9, leading=12, textColor=GOLD,
alignment=TA_CENTER, fontName="Helvetica-Oblique")
section_title = PS("SectionTitle",
fontSize=14, leading=18, textColor=WHITE,
fontName="Helvetica-Bold", spaceBefore=4, spaceAfter=2)
sub_heading = PS("SubHeading",
fontSize=11, leading=14, textColor=DARK_BLUE,
fontName="Helvetica-Bold", spaceBefore=6, spaceAfter=3)
body = PS("Body",
fontSize=9.5, leading=14, textColor=BLACK,
fontName="Helvetica", spaceAfter=4,
alignment=TA_JUSTIFY)
bullet = PS("Bullet",
fontSize=9, leading=13, textColor=BLACK,
fontName="Helvetica", leftIndent=12, bulletIndent=0,
spaceAfter=2, alignment=TA_LEFT)
small = PS("Small",
fontSize=8.5, leading=12, textColor=colors.HexColor("#444"),
fontName="Helvetica-Oblique", spaceAfter=2)
key_box = PS("KeyBox",
fontSize=9, leading=13, textColor=DARK_BLUE,
fontName="Helvetica-Bold", spaceAfter=0)
formula_style = PS("Formula",
fontSize=10, leading=14, textColor=TEAL,
fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=4)
# ── helper builders ───────────────────────────────────────────────────────────
def color_box(content_flowables, bg_color, border_color=None, radius=4):
"""Wrap flowables in a single-cell table acting as a coloured card."""
bc = border_color or bg_color
t = Table([[content_flowables]], colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg_color),
("ROUNDEDCORNERS", [radius, radius, radius, radius]),
("BOX", (0,0), (-1,-1), 1, bc),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
def section_header(text, bg=DARK_BLUE, text_color=WHITE):
p = Paragraph(text, PS("SH", parent="SectionTitle",
textColor=text_color, fontSize=13,
fontName="Helvetica-Bold",
spaceBefore=0, spaceAfter=0))
t = Table([[p]], colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("ROUNDEDCORNERS", [3,3,3,3]),
("BOX", (0,0), (-1,-1), 0, bg),
("LEFTPADDING", (0,0), (-1,-1), 12),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
]))
return t
def two_col_table(rows, col1_w=4.5*cm, header_bg=LIGHT_BLUE):
avail = doc.width
c2w = avail - col1_w
tbl_data = rows
ts = TableStyle([
("BACKGROUND", (0,0), (-1,0), header_bg),
("TEXTCOLOR", (0,0), (-1,0), DARK_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("LEADING", (0,0), (-1,-1), 13),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#CCCCCC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_BG]),
])
t = Table([[Paragraph(str(r[0]), key_box), Paragraph(str(r[1]), body)]
for r in tbl_data], colWidths=[col1_w, c2w])
t.setStyle(ts)
return t
def three_col_table(rows, widths=None, header_bg=LIGHT_BLUE):
avail = doc.width
if widths is None:
widths = [avail/3, avail/3, avail/3]
ts = TableStyle([
("BACKGROUND", (0,0), (-1,0), header_bg),
("TEXTCOLOR", (0,0), (-1,0), DARK_BLUE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 9),
("LEADING", (0,0), (-1,-1), 13),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#CCCCCC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_BG]),
])
styled = []
for i, row in enumerate(rows):
if i == 0:
styled.append([Paragraph(str(c), PS("th",fontSize=9,fontName="Helvetica-Bold",textColor=DARK_BLUE)) for c in row])
else:
styled.append([Paragraph(str(c), body) for c in row])
t = Table(styled, colWidths=widths)
t.setStyle(ts)
return t
# ═══════════════════════════════════════════════════════════════════════════════
# CONTENT BUILD
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER PAGE ────────────────────────────────────────────────────────────────
cover_content = [
Spacer(1, 1.5*cm),
Paragraph("ARTERIAL BLOOD GAS", title_style),
Paragraph("ANALYSIS & INTERPRETATION", title_style),
Spacer(1, 0.4*cm),
HRFlowable(width="60%", thickness=2, color=GOLD, spaceAfter=10, hAlign="CENTER"),
Paragraph("Four Major ABG Disorders | Mixed Disorders", subtitle_style),
Paragraph("Causes • Pathophysiology • Management", subtitle_style),
Spacer(1, 0.5*cm),
Paragraph("Based on:", source_style),
Paragraph("Tintinalli's Emergency Medicine: A Comprehensive Study Guide", source_style),
Paragraph("Sanjay Pandya: Practical Approach to Fluid Management", source_style),
Spacer(1, 1*cm),
]
cover_bg = Table([[ cover_content ]], colWidths=[doc.width + 3.6*cm])
cover_bg.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DARK_BLUE),
("LEFTPADDING", (0,0), (-1,-1), -1.8*cm),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
]))
story.append(cover_bg)
story.append(Spacer(1, 0.6*cm))
# ── SECTION 1: ABG NORMAL VALUES ──────────────────────────────────────────────
story.append(section_header("1. ARTERIAL BLOOD GAS — NORMAL VALUES & INTERPRETATION"))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Normal ABG Reference Values", sub_heading))
normal_vals = [
["Parameter", "Normal Range", "Clinical Significance"],
["pH", "7.35 – 7.45", "< 7.35 = acidemia; > 7.45 = alkalemia"],
["PaCO₂", "35 – 45 mmHg", "Primary respiratory parameter; CO₂ = volatile acid"],
["HCO₃⁻ (calculated)", "22 – 26 mEq/L", "Primary metabolic parameter; renal regulation"],
["PaO₂", "80 – 100 mmHg", "< 60 mmHg = hypoxemia requiring intervention"],
["SaO₂", "95 – 100%", "Reflects haemoglobin oxygen saturation"],
["Base Excess (BE)", "-2 to +2 mEq/L", "Metabolic component; negative = deficit"],
["Anion Gap (AG)", "8 – 12 mEq/L", "AG = Na⁺ − (HCO₃⁻ + Cl⁻)"],
]
story.append(three_col_table(normal_vals,
widths=[3.5*cm, 3.5*cm, doc.width - 7*cm],
header_bg=LIGHT_BLUE))
story.append(Spacer(1, 0.3*cm))
# Henderson-Hasselbalch
story.append(color_box([
Paragraph("<b>Henderson-Hasselbalch Equation</b>", key_box),
Paragraph("pH = 6.1 + log ( [HCO₃⁻] / 0.03 × PaCO₂ )", formula_style),
Paragraph("pH is maintained by the ratio of metabolic (HCO₃⁻) to respiratory (PaCO₂) component. "
"Compensation restores the ratio but rarely normalises pH completely.", body),
], TEAL_LIGHT, TEAL))
story.append(Spacer(1, 0.3*cm))
# Step-wise interpretation
story.append(Paragraph("Stepwise ABG Interpretation (Tintinalli Method)", sub_heading))
steps = [
["Step", "Action"],
["Step 1", "Look at pH: <7.35 → acidemia; >7.45 → alkalemia; normal but HCO₃⁻/PaCO₂ abnormal → suspect mixed disorder"],
["Step 2", "Identify primary disorder: ↓HCO₃⁻ → metabolic acidosis; ↑PaCO₂ (with normal HCO₃⁻) → respiratory acidosis"],
["Step 3", "Calculate Anion Gap: AG = Na⁺ − (Cl⁻ + HCO₃⁻). Normal AG = 8–12 mEq/L"],
["Step 4", "Assess compensation (see formulas below)"],
["Step 5", "Delta-delta ratio (AG acidosis): ΔAG / ΔHCO₃⁻. ~1 = pure; >1 = concomitant met. alkalosis; <1 = concomitant normal-AG acidosis"],
["Step 6", "Correlate with clinical picture"],
]
story.append(two_col_table(steps, col1_w=2*cm, header_bg=LIGHT_BLUE))
story.append(Spacer(1, 0.3*cm))
# Compensation formulas
story.append(Paragraph("Compensation Formulas", sub_heading))
comp_data = [
["Disorder", "Expected Compensation", "Rule of Thumb"],
["Metabolic Acidosis", "PaCO₂ = 1.5×[HCO₃⁻] + 8 ± 2 (Winter's formula)\nOR: PaCO₂ decreases 1 mmHg per 1 mEq/L ↓ HCO₃⁻", "Last 2 digits of pH ≈ expected PaCO₂"],
["Metabolic Alkalosis", "PaCO₂ increases 0.7 mmHg per 1 mEq/L ↑ HCO₃⁻\n(max PaCO₂ ~55 mmHg)", "Hypoventilation is limited by hypoxic drive"],
["Resp. Acidosis (Acute)", "HCO₃⁻ increases 1 mEq/L per 10 mmHg ↑ PaCO₂", "Buffering by non-bicarbonate buffers"],
["Resp. Acidosis (Chronic)", "HCO₃⁻ increases 3.5 mEq/L per 10 mmHg ↑ PaCO₂", "Renal compensation over 3–5 days"],
["Resp. Alkalosis (Acute)", "HCO₃⁻ decreases 2 mEq/L per 10 mmHg ↓ PaCO₂", "Immediate buffering response"],
["Resp. Alkalosis (Chronic)", "HCO₃⁻ decreases 5 mEq/L per 10 mmHg ↓ PaCO₂", "Renal compensation over days"],
]
story.append(three_col_table(comp_data,
widths=[4*cm, 7*cm, doc.width - 11*cm],
header_bg=LIGHT_BLUE))
story.append(Spacer(1, 0.3*cm))
# Oxygenation assessment
story.append(Paragraph("Oxygenation Assessment", sub_heading))
oxy_content = [
Paragraph("<b>A-a Gradient</b> = PAO₂ − PaO₂", key_box),
Paragraph("PAO₂ = (FiO₂ × [Patm − PH₂O]) − (PaCO₂ / 0.8) = FiO₂ × 713 − PaCO₂/0.8 (at sea level)", formula_style),
Paragraph("Normal gradient: < 15 mmHg (young adults); increases with age (age/4 + 4) and with ↑ FiO₂", body),
Paragraph("<b>PaO₂/FiO₂ ratio:</b> Normal ~600 (on 40% O₂). < 300 = ALI; < 200 = ARDS (Berlin criteria). "
"Ratio decreases as physiologic shunt increases.", body),
]
story.append(color_box(oxy_content, LIGHT_BLUE, MID_BLUE))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ── SECTION 2: METABOLIC ACIDOSIS ─────────────────────────────────────────────
story.append(section_header("2. METABOLIC ACIDOSIS", bg=RED, text_color=WHITE))
story.append(Spacer(1, 0.3*cm))
story.append(color_box([
Paragraph("<b>Definition:</b> Primary decrease in serum HCO₃⁻ (< 22 mEq/L) → pH < 7.35. "
"Classified by Anion Gap (AG) status.", body),
], RED_LIGHT, RED))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Causes — HIGH Anion Gap (AG > 12): Mnemonic MUDPILES / GOLDMARK", sub_heading))
mudpiles_data = [
["MUDPILES", "Causes"],
["M — Methanol / Metformin", "Toxic alcohol ingestion, lactic acidosis from metformin accumulation"],
["U — Uraemia", "Renal failure → retention of organic acids (sulphate, phosphate)"],
["D — Diabetic Ketoacidosis", "Insulin deficiency → ↑ ketone bodies (acetoacetate, β-hydroxybutyrate)"],
["P — Propylene glycol / Paracetamol", "Solvent toxicity; hepatotoxicity causing hepatic acidosis"],
["I — Isoniazid / Iron", "Lactic acidosis; iron toxicity causes AG elevation"],
["L — Lactic Acidosis", "Type A: hypoperfusion/hypoxia. Type B: drugs, liver disease, malignancy"],
["E — Ethylene glycol", "Toxic metabolites (oxalate, glycolate) → renal failure + AG acidosis"],
["S — Salicylates", "Mixed disorder: resp. alkalosis early + anion gap acidosis"],
]
story.append(two_col_table(mudpiles_data, col1_w=5.5*cm, header_bg=RED_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Causes — NORMAL Anion Gap (Hyperchloraemic): Mnemonic USED CARP", sub_heading))
nagma = [
["Category", "Causes"],
["GI HCO₃⁻ Loss", "Diarrhoea, small bowel/pancreatic fistula, ileostomy, ureterosigmoidostomy"],
["Renal HCO₃⁻ Loss", "Renal Tubular Acidosis (RTA I, II, IV), carbonic anhydrase inhibitors"],
["Exogenous Cl⁻ load", "Normal saline excess (hyperchloraemic), NH₄Cl, HCl administration"],
["Adrenal/endocrine", "Hypoaldosteronism, Addison's disease"],
["Ureteral diversion", "Ileal conduit — chloride absorption, bicarbonate loss"],
]
story.append(two_col_table(nagma, col1_w=4.5*cm, header_bg=RED_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Pathophysiology", sub_heading))
story.append(color_box([
Paragraph("<b>Two Mechanisms:</b>", key_box),
Paragraph("1. <b>Gain of H⁺:</b> Organic acid accumulation (ketones, lactate, toxins) or strong acid addition. "
"H⁺ titrates HCO₃⁻ → CO₂ eliminated by lungs. AG rises = unmeasured anions accumulate.", body),
Paragraph("2. <b>Loss of HCO₃⁻:</b> Gastrointestinal losses (diarrhoea) or renal wasting (RTA). "
"Chloride reabsorbed to maintain electroneutrality → hyperchloraemia. AG remains normal.", body),
Paragraph("<b>Compensation:</b> Chemoreceptors detect ↓pH → ↑ ventilation → ↓ PaCO₂ (respiratory compensation, "
"begins within minutes, maximal at 12–24 h). Kidney retains HCO₃⁻ and excretes H⁺ (days).", body),
Paragraph("<b>Effects:</b> Myocardial depression, ↓ cardiac output, vasodilation/vasoconstriction (mixed), "
"hyperkalaemia (H⁺/K⁺ exchange), impaired enzyme function, shift of O₂-Hb dissociation curve right (Bohr effect).", body),
], RED_LIGHT, RED))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Management", sub_heading))
met_acid_mgmt = [
["Priority", "Intervention"],
["1. Treat underlying cause", "DKA → insulin + fluids; lactic acidosis → improve perfusion; diarrhoea → replace losses; toxins → antidote/dialysis"],
["2. IV fluids", "0.9% NaCl or balanced crystalloid (Plasmalyte, Hartmann's) for volume resuscitation.\nAvoid excess normal saline (worsens hyperchloraemia)"],
["3. NaHCO₃ (selective use)", "Consider if pH < 7.1 or HCO₃⁻ < 8 mEq/L in NAGMA or severe acidaemia refractory to treatment.\nDose: HCO₃⁻ deficit = 0.3 × weight(kg) × (target − actual HCO₃⁻). Give 50% over 4–6 h"],
["4. Monitor K⁺", "Acidosis causes hyperkalaemia; as pH corrects, K⁺ shifts intracellularly → may cause hypokalaemia. Supplement cautiously"],
["5. Renal Replacement Therapy", "Severe refractory acidosis, uraemia, toxin removal (methanol, ethylene glycol)"],
["6. Special: DKA", "Fluids + insulin drip. Dextrose when glucose < 250 mg/dL. K⁺ must be ≥ 3.5 before insulin"],
["7. Special: Lactic acidosis", "Identify Type A (hypoxia) vs Type B (sepsis, drugs). Treat cause. NaHCO₃ controversial — may ↑ intracellular CO₂"],
]
story.append(two_col_table(met_acid_mgmt, col1_w=5*cm, header_bg=RED_LIGHT))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ── SECTION 3: METABOLIC ALKALOSIS ───────────────────────────────────────────
story.append(section_header("3. METABOLIC ALKALOSIS", bg=GREEN, text_color=WHITE))
story.append(Spacer(1, 0.3*cm))
story.append(color_box([
Paragraph("<b>Definition:</b> Primary increase in serum HCO₃⁻ (> 26 mEq/L) → pH > 7.45. "
"Classified as Chloride-Responsive (urine Cl⁻ < 20 mEq/L) or Chloride-Resistant (urine Cl⁻ > 20 mEq/L).", body),
], GREEN_LIGHT, GREEN))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Causes", sub_heading))
met_alk_causes = [
["Type", "Mechanism", "Examples"],
["Chloride-Responsive\n(Urine Cl⁻ < 20)", "HCl loss; volume contraction; chloride depletion maintains HCO₃⁻ retention", "Vomiting/NG suction (most common), pyloric stenosis, thiazide/loop diuretics (early), posthypercapnic state, diarrhoea with high Cl⁻ loss"],
["Chloride-Resistant\n(Urine Cl⁻ > 20)", "Mineralocorticoid excess → H⁺/K⁺ excretion, HCO₃⁻ retention; or exogenous alkali load", "Primary hyperaldosteronism (Conn's), Cushing's syndrome, Bartter/Gitelman syndromes, exogenous steroids, severe hypokalaemia, excess NaHCO₃/antacids, massive blood transfusion (citrate → HCO₃⁻)"],
]
story.append(three_col_table(met_alk_causes,
widths=[3.8*cm, 5.5*cm, doc.width - 9.3*cm],
header_bg=GREEN_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Pathophysiology", sub_heading))
story.append(color_box([
Paragraph("<b>Generation Phase:</b> Primary alkali gain or acid/chloride loss elevates plasma HCO₃⁻.", body),
Paragraph("<b>Maintenance Phase:</b> Normal kidneys excrete HCO₃⁻ rapidly, so maintenance requires a co-existing "
"factor — usually <b>volume depletion</b> (↑ proximal tubular Na⁺/HCO₃⁻ reabsorption) or "
"<b>hypokalaemia</b> (↑ distal H⁺ secretion, K⁺/H⁺ exchange) or <b>aldosterone excess</b>.", body),
Paragraph("<b>Compensation:</b> ↑pH inhibits peripheral chemoreceptors → hypoventilation → ↑ PaCO₂. "
"Limited by hypoxic ventilatory drive (PaCO₂ rarely exceeds 55–60 mmHg).", body),
Paragraph("<b>Effects:</b> ↓ ionised Ca²⁺ (Chvostek/Trousseau signs), hypokalaemia, neuromuscular irritability, "
"↓ O₂ delivery (left shift of O₂-Hb curve), arrhythmias.", body),
], GREEN_LIGHT, GREEN))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Management", sub_heading))
met_alk_mgmt = [
["Step", "Intervention"],
["1. Chloride-Responsive", "IV 0.9% Normal Saline — restores volume, delivers Cl⁻, allows kidneys to excrete excess HCO₃⁻. "
"Target urine Cl⁻ > 20 mEq/L as endpoint of adequate Cl⁻ replacement"],
["2. Correct hypokalaemia", "KCl supplementation — essential. K⁺ replaces H⁺ in cells, reducing renal H⁺ excretion. "
"Oral preferred; IV if severe (< 2.5 mEq/L) via central line at ≤ 10 mEq/h"],
["3. Stop offending drugs", "Cease diuretics, exogenous steroids, antacids, NaHCO₃ infusions"],
["4. Chloride-Resistant", "Treat underlying mineralocorticoid excess. Spironolactone for hyperaldosteronism. "
"Triamterene/amiloride for Bartter/Gitelman. Correct hypokalaemia aggressively"],
["5. Severe/refractory alkalosis", "IV HCl (0.1 N via central line) — rarely needed. Acetazolamide 250–500 mg "
"IV/PO → ↑ renal HCO₃⁻ excretion (contraindicated if volume depleted). Dialysis if renal failure"],
["6. Post-NG suction", "PPI/H₂ blockers reduce gastric HCl secretion, limiting ongoing generation"],
]
story.append(two_col_table(met_alk_mgmt, col1_w=4.5*cm, header_bg=GREEN_LIGHT))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ── SECTION 4: RESPIRATORY ACIDOSIS ──────────────────────────────────────────
story.append(section_header("4. RESPIRATORY ACIDOSIS", bg=ORANGE, text_color=WHITE))
story.append(Spacer(1, 0.3*cm))
story.append(color_box([
Paragraph("<b>Definition:</b> Primary increase in PaCO₂ (> 45 mmHg) → pH < 7.35. "
"Results from alveolar hypoventilation or impaired CO₂ elimination.", body),
], ORANGE_LIGHT, ORANGE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Causes — Mnemonic: STOP breathing (6 categories)", sub_heading))
resp_acid_causes = [
["Category", "Mechanism", "Examples"],
["CNS Depression", "↓ Drive to breathe", "Opioids, benzodiazepines, anaesthetics, stroke/TBI, intracranial hypertension, brainstem lesion"],
["Neuromuscular Disease", "Failure of respiratory muscles", "Myasthenia gravis crisis, Guillain-Barré, ALS, diaphragm paralysis, cervical cord injury (C3–C5)"],
["Chest Wall / Pleural", "Mechanical restriction to breathing", "Tension pneumothorax, flail chest, severe kyphoscoliosis, obesity hypoventilation syndrome, massive pleural effusion"],
["Airway Obstruction", "↑ Airway resistance", "Severe asthma, acute COPD exacerbation, epiglottitis, foreign body, obstructive sleep apnoea"],
["Parenchymal Lung Disease", "V/Q mismatch, impaired gas exchange", "ARDS, severe pneumonia, pulmonary oedema, diffuse interstitial fibrosis"],
["Iatrogenic / Equipment", "Inadequate ventilation support", "Ventilator malfunction, undersized ET tube, excessive sedation, high dead space ventilation"],
]
story.append(three_col_table(resp_acid_causes,
widths=[3.8*cm, 4.5*cm, doc.width - 8.3*cm],
header_bg=ORANGE_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Pathophysiology", sub_heading))
story.append(color_box([
Paragraph("<b>CO₂ accumulation:</b> CO₂ + H₂O → H₂CO₃ → H⁺ + HCO₃⁻ (catalysed by carbonic anhydrase). "
"Accumulated CO₂ directly depresses CNS ('CO₂ narcosis') and causes cerebral vasodilation.", body),
Paragraph("<b>Acute (< 24–48 h):</b> Limited buffering. Each 10 mmHg ↑ PaCO₂ → HCO₃⁻ ↑ only 1 mEq/L "
"(non-bicarbonate intracellular buffers). Significant acidaemia results. Sympathetic activation → "
"↑HR, ↑BP (early), then cardiovascular depression.", body),
Paragraph("<b>Chronic (> 48–72 h):</b> Kidney increases H⁺ secretion, reabsorbs HCO₃⁻, and produces NH₄⁺. "
"Each 10 mmHg ↑ PaCO₂ → HCO₃⁻ ↑ 3.5 mEq/L. pH partially normalised.", body),
Paragraph("<b>COPD chronic hypercapnia:</b> Chemoreceptors reset ('CO₂ insensitivity'). Hypoxic drive "
"becomes primary stimulus → caution with high-flow O₂ (may suppress drive).", body),
], ORANGE_LIGHT, ORANGE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Management", sub_heading))
resp_acid_mgmt = [
["Intervention", "Details"],
["1. Treat underlying cause", "Reverse opioids (naloxone 0.4–2 mg IV/IM/IN). Bronchodilators for asthma/COPD. "
"Steroids for airway inflammation. Drain pneumothorax. Antibiotics for pneumonia"],
["2. Airway management", "Position upright. Clear secretions. Consider NIV (BiPAP/CPAP) early — preferred for COPD exacerbation, "
"OHS, pulmonary oedema. Intubation if failing NIV, coma, unable to protect airway"],
["3. Non-Invasive Ventilation (NIV)", "BiPAP: IPAP 10–20, EPAP 4–8 cmH₂O. Reduces PaCO₂, decreases WOB, "
"avoids complications of intubation. First-line for COPD (reduces mortality)"],
["4. Mechanical Ventilation", "Target PaCO₂ toward patient baseline (not always normal). Tidal volume 6 mL/kg IBW. "
"Increase RR to ↓ PaCO₂. Allow permissive hypercapnia in ARDS (pH > 7.20 acceptable)"],
["5. O₂ therapy", "Target SpO₂ 88–92% in known chronic hypercapnia (COPD) to avoid suppressing hypoxic drive. "
"Higher targets (94–98%) in acute without prior hypercapnia"],
["6. Avoid NaHCO₃", "Bicarbonate generates CO₂ (HCO₃⁻ + H⁺ → CO₂ + H₂O) — worsens hypercapnia if ventilation inadequate"],
]
story.append(two_col_table(resp_acid_mgmt, col1_w=4.5*cm, header_bg=ORANGE_LIGHT))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ── SECTION 5: RESPIRATORY ALKALOSIS ─────────────────────────────────────────
story.append(section_header("5. RESPIRATORY ALKALOSIS", bg=PURPLE, text_color=WHITE))
story.append(Spacer(1, 0.3*cm))
story.append(color_box([
Paragraph("<b>Definition:</b> Primary decrease in PaCO₂ (< 35 mmHg) → pH > 7.45. "
"Results from alveolar hyperventilation. Most common acid-base disorder in ICU patients.", body),
], PURPLE_LIGHT, PURPLE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Causes — Mnemonic: CHAMPS", sub_heading))
resp_alk_causes = [
["Category", "Mechanism", "Examples"],
["CNS / Anxiety", "↑ Central drive", "Anxiety, pain, psychogenic hyperventilation, fever, CNS lesions (meningitis, stroke, trauma), salicylate poisoning (early)"],
["Hypoxaemia-driven", "Hypoxic chemoreceptor stimulation", "Pneumonia, pulmonary embolism, high altitude, CHF, severe anaemia, early ARDS/ALI"],
["Activation of pulmonary receptors", "J-receptor/stretch receptor stimulation", "Pulmonary oedema, ILD, pulmonary hypertension"],
["Mechanical Ventilation", "Iatrogenic hyperventilation", "Excessive RR or VT settings, patient–ventilator dyssynchrony"],
["Physiologic states", "↑ Metabolic demand or hormonal effects", "Pregnancy (progesterone), sepsis/SIRS (early), liver failure, exercise, thyrotoxicosis"],
["Special: Salicylates", "Direct respiratory centre stimulation", "Mixed picture: respiratory alkalosis (early) + anion gap metabolic acidosis (later)"],
]
story.append(three_col_table(resp_alk_causes,
widths=[3.8*cm, 4.5*cm, doc.width - 8.3*cm],
header_bg=PURPLE_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Pathophysiology", sub_heading))
story.append(color_box([
Paragraph("<b>CO₂ elimination:</b> ↑ Alveolar ventilation washes out CO₂ → ↓ H₂CO₃ → ↓ H⁺ → ↑ pH.", body),
Paragraph("<b>Acute:</b> Each 10 mmHg ↓ PaCO₂ → HCO₃⁻ ↓ by 2 mEq/L (rapid cellular buffering: intracellular H⁺ moves out, "
"HCO₃⁻ moves into cells). pH rises significantly.", body),
Paragraph("<b>Chronic:</b> Renal compensation over 2–5 days. ↓ H⁺ secretion, ↓ HCO₃⁻ reabsorption, ↓ NH₄⁺ excretion. "
"Each 10 mmHg ↓ PaCO₂ → HCO₃⁻ ↓ 5 mEq/L. pH near-normalises.", body),
Paragraph("<b>Effects of ↑ pH:</b> ↓ Ionised Ca²⁺ → tetany, paraesthesia, carpopedal spasm (Trousseau). "
"Cerebral vasoconstriction → dizziness, confusion, syncope. Coronary vasoconstriction. "
"Hypokalaemia (K⁺ shifts intracellularly). ↑ Neuronal excitability → seizures.", body),
], PURPLE_LIGHT, PURPLE))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Management", sub_heading))
resp_alk_mgmt = [
["Intervention", "Details"],
["1. Treat underlying cause", "This is the most important step. Treat PE (anticoagulation), pneumonia (antibiotics), "
"sepsis (source control + resuscitation), salicylate toxicity, fever, pain"],
["2. Psychogenic / anxiety", "Reassurance. Controlled breathing techniques. Rebreathing into paper bag (increases CO₂) — "
"use cautiously; rule out organic cause first. Benzodiazepine if severe"],
["3. Hypoxaemia-driven", "Supplement O₂ to correct underlying hypoxaemia. This removes hypoxic stimulus and resolves hyperventilation"],
["4. Mechanically ventilated", "Reduce rate (RR) or tidal volume. Increase dead space if needed. "
"Target PaCO₂ 35–45 mmHg unless permissive hypercapnia strategy in use"],
["5. Salicylate toxicity", "Sodium bicarbonate infusion (urine alkalinisation → enhances salicylate excretion). "
"Haemodialysis for severe toxicity. Monitor for coexistent metabolic acidosis"],
["6. Symptomatic treatment", "IV calcium gluconate (1 g) for severe tetany or carpopedal spasm from hypocalcaemia"],
]
story.append(two_col_table(resp_alk_mgmt, col1_w=4.5*cm, header_bg=PURPLE_LIGHT))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ── SECTION 6: MIXED DISORDERS ────────────────────────────────────────────────
story.append(section_header("6. MIXED ACID-BASE DISORDERS", bg=TEAL, text_color=WHITE))
story.append(Spacer(1, 0.3*cm))
story.append(color_box([
Paragraph("<b>Definition:</b> Two or more simultaneous primary acid-base disturbances. Suspected when: "
"(a) pH is normal but HCO₃⁻ and PaCO₂ are both abnormal; "
"(b) compensation is more or less than expected; "
"(c) delta-delta ratio is outside the 1:1 range.", body),
], TEAL_LIGHT, TEAL))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("How to Identify Mixed Disorders (Tintinalli)", sub_heading))
identify_mixed = [
["Clue", "Interpretation"],
["pH normal + HCO₃⁻ ↓ + PaCO₂ ↓", "Met. acidosis + Resp. alkalosis (opposing — cancel each other)"],
["pH normal + HCO₃⁻ ↑ + PaCO₂ ↑", "Met. alkalosis + Resp. acidosis (opposing — cancel each other)"],
["Measured PaCO₂ > expected (Winter's)", "Primary resp. acidosis superimposed on met. acidosis"],
["Measured PaCO₂ < expected (Winter's)", "Primary resp. alkalosis superimposed on met. acidosis"],
["Δ-Δ ratio > 2 (ΔAG >> ΔHCO₃⁻)", "HAGMA + concomitant metabolic alkalosis"],
["Δ-Δ ratio < 1 (ΔAG << ΔHCO₃⁻)", "HAGMA + concomitant normal AG metabolic acidosis"],
["↓ HCO₃⁻ + ↑ PaCO₂", "Met. acidosis + Resp. acidosis — additive, severe acidaemia"],
["↑ HCO₃⁻ + ↓ PaCO₂", "Met. alkalosis + Resp. alkalosis — additive, severe alkalaemia"],
]
story.append(two_col_table(identify_mixed, col1_w=6*cm, header_bg=TEAL_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Common Mixed Disorder Patterns", sub_heading))
mixed_patterns = [
["Mixed Disorder", "Common Clinical Settings", "Key Features"],
["Metabolic Acidosis\n+\nRespiratory Alkalosis", "Sepsis (most common), salicylate poisoning, hepatic failure, pulmonary embolism",
"pH may be near-normal or alkaline. Both PaCO₂ and HCO₃⁻ low. Resp. alkalosis masks severity of metabolic acidosis"],
["Metabolic Alkalosis\n+\nRespiratory Acidosis", "COPD + diuretic use, post-operative with nasogastric suctioning, severe OHS, chronic liver disease with diuretics",
"pH often near-normal. Both PaCO₂ and HCO₃⁻ elevated. Common in chronic lung disease. Paradoxical combination"],
["Metabolic Acidosis\n+\nRespiratory Acidosis", "Cardiorespiratory arrest, severe septic shock with respiratory failure, drowning, combined opioid OD + rhabdomyolysis",
"Profoundly low pH. Critically ill. Immediate ventilatory support + resuscitation required"],
["Metabolic Alkalosis\n+\nRespiratory Alkalosis", "Cirrhosis with diuretics, pregnancy with vomiting, ICU patient on ventilator + NG suctioning",
"Markedly elevated pH (> 7.55). Dangerous cardiac arrhythmias. ↓↓ ionised Ca²⁺"],
["HAGMA + Normal AG Acidosis\n(Triple disorder with Resp. Alk.)", "Salicylate toxicity (classic triple), sepsis with vomiting",
"HAGMA + NAGMA coexistent: Δ-Δ < 1. pH depends on balance of all three. Treat each component"],
["HAGMA + Metabolic Alkalosis", "DKA with vomiting, lactic acidosis + diuretics",
"Δ-Δ ratio > 2. HCO₃⁻ is less reduced than expected for degree of AG elevation. Easy to underestimate severity"],
]
story.append(three_col_table(mixed_patterns,
widths=[4*cm, 5.5*cm, doc.width - 9.5*cm],
header_bg=TEAL_LIGHT))
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("Approach to Mixed Disorders — Management Principles", sub_heading))
story.append(color_box([
Paragraph("1. <b>Never treat numbers alone</b> — correlate with clinical picture, history, and medications.", body),
Paragraph("2. <b>Treat the most life-threatening component first</b> (usually the disorder causing severe pH deviation).", body),
Paragraph("3. <b>Sequential re-assessment:</b> As one disorder resolves, unmasked disorders may become apparent.", body),
Paragraph("4. <b>Be cautious with alkali therapy</b> in mixed metabolic acidosis + respiratory acidosis — NaHCO₃ generates CO₂ "
"and worsens hypercapnia without improved ventilation.", body),
Paragraph("5. <b>Delta-delta ratio:</b> Use to uncover hidden metabolic disorders within a high-AG acidosis. "
"ΔAG = (measured AG − 12); ΔHCO₃⁻ = (24 − measured HCO₃⁻). Ratio = ΔAG/ΔHCO₃⁻.", body),
Paragraph("6. <b>Serum electrolytes:</b> Always check Na⁺, K⁺, Cl⁻, phosphate, magnesium and correct them.", body),
], TEAL_LIGHT, TEAL))
story.append(Spacer(1, 0.4*cm))
story.append(PageBreak())
# ── SECTION 7: QUICK REFERENCE SUMMARY ───────────────────────────────────────
story.append(section_header("7. QUICK REFERENCE — ABG DISORDER SUMMARY TABLE", bg=DARK_BLUE))
story.append(Spacer(1, 0.3*cm))
summary_data = [
["Disorder", "pH", "PaCO₂", "HCO₃⁻", "AG", "Key Cause", "Compensation"],
["Metabolic Acidosis\n(High AG)", "↓", "↓ (comp.)", "↓↓ (primary)", "↑", "DKA, lactic acidosis, toxins, uraemia", "PaCO₂ = 1.5×HCO₃⁻ + 8"],
["Metabolic Acidosis\n(Normal AG)", "↓", "↓ (comp.)", "↓↓ (primary)", "Normal", "Diarrhoea, RTA, saline excess", "PaCO₂ = 1.5×HCO₃⁻ + 8"],
["Metabolic Alkalosis", "↑", "↑ (comp.)", "↑↑ (primary)", "Normal", "Vomiting, diuretics, hyperaldosteronism", "PaCO₂ ↑ 0.7 per 1 mEq/L ↑HCO₃⁻"],
["Respiratory Acidosis\n(Acute)", "↓", "↑↑ (primary)", "↑ (comp.)", "Normal", "Opioids, severe asthma, neuromuscular", "HCO₃⁻ ↑ 1 per 10 mmHg ↑PaCO₂"],
["Respiratory Acidosis\n(Chronic)", "↓ (mild)", "↑↑ (primary)", "↑↑ (comp.)", "Normal", "COPD, OHS, chronic NM disease", "HCO₃⁻ ↑ 3.5 per 10 mmHg ↑PaCO₂"],
["Respiratory Alkalosis\n(Acute)", "↑", "↓↓ (primary)", "↓ (comp.)", "Normal", "Anxiety, PE, sepsis, pain, altitude", "HCO₃⁻ ↓ 2 per 10 mmHg ↓PaCO₂"],
["Respiratory Alkalosis\n(Chronic)", "↑ (mild)", "↓↓ (primary)", "↓↓ (comp.)", "Normal", "Pregnancy, chronic hypoxia, hepatic failure", "HCO₃⁻ ↓ 5 per 10 mmHg ↓PaCO₂"],
]
avail = doc.width
cws = [3*cm, 1.2*cm, 1.8*cm, 1.8*cm, 1.5*cm, 4.5*cm, avail - 13.8*cm]
ts2 = TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_BLUE),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,-1), 8.5),
("LEADING", (0,0), (-1,-1), 12),
("GRID", (0,0), (-1,-1), 0.5, colors.HexColor("#AAAAAA")),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, GREY_BG]),
])
styled_rows = []
for i, row in enumerate(summary_data):
if i == 0:
styled_rows.append([Paragraph(c, PS("sh2", fontSize=8.5, fontName="Helvetica-Bold", textColor=WHITE)) for c in row])
else:
styled_rows.append([Paragraph(c, PS("td", fontSize=8.5, leading=12)) for c in row])
t_summary = Table(styled_rows, colWidths=cws)
t_summary.setStyle(ts2)
story.append(t_summary)
story.append(Spacer(1, 0.4*cm))
# ── SECTION 8: FLUID THERAPY IN ABG ──────────────────────────────────────────
story.append(section_header("8. FLUID MANAGEMENT PRINCIPLES IN ABG DISORDERS", bg=MID_BLUE))
story.append(Spacer(1, 0.3*cm))
story.append(color_box([
Paragraph("<b>Sanjay Pandya Principles — Fluid Therapy in Acid-Base Disorders</b>", key_box),
Spacer(1, 4),
Paragraph("<b>Metabolic Acidosis:</b> Use balanced crystalloids (Ringer's Lactate / Plasmalyte) to avoid "
"hyperchloraemic acidosis from excess 0.9% NaCl. In DKA, start with 0.9% NaCl (1 L/h initially for shock), "
"then switch to 0.45% NaCl with K⁺ once volume restored. Lactate-containing fluids are generally safe — "
"the liver converts lactate to HCO₃⁻. Avoid in severe hepatic failure.", body),
Spacer(1, 4),
Paragraph("<b>Metabolic Alkalosis:</b> Normal saline (0.9% NaCl) is the fluid of choice — restores volume "
"and provides Cl⁻ to correct chloride-responsive alkalosis. Add KCl 10–20 mEq/L to maintenance fluids. "
"In pyloric stenosis/vomiting: 0.9% NaCl + KCl until urine Cl⁻ > 20 mEq/L.", body),
Spacer(1, 4),
Paragraph("<b>Respiratory Acidosis / Alkalosis:</b> Fluid choice plays a secondary role — focus on ventilation. "
"Avoid excess NaHCO₃ infusion (generates CO₂). Maintain euvolaemia to optimise cardiac output and O₂ delivery.", body),
Spacer(1, 4),
Paragraph("<b>Volume Assessment:</b> CVP, urine output (target 0.5 mL/kg/h), lactate clearance, and clinical signs "
"guide fluid therapy. Excess fluids worsen pulmonary oedema and dilutional acidosis.", body),
], LIGHT_BLUE, MID_BLUE))
story.append(Spacer(1, 0.3*cm))
# IV Fluid Comparison Table
story.append(Paragraph("IV Fluid pH and Electrolyte Content — Clinical Selection Guide", sub_heading))
fluid_data = [
["Fluid", "pH", "Na⁺\n(mEq/L)", "Cl⁻\n(mEq/L)", "HCO₃⁻ equiv.", "Use In"],
["0.9% Normal Saline", "5.0", "154", "154", "None", "Met. alkalosis (Cl⁻ responsive), volume expansion, DKA (initial)"],
["Hartmann's (RL)", "6.5", "130", "109", "Lactate 28", "Metabolic acidosis, general resuscitation, trauma"],
["Plasmalyte 148", "7.4", "140", "98", "Acetate+Gluconate 50", "Preferred balanced crystalloid, large volume resus., met. acidosis"],
["0.45% NaCl + Dextrose", "4.5", "77", "77", "None", "DKA maintenance phase, free water replacement"],
["NaHCO₃ (8.4%)", "8.0", "1000", "None", "1000 (as HCO₃⁻)", "Severe met. acidosis pH < 7.1, hyperkalaemia, Na⁺ channel toxicity"],
["Dextrose 5%", "4.0", "0", "0", "None", "Free water deficit, maintenance only; NOT for resuscitation"],
]
story.append(three_col_table(fluid_data,
widths=[3.5*cm, 1.2*cm, 1.5*cm, 1.5*cm, 2.8*cm, doc.width - 10.5*cm],
header_bg=LIGHT_BLUE))
story.append(Spacer(1, 0.5*cm))
# Footer note
story.append(HRFlowable(width="100%", thickness=1, color=DARK_BLUE, spaceAfter=6))
story.append(Paragraph(
"Sources: Tintinalli's Emergency Medicine: A Comprehensive Study Guide, 9th Ed. (Tintinalli et al., McGraw-Hill, 2020) | "
"Sanjay Pandya: Practical Approach to Fluid Management (principles applied to acid-base context) | "
"Harrison's Principles of Internal Medicine 22E (2025). "
"Prepared as short-note reference for educational use. Always verify drug doses and protocols in clinical practice.",
PS("footer", fontSize=7.5, textColor=colors.grey, leading=10, alignment=TA_CENTER)
))
# ── BUILD ─────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF generated successfully: /tmp/workspace/abg-pdf/ABG_Analysis_Short_Notes.pdf")
cd /tmp/workspace/abg-pdf && python generate_abg_pdf.py 2>&1
~/abg-pdf/generate_abg_pdf.py
Successfully replaced 1 instance(s) of the string in '/tmp/workspace/abg-pdf/generate_abg_pdf.py'
cd /tmp/workspace/abg-pdf && python generate_abg_pdf.py 2>&1
ls -lh /tmp/workspace/abg-pdf/ABG_Analysis_Short_Notes.pdf
ABG Analysis Short Notes
PDF Document · PDF
| Section | Content |
|---|---|
| 1. Normal Values & Interpretation | Reference ranges (pH, PaCO₂, HCO₃⁻, PaO₂, BE, AG), Henderson-Hasselbalch equation, Tintinalli's 6-step method, all 6 compensation formulas, A-a gradient & PaO₂/FiO₂ ratio |
| 2. Metabolic Acidosis (Red) | MUDPILES (high AG), USED CARP (normal AG), pathophysiology (H⁺ gain vs HCO₃⁻ loss), delta-delta ratio, management table |
| 3. Metabolic Alkalosis (Green) | Chloride-responsive vs resistant causes, generation vs maintenance phases, NaCl/KCl therapy, acetazolamide, HCl |
| 4. Respiratory Acidosis (Orange) | 6-category causes (CNS → equipment), acute vs chronic compensation, NIV/BiPAP, O₂ targets for COPD |
| 5. Respiratory Alkalosis (Purple) | CHAMPS mnemonic, acute vs chronic effects, anxiety/hypoxia/sepsis/pregnancy management, salicylate triple disorder |
| 6. Mixed Disorders (Teal) | 8 identification clues, 6 common mixed patterns with clinical settings, delta-delta approach, management principles |
| 7. Quick Reference Table | All 7 disorders side-by-side (pH/PaCO₂/HCO₃⁻/AG/cause/compensation formula) |
| 8. Fluid Management (Blue) | Pandya principles per disorder, IV fluid comparison table (pH, Na⁺, Cl⁻, HCO₃⁻ content, clinical use) |
Make pdf more short note kind and add management in detail based on harrisson book of medicine and tintinalli book of emergency
~/abg-pdf/generate_abg_v2.py
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
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
doc = SimpleDocTemplate(
"/tmp/workspace/abg-pdf/ABG_ShortNotes_v2.pdf",
pagesize=A4,
rightMargin=1.6*cm, leftMargin=1.6*cm,
topMargin=1.8*cm, bottomMargin=1.8*cm,
)
W, H = A4
styles = getSampleStyleSheet()
# ── Colour palette ───────────────────────────────────────────────────────────
NAVY = colors.HexColor("#0D2B55")
BLUE = colors.HexColor("#1A5BB0")
L_BLUE = colors.HexColor("#D6E8F7")
RED = colors.HexColor("#B02020")
L_RED = colors.HexColor("#FDECEA")
GREEN = colors.HexColor("#1A6B3A")
L_GREEN = colors.HexColor("#E6F5EC")
ORANGE = colors.HexColor("#B85C00")
L_ORG = colors.HexColor("#FEF0E6")
PURPLE = colors.HexColor("#5B2C8D")
L_PUR = colors.HexColor("#F3EEF9")
TEAL = colors.HexColor("#0B6B6B")
L_TEAL = colors.HexColor("#E2F4F4")
GOLD = colors.HexColor("#D4A017")
DGREY = colors.HexColor("#2C2C2C")
MGREY = colors.HexColor("#555555")
LGREY = colors.HexColor("#F5F5F5")
WHITE = colors.white
# ── Style factory ────────────────────────────────────────────────────────────
def S(name, **kw):
base = kw.pop("base", "Normal")
return ParagraphStyle(name, parent=styles[base], **kw)
# ── Core styles ───────────────────────────────────────────────────────────────
COVER_TITLE = S("ct", base="Normal", fontSize=24, leading=30, textColor=WHITE,
alignment=TA_CENTER, fontName="Helvetica-Bold")
COVER_SUB = S("cs", base="Normal", fontSize=11, leading=16, textColor=colors.HexColor("#B8D4F0"),
alignment=TA_CENTER, fontName="Helvetica")
COVER_SRC = S("csrc", base="Normal", fontSize=9, leading=13, textColor=GOLD,
alignment=TA_CENTER, fontName="Helvetica-Oblique")
SEC_HDR = S("sh", base="Normal", fontSize=12, leading=16, textColor=WHITE,
fontName="Helvetica-Bold")
SUB_HDR = S("subh", base="Normal", fontSize=10, leading=14, textColor=NAVY,
fontName="Helvetica-Bold", spaceBefore=5, spaceAfter=2)
BODY = S("body", base="Normal", fontSize=9, leading=13, textColor=DGREY,
fontName="Helvetica", spaceAfter=3, alignment=TA_JUSTIFY)
BULLET = S("bul", base="Normal", fontSize=9, leading=13, textColor=DGREY,
fontName="Helvetica", leftIndent=10, spaceAfter=1)
BOLD_BODY = S("bb", base="Normal", fontSize=9, leading=13, textColor=DGREY,
fontName="Helvetica-Bold", spaceAfter=2)
FORMULA = S("form", base="Normal", fontSize=9.5, leading=14, textColor=TEAL,
fontName="Helvetica-Bold", alignment=TA_CENTER, spaceAfter=3)
SMALL = S("sm", base="Normal", fontSize=7.5, leading=11, textColor=MGREY,
fontName="Helvetica-Oblique")
TH = S("th", base="Normal", fontSize=8.5, leading=12, textColor=WHITE,
fontName="Helvetica-Bold")
TD = S("td", base="Normal", fontSize=8.5, leading=12, textColor=DGREY,
fontName="Helvetica")
TD_BOLD = S("tdb", base="Normal", fontSize=8.5, leading=12, textColor=DGREY,
fontName="Helvetica-Bold")
# ── Helper: section header bar ────────────────────────────────────────────────
def hdr(text, col=NAVY, emoji=""):
full = f"{emoji} {text}" if emoji else text
p = Paragraph(full, SEC_HDR)
t = Table([[p]], colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), col),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
]))
return t
# ── Helper: coloured info box ─────────────────────────────────────────────────
def box(items, bg, border):
"""items = list of Paragraph/Spacer flowables"""
t = Table([[items]], colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1.2, border),
("LEFTPADDING", (0,0), (-1,-1), 9),
("RIGHTPADDING", (0,0), (-1,-1), 9),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
return t
# ── Helper: two-col table ─────────────────────────────────────────────────────
def tbl2(rows, c1=4*cm, hdr_bg=NAVY):
c2 = doc.width - c1
data = []
for i, row in enumerate(rows):
if i == 0:
data.append([Paragraph(row[0], TH), Paragraph(row[1], TH)])
else:
data.append([Paragraph(str(row[0]), TD_BOLD), Paragraph(str(row[1]), TD)])
t = Table(data, colWidths=[c1, c2])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), hdr_bg),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGREY]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
return t
# ── Helper: three-col table ───────────────────────────────────────────────────
def tbl3(rows, widths=None, hdr_bg=NAVY):
if widths is None:
w = doc.width / 3
widths = [w, w, w]
data = []
for i, row in enumerate(rows):
if i == 0:
data.append([Paragraph(c, TH) for c in row])
else:
data.append([Paragraph(str(c), TD) for c in row])
t = Table(data, colWidths=widths)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), hdr_bg),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGREY]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
return t
# ── Helper: tag label ─────────────────────────────────────────────────────────
def tag(text, col):
p = Paragraph(f"<b>{text}</b>", S("tag", base="Normal", fontSize=8,
textColor=WHITE, fontName="Helvetica-Bold"))
t = Table([[p]], colWidths=[len(text)*5.5*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), col),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 1),
("BOTTOMPADDING", (0,0), (-1,-1), 1),
]))
return t
def sp(h=0.2):
return Spacer(1, h*cm)
def hr(col=NAVY):
return HRFlowable(width="100%", thickness=0.8, color=col, spaceAfter=4)
# ════════════════════════════════════════════════════════════════════════════════
story = []
# ══════════════════════════════════ COVER ════════════════════════════════════
cover = [
sp(1.2),
Paragraph("ARTERIAL BLOOD GAS (ABG)", COVER_TITLE),
Paragraph("ANALYSIS & INTERPRETATION", COVER_TITLE),
sp(0.3),
HRFlowable(width="55%", thickness=2.5, color=GOLD, spaceAfter=8, hAlign="CENTER"),
Paragraph("Short Notes: ABG Interpretation · Metabolic Acidosis & Alkalosis", COVER_SUB),
Paragraph("Respiratory Acidosis & Alkalosis · Mixed Disorders", COVER_SUB),
Paragraph("Causes · Pathophysiology · Detailed Management", COVER_SUB),
sp(0.5),
Paragraph("Sources:", COVER_SRC),
Paragraph("Harrison's Principles of Internal Medicine, 22nd Edition (2025)", COVER_SRC),
Paragraph("Tintinalli's Emergency Medicine: A Comprehensive Study Guide, 9th Edition", COVER_SRC),
sp(1.2),
]
cover_tbl = Table([[cover]], colWidths=[doc.width + 3.2*cm])
cover_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("LEFTPADDING", (0,0), (-1,-1), -1.6*cm),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("TOPPADDING", (0,0), (-1,-1), 0),
("BOTTOMPADDING", (0,0), (-1,-1), 0),
]))
story.append(cover_tbl)
story.append(sp(0.5))
# ══════════════════ SECTION 1 — ABG BASICS ═══════════════════════════════════
story.append(hdr("1. ABG BASICS — NORMAL VALUES & STEPWISE INTERPRETATION"))
story.append(sp(0.2))
# Normal values compact table
story.append(Paragraph("Normal Reference Values", SUB_HDR))
nv = [
["Parameter", "Normal Range", "Primary Disorder if Abnormal"],
["pH", "7.35 – 7.45", "< 7.35 Acidaemia | > 7.45 Alkalaemia"],
["PaCO₂", "35 – 45 mmHg", "↑ Respiratory Acidosis | ↓ Respiratory Alkalosis"],
["HCO₃⁻", "22 – 26 mEq/L", "↓ Metabolic Acidosis | ↑ Metabolic Alkalosis"],
["PaO₂", "80 – 100 mmHg", "< 60 mmHg = Hypoxaemia"],
["SaO₂", "95 – 100%", "< 90% = Hypoxaemia; requires urgent O₂"],
["Anion Gap", "8 – 12 mEq/L", "AG = Na⁺ − (HCO₃⁻ + Cl⁻). ↑ AG = unmeasured anions"],
["Base Excess", "−2 to +2 mEq/L", "< −2 = Metabolic acidosis; > +2 = Metabolic alkalosis"],
]
story.append(tbl3(nv, widths=[3.2*cm, 3*cm, doc.width - 6.2*cm], hdr_bg=NAVY))
story.append(sp(0.25))
# H-H equation
story.append(box([
Paragraph("<b>Henderson-Hasselbalch:</b> pH = 6.1 + log ( [HCO₃⁻] / 0.03 × PaCO₂ )", FORMULA),
Paragraph("pH is determined by the HCO₃⁻:PaCO₂ ratio. Compensation always moves both in the same direction. "
"Opposing changes = mixed disorder.", BODY),
], L_BLUE, BLUE))
story.append(sp(0.25))
# 6-step interpretation
story.append(Paragraph("6-Step ABG Interpretation (Tintinalli)", SUB_HDR))
steps = [
["Step", "Action"],
["1 — pH", "< 7.35 → Acidaemia. > 7.45 → Alkalaemia. Normal with abnormal HCO₃⁻/PaCO₂ → Mixed disorder."],
["2 — Primary disorder", "↓HCO₃⁻ (with ↓pH) → Metabolic acidosis. ↑PaCO₂ (with ↓pH, normal HCO₃⁻) → Respiratory acidosis."],
["3 — Anion Gap", "AG = Na⁺ − (Cl⁻ + HCO₃⁻). >12 → High AG metabolic acidosis. Normal → Hyperchloraemic/NAGMA."],
["4 — Compensation", "Is compensation appropriate? Use Winter's formula / expected values (Table 1). Deviation → mixed disorder."],
["5 — Delta-Delta (AG only)", "ΔAG / ΔHCO₃⁻: ~1 = pure HAGMA. >1 = HAGMA + metabolic alkalosis. <1 = HAGMA + NAGMA."],
["6 — Clinical correlation", "Always correlate numbers with history, medications, and clinical status. Treat the patient, not the number."],
]
story.append(tbl2(steps, c1=3.2*cm, hdr_bg=NAVY))
story.append(sp(0.25))
# Compensation formulas compact
story.append(Paragraph("Compensation Formulas", SUB_HDR))
comp = [
["Disorder", "Expected Compensation"],
["Metabolic Acidosis", "Winter's: PaCO₂ = 1.5×[HCO₃⁻] + 8 ± 2\nOR: PaCO₂ ↓ 1 mmHg per 1 mEq/L ↓ HCO₃⁻"],
["Metabolic Alkalosis", "PaCO₂ ↑ 0.7 mmHg per 1 mEq/L ↑ HCO₃⁻ (max ~55 mmHg)"],
["Resp. Acidosis — Acute", "HCO₃⁻ ↑ 1 mEq/L per 10 mmHg ↑ PaCO₂"],
["Resp. Acidosis — Chronic", "HCO₃⁻ ↑ 3.5 mEq/L per 10 mmHg ↑ PaCO₂ (3–5 days, renal)"],
["Resp. Alkalosis — Acute", "HCO₃⁻ ↓ 2 mEq/L per 10 mmHg ↓ PaCO₂"],
["Resp. Alkalosis — Chronic", "HCO₃⁻ ↓ 5 mEq/L per 10 mmHg ↓ PaCO₂ (may fully normalise pH)"],
]
story.append(tbl2(comp, c1=4.5*cm, hdr_bg=BLUE))
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════ SECTION 2 — METABOLIC ACIDOSIS ═══════════════════════════
story.append(hdr("2. METABOLIC ACIDOSIS", col=RED))
story.append(sp(0.2))
story.append(box([
Paragraph("↓ HCO₃⁻ (primary) → ↓ pH. Two types: <b>High AG (HAGMA)</b> and <b>Normal AG / Hyperchloraemic (NAGMA)</b>. "
"Respiratory compensation: ↓ PaCO₂ (begins in minutes, max at 12–24 h).", BODY),
], L_RED, RED))
story.append(sp(0.2))
# Causes 2-col
story.append(Paragraph("Causes", SUB_HDR))
mac_causes = [
["HIGH Anion Gap (HAGMA) — MUDPILES", "NORMAL Anion Gap (NAGMA) — Hyperchloraemic"],
["M – Methanol / Metformin lactic acidosis\nU – Uraemia (renal failure — sulphate, phosphate)\n"
"D – DKA / Alcoholic ketoacidosis / Starvation\nP – Propylene glycol / Pyroglutamic acidaemia\n"
"I – Isoniazid / Iron overdose / Ischaemia\nL – Lactic acidosis (Type A: hypoxia; Type B: drugs, liver, malignancy)\n"
"E – Ethylene glycol (oxalic acid → AKI)\nS – Salicylates (early respiratory alk + later HAGMA)",
"Diarrhoea (most common — GI HCO₃⁻ loss)\nRTA Type I (distal — ↓ H⁺ secretion) → low urine pH\n"
"RTA Type II (proximal — HCO₃⁻ wasting) → low serum K⁺\n"
"RTA Type IV (hypoaldosteronism) → high K⁺\n"
"Excess normal saline (hyperchloraemic dilutional)\nCarbonic anhydrase inhibitors (acetazolamide)\n"
"Ureterosigmoidostomy / ileal conduit\nHypoaldosteronism / Addison's disease"],
]
cause_tbl = Table(
[[Paragraph(mac_causes[0][0], TD_BOLD), Paragraph(mac_causes[0][1], TD_BOLD)],
[Paragraph(mac_causes[1][0], TD), Paragraph(mac_causes[1][1], TD)]],
colWidths=[doc.width/2, doc.width/2]
)
cause_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), RED),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
story.append(cause_tbl)
story.append(sp(0.2))
# Pathophysiology
story.append(Paragraph("Pathophysiology (Harrison's)", SUB_HDR))
story.append(box([
Paragraph("<b>Three mechanisms (Harrison's):</b>", BOLD_BODY),
Paragraph("① <b>Endogenous acid overproduction</b> — lactate, ketoacids accumulate and titrate HCO₃⁻ → AG rises.", BULLET),
Paragraph("② <b>Loss of HCO₃⁻</b> — GI losses (diarrhoea) or renal wasting (RTA) → Cl⁻ reabsorbed to maintain electroneutrality → hyperchloraemia, normal AG.", BULLET),
Paragraph("③ <b>Reduced renal H⁺ excretion</b> — CKD → sulphate, phosphate, urate accumulate → AG rises.", BULLET),
sp(0.1),
Paragraph("<b>Systemic effects (Harrison's):</b> ↓ cardiac contractility (direct myocardial depression, though catecholamines compensate early); "
"↓ central and ↑ peripheral vascular compliance → pulmonary oedema risk with volume overload; "
"↓ CNS — headache, lethargy, stupor, coma; glucose intolerance; "
"hyperkalaemia (H⁺/K⁺ exchange, ~0.6 mEq/L rise per 0.1 pH unit fall).", BULLET),
Paragraph("<b>Respiratory compensation (Tintinalli):</b> Chemoreceptors drive Kussmaul hyperventilation. "
"Lowest achievable PaCO₂ ≈ 12 mmHg. Below pH 7.10, respiratory compensation may fail — "
"minute volume paradoxically declines. Mechanical ventilation must then be considered.", BULLET),
], L_RED, RED))
story.append(sp(0.2))
# Management
story.append(Paragraph("Management (Harrison's + Tintinalli)", SUB_HDR))
mac_mgmt = [
["Priority / Step", "Detailed Action"],
["① Treat the Cause\n(FIRST priority)", "DKA: IV insulin 0.1 U/kg/h + 0.9% NaCl 1L/h (first hour) → 0.45% NaCl; add dextrose when BG < 250 mg/dL.\n"
"Lactic acidosis: Improve perfusion — fluids, vasopressors, treat sepsis source.\n"
"Uraemia / AKI: Renal replacement therapy (RRT) if severe.\n"
"Methanol/EG: Fomepizole (4-MP) 15 mg/kg IV load → maintenance; dialysis for severe toxicity.\n"
"Salicylates: IV NaHCO₃ to alkalinise urine (target urine pH 7.5–8), haemodialysis if severe."],
["② IV Fluid\nSelection", "Balanced crystalloids (Plasmalyte/Hartmann's) preferred over 0.9% NaCl to avoid worsening hyperchloraemia.\n"
"0.9% NaCl: Use in DKA initial phase only (first 1–2 L).\n"
"Hartmann's (Ringer's Lactate): Liver converts lactate → HCO₃⁻; safe except in hepatic failure."],
["③ NaHCO₃ Therapy\n(Harrison's — selective)", "Indications: (a) Non-AG (NAGMA) or uraemic acidosis with non-metabolisable anions — target HCO₃⁻ 22 mmol/L.\n"
"(b) DKA with severe acidaemia: pH < 7.00 AND shock — 50 mEq NaHCO₃ in 300 mL saline over 30–45 min (NOT bolus).\n"
"(c) Initial goal in DKA: raise HCO₃⁻ to 10–12 mmol/L and pH to ~7.20 only — do NOT normalise.\n"
"Tintinalli dose: 0.5 mEq/kg per mEq/L HCO₃⁻ rise desired. Target HCO₃⁻ > 8 mEq/L.\n"
"Caution: NaHCO₃ generates CO₂ → worsens hypercapnia if ventilation is inadequate."],
["④ Potassium\nManagement", "Acidosis → hyperkalaemia (H⁺/K⁺ exchange). As pH corrects → K⁺ shifts intracellularly → hypokalaemia.\n"
"Harrison's: Monitor K⁺ closely during NaHCO₃ infusion; supplement KCl as urine output is re-established.\n"
"Tintinalli: In DKA, do NOT start insulin until K⁺ ≥ 3.5 mEq/L (risk fatal hypokalaemia)."],
["⑤ Ventilatory\nSupport", "Tintinalli: If pH < 7.10 and minute ventilation inadequate, start NIV/mechanical ventilation.\n"
"Maintain current PaCO₂ or lower it; do NOT allow PaCO₂ to rise when starting NaHCO₃ without ventilatory support.\n"
"Giving HCO₃⁻ in the presence of hypoventilation converts HCO₃⁻ → CO₂ → acute respiratory acidosis superimposed."],
["⑥ Haemodialysis /\nRRT", "Indications: Severe uraemic acidosis, non-metabolisable anion accumulation (CKD), methanol/EG toxicity, "
"severe acidosis (pH < 7.1) unresponsive to other measures, fluid overload preventing NaHCO₃ use."],
["⑦ Lactic Acidosis\nSpecific", "Type A (hypoperfusion): O₂, fluids, vasopressors, treat cause. NaHCO₃ controversial — may ↑ intracellular CO₂.\n"
"Type B (drugs): Discontinue metformin, linezolid, NRTIs. Thiamine deficiency: give IV thiamine 100 mg."],
]
story.append(tbl2(mac_mgmt, c1=4*cm, hdr_bg=RED))
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════ SECTION 3 — METABOLIC ALKALOSIS ══════════════════════════
story.append(hdr("3. METABOLIC ALKALOSIS", col=GREEN))
story.append(sp(0.2))
story.append(box([
Paragraph("↑ HCO₃⁻ (primary) → ↑ pH. Classified by urine Cl⁻: <b>Chloride-Responsive (uCl⁻ < 20)</b> or "
"<b>Chloride-Resistant (uCl⁻ > 20)</b>. Compensation: hypoventilation → ↑ PaCO₂ (max ~55 mmHg).", BODY),
], L_GREEN, GREEN))
story.append(sp(0.2))
# Causes
story.append(Paragraph("Causes & Pathogenesis (Harrison's)", SUB_HDR))
mak_causes = [
["Chloride-Responsive (urine Cl⁻ < 20 mEq/L)", "Chloride-Resistant (urine Cl⁻ > 20 mEq/L)"],
["Vomiting / NG suction (HCl loss → HCO₃⁻ retention)\nDiuretics — thiazides/loop (Cl⁻, K⁺, volume loss)\nPost-hypercapnic state (chronic resp. acidosis corrected too fast)\nChloride-wasting diarrhoea / villous adenoma\nCystic fibrosis (Cl⁻ wasting in sweat)",
"Primary hyperaldosteronism (Conn's) — autonomous Na⁺ reabsorption, H⁺/K⁺ excretion\nCushing's syndrome / exogenous glucocorticoids\nBartter's syndrome (loop-like — normotensive, ↓K⁺, ↑renin)\nGitelman's syndrome (thiazide-like — hypocalciuria, ↓Mg²⁺)\nRenal artery stenosis / renin-secreting tumour\nExcessive NaHCO₃ / antacids / citrate (massive transfusion)\nSevere hypokalaemia (↑ distal H⁺ secretion)"],
]
mak_tbl = Table(
[[Paragraph(mak_causes[0][0], TD_BOLD), Paragraph(mak_causes[0][1], TD_BOLD)],
[Paragraph(mak_causes[1][0], TD), Paragraph(mak_causes[1][1], TD)]],
colWidths=[doc.width/2, doc.width/2]
)
mak_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), GREEN),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#CCCCCC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
story.append(mak_tbl)
story.append(sp(0.2))
# Pathophysiology
story.append(Paragraph("Pathophysiology (Harrison's)", SUB_HDR))
story.append(box([
Paragraph("<b>Generation phase:</b> HCl loss (vomiting) → HCO₃⁻ not neutralised in bowel → retained in ECF. "
"Alkali intake or Cl⁻/K⁺ depletion generates HCO₃⁻.", BULLET),
Paragraph("<b>Maintenance phase (Harrison's):</b> Normal kidneys rapidly excrete excess HCO₃⁻. Alkalosis is maintained by: "
"(1) <b>Volume/Cl⁻ depletion</b> → ↑ aldosterone → proximal HCO₃⁻ reabsorption ↑; urine Cl⁻ low. "
"(2) <b>Hypokalaemia</b> → ↑ distal H⁺ secretion (K⁺/H⁺ exchange). "
"(3) <b>Excess aldosterone</b> → Na⁺ reabsorption + H⁺ secretion; urine Cl⁻ normal/high.", BULLET),
Paragraph("<b>Clinical effects (Tintinalli):</b> ↓ ionised Ca²⁺ → tetany, carpopedal spasm (Trousseau/Chvostek). "
"Hypokalaemia → muscle weakness, arrhythmias. Left shift O₂-Hb curve → ↓ tissue O₂. "
"Depression of ventilation (serious in COPD). ↓ Mg²⁺, ↓ phosphate.", BULLET),
], L_GREEN, GREEN))
story.append(sp(0.2))
# Management
story.append(Paragraph("Management (Harrison's + Tintinalli)", SUB_HDR))
mak_mgmt = [
["Step", "Detailed Action"],
["① Chloride-Responsive\n(Harrison's)", "IV 0.9% NaCl — restores ECFV + Cl⁻; kidneys then excrete excess HCO₃⁻.\n"
"Volume endpoint: urine Cl⁻ rises > 20 mEq/L (Harrison's criterion for adequate Cl⁻ replacement).\n"
"Start at 100–125 mL/h; adjust to clinical response. Avoid fluid overload."],
["② Potassium Replacement\n(essential step)", "Administer KCl — K⁺ re-enters cells, H⁺ returns to ECF → reduces renal H⁺ secretion.\n"
"Oral KCl preferred if tolerating orally; IV KCl via central line (max 10 mEq/h peripherally, 20 mEq/h central).\n"
"Target K⁺ ≥ 3.5 mEq/L before stopping supplementation. Correct Mg²⁺ deficiency concurrently (↓Mg²⁺ worsens hypokalaemia)."],
["③ Stop Causative Agents", "Cease loop/thiazide diuretics, antacids, NaHCO₃ drips, NG suction (or add PPI/H₂ blocker to reduce HCl production while suction ongoing)."],
["④ Chloride-Resistant\n(Harrison's)", "Saline does NOT correct alkalosis. Treat underlying mineralocorticoid excess:\n"
"Primary hyperaldosteronism: Surgical adrenalectomy (adenoma) or spironolactone 100–400 mg/day (bilateral hyperplasia).\n"
"Cushing's: Treat underlying cause (surgery/ketoconazole).\n"
"Bartter's/Gitelman's: KCl + Mg²⁺ supplementation + NSAIDs (indomethacin for Bartter's) + K⁺-sparing diuretics."],
["⑤ Acetazolamide\n(Tintinalli)", "250–500 mg IV or PO — carbonic anhydrase inhibitor → ↑ renal HCO₃⁻ excretion.\n"
"Use in euvolaemic/hypervolaemic patients (heart failure + metabolic alkalosis from diuretics).\n"
"Contraindicated in volume-depleted patients (worsens contraction alkalosis)."],
["⑥ IV HCl (Severe/Refractory)", "0.1–0.2 N HCl via central venous catheter ONLY. Dose: mEq HCl = 0.2 × wt (kg) × (serum HCO₃⁻ − 24).\n"
"Infuse at 0.1–0.2 mEq/kg/h (max 25 mEq/h). Monitor ABG every 4–6 h. Reserved for severe alkalosis (pH > 7.60) in ICU."],
["⑦ Haemodialysis", "In patients with renal failure or unable to receive large volumes — low-chloride, low-HCO₃⁻ dialysate used."],
]
story.append(tbl2(mak_mgmt, c1=3.8*cm, hdr_bg=GREEN))
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════ SECTION 4 — RESPIRATORY ACIDOSIS ═════════════════════════
story.append(hdr("4. RESPIRATORY ACIDOSIS", col=ORANGE))
story.append(sp(0.2))
story.append(box([
Paragraph("↑ PaCO₂ (primary) → ↓ pH. <b>Acute:</b> HCO₃⁻ ↑ 1 mEq/L / 10 mmHg PaCO₂. "
"<b>Chronic (>48–72 h):</b> HCO₃⁻ ↑ 3.5 mEq/L / 10 mmHg PaCO₂ (renal compensation).", BODY),
], L_ORG, ORANGE))
story.append(sp(0.2))
# Causes
story.append(Paragraph("Causes (Harrison's Classification)", SUB_HDR))
rac_causes = [
["Category", "Examples"],
["CNS Depression\n(↓ drive)", "Opioids, benzodiazepines, barbiturates, anaesthetic agents, stroke/TBI, brainstem lesion, "
"intracranial hypertension, hypothyroidism, sleep apnoea central"],
["Airway Obstruction\n(↑ resistance)", "Status asthmaticus, acute COPD exacerbation, epiglottitis, foreign body aspiration, "
"laryngospasm, OSA, tracheal obstruction"],
["Parenchymal / Alveolar\n(V/Q mismatch)", "ARDS, severe pneumonia, pulmonary oedema, widespread atelectasis, "
"massive pulmonary fibrosis, pneumoconiosis, end-stage emphysema"],
["Chest Wall /\nNeuromuscular", "GBS (Harrison's), myasthenia gravis crisis, poliomyelitis, ALS, cervical cord injury (C3–C5), "
"kyphoscoliosis, flail chest, tension pneumothorax, massive pleural effusion, muscular dystrophies"],
["Obesity /\nMiscellaneous", "Obesity hypoventilation syndrome (Pickwickian — Tintinalli), permissive hypercapnia strategy, "
"barotrauma, iatrogenic (ventilator malfunction)"],
]
story.append(tbl2(rac_causes, c1=3.5*cm, hdr_bg=ORANGE))
story.append(sp(0.2))
# Pathophysiology
story.append(Paragraph("Pathophysiology (Tintinalli + Harrison's)", SUB_HDR))
story.append(box([
Paragraph("<b>CO₂ accumulation:</b> CO₂ + H₂O ⇌ H₂CO₃ ⇌ H⁺ + HCO₃⁻. Rising CO₂ generates H⁺. "
"CO₂ freely crosses BBB → cerebral acidosis + vasodilation → ↑ ICP.", BULLET),
Paragraph("<b>Acute (< 24 h):</b> Non-bicarbonate intracellular buffering (haemoglobin, proteins). "
"Significant acidaemia. Sympathetic activation → early ↑HR, ↑BP; then myocardial depression at severe acidaemia. "
"Each 1 mmHg ↑ PaCO₂ → ↑ [H⁺] by ~1 nmol/L (Tintinalli).", BULLET),
Paragraph("<b>Chronic (>48–72 h):</b> Renal H⁺ excretion ↑ as NH₄⁺; HCO₃⁻ reabsorption ↑. "
"HCO₃⁻ rises 3.5 mEq/L per 10 mmHg → pH partially normalises. "
"COPD: Chemoreceptors become insensitive to CO₂; hypoxic drive becomes primary ventilatory stimulus.", BULLET),
Paragraph("<b>Tintinalli warning:</b> In COPD with chronic PaCO₂ > 60–70 mmHg, high-flow O₂ removes hypoxic drive → "
"PaCO₂ rises abruptly → acute-on-chronic decompensation. Monitor closely.", BULLET),
], L_ORG, ORANGE))
story.append(sp(0.2))
# Management
story.append(Paragraph("Management (Harrison's + Tintinalli)", SUB_HDR))
rac_mgmt = [
["Step", "Detailed Action"],
["① Reverse cause", "Opioid OD: Naloxone 0.4–2 mg IV/IM/IN; repeat q2–3 min (short-acting — repeat dosing or infusion needed).\n"
"Bronchospasm: Salbutamol 2.5–5 mg nebulised + ipratropium 0.5 mg + IV methylprednisolone 1 mg/kg.\n"
"Pneumothorax: Needle decompression then chest drain. Effusion: Thoracocentesis/drain.\n"
"NMJ blockade reversal: Neostigmine (if non-depolarising agent used)."],
["② O₂ Therapy\n(Tintinalli)", "COPD / known chronic hypercapnia: Target SpO₂ 88–92% (controlled O₂). Titrate 24–28% via Venturi mask.\n"
"Acute hypercapnia without prior hypercapnia: Target SpO₂ 94–98%. Do NOT withhold O₂ for severe hypoxaemia."],
["③ Non-Invasive\nVentilation (NIV)", "BiPAP: IPAP 10–20 cmH₂O / EPAP 4–6 cmH₂O. First-line for:\n"
"- COPD exacerbation (reduces intubation rate + mortality — Tintinalli)\n"
"- Obesity hypoventilation syndrome\n"
"- Acute cardiogenic pulmonary oedema\n"
"Contraindications: inability to protect airway, haemodynamic instability, uncooperative patient, facial trauma."],
["④ Intubation + MV\nIndications", "Failing NIV or declining mental status. Respiratory arrest. Haemodynamic instability.\n"
"RSI: ketamine (2 mg/kg) or etomidate (0.3 mg/kg) + succinylcholine (1.5 mg/kg).\n"
"Ventilator settings: Tidal volume 6–8 mL/kg IBW; RR 12–16/min; titrate to patient's baseline PaCO₂ (not necessarily 40)."],
["⑤ Rate of\nPaCO₂ Correction", "Tintinalli: In chronic respiratory acidosis, do NOT lower PaCO₂ > 5 mmHg/h.\n"
"Rapid correction → sudden metabolic alkalosis → arrhythmias, ↓ ionised Ca²⁺, ↓ K⁺."],
["⑥ Avoid NaHCO₃", "NaHCO₃ generates CO₂ (HCO₃⁻ + H⁺ → CO₂ + H₂O) → worsens hypercapnia if ventilation is inadequate. Contraindicated."],
["⑦ Treat COPD\nExacerbation", "Salbutamol + ipratropium nebulisers. IV/PO prednisolone 40 mg × 5 days. "
"Antibiotics if purulent sputum (amoxicillin, doxycycline, or azithromycin). NIV if pH < 7.35 with PaCO₂ > 45."],
]
story.append(tbl2(rac_mgmt, c1=3.8*cm, hdr_bg=ORANGE))
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════ SECTION 5 — RESPIRATORY ALKALOSIS ════════════════════════
story.append(hdr("5. RESPIRATORY ALKALOSIS", col=PURPLE))
story.append(sp(0.2))
story.append(box([
Paragraph("↓ PaCO₂ (primary) → ↑ pH. Most common acid-base disorder in ICU (Harrison's). "
"<b>Acute:</b> HCO₃⁻ ↓ 2 mEq/L / 10 mmHg. <b>Chronic:</b> HCO₃⁻ ↓ 5 mEq/L / 10 mmHg. "
"Chronic resp. alkalosis is unique — pH may fully normalise (Harrison's).", BODY),
], L_PUR, PURPLE))
story.append(sp(0.2))
# Causes
story.append(Paragraph("Causes (Harrison's Classification)", SUB_HDR))
rak_causes = [
["Category", "Examples"],
["A. CNS stimulation\n(↑ central drive)", "Anxiety/psychogenic hyperventilation, pain, meningitis/encephalitis, stroke, tumour, "
"head trauma, fever, salicylate toxicity (direct stimulation of resp. centre)"],
["B. Hypoxaemia-driven\n(peripheral chemoreceptors)", "Pulmonary embolism, pneumonia, altitude (hypobaric hypoxia), "
"severe anaemia, high-output cardiac failure, early ARDS"],
["C. Pulmonary\nreceptor stimulation", "Pulmonary oedema (J-receptor activation), pulmonary fibrosis/ILD, "
"pulmonary hypertension, haemothorax, flail chest, cardiac failure"],
["D. Physiological /\nHormonal", "Pregnancy (progesterone → ↑ central sensitivity to CO₂ — Harrison's), sepsis/SIRS (early), "
"liver failure (↑ progesterone, CNS stimulation), thyrotoxicosis, heat exposure"],
["E. Iatrogenic", "Mechanical ventilation — excessive RR or VT settings, recovery from metabolic acidosis"],
]
story.append(tbl2(rak_causes, c1=3.5*cm, hdr_bg=PURPLE))
story.append(sp(0.2))
# Pathophysiology
story.append(Paragraph("Pathophysiology (Tintinalli + Harrison's)", SUB_HDR))
story.append(box([
Paragraph("<b>CO₂ washout:</b> ↑ Alveolar ventilation → ↓ CO₂ → ↓ H₂CO₃ → ↓ H⁺ → ↑ pH.", BULLET),
Paragraph("<b>Acute effects (Tintinalli):</b> ↓ [H⁺] → anionic proteins (albumin) bind Ca²⁺ instead of H⁺ → "
"↓ ionised Ca²⁺ → tetany, paraesthesia, carpopedal spasm, perioral numbness. "
"Cerebral vasoconstriction → ↓ CBF → dizziness, syncope, confusion. "
"Coronary vasoconstriction in severe cases.", BULLET),
Paragraph("<b>Chronic compensation (Harrison's):</b> Kidneys ↓ H⁺ secretion → bicarbonaturia → ↓ HCO₃⁻. "
"Requires 6–72 h to begin, ≥1 week to fully normalise pH. Compensation can be complete (unlike other disorders).", BULLET),
Paragraph("<b>Hypokalaemia:</b> K⁺ shifts intracellularly as pH rises. Arrhythmias in cardiac-compromised patients.", BULLET),
], L_PUR, PURPLE))
story.append(sp(0.2))
# Management
story.append(Paragraph("Management (Tintinalli + Harrison's)", SUB_HDR))
rak_mgmt = [
["Step", "Detailed Action"],
["① Treat Cause\n(always first)", "PE: Anticoagulation (heparin/LMWH); thrombolysis if haemodynamically unstable.\n"
"Pneumonia/Sepsis: Antibiotics + source control + fluid resuscitation.\n"
"High altitude: Descent; supplemental O₂; acetazolamide 250 mg BD prophylaxis.\n"
"Liver failure: Lactulose, rifaximin, transplant evaluation."],
["② Psychogenic /\nAnxiety (Tintinalli)", "Reassurance + rebreathing (paper bag) if organic cause excluded — raises PaCO₂.\n"
"Benzodiazepine if severe: lorazepam 0.5–1 mg IV/IM.\n"
"Anxiolytic or antidepressant if chronic psychogenic hyperventilation disorder."],
["③ Correct Hypoxaemia", "Supplemental O₂ to target SpO₂ 94–98% — removes hypoxic stimulus → PaCO₂ normalises.\n"
"Nasal cannula 2–4 L/min for mild; high-flow O₂ or NIV for severe (ARDS, pulmonary oedema)."],
["④ Mechanically\nVentilated Patients", "Reduce respiratory rate (target 12–14/min) and/or tidal volume.\n"
"Add mechanical dead space if needed to raise PaCO₂.\n"
"Check patient–ventilator synchrony; treat pain and agitation (reduces respiratory drive)."],
["⑤ Salicylate Toxicity\n(Special — mixed disorder)", "IV NaHCO₃ to alkalinise urine (pH 7.5–8.0) → traps ionised salicylate in urine → ↑ excretion.\n"
"Haemodialysis: salicylate > 100 mg/dL, severe acidaemia, AKI, pulmonary oedema, altered consciousness.\n"
"Monitor for coexisting HAGMA (late presentation)."],
["⑥ Symptomatic Ca²⁺\nReplacement", "Tetany: IV calcium gluconate 10 mL of 10% solution over 10 min.\n"
"Repeat if no response. Treat underlying alkalosis to prevent recurrence."],
["⑦ Hypokalaemia", "Replace K⁺ orally or IV (as per severity). Correct Mg²⁺ if deficient (prevents refractory hypokalaemia)."],
]
story.append(tbl2(rak_mgmt, c1=3.8*cm, hdr_bg=PURPLE))
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════ SECTION 6 — MIXED DISORDERS ══════════════════════════════
story.append(hdr("6. MIXED ACID-BASE DISORDERS", col=TEAL))
story.append(sp(0.2))
story.append(box([
Paragraph("<b>Definition (Harrison's):</b> Two or more independently coexisting primary disorders — NOT compensatory responses. "
"Common in critically ill patients; can cause dangerous extremes of pH. "
"Diagnosis requires systematic application of compensation formulas + AG calculation + delta-delta ratio.", BODY),
], L_TEAL, TEAL))
story.append(sp(0.2))
# How to identify
story.append(Paragraph("How to Diagnose Mixed Disorders", SUB_HDR))
mix_id = [
["Clue", "Interpretation (Tintinalli + Harrison's)"],
["pH normal + HCO₃⁻ ↓ + PaCO₂ ↓", "Metabolic acidosis + Respiratory alkalosis (opposing — cancel each other out)"],
["pH normal + HCO₃⁻ ↑ + PaCO₂ ↑", "Metabolic alkalosis + Respiratory acidosis (opposing)"],
["↑ HCO₃⁻ and ↓ PaCO₂ (or vice versa)", "ANY time HCO₃⁻ and PaCO₂ move in OPPOSITE directions = mixed disorder (Harrison's)"],
["Measured PaCO₂ > Winter's predicted", "Superimposed respiratory acidosis on metabolic acidosis"],
["Measured PaCO₂ < Winter's predicted", "Superimposed respiratory alkalosis on metabolic acidosis"],
["Δ-Δ ratio > 2 (ΔAG >> ΔHCO₃⁻)", "HAGMA + concomitant metabolic alkalosis (HCO₃⁻ less reduced than expected)"],
["Δ-Δ ratio < 1 (ΔAG << ΔHCO₃⁻)", "HAGMA + concomitant normal-AG metabolic acidosis (HCO₃⁻ more reduced than expected)"],
["pH near-normal; AG = 23 (example Tintinalli)", "Wide AG acidosis masked by coexisting metabolic alkalosis — check AG on all ABGs!"],
]
story.append(tbl2(mix_id, c1=4.8*cm, hdr_bg=TEAL))
story.append(sp(0.2))
# Common patterns
story.append(Paragraph("Common Mixed Disorder Patterns (Harrison's Table 58-2)", SUB_HDR))
mix_pat = [
["Mixed Disorder", "Clinical Setting", "Management Highlights"],
["Met. Acidosis\n+\nResp. Alkalosis", "Sepsis (commonest), salicylate OD, hepatic failure, PE",
"Treat underlying cause (sepsis, PE). Both abnormalities may cancel → pH near-normal. "
"Respiratory alkalosis may mask severity of metabolic acidosis."],
["Met. Alkalosis\n+\nResp. Acidosis", "COPD + diuretics (most common), post-op NG suction + hypoventilation",
"Correct metabolic alkalosis (KCl + NaCl) + treat respiratory cause (NIV). "
"pH may be near-normal. Common 'silent' combination."],
["Met. Acidosis\n+\nResp. Acidosis", "Cardiac arrest, severe septic shock + respiratory failure, overdose (opioid + aspirin)",
"Most dangerous — additive acidaemia. Immediate: intubation + ventilation + resuscitation. "
"Address both components simultaneously. NaHCO₃ only after securing ventilation."],
["Met. Alkalosis\n+\nResp. Alkalosis", "Cirrhosis + diuretics, pregnancy + vomiting, ICU NG suction + mechanical hyperventilation",
"Most severe alkalaemia. Stop causative agents. KCl + NaCl. Reduce ventilator rate. "
"IV Ca²⁺ for tetany. Acetazolamide if euvolaemic."],
["HAGMA + Met. Alkalosis\n(Δ-Δ > 2)", "DKA + vomiting, lactic acidosis + diuretics, severe vomiting + CKD",
"Treat both: correct ketosis/lactataemia AND replenish Cl⁻/K⁺. "
"HCO₃⁻ appears falsely adequate — do not underestimate severity."],
["Salicylate Triple\n(HAGMA + NAGMA + Resp. Alk.)", "Salicylate toxicity (classic — Harrison's)",
"Alkalinise urine (NaHCO₃ infusion). Haemodialysis if severe. Monitor coexisting NAGMA from RTA-like effect."],
]
story.append(tbl3(mix_pat, widths=[3.5*cm, 4.5*cm, doc.width - 8*cm], hdr_bg=TEAL))
story.append(sp(0.25))
# Management principles
story.append(Paragraph("Management Principles for Mixed Disorders", SUB_HDR))
story.append(box([
Paragraph("1. <b>Treat the most dangerous pH deviation first</b> — the component causing pH extremes (< 7.1 or > 7.55) threatens life.", BULLET),
Paragraph("2. <b>Never give NaHCO₃ in acidosis + hypoventilation</b> without securing ventilation first — it generates CO₂ and worsens hypercapnia.", BULLET),
Paragraph("3. <b>Sequential re-assessment</b> — resolving one disorder unmasks the other. Repeat ABG after each intervention.", BULLET),
Paragraph("4. <b>Always calculate AG</b> on every ABG — a 'normal' pH with elevated AG = hidden metabolic acidosis + coexisting alkalosis.", BULLET),
Paragraph("5. <b>Electrolytes are essential</b> — check K⁺, Na⁺, Cl⁻, Mg²⁺, phosphate. Correct all deficiencies.", BULLET),
], L_TEAL, TEAL))
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════ SECTION 7 — QUICK SUMMARY TABLE ══════════════════════════
story.append(hdr("7. QUICK-REFERENCE SUMMARY", col=NAVY))
story.append(sp(0.2))
aw = doc.width
summary = [
["Disorder", "pH", "PaCO₂", "HCO₃⁻", "AG", "Key Cause", "1st-Line Rx"],
["Met. Acidosis\n(High AG)", "↓", "↓comp", "↓↓primary", "↑", "DKA, lactic, uraemia, toxins", "Treat cause; selective NaHCO₃"],
["Met. Acidosis\n(Normal AG)", "↓", "↓comp", "↓↓primary", "Normal", "Diarrhoea, RTA, excess NaCl", "NaHCO₃ if non-metabolisable anions; NaCl if NAGMA"],
["Met. Alkalosis", "↑", "↑comp", "↑↑primary", "Normal", "Vomiting, diuretics, hyperaldo", "0.9% NaCl + KCl (Cl-responsive); spironolactone (Cl-resistant)"],
["Resp. Acidosis\nAcute", "↓", "↑↑primary", "↑1mEq/10", "Normal", "Opioids, asthma, NM disease", "Naloxone; bronchodilators; NIV/intubation"],
["Resp. Acidosis\nChronic", "↓mild", "↑↑primary", "↑3.5/10", "Normal", "COPD, OHS", "NIV (BiPAP); controlled O₂ 88–92%; treat exacerbation"],
["Resp. Alkalosis\nAcute", "↑", "↓↓primary", "↓2mEq/10", "Normal", "Anxiety, PE, sepsis, pain", "Treat cause; O₂ for hypoxaemia; rebreathing (psychogenic)"],
["Resp. Alkalosis\nChronic", "↑mild", "↓↓primary", "↓5mEq/10", "Normal", "Pregnancy, hepatic, altitude", "Treat underlying; pH may normalise fully"],
]
cws = [2.8*cm, 1.2*cm, 2*cm, 2*cm, 1.5*cm, 3.5*cm, aw-13*cm]
sdata = []
for i, row in enumerate(summary):
if i == 0:
sdata.append([Paragraph(c, TH) for c in row])
else:
sdata.append([Paragraph(c, S(f"td{i}", base="Normal", fontSize=8, leading=11)) for c in row])
st = Table(sdata, colWidths=cws)
st.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#AAAAAA")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LGREY]),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
]))
story.append(st)
story.append(sp(0.3))
# ── HCO3 Deficit formula box ──────────────────────────────────────────────────
story.append(box([
Paragraph("<b>Useful Formulas at a Glance</b>", BOLD_BODY),
Paragraph("AG = Na⁺ − (Cl⁻ + HCO₃⁻) | Normal AG = 8–12. Correct for albumin: AG corrected = AG + 2.5 × (4.5 − albumin g/dL)", BULLET),
Paragraph("Delta-Delta = ΔAG / ΔHCO₃⁻ = (AG − 12) / (24 − HCO₃⁻). ~1 pure HAGMA | >2 = +Met. Alk. | <1 = +NAGMA", BULLET),
Paragraph("Winter's formula: Expected PaCO₂ = 1.5 × [HCO₃⁻] + 8 ± 2 (for metabolic acidosis)", BULLET),
Paragraph("NaHCO₃ dose: mEq = 0.5 × weight (kg) × (target HCO₃⁻ − actual HCO₃⁻) | Give 50% over 4–6 h then re-assess", BULLET),
Paragraph("A-a gradient = PAO₂ − PaO₂ | PAO₂ = (FiO₂ × 713) − PaCO₂/0.8 | Normal < 15 mmHg (young) | Age/4 + 4", BULLET),
Paragraph("PaO₂ / FiO₂ ratio: Normal ~600 (on 40% O₂) | < 300 = ALI | < 200 = ARDS", BULLET),
], L_BLUE, NAVY))
story.append(sp(0.25))
# Footer
story.append(hr(NAVY))
story.append(Paragraph(
"Sources: Harrison's Principles of Internal Medicine, 22nd Edition (McGraw-Hill, 2025) · "
"Tintinalli's Emergency Medicine: A Comprehensive Study Guide, 9th Edition (McGraw-Hill, 2020). "
"Short-note reference for educational purposes. Always verify doses and protocols against current guidelines and institutional protocols.",
S("footer", base="Normal", fontSize=7, textColor=MGREY, leading=10, alignment=TA_CENTER)
))
# ── BUILD ─────────────────────────────────────────────────────────────────────
doc.build(story)
print("Done: /tmp/workspace/abg-pdf/ABG_ShortNotes_v2.pdf")
cd /tmp/workspace/abg-pdf && python generate_abg_v2.py 2>&1
ls -lh /tmp/workspace/abg-pdf/ABG_ShortNotes_v2.pdf
ABG ShortNotes v2
PDF Document · PDF
| Feature | V1 | V2 (this) |
|---|---|---|
| Format | Long paragraphs + wide boxes | Compact bullet tables throughout |
| Management depth | Generic steps | Detailed drug doses, specific protocols |
| Harrison's content | Limited | Full pathophysiology + treatment criteria per disorder |
| Tintinalli content | Full | Retained + integrated with Harrison's |
| NaHCO₃ guidance | Brief | Harrison's exact criteria: pH < 7.00 for DKA; dose formula; timing |
| COPD O₂ warning | Yes | Tintinalli detail: PaCO₂ > 60–70 → hypoxic drive → exact SpO₂ targets |
| Mixed disorders | General | Harrison's Table 58-2 patterns + delta-delta ratios |
| RSI drugs | No | Added: ketamine/etomidate + succinylcholine doses |
| Salicylate triple disorder | Brief | Full workup + dialysis criteria |
| Quick-ref summary | Full-page table | Single compact page with all 7 disorders |
| Formulas cheat sheet | Spread out | Consolidated box at end: AG correction, delta-delta, Winter's, A-a gradient |