Blood „ INTRODUCTION „ PROPERTIES „ COMPOSITION „ BLOOD CELLS „ PLASMA „ SERUM „ FUNCTIONS „ NUTRITIVE FUNCTION „ RESPIRATORY FUNCTION „ EXCRETORY FUNCTION „ TRANSPORT OF HORMONES AND ENZYMES „ REGULATION OF WATER BALANCE „ REGULATION OF ACID-BASE BALANCE „ REGULATION OF BODY TEMPERATURE „ STORAGE FUNCTION „ DEFENSIVE FUNCTION Please make a pdf on this topic

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

mkdir -p /home/daytona/workspace/blood-pdf && ls /home/daytona/workspace/blood-p…

Writing File

~/blood-pdf/generate_blood_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.colors import HexColor, white, black
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.lib import colors

OUTPUT = "/home/daytona/workspace/blood-pdf/Blood_Introduction.pdf"

# ── Color palette ──────────────────────────────────────────────────────────────
RED_DARK   = HexColor("#8B0000")
RED_MED    = HexColor("#C0392B")
RED_LIGHT  = HexColor("#FADBD8")
RED_PALE   = HexColor("#FDFAFA")
GOLD       = HexColor("#D4A017")
DARK_TEXT  = HexColor("#1A1A2E")
MID_TEXT   = HexColor("#34495E")
GREY_LINE  = HexColor("#BDC3C7")
WHITE      = white

# ── Document ───────────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT, pagesize=A4,
    leftMargin=2*cm, rightMargin=2*cm,
    topMargin=2.5*cm, bottomMargin=2.5*cm,
    title="Blood – Introduction",
    author="Medical Notes"
)

W, H = A4
styles = getSampleStyleSheet()

# ── Custom styles ──────────────────────────────────────────────────────────────
def ps(name, **kw):
    return ParagraphStyle(name, **kw)

COVER_TITLE = ps("CoverTitle",
    fontName="Helvetica-Bold", fontSize=42, textColor=WHITE,
    alignment=TA_CENTER, spaceAfter=6, leading=50)

COVER_SUB = ps("CoverSub",
    fontName="Helvetica", fontSize=16, textColor=HexColor("#F5C6C6"),
    alignment=TA_CENTER, spaceAfter=4, leading=22)

COVER_DATE = ps("CoverDate",
    fontName="Helvetica", fontSize=12, textColor=HexColor("#FADBD8"),
    alignment=TA_CENTER, spaceAfter=0)

CH_TITLE = ps("ChTitle",
    fontName="Helvetica-Bold", fontSize=20, textColor=WHITE,
    alignment=TA_LEFT, spaceAfter=0, spaceBefore=0, leading=24)

CH_NUM = ps("ChNum",
    fontName="Helvetica", fontSize=10, textColor=HexColor("#F5C6C6"),
    alignment=TA_LEFT, spaceAfter=2, leading=14)

SECTION = ps("Section",
    fontName="Helvetica-Bold", fontSize=13, textColor=RED_DARK,
    spaceBefore=14, spaceAfter=4, leading=17, borderPadding=(0,0,3,0))

SUBSECTION = ps("Subsection",
    fontName="Helvetica-Bold", fontSize=11, textColor=RED_MED,
    spaceBefore=10, spaceAfter=3, leading=15)

BODY = ps("Body",
    fontName="Helvetica", fontSize=10, textColor=DARK_TEXT,
    spaceBefore=3, spaceAfter=3, leading=15, alignment=TA_JUSTIFY)

BULLET = ps("Bullet",
    fontName="Helvetica", fontSize=10, textColor=DARK_TEXT,
    spaceBefore=2, spaceAfter=2, leading=14,
    leftIndent=14, bulletIndent=0)

CAPTION = ps("Caption",
    fontName="Helvetica-Oblique", fontSize=9, textColor=MID_TEXT,
    alignment=TA_CENTER, spaceBefore=2, spaceAfter=6)

NOTE_STYLE = ps("Note",
    fontName="Helvetica-Oblique", fontSize=9.5, textColor=HexColor("#5D4037"),
    spaceBefore=2, spaceAfter=2, leading=14, alignment=TA_JUSTIFY)

KEY_STYLE = ps("KeyFact",
    fontName="Helvetica-Bold", fontSize=10, textColor=RED_DARK,
    spaceBefore=2, spaceAfter=2, leading=14)

# ── Helper builders ────────────────────────────────────────────────────────────

