Metabolic Acidosis pdf

Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Running Command

mkdir -p /home/daytona/workspace/metabolic-acidosis && ls /home/daytona/workspace/metabolic-acidosis/

Writing File

~/metabolic-acidosis/generate_pdf.py

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

OUTPUT = "/home/daytona/workspace/metabolic-acidosis/Metabolic_Acidosis.pdf"

# Colors
DARK_BLUE = HexColor("#1a3a5c")
MID_BLUE = HexColor("#2c6496")
LIGHT_BLUE = HexColor("#d6e8f7")
ACCENT = HexColor("#e74c3c")
LIGHT_GRAY = HexColor("#f5f5f5")
BORDER_GRAY = HexColor("#cccccc")
GREEN = HexColor("#27ae60")
ORANGE = HexColor("#e67e22")

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2*cm, bottomMargin=2*cm
)

styles = getSampleStyleSheet()

# Custom styles
title_style = ParagraphStyle(
    'CustomTitle', fontSize=26, textColor=white,
    fontName='Helvetica-Bold', alignment=TA_CENTER, leading=32,
    spaceAfter=6
)
subtitle_style = ParagraphStyle(
    'Subtitle', fontSize=12, textColor=LIGHT_BLUE,
    fontName='Helvetica', alignment=TA_CENTER, leading=16
)
h1_style = ParagraphStyle(
    'H1', fontSize=16, textColor=white,
    fontName='Helvetica-Bold', alignment=TA_LEFT, leading=20,
    spaceBefore=14, spaceAfter=6,
    leftIndent=0, rightIndent=0,
    backColor=MID_BLUE,
    borderPad=(6, 8, 6, 8)
)
h2_style = ParagraphStyle(
    'H2', fontSize=13, textColor=DARK_BLUE,
    fontName='Helvetica-Bold', alignment=TA_LEFT, leading=17,
    spaceBefore=12, spaceAfter=4,
    borderPad=4
)
h3_style = ParagraphStyle(
    'H3', fontSize=11, textColor=MID_BLUE,
    fontName='Helvetica-Bold', alignment=TA_LEFT, leading=14,
    spaceBefore=8, spaceAfter=3
)
body_style = ParagraphStyle(
    'Body', fontSize=10, textColor=black,
    fontName='Helvetica', alignment=TA_JUSTIFY, leading=15,
    spaceAfter=6
)
bullet_style = ParagraphStyle(
    'Bullet', fontSize=10, textColor=black,
    fontName='Helvetica', alignment=TA_LEFT, leading=14,
    leftIndent=16, spaceAfter=3,
    bulletIndent=6
)
formula_style = ParagraphStyle(
    'Formula', fontSize=10.5, textColor=DARK_BLUE,
    fontName='Helvetica-Bold', alignment=TA_CENTER, leading=14,
    spaceAfter=6, spaceBefore=4,
    backColor=LIGHT_BLUE, borderPad=8,
    borderColor=MID_BLUE, borderWidth=1,
    leftIndent=20, rightIndent=20
)
caption_style = ParagraphStyle(
    'Caption', fontSize=9, textColor=HexColor("#555555"),
    fontName='Helvetica-Oblique', alignment=TA_CENTER, leading=12
)
source_style = ParagraphStyle(
    'Source', fontSize=8, textColor=HexColor("#777777"),
    fontName='Helvetica', alignment=TA_LEFT, leading=11,
    spaceAfter=2
)
warning_style = ParagraphStyle(
    'Warning', fontSize=10, textColor=HexColor("#7d2020"),
    fontName='Helvetica', alignment=TA_LEFT, leading=14,
    leftIndent=8, spaceAfter=3
)

def section_header(text):
    """Returns a blue section header paragraph."""
    return Paragraph(f"  {text}", h1_style)

def make_key_box(content_rows, bg=LIGHT_BLUE, border=MID_BLUE):
    """Renders a shaded key-fact box as a 1-col table."""
    cells = [[Paragraph(row, bullet_style)] for row in content_rows]
    t = Table(cells, colWidths=[16.5*cm])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), bg),
        ('BOX', (0,0), (-1,-1), 1, border),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 10),
    ]))
    return t

story = []

# ── COVER BANNER ─────────────────────────────────────────────────────────────
cover = Table(
    [[Paragraph("METABOLIC ACIDOSIS", title_style)],
     [Paragraph("A Comprehensive Clinical Reference", subtitle_style)],
     [Paragraph("Pathophysiology • Classification • Diagnosis • Management", subtitle_style)]],
    colWidths=[16.5*cm]
)
cover.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,-1), DARK_BLUE),
    ('BOX', (0,0), (-1,-1), 2, MID_BLUE),
    ('TOPPADDING', (0,0), (-1,-1), 18),
    ('BOTTOMPADDING', (0,0), (-1,-1), 18),
    ('LEFTPADDING', (0,0), (-1,-1), 12),
]))
story.append(cover)
story.append(Spacer(1, 0.5*cm))
story.append(Paragraph(
    "Sources: Harrison's Principles of Internal Medicine 22E (2025) | Rosen's Emergency Medicine | "
    "Barash's Clinical Anesthesia 9E | Frameworks for Internal Medicine | Brenner & Rector's The Kidney",
    source_style
))
story.append(HRFlowable(width="100%", thickness=1, color=BORDER_GRAY))
story.append(Spacer(1, 0.3*cm))

