~/blood-test-guide/create_pdf.py
#!/usr/bin/env python3
# Blood Test Reference Guide - Hindi PDF Generator
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm, cm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_RIGHT
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import os
# ─── Register Hindi-capable font ───────────────────────────────────────────
# Try to find a Unicode font that supports Devanagari
FONT_PATHS = [
"/usr/share/fonts/truetype/noto/NotoSansDevanagari-Regular.ttf",
"/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf",
"/usr/share/fonts/opentype/noto/NotoSansDevanagari-Regular.otf",
"/usr/share/fonts/truetype/lohit-devanagari/Lohit-Devanagari.ttf",
"/usr/share/fonts/truetype/freefont/FreeSans.ttf",
]
BOLD_PATHS = [
"/usr/share/fonts/truetype/noto/NotoSansDevanagari-Bold.ttf",
"/usr/share/fonts/truetype/noto/NotoSans-Bold.ttf",
"/usr/share/fonts/opentype/noto/NotoSansDevanagari-Bold.otf",
"/usr/share/fonts/truetype/lohit-devanagari/Lohit-Devanagari.ttf",
]
font_reg = None
font_bold = None
for p in FONT_PATHS:
if os.path.exists(p):
font_reg = p
break
for p in BOLD_PATHS:
if os.path.exists(p):
font_bold = p
break
if font_reg:
pdfmetrics.registerFont(TTFont("Hindi", font_reg))
FONT = "Hindi"
else:
FONT = "Helvetica"
if font_bold:
pdfmetrics.registerFont(TTFont("HindiBold", font_bold))
FONT_B = "HindiBold"
else:
FONT_B = "Helvetica-Bold"
print(f"Using font: {FONT} | bold: {FONT_B}")
# ─── Colors ────────────────────────────────────────────────────────────────
RED = colors.HexColor("#C0392B")
DARK_RED = colors.HexColor("#922B21")
BLUE = colors.HexColor("#1A5276")
LIGHT_BLUE= colors.HexColor("#D6EAF8")
GREEN = colors.HexColor("#1E8449")
LIGHT_GREEN=colors.HexColor("#D5F5E3")
ORANGE = colors.HexColor("#E67E22")
LIGHT_ORANGE=colors.HexColor("#FDEBD0")
PURPLE = colors.HexColor("#6C3483")
LIGHT_PURPLE=colors.HexColor("#E8DAEF")
TEAL = colors.HexColor("#117A65")
LIGHT_TEAL= colors.HexColor("#D0ECE7")
YELLOW_BG = colors.HexColor("#FEF9E7")
HEADER_BG = colors.HexColor("#1B2631")
GRAY_LIGHT= colors.HexColor("#F2F3F4")
GRAY_MID = colors.HexColor("#BFC9CA")
WHITE = colors.white
BLACK = colors.black
# ─── Styles ────────────────────────────────────────────────────────────────
def make_styles():
s = {}
s['cover_title'] = ParagraphStyle(
'cover_title', fontName=FONT_B, fontSize=28, textColor=WHITE,
alignment=TA_CENTER, leading=36, spaceAfter=6
)
s['cover_sub'] = ParagraphStyle(
'cover_sub', fontName=FONT, fontSize=14, textColor=colors.HexColor("#AED6F1"),
alignment=TA_CENTER, leading=20
)
s['cover_date'] = ParagraphStyle(
'cover_date', fontName=FONT, fontSize=10, textColor=colors.HexColor("#85929E"),
alignment=TA_CENTER
)
s['section_heading'] = ParagraphStyle(
'section_heading', fontName=FONT_B, fontSize=14, textColor=WHITE,
alignment=TA_LEFT, leading=18, leftIndent=6, spaceAfter=4, spaceBefore=8
)
s['sub_heading'] = ParagraphStyle(
'sub_heading', fontName=FONT_B, fontSize=11, textColor=BLUE,
alignment=TA_LEFT, leading=16, spaceAfter=2, spaceBefore=6
)
s['body'] = ParagraphStyle(
'body', fontName=FONT, fontSize=9, textColor=BLACK,
alignment=TA_LEFT, leading=14, spaceAfter=3
)
s['body_small'] = ParagraphStyle(
'body_small', fontName=FONT, fontSize=8, textColor=colors.HexColor("#4A4A4A"),
alignment=TA_LEFT, leading=12
)
s['note'] = ParagraphStyle(
'note', fontName=FONT, fontSize=8, textColor=colors.HexColor("#7D6608"),
alignment=TA_LEFT, leading=12, leftIndent=8, borderPad=4
)
s['tbl_header'] = ParagraphStyle(
'tbl_header', fontName=FONT_B, fontSize=8, textColor=WHITE,
alignment=TA_CENTER, leading=11
)
s['tbl_cell'] = ParagraphStyle(
'tbl_cell', fontName=FONT, fontSize=8, textColor=BLACK,
alignment=TA_LEFT, leading=11
)
s['tbl_cell_c'] = ParagraphStyle(
'tbl_cell_c', fontName=FONT, fontSize=8, textColor=BLACK,
alignment=TA_CENTER, leading=11
)
s['footer'] = ParagraphStyle(
'footer', fontName=FONT, fontSize=7, textColor=colors.HexColor("#717D7E"),
alignment=TA_CENTER
)
s['toc_item'] = ParagraphStyle(
'toc_item', fontName=FONT, fontSize=10, textColor=BLUE,
leftIndent=20, leading=18
)
s['toc_num'] = ParagraphStyle(
'toc_num', fontName=FONT_B, fontSize=10, textColor=DARK_RED,
leading=18
)
return s
# ─── Helper: colored section banner ───────────────────────────────────────
def section_banner(text, bg_color, styles):
data = [[Paragraph(text, styles['section_heading'])]]
t = Table(data, colWidths=[170*mm])
t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), bg_color),
('ROUNDEDCORNERS', [4,4,4,4]),
('BOX', (0,0), (-1,-1), 0, bg_color),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
return t
# ─── Helper: data table ────────────────────────────────────────────────────
def data_table(headers, rows, col_widths, header_color, styles, alt_color=GRAY_LIGHT):
h_cells = [Paragraph(h, styles['tbl_header']) for h in headers]
data = [h_cells]
for row in rows:
data.append([Paragraph(str(c), styles['tbl_cell']) for c in row])
t = Table(data, colWidths=col_widths, repeatRows=1)
style = [
('BACKGROUND', (0,0), (-1,0), header_color),
('FONTNAME', (0,0), (-1,0), FONT_B),
('FONTSIZE', (0,0), (-1,-1), 8),
('GRID', (0,0), (-1,-1), 0.4, GRAY_MID),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, alt_color]),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 5),
('RIGHTPADDING', (0,0), (-1,-1), 5),
]
t.setStyle(TableStyle(style))
return t
# ─── Page callbacks ────────────────────────────────────────────────────────
def on_page(canvas, doc):
W, H = A4
# footer line
canvas.setStrokeColor(GRAY_MID)
canvas.setLineWidth(0.5)
canvas.line(15*mm, 12*mm, W - 15*mm, 12*mm)
# footer text
canvas.setFont(FONT, 7)
canvas.setFillColor(colors.HexColor("#717D7E"))
canvas.drawCentredString(W/2, 8*mm, "Blood Test Reference Guide | yeh guide sirf reference ke liye hai - doctor ki salah zaroor len")
canvas.drawRightString(W - 15*mm, 8*mm, f"Page {doc.page}")
# ─── Build PDF ─────────────────────────────────────────────────────────────
OUT = "/home/daytona/workspace/blood-test-guide/Blood_Test_Reference_Guide.pdf"
doc = SimpleDocTemplate(
OUT, pagesize=A4,
leftMargin=15*mm, rightMargin=15*mm,
topMargin=15*mm, bottomMargin=20*mm,
title="Blood Test Reference Guide",
author="Orris Health Guide"
)
S = make_styles()
story = []
# ══════════════════════════════════════════════════════════════════════
# COVER PAGE
# ══════════════════════════════════════════════════════════════════════
W_page, H_page = A4
# Full-page cover background via a table
cover_data = [[
Paragraph("", S['body']) # placeholder; actual content drawn below
]]
story.append(Spacer(1, 30*mm))
# Big title block
title_block = Table(
[[Paragraph("Blood Test", S['cover_title'])],
[Paragraph("Reference Guide", S['cover_title'])],
[Spacer(1, 4*mm)],
[Paragraph("Khoon ki Jaanch - Poori Jaankari", S['cover_sub'])],
[Spacer(1, 3*mm)],
[HRFlowable(width="60%", thickness=1, color=colors.HexColor("#AED6F1"), hAlign='CENTER')],
[Spacer(1, 3*mm)],
[Paragraph("CBC | Diabetes | Thyroid | Liver | Kidney | Heart | Infection", S['cover_sub'])],
],
colWidths=[170*mm]
)
title_block.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), HEADER_BG),
('ALIGN', (0,0), (-1,-1), 'CENTER'),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('BOX', (0,0), (-1,-1), 2, RED),
]))
story.append(title_block)
story.append(Spacer(1, 8*mm))
# Info strip
info_data = [
[Paragraph("Taiyar kiya:", S['body_small']),
Paragraph("Orris Health Assistant", S['body']),
Paragraph("July 2026", S['body_small'])]
]
info_t = Table(info_data, colWidths=[35*mm, 100*mm, 35*mm])
info_t.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), LIGHT_BLUE),
('GRID', (0,0), (-1,-1), 0, WHITE),
('ALIGN', (1,0), (1,0), 'CENTER'),
('ALIGN', (2,0), (2,0), 'RIGHT'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
story.append(info_t)
story.append(Spacer(1, 6*mm))
# Disclaimer box
disc = Table([[Paragraph(
"IMPORTANT: Yeh guide sirf educational purpose ke liye hai. "
"Koi bhi test ya report ke liye apne doctor se salah zaroor len. "
"Khud se diagnosis ya treatment na karein.",
S['note']
)]], colWidths=[170*mm])
disc.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), YELLOW_BG),
('BOX', (0,0), (-1,-1), 1, ORANGE),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
]))
story.append(disc)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# TABLE OF CONTENTS
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" Vishay Soochi (Table of Contents)", DARK_RED, S))
story.append(Spacer(1, 4*mm))
toc_items = [
("1", "CBC – Complete Blood Count"),
("2", "Blood Sugar – Diabetes (Madhumeh)"),
("3", "Lipid Profile – Dil ki Bimari"),
("4", "Thyroid – TSH, T3, T4"),
("5", "Liver Function Test (LFT)"),
("6", "Kidney Function Test (KFT / RFT)"),
("7", "Infection / Bukhar – Dengue, Malaria, Typhoid"),
("8", "Haddi aur Jod – Vitamin D, Calcium, RA"),
("9", "Routine Full Body Checkup"),
("10", "Normal Values Quick Reference"),
]
for num, title in toc_items:
row_data = [[
Paragraph(num + ".", S['toc_num']),
Paragraph(title, S['toc_item'])
]]
row_t = Table(row_data, colWidths=[12*mm, 158*mm])
row_t.setStyle(TableStyle([
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 2),
('BOTTOMPADDING', (0,0), (-1,-1), 2),
]))
story.append(row_t)
story.append(HRFlowable(width="100%", thickness=0.3, color=GRAY_MID))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 1: CBC
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 1. CBC – Complete Blood Count", BLUE, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"CBC khoon ka sabse aam aur zaroori test hai. Isme khoon ke teeno mukhya "
"hisson ki jaanch hoti hai: Red Blood Cells, White Blood Cells, aur Platelets.",
S['body']
))
story.append(Spacer(1, 3*mm))
story.append(Paragraph("A) Red Blood Cells (RBC) – Laal Rakt Koshikaen", S['sub_heading']))
cbc_rbc = data_table(
["Parameter", "Purush (Male)", "Mahila (Female)", "Kaam / Matlab"],
[
["RBC Count", "4.5 – 5.9 M/uL", "4.1 – 5.1 M/uL", "Oxygen le jaana"],
["Hemoglobin (Hb)", "13.5 – 17.5 g/dL", "12.0 – 15.5 g/dL", "Khoon ka laal rang, O2 vahak"],
["Hematocrit (PCV)", "41 – 53%", "36 – 46%", "Khoon mein RBC ka %"],
["MCV", "80 – 100 fL", "80 – 100 fL", "RBC ka aakar"],
["MCH", "27 – 31 pg", "27 – 31 pg", "Har RBC mein Hb ki maatra"],
["MCHC", "32 – 36 g/dL", "32 – 36 g/dL", "RBC mein Hb ki saghanata"],
["RDW", "11.5 – 14.5%", "11.5 – 14.5%", "RBC ke aakar mein antar"],
],
[38*mm, 32*mm, 32*mm, 62*mm], BLUE, S
)
story.append(cbc_rbc)
story.append(Spacer(1, 2*mm))
anemia_data = data_table(
["Hb Kam + MCV", "Sambhavit Kaaran"],
[
["MCV Kam (< 80)", "Iron ki Kami (Sabse aam)"],
["MCV Zyada (> 100)", "Vitamin B12 ya Folic Acid ki kami"],
["MCV Saamaanya", "Chronic bimari, Kidney ki samasya"],
],
[60*mm, 110*mm], RED, S, LIGHT_BLUE
)
story.append(anemia_data)
story.append(Spacer(1, 3*mm))
story.append(Paragraph("B) White Blood Cells (WBC) – Safed Rakt Koshikaen", S['sub_heading']))
cbc_wbc = data_table(
["Parameter", "Saamaanya Maan", "Kaam"],
[
["Total WBC", "4,000 – 11,000 /uL", "Rog pratirodhak kshamata (Immunity)"],
["Neutrophils", "50 – 70%", "Bacterial sankraman se ladte hain"],
["Lymphocytes", "20 – 40%", "Viral sankraman / Immunity memory"],
["Monocytes", "2 – 8%", "Purane sankraman mein badhte hain"],
["Eosinophils", "1 – 4%", "Allergy / Parasite sankraman"],
["Basophils", "0.5 – 1%", "Allergic reaction"],
],
[40*mm, 40*mm, 90*mm], TEAL, S
)
story.append(cbc_wbc)
story.append(Spacer(1, 2*mm))
wbc_interp = data_table(
["WBC ka Haal", "Matlab"],
[
["WBC Zyada (Leukocytosis)", "Bacterial infection, Sujan (inflammation), Leukemia"],
["WBC Kam (Leukopenia)", "Viral bukhar (Dengue, Typhoid), Chemotherapy"],
["Neutrophils Zyada", "Bacterial ya fungal infection"],
["Lymphocytes Zyada", "Viral infection (flu, COVID, etc.)"],
["Eosinophils Zyada", "Allergy, Asthma, Parasite"],
],
[65*mm, 105*mm], TEAL, S, LIGHT_TEAL
)
story.append(wbc_interp)
story.append(Spacer(1, 3*mm))
story.append(Paragraph("C) Platelets – Platelet Count", S['sub_heading']))
plt_data = data_table(
["Parameter", "Saamaanya Maan", "Kaam / Matlab"],
[
["Platelet Count", "1.5 – 4.5 lakh /uL", "Khoon ka thakka banana (clotting)"],
["MPV", "7.5 – 12 fL", "Platelet ka aakar"],
],
[40*mm, 45*mm, 85*mm], PURPLE, S
)
story.append(plt_data)
story.append(Spacer(1, 2*mm))
plt_interp = data_table(
["Platelets ka Haal", "Kaaran"],
[
["Kam (< 1.5 lakh) – Thrombocytopenia", "Dengue, Malaria, ITP, Chemotherapy"],
["Bahut Kam (< 50,000)", "DANGER: Khoon bahne ka khatra"],
["Zyada – Thrombocytosis", "Iron kami, Sujan, Infection ke baad"],
],
[70*mm, 100*mm], PURPLE, S, LIGHT_PURPLE
)
story.append(plt_interp)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 2: DIABETES
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 2. Blood Sugar – Diabetes (Madhumeh)", RED, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Diabetes ki jaanch ke liye khoon mein sugar (glucose) ka level maapa jaata hai.",
S['body']
))
story.append(Spacer(2*mm, 2*mm))
diab_data = data_table(
["Test", "Saamaanya", "Pre-Diabetes", "Diabetes", "Kaise kiya jaata hai"],
[
["Fasting Blood Sugar (FBS)", "70 – 99 mg/dL", "100 – 125 mg/dL", ">= 126 mg/dL", "8 ghante khaali pet"],
["PP Blood Sugar (PPBS)", "< 140 mg/dL", "140 – 199 mg/dL", ">= 200 mg/dL", "Khaane ke 2 ghante baad"],
["Random Blood Sugar", "< 140 mg/dL", "—", ">= 200 + lakshan", "Kisi bhi samay"],
["HbA1c", "< 5.7%", "5.7 – 6.4%", ">= 6.5%", "3 mahine ka ausat"],
["Insulin Level", "2 – 25 uIU/mL", "—", "—", "Insulin resistance jaanch"],
["C-Peptide", "0.5 – 2.0 ng/mL", "—", "—", "Insulin utpaadan ki jaanch"],
],
[38*mm, 26*mm, 26*mm, 26*mm, 54*mm], RED, S, LIGHT_ORANGE
)
story.append(diab_data)
story.append(Spacer(2*mm, 2*mm))
story.append(Paragraph(
"Yaad rakhein: Diagnosis ke liye 2 baar alag-alag din test karna zaroori hota hai (sirf ek baar test se "
"diabetes confirm nahi hoti). HbA1c test ka fayda yeh hai ki isme khaali pet rehna zaroori nahi hota.",
S['note']
))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 3: LIPID PROFILE
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 3. Lipid Profile – Dil ki Bimari (Heart Disease)", DARK_RED, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Lipid profile se khoon mein cholesterol aur fat (triglycerides) ka pata chalta hai. "
"Yeh test heart attack aur stroke ka jokhim jaanne ke liye kiya jaata hai. "
"Test se 9-12 ghante pehle kuch nahi khaana chahiye.",
S['body']
))
story.append(Spacer(2*mm, 2*mm))
lipid_data = data_table(
["Test", "Behtar Maan", "Saamaanya", "Zyada / Khataraanak"],
[
["Total Cholesterol", "< 170 mg/dL", "< 200 mg/dL", "> 240 mg/dL"],
["LDL (Bura Cholesterol)", "< 100 mg/dL", "< 130 mg/dL", "> 160 mg/dL"],
["HDL (Acha Cholesterol) – Purush", "> 60 mg/dL", "> 40 mg/dL", "< 35 mg/dL"],
["HDL (Acha Cholesterol) – Mahila", "> 60 mg/dL", "> 50 mg/dL", "< 45 mg/dL"],
["Triglycerides", "< 100 mg/dL", "< 150 mg/dL", "> 200 mg/dL"],
["Non-HDL Cholesterol", "< 130 mg/dL", "< 160 mg/dL", "> 190 mg/dL"],
["Total/HDL Ratio", "< 3.5", "< 5.0", "> 5.0"],
],
[52*mm, 38*mm, 38*mm, 42*mm], DARK_RED, S, LIGHT_ORANGE
)
story.append(lipid_data)
story.append(Spacer(2*mm, 2*mm))
story.append(Paragraph("Dil ki Bimari ke Aur Tests:", S['sub_heading']))
heart_data = data_table(
["Test", "Kab Kiya Jaata Hai", "Matlab"],
[
["Troponin I / T", "Heart attack ka shak", "Dil ki maansapeshi ki kshati"],
["CK-MB", "Heart attack confirmation", "Cardiac muscle damage"],
["BNP / NT-proBNP", "Heart failure ka shak", "Dil ka zyada kaam karna"],
["Homocysteine", "Heart risk assessment", "Elevated = high risk"],
["hs-CRP", "Inflammation jaanch", "Arteries mein sujan ka indicator"],
["Lipoprotein(a)", "Family history mein", "Genetic heart risk"],
],
[40*mm, 50*mm, 80*mm], DARK_RED, S
)
story.append(heart_data)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 4: THYROID
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 4. Thyroid – TSH, T3, T4", TEAL, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Thyroid gland gardan mein hoti hai jo hormones banati hai jो poore body ki "
"metabolism control karte hain. Thyroid test anytime kiya ja sakta hai - "
"khaali pet rehna zaroori nahi.",
S['body']
))
story.append(Spacer(2*mm, 2*mm))
thyroid_data = data_table(
["Test", "Saamaanya Maan", "Hypothyroidism", "Hyperthyroidism"],
[
["TSH (Thyroid Stimulating Hormone)", "0.4 – 4.0 mIU/L", "TSH Zyada (> 4.0)", "TSH Kam (< 0.4)"],
["Free T4 (Thyroxine)", "0.8 – 1.8 ng/dL", "T4 Kam", "T4 Zyada"],
["Free T3 (Triiodothyronine)", "2.3 – 4.2 pg/mL", "T3 Kam", "T3 Zyada"],
["Anti-TPO Antibodies", "< 35 IU/mL", "High = Hashimoto's", "High = Graves' disease"],
["Anti-Thyroglobulin Ab", "< 40 IU/mL", "Autoimmune thyroid", "—"],
["Thyroglobulin", "3 – 40 ng/mL", "Thyroid cancer monitoring", "—"],
],
[54*mm, 38*mm, 38*mm, 40*mm], TEAL, S, LIGHT_TEAL
)
story.append(thyroid_data)
story.append(Spacer(2*mm, 2*mm))
thyroid_symptoms = data_table(
["Hypothyroidism ke Lakshan", "Hyperthyroidism ke Lakshan"],
[
["Thakaan, wajan badhna, thand lagni, balon ka girna,\nnind zyada aana, constipation",
"Wajan ghatna, ghabrahat, dhadkan tej, paseena,\nnind na aana, haath kaanpna"],
],
[85*mm, 85*mm], TEAL, S, LIGHT_TEAL
)
story.append(thyroid_symptoms)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 5: LFT
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 5. Liver Function Test (LFT) – Jigar ki Jaanch", GREEN, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"LFT se liver ki sehat ka pata chalta hai. Peeliya (jaundice), hepatitis, fatty liver, "
"alcohol ka asar jaanch ke liye kiya jaata hai.",
S['body']
))
story.append(Spacer(2*mm, 2*mm))
lft_data = data_table(
["Test", "Saamaanya Maan", "Zyada Hone par Matlab"],
[
["SGOT / AST", "10 – 40 U/L", "Liver ya heart damage"],
["SGPT / ALT", "7 – 56 U/L", "Liver-specific damage (zyada accurate)"],
["Alkaline Phosphatase (ALP)", "44 – 147 U/L", "Bile duct blockage, haddi bimari"],
["GGT (Gamma GT)", "9 – 48 U/L", "Alcohol, fatty liver, bile problem"],
["Total Bilirubin", "0.1 – 1.2 mg/dL", "Peeliya (jaundice)"],
["Direct Bilirubin", "0.0 – 0.4 mg/dL", "Bile duct blockage"],
["Indirect Bilirubin", "0.1 – 0.8 mg/dL", "Hemolytic anemia, liver failure"],
["Total Protein", "6.3 – 8.2 g/dL", "Kam = malnutrition, liver failure"],
["Albumin", "3.5 – 5.0 g/dL", "Kam = cirrhosis, kidney disease"],
["Prothrombin Time (PT)", "11 – 13.5 sec", "Zyada = liver clotting problem"],
],
[52*mm, 38*mm, 80*mm], GREEN, S, LIGHT_GREEN
)
story.append(lft_data)
story.append(Spacer(2*mm, 2*mm))
hepatitis = data_table(
["Hepatitis Test", "Matlab"],
[
["HBsAg (Hepatitis B Surface Antigen)", "Hepatitis B infection hai"],
["Anti-HCV (Hepatitis C Antibody)", "Hepatitis C infection ka shak"],
["HAV IgM (Hepatitis A)", "Active Hepatitis A infection"],
["HBV DNA / HCV RNA (PCR)", "Active viral load measurement"],
],
[80*mm, 90*mm], GREEN, S, LIGHT_GREEN
)
story.append(hepatitis)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 6: KFT
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 6. Kidney Function Test (KFT / RFT) – Gurde ki Jaanch", PURPLE, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"KFT se kidney ki filtering kshamata ka pata chalta hai. Diabetes, high BP, "
"ya kidney bimari ke patient ke liye yeh test zaroori hai.",
S['body']
))
story.append(Spacer(2*mm, 2*mm))
kft_data = data_table(
["Test", "Saamaanya Maan", "Zyada Hone par Matlab"],
[
["Serum Creatinine – Purush", "0.7 – 1.3 mg/dL", "Kidney filtering kam ho gayi"],
["Serum Creatinine – Mahila", "0.6 – 1.1 mg/dL", "Kidney filtering kam ho gayi"],
["Blood Urea Nitrogen (BUN)", "7 – 20 mg/dL", "Kidney ya liver problem"],
["BUN/Creatinine Ratio", "10:1 – 20:1", "Dehydration ya kidney blockage"],
["eGFR (Kidney filtering rate)", "> 60 mL/min", "Kam = Chronic Kidney Disease (CKD)"],
["Uric Acid – Purush", "3.4 – 7.0 mg/dL", "Gout (jod dard), Kidney stone"],
["Uric Acid – Mahila", "2.4 – 6.0 mg/dL", "Gout, Kidney stone"],
["Sodium (Na)", "136 – 145 mEq/L", "Dehydration, Heart/Kidney problem"],
["Potassium (K)", "3.5 – 5.0 mEq/L", "Heart rhythm problem (kam ya zyada dono)"],
["Chloride (Cl)", "98 – 107 mEq/L", "Acid-base balance"],
["Bicarbonate (HCO3)", "22 – 29 mEq/L", "Acidosis / Alkalosis"],
["Calcium", "8.5 – 10.5 mg/dL", "Haddi, parathyroid problem"],
["Phosphorus", "2.5 – 4.5 mg/dL", "Kidney failure mein badhta hai"],
],
[52*mm, 38*mm, 80*mm], PURPLE, S, LIGHT_PURPLE
)
story.append(kft_data)
story.append(Spacer(2*mm, 2*mm))
ckd_stages = data_table(
["CKD Stage", "eGFR Maan", "Matlab"],
[
["Stage 1 (Normal/High)", ">= 90", "Kidney theek hai, par kuch aur lakshan hain"],
["Stage 2 (Mildly Reduced)", "60 – 89", "Thodi si kami"],
["Stage 3 (Moderately Reduced)", "30 – 59", "Moderate CKD - Doctor se milein"],
["Stage 4 (Severely Reduced)", "15 – 29", "Serious – dialysis ki taiyari"],
["Stage 5 (Kidney Failure)", "< 15", "Dialysis ya Transplant zaroori"],
],
[45*mm, 35*mm, 90*mm], PURPLE, S, LIGHT_PURPLE
)
story.append(ckd_stages)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 7: INFECTION
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 7. Infection / Bukhar – Dengue, Malaria, Typhoid", ORANGE, S))
story.append(Spacer(1, 3*mm))
infect_data = data_table(
["Bimari", "Tests", "Kab Kiya Jaaye", "Kya Pata Chalta Hai"],
[
["Dengue", "NS1 Antigen, IgM/IgG Antibodies,\nCBC (Platelets)", "Bukhar ke 1-5 din",
"NS1: Active infection\nIgM: Recent infection\nIgG: Pehle ho chuka"],
["Malaria", "Malaria Antigen (PfHRP2/pLDH),\nMalaria Smear, CBC", "Bukhar ke samay",
"P. falciparum ya P. vivax\nka pata chalta hai"],
["Typhoid", "Widal Test, Blood Culture,\nTyphidot (IgM/IgG)", "Bukhar ke 5-7 din",
"Salmonella Typhi ka\ninfection"],
["COVID-19", "RT-PCR, Rapid Antigen Test,\nIgG/IgM Antibody", "Lakshan hone par",
"Active infection ya\npehle hua infection"],
["HIV", "HIV 1/2 Antibody ELISA,\nWestern Blot, HIV RNA", "Risk ke 3 mahine baad",
"HIV infection ka pata"],
["Chikungunya", "IgM/IgG Antibody ELISA", "Bukhar ke 5+ din", "Chikungunya virus"],
],
[28*mm, 50*mm, 38*mm, 54*mm], ORANGE, S, LIGHT_ORANGE
)
story.append(infect_data)
story.append(Spacer(2*mm, 2*mm))
inflammation = data_table(
["Sujan (Inflammation) Tests", "Saamaanya Maan", "Zyada Hone par"],
[
["ESR (Erythrocyte Sedimentation Rate)", "Purush: 0-15 mm/hr; Mahila: 0-20 mm/hr", "Infection, autoimmune bimari"],
["CRP (C-Reactive Protein)", "< 1.0 mg/L", "Active infection ya sujan"],
["hs-CRP (High Sensitivity)", "< 1.0 mg/L (low risk)", "Heart disease risk"],
["Procalcitonin (PCT)", "< 0.1 ng/mL", "Bacterial sepsis (bahut specific)"],
["Ferritin", "Purush: 24-336 ng/mL; Mahila: 11-307 ng/mL", "Infection, iron overload, cancer"],
],
[62*mm, 54*mm, 54*mm], ORANGE, S, LIGHT_ORANGE
)
story.append(inflammation)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 8: BONE & JOINT
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 8. Haddi aur Jod – Vitamin D, Calcium, Arthritis", GREEN, S))
story.append(Spacer(1, 3*mm))
bone_data = data_table(
["Test", "Saamaanya Maan", "Matlab / Bimari"],
[
["Vitamin D (25-OH)", "> 30 ng/mL saamaanya; 20-30 insufficient; < 20 deficient", "Haddi kamzor, thakaan, immunity kam"],
["Calcium (Total)", "8.5 – 10.5 mg/dL", "Kam: haddi kami; Zyada: kidney stone"],
["Phosphorus", "2.5 – 4.5 mg/dL", "Parathyroid, kidney bimari"],
["PTH (Parathyroid Hormone)", "15 – 65 pg/mL", "Hyperparathyroidism"],
["Uric Acid (Gout)", "Purush: 3.4-7.0; Mahila: 2.4-6.0 mg/dL", "Gout – jod mein dard, sujan"],
["RA Factor (Rheumatoid Factor)", "< 14 IU/mL (Negative)", "Rheumatoid Arthritis ka shak"],
["Anti-CCP Antibodies", "< 20 U/mL (Negative)", "RA ki pakki jaanch (zyada accurate)"],
["ANA (Antinuclear Antibody)", "Negative", "SLE (Lupus) ya autoimmune bimari"],
["Vitamin B12", "200 – 900 pg/mL", "Kam: neend na aana, thakaan, haath-pair sunna"],
["Folic Acid", "3 – 17 ng/mL", "Kam: anemia, pregnancy mein zaroori"],
["Magnesium", "1.7 – 2.2 mg/dL", "Muscle cramps, heart problem"],
],
[48*mm, 52*mm, 70*mm], GREEN, S, LIGHT_GREEN
)
story.append(bone_data)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 9: FULL BODY CHECKUP
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 9. Routine Full Body Checkup – Kya Hona Chahiye", BLUE, S))
story.append(Spacer(1, 3*mm))
story.append(Paragraph(
"Har vyakti ko saal mein kam se kam ek baar routine checkup karwana chahiye, "
"khaaskar 30+ saal ki umar ke baad ya kisi bimari ka jokhim hone par.",
S['body']
))
story.append(Spacer(2*mm, 2*mm))
checkup_data = data_table(
["Category", "Tests", "Kab Zaruri"],
[
["Khoon ki Saamaanya Jaanch", "CBC with Differential", "Hamesha"],
["Diabetes", "Fasting Blood Sugar, HbA1c", "Hamesha (30+ umar)"],
["Cholesterol / Dil", "Lipid Profile (Total, LDL, HDL, TG)", "Hamesha"],
["Thyroid", "TSH", "Mahilaon mein zaroori, 35+ mein sab ke liye"],
["Jigar (Liver)", "LFT (SGOT, SGPT, Bilirubin, etc.)", "Hamesha"],
["Gurde (Kidney)", "KFT (Creatinine, BUN, eGFR)", "Hamesha"],
["Vitamins", "Vitamin D, Vitamin B12", "Zyada zaroori India mein"],
["Iron", "Serum Iron, Ferritin, TIBC", "Mahilaon mein, anemia ke shak par"],
["Uric Acid", "Serum Uric Acid", "Gout ka itihaas hone par"],
["Thyroid (Vishesh)", "T3, T4, Anti-TPO", "Thyroid lakshan hone par"],
["Infection Marker", "ESR, CRP", "Lambe bukhar ya sujan par"],
["Cancer Markers (Basic)", "PSA (purush, 50+), CA-125 (mahila)", "Doctor ki salah par"],
],
[42*mm, 72*mm, 56*mm], BLUE, S, LIGHT_BLUE
)
story.append(checkup_data)
story.append(Spacer(2*mm, 2*mm))
prep_data = data_table(
["Test", "Taiyari"],
[
["Fasting Blood Sugar, Lipid Profile", "8 – 12 ghante kuch na khaayein / piyein (paani theek hai)"],
["HbA1c, CBC, Thyroid, LFT, KFT", "Khaali pet zaroori nahi – anytime ho sakta hai"],
["PP Blood Sugar (PPBS)", "Khaane ke 2 ghante baad test kiya jaata hai"],
["Blood Culture", "Antibiotics shuru karne SE PEHLE kiya jaaye"],
],
[55*mm, 115*mm], BLUE, S, LIGHT_BLUE
)
story.append(prep_data)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════
# SECTION 10: QUICK REFERENCE
# ══════════════════════════════════════════════════════════════════════
story.append(section_banner(" 10. Normal Values Quick Reference – Ek Nazar Mein", DARK_RED, S))
story.append(Spacer(1, 3*mm))
quick_data = data_table(
["Test", "Saamaanya Maan (Purush)", "Saamaanya Maan (Mahila)"],
[
["Hemoglobin (Hb)", "13.5 – 17.5 g/dL", "12.0 – 15.5 g/dL"],
["WBC Count", "4,000 – 11,000 /uL", "4,000 – 11,000 /uL"],
["Platelet Count", "1.5 – 4.5 lakh /uL", "1.5 – 4.5 lakh /uL"],
["Fasting Blood Sugar", "70 – 99 mg/dL", "70 – 99 mg/dL"],
["HbA1c", "< 5.7%", "< 5.7%"],
["Total Cholesterol", "< 200 mg/dL", "< 200 mg/dL"],
["LDL", "< 100 mg/dL (heart risk)", "< 100 mg/dL (heart risk)"],
["HDL", "> 40 mg/dL", "> 50 mg/dL"],
["Triglycerides", "< 150 mg/dL", "< 150 mg/dL"],
["TSH (Thyroid)", "0.4 – 4.0 mIU/L", "0.4 – 4.0 mIU/L"],
["Creatinine", "0.7 – 1.3 mg/dL", "0.6 – 1.1 mg/dL"],
["Uric Acid", "3.4 – 7.0 mg/dL", "2.4 – 6.0 mg/dL"],
["SGPT (ALT)", "7 – 56 U/L", "7 – 40 U/L"],
["Total Bilirubin", "0.1 – 1.2 mg/dL", "0.1 – 1.2 mg/dL"],
["Vitamin D", "> 30 ng/mL", "> 30 ng/mL"],
["Vitamin B12", "200 – 900 pg/mL", "200 – 900 pg/mL"],
["Calcium", "8.5 – 10.5 mg/dL", "8.5 – 10.5 mg/dL"],
["Sodium (Na)", "136 – 145 mEq/L", "136 – 145 mEq/L"],
["Potassium (K)", "3.5 – 5.0 mEq/L", "3.5 – 5.0 mEq/L"],
["ESR", "0 – 15 mm/hr", "0 – 20 mm/hr"],
["CRP", "< 1.0 mg/L", "< 1.0 mg/L"],
],
[70*mm, 50*mm, 50*mm], DARK_RED, S, LIGHT_ORANGE
)
story.append(quick_data)
story.append(Spacer(4*mm, 4*mm))
# Final disclaimer
final_disc = Table([[Paragraph(
"ZAROORI SUUCHNA: Yeh Blood Test Reference Guide kewal shaikshik (educational) "
"uddeshya ke liye banaayi gayi hai. Kisi bhi test, diagnosis, ya treatment ke liye "
"apne registered doctor ya specialist se salah zaroor lein. Normal values alag-alag "
"laboratory mein thodi bhinn ho sakti hain. Khud se koi dawai shuru ya band na karein.",
S['note']
)]], colWidths=[170*mm])
final_disc.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,-1), YELLOW_BG),
('BOX', (0,0), (-1,-1), 1.5, ORANGE),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 10),
('RIGHTPADDING', (0,0), (-1,-1), 10),
]))
story.append(final_disc)
# ─── BUILD ──────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=on_page, onLaterPages=on_page)
print(f"PDF saved to: {OUT}")