def chapter_banner(num, title):
    """Red banner row for chapter headings."""
    tbl = Table([[
        Paragraph(f"SECTION {num}", CH_NUM),
        Paragraph(title, CH_TITLE)
    ]], colWidths=[2.5*cm, 12.5*cm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), RED_MED),
        ("ROWBACKGROUNDS", (0,0), (-1,-1), [RED_MED]),
        ("VALIGN",   (0,0), (-1,-1), "MIDDLE"),
        ("TOPPADDING",  (0,0), (-1,-1), 10),
        ("BOTTOMPADDING", (0,0), (-1,-1), 10),
        ("LEFTPADDING", (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    return [tbl, Spacer(1, 8)]


def info_box(heading, text, bg=RED_LIGHT, heading_color=RED_DARK):
    """Shaded info box with bold heading."""
    rows = [[Paragraph(f"<b>{heading}</b>", ps("IH", fontName="Helvetica-Bold",
            fontSize=10, textColor=heading_color, leading=14))],
            [Paragraph(text, ps("IT", fontName="Helvetica", fontSize=9.8,
            textColor=DARK_TEXT, leading=14, alignment=TA_JUSTIFY))]]
    tbl = Table(rows, colWidths=[15*cm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), bg),
        ("BOX", (0,0), (-1,-1), 1, RED_MED),
        ("LEFTPADDING",  (0,0), (-1,-1), 10),
        ("RIGHTPADDING", (0,0), (-1,-1), 10),
        ("TOPPADDING",   (0,0), (-1,-1), 6),
        ("BOTTOMPADDING",(0,0), (-1,-1), 6),
    ]))
    return [tbl, Spacer(1, 6)]


def two_col_table(headers, rows_data, col_widths=None):
    col_widths = col_widths or [5*cm, 10*cm]
    data = [headers] + rows_data
    tbl = Table(data, colWidths=col_widths)
    style = [
        ("BACKGROUND",    (0,0), (-1,0), RED_DARK),
        ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
        ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
        ("FONTSIZE",      (0,0), (-1,-1), 9.5),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
        ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 8),
    ]
    tbl.setStyle(TableStyle(style))
    return [tbl, Spacer(1, 8)]


def bullet_item(text):
    return Paragraph(f"<bullet>&bull;</bullet> {text}", BULLET)


def hr():
    return HRFlowable(width="100%", thickness=1, color=GREY_LINE,
                      spaceAfter=6, spaceBefore=6)

# ══════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ══════════════════════════════════════════════════════════════════════════════
story = []

# ─────────────────────────────────────────────────────
# COVER PAGE
# ─────────────────────────────────────────────────────
cover_table = Table([[""]], colWidths=[17*cm], rowHeights=[25*cm])
cover_table.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), RED_DARK),
    ("ROUNDEDCORNERS", [8,8,8,8]),
]))

story.append(Spacer(1, 0.5*cm))
story.append(cover_table)
# Overlay text by building cover as a single table with text inside
# Rebuild cover as proper table
cover_inner = Table([
    [Paragraph("&#x2665;", ps("CI", fontName="Helvetica-Bold", fontSize=60,
               textColor=HexColor("#C0392B"), alignment=TA_CENTER))],
    [Spacer(1, 0.3*cm)],
    [Paragraph("BLOOD", COVER_TITLE)],
    [Paragraph("A Comprehensive Introduction", COVER_SUB)],
    [Spacer(1, 0.4*cm)],
    [Paragraph("Properties · Composition · Blood Cells · Plasma · Serum · Functions",
               COVER_SUB)],
    [Spacer(1, 1.5*cm)],
    [Paragraph("Medical Physiology Notes  |  July 2026", COVER_DATE)],
], colWidths=[15*cm])
cover_inner.setStyle(TableStyle([
    ("BACKGROUND", (0,0), (-1,-1), RED_DARK),
    ("ALIGN", (0,0), (-1,-1), "CENTER"),
    ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING", (0,0), (-1,-1), 6),
    ("BOTTOMPADDING", (0,0), (-1,-1), 6),
    ("LEFTPADDING", (0,0), (-1,-1), 20),
    ("RIGHTPADDING", (0,0), (-1,-1), 20),
    ("ROUNDEDCORNERS", [8,8,8,8]),
]))

story.pop()  # remove blank cover table
story.append(Spacer(1, 0.5*cm))
story.append(cover_inner)
story.append(PageBreak())

# ─────────────────────────────────────────────────────
# TABLE OF CONTENTS
# ─────────────────────────────────────────────────────
story.append(Paragraph("TABLE OF CONTENTS", ps("TOC_H",
    fontName="Helvetica-Bold", fontSize=18, textColor=RED_DARK,
    alignment=TA_CENTER, spaceAfter=12)))
story.append(hr())