# ── 1. DEFINITION & OVERVIEW ──────────────────────────────────────────────────
story.append(section_header("1.  Definition & Overview"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "Metabolic acidosis is an acid-base disorder characterized by a primary decrease in serum bicarbonate "
    "(HCO<sub rise='3'>3</sub><sup>−</sup>) concentration, resulting in a fall in arterial blood pH. "
    "It arises either from gain of non-volatile acid (which consumes HCO<sub rise='3'>3</sub><sup>−</sup>) "
    "or from direct loss of bicarbonate from the body. Unlike respiratory acidosis, the primary disturbance "
    "is metabolic rather than ventilatory.", body_style
))
story.append(Paragraph(
    "The physiological response is compensatory hyperventilation (Kussmaul respiration), which lowers "
    "PaCO<sub rise='2'>2</sub> and partially restores pH toward normal. Complete normalization of pH does not "
    "occur through respiratory compensation alone.", body_style
))

key_facts = [
    "• Normal serum HCO<sub rise='3'>3</sub><sup>−</sup>: 22–26 mEq/L",
    "• Normal arterial pH: 7.35–7.45",
    "• Metabolic acidosis: HCO<sub rise='3'>3</sub><sup>−</sup> &lt; 22 mEq/L with pH &lt; 7.35",
    "• Anion gap (AG) = Na<sup>+</sup> − (Cl<sup>−</sup> + HCO<sub rise='3'>3</sub><sup>−</sup>)   |   Normal AG: 6–12 mEq/L (avg ~10 mEq/L)",
]
story.append(make_key_box(key_facts))
story.append(Spacer(1, 0.3*cm))

# ── 2. PATHOPHYSIOLOGY ────────────────────────────────────────────────────────
story.append(section_header("2.  Pathophysiology"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "The body normally generates ~1 mEq/kg/day of non-volatile acid from protein catabolism and cellular "
    "metabolism. These are excreted by the kidneys as titratable acid (primarily phosphate) and ammonium "
    "(NH<sub rise='4'>4</sub><sup>+</sup>). Disruption of this balance leads to acid accumulation.", body_style
))

story.append(Paragraph("Buffering Systems", h3_style))
story.append(Paragraph(
    "Excess H<sup>+</sup> is initially buffered by extracellular bicarbonate, intracellular proteins, "
    "hemoglobin, and phosphate. The Henderson-Hasselbalch equation governs the relationship:", body_style
))
story.append(Paragraph(
    "pH = 6.1 + log([HCO3<sup>−</sup>] / 0.03 × PaCO2)",
    formula_style
))

story.append(Paragraph("Respiratory Compensation (Winters' Formula)", h3_style))
story.append(Paragraph(
    "In metabolic acidosis, peripheral and central chemoreceptors detect the fall in pH and stimulate "
    "increased ventilation. The expected compensatory PaCO<sub rise='2'>2</sub> is predicted by Winters' formula:", body_style
))
story.append(Paragraph(
    "Expected PaCO2 = (1.5 × [HCO3<sup>−</sup>]) + 8 ± 2  mmHg",
    formula_style
))
story.append(Paragraph(
    "If measured PaCO<sub rise='2'>2</sub> is <b>higher</b> than predicted → concurrent <b>respiratory acidosis</b>. "
    "If <b>lower</b> → concurrent <b>respiratory alkalosis</b>.",
    body_style
))
story.append(Spacer(1, 0.3*cm))

# ── 3. CLASSIFICATION ─────────────────────────────────────────────────────────
story.append(section_header("3.  Classification by Anion Gap"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "The anion gap is the cornerstone of metabolic acidosis classification. "
    "It represents unmeasured anions in plasma (albumin, phosphate, sulfate, organic anions). "
    "Always <b>correct for hypoalbuminemia</b>: add 2.5 mEq/L to the AG for each 1 g/dL that albumin "
    "falls below 4.5 g/dL.", body_style
))

story.append(Paragraph(
    "Corrected AG = Measured AG + 2.5 × (4.5 − serum albumin [g/dL])",
    formula_style
))

