~/lipid-cheatsheet/generate_cheatsheet.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import PageBreak
# ── Output path ──────────────────────────────────────────────────────────────
OUTPUT = "/home/daytona/workspace/lipid-cheatsheet/Lipid_Metabolism_MCQ_Cheatsheet.pdf"
# ── Colour palette ────────────────────────────────────────────────────────────
C_NAVY = colors.HexColor("#1a2b5e")
C_TEAL = colors.HexColor("#0d7377")
C_AMBER = colors.HexColor("#e8a020")
C_WARN = colors.HexColor("#c0392b")
C_LGRAY = colors.HexColor("#f4f6fb")
C_MGRAY = colors.HexColor("#dde3f0")
C_WHITE = colors.white
C_BLACK = colors.HexColor("#1c1c1c")
C_GREEN = colors.HexColor("#1a7a4a")
C_PURPLE = colors.HexColor("#6c3483")
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=1.5*cm, rightMargin=1.5*cm,
topMargin=1.5*cm, bottomMargin=1.5*cm,
title="Lipid Metabolism MCQ Cheat Sheet",
author="Orris"
)
W = A4[0] - 3*cm # usable width
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
# Custom styles
TITLE = S("title_s", fontName="Helvetica-Bold", fontSize=20, textColor=C_WHITE,
alignment=TA_CENTER, spaceAfter=2)
SUBTITLE = S("sub_s", fontName="Helvetica", fontSize=9, textColor=C_MGRAY,
alignment=TA_CENTER, spaceAfter=4)
SEC = S("sec_s", fontName="Helvetica-Bold", fontSize=10, textColor=C_WHITE,
backColor=C_NAVY, alignment=TA_LEFT, leftIndent=4, spaceBefore=8, spaceAfter=2,
borderPad=3)
BODY = S("body_s", fontName="Helvetica", fontSize=8, textColor=C_BLACK,
leading=11, spaceAfter=1)
BOLD = S("bold_s", fontName="Helvetica-Bold", fontSize=8, textColor=C_BLACK, leading=11)
TRAP = S("trap_s", fontName="Helvetica-Bold", fontSize=8, textColor=C_WARN, leading=11)
TH = S("th_s", fontName="Helvetica-Bold", fontSize=7.5, textColor=C_WHITE,
alignment=TA_CENTER)
TD = S("td_s", fontName="Helvetica", fontSize=7.5, textColor=C_BLACK,
alignment=TA_LEFT, leading=10)
TDC = S("tdc_s", fontName="Helvetica", fontSize=7.5, textColor=C_BLACK,
alignment=TA_CENTER, leading=10)
TDB = S("tdb_s", fontName="Helvetica-Bold", fontSize=7.5, textColor=C_BLACK,
alignment=TA_LEFT, leading=10)
def section_header(text, color=C_NAVY):
tbl = Table([[Paragraph(text, S("sh", fontName="Helvetica-Bold", fontSize=9.5,
textColor=C_WHITE, leftIndent=4))]],
colWidths=[W])
tbl.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING",(0,0),(-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 6),
]))
return tbl
def bullet(text, color=C_TEAL, indent=0):
bullet_char = "▸"
full = f'<font color="#{color.hexval()[2:]}"><b>{bullet_char}</b></font> {text}'
return Paragraph(full, S("b_s", fontName="Helvetica", fontSize=8,
textColor=C_BLACK, leading=11,
leftIndent=8+indent, spaceAfter=1.5))
def sub_bullet(text):
return Paragraph(f" – {text}",
S("sb_s", fontName="Helvetica", fontSize=7.5,
textColor=C_BLACK, leading=10, leftIndent=20, spaceAfter=1))
def highlight_box(items, bg=C_LGRAY, border=C_TEAL):
rows = [[Paragraph(f"• {i}", S("hb_s", fontName="Helvetica", fontSize=7.5,
textColor=C_BLACK, leading=11))]
for i in items]
t = Table(rows, colWidths=[W-0.4*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), bg),
("LINEAFTER", (0,0),(0,-1), 2, border),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING",(0,0),(-1,-1),3),
("LEFTPADDING",(0,0),(-1,-1), 8),
]))
return t
def make_table(headers, rows, col_widths, header_color=C_NAVY):
data = [[Paragraph(h, TH) for h in headers]]
for row in rows:
data.append([Paragraph(str(c), TDC if i > 0 else TD) for i, c in enumerate(row)])
t = Table(data, colWidths=col_widths)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), header_color),
("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_LGRAY]),
("GRID", (0,0), (-1,-1), 0.3, C_MGRAY),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
return t
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── TITLE BANNER ─────────────────────────────────────────────────────────────
banner_data = [[
Paragraph("🧬 LIPID METABOLISM", S("tb", fontName="Helvetica-Bold", fontSize=22,
textColor=C_WHITE, alignment=TA_CENTER)),
Paragraph("MCQ Quick Reference Cheat Sheet · Biochemistry",
S("ts", fontName="Helvetica", fontSize=9, textColor=C_MGRAY,
alignment=TA_CENTER)),
]]
banner = Table([[Paragraph("🧬 LIPID METABOLISM — MCQ Quick Reference Cheat Sheet",
S("t2", fontName="Helvetica-Bold", fontSize=15,
textColor=C_WHITE, alignment=TA_CENTER))]],
colWidths=[W])
banner.setStyle(TableStyle([
("BACKGROUND", (0,0),(-1,-1), C_NAVY),
("TOPPADDING", (0,0),(-1,-1), 10),
("BOTTOMPADDING", (0,0),(-1,-1), 10),
("ROUNDEDCORNERS",[4]),
]))
story.append(banner)
story.append(Spacer(1, 6))
# ═══ TWO-COLUMN LAYOUT HELPER ═════════════════════════════════════════════════
def two_col(left_items, right_items, ratio=(0.5, 0.5)):
lw = W * ratio[0] - 4
rw = W * ratio[1] - 4
tbl = Table([[left_items, right_items]], colWidths=[lw+4, rw+4])
tbl.setStyle(TableStyle([
("VALIGN", (0,0),(-1,-1), "TOP"),
("LEFTPADDING", (0,0),(-1,-1), 0),
("RIGHTPADDING",(0,0),(-1,-1), 0),
("TOPPADDING", (0,0),(-1,-1), 0),
("BOTTOMPADDING",(0,0),(-1,-1), 0),
]))
return tbl
# ═══ SECTION 1: β-OXIDATION ══════════════════════════════════════════════════
s1 = [
section_header("1 · FATTY ACID β-OXIDATION", C_TEAL),
bullet("Location: <b>Mitochondria</b> (LCFA) | <b>Peroxisomes</b> (VLCFA >C22)"),
bullet("Activation: FFA → Acyl CoA (Acyl CoA Synthetase); costs <b>2 ATP</b> (ATP→AMP+PPi)"),
bullet("Carnitine Shuttle: CPT-I (outer) → Translocase → CPT-II (inner) — <b>CPT-I = rate-limiting</b>"),
bullet("<b>Malonyl CoA inhibits CPT-I</b> (fed state blocks oxidation simultaneously with synthesis)"),
Spacer(1, 2),
Paragraph("<b>Each cycle yields:</b>", BOLD),
make_table(["Product","Amount","ATP equiv."],
[["FADH₂","1","1.5"],["NADH","1","2.5"],["Acetyl CoA","1","~10 via TCA"]],
[W*0.38, W*0.3, W*0.32], C_TEAL),
Spacer(1,3),
bullet("Odd-chain FA → last product = <b>Propionyl CoA</b> → needs <b>Biotin</b> (propionyl CoA carboxylase) + <b>B12</b> (methylmalonyl CoA mutase) → Succinyl CoA"),
bullet("<b>Only FA that contributes to gluconeogenesis</b> (via succinyl CoA)"),
bullet("Peroxisomal 1st step: <b>Acyl CoA oxidase</b> → H₂O₂ (not FADH₂)"),
bullet("Zellweger = peroxisome biogenesis defect → VLCFA ↑"),
bullet("X-linked ALD = ABCD1 mutation → VLCFA in adrenal/CNS"),
]
# ═══ SECTION 2: FA SYNTHESIS ═════════════════════════════════════════════════
s2 = [
section_header("2 · FATTY ACID SYNTHESIS (De Novo)", C_PURPLE),
bullet("Location: <b>Cytosol</b> | Main site: Liver, adipose, mammary gland"),
bullet("Acetyl CoA exits mitochondria as <b>citrate</b> → cleaved by <b>ATP-citrate lyase</b>"),
Spacer(1,2),
Paragraph("<b>Rate-limiting step: Acetyl CoA → Malonyl CoA</b>", BOLD),
make_table(["Acetyl CoA Carboxylase (ACC)","Detail"],
[["Cofactor","Biotin"],
["Activated by","Citrate, Insulin (dephosphorylation)"],
["Inhibited by","Palmitoyl CoA, Glucagon, Epinephrine (phosphorylation)"]],
[W*0.38, W*0.62], C_PURPLE),
Spacer(1,3),
bullet("Fatty Acid Synthase (FAS): needs <b>NADPH</b> → makes <b>Palmitate (C16)</b>"),
bullet("Needs: 7 malonyl CoA + 1 acetyl CoA + 14 NADPH"),
bullet("NADPH sources: <b>Pentose Phosphate Pathway</b> (main) + Malic enzyme"),
bullet("Elongation: <b>ER</b> | Desaturation: <b>ER</b> (Δ9-desaturase)"),
bullet("Essential FA (cannot synthesize): <b>Linoleic</b> (ω-6, C18:2) + <b>α-Linolenic</b> (ω-3, C18:3)"),
]
story.append(two_col(s1, s2, (0.49, 0.51)))
story.append(Spacer(1, 5))
# ═══ SECTION 3: KETONE BODIES ════════════════════════════════════════════════
s3_left = [
section_header("3 · KETONE BODY METABOLISM", C_AMBER),
bullet("Synthesis (<b>ketogenesis</b>): <b>Liver mitochondria ONLY</b>"),
bullet("Trigger: fasting/DKA → ↓ OAA → acetyl CoA can't enter TCA → ketones"),
Spacer(1,2),
Paragraph("<b>Ketogenesis Steps:</b>", BOLD),
sub_bullet("Acetoacetyl CoA → <b>HMG CoA</b> (mito. HMG CoA synthase = <b>rate-limiting</b>)"),
sub_bullet("HMG CoA → <b>Acetoacetate</b> + Acetyl CoA (HMG CoA lyase)"),
sub_bullet("Acetoacetate → <b>3-Hydroxybutyrate</b> (when NADH ↑; favored in DKA/fasting)"),
sub_bullet("Acetoacetate → <b>Acetone</b> (spontaneous decarboxylation; fruity breath)"),
Spacer(1,2),
bullet("<b>Liver CANNOT use ketone bodies</b> — lacks <b>thiophorase</b> (succinyl CoA transferase)"),
bullet("Peripheral tissues: 3-HB → acetoacetate → acetoacetyl CoA → 2 Acetyl CoA → TCA"),
bullet("<b>DKA</b>: No insulin → massive lipolysis → ↑FA oxidation → ↑ketones → acidosis"),
bullet("Brain uses ketones during prolonged fasting (after ~3–4 days)"),
]
s3_right = [
section_header("4 · CHOLESTEROL SYNTHESIS", C_GREEN),
bullet("All 27 carbons from <b>Acetyl CoA</b> | Location: <b>Cytosol/ER</b>"),
Spacer(1,2),
Paragraph("<b>Rate-limiting: HMG CoA → Mevalonate</b> (HMG CoA Reductase)", BOLD),
make_table(["HMG CoA Reductase",""],
[["Inhibited by","Statins, Cholesterol (feedback), Glucagon, AMPK"],
["Activated by","Insulin, Thyroid hormone"],
["Timing","Peaks at midnight → give statins at night"]],
[W*0.38*0.51, W*0.62*0.51], C_GREEN),
Spacer(1,3),
bullet("Mevalonate → IPP → Farnesyl PP → <b>Squalene</b> → <b>Cholesterol</b>"),
bullet("Farnesyl PP also → <b>CoQ10, Dolichol, Ras proteins</b>"),
sub_bullet("CoQ10 depletion = statin myopathy"),
bullet("<b>SREBP</b>: ↑ LDL receptors + HMG CoA reductase when cholesterol low"),
bullet("<b>ACAT</b>: intracellular esterification | <b>LCAT</b>: on HDL (activated by Apo A-I)"),
bullet("Bile acid rate-limiting: <b>7α-hydroxylase</b>; Primary: cholic + chenodeoxycholic"),
bullet("95% bile acids reabsorbed: <b>terminal ileum</b> (enterohepatic circulation)"),
]
story.append(two_col(s3_left, s3_right, (0.49, 0.51)))
story.append(Spacer(1, 5))
# ═══ SECTION 5: LIPOPROTEINS ═════════════════════════════════════════════════
story.append(section_header("5 · LIPOPROTEINS & TRANSPORT", C_NAVY))
story.append(Spacer(1, 3))
lp_left = [
make_table(
["Lipoprotein", "Source", "Key Apo", "Main Lipid", "Function"],
[
["Chylomicron", "Intestine", "Apo B-48", "Dietary TAG", "Dietary fat → tissues; enters lymph"],
["VLDL", "Liver", "Apo B-100", "Endogenous TAG","Liver TAG → periphery"],
["IDL", "From VLDL", "Apo B-100, E", "TAG+Chol", "Intermediate; → LDL"],
["LDL", "From IDL", "Apo B-100", "Cholesterol", "Chol → tissues (atherogenic)"],
["HDL", "Liver/Gut", "Apo A-I", "Protein-rich", "Reverse cholesterol transport"],
],
[W*0.13, W*0.12, W*0.15, W*0.17, W*0.43],
C_NAVY
),
Spacer(1,4),
bullet("<b>LPL</b> (Lipoprotein Lipase): on capillary endothelium; activated by <b>Apo C-II</b>; hydrolyzes TAG"),
bullet("<b>Chylomicron remnants</b> (not intact chylomicrons) taken up by liver via <b>Apo E receptor</b>"),
bullet("<b>CETP</b>: transfers cholesterol esters from HDL → LDL/VLDL"),
bullet("<b>ABCA1</b>: cholesterol efflux from cells → HDL; defective in <b>Tangier disease</b> (↓↓ HDL)"),
]
story.extend(lp_left)
story.append(Spacer(1, 5))
# ═══ SECTION 6+7: DISORDERS + HORMONES ═══════════════════════════════════════
s6_left = [
section_header("6 · LIPOLYSIS (Adipose Tissue)", C_TEAL),
bullet("<b>ATGL</b>: TAG → DAG (initiates)"),
bullet("<b>HSL</b> (Hormone-Sensitive Lipase): rate-limiting; DAG → MAG"),
sub_bullet("Activated: glucagon, epinephrine (cAMP → PKA)"),
sub_bullet("Inhibited: <b>insulin</b>"),
bullet("Released: FFA → albumin → liver/muscle; Glycerol → liver (gluconeogenesis)"),
bullet("<b>Adipose lacks glycerol kinase</b> → needs glucose for glycerol-3-P"),
Spacer(1,4),
section_header("7 · HORMONAL REGULATION", C_PURPLE),
make_table(["Hormone","FA Synthesis","Lipolysis","Ketogenesis"],
[["Insulin","↑ (activates ACC)","↓ (inhibits HSL)","↓"],
["Glucagon","↓ (inhibits ACC)","↑","↑"],
["Epinephrine","–","↑↑","↑"],
["Cortisol","–","↑","↑"],
["T3/T4","–","–","↑ LDL receptors"]],
[W*0.49*0.3, W*0.49*0.24, W*0.49*0.23, W*0.49*0.23],
C_PURPLE),
]
s6_right = [
section_header("8 · DISORDERS", C_WARN),
make_table(["Disease","Defect","Key Feature"],
[["Fam. Hypercholesterolemia","LDL receptor","Very ↑ LDL, xanthomas, early MI"],
["Type I Hyperlipidemia","LPL or Apo C-II","Milky plasma, pancreatitis, no ↑CVD"],
["Type III (Dysbetalipoprotein.)","Apo E2/E2","↑ IDL, palmar xanthomas"],
["MCAD deficiency","Medium-chain acyl CoA DH","Hypo<b>keto</b>tic hypoglycemia (C8)"],
["Abetalipoproteinemia","No Apo B","Fat malabsorb, acanthocytes, ataxia"],
["Zellweger syndrome","Peroxisome biogenesis","VLCFA ↑, neonatal hypotonia"],
["Tangier disease","ABCA1 mutation","Very ↓ HDL, cholesterol in tonsils"]],
[W*0.51*0.32, W*0.51*0.28, W*0.51*0.4],
C_WARN),
Spacer(1,4),
section_header("9 · SPHINGOLIPIDOSES", C_GREEN),
make_table(["Disease","Enzyme","Accumulates"],
[["Gaucher","Glucocerebrosidase","Glucocerebroside"],
["Niemann-Pick","Sphingomyelinase","Sphingomyelin"],
["Tay-Sachs","Hexosaminidase A","GM2 ganglioside"],
["Fabry","α-Galactosidase A","Ceramide trihexoside"],
["Krabbe","Galactocerebrosidase","Galactocerebroside"]],
[W*0.51*0.33, W*0.51*0.37, W*0.51*0.3],
C_GREEN),
]
story.append(two_col(s6_left, s6_right, (0.49, 0.51)))
story.append(Spacer(1, 5))
# ═══ SECTION 10: KEY ENZYMES ═════════════════════════════════════════════════
story.append(section_header("10 · KEY ENZYMES & COFACTORS", C_NAVY))
story.append(Spacer(1, 3))
story.append(make_table(
["Enzyme","Cofactor","Rate-Limiting For","Location"],
[
["Acetyl CoA Carboxylase (ACC)","Biotin","FA Synthesis","Cytosol"],
["Fatty Acid Synthase (FAS)","NADPH","FA chain elongation","Cytosol"],
["HMG CoA Reductase","NADPH","Cholesterol synthesis","ER"],
["Mito. HMG CoA Synthase","–","Ketogenesis","Mitochondria (liver)"],
["7α-Hydroxylase","–","Bile acid synthesis","ER (liver)"],
["Lipoprotein Lipase (LPL)","Apo C-II (activator)","TAG hydrolysis","Capillary endothelium"],
["Pyruvate Carboxylase","Biotin","Gluconeogenesis/OAA","Mitochondria"],
["Propionyl CoA Carboxylase","Biotin","Odd-chain FA metabolism","Mitochondria"],
["Methylmalonyl CoA Mutase","Vitamin B12","Odd-chain FA → TCA","Mitochondria"],
["Hormone-Sensitive Lipase (HSL)","–","Adipose lipolysis","Adipose cytoplasm"],
["LCAT","–","Cholesterol esterification on HDL","Plasma (on HDL)"],
["ACAT","–","Intracellular cholesterol storage","ER"],
],
[W*0.27, W*0.16, W*0.3, W*0.27],
C_NAVY
))
story.append(Spacer(1, 5))
# ═══ MCQ TRAPS BOX ═══════════════════════════════════════════════════════════
story.append(section_header("⭐ TOP MCQ TRAPS — Memorize These!", C_WARN))
story.append(Spacer(1, 3))
traps = [
["1","Malonyl CoA inhibits CPT-I → fed state: FA synthesis & oxidation don't run simultaneously"],
["2","Liver CANNOT use ketone bodies — lacks thiophorase (succinyl CoA:acetoacetate CoA transferase)"],
["3","Adipose lacks glycerol kinase → cannot recycle glycerol; needs glucose for glycerol-3-P"],
["4","Chylomicron REMNANTS (not intact chylomicrons) are taken up by liver via Apo E"],
["5","HMG CoA exists in both mitochondria (ketogenesis) & cytosol (cholesterol) — different pools!"],
["6","Biotin deficiency → impairs ACC, pyruvate carboxylase, propionyl CoA carboxylase (3 enzymes)"],
["7","B12 deficiency → methylmalonic acidemia; does NOT affect FA synthesis"],
["8","Odd-chain FA only → contributes to gluconeogenesis (via propionyl CoA → succinyl CoA)"],
["9","MCAD deficiency → HYPOketotic hypoglycemia (cannot oxidize FA, so no ketones)"],
["10","Chylomicrons enter lymph (thoracic duct); short-chain FA enter portal blood directly"],
["11","Statins given at night — HMG CoA reductase activity peaks at midnight"],
["12","Ezetimibe blocks NPC1L1 (intestinal absorption); cholestyramine blocks ileal reabsorption"],
["13","3-Hydroxybutyrate predominates over acetoacetate when NADH is high (fasting/DKA)"],
["14","Acetone is NOT metabolized — detected in breath; biologically inert"],
["15","LCAT is activated by Apo A-I; LPL is activated by Apo C-II"],
]
trap_tbl = Table(
[[Paragraph(f"<b>{r[0]}.</b>", S("tn", fontName="Helvetica-Bold", fontSize=8,
textColor=C_WARN, alignment=TA_CENTER)),
Paragraph(r[1], S("tt", fontName="Helvetica", fontSize=7.5,
textColor=C_BLACK, leading=11))]
for r in traps],
colWidths=[W*0.05, W*0.95]
)
trap_tbl.setStyle(TableStyle([
("ROWBACKGROUNDS", (0,0),(-1,-1), [C_WHITE, C_LGRAY]),
("GRID", (0,0),(-1,-1), 0.3, C_MGRAY),
("TOPPADDING", (0,0),(-1,-1), 3),
("BOTTOMPADDING", (0,0),(-1,-1), 3),
("LEFTPADDING", (0,0),(-1,-1), 5),
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
("LINEAFTER", (0,0),(0,-1), 1, C_WARN),
]))
story.append(trap_tbl)
story.append(Spacer(1, 5))
# ═══ COMPARTMENTALIZATION QUICK TABLE ════════════════════════════════════════
story.append(section_header("11 · COMPARTMENTALIZATION AT A GLANCE", C_NAVY))
story.append(Spacer(1, 3))
comp_left = make_table(
["Process","Location"],
[["β-Oxidation (LCFA)","Mitochondria"],
["β-Oxidation (VLCFA)","Peroxisomes"],
["FA Synthesis","Cytosol"],
["Cholesterol Synthesis","Cytosol/ER"],
["Ketogenesis","Mitochondria (liver)"],
["FA Elongation","ER"],
["FA Desaturation","ER"],
["TAG Synthesis","ER"],
["LPL action","Capillary endothelium"],
["LCAT action","Plasma (on HDL)"]],
[W*0.5*0.55, W*0.5*0.45],
C_NAVY
)
eicosanoid = make_table(
["Eicosanoid","Enzyme","Source","Action"],
[["PGI₂ (Prostacyclin)","COX","Endothelium","Vasodilate, ↓ aggregation"],
["TXA₂ (Thromboxane)","COX","Platelets","Vasoconstrict, ↑ aggregation"],
["LTB4","Lipoxygenase","Neutrophils","Chemotaxis"],
["LTC4/D4/E4","Lipoxygenase","Mast cells","Bronchoconstriction (asthma)"]],
[W*0.5*0.25, W*0.5*0.22, W*0.5*0.22, W*0.5*0.31],
C_TEAL
)
comp_block = [
comp_left,
]
eico_block = [
section_header("12 · EICOSANOIDS", C_TEAL),
Spacer(1,3),
eicosanoid,
Spacer(1,3),
bullet("From: <b>Arachidonic acid</b> (C20:4, ω-6)"),
bullet("<b>Aspirin</b>: irreversibly inhibits COX → ↓ TXA₂ (antiplatelet) + ↓ PGI₂"),
bullet("NSAIDs: reversibly inhibit COX"),
]
story.append(two_col(comp_block, eico_block, (0.49, 0.51)))
# ═══ FOOTER ══════════════════════════════════════════════════════════════════
story.append(Spacer(1, 6))
story.append(HRFlowable(width=W, thickness=0.5, color=C_MGRAY))
story.append(Spacer(1, 3))
story.append(Paragraph(
"Sources: Lippincott Illustrated Reviews Biochemistry 8e (Chapters 16–18) · Guyton & Hall Medical Physiology · Generated by Orris",
S("ft", fontName="Helvetica", fontSize=6.5, textColor=colors.grey, alignment=TA_CENTER)
))
# ═══ BUILD ════════════════════════════════════════════════════════════════════
doc.build(story)
print(f"PDF saved to: {OUTPUT}")