toc_items = [
    ("1", "Introduction", ""),
    ("2", "Properties of Blood", ""),
    ("3", "Composition of Blood", ""),
    ("4", "Blood Cells", ""),
    ("  4.1", "Red Blood Cells (Erythrocytes)", ""),
    ("  4.2", "White Blood Cells (Leukocytes)", ""),
    ("  4.3", "Platelets (Thrombocytes)", ""),
    ("5", "Plasma", ""),
    ("  5.1", "Plasma Proteins", ""),
    ("  5.2", "Other Plasma Components", ""),
    ("6", "Serum", ""),
    ("7", "Functions of Blood", ""),
    ("  7.1", "Nutritive Function", ""),
    ("  7.2", "Respiratory Function", ""),
    ("  7.3", "Excretory Function", ""),
    ("  7.4", "Transport of Hormones & Enzymes", ""),
    ("  7.5", "Regulation of Water Balance", ""),
    ("  7.6", "Regulation of Acid-Base Balance", ""),
    ("  7.7", "Regulation of Body Temperature", ""),
    ("  7.8", "Storage Function", ""),
    ("  7.9", "Defensive Function", ""),
]
for num, title, pg in toc_items:
    tbl = Table([[
        Paragraph(f"<b>{num}</b>", ps("TN", fontName="Helvetica-Bold",
                  fontSize=10, textColor=RED_MED, leading=14)),
        Paragraph(title, ps("TT", fontName="Helvetica", fontSize=10,
                  textColor=DARK_TEXT, leading=14)),
    ]], colWidths=[1.8*cm, 13.2*cm])
    tbl.setStyle(TableStyle([
        ("VALIGN", (0,0), (-1,-1), "MIDDLE"),
        ("BOTTOMPADDING", (0,0), (-1,-1), 2),
        ("TOPPADDING", (0,0), (-1,-1), 2),
    ]))
    story.append(tbl)

story.append(PageBreak())

# ═════════════════════════════════════════════════════
# SECTION 1 – INTRODUCTION
# ═════════════════════════════════════════════════════
story += chapter_banner("01", "INTRODUCTION")

story.append(Paragraph("What is Blood?", SECTION))
story.append(Paragraph(
    "Blood is a complex, specialized connective tissue consisting of cellular elements "
    "suspended in a fluid medium called plasma. It is the only fluid tissue in the body "
    "and forms the main transport system, linking every organ and tissue together. "
    "Total blood volume averages <b>5–6 litres</b> in an adult (approximately <b>70–80 mL/kg</b> "
    "body weight: ~70 mL/kg in women, ~80 mL/kg in men).",
    BODY))

story += info_box(
    "Quick Facts",
    "Total blood volume: 5–6 L in an adult (70–80 mL/kg body weight).  "
    "Hematocrit: ~40% (women), ~45% (men).  "
    "pH: 7.35–7.45.  "
    "Temperature: 38°C (slightly above core body temperature)."
)

story.append(Paragraph(
    "Blood circulates through the cardiovascular system driven by the heart, "
    "completing roughly one full circuit every minute at rest. It acts simultaneously "
    "as a transport medium, a buffer system, a thermoregulator, and an immune defence.",
    BODY))
story.append(hr())

# ═════════════════════════════════════════════════════
# SECTION 2 – PROPERTIES
# ═════════════════════════════════════════════════════
story += chapter_banner("02", "PROPERTIES OF BLOOD")
story.append(Spacer(1, 4))

props = [
    [Paragraph("<b>Property</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Value / Description</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13))],
    [Paragraph("Colour", BODY), Paragraph("Bright red (oxygenated) / Dark red–purple (deoxygenated)", BODY)],
    [Paragraph("Volume", BODY), Paragraph("5–6 L in adults (70–80 mL/kg body weight)", BODY)],
    [Paragraph("Viscosity", BODY), Paragraph("3.5–5.5× that of water; increases with hematocrit", BODY)],
    [Paragraph("Specific gravity", BODY), Paragraph("Whole blood: 1.050–1.060; Plasma: 1.025–1.029", BODY)],
    [Paragraph("pH", BODY), Paragraph("7.35–7.45 (slightly alkaline)", BODY)],
    [Paragraph("Osmolarity", BODY), Paragraph("285–295 mOsm/L", BODY)],
    [Paragraph("Temperature", BODY), Paragraph("38°C (slightly above body temperature)", BODY)],
    [Paragraph("Reaction", BODY), Paragraph("Slightly alkaline; maintained by buffer systems", BODY)],
    [Paragraph("Taste / Smell", BODY), Paragraph("Slightly salty; distinctive odour due to iron in haem", BODY)],
]

tbl = Table(props, colWidths=[5*cm, 10*cm])
tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
    ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
]))
story.append(tbl)
story.append(Spacer(1, 6))
story.append(hr())

# ═════════════════════════════════════════════════════
# SECTION 3 – COMPOSITION
# ═════════════════════════════════════════════════════
story += chapter_banner("03", "COMPOSITION OF BLOOD")