# Classification table
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Table 1: Classification of Metabolic Acidosis", h2_style))
class_data = [
    [Paragraph("<b>Feature</b>", body_style),
     Paragraph("<b>High AG (Wide AG)</b>", body_style),
     Paragraph("<b>Normal AG (Hyperchloremic)</b>", body_style)],
    [Paragraph("AG threshold", body_style),
     Paragraph("> 12–13 mEq/L", body_style),
     Paragraph("≤ 12 mEq/L", body_style)],
    [Paragraph("Chloride", body_style),
     Paragraph("Normal", body_style),
     Paragraph("Elevated (hyperchloremia)", body_style)],
    [Paragraph("Mechanism", body_style),
     Paragraph("Accumulation of unmeasured anions", body_style),
     Paragraph("Loss of HCO3− or impaired acid excretion", body_style)],
    [Paragraph("Key mnemonic", body_style),
     Paragraph("MUDPILES", body_style),
     Paragraph("HARDUP", body_style)],
]
ct = Table(class_data, colWidths=[4.5*cm, 6*cm, 6*cm])
ct.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), MID_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('BACKGROUND', (0,1), (-1,-1), LIGHT_GRAY),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_GRAY]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
]))
story.append(ct)
story.append(Spacer(1, 0.3*cm))

# ── 4. HIGH AG ACIDOSIS ───────────────────────────────────────────────────────
story.append(section_header("4.  High Anion Gap Metabolic Acidosis"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "A high-AG acidosis results from accumulation of acid anions that replace bicarbonate but are not "
    "measured in the standard electrolyte panel. There are four principal categories:", body_style
))

# MUDPILES table
story.append(Paragraph("Mnemonic: MUDPILES", h2_style))
mudpiles_data = [
    [Paragraph("<b>Letter</b>", body_style), Paragraph("<b>Cause</b>", body_style), Paragraph("<b>Accumulated Anion / Notes</b>", body_style)],
    [Paragraph("M", body_style), Paragraph("Methanol", body_style), Paragraph("Formate; causes visual disturbance, high osmolar gap", body_style)],
    [Paragraph("U", body_style), Paragraph("Uremia (kidney failure)", body_style), Paragraph("Sulfate, phosphate, hippurate; nonmetabolizable", body_style)],
    [Paragraph("D", body_style), Paragraph("Diabetic / Alcoholic / Starvation Ketoacidosis", body_style), Paragraph("β-hydroxybutyrate, acetoacetate; metabolizable", body_style)],
    [Paragraph("P", body_style), Paragraph("Paraldehyde / Propylene glycol / Paracetamol (acetaminophen)", body_style), Paragraph("Organic acids; drug toxicity", body_style)],
    [Paragraph("I", body_style), Paragraph("Iron / Isoniazid", body_style), Paragraph("Lactic acidosis (secondary); overdose scenarios", body_style)],
    [Paragraph("L", body_style), Paragraph("Lactic acidosis", body_style), Paragraph("L-lactate; most common cause (~50% of wide-AG cases)", body_style)],
    [Paragraph("E", body_style), Paragraph("Ethylene glycol", body_style), Paragraph("Glycolate, oxalate; renal failure, oxalate crystaluria", body_style)],
    [Paragraph("S", body_style), Paragraph("Salicylates", body_style), Paragraph("Salicylate anion; also causes respiratory alkalosis", body_style)],
]
mt = Table(mudpiles_data, colWidths=[1.5*cm, 5.5*cm, 9.5*cm])
mt.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_BLUE]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
    ('TEXTCOLOR', (0,1), (0,-1), ACCENT),
]))
story.append(mt)
story.append(Spacer(1, 0.3*cm))

story.append(Paragraph("4.1  Lactic Acidosis", h2_style))
story.append(Paragraph(
    "Lactic acidosis is the <b>most common</b> cause of high-AG metabolic acidosis. Plasma L-lactate "
    "rises when tissue oxygen delivery is insufficient (Type A) or when mitochondrial metabolism is "
    "impaired (Type B).", body_style
))

lactic_data = [
    [Paragraph("<b>Type A (Tissue Hypoperfusion)</b>", body_style),
     Paragraph("<b>Type B (Impaired Metabolism)</b>", body_style)],
    [Paragraph(
        "• Shock (septic, cardiogenic, hypovolemic)\n"
        "• Severe hypoxemia\n"
        "• Mesenteric ischemia\n"
        "• Carbon monoxide poisoning",
        body_style),
     Paragraph(
        "• Metformin toxicity\n"
        "• Hepatic failure\n"
        "• Malignancy (Warburg effect)\n"
        "• Nucleoside reverse-transcriptase inhibitors\n"
        "• Cyanide poisoning",
        body_style)],
]
lt = Table(lactic_data, colWidths=[8.25*cm, 8.25*cm])
lt.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), LIGHT_BLUE),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 8),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(lt)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "Treatment of lactic acidosis focuses on <b>correcting the underlying cause</b> (restoring perfusion, "
    "stopping offending drugs). Sodium bicarbonate is not recommended routinely; it may paradoxically worsen "
    "intracellular acidosis. Consider NaHCO<sub rise='3'>3</sub> only if pH &lt;7.1 with hemodynamic instability.",
    body_style
))

story.append(Paragraph("4.2  Ketoacidosis", h2_style))
story.append(Paragraph(
    "Ketoacidosis occurs when insulin deficiency and glucagon excess drive hepatic fatty acid oxidation "
    "to produce ketone bodies (β-hydroxybutyrate, acetoacetate). Three forms:", body_style
))
keto_rows = [
    "• <b>Diabetic ketoacidosis (DKA)</b>: Most common. Glucose typically &gt;250 mg/dL; absolute or relative insulin deficiency.",
    "• <b>Alcoholic ketoacidosis (AKA)</b>: After binge drinking + starvation; glucose normal or low; β-hydroxybutyrate dominant.",
    "• <b>Starvation ketoacidosis</b>: Mild; occurs after prolonged fasting; rarely severe.",
]
story.append(make_key_box(keto_rows))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph(
    "Bicarbonate therapy in DKA is reserved for patients with pH &lt;7.00 and/or evidence of shock: "
    "50 mEq NaHCO<sub rise='3'>3</sub> in 300 mL saline over 30–45 min. Target HCO<sub rise='3'>3</sub><sup>−</sup> "
    "of 10–12 mEq/L and pH ~7.20, not full normalization.", body_style
))

story.append(Paragraph("4.3  Toxic Alcohol Ingestion", h2_style))
story.append(Paragraph(
    "Methanol and ethylene glycol both cause a high-AG acidosis <b>with an osmolar gap</b>. "
    "The osmolar gap = Measured S<sub>osm</sub> − Calculated S<sub>osm</sub>, where:", body_style
))
story.append(Paragraph(
    "Calculated Osmolality = 2[Na<sup>+</sup>] + [BUN]/2.8 + [Glucose]/18",
    formula_style
))
story.append(Paragraph(
    "<b>Ethylene glycol</b>: Found in antifreeze. Metabolized to glycolate and oxalate → renal failure "
    "and oxalate crystaluria. Treatment: fomepizole 15 mg/kg IV load, then 10 mg/kg q12h; thiamine + "
    "pyridoxine; hemodialysis if pH &lt;7.3 or osmolar gap &gt;20 or end-organ damage.", body_style
))
story.append(Paragraph(
    "<b>Methanol</b>: Wood alcohol. Metabolized to formaldehyde and formate → optic nerve damage, "
    "blindness. Treatment: same as EG (fomepizole preferred; dialysis for severe cases).", body_style
))
story.append(Paragraph(
    "<b>Note</b>: Isopropyl alcohol causes osmolar gap WITHOUT high-AG acidosis (unless extreme overdose "
    "causes hypotension and lactic acidosis).", warning_style
))
story.append(Spacer(1, 0.3*cm))

# ── 5. NORMAL AG ACIDOSIS ─────────────────────────────────────────────────────
story.append(section_header("5.  Normal Anion Gap (Hyperchloremic) Metabolic Acidosis"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "Also called hyperchloremic metabolic acidosis. The AG is normal (&lt;12 mEq/L) because the lost "
    "bicarbonate is replaced by chloride. Causes are remembered with the mnemonic <b>HARDUP</b>:", body_style
))

hardup_data = [
    [Paragraph("<b>Letter</b>", body_style), Paragraph("<b>Cause</b>", body_style), Paragraph("<b>Mechanism</b>", body_style)],
    [Paragraph("H", body_style), Paragraph("Hyperalimentation / Hospital-acquired saline administration", body_style),
     Paragraph("Large volumes of 0.9% NaCl → hyperchloremia, dilutional HCO3− loss", body_style)],
    [Paragraph("A", body_style), Paragraph("Acid infusion / Addison disease / Carbonic anhydrase inhibitors (e.g., acetazolamide)", body_style),
     Paragraph("Acetazolamide blocks tubular HCO3− reabsorption; Addison → decreased aldosterone → impaired H+ excretion", body_style)],
    [Paragraph("R", body_style), Paragraph("Renal tubular acidosis (RTA)", body_style),
     Paragraph("Impaired renal acid excretion (see Section 6)", body_style)],
    [Paragraph("D", body_style), Paragraph("Diarrhea", body_style),
     Paragraph("GI loss of HCO3−; most common GI cause", body_style)],
    [Paragraph("U", body_style), Paragraph("Ureteral diversion (ileal conduit, ureterosigmoidostomy)", body_style),
     Paragraph("Bowel reabsorbs urinary NH4Cl, secretes HCO3−", body_style)],
    [Paragraph("P", body_style), Paragraph("Pancreatic / biliary fistula; Post-hypocapnia", body_style),
     Paragraph("GI HCO3− loss; or renal HCO3− excretion persisting after correction of respiratory alkalosis", body_style)],
]
ht = Table(hardup_data, colWidths=[1.5*cm, 6.5*cm, 8.5*cm])
ht.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_GRAY]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
    ('TEXTCOLOR', (0,1), (0,-1), ACCENT),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(ht)
story.append(Spacer(1, 0.3*cm))

# ── 6. RENAL TUBULAR ACIDOSIS ─────────────────────────────────────────────────
story.append(section_header("6.  Renal Tubular Acidosis (RTA)"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "RTAs are a group of disorders in which the kidney cannot properly excrete acid despite relatively "
    "preserved glomerular filtration. All three types produce non-AG metabolic acidosis.", body_style
))

