Can u make a note on a page containing all the best nd boss season tion in fmt in pc Ignatius in a order that I can remember nd revise
Can u make a note on a page containing all the bns nd bnss season tion in fmt in pc Ignatius in a order that I can remember nd revise
BNS BNSS sections relevant forensic medicine toxicology PC Ignatius medical students
mkdir -p /tmp/workspace/fmt-bns-notes && ls /tmp/workspace/fmt-bns-notes/
~/fmt-bns-notes/generate_pdf.py
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, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
doc_path = "/tmp/workspace/fmt-bns-notes/BNS_BNSS_FMT_Revision_Notes.pdf"
doc = SimpleDocTemplate(
doc_path,
pagesize=A4,
rightMargin=15*mm,
leftMargin=15*mm,
topMargin=18*mm,
bottomMargin=18*mm
)
styles = getSampleStyleSheet()
# Custom styles
NAVY = colors.HexColor("#1a2e5a")
TEAL = colors.HexColor("#0e6b7a")
GOLD = colors.HexColor("#c8860a")
LIGHT_BLUE = colors.HexColor("#dbeeff")
LIGHT_GREEN = colors.HexColor("#e6f7f0")
LIGHT_YELLOW = colors.HexColor("#fff8e1")
LIGHT_PINK = colors.HexColor("#fce4ec")
LIGHT_PURPLE = colors.HexColor("#f3e5f5")
LIGHT_ORANGE = colors.HexColor("#fff3e0")
WHITE = colors.white
DARK_GRAY = colors.HexColor("#2d2d2d")
title_style = ParagraphStyle(
"TitleStyle",
parent=styles["Title"],
fontSize=20,
textColor=WHITE,
alignment=TA_CENTER,
fontName="Helvetica-Bold",
spaceAfter=4,
)
subtitle_style = ParagraphStyle(
"SubtitleStyle",
parent=styles["Normal"],
fontSize=10,
textColor=colors.HexColor("#c8e6ff"),
alignment=TA_CENTER,
fontName="Helvetica",
spaceAfter=2,
)
section_header_style = ParagraphStyle(
"SectionHeader",
parent=styles["Normal"],
fontSize=13,
textColor=WHITE,
fontName="Helvetica-Bold",
alignment=TA_LEFT,
leftIndent=4,
spaceAfter=2,
spaceBefore=2,
)
subsection_style = ParagraphStyle(
"SubsectionStyle",
parent=styles["Normal"],
fontSize=10.5,
textColor=NAVY,
fontName="Helvetica-Bold",
alignment=TA_LEFT,
spaceBefore=4,
spaceAfter=2,
)
body_style = ParagraphStyle(
"BodyStyle",
parent=styles["Normal"],
fontSize=9.5,
textColor=DARK_GRAY,
fontName="Helvetica",
alignment=TA_JUSTIFY,
spaceBefore=1,
spaceAfter=1,
leading=13,
)
note_style = ParagraphStyle(
"NoteStyle",
parent=styles["Normal"],
fontSize=8.5,
textColor=colors.HexColor("#555555"),
fontName="Helvetica-Oblique",
alignment=TA_LEFT,
leftIndent=8,
spaceBefore=1,
spaceAfter=1,
)
small_bold = ParagraphStyle(
"SmallBold",
parent=styles["Normal"],
fontSize=9,
textColor=DARK_GRAY,
fontName="Helvetica-Bold",
)
table_header_style = ParagraphStyle(
"TableHeader",
parent=styles["Normal"],
fontSize=9,
textColor=WHITE,
fontName="Helvetica-Bold",
alignment=TA_CENTER,
)
table_cell_style = ParagraphStyle(
"TableCell",
parent=styles["Normal"],
fontSize=8.5,
textColor=DARK_GRAY,
fontName="Helvetica",
alignment=TA_LEFT,
leading=11,
)
table_cell_center = ParagraphStyle(
"TableCellCenter",
parent=styles["Normal"],
fontSize=8.5,
textColor=DARK_GRAY,
fontName="Helvetica",
alignment=TA_CENTER,
leading=11,
)
highlight_style = ParagraphStyle(
"HighlightStyle",
parent=styles["Normal"],
fontSize=9,
textColor=colors.HexColor("#7b0000"),
fontName="Helvetica-Bold",
leftIndent=6,
)
story = []
# ─── TITLE BANNER ────────────────────────────────────────────────────────────
def make_title_banner():
data = [[
Paragraph("BNS & BNSS Sections", title_style),
],
[Paragraph("Relevant to Forensic Medicine & Toxicology", subtitle_style)],
[Paragraph("As per PC Ignatius | Quick Revision Notes", subtitle_style)],
]
t = Table(data, colWidths=[180*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("TOPPADDING", (0,0), (-1,0), 10),
("BOTTOMPADDING", (0,-1), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("ROUNDEDCORNERS", [6]),
]))
return t
story.append(make_title_banner())
story.append(Spacer(1, 6*mm))
# ─── INTRO BOX ───────────────────────────────────────────────────────────────
intro_data = [[Paragraph(
"<b>KEY:</b> BNS = Bharatiya Nyaya Sanhita 2023 (replaces IPC) | "
"BNSS = Bharatiya Nagarik Suraksha Sanhita 2023 (replaces CrPC) | "
"BSA = Bharatiya Sakshya Adhiniyam 2023 (replaces IEA)",
body_style
)]]
intro_t = Table(intro_data, colWidths=[180*mm])
intro_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_YELLOW),
("BOX", (0,0), (-1,-1), 1, GOLD),
("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(intro_t)
story.append(Spacer(1, 5*mm))
# ─────────────────────────────────────────────────────────────────────────────
# HELPER: section banner
# ─────────────────────────────────────────────────────────────────────────────
def section_banner(text, color=TEAL):
data = [[Paragraph(text, section_header_style)]]
t = Table(data, colWidths=[180*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
return t
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 1: BNS — OFFENCES (ex-IPC sections)
# ─────────────────────────────────────────────────────────────────────────────
story.append(section_banner("SECTION 1: BNS 2023 — Offences Relevant to FMT", color=NAVY))
story.append(Spacer(1, 3*mm))
# TABLE: BNS sections
bns_headers = [
Paragraph("BNS Sec.", table_header_style),
Paragraph("Old IPC", table_header_style),
Paragraph("Topic", table_header_style),
Paragraph("Key Points for FMT", table_header_style),
]
bns_data = [
# General
["11", "44", "Injury", "Bodily harm to any person — foundation for wound description in MLRs"],
["2(17)", "—", "Child", "Person <18 yrs — relevant to infanticide, POCSO cases"],
["2(20)", "—", "Death", "Cessation of life — medico-legal definition used in PME"],
["2(22)", "—", "Document", "Includes medical certificates, post-mortem reports"],
["2(55)", "—", "Wrongful gain/loss", "Relevant to medical negligence fraud cases"],
# Culpable homicide & murder
["100", "299", "Culpable Homicide (CH)", "Causing death with intention / knowledge it will likely cause death"],
["101", "300", "Murder", "CH becomes murder if done with intention to cause death or bodily injury sufficient to cause death; Exceptions: grave provocation, exceeding private defence"],
["105", "304A", "Death by Negligence", "No intention; rash/negligent act by doctor = medical negligence; 2 yrs imprisonment / fine / both"],
["106", "304B", "Dowry Death", "Death within 7 yrs of marriage due to burns/bodily injury; ILL-TREATMENT by husband or relatives"],
["109", "307", "Attempt to Murder", "Act done with intention/knowledge to cause death"],
["115", "319", "Hurt", "Causing bodily pain, disease or infirmity"],
["116", "320", "Grievous Hurt", "Emasculation; permanent privation of sight/hearing; loss of any limb/joint; permanent disfiguration of head/face; fracture or dislocation of bone/tooth; any hurt endangering life / causing 20-day severe body pain"],
["117", "321", "Voluntarily causing Hurt", "Person causes hurt; used in MLR for classifying assault injuries"],
["118", "322", "Voluntarily causing Grievous Hurt", "—"],
["124", "326A", "Acid Attack", "Permanent or partial damage by acid; min 10 yrs to life imprisonment"],
["125", "326B", "Attempt to throw Acid", "2–7 yrs imprisonment"],
["131", "338", "Grievous Hurt by Rash/Negligent Act", "Endangering life/safety of others; 2 yrs / fine / both"],
["138", "304A", "Causing Death by Negligence", "Rash/negligent act not amounting to CH — medical negligence"],
# Sexual offences
["63", "375", "Rape", "6 exceptions: includes age <18 always rape; MLR mandatory; examination by female doctor preferred"],
["64", "376", "Punishment for Rape", "Min 10 yrs to life + fine"],
["65", "376A–D", "Aggravated Rape", "By police/public servant/gang rape; min 20 yrs to life/death"],
["69", "376C", "Sexual intercourse by deceit/false promise of marriage", "Imprisonment up to 10 yrs + fine"],
["70", "376D", "Gang Rape", "Rigorous imprisonment ≥20 yrs to life"],
["74", "354", "Outraging Modesty", "1–5 yrs; includes stalking"],
["75", "354A", "Sexual Harassment", "Up to 3 yrs / fine / both"],
["77", "354C", "Voyeurism", "1st offence: 1–3 yrs; 2nd: 3–7 yrs"],
["78", "354D", "Stalking", "1st: 3 yrs; 2nd: 5 yrs"],
["94", "377", "Unnatural Offences", "Voluntarily having carnal intercourse against the order of nature"],
# Abortion
["88", "312", "Causing Miscarriage (Abortion)", "Unless to save mother's life; 3 yrs / fine / both; 7 yrs if woman quick with child"],
["89", "313", "Abortion without Consent", "Life imprisonment or 10 yrs + fine"],
["90", "314", "Death caused in attempt to cause Miscarriage", "10 yrs or life imprisonment"],
["91", "315", "Acts to prevent child from being born alive / cause death after birth", "10 yrs / fine / both"],
["92", "316", "Causing Death of Quick Unborn Child", "Culpable homicide – life imprisonment"],
# Infanticide & abandonment
["93", "317", "Exposure & Abandonment of child <12 yrs", "7 yrs / fine / both"],
["86", "310B", "Child Trafficking", "—"],
# False evidence/certificates
["227", "191", "Giving False Evidence", "7 yrs + fine; relevant to doctors giving false certificates"],
["228", "192", "Fabricating False Evidence", "—"],
["231", "196", "Using False Evidence as True", "—"],
["237", "202", "Omission to give information", "Withholding info from magistrate/police"],
["240", "204", "Destruction of Document", "Destroying medical/legal evidence"],
# Negligence / Public servant
["202", "304A", "Medical Negligence (general)", "Rash/negligent act; NOT intentional killing"],
["174B", "197B", "False certificate by public servant", "1 yr / fine / both — relevant to MOs issuing false certificates"],
# Poisoning
["122", "328", "Causing Hurt by Poison", "Administering poison/stupefying substance; 10 yrs / fine"],
# Consent
["20", "87", "Consent – no offence for acts causing grievous hurt by consent", "Consent <18 yrs = not valid"],
["21", "88", "Medical treatment under consent", "Good faith treatment; patient consents to harm; valid legal defence for doctors"],
["22", "89", "Act done in good faith for child/insane person", "Guardian consent valid"],
]
bns_table_data = [bns_headers]
for row in bns_data:
bns_table_data.append([
Paragraph(f"<b>{row[0]}</b>", table_cell_center),
Paragraph(row[1], table_cell_center),
Paragraph(f"<b>{row[2]}</b>", table_cell_style),
Paragraph(row[3], table_cell_style),
])
bns_t = Table(
bns_table_data,
colWidths=[18*mm, 18*mm, 44*mm, 100*mm],
repeatRows=1
)
bns_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("ALIGN", (0,0), (1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(bns_t)
story.append(Spacer(1, 5*mm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 2: BNSS — Procedure (ex-CrPC)
# ─────────────────────────────────────────────────────────────────────────────
story.append(section_banner("SECTION 2: BNSS 2023 — Procedure Relevant to FMT", color=colors.HexColor("#145a32")))
story.append(Spacer(1, 3*mm))
bnss_headers = [
Paragraph("BNSS Sec.", table_header_style),
Paragraph("Old CrPC", table_header_style),
Paragraph("Topic", table_header_style),
Paragraph("Key Points for FMT", table_header_style),
]
bnss_data = [
["173", "154", "FIR (First Information Report)", "Duty of police to register; copy to magistrate; doctor informs police of ML case"],
["176(1)", "174", "Inquest by Police", "Investigation of unnatural/sudden death; constable/police officer in charge"],
["176(3)", "NEW", "Forensic Expert at Scene", "MANDATORY forensic team for offences punishable ≥7 yrs; 5-yr implementation period; forensic expert must document & collect evidence"],
["194", "176", "Magistrate Inquest", "Inquest by Executive Magistrate: dowry deaths, police custody deaths, gang rape victims, acid attack deaths"],
["195", "177", "Jurisdiction of Inquest", "Magistrate of district where body found"],
["230", "198B", "Complaint for Rape of wife", "Court cannot take cognisance unless wife files complaint (wife ≥18 yrs)"],
["248", "161", "Examination of witnesses by police", "Statements to police — not admissible; doctor's verbal information"],
["249", "162", "Statements not to be signed; use of statement", "Police statements can be used to contradict a witness in court"],
["312", "273", "Evidence to be in presence of accused", "Doctor's court testimony given in presence of accused"],
["329", "293", "Government Scientific Expert's Report", "Written report admissible in evidence without oral testimony; BNSS expands to 'any other scientific expert' beyond govt expert; Experts listed: FSL, Chemical Examiner, Serologist, Fingerprint, Handwriting, Ballistic experts + others"],
["349", "311A", "Power of Magistrate to order samples", "Finger impressions, handwriting, voice samples, blood, saliva, semen etc. on written order from 1st class Magistrate; BNSS allows without prior arrest (broader than old CrPC 311A)"],
["350", "312", "Examination of accused by doctor", "Medical examination of accused by registered medical practitioner on request of police officer (rape cases)"],
["351", "313", "Power to examine accused", "Court may examine accused; used in mental state assessments"],
["376", "327", "Trial of rape in camera", "In-camera trial for rape; identity of victim protected"],
["397", "357", "Compensation to victims", "Court can award compensation to victim of crime including rape/acid attack"],
["530(a)", "509", "Insult to modesty – word/gesture", "Simple imprisonment up to 3 yrs + fine"],
["184", "185", "Examination of person in police custody", "Magistrate can order medical examination; important in custodial torture cases"],
["360", "316", "Detention in safe custody (insane accused)", "Accused of unsound mind detained until fit for trial — Sec 84 BNS defence applies"],
["505", "482", "Inherent powers of High Court", "HC can quash FIR/proceedings — relevant to medical negligence FIRs"],
]
bnss_table_data = [bnss_headers]
for row in bnss_data:
bnss_table_data.append([
Paragraph(f"<b>{row[0]}</b>", table_cell_center),
Paragraph(row[1], table_cell_center),
Paragraph(f"<b>{row[2]}</b>", table_cell_style),
Paragraph(row[3], table_cell_style),
])
bnss_t = Table(
bnss_table_data,
colWidths=[18*mm, 18*mm, 44*mm, 100*mm],
repeatRows=1
)
bnss_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#145a32")),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("ALIGN", (0,0), (1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_GREEN]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(bnss_t)
story.append(Spacer(1, 5*mm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 3: BSA (Bharatiya Sakshya Adhiniyam) — Evidence
# ─────────────────────────────────────────────────────────────────────────────
story.append(section_banner("SECTION 3: BSA 2023 — Evidence Relevant to FMT", color=colors.HexColor("#6d1a7a")))
story.append(Spacer(1, 3*mm))
bsa_headers = [
Paragraph("BSA Sec.", table_header_style),
Paragraph("Old IEA", table_header_style),
Paragraph("Topic", table_header_style),
Paragraph("Key Points for FMT", table_header_style),
]
bsa_data = [
["26", "32(1)", "Dying Declaration", "Statement by person who believes death imminent; admissible even if declarant dies; doctor may record; no oath needed; thumb impression accepted"],
["27", "32(2)–(8)", "Statements by deceased in other situations", "Includes cause of death of deceased in proceedings where their death is in question"],
["39", "45", "Expert Witness", "Opinions of expert in science, art, foreign law etc. — doctor as expert witness in court"],
["40", "46", "Facts bearing upon opinions of experts", "Facts on which expert's opinion is based — basis of medico-legal report"],
["57", "65B", "Admissibility of Electronic Records", "Electronic evidence (CCTV, digital records) — important in new era forensics"],
["63", "73", "Comparison of signatures / handwriting", "Handwriting expert evidence — questioned documents"],
["30", "35", "Relevance of entries in public records", "Hospital admission records, death registers — admissible as evidence"],
["114", "114", "Presumptions of fact by court", "Court may presume: rape accused knew victim was <18 if she looks <18; woman's recent absence = presumed dead if 7 yrs"],
["118", "118", "Who may testify", "All persons competent to testify unless court considers them unable to understand due to mental illness etc."],
["119", "119", "Deaf-mute witness", "Can give evidence in writing or by signs; relevant to forensic psychiatry"],
["166", "165", "Judge's power to ask questions", "Judge may ask any question in any form at any time — affects expert witness examination"],
]
bsa_table_data = [bsa_headers]
for row in bsa_data:
bsa_table_data.append([
Paragraph(f"<b>{row[0]}</b>", table_cell_center),
Paragraph(row[1], table_cell_center),
Paragraph(f"<b>{row[2]}</b>", table_cell_style),
Paragraph(row[3], table_cell_style),
])
bsa_t = Table(
bsa_table_data,
colWidths=[18*mm, 18*mm, 44*mm, 100*mm],
repeatRows=1
)
bsa_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#6d1a7a")),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("ALIGN", (0,0), (1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("FONTSIZE", (0,0), (-1,0), 9),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_PURPLE]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(bsa_t)
story.append(Spacer(1, 5*mm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 4: TOPIC-WISE QUICK CROSS-REFERENCE
# ─────────────────────────────────────────────────────────────────────────────
story.append(section_banner("SECTION 4: Topic-wise Quick Cross Reference (Exam-Ready)", color=colors.HexColor("#8b1a1a")))
story.append(Spacer(1, 3*mm))
xref_data = [
[Paragraph("<b>FMT Topic</b>", table_header_style), Paragraph("<b>BNS Section</b>", table_header_style), Paragraph("<b>BNSS Section</b>", table_header_style), Paragraph("<b>BSA Section</b>", table_header_style)],
[Paragraph("<b>Wounds / Injuries</b>", table_cell_style), Paragraph("Sec 11 (Injury)\nSec 115–131 (Hurt → Grievous Hurt)\nSec 124–125 (Acid Attack)", table_cell_style), Paragraph("Sec 350 (Medical exam of accused)\nSec 184 (Custody exam)", table_cell_style), Paragraph("Sec 39 (Expert opinion)\nSec 40 (Expert's basis)", table_cell_style)],
[Paragraph("<b>Death Investigation</b>", table_cell_style), Paragraph("Sec 100–105 (CH/Murder)\nSec 106 (Dowry death)\nSec 105 (Negligent death)", table_cell_style), Paragraph("Sec 176(1) (Police inquest)\nSec 194 (Magistrate inquest)\nSec 176(3) (Forensic expert at scene)", table_cell_style), Paragraph("Sec 26 (Dying Declaration)\nSec 27 (Deceased's statements)", table_cell_style)],
[Paragraph("<b>Rape / Sexual Assault</b>", table_cell_style), Paragraph("Sec 63–70 (Rape, aggravated, gang)\nSec 74–78 (Outraging modesty)\nSec 94 (Unnatural offences)", table_cell_style), Paragraph("Sec 350 (Exam of accused)\nSec 376 (In-camera trial)\nSec 230 (Complaint by wife)", table_cell_style), Paragraph("Sec 114 (Presumption re: age)\nSec 39 (Expert witness)", table_cell_style)],
[Paragraph("<b>Abortion / MTP</b>", table_cell_style), Paragraph("Sec 88–92 (Miscarriage, quick child)\nSec 91–92 (Infanticide-adjacent)", table_cell_style), Paragraph("—", table_cell_style), Paragraph("—", table_cell_style)],
[Paragraph("<b>Infanticide / Child</b>", table_cell_style), Paragraph("Sec 93 (Exposure of child)\nSec 2(17) (Child <18 yrs)\nSec 86 (Child trafficking)", table_cell_style), Paragraph("Sec 176(3) (Crime scene forensics)", table_cell_style), Paragraph("Sec 118–119 (Witness competency)", table_cell_style)],
[Paragraph("<b>Medical Negligence</b>", table_cell_style), Paragraph("Sec 105 (Negligent death / 304A)\nSec 131 (GH by negligence)\nSec 21 (Consent – doctor defence)", table_cell_style), Paragraph("Sec 505 (HC quash FIR)\nSec 248 (Witness examination)", table_cell_style), Paragraph("Sec 39 (Expert witness)", table_cell_style)],
[Paragraph("<b>Poisoning</b>", table_cell_style), Paragraph("Sec 122 (Causing hurt by poison)\nSec 105 (Negligent death by drugs)", table_cell_style), Paragraph("Sec 329 (Expert report admissible)\nSec 349 (Biological sample order)", table_cell_style), Paragraph("Sec 39 (Toxicologist as expert)", table_cell_style)],
[Paragraph("<b>Identification / Forensic Science</b>", table_cell_style), Paragraph("—", table_cell_style), Paragraph("Sec 329 (Govt scientific expert)\nSec 349 (Fingerprints/voice samples)\nSec 176(3) (Forensic at scene)", table_cell_style), Paragraph("Sec 57 (Electronic evidence)\nSec 63 (Handwriting comparison)", table_cell_style)],
[Paragraph("<b>Mental Health / Psychiatry</b>", table_cell_style), Paragraph("Sec 22 BNS (Unsoundness of mind)\nSec 84 IPC → Sec 22 BNS: McNaughten rules", table_cell_style), Paragraph("Sec 360 (Detention of insane accused)\nSec 351 (Examination of accused)", table_cell_style), Paragraph("Sec 118 (Competency of witness)", table_cell_style)],
[Paragraph("<b>Dying Declaration</b>", table_cell_style), Paragraph("—", table_cell_style), Paragraph("Sec 176 (Inquest note dying decl.)", table_cell_style), Paragraph("Sec 26 BSA (Dying Declaration admissible)\nDoctor's fitness certificate validates", table_cell_style)],
[Paragraph("<b>False Certificates</b>", table_cell_style), Paragraph("Sec 227–228 (False evidence)\nSec 174B (False cert by public servant)", table_cell_style), Paragraph("—", table_cell_style), Paragraph("Sec 30 (Public record entries)", table_cell_style)],
]
xref_t = Table(
xref_data,
colWidths=[40*mm, 50*mm, 48*mm, 42*mm],
repeatRows=1
)
xref_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#8b1a1a")),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("VALIGN", (0,0), (-1,-1), "TOP"),
("FONTNAME", (0,0), (-1,0), "Helvetica-Bold"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_PINK]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(xref_t)
story.append(Spacer(1, 5*mm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 5: HIGH-YIELD MNEMONICS & MEMORY AIDS
# ─────────────────────────────────────────────────────────────────────────────
story.append(section_banner("SECTION 5: High-Yield Mnemonics & Memory Aids", color=colors.HexColor("#b35900")))
story.append(Spacer(1, 3*mm))
mnemonics = [
("GRIEVOUS HURT (BNS Sec.116) — Mnemonic: 'E-PELL-FBH'",
"E = Emasculation\n"
"P = Privation of sight (permanent)\n"
"E = Ear (permanent privation of hearing)\n"
"L = Limb / joint loss (any member / joint)\n"
"L = Look (permanent disfiguration of head/face)\n"
"F = Fracture or dislocation of bone or tooth\n"
"B = Body pain >20 days or severe pain\n"
"H = Hurt endangering life"
),
("RAPE (BNS Sec.63) — 6 EXCEPTIONS where consent irrelevant",
"1. Wife <18 yrs (marital rape of minor)\n"
"2. Fear of death or hurt\n"
"3. Unsoundness of mind / intoxication\n"
"4. Below age of consent (18 yrs)\n"
"5. Consent obtained by fraud / impersonation\n"
"6. Communicates consent but in a state unable to understand"
),
("MAGISTRATE INQUEST (BNSS Sec.194) — Mnemonic: 'D-PGA'",
"D = Dowry death (within 7 yrs)\n"
"P = Police custody death\n"
"G = Gang rape victim's death\n"
"A = Acid attack victim's death"
),
("DYING DECLARATION (BSA Sec.26) — 'FACE'",
"F = Fit to make statement (doctor certifies mental fitness)\n"
"A = Ante mortem (made when death was apprehended)\n"
"C = Complete (though incomplete may still be accepted)\n"
"E = Even without oath; thumb impression valid"
),
("BNSS Sec.329 — Experts who can send report without court appearance",
"Chemical Examiner / Asst Chemical Examiner\n"
"Chief Inspector of Explosives\n"
"Director of Fingerprint Bureau\n"
"Director / Deputy Director — FSL\n"
"Serologist to Government\n"
"+ Any other scientific expert notified by Central/State Govt"
),
("IPC vs BNS — KEY SECTION PAIRS to remember",
"IPC 302 (Murder) → BNS 101\n"
"IPC 304A (Negligence) → BNS 105 / 106\n"
"IPC 312 (Abortion) → BNS 88\n"
"IPC 320 (Grievous Hurt) → BNS 116\n"
"IPC 375 (Rape) → BNS 63\n"
"IPC 328 (Poison) → BNS 122\n"
"IPC 87–89 (Consent) → BNS 20–22"
),
]
for title, content in mnemonics:
m_data = [
[Paragraph(f"<b>{title}</b>", ParagraphStyle("mT", parent=styles["Normal"], fontSize=9.5, textColor=colors.HexColor("#5a2d00"), fontName="Helvetica-Bold"))],
[Paragraph(content.replace("\n", "<br/>"), ParagraphStyle("mB", parent=styles["Normal"], fontSize=9, textColor=DARK_GRAY, fontName="Courier", leading=13, leftIndent=6))],
]
m_t = Table(m_data, colWidths=[180*mm])
m_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), LIGHT_ORANGE),
("BACKGROUND", (0,1), (-1,1), colors.HexColor("#fffdf5")),
("BOX", (0,0), (-1,-1), 0.7, colors.HexColor("#e08000")),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
]))
story.append(m_t)
story.append(Spacer(1, 2.5*mm))
story.append(Spacer(1, 3*mm))
# ─────────────────────────────────────────────────────────────────────────────
# SECTION 6: IMPORTANT NUMBERS / PENALTIES AT A GLANCE
# ─────────────────────────────────────────────────────────────────────────────
story.append(section_banner("SECTION 6: Important Numbers & Punishments at a Glance", color=colors.HexColor("#1a3c5a")))
story.append(Spacer(1, 3*mm))
num_data = [
[Paragraph("<b>Offence</b>", table_header_style), Paragraph("<b>BNS Sec.</b>", table_header_style), Paragraph("<b>Punishment</b>", table_header_style)],
["Culpable Homicide not amounting to Murder", "101", "Life / 10 yrs + fine"],
["Murder", "101", "Death / Life + fine"],
["Negligent Death (Medical Negligence)", "105", "2 yrs / fine / both"],
["Dowry Death", "106", "7 yrs → Life"],
["Rape (basic)", "64", "Min 10 yrs → Life + fine"],
["Gang Rape", "70", "≥20 yrs → Life"],
["Aggravated Rape (custody/repeat)", "65", "Min 20 yrs → Life / Death"],
["Acid Attack", "124", "Min 10 yrs → Life + fine (special)"],
["Attempt to throw Acid", "125", "2–7 yrs + fine"],
["Causing Miscarriage", "88", "3 yrs / fine (7 yrs if quick with child)"],
["Causing Hurt by Poison", "122", "10 yrs + fine"],
["Grievous Hurt by Negligence", "131", "2 yrs / fine / both"],
["Outraging Modesty of Woman", "74", "1–5 yrs + fine"],
["False Evidence (Certificate)", "227", "7 yrs + fine"],
["False Certificate by Public Servant", "174B", "1 yr / fine / both"],
["Exposure/Abandonment of child <12 yrs", "93", "7 yrs / fine / both"],
["Unnatural Offences", "94", "Life / 10 yrs + fine"],
]
num_t_data = [num_data[0]]
for row in num_data[1:]:
num_t_data.append([
Paragraph(row[0], table_cell_style),
Paragraph(f"<b>{row[1]}</b>", table_cell_center),
Paragraph(row[2], table_cell_style),
])
num_t = Table(num_t_data, colWidths=[90*mm, 22*mm, 68*mm], repeatRows=1)
num_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#1a3c5a")),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("ALIGN", (1,0), (1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, LIGHT_BLUE]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(num_t)
story.append(Spacer(1, 5*mm))
# ─────────────────────────────────────────────────────────────────────────────
# FOOTER NOTE
# ─────────────────────────────────────────────────────────────────────────────
footer_data = [[Paragraph(
"<b>Note:</b> BNS (Bharatiya Nyaya Sanhita), BNSS (Bharatiya Nagarik Suraksha Sanhita) and BSA (Bharatiya Sakshya Adhiniyam) came into force on <b>1st July 2024</b>, "
"replacing IPC 1860, CrPC 1973, and IEA 1872 respectively. Always check the latest notifications as sections may be amended. "
"Compiled for FMT revision as per PC Ignatius textbook framework.",
note_style
)]]
footer_t = Table(footer_data, colWidths=[180*mm])
footer_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_YELLOW),
("BOX", (0,0), (-1,-1), 0.7, GOLD),
("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(footer_t)
# ─────────────────────────────────────────────────────────────────────────────
# BUILD
# ─────────────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to: {doc_path}")
cd /tmp/workspace/fmt-bns-notes && python generate_pdf.py 2>&1
ls -lh /tmp/workspace/fmt-bns-notes/BNS_BNSS_FMT_Revision_Notes.pdf
BNS BNSS FMT Revision Notes
PDF Document · PDF
Reminder: BNS, BNSS and BSA came into force on 1st July 2024. All new exams will ask BNS/BNSS sections, not IPC/CrPC - but the old section numbers are kept in the table for cross-reference.
Make note on chelating agents with mneumonics
mkdir -p /tmp/workspace/fmt-chelating-notes
~/fmt-chelating-notes/generate_chelating_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
doc_path = "/tmp/workspace/fmt-chelating-notes/Chelating_Agents_FMT_Notes.pdf"
doc = SimpleDocTemplate(
doc_path,
pagesize=A4,
rightMargin=14*mm,
leftMargin=14*mm,
topMargin=16*mm,
bottomMargin=16*mm
)
styles = getSampleStyleSheet()
# Colours
NAVY = colors.HexColor("#1a2e5a")
TEAL = colors.HexColor("#0e6b7a")
GOLD = colors.HexColor("#c8860a")
MAROON = colors.HexColor("#8b1a1a")
PURPLE = colors.HexColor("#5c1f7a")
DKGREEN = colors.HexColor("#145a32")
ORANGE = colors.HexColor("#b35900")
LGRAY = colors.HexColor("#f5f5f5")
WHITE = colors.white
DKGRAY = colors.HexColor("#2d2d2d")
LT_BLUE = colors.HexColor("#dbeeff")
LT_GREEN = colors.HexColor("#e6f7f0")
LT_YELLOW = colors.HexColor("#fff8e1")
LT_PINK = colors.HexColor("#fce4ec")
LT_PURPLE = colors.HexColor("#f3e5f5")
LT_ORANGE = colors.HexColor("#fff3e0")
LT_TEAL = colors.HexColor("#e0f7fa")
def st(name, base="Normal", **kw):
s = ParagraphStyle(name, parent=styles[base])
for k, v in kw.items():
setattr(s, k, v)
return s
TITLE_S = st("TitleS", fontSize=21, textColor=WHITE, alignment=TA_CENTER, fontName="Helvetica-Bold")
SUB_S = st("SubS", fontSize=10, textColor=colors.HexColor("#c8e6ff"), alignment=TA_CENTER, fontName="Helvetica")
SEC_S = st("SecS", fontSize=13, textColor=WHITE, fontName="Helvetica-Bold", leftIndent=4)
DRUG_S = st("DrugS", fontSize=12, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
BODY_S = st("BodyS", fontSize=9.5, textColor=DKGRAY, fontName="Helvetica", alignment=TA_JUSTIFY, leading=13)
BOLD_S = st("BoldS", fontSize=9.5, textColor=NAVY, fontName="Helvetica-Bold", leading=13)
NOTE_S = st("NoteS", fontSize=8.5, textColor=colors.HexColor("#555555"), fontName="Helvetica-Oblique", leading=12)
TH_S = st("ThS", fontSize=9, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
TC_S = st("TcS", fontSize=8.8, textColor=DKGRAY, fontName="Helvetica", leading=12)
TC_C = st("TcC", fontSize=8.8, textColor=DKGRAY, fontName="Helvetica", alignment=TA_CENTER, leading=12)
MNEM_T = st("MnT", fontSize=10, textColor=colors.HexColor("#5a2d00"), fontName="Helvetica-Bold")
MNEM_B = st("MnB", fontSize=9.2, textColor=DKGRAY, fontName="Courier", leading=14, leftIndent=6)
HL_S = st("HlS", fontSize=9, textColor=MAROON, fontName="Helvetica-Bold", leftIndent=4)
def banner(text, color=NAVY):
t = Table([[Paragraph(text, SEC_S)]], colWidths=[182*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
return t
def drug_banner(name, alias, color=TEAL):
rows = [
[Paragraph(name, DRUG_S)],
[Paragraph(alias, st("AlS", fontSize=9, textColor=colors.HexColor("#c8e6ff"), fontName="Helvetica-Oblique", alignment=TA_CENTER))],
]
t = Table(rows, colWidths=[182*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (0,0), 5),
("BOTTOMPADDING", (0,-1), (-1,-1), 5),
("TOPPADDING", (0,1), (-1,1), 2),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
return t
def info_table(rows_data, bg_col=LT_BLUE, border_col=TEAL):
data = []
for label, val in rows_data:
data.append([
Paragraph(f"<b>{label}</b>", TC_S),
Paragraph(val, TC_S),
])
t = Table(data, colWidths=[42*mm, 140*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), bg_col),
("BACKGROUND", (1,0), (1,-1), WHITE),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("BOX", (0,0), (-1,-1), 0.7, border_col),
("INNERGRID", (0,0), (-1,-1), 0.3, colors.HexColor("#cccccc")),
]))
return t
def mnemonic_box(title, lines):
data = [
[Paragraph(title, MNEM_T)],
[Paragraph("<br/>".join(lines), MNEM_B)],
]
t = Table(data, colWidths=[182*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), LT_ORANGE),
("BACKGROUND", (0,1), (-1,1), colors.HexColor("#fffdf5")),
("BOX", (0,0), (-1,-1), 0.8, ORANGE),
("TOPPADDING", (0,0), (-1,-1), 4),
("BOTTOMPADDING", (0,0), (-1,-1), 4),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
]))
return t
def warn_box(text, bg=LT_PINK, border=MAROON):
t = Table([[Paragraph(text, st("WS", fontSize=9, textColor=MAROON, fontName="Helvetica-Bold", leading=13))]], colWidths=[182*mm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1, border),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
return t
def sp(n=3): return Spacer(1, n*mm)
story = []
# ── TITLE ────────────────────────────────────────────────────────────────────
title_rows = [
[Paragraph("CHELATING AGENTS", TITLE_S)],
[Paragraph("Forensic Medicine & Toxicology | Revision Notes", SUB_S)],
[Paragraph("Based on PC Ignatius / PC Dikshit Framework", st("SubS2", fontSize=9, textColor=colors.HexColor("#90caf9"), alignment=TA_CENTER, fontName="Helvetica-Oblique"))],
]
title_t = Table(title_rows, colWidths=[182*mm])
title_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (-1,0), 10),
("BOTTOMPADDING", (0,-1), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
]))
story.append(title_t)
story.append(sp(4))
# ── DEFINITION BOX ───────────────────────────────────────────────────────────
defn = Table([[Paragraph(
"<b>Definition:</b> Chelating agents are compounds that form stable, soluble, non-toxic ring structures (chelates) "
"with metallic ions, rendering them water-soluble and non-ionized so they are excreted in urine without damaging "
"the liver or kidneys. The word 'Chelate' comes from the Greek <i>chele</i> = claw (the metal is 'gripped').",
BODY_S)]], colWidths=[182*mm])
defn.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LT_YELLOW),
("BOX", (0,0), (-1,-1), 1, GOLD),
("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(defn)
story.append(sp(4))
# ── MASTER TABLE ─────────────────────────────────────────────────────────────
story.append(banner("MASTER QUICK-REFERENCE TABLE — All Chelating Agents at a Glance", NAVY))
story.append(sp(2))
master_hdr = [
Paragraph("Agent", TH_S),
Paragraph("Drug / Full Name", TH_S),
Paragraph("Metals Chelated", TH_S),
Paragraph("Route", TH_S),
Paragraph("Key Use / Unique Fact", TH_S),
Paragraph("Contraindicated In", TH_S),
]
master_rows = [
["BAL\n(Dimercaprol)", "British Anti-Lewisite\nDimercaptopropanol", "As, Hg, Pb, Sb, Au, Tl\n(+ Cu, Bi)", "IM only\n(deep, in oil)", "Drug of choice: Arsenic & Mercury\nChloice in impaired renal function\n2 mol BAL : 1 atom metal", "Cadmium (nephrotoxic complex)\nLiver disease"],
["CaNa₂EDTA\n(Calcium Disodium Versenate)", "Ethylene Diamine\nTetra-acetic Acid", "Pb (best), Zn, Mn,\nCu, Ni, Cd, Fe", "IV / IM\n(NOT oral)", "Best for inorganic lead\nNOT effective in tetraethyl lead\nGive BAL 4 hrs BEFORE EDTA", "Raised intracranial pressure\n(fluids restricted)"],
["Penicillamine\n(Cuprimine / D-Pen)", "β,β-Dimethylcysteine\n(hydrolysis product of penicillin)", "Cu (main), Pb, Hg,\nZn, Fe", "Oral\n(unique advantage)", "Drug of choice: Wilson's disease, Cystinuria\nOnly agent given orally for long term\nGive Pyridoxine 25–50 mg/day with it", "Penicillin allergy\nPregnancy (teratogenic)"],
["Deferoxamine\n(Desferrioxamine)", "Deferoxamine mesylate\nDesferal", "Fe³⁺ (ferric ion only)\nAluminium", "Oral / IM / IV\n(all routes)", "Drug of choice: Acute iron poisoning & Haemochromatosis\nDoes NOT chelate Fe from Hb or cytochromes\nUrine turns 'vin rosé' (pink-orange) = positive test", "Not for primary haemochromatosis treatment alone"],
["DMSA\n(Succimer)", "Dimercaptosuccinic acid\n2,3-DMSA", "Pb (children), As,\nHg, Cd", "Oral\n(water soluble BAL analogue)", "Drug of choice: Pb poisoning in children\nWater-soluble; less toxic than BAL\nCan cross blood–brain barrier (minor)", "—"],
["DMPS", "2,3-Dimercaptopropane-\n1-sulphonate", "Hg (organic + inorganic),\nAs, Pb", "IV / Oral", "Used in mercury poisoning (esp. organic)\nMore water-soluble than BAL", "—"],
["Prussian Blue\n(Ferric hexacyanoferrate)", "Ferric ferrocyanide", "Thallium (Tl)\nRadiocesium (¹³⁷Cs)", "Oral", "Ion exchange in gut; prevents reabsorption\nFDA approved for Tl & radiocesium\nBlue stool expected", "—"],
["Deferiprone\n(L1)", "1,2-Dimethyl-3-\nhydroxypyrid-4-one", "Fe³⁺ (oral iron chelator)", "Oral", "Used in thalassaemia iron overload\nSecond-line if deferoxamine fails\nSide effect: Agranulocytosis (monitor WBC)", "—"],
["Desferasirox\n(Exjade)", "Deferasirox", "Fe³⁺", "Oral\n(once daily)", "Newer oral iron chelator\nUsed in transfusion-related iron overload", "Renal failure (nephrotoxic)"],
["Dithiocarb\n(Diethyldithiocarbamate)", "Sodium diethyldithiocarbamate", "Nickel carbonyl (main)", "IV", "Drug of choice: Nickel carbonyl pneumonitis", "—"],
["Hydroxocobalamin", "Vitamin B12a", "Cyanide (CN⁻)", "IV", "Drug of choice: Cyanide poisoning\nBinds CN to form cyanocobalamin\nTurns urine red", "—"],
["Protamine Sulphate", "Basic protein (from fish sperm)", "Heparin (not a metal)", "IV", "Antidote for heparin overdose\nNot a classical chelator but functionally similar", "—"],
]
master_tdata = [master_hdr]
row_bgs = [WHITE, LT_BLUE]
for i, row in enumerate(master_rows):
bg = row_bgs[i % 2]
master_tdata.append([Paragraph(f"<b>{row[0]}</b>", TC_C), Paragraph(row[1], TC_S), Paragraph(f"<b>{row[2]}</b>", TC_S), Paragraph(row[3], TC_C), Paragraph(row[4], TC_S), Paragraph(row[5], TC_S)])
mt = Table(master_tdata, colWidths=[24*mm, 32*mm, 28*mm, 18*mm, 52*mm, 28*mm], repeatRows=1)
mt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 4),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LT_BLUE]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(mt)
story.append(sp(5))
# ─── DRUG PROFILES ───────────────────────────────────────────────────────────
story.append(banner("INDIVIDUAL DRUG PROFILES (Exam Detail)", TEAL))
story.append(sp(3))
# ─ BAL ─
story.append(drug_banner("1. BAL — British Anti-Lewisite (Dimercaprol)", "Dimercaptopropanol | 2,3-Dimercapto-1-propanol", color=TEAL))
story.append(sp(2))
story.append(info_table([
("Full name", "British Anti-Lewisite (BAL) | Dimercaptopropanol"),
("Mechanism", "Heavy metal ions combine with sulphydryl (SH) groups of tissue enzymes, blocking them. "
"BAL has 2 thiol (-SH) groups that compete with tissue SH groups, grab the metal ion, "
"form a stable chelate ring (2 mol BAL : 1 mol metal) → excreted in urine & bile."),
("Metals chelated","Arsenic (DOC), Mercury (DOC), Lead, Antimony, Gold, Thallium, Copper, Bismuth"),
("Route / Dose", "Deep IM (ONLY) in arachis/peanut oil with 20% benzyl benzoate; "
"Dose: 3–4 mg/kg body weight; 4-hourly × 2 days, then 3× daily × 10 days"),
("Preparation", "Ampoule: 100 mg/mL — 2 mL of 10% compound in arachis oil"),
("Side effects", "Anorexia / Nausea / Vomiting | Excessive salivation, lachrymation | "
"Generalised aches & pains | Hyperthermia | Chest constriction | "
"Burning eyes & throat | Fall in BP (appear at >3.5 mg/kg)"),
("Contraindicated","Cadmium poisoning (forms nephrotoxic BAL-Cd complex) | Hepatic disease | "
"Relatively CI in renal disease"),
("Special facts", "Originally developed as antidote for Lewisite (arsenic war gas) | "
"Give BAL at least 4 hours BEFORE EDTA in lead poisoning | "
"Chelator of CHOICE when renal function is impaired"),
], LT_TEAL, TEAL))
story.append(sp(4))
# ─ EDTA ─
story.append(drug_banner("2. CaNa₂EDTA — Calcium Disodium Versenate", "Ethylene Diamine Tetra-acetic Acid (Calcium Disodium Edetate)", color=DKGREEN))
story.append(sp(2))
story.append(info_table([
("Full name", "Calcium Disodium EDTA (CaNa₂EDTA) | Calcium Disodium Versenate"),
("Mechanism", "Acts as an ion exchanger: Ca²⁺ is exchanged for heavy metal ion (Pb²⁺). "
"Lead displaces calcium, forming stable, soluble, non-ionized Pb-EDTA complex → excreted in urine. "
"Chelates extracellular lead in soft tissues AND bones. "
"Urinary lead excretion increases ×50 above baseline."),
("Metals chelated","Lead (BEST — inorganic only), Zinc, Manganese, Copper, Nickel, Cadmium, Iron"),
("NOT effective", "Tetraethyl lead (organic lead) | Less effective for Manganese, Iron, Cd, radioactive elements | "
"INFERIOR to BAL for Arsenic & Mercury"),
("Route / Dose", "IV infusion (NOT oral — oral increases GIT lead absorption!) | "
"5 mL of 20% solution in 250–500 mL NS or 5% dextrose-saline; "
"concentration must NOT exceed 3%; drip >2 hours; "
"50–70 mg/kg/day; 1 g IV twice daily × 5 days; repeat after 3-day gap"),
("Side effects", "Thrombophlebitis (strong solution) | Lower nephron nephrosis | "
"Hypersensitivity | Fever, headache, malaise | Lachrymation, nasal congestion | "
"Sneezing, muscle pain | Hypotension"),
("Contraindicated","Raised intracranial pressure (fluids must be restricted)"),
("Special facts", "NEVER give orally (chelates gut lead → increased absorption) | "
"Give BAL 4 hrs BEFORE EDTA in lead poisoning | "
"Best chelator for inorganic lead poisoning"),
], LT_GREEN, DKGREEN))
story.append(sp(4))
# ─ Penicillamine ─
story.append(drug_banner("3. Penicillamine (Cuprimine / D-Pen)", "β,β-Dimethylcysteine — Hydrolysis Product of Penicillin", color=PURPLE))
story.append(sp(2))
story.append(info_table([
("Full name", "D-Penicillamine | Cuprimine | β,β-Dimethylcysteine"),
("Mechanism", "Contains stable SH (thiol) groups (product of penicillin hydrolysis). "
"SH groups chelate heavy metals. Can be given orally and continuously without major toxicity."),
("Metals chelated","Copper (PRIMARY — DOC for Wilson's disease), Lead, Mercury, Zinc, Iron"),
("Indications", "Wilson's disease (hepatolenticular degeneration — copper metabolism disorder) | "
"Cystinuria | Lead, Cu, Hg, Zn poisoning | Rheumatoid arthritis (DMARDs use)"),
("Route / Dose", "ORAL (unique advantage over BAL, EDTA) | "
"0.5 g orally 30 min before meals × 4 times/day × 8–10 days | "
"Also IM: 30 mg/kg body weight"),
("Side effects", "Hypersensitivity: skin rashes, nephrotoxicity | "
"Optic neuritis (due to pyridoxine deficiency — give Pyridoxine 25–50 mg/day) | "
"Leucopenia, Thrombocytopenia, Agranulocytosis"),
("Contraindicated","Penicillin allergy | Pregnancy (teratogenic) | Systemic lupus"),
("Special facts", "Only oral chelating agent for LONG-TERM use | "
"Always supplement Pyridoxine (Vit B6) 25–50 mg/day | "
"DOC for Wilson's disease and Cystinuria | "
"Commercial preparation: controlled decomposition of penicillin"),
], LT_PURPLE, PURPLE))
story.append(sp(4))
# ─ Deferoxamine ─
story.append(drug_banner("4. Deferoxamine (Desferrioxamine / Desferal)", "Siderophore — Specific Ferric (Fe³⁺) Chelator", color=MAROON))
story.append(sp(2))
story.append(info_table([
("Full name", "Desferrioxamine mesylate | Deferoxamine | Desferal"),
("Mechanism", "Water-soluble compound with great affinity for ferric ion (Fe³⁺). "
"Removes iron from ferritin and hemosiderin. "
"Does NOT chelate iron from haemoglobin or cytochromes (selective). "
"Forms ferrioxamine complex → excreted in urine."),
("Metals chelated","Iron (Fe³⁺) — PRIMARY; also Aluminium"),
("Indications", "DOC: Acute iron poisoning | Haemochromatosis (iron overload) | "
"Thalassaemia (iron overload from transfusions — with deferiprone)"),
("Route / Dose", "Oral: 8–10 g in 80–100 mL distilled water | "
"IM: 1 g initially → 0.5 g 2–3× daily | "
"IV: 1–2 g in 500 mL 5% dextrose saline; NOT more than 15 mg/kg/hr or 80 mg/kg/24 hr"),
("Key test", "Urine turns PINK-ORANGE ('Vin rosé' colour) after deferoxamine → confirms iron poisoning"),
("Side effects", "Hypotension (rapid IV) | Allergic reactions | Neurotoxicity (long-term) | "
"Growth retardation in children | Yersinia enterocolitica infection risk"),
("Special facts", "Does NOT remove iron from Hb or cytochromes | "
"Vin rosé urine = diagnostic AND therapeutic confirmation | "
"Also used in intracerebral haemorrhage research (removes haematoma iron)"),
], LT_PINK, MAROON))
story.append(sp(4))
# ─ DMSA ─
story.append(drug_banner("5. DMSA — Succimer (Dimercaptosuccinic Acid)", "Oral BAL Analogue — Drug of Choice for Paediatric Lead Poisoning", color=ORANGE))
story.append(sp(2))
story.append(info_table([
("Full name", "2,3-Dimercaptosuccinic acid (DMSA) | Succimer | Chemet"),
("Mechanism", "Water-soluble analogue of BAL with 2 thiol (SH) groups. "
"Can be given orally (unlike BAL). Less toxic. "
"Chelates lead intracellularly and extracellularly."),
("Metals chelated","Lead (PRIMARY — children's DOC), Arsenic, Mercury, Cadmium"),
("Route / Dose", "ORAL: 10 mg/kg every 8 hrs × 5 days, then every 12 hrs × 14 days"),
("Side effects", "GI upset | Skin rash | Transaminase elevation | Sulphurous odour (from thiol groups)"),
("Special facts", "DOC for lead poisoning in CHILDREN | "
"More water-soluble and less toxic than BAL | "
"Can penetrate CNS (minor) | "
"First oral chelator approved for paediatric lead poisoning (FDA)"),
], LT_ORANGE, ORANGE))
story.append(sp(5))
# ── MNEMONICS ────────────────────────────────────────────────────────────────
story.append(banner("MNEMONICS & MEMORY AIDS", color=colors.HexColor("#b35900")))
story.append(sp(3))
mnemonics = [
(
"🔑 METALS CHELATED BY BAL — Mnemonic: 'A MAGIC Compound'",
[
"A = Arsenic (DOC)",
"M = Mercury (DOC)",
"A = Antimony",
"G = Gold",
"I = [lead] Intracellular chelation",
"C = Copper / Cobalt / Cadmium (CI — nephrotoxic!)",
" → Also: Thallium, Bismuth",
]
),
(
"🔑 DOC (Drug of Choice) for each metal — Mnemonic: 'BAIL PEDF'",
[
"B = BAL → Arsenic, Mercury (also Lead in renal impairment)",
"A = —",
"I = —",
"L = Lead → CaNa₂EDTA (inorganic Pb); DMSA (children)",
" ─────────────────────────────────────",
"P = Penicillamine → Copper (Wilson's disease), Cystinuria",
"E = EDTA → Inorganic Lead (adults)",
"D = Deferoxamine → Iron",
"F = DMSA (Fine for children) → Paediatric Lead",
]
),
(
"🔑 PENICILLAMINE side effects — Mnemonic: 'HOL-P'",
[
"H = Hypersensitivity (rash, nephropathy)",
"O = Optic neuritis (pyridoxine deficiency → give Vit B6!)",
"L = Leucopenia / thrombocytopenia / agranulocytosis",
"P = Pyridoxine deficiency (always supplement B6 25–50 mg/day)",
]
),
(
"🔑 DEFEROXAMINE — Key facts to remember: 'VIN ROSE'",
[
"V = Vin rosé urine (pink-orange) = positive test for iron poisoning",
"I = Iron (Fe³⁺) only — ferric iron",
"N = NOT Hb, NOT cytochromes (spared)",
"R = Removes iron from ferritin, hemosiderin",
"O = Oral / IM / IV (all routes)",
"S = Selective ferric ion chelator",
"E = Emergency use in acute iron poisoning",
]
),
(
"🔑 BAL CONTRAINDICATIONS — Mnemonic: 'BAL CAN'T do Cadmium'",
[
"Cadmium → BAL + Cd = nephrotoxic complex (ABSOLUTELY CI)",
"Hepatic disease → absolutely contraindicated",
"Kidney disease → relatively contraindicated",
"Also: BAL must be given 4 hrs BEFORE EDTA in lead poisoning",
]
),
(
"🔑 EDTA — 'Never give EDTA by mouth' (Oral EDTA increases Pb absorption from GIT!)",
[
"E = Exchange — Ca for Pb (ion exchanger mechanism)",
"D = Drip (IV, slow, >2 hrs; concentration <3%)",
"T = Twice daily × 5 days, then 3-day gap, repeat",
"A = Always give BAL 4 hrs BEFORE EDTA",
"EXTRA: Urinary Pb excretion ×50 above baseline after EDTA",
]
),
(
"🔑 COMPARISON TABLE: BAL vs EDTA vs Penicillamine — Quick Recall",
[
"Feature | BAL | EDTA | Penicillamine",
"─────────────────────────────────────────────────────────────────────",
"Route | IM only | IV / IM | ORAL (only oral)",
"Metal (DOC) | As, Hg | Pb (inorganic) | Cu (Wilson's)",
"Mechanism | Thiol (SH) grp | Ion exchange | Thiol (SH) grp",
"CI | Cadmium, Liver | Raised ICP | PCN allergy, Preg",
"Give with | Nothing special | BAL 4 hr before | Pyridoxine (B6)",
"Solvent | Arachis oil | Saline/Dextrose | —",
]
),
(
"🔑 Urine Colour Clues in Chelation Therapy",
[
"Pink-Orange (Vin rosé) → Deferoxamine given for iron poisoning",
"Blue stool → Prussian Blue given for Thallium / Radiocesium",
"Red urine → Hydroxocobalamin given for Cyanide poisoning",
]
),
]
for title, lines in mnemonics:
story.append(mnemonic_box(title, lines))
story.append(sp(2.5))
story.append(sp(3))
# ── HIGH-YIELD EXAM POINTS ────────────────────────────────────────────────────
story.append(banner("HIGH-YIELD EXAM POINTS (Must Know)", MAROON))
story.append(sp(2))
exam_data = [
[Paragraph("<b>Question / Scenario</b>", TH_S), Paragraph("<b>Answer</b>", TH_S)],
[Paragraph("DOC for arsenic poisoning", TC_S), Paragraph("<b>BAL (Dimercaprol)</b>", TC_S)],
[Paragraph("DOC for mercury poisoning", TC_S), Paragraph("<b>BAL</b> (DMPS for organic mercury)", TC_S)],
[Paragraph("DOC for inorganic lead in adults", TC_S), Paragraph("<b>CaNa₂EDTA</b> (give BAL 4 hrs before)", TC_S)],
[Paragraph("DOC for lead poisoning in children", TC_S), Paragraph("<b>DMSA (Succimer)</b> — oral", TC_S)],
[Paragraph("DOC for copper poisoning / Wilson's disease", TC_S), Paragraph("<b>Penicillamine</b> (oral)", TC_S)],
[Paragraph("DOC for acute iron poisoning", TC_S), Paragraph("<b>Deferoxamine</b> (Desferrioxamine)", TC_S)],
[Paragraph("DOC for thallium poisoning", TC_S), Paragraph("<b>Prussian Blue</b> (Ferric hexacyanoferrate)", TC_S)],
[Paragraph("DOC for nickel carbonyl poisoning", TC_S), Paragraph("<b>Dithiocarb (Diethyldithiocarbamate)</b>", TC_S)],
[Paragraph("DOC for cyanide poisoning", TC_S), Paragraph("<b>Hydroxocobalamin</b> (IV) ± Sodium thiosulphate", TC_S)],
[Paragraph("Only chelator given ORALLY long-term", TC_S), Paragraph("<b>Penicillamine</b>", TC_S)],
[Paragraph("BAL absolutely contraindicated in which metal?", TC_S), Paragraph("<b>Cadmium</b> (forms nephrotoxic complex)", TC_S)],
[Paragraph("Why NOT give EDTA orally?", TC_S), Paragraph("Chelates gut lead → <b>INCREASES absorption</b> from GIT", TC_S)],
[Paragraph("Order of giving BAL + EDTA in lead poisoning", TC_S), Paragraph("<b>BAL first (4 hrs before EDTA)</b> — BAL mobilizes intracellular Pb, then EDTA mops up", TC_S)],
[Paragraph("Vin rosé (pink-orange) urine after chelation", TC_S), Paragraph("<b>Deferoxamine</b> — confirms iron poisoning / therapy working", TC_S)],
[Paragraph("Vitamin to give with Penicillamine", TC_S), Paragraph("<b>Pyridoxine (Vit B6)</b> 25–50 mg/day", TC_S)],
[Paragraph("Penicillamine source / origin", TC_S), Paragraph("<b>Hydrolysis of Penicillin</b> (controlled decomposition)", TC_S)],
[Paragraph("EDTA mechanism in brief", TC_S), Paragraph("Ion exchange: Ca²⁺ displaced by Pb²⁺ → Pb-EDTA complex excreted in urine; urinary Pb ×50 baseline", TC_S)],
[Paragraph("Which chelator works in impaired renal function?", TC_S), Paragraph("<b>BAL</b> — excreted via bile (not dependent on renal excretion)", TC_S)],
[Paragraph("Deferoxamine does NOT chelate iron from?", TC_S), Paragraph("<b>Haemoglobin and Cytochromes</b>", TC_S)],
]
exam_t = Table(exam_data, colWidths=[82*mm, 100*mm], repeatRows=1)
exam_t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), MAROON),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("VALIGN", (0,0), (-1,-1), "TOP"),
("TOPPADDING", (0,0), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-1), 3),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
("ROWBACKGROUNDS",(0,1), (-1,-1), [WHITE, LT_PINK]),
("GRID", (0,0), (-1,-1), 0.3, colors.HexColor("#aaaaaa")),
("LINEBELOW", (0,0), (-1,0), 1.5, GOLD),
]))
story.append(exam_t)
story.append(sp(4))
# ── FOOTER ────────────────────────────────────────────────────────────────────
foot = Table([[Paragraph(
"<b>Sources:</b> PC Dikshit Textbook of Forensic Medicine & Toxicology | "
"Katzung's Basic & Clinical Pharmacology 16e | Compiled for FMT exam revision. "
"All dose information is for academic reference — always verify with current clinical guidelines.",
NOTE_S)]], colWidths=[182*mm])
foot.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LT_YELLOW),
("BOX", (0,0), (-1,-1), 0.7, GOLD),
("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(foot)
doc.build(story)
print(f"PDF created: {doc_path}")
cd /tmp/workspace/fmt-chelating-notes && python generate_chelating_pdf.py 2>&1
ls -lh /tmp/workspace/fmt-chelating-notes/Chelating_Agents_FMT_Notes.pdf
Chelating Agents FMT Notes
PDF Document · PDF
| Agent | Metals | Route | CI |
|---|---|---|---|
| BAL | As, Hg, Pb, Sb, Au, Tl | IM only (oil) | Cadmium, Liver disease |
| CaNa₂EDTA | Pb (best), Zn, Mn, Cu | IV/IM (NOT oral) | Raised ICP |
| Penicillamine | Cu, Pb, Hg, Zn | ORAL | PCN allergy, Pregnancy |
| Deferoxamine | Fe³⁺ only | Oral/IM/IV | — |
| DMSA (Succimer) | Pb (children), As, Hg | Oral | — |
| Prussian Blue | Thallium, Radiocesium | Oral | — |
| Deferirpone / Deferasirox | Fe³⁺ | Oral | Agranulocytosis risk |
| Hydroxocobalamin | Cyanide | IV | — |