story.append(Paragraph(
    "Whole blood is a suspension of cellular (formed) elements in plasma. When a "
    "blood sample is centrifuged, it separates into three distinct layers:",
    BODY))
story.append(Spacer(1, 4))

comp_rows = [
    [Paragraph("<b>Layer</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Component</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>% of Total Blood</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13))],
    [Paragraph("Top (pale yellow)", BODY), Paragraph("Plasma (fluid portion)", BODY), Paragraph("55%", BODY)],
    [Paragraph("Thin white layer", BODY), Paragraph("Buffy coat (WBCs + platelets)", BODY), Paragraph("<1%", BODY)],
    [Paragraph("Bottom (red)", BODY), Paragraph("Red blood cells (erythrocytes)", BODY), Paragraph("~45%", BODY)],
]

tbl2 = Table(comp_rows, colWidths=[4.5*cm, 7*cm, 3.5*cm])
tbl2.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("FONTNAME",      (0,0), (-1,0), "Helvetica-Bold"),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
    ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
    ("ALIGN",         (2,0), (2,-1), "CENTER"),
]))
story.append(tbl2)
story.append(Spacer(1, 8))

story.append(Paragraph("Hematocrit (Packed Cell Volume)", SUBSECTION))
story.append(Paragraph(
    "The <b>hematocrit (HCT)</b> is the fraction of total blood volume occupied by RBCs. "
    "Normal values: <b>40% in adult women</b> and <b>45% in adult men</b>. In newborns it is ~55%, "
    "falling to ~35% by 2 months of age, then gradually rising to adult values at puberty.",
    BODY))
story.append(hr())

# ═════════════════════════════════════════════════════
# SECTION 4 – BLOOD CELLS
# ═════════════════════════════════════════════════════
story += chapter_banner("04", "BLOOD CELLS")

# 4.1 RBCs
story.append(Paragraph("4.1  Red Blood Cells (Erythrocytes)", SECTION))
story.append(Paragraph(
    "RBCs are the most numerous cells in blood and are responsible for O₂ and CO₂ transport. "
    "They are biconcave, anucleate discs (~7–8 µm diameter) packed with <b>haemoglobin (Hb)</b>.",
    BODY))

rbc_data = [
    [Paragraph("<b>Parameter</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Normal Values</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13))],
    [Paragraph("Count", BODY), Paragraph("Men: 4.5–5.5 × 10¹²/L; Women: 3.8–4.8 × 10¹²/L", BODY)],
    [Paragraph("Haemoglobin", BODY), Paragraph("Men: 13.5–17.5 g/dL; Women: 12.0–15.5 g/dL", BODY)],
    [Paragraph("Life span", BODY), Paragraph("~120 days", BODY)],
    [Paragraph("Site of production", BODY), Paragraph("Bone marrow (regulated by erythropoietin from kidneys)", BODY)],
    [Paragraph("Site of destruction", BODY), Paragraph("Spleen, liver (reticuloendothelial system)", BODY)],
    [Paragraph("Shape", BODY), Paragraph("Biconcave disc – maximises surface area:volume ratio for gas exchange", BODY)],
]
tbl3 = Table(rbc_data, colWidths=[4.5*cm, 10.5*cm])
tbl3.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED_MED),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
    ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
]))
story.append(tbl3)
story.append(Spacer(1, 8))

# 4.2 WBCs
story.append(Paragraph("4.2  White Blood Cells (Leukocytes)", SECTION))
story.append(Paragraph(
    "WBCs are nucleated cells that form the cellular arm of immunity. "
    "Normal total WBC count is <b>4,000–11,000/µL</b>. They are classified into "
    "granulocytes and agranulocytes:",
    BODY))
story.append(Spacer(1, 4))

wbc_data = [
    [Paragraph("<b>Cell Type</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>% of WBCs</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Key Function</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13))],
    [Paragraph("Neutrophils", BODY), Paragraph("50–70%", BODY), Paragraph("Phagocytosis; first responders to bacterial infection", BODY)],
    [Paragraph("Eosinophils", BODY), Paragraph("2–4%", BODY), Paragraph("Allergy; parasitic infections; modulate inflammation", BODY)],
    [Paragraph("Basophils", BODY), Paragraph("<1%", BODY), Paragraph("Release histamine; mediate allergic & inflammatory reactions", BODY)],
    [Paragraph("Lymphocytes", BODY), Paragraph("20–40%", BODY), Paragraph("Adaptive immunity – B cells (antibodies), T cells (cell-mediated)", BODY)],
    [Paragraph("Monocytes", BODY), Paragraph("4–8%", BODY), Paragraph("Phagocytosis; differentiate into macrophages in tissues", BODY)],
]
tbl4 = Table(wbc_data, colWidths=[3.5*cm, 2.5*cm, 9*cm])
tbl4.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED_MED),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
    ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
]))
story.append(tbl4)
story.append(Spacer(1, 8))