rta_data = [
    [Paragraph("<b>Type</b>", body_style),
     Paragraph("<b>Name</b>", body_style),
     Paragraph("<b>Defect</b>", body_style),
     Paragraph("<b>Serum K+</b>", body_style),
     Paragraph("<b>Urine pH</b>", body_style),
     Paragraph("<b>Key Causes</b>", body_style)],
    [Paragraph("Type I", body_style),
     Paragraph("Distal RTA", body_style),
     Paragraph("Impaired H+ secretion in collecting duct", body_style),
     Paragraph("Low (hypokalemia)", body_style),
     Paragraph("> 5.5 (alkaline)", body_style),
     Paragraph("Sjögren's, lupus, amphotericin B, medullary sponge kidney", body_style)],
    [Paragraph("Type II", body_style),
     Paragraph("Proximal RTA", body_style),
     Paragraph("Impaired HCO3− reabsorption in proximal tubule", body_style),
     Paragraph("Low", body_style),
     Paragraph("Acid (< 5.5 when acidotic)", body_style),
     Paragraph("Fanconi syndrome, multiple myeloma, acetazolamide, Wilson disease", body_style)],
    [Paragraph("Type IV", body_style),
     Paragraph("Hypoaldosteronism", body_style),
     Paragraph("Reduced aldosterone → impaired NH4+ excretion", body_style),
     Paragraph("High (hyperkalemia)", body_style),
     Paragraph("Acid (< 5.5)", body_style),
     Paragraph("Diabetic nephropathy, ACE inhibitors/ARBs, NSAIDs, adrenal insufficiency", body_style)],
]
rta_t = Table(rta_data, colWidths=[1.5*cm, 2.5*cm, 3.8*cm, 2*cm, 2.2*cm, 4.5*cm])
rta_t.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), MID_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_BLUE]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 5),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
]))
story.append(rta_t)
story.append(Paragraph(
    "Note: Type III RTA is rarely used as a clinical category (represents a combination of Types I and II).",
    caption_style
))
story.append(Spacer(1, 0.3*cm))

# ── 7. DIAGNOSTIC APPROACH ────────────────────────────────────────────────────
story.append(section_header("7.  Stepwise Diagnostic Approach"))
story.append(Spacer(1, 0.2*cm))

steps = [
    ("Step 1", "Obtain simultaneous ABG and serum electrolytes",
     "The calculated HCO3− on ABG and measured value on electrolyte panel should agree within ±2 mEq/L. "
     "Discordance suggests lab error or timing mismatch."),
    ("Step 2", "Assess arterial pH",
     "pH < 7.35 = acidemia. Confirm the primary process is metabolic (low HCO3−)."),
    ("Step 3", "Calculate the anion gap",
     "AG = Na+ − (Cl− + HCO3−). Correct for albumin if hypoalbuminemic."),
    ("Step 4", "Classify as high-AG or normal-AG acidosis",
     "AG > 12–13: high-AG (MUDPILES). AG ≤ 12: normal-AG (HARDUP). High AG is significant even if pH is normal."),
    ("Step 5", "Check for compensatory response (Winters' formula)",
     "Expected PaCO2 = 1.5 × [HCO3−] + 8 ± 2. Deviation indicates a mixed disorder."),
    ("Step 6", "Calculate the Delta-Delta (ΔΔ) ratio for high-AG acidosis",
     "ΔAG / ΔHCO3− = (AG − 10) / (24 − HCO3−). Ratio 1–2: pure AG acidosis. < 1: concurrent normal-AG acidosis. > 2: concurrent metabolic alkalosis."),
    ("Step 7", "Specific workup based on AG category",
     "High AG: lactate, ketones, BUN/creatinine, osmolar gap, salicylate level. "
     "Normal AG: urine AG = (urine Na+ + K+) − Cl−; negative = GI HCO3− loss; positive = RTA."),
]

for step, title, desc in steps:
    step_data = [[
        Paragraph(f"<b>{step}</b>", ParagraphStyle('StepNum', fontSize=10,
            fontName='Helvetica-Bold', textColor=white, alignment=TA_CENTER,
            backColor=MID_BLUE, borderPad=4)),
        Paragraph(f"<b>{title}</b><br/>{desc}", body_style)
    ]]
    st = Table(step_data, colWidths=[2.5*cm, 14*cm])
    st.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (0,0), MID_BLUE),
        ('VALIGN', (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 6),
        ('BOTTOMPADDING', (0,0), (-1,-1), 6),
        ('LEFTPADDING', (0,0), (-1,-1), 6),
        ('BOX', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ]))
    story.append(st)
    story.append(Spacer(1, 0.12*cm))