# 4.3 Platelets
story.append(Paragraph("4.3  Platelets (Thrombocytes)", SECTION))
story.append(Paragraph(
    "Platelets are small, anucleate fragments derived from megakaryocytes in the bone marrow. "
    "Normal count: <b>150,000–400,000/µL</b>. Life span: ~10 days. "
    "They are essential for primary haemostasis – forming the initial platelet plug at sites of "
    "vessel injury and releasing factors that activate the clotting cascade.",
    BODY))
story.append(hr())

# ═════════════════════════════════════════════════════
# SECTION 5 – PLASMA
# ═════════════════════════════════════════════════════
story.append(PageBreak())
story += chapter_banner("05", "PLASMA")

story.append(Paragraph(
    "Plasma is the pale-yellow, non-cellular liquid fraction of blood (~55% of blood volume). "
    "It is a remarkable solution containing water (~91–92%), proteins (~7%), and small "
    "molecules (~1–2%) including electrolytes, nutrients, gases, hormones, and waste products.",
    BODY))
story.append(Spacer(1, 4))

plasma_comp = [
    [Paragraph("<b>Component</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Approximate Concentration / Notes</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13))],
    [Paragraph("Water", BODY), Paragraph("91–92% of plasma volume", BODY)],
    [Paragraph("Total Proteins", BODY), Paragraph("~7.0 g/dL; oncotic pressure ~25 mmHg", BODY)],
    [Paragraph("Albumin", BODY), Paragraph("3.5–5.5 g/dL; transport, oncotic pressure, pH buffering", BODY)],
    [Paragraph("Globulins", BODY), Paragraph("2.0–3.5 g/dL; immune functions (IgG, IgA, IgM etc.)", BODY)],
    [Paragraph("Fibrinogen", BODY), Paragraph("200–400 mg/dL; precursor to fibrin in clotting", BODY)],
    [Paragraph("Glucose", BODY), Paragraph("70–110 mg/dL (fasting)", BODY)],
    [Paragraph("Urea", BODY), Paragraph("7–20 mg/dL; principal nitrogenous waste", BODY)],
    [Paragraph("Na⁺", BODY), Paragraph("136–145 mEq/L; major extracellular cation", BODY)],
    [Paragraph("K⁺", BODY), Paragraph("3.5–5.0 mEq/L", BODY)],
    [Paragraph("Ca²⁺", BODY), Paragraph("8.5–10.5 mg/dL", BODY)],
    [Paragraph("Cl⁻", BODY), Paragraph("98–106 mEq/L; major extracellular anion", BODY)],
    [Paragraph("HCO₃⁻", BODY), Paragraph("22–29 mEq/L; primary CO₂ transport form and buffer", BODY)],
]
tbl5 = Table(plasma_comp, colWidths=[4*cm, 11*cm])
tbl5.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
    ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
]))
story.append(tbl5)
story.append(Spacer(1, 8))

story.append(Paragraph("Plasma Proteins – Detailed Overview", SUBSECTION))
story.append(Paragraph(
    "Plasma proteins are synthesised mainly in the liver (except immunoglobulins, which are "
    "made by plasma cells). They serve transport, oncotic, buffering, coagulation, and immune "
    "functions. At normal plasma pH 7.40, most proteins are in anionic form, contributing ~15% "
    "of total blood buffering capacity.",
    BODY))
story += info_box(
    "Albumin – Key Functions",
    "1. Maintains colloid osmotic (oncotic) pressure (~25 mmHg) – keeps fluid in the vasculature.  "
    "2. Transports fatty acids, bilirubin, calcium, drugs (e.g. warfarin, phenytoin) and hormones.  "
    "3. Contributes to acid-base buffering.  "
    "Half-life: ~20 days. Synthesised in liver at ~120 mg/kg/day."
)
story.append(hr())

# ═════════════════════════════════════════════════════
# SECTION 6 – SERUM
# ═════════════════════════════════════════════════════
story += chapter_banner("06", "SERUM")

story.append(Paragraph(
    "Serum is the fluid that remains after whole blood has been allowed to clot and the clot "
    "(containing RBCs, platelets, and fibrin) has been removed. "
    "Serum has essentially the same composition as plasma <b>except</b>:",
    BODY))
story.append(Spacer(1, 4))
for item in [
    "Fibrinogen is absent (consumed during clotting to form fibrin).",
    "Clotting factors II, V, and VIII are removed.",
    "Serotonin content is higher (released by platelet breakdown during clotting).",
    "Calcium and potassium levels may be slightly higher due to platelet release.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

diff_data = [
    [Paragraph("<b>Feature</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Plasma</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13)),
     Paragraph("<b>Serum</b>", ps("PH", fontName="Helvetica-Bold", fontSize=10, textColor=WHITE, leading=13))],
    [Paragraph("Fibrinogen", BODY), Paragraph("Present", BODY), Paragraph("Absent", BODY)],
    [Paragraph("Clotting factors", BODY), Paragraph("All present", BODY), Paragraph("II, V, VIII absent", BODY)],
    [Paragraph("Anticoagulant needed?", BODY), Paragraph("Yes", BODY), Paragraph("No (blood allowed to clot)", BODY)],
    [Paragraph("Serotonin", BODY), Paragraph("Low", BODY), Paragraph("Higher", BODY)],
    [Paragraph("Main use", BODY), Paragraph("Electrolytes, coagulation studies", BODY), Paragraph("Most biochemistry tests, serology", BODY)],
]
tbl6 = Table(diff_data, colWidths=[4.5*cm, 5.5*cm, 5*cm])
tbl6.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), RED_DARK),
    ("TEXTCOLOR",     (0,0), (-1,0), WHITE),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, RED_PALE]),
    ("GRID",          (0,0), (-1,-1), 0.5, GREY_LINE),
    ("VALIGN",        (0,0), (-1,-1), "MIDDLE"),
    ("TOPPADDING",    (0,0), (-1,-1), 5),
    ("BOTTOMPADDING", (0,0), (-1,-1), 5),
    ("LEFTPADDING",   (0,0), (-1,-1), 8),
    ("RIGHTPADDING",  (0,0), (-1,-1), 8),
]))
story.append(tbl6)
story.append(hr())

# ═════════════════════════════════════════════════════
# SECTION 7 – FUNCTIONS
# ═════════════════════════════════════════════════════
story.append(PageBreak())
story += chapter_banner("07", "FUNCTIONS OF BLOOD")

story.append(Paragraph(
    "Blood serves an extraordinary variety of physiological functions. "
    "These can be grouped into transport, regulatory, and protective categories:",
    BODY))
story.append(Spacer(1, 6))

# 7.1 Nutritive
story.append(Paragraph("7.1  Nutritive Function", SECTION))
story.append(Paragraph(
    "Blood transports absorbed nutrients from the gastrointestinal tract to every cell in the body:",
    BODY))