story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Urine Anion Gap (UAG)", h2_style))
story.append(Paragraph(
    "UAG = (Urine Na<sup>+</sup> + Urine K<sup>+</sup>) − Urine Cl<sup>−</sup>", formula_style
))
uag_rows = [
    "• Negative UAG (Cl− > Na+ + K+): suggests adequate NH4+ excretion → GI cause (e.g., diarrhea)",
    "• Positive UAG (Cl− < Na+ + K+): suggests impaired NH4+ excretion → RTA (most types)",
    "• Proximal RTA (Type II) may show variable UAG depending on serum HCO3− level",
]
story.append(make_key_box(uag_rows))
story.append(Spacer(1, 0.3*cm))

# ── 8. CLINICAL EFFECTS ───────────────────────────────────────────────────────
story.append(section_header("8.  Clinical Manifestations"))
story.append(Spacer(1, 0.2*cm))

effects_data = [
    [Paragraph("<b>System</b>", body_style), Paragraph("<b>Effects</b>", body_style)],
    [Paragraph("Cardiovascular", body_style),
     Paragraph("Decreased myocardial contractility, vasodilation, hypotension, arrhythmias (especially at pH < 7.1); resistance to catecholamines", body_style)],
    [Paragraph("Respiratory", body_style),
     Paragraph("Compensatory hyperventilation (Kussmaul breathing); respiratory muscle fatigue in severe cases", body_style)],
    [Paragraph("Neurological", body_style),
     Paragraph("Progressive obtundation, confusion, coma (especially with pH < 7.1)", body_style)],
    [Paragraph("Metabolic", body_style),
     Paragraph("Hyperkalemia (H+/K+ exchange across cell membranes); insulin resistance; impaired protein synthesis", body_style)],
    [Paragraph("Skeletal", body_style),
     Paragraph("Bone resorption (buffers chronic acid load); osteopenia/osteoporosis in chronic acidosis", body_style)],
    [Paragraph("Renal", body_style),
     Paragraph("Impaired ammoniagenesis in chronic acidosis; nephrolithiasis in distal RTA (calcium oxalate/phosphate stones)", body_style)],
]
eff_t = Table(effects_data, colWidths=[3*cm, 13.5*cm])
eff_t.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_GRAY]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
]))
story.append(eff_t)
story.append(Spacer(1, 0.3*cm))

# ── 9. MANAGEMENT ─────────────────────────────────────────────────────────────
story.append(section_header("9.  Management"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "Treatment of metabolic acidosis is directed at the <b>underlying cause</b>. Specific interventions "
    "depend on the type and severity of the acidosis.", body_style
))

story.append(Paragraph("9.1  General Principles", h2_style))
gen_mgmt = [
    "• Address the root cause: restore perfusion (lactic acidosis), insulin + IV fluids (DKA), antidotes (toxic alcohols), dialysis (uremia).",
    "• In mechanically ventilated patients: maintain compensatory hyperventilation — do not normalize PaCO2 without correcting HCO3−.",
    "• Monitor serum K+ closely: correction of acidosis shifts K+ intracellularly and can precipitate hypokalemia.",
    "• Avoid aggressive NaHCO3 therapy in most forms of metabolic acidosis — evidence of benefit is limited.",
]
story.append(make_key_box(gen_mgmt))

story.append(Paragraph("9.2  Bicarbonate Therapy", h2_style))
story.append(Paragraph(
    "Alkali therapy (NaHCO<sub rise='3'>3</sub>) is appropriate in select situations:", body_style
))
bicarb_data = [
    [Paragraph("<b>Indication</b>", body_style), Paragraph("<b>Details</b>", body_style)],
    [Paragraph("Non-AG acidosis (e.g., RTA, diarrhea)", body_style),
     Paragraph("Oral NaHCO3 tablets or Shohl's solution (sodium citrate); target HCO3− ~22 mEq/L. Avoid overcorrection.", body_style)],
    [Paragraph("Uremic acidosis (advanced CKD)", body_style),
     Paragraph("Oral bicarbonate to maintain HCO3− ≥ 22 mEq/L; may slow CKD progression.", body_style)],
    [Paragraph("DKA with severe acidemia (pH < 7.00)", body_style),
     Paragraph("50 mEq NaHCO3 in 300 mL saline over 30–45 min; target pH ~7.20 and HCO3− 10–12 mEq/L.", body_style)],
    [Paragraph("Severe lactic acidosis (pH < 7.1 + hemodynamic instability)", body_style),
     Paragraph("Controversial; BICAR-ICU trial showed no mortality benefit overall, but possible benefit in AKI subgroup.", body_style)],
    [Paragraph("Hyperchloremic post-saline acidosis", body_style),
     Paragraph("Usually self-correcting; switch to balanced crystalloids (lactated Ringer's) for ongoing fluid therapy.", body_style)],
]
bicarb_t = Table(bicarb_data, colWidths=[5.5*cm, 11*cm])
bicarb_t.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), MID_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_BLUE]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(bicarb_t)
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph(
    "THAM (tris-hydroxymethyl aminomethane): an alternative buffer that reduces [H+] without generating CO2 "
    "or increasing sodium. May be useful when NaHCO3 is contraindicated (sodium overload). No large RCT evidence.",
    body_style
))