for item in [
    "Glucose from the intestinal mucosa via the portal circulation to the liver and peripheral tissues.",
    "Amino acids absorbed after protein digestion, distributed for protein synthesis and energy.",
    "Fatty acids and glycerol (as chylomicrons and VLDL) transported from the gut and liver.",
    "Fat-soluble vitamins (A, D, E, K) carried bound to plasma proteins.",
    "Water-soluble vitamins (B complex, C) dissolved in plasma.",
    "Minerals (iron, calcium, phosphate) transported in free or protein-bound form.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.2 Respiratory
story.append(Paragraph("7.2  Respiratory Function", SECTION))
story.append(Paragraph(
    "Blood is the primary medium for gas exchange between the lungs and tissues:",
    BODY))
for item in [
    "<b>Oxygen (O₂):</b> ~98% carried bound to haemoglobin as oxyhaemoglobin (HbO₂); ~2% dissolved in plasma.",
    "<b>Carbon dioxide (CO₂):</b> ~70% as bicarbonate (HCO₃⁻) in plasma; ~23% as carbaminohaemoglobin; ~7% dissolved.",
    "The P50 of adult haemoglobin is ~26.5 mmHg; the sigmoid O₂ dissociation curve allows efficient loading and unloading.",
    "Factors promoting O₂ unloading to tissues (Bohr effect): ↑CO₂, ↑temperature, ↑2,3-BPG, ↓pH.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.3 Excretory
story.append(Paragraph("7.3  Excretory Function", SECTION))
story.append(Paragraph(
    "Metabolic waste products are collected from cells and transported to excretory organs:",
    BODY))
for item in [
    "Urea (from protein catabolism) – transported to kidneys for urinary excretion.",
    "Uric acid (from purine catabolism) – excreted by kidneys.",
    "Creatinine (from muscle metabolism) – glomerular filtration.",
    "Bilirubin (from haem degradation) – transported to liver, conjugated, and excreted in bile.",
    "CO₂ (metabolic waste gas) – transported to lungs for exhalation.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.4 Hormones & Enzymes
story.append(Paragraph("7.4  Transport of Hormones and Enzymes", SECTION))
story.append(Paragraph(
    "Blood is the highway for chemical messengers produced by endocrine glands:",
    BODY))
for item in [
    "Hormones (insulin, thyroxine, cortisol, ADH, ACTH) travel in plasma – free or protein-bound – to distant target organs.",
    "Thyroid hormones are >99% protein-bound to TBG (thyroxine-binding globulin) and transthyretin.",
    "Steroid hormones bind albumin and specific binding globulins (CBG, SHBG).",
    "Enzymes such as amylase, lipase, and ALT circulate in plasma; elevated levels signal organ disease.",
    "Clotting factors (zymogens) circulate in plasma until activated by vascular injury.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.5 Water balance
story.append(Paragraph("7.5  Regulation of Water Balance", SECTION))
story.append(Paragraph(
    "Blood volume and plasma osmolarity are tightly regulated to maintain fluid homeostasis:",
    BODY))
for item in [
    "Plasma proteins (chiefly albumin) exert colloid osmotic (oncotic) pressure (~25 mmHg) that retains water in the vascular compartment.",
    "Hydrostatic pressure drives fluid out of capillaries; oncotic pressure draws it back (Starling forces).",
    "ADH (vasopressin) is released in response to plasma hyperosmolarity, increasing renal water reabsorption.",
    "Aldosterone promotes Na⁺ reabsorption (and thus water) when blood volume falls.",
    "Atrial natriuretic peptide (ANP) promotes Na⁺ and water excretion when blood volume rises.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.6 Acid-base
story.append(Paragraph("7.6  Regulation of Acid-Base Balance", SECTION))
story.append(Paragraph(
    "Blood maintains pH within the narrow range of <b>7.35–7.45</b> via three interacting mechanisms:",
    BODY))
for item in [
    "<b>Chemical buffers (immediate):</b> Bicarbonate/carbonic acid (most important), haemoglobin, plasma proteins, phosphate.",
    "<b>Respiratory compensation:</b> CO₂ (volatile acid) is eliminated by adjusting ventilation rate (minutes to hours).",
    "<b>Renal compensation:</b> Kidneys excrete H⁺ and reabsorb/generate HCO₃⁻ (hours to days).",
    "Henderson-Hasselbalch: pH = 6.1 + log ([HCO₃⁻] / 0.03 × PaCO₂). Normal HCO₃⁻: 22–26 mEq/L.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.7 Temperature
story.append(Paragraph("7.7  Regulation of Body Temperature", SECTION))
story.append(Paragraph(
    "Blood is the primary medium for heat distribution and dissipation in the body:",
    BODY))
for item in [
    "Absorbs heat produced by active muscles and metabolically active organs (liver, heart).",
    "Redistributes heat to the periphery (skin) where it can be lost via radiation, conduction, and evaporation.",
    "Peripheral vasodilation increases blood flow to skin for heat loss; vasoconstriction conserves heat in cold environments.",
    "Sweating (controlled by the hypothalamus) uses the high latent heat of vaporisation of water to cool the blood.",
    "The high specific heat capacity of water in plasma helps buffer sudden temperature changes.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.8 Storage
story.append(Paragraph("7.8  Storage Function", SECTION))
story.append(Paragraph(
    "Blood and blood-forming organs serve as dynamic reservoirs for several substances:",
    BODY))
for item in [
    "The <b>spleen</b> acts as a reservoir for ~250–300 mL of blood; it stores RBCs and platelets that can be mobilised in haemorrhage.",
    "Liver stores excess glucose as glycogen; mobilises it to blood as glucose during fasting.",
    "Iron is stored as ferritin and haemosiderin in liver, spleen, and bone marrow; released bound to transferrin in plasma.",
    "Fat-soluble vitamins (A, D, E, K) are stored in the liver and released into circulation as needed.",
    "Plasma proteins such as albumin represent a labile protein reserve that can be catabolised during starvation.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 6))

# 7.9 Defensive
story.append(Paragraph("7.9  Defensive Function", SECTION))
story.append(Paragraph(
    "Blood provides both innate and adaptive immunity and protects against blood loss:",
    BODY))
for item in [
    "<b>Leucocytes:</b> Neutrophils and macrophages phagocytose pathogens; lymphocytes mount specific immune responses.",
    "<b>Antibodies (immunoglobulins):</b> Produced by plasma cells; neutralise toxins, opsonise bacteria, activate complement.",
    "<b>Complement system:</b> Cascade of plasma proteins that lyse pathogens, recruit phagocytes, and enhance opsonisation.",
    "<b>Haemostasis:</b> Platelets form a primary plug at vessel injury; the coagulation cascade (factors I–XIII) forms a stable fibrin clot to prevent blood loss.",
    "<b>Fibrinolysis:</b> Plasmin degrades fibrin clots once healing is complete, maintaining vascular patency.",
    "<b>Fever response:</b> Pyrogenic cytokines (IL-1, IL-6, TNF-α) are transported in blood to the hypothalamus, raising body temperature to impair microbial growth.",
]:
    story.append(bullet_item(item))
story.append(Spacer(1, 8))

story += info_box(
    "Summary – Functions of Blood at a Glance",
    "Transport (O₂, CO₂, nutrients, hormones, enzymes, waste) | "
    "Regulation (water balance, acid-base, temperature) | "
    "Protection (immunity, haemostasis, defensive cells) | "
    "Storage (iron, vitamins, glycogen reserve via liver)"
)
story.append(hr())

# ─────────────────────────────────────────────────────
# FOOTER / REFERENCES PAGE
# ─────────────────────────────────────────────────────
story.append(PageBreak())
story.append(Paragraph("SOURCES & REFERENCES", ps("REF_H",
    fontName="Helvetica-Bold", fontSize=14, textColor=RED_DARK,
    spaceAfter=8)))
story.append(hr())
refs = [
    "Boron WF, Boulpaep EL. Medical Physiology, 3rd Edition. Chapter 18: Blood. Elsevier; 2017.",
    "Barrett KE, Barman SM, Brooks HL, Yuan J-XJ. Ganong's Review of Medical Physiology, 26th Edition. Chapter 31. McGraw-Hill; 2019.",
    "Ganong WF. Review of Medical Physiology – Plasma, Plasma Proteins, and Haemostasis sections.",
    "Hall JE. Guyton and Hall Textbook of Medical Physiology, 14th Edition. Elsevier; 2021.",
    "Longo DL, et al. Harrison's Principles of Internal Medicine, 20th Edition. McGraw-Hill; 2018.",
]
for i, ref in enumerate(refs, 1):
    story.append(Paragraph(f"[{i}]  {ref}", ps("RefItem",
        fontName="Helvetica", fontSize=9.5, textColor=MID_TEXT,
        spaceBefore=4, spaceAfter=4, leading=14, leftIndent=14)))

story.append(Spacer(1, 1*cm))
story.append(Paragraph(
    "This document was prepared as a medical physiology study aid. "
    "All values are representative adult reference ranges; clinical decisions should always "
    "be based on current institutional guidelines and patient-specific factors.",
    NOTE_STYLE))

# ══════════════════════════════════════════════════════════════════════════════
# BUILD PDF
# ══════════════════════════════════════════════════════════════════════════════
def add_page_number(canvas, doc):
    canvas.saveState()
    canvas.setFont("Helvetica", 8)
    canvas.setFillColor(MID_TEXT)
    # Footer bar
    canvas.setFillColor(RED_PALE)
    canvas.rect(doc.leftMargin, 1.2*cm,
                A4[0] - doc.leftMargin - doc.rightMargin, 0.6*cm, fill=1, stroke=0)
    canvas.setFillColor(RED_MED)
    canvas.setFont("Helvetica-Bold", 8)
    canvas.drawString(doc.leftMargin + 4, 1.45*cm, "BLOOD – Introduction to Medical Physiology")
    canvas.drawRightString(A4[0] - doc.rightMargin - 4, 1.45*cm, f"Page {doc.page}")
    canvas.restoreState()

doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)
print("PDF generated successfully:", OUTPUT)
Running Command

cd /home/daytona/workspace/blood-pdf && python generate_blood_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/blood-pdf/Blood_Introduction.pdf

Your PDF has been generated successfully. Here is your download link:

Blood Introduction

PDF Document · PDF


What's inside the PDF (7 sections across multiple pages):
SectionContent
Cover PageStyled title page with red theme
Table of ContentsAll 7 sections with subsections listed
1 - IntroductionDefinition, volume (5-6 L, 70-80 mL/kg), quick facts box
2 - PropertiesFull table: colour, volume, viscosity, specific gravity, pH (7.35-7.45), osmolarity, temperature
3 - CompositionCentrifugation layers, hematocrit values (40% women, 45% men)
4 - Blood CellsRBCs (count, Hb, lifespan, shape), WBCs (5-type differential table), Platelets
5 - PlasmaFull composition table (water, proteins, electrolytes, glucose, urea), albumin functions box
6 - SerumPlasma vs Serum comparison table (fibrinogen, clotting factors, serotonin, clinical uses)
7 - FunctionsAll 9 functions with bullet points: Nutritive, Respiratory (O₂/CO₂ transport), Excretory, Hormones/Enzymes, Water balance, Acid-base (Henderson-Hasselbalch), Temperature, Storage, Defensive
ReferencesBoron & Boulpaep, Ganong's, Guyton, Harrison's
The design uses a red/white medical theme with colour-coded section banners, formatted tables, and highlighted information boxes throughout.
This is a shared conversation. Sign in to Orris to start your own chat.