story.append(Paragraph("9.3  Cause-Specific Management", h2_style))
cause_mgmt_data = [
    [Paragraph("<b>Cause</b>", body_style), Paragraph("<b>Key Treatment</b>", body_style)],
    [Paragraph("DKA", body_style),
     Paragraph("IV insulin infusion + isotonic saline; potassium replacement; glucose monitoring; bicarbonate only if pH < 7.00", body_style)],
    [Paragraph("Alcoholic ketoacidosis", body_style),
     Paragraph("Dextrose-containing IV fluids; thiamine 100 mg IV before glucose; no insulin required", body_style)],
    [Paragraph("Lactic acidosis (Type A)", body_style),
     Paragraph("Reverse underlying hypoperfusion; vasopressors/inotropes; antibiotics for sepsis; avoid metformin", body_style)],
    [Paragraph("Ethylene glycol", body_style),
     Paragraph("Fomepizole (4-MP) 15 mg/kg IV load; thiamine + pyridoxine; hemodialysis if pH < 7.3 or osmolar gap > 20", body_style)],
    [Paragraph("Methanol", body_style),
     Paragraph("Fomepizole; folate 50 mg IV q4–6h; hemodialysis for visual symptoms or severe acidosis", body_style)],
    [Paragraph("Salicylate toxicity", body_style),
     Paragraph("Urinary alkalinization with IV NaHCO3; activated charcoal if early; hemodialysis for severe cases", body_style)],
    [Paragraph("RTA Type I", body_style),
     Paragraph("Potassium citrate (preferred; corrects acidosis and hypokalemia); alkali therapy to prevent nephrolithiasis", body_style)],
    [Paragraph("RTA Type II", body_style),
     Paragraph("Large doses of oral bicarbonate/citrate; thiazide diuretics (reduce tubular flow); treat underlying Fanconi syndrome", body_style)],
    [Paragraph("RTA Type IV", body_style),
     Paragraph("Fludrocortisone (if mineralocorticoid deficiency); furosemide (promotes K+ excretion); dietary K+ restriction", body_style)],
]
cm_t = Table(cause_mgmt_data, colWidths=[4*cm, 12.5*cm])
cm_t.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_GRAY]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
    ('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
]))
story.append(cm_t)
story.append(Spacer(1, 0.3*cm))

# ── 10. MIXED DISORDERS ───────────────────────────────────────────────────────
story.append(section_header("10.  Mixed Acid-Base Disorders"))
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph(
    "Metabolic acidosis frequently coexists with other acid-base disorders. Recognition requires systematic "
    "application of the Delta-Delta ratio and Winters' formula.", body_style
))

mixed_data = [
    [Paragraph("<b>Mixed Disorder</b>", body_style), Paragraph("<b>Clinical Example</b>", body_style), Paragraph("<b>Lab Clue</b>", body_style)],
    [Paragraph("High-AG + Normal-AG metabolic acidosis", body_style),
     Paragraph("Diarrhea + lactic acidosis; toluene toxicity", body_style),
     Paragraph("ΔAG + ΔCl− together account for ΔHCO3−; Na 135, K 3.0, Cl 110, HCO3− 10, AG 15, pH 7.20", body_style)],
    [Paragraph("Metabolic acidosis + metabolic alkalosis", body_style),
     Paragraph("DKA + vomiting; uremia + vomiting", body_style),
     Paragraph("ΔAG > ΔHCO3−; pH may be near normal despite high AG", body_style)],
    [Paragraph("Metabolic acidosis + respiratory acidosis", body_style),
     Paragraph("Septic shock + COPD or sedative overdose", body_style),
     Paragraph("Measured PaCO2 > predicted by Winters'", body_style)],
    [Paragraph("Metabolic acidosis + respiratory alkalosis", body_style),
     Paragraph("Salicylate toxicity; hepatic failure; sepsis", body_style),
     Paragraph("Measured PaCO2 < predicted by Winters'; pH may be normal or alkaline", body_style)],
    [Paragraph("Triple disorder", body_style),
     Paragraph("Alcoholic ketoacidosis + vomiting + liver disease", body_style),
     Paragraph("High AG + alkalosis + respiratory alkalosis; pH very variable", body_style)],
]
mix_t = Table(mixed_data, colWidths=[4.5*cm, 5*cm, 7*cm])
mix_t.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_BLUE]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('VALIGN', (0,0), (-1,-1), 'TOP'),
]))
story.append(mix_t)
story.append(Spacer(1, 0.3*cm))

# ── 11. QUICK REFERENCE ───────────────────────────────────────────────────────
story.append(section_header("11.  Quick Reference Summary"))
story.append(Spacer(1, 0.2*cm))

qr_data = [
    [Paragraph("<b>Parameter</b>", body_style), Paragraph("<b>Formula / Value</b>", body_style)],
    [Paragraph("Anion Gap", body_style), Paragraph("Na+ − (Cl− + HCO3−); normal 6–12 mEq/L", body_style)],
    [Paragraph("Corrected AG (hypoalbuminemia)", body_style), Paragraph("AG + 2.5 × (4.5 − albumin g/dL)", body_style)],
    [Paragraph("Winters' Formula", body_style), Paragraph("Expected PaCO2 = 1.5 × [HCO3−] + 8 ± 2", body_style)],
    [Paragraph("Delta-Delta Ratio", body_style), Paragraph("(AG − 10) / (24 − HCO3−); 1–2 = pure AG acidosis", body_style)],
    [Paragraph("Urine Anion Gap", body_style), Paragraph("(Urine Na+ + K+) − Urine Cl−; negative = GI cause", body_style)],
    [Paragraph("Osmolar Gap", body_style), Paragraph("Measured Sosm − (2[Na+] + BUN/2.8 + Glucose/18); normal < 10", body_style)],
    [Paragraph("DKA NaHCO3 threshold", body_style), Paragraph("pH < 7.00; 50 mEq in 300 mL saline over 30–45 min", body_style)],
    [Paragraph("Fomepizole loading dose", body_style), Paragraph("15 mg/kg IV over 30 min (ethylene glycol / methanol)", body_style)],
    [Paragraph("BICAR-ICU trial", body_style), Paragraph("No overall mortality benefit from NaHCO3 in severe metabolic acidemia; possible AKI subgroup benefit", body_style)],
]
qr_t = Table(qr_data, colWidths=[5.5*cm, 11*cm])
qr_t.setStyle(TableStyle([
    ('BACKGROUND', (0,0), (-1,0), DARK_BLUE),
    ('TEXTCOLOR', (0,0), (-1,0), white),
    ('ROWBACKGROUNDS', (0,1), (-1,-1), [white, LIGHT_BLUE]),
    ('GRID', (0,0), (-1,-1), 0.5, BORDER_GRAY),
    ('TOPPADDING', (0,0), (-1,-1), 5),
    ('BOTTOMPADDING', (0,0), (-1,-1), 5),
    ('LEFTPADDING', (0,0), (-1,-1), 6),
    ('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
]))
story.append(qr_t)
story.append(Spacer(1, 0.3*cm))

# ── REFERENCES ────────────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=1, color=BORDER_GRAY))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph("References", h2_style))
refs = [
    "1. Harrison's Principles of Internal Medicine, 22nd Edition (2025). McGraw Hill Medical. ISBN: 9781265977061.",
    "2. Rosen's Emergency Medicine: Concepts and Clinical Practice. Elsevier. ISBN: 9780323757898.",
    "3. Barash, Cullen, and Stoelting's Clinical Anesthesia, 9th Edition. Wolters Kluwer. ISBN: 9781975199074.",
    "4. Frameworks for Internal Medicine. Wolters Kluwer. ISBN: 9781496359308.",
    "5. Brenner and Rector's The Kidney, 2-Volume Set. Elsevier. ISBN: 9780323532655.",
    "6. Jaber S, et al. Sodium bicarbonate therapy for patients with severe metabolic acidaemia in the intensive care unit (BICAR-ICU): a multicentre, open-label, randomised controlled, phase 3 trial. Lancet. 2018;392(10141):31-40.",
]
for ref in refs:
    story.append(Paragraph(ref, source_style))

# Build PDF
doc.build(story)
print(f"PDF generated: {OUTPUT}")
Running Command

cd /home/daytona/workspace/metabolic-acidosis && python generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/metabolic-acidosis/Metabolic_Acidosis.pdf

Your PDF is ready:

Metabolic Acidosis

PDF Document · PDF


Here's what's covered in the document, compiled from Harrison's 22E, Rosen's Emergency Medicine, Barash's Clinical Anesthesia 9E, Frameworks for Internal Medicine, and Brenner & Rector's The Kidney:
SectionContent
1. Definition & OverviewNormal values, what constitutes metabolic acidosis
2. PathophysiologyBuffering systems, Henderson-Hasselbalch, Winters' formula
3. ClassificationHigh-AG vs. Normal-AG comparison table
4. High AG AcidosisFull MUDPILES table; lactic acidosis (Type A/B), ketoacidosis (DKA/AKA/starvation), toxic alcohols (EG/methanol) with osmolar gap formula
5. Normal AG AcidosisFull HARDUP mnemonic table with mechanisms
6. Renal Tubular AcidosisTypes I, II, IV - defect, K+, urine pH, key causes
7. Diagnostic Approach7-step framework; Urine Anion Gap interpretation
8. Clinical ManifestationsCardiovascular, respiratory, neurological, metabolic, skeletal, renal effects
9. ManagementBicarbonate therapy indications; cause-specific treatments; BICAR-ICU trial summary
10. Mixed DisordersDelta-delta ratio; common mixed disorder scenarios
11. Quick ReferenceAll key formulas at a glance
This is a shared conversation. Sign in to Orris to start your own chat.