1. What are the implications of ignoring a court summons? 22. What is the borrowed servant doctrine? 32. Describe exhumation. 37. What is IPC Section 84? 42. What is chief and cross-examination in a court of law? 43. What is documentary evidence? 59. What is infamous conduct? 64. What constitutes valid consent? 65. What are the benefits of in loco parentis? 75. What is the doctrine of res ipsa loquitur? 86. What is a subpoena? 100. What is the doctrine of res ipsa loquitur? (repeat) 102. What constitutes grievous hurt? 106. What is privileged communication? (repeat) 117. What is conduct money? 139. What is a subpoena or summons? (repeat) 151. What is an inquest? 10. A body is recovered from a river one week after a suspected drowning incident. Describe the changes of decomposition in such cases. 32. Describe exhumation. (repeat) 38. Enumerate 4 types of early post-mortem changes. 40. Which viscera need to be preserved commonly for chemical analysis during post-mortem examination in a case of poisoning? 81. Describe exhumation (including procedures and indications). (repeat) 85. Describe the preservation of viscera in poisoning cases. 140. What are the methods of removal of organs in post-mortem examination? 154. What are the protocols for sample collection during autopsy? 171. What are the characteristics of entry wounds due to shotgun at various ranges? 11. What causes sudden death? 12. What is Casper's Dictum? 13. What is Tache Noire? 30. Write about suspended animation. 34. What is the differential diagnosis of rigor mortis? 49. What is postmortem caloricity? 50. What is the difference between artificial bruise and true bruise? 77. What is cadaveric spasm? 84. What is suspended animation? (repeat) 89. What is suspended animation? (repeat) 93. What is the difference between rigor mortis and cadaveric spasm? 130. What are the late post-mortem changes? 155. What is post-mortem staining? 158. What is the difference between post-mortem staining and bruising? 5. A 15-year-old student presents with a deep stab wound to his forearm... Describe the detailed information about the stab wound... 9. A 30-year-old woman sustained burns while cooking. How will you assess the burn area and its depth? 14. What are filigree burns? 18. A 40-year-old man accidentally falls... exposed to a concentrated acid solution. Describe the management... 26. Define primary and secondary impact injuries. 29. Describe abrasion in detail. 45. What is primary impact injury? 67. What is the difference between antemortem and postmortem burns? 71. 73. WhWhat is the difference between homicidal and suicidal cut throat wounds?at is the difference between firearm entry and exit wounds? 82. What is contusion? 118. What is laceration? 134. What is the difference between ante-mortem and post-mortem wounds? 137. What are contusions (bruises)? 141. What is the medico-legal importance of abrasions? 4. Describe the postmortem signs of asphyxia. 7. What is the difference between hanging and strangulation? 83. Describe HCN (hydrogen cyanide) poisoning. 135. What is the difference between hanging and strangulation? (repeat) 17. What are the key clinical signs... after a venomous snake bite? 20. Describe the management of aluminium phosphide poisoning. 21. Describe the early symptoms... of acute arsenic poisoning. 35. Describe war gases. 36. Describe the treatment of methanol poisoning. 48. What are the signs and symptoms of Dhatura poisoning? 61. What is the management of OPC poisoning? 79. What is the treatment of methyl alcohol poisoning? 95. What is the difference between arsenic poisoning and cholera? 103. What are the medicolegal duties of a doctor in case of a suspected poisoning. 105. What is the treatment of methyl alcohol poisoning? (repeat) 143. What is the treatment of Datura poisoning. 161. What are the duties of a doctor in a suspected case of poisoning (repeat) 166. What is Dhatura poisoning? (repeat) 39. Enumerate 4 types of unnatural sexual offences. 56. What are the positive signs of pregnancy? 68. What are the confirmatory diagnostic signs of pregnancy? 74. What is the difference between a stillborn and deadborn fetus? 78. What are the types of hymen? 112. What is the difference between a true virgin and false virgin? 164. What are the positive signs of pregnancy? ( 15. What is impulse in the context of forensic psychiatry? 16. What are the key features of mental health assessments in medico-legal contexts? 54. What is transvestism? 69. What is hallucination? 90. What are delusions? 98. What is Magnan's syndrome? 99. What is transvestism? (repeat) 110. What is the right-wrong test? 126. What is Munchausen syndrome by proxy? 131. What are delusions? (repeat) 168. What are delusions? 24. Classify the patterns of fingerprints. 92. What are the differences between male and female pelvis? 107. What is vicarious liability? 108. What is cheiloscopy? 113. What is the difference between human hair and animal hair? 145. What is dactylography? 157. What are the differences between male and female skulls? ### Chapter 10: MTP Act & Reproductive Health (Questions 27, 52, 60, 104, 152) 27. What is the difference between natural and criminal abortion? 52. What is the difference between criminal abortion and natural abortion? (repeat) 60. What is the MTP Act? 104. What is the MTP Act? (repeat) 152. What is the MTP Act? 3. What are the signs of head injury? 6. Describe coma cocktail therapy. 8. Describe the various components... of taking informed consent for surgery. 19. Describe informed refusal. 23. What is a lucid interval? Give an example. 25. Write briefly about surrogacy and its medico-legal significance. 28. Describe privileged communication. 31. Write about intersex. 33. Describe brain stem death. 41. What is virtual autopsy? 44. What is Gustafson's method? 46. What is immersion syndrome? 47. What is testamentary capacity? 55. What is cafe coronary? 57. What is Untersuchungsanboots (immersion foot syndrome)? 58. What is Magnan's syndrome? (repeat) 62. What is negative autopsy? 63. What is superimposition? 70. Describe the cartridge of a smooth bore firearm. 76. What is IPC Section 320? 80. What are Joule burns? 87. What is the hydrostatic test? 88. What is Turner's syndrome? 91. What are Joule burns? (repeat) 94. What are the differences between burns from dry heat, moist heat, and chemicals? 96. What are the contraindications of gastric lavage? 97. What is Burtonian line? 101. What is testamentary capacity? (repeat) 109. What is a tandem bullet? 114. What is the difference between drunkenness and concussion? 115. What are abortifacient drugs? 116. Describe the preparation of cannabis. 119. Draw a labelled diagram of a shotgun cartridge. 120. What is parrot's perch (position)? 121. What is plumbism? 122. What is Burking? 123. What is narcoanalysis? 124. What is solvent abuse? 125. What are Joule burns? (repeat) 127. What is IPC Section 375? 128. What is body packer syndrome? 132. What is the difference between strychnine poisoning and tetanus? 133. What is the difference between drug addiction and drug habituation? 136. What is the medico-legal importance of age? 138. What is botulism? 142. What are counter-coup lesions? 144. What is the 'Rule of Nines' (Wallace rule)? 146. What is gastric lavage? 147. What is ergot poisoning? 148. What is battered baby syndrome? 149. What is bestiality? 150. What constitutes grievous hurt? (repeat) 156. What are the types of skull fractures? 159. What is the difference between ante-mortem and post-mortem burns? (repeat) 160. What is the difference between neurotoxic and vasculotoxic venom snakes? 162. What is vitriolage? 165. What are the causes of impotency and sterility in males? 169. What are the signs of a liveborn child?🧠 1. Forensic Psychiatry & Mental Health β€’ What is transvestism? (repeat removed) β€’ What is hallucination? β€’ What are delusions? (multiple repeats merged) β€’ What is Magnan’s syndrome? (repeat merged) β€’ What is Munchausen syndrome by proxy? β€’ Write about intersex. β€’ What is narcoanalysis? β€’ What is solvent abuse? β€’ What is the difference between drug addiction and drug habituation? βΈ» βš–οΈ 2. Medical Jurisprudence & Legal Concepts β€’ What is the right-wrong test? β€’ What is vicarious liability? β€’ Describe privileged communication. β€’ What is testamentary capacity? (repeat merged) β€’ What is IPC Section 320? β€’ What constitutes grievous hurt? (repeat merged) β€’ What is IPC Section 375? β€’ What is the medico-legal importance of age? βΈ» 🧬 3. Identification & Forensic Anthropology β€’ Classify the patterns of fingerprints. β€’ What is dactylography? β€’ What is cheiloscopy? β€’ What is superimposition? β€’ What are the differences between male and female pelvis? β€’ What are the differences between male and female skulls? β€’ What is the difference between human hair and animal hair? βΈ» πŸ‘Ά 4. Reproductive Health, Sexual Offences & MTP β€’ What is the difference between natural and criminal abortion? (repeat merged) β€’ What is the MTP Act? (repeat merged) β€’ Write briefly about surrogacy and its medico-legal significance. β€’ What are abortifacient drugs? β€’ What are the causes of impotency and sterility in males? β€’ What are the signs of a liveborn child? β€’ What is bestiality? βΈ» ☠️ 5. Toxicology & Poisoning β€’ What are the contraindications of gastric lavage? β€’ What is gastric lavage? β€’ What is Burtonian line? β€’ What is plumbism? β€’ What is botulism? β€’ What is ergot poisoning? β€’ Describe the preparation of cannabis. β€’ What is body packer syndrome? β€’ What is the difference between strychnine poisoning and tetanus? βΈ» πŸ”₯ 6. Burns, Injuries & Trauma β€’ What are Joule burns? (repeat merged) β€’ What are the differences between burns (dry, moist, chemical)? β€’ What is the difference between ante-mortem and post-mortem burns? (repeat merged) β€’ What is the Rule of Nines (Wallace rule)? β€’ What are counter-coup lesions? β€’ What are the types of skull fractures? β€’ What are the signs of head injury? βΈ» πŸ§ͺ 7. Forensic Pathology & Autopsy β€’ What is virtual autopsy? β€’ What is negative autopsy? β€’ What is immersion syndrome? β€’ What is cafe coronary? β€’ What is Untersuchungsanboots (immersion foot syndrome)? β€’ What is Burking? β€’ What is battered baby syndrome? βΈ» πŸ”« 8. Ballistics & Firearms β€’ Describe the cartridge of a smooth bore firearm. β€’ Draw a labelled diagram of a shotgun cartridge. β€’ What is a tandem bullet? βΈ» ⚑ 9. Miscellaneous Medical & Forensic Concepts β€’ Describe coma cocktail therapy. β€’ Components of informed consent for surgery. β€’ Describe informed refusal. β€’ What is a lucid interval? β€’ Describe brain stem death. β€’ What is Gustafson’s method? β€’ What is hydrostatic test? β€’ What is Turner’s syndrome? β€’ What is parrot’s perch (position)? β€’ What is vitriolage? β€’ What is the difference between drunkenness and concussion? β€’ What is the difference between neurotoxic and vasculotoxic snake venom? Now arrange them chapter

Reading File
The user is asking me to organize the listed forensic medicine questions into chapters - this is primarily an organizational/classification task, not a content-generation task. No tool calls are needed for this. I can do this directly from my knowledge of standard forensic medicine textbook chapter organization.
Here is the complete chapter-wise organization of all the questions listed:

Forensic Medicine & Toxicology - Chapter-wise Question Bank


Chapter 1: Medical Jurisprudence & Legal Concepts

Q. No.Question
1What are the implications of ignoring a court summons?
22What is the borrowed servant doctrine?
37What is IPC Section 84?
42What is chief and cross-examination in a court of law?
43What is documentary evidence?
59What is infamous conduct?
64What constitutes valid consent?
65What are the benefits of in loco parentis?
75What is the doctrine of res ipsa loquitur?
86 / 139What is a subpoena / summons?
100What is the doctrine of res ipsa loquitur?
106What is privileged communication?
117What is conduct money?
107What is vicarious liability?
28Describe privileged communication.
76What is IPC Section 320?
127What is IPC Section 375?
136What is the medico-legal importance of age?
150 / 102What constitutes grievous hurt?
101 / 47What is testamentary capacity?
8Describe the various components of taking informed consent for surgery.
19Describe informed refusal.
103 / 161What are the medico-legal duties of a doctor in a suspected case of poisoning?
110What is the right-wrong test?
25Write briefly about surrogacy and its medico-legal significance.

Chapter 2: Forensic Pathology - Post-Mortem Examination & Autopsy

Q. No.Question
32 / 81Describe exhumation (including procedures and indications).
38Enumerate 4 types of early post-mortem changes.
40 / 85Which viscera need to be preserved for chemical analysis during post-mortem in poisoning? / Describe preservation of viscera in poisoning cases.
140What are the methods of removal of organs in post-mortem examination?
154What are the protocols for sample collection during autopsy?
88What is the hydrostatic test?
41What is virtual autopsy?
62What is negative autopsy?
88What is Turner's syndrome? (misplaced - belongs in Reproductive/Clinical)
151What is an inquest?
10A body recovered from a river one week after drowning - describe changes of decomposition.

Chapter 3: Thanatology (Death & Post-Mortem Changes)

Q. No.Question
11What causes sudden death?
12What is Casper's Dictum?
13What is Tache Noire?
30 / 84 / 89Write about suspended animation.
34What is the differential diagnosis of rigor mortis?
49What is post-mortem caloricity?
77What is cadaveric spasm?
93What is the difference between rigor mortis and cadaveric spasm?
130What are the late post-mortem changes?
155What is post-mortem staining?
158What is the difference between post-mortem staining and bruising?
33Describe brain stem death.
46What is immersion syndrome?
55What is cafe coronary?
57What is Untersuchungsanboots (immersion foot syndrome)?

Chapter 4: Mechanical Injuries (Wounds & Trauma)

Q. No.Question
5A 15-year-old with deep stab wound to forearm - describe the stab wound in detail.
26Define primary and secondary impact injuries.
29Describe abrasion in detail.
45What is primary impact injury?
73What is the difference between homicidal and suicidal cut throat wounds?
82What is contusion?
118What is laceration?
134What is the difference between ante-mortem and post-mortem wounds?
137What are contusions (bruises)?
141What is the medico-legal importance of abrasions?
50What is the difference between artificial bruise and true bruise?
142What are counter-coup lesions?
3What are the signs of head injury?
23What is a lucid interval? Give an example.
156What are the types of skull fractures?
122What is Burking?

Chapter 5: Burns & Thermal/Chemical Injuries

Q. No.Question
9A 30-year-old woman sustained burns while cooking - assess burn area and depth.
14What are filigree burns?
18A 40-year-old man exposed to concentrated acid - describe management.
67What is the difference between ante-mortem and post-mortem burns?
80 / 91 / 125What are Joule burns?
94What are the differences between burns from dry heat, moist heat, and chemicals?
144What is the Rule of Nines (Wallace rule)?
159What is the difference between ante-mortem and post-mortem burns? (repeat)
162What is vitriolage?

Chapter 6: Asphyxia & Respiratory Deaths

Q. No.Question
4Describe the post-mortem signs of asphyxia.
7 / 135What is the difference between hanging and strangulation?
120What is parrot's perch (position)?

Chapter 7: Ballistics & Firearms

Q. No.Question
70Describe the cartridge of a smooth bore firearm.
71What is the difference between firearm entry and exit wounds?
109What is a tandem bullet?
119Draw a labelled diagram of a shotgun cartridge.
171What are the characteristics of entry wounds due to shotgun at various ranges?

Chapter 8: Toxicology - General & Specific Poisons

Q. No.Question
17What are the key clinical signs after a venomous snake bite?
20Describe the management of aluminium phosphide poisoning.
21Describe early symptoms of acute arsenic poisoning.
35Describe war gases.
36 / 79 / 105Describe the treatment of methanol / methyl alcohol poisoning.
48 / 143 / 166What are the signs and symptoms of Dhatura / Datura poisoning? / What is the treatment of Datura poisoning?
61What is the management of OPC (organophosphorus compound) poisoning?
83Describe HCN (hydrogen cyanide) poisoning.
95What is the difference between arsenic poisoning and cholera?
97What is Burtonian line?
98 / 58What is Magnan's syndrome?
121What is plumbism?
128What is body packer syndrome?
132What is the difference between strychnine poisoning and tetanus?
138What is botulism?
147What is ergot poisoning?
160What is the difference between neurotoxic and vasculotoxic snake venom?
96What are the contraindications of gastric lavage?
146What is gastric lavage?

Chapter 9: Narcotic & Substance Abuse

Q. No.Question
116Describe the preparation of cannabis.
123What is narcoanalysis?
124What is solvent abuse?
133What is the difference between drug addiction and drug habituation?

Chapter 10: Reproductive Forensics, Sexual Offences & MTP Act

Q. No.Question
27 / 52What is the difference between natural and criminal abortion?
39Enumerate 4 types of unnatural sexual offences.
56 / 68 / 164What are the positive / confirmatory diagnostic signs of pregnancy?
60 / 104 / 152What is the MTP Act?
74What is the difference between a stillborn and deadborn fetus?
78What are the types of hymen?
112What is the difference between a true virgin and false virgin?
115What are abortifacient drugs?
149What is bestiality?
165What are the causes of impotency and sterility in males?
169What are the signs of a liveborn child?
25Write briefly about surrogacy and its medico-legal significance.
31Write about intersex.
88What is Turner's syndrome?

Chapter 11: Forensic Psychiatry & Mental Health Law

Q. No.Question
15What is impulse in forensic psychiatry?
16What are the key features of mental health assessments in medico-legal contexts?
37What is IPC Section 84? (McNaghten rules / legal insanity)
54 / 99What is transvestism?
69What is hallucination?
90 / 131 / 168What are delusions?
98What is Magnan's syndrome?
110What is the right-wrong test?
126What is Munchausen syndrome by proxy?
148What is battered baby syndrome?

Chapter 12: Forensic Medicine - Identification & Forensic Anthropology

Q. No.Question
24Classify the patterns of fingerprints.
44What is Gustafson's method?
63What is superimposition?
92What are the differences between male and female pelvis?
108What is cheiloscopy?
113What is the difference between human hair and animal hair?
145What is dactylography?
157What are the differences between male and female skulls?

Chapter 13: Clinical Forensic Medicine & Miscellaneous

Q. No.Question
6Describe coma cocktail therapy.
33Describe brain stem death.
114What is the difference between drunkenness and concussion?
163(missing/unclear)

Summary: Chapter-wise Distribution

ChapterTopicApprox. No. of Questions
1Medical Jurisprudence & Legal Concepts~25
2Post-Mortem Examination & Autopsy~10
3Thanatology & Post-Mortem Changes~15
4Mechanical Injuries & Wounds~15
5Burns & Thermal/Chemical Injuries~9
6Asphyxia & Respiratory Deaths~3
7Ballistics & Firearms~5
8Toxicology - General & Specific Poisons~20
9Narcotic & Substance Abuse~4
10Reproductive Forensics, Sexual Offences & MTP~14
11Forensic Psychiatry & Mental Health Law~10
12Forensic Identification & Anthropology~8
13Clinical Forensic Medicine & Miscellaneous~3

Notes on placement:
  • Questions with (repeat) have been merged under a single entry in the relevant chapter.
  • A few questions span two chapters (e.g., IPC Section 84 sits in both Jurisprudence and Psychiatry because it deals with legal insanity).
  • Turner's syndrome (Q.88) and brain stem death (Q.33) are clinical topics embedded within a forensic context and are placed in Chapters 13/3 respectively.
  • Magnan's syndrome appears in both Toxicology (cocaine-induced formication) and Psychiatry - it is primarily a Toxicology topic but cross-referenced under Forensic Psychiatry.
  • Burtonian line and plumbism both relate to lead poisoning and are grouped under Toxicology (Chapter 8).

Now make 13 PDFs separately for each chapter including answer of these questions only in tables , flowcharts and diagrams reference from standard books like ks Narayan Reddy and consider other books and resources also for better and easy language answer in flow charts

Reading File
Finding Sources
Finding Sources
Running Command

mkdir -p /home/daytona/workspace/forensic-medicine-pdfs && echo "Directory creat…

Make pdf

Make first chapter 1 pdf having flowchart answers of each question along with some theory but flow chart in each question

Finding Sources
Finding Sources
Reading File
Finding Sources
Reading File
Finding Sources
Reading File
Finding Sources
Reading File
Reading File
Writing File

~/forensic-medicine-pdfs/chapter1_gen.py

#!/usr/bin/env python3
"""
Chapter 1: Medical Jurisprudence & Legal Concepts
Forensic Medicine & Toxicology Question Bank PDF
Reference: KS Narayan Reddy (36th Ed 2026), Parikh's, PC Dikshit
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.graphics.shapes import Drawing, Rect, String, Line, Circle, Polygon, Arrow
from reportlab.graphics.charts.flowcharts import FlowChart
from reportlab.graphics import renderPDF
from reportlab.platypus.flowables import Flowable
from reportlab.pdfgen import canvas
import os

OUTPUT_PATH = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter1_Medical_Jurisprudence.pdf"

# ─────────────────────────── COLORS ────────────────────────────
DARK_BLUE   = colors.HexColor("#1a3a5c")
MED_BLUE    = colors.HexColor("#2e6da4")
LIGHT_BLUE  = colors.HexColor("#d0e8f8")
TEAL        = colors.HexColor("#0d7377")
LIGHT_TEAL  = colors.HexColor("#c8f0f0")
ORANGE      = colors.HexColor("#e07b00")
LIGHT_ORANGE= colors.HexColor("#fff0d0")
GREEN       = colors.HexColor("#1a6b3a")
LIGHT_GREEN = colors.HexColor("#d4f0dc")
RED         = colors.HexColor("#b52b27")
LIGHT_RED   = colors.HexColor("#fde8e8")
PURPLE      = colors.HexColor("#5a2d82")
LIGHT_PURPLE= colors.HexColor("#ede0f7")
YELLOW_BG   = colors.HexColor("#fffbe6")
GREY_LIGHT  = colors.HexColor("#f5f5f5")
GREY_MED    = colors.HexColor("#cccccc")
WHITE       = colors.white
BLACK       = colors.black

# ─────────────────────────── STYLES ────────────────────────────
styles = getSampleStyleSheet()

def make_style(name, parent='Normal', **kwargs):
    return ParagraphStyle(name=name, parent=styles[parent], **kwargs)

TITLE_STYLE = make_style('ChTitle', fontSize=26, textColor=WHITE,
    alignment=TA_CENTER, spaceAfter=6, fontName='Helvetica-Bold', leading=32)
SUBTITLE_STYLE = make_style('ChSub', fontSize=13, textColor=LIGHT_BLUE,
    alignment=TA_CENTER, spaceAfter=4, fontName='Helvetica', leading=18)
REF_STYLE = make_style('Ref', fontSize=9, textColor=GREY_MED,
    alignment=TA_CENTER, fontName='Helvetica-Oblique')

Q_STYLE = make_style('QHead', fontSize=14, textColor=WHITE,
    fontName='Helvetica-Bold', leading=20, leftIndent=8, rightIndent=8,
    spaceBefore=14, spaceAfter=6)
BODY_STYLE = make_style('Body', fontSize=10.5, textColor=colors.HexColor("#222222"),
    leading=16, spaceAfter=5, fontName='Helvetica', alignment=TA_JUSTIFY)
BOLD_BODY = make_style('BBody', fontSize=10.5, textColor=DARK_BLUE,
    leading=16, spaceAfter=4, fontName='Helvetica-Bold')
SMALL_STYLE = make_style('Small', fontSize=9, textColor=colors.HexColor("#444"),
    leading=13, spaceAfter=2)
BOX_TITLE = make_style('BoxT', fontSize=11, textColor=DARK_BLUE,
    fontName='Helvetica-Bold', leading=15, spaceAfter=3)
TBL_HDR = make_style('TH', fontSize=9.5, textColor=WHITE,
    fontName='Helvetica-Bold', alignment=TA_CENTER, leading=13)
TBL_CELL = make_style('TC', fontSize=9, textColor=BLACK,
    fontName='Helvetica', leading=13, alignment=TA_LEFT)
TBL_CELL_C = make_style('TCC', fontSize=9, textColor=BLACK,
    fontName='Helvetica', leading=13, alignment=TA_CENTER)
FLOW_TXT = make_style('FT', fontSize=9, textColor=BLACK,
    fontName='Helvetica', leading=12, alignment=TA_CENTER)
FLOW_BOLD = make_style('FB', fontSize=9.5, textColor=DARK_BLUE,
    fontName='Helvetica-Bold', leading=13, alignment=TA_CENTER)
NOTE_STYLE = make_style('Note', fontSize=9, textColor=PURPLE,
    fontName='Helvetica-Oblique', leading=13, leftIndent=10)
MNEMONIC = make_style('Mnem', fontSize=10.5, textColor=GREEN,
    fontName='Helvetica-Bold', leading=15, leftIndent=10)

PAGE_W, PAGE_H = A4
MARGIN = 1.8*cm

# ─────────────────────── FLOWCHART HELPER ──────────────────────
class FlowchartDrawing(Flowable):
    """
    Renders a vertical flowchart from a list of (text, shape, color) tuples.
    shape: 'rect', 'diamond', 'rounded', 'oval', 'terminal'
    Arrows connect each node to the next.
    """
    def __init__(self, nodes, width=None, node_h=32, gap=18, arrow_color=MED_BLUE,
                 label_list=None):
        super().__init__()
        self.nodes = nodes          # list of (text, shape, fill_color, text_color)
        self.nw = width or (PAGE_W - 2*MARGIN - 0.5*cm)
        self.node_h = node_h
        self.gap = gap
        self.arrow_color = arrow_color
        self.label_list = label_list  # optional labels between nodes e.g. ['Yes','No']
        total = len(nodes)*(node_h+gap) - gap + 20
        self.width = self.nw
        self.height = total

    def wrap(self, aW, aH):
        return self.width, self.height

    def draw(self):
        c_obj = self.canv
        y = self.height - 10
        nw = self.nw
        nh = self.node_h
        cx = nw / 2

        for i, node in enumerate(self.nodes):
            text, shape, fill, txt_color = node
            top_y = y - nh
            mid_y = y - nh/2

            if shape == 'terminal':
                radius = nh/2
                c_obj.setFillColor(fill)
                c_obj.setStrokeColor(DARK_BLUE)
                c_obj.setLineWidth(1.2)
                c_obj.roundRect(cx - nw*0.35, top_y, nw*0.7, nh, radius, fill=1, stroke=1)
            elif shape == 'diamond':
                pts = [cx, y, cx+nw*0.42, mid_y, cx, top_y, cx-nw*0.42, mid_y]
                c_obj.setFillColor(fill)
                c_obj.setStrokeColor(DARK_BLUE)
                c_obj.setLineWidth(1.2)
                p = c_obj.beginPath()
                p.moveTo(pts[0], pts[1])
                p.lineTo(pts[2], pts[3])
                p.lineTo(pts[4], pts[5])
                p.lineTo(pts[6], pts[7])
                p.close()
                c_obj.drawPath(p, fill=1, stroke=1)
            elif shape == 'rounded':
                c_obj.setFillColor(fill)
                c_obj.setStrokeColor(DARK_BLUE)
                c_obj.setLineWidth(1.2)
                c_obj.roundRect(cx - nw*0.46, top_y, nw*0.92, nh, 8, fill=1, stroke=1)
            elif shape == 'oval':
                c_obj.setFillColor(fill)
                c_obj.setStrokeColor(DARK_BLUE)
                c_obj.setLineWidth(1.2)
                c_obj.ellipse(cx - nw*0.4, top_y, cx + nw*0.4, y, fill=1, stroke=1)
            else:  # rect
                c_obj.setFillColor(fill)
                c_obj.setStrokeColor(DARK_BLUE)
                c_obj.setLineWidth(1.2)
                c_obj.rect(cx - nw*0.46, top_y, nw*0.92, nh, fill=1, stroke=1)

            # Text
            c_obj.setFillColor(txt_color)
            c_obj.setFont('Helvetica-Bold' if txt_color == WHITE else 'Helvetica', 8.5)
            lines = text.split('\n')
            line_h = 11
            total_h = len(lines)*line_h
            ty = mid_y + total_h/2 - line_h*0.7
            for ln in lines:
                c_obj.drawCentredString(cx, ty, ln)
                ty -= line_h

            # Arrow to next
            if i < len(self.nodes)-1:
                arrow_y_top = top_y
                arrow_y_bot = top_y - self.gap
                c_obj.setStrokeColor(self.arrow_color)
                c_obj.setLineWidth(1.5)
                c_obj.line(cx, arrow_y_top, cx, arrow_y_bot+6)
                # arrowhead
                c_obj.setFillColor(self.arrow_color)
                p = c_obj.beginPath()
                p.moveTo(cx, arrow_y_bot)
                p.lineTo(cx-5, arrow_y_bot+8)
                p.lineTo(cx+5, arrow_y_bot+8)
                p.close()
                c_obj.drawPath(p, fill=1, stroke=0)

                if self.label_list and i < len(self.label_list):
                    c_obj.setFillColor(ORANGE)
                    c_obj.setFont('Helvetica-Bold', 7.5)
                    c_obj.drawCentredString(cx+20, arrow_y_bot+4, self.label_list[i])

            y = top_y - self.gap


# ─────────────────────── TABLE BUILDER ──────────────────────────
def make_table(headers, rows, col_widths=None, hdr_color=MED_BLUE,
               alt_row=True, stripe_color=None, font_size=9):
    sc = stripe_color or LIGHT_BLUE
    data = [[Paragraph(h, TBL_HDR) for h in headers]]
    for r in rows:
        data.append([Paragraph(str(c), TBL_CELL) for c in r])

    if col_widths is None:
        avail = PAGE_W - 2*MARGIN - 0.3*cm
        col_widths = [avail/len(headers)]*len(headers)

    t = Table(data, colWidths=col_widths, repeatRows=1)
    style_cmds = [
        ('BACKGROUND', (0,0), (-1,0), hdr_color),
        ('TEXTCOLOR',  (0,0), (-1,0), WHITE),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('FONTSIZE',   (0,0), (-1,0), font_size),
        ('FONTNAME',   (0,1), (-1,-1), 'Helvetica'),
        ('FONTSIZE',   (0,1), (-1,-1), font_size-0.5),
        ('ROWBACKGROUND', (0,0), (-1,0), hdr_color),
        ('GRID',       (0,0), (-1,-1), 0.4, GREY_MED),
        ('VALIGN',     (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 5),
        ('BOTTOMPADDING',(0,0),(-1,-1),5),
        ('LEFTPADDING',(0,0), (-1,-1), 6),
        ('RIGHTPADDING',(0,0),(-1,-1), 6),
    ]
    if alt_row:
        for row_idx in range(1, len(data)):
            if row_idx % 2 == 0:
                style_cmds.append(('BACKGROUND', (0,row_idx),(-1,row_idx), sc))
    t.setStyle(TableStyle(style_cmds))
    return t

# ─────────────── Q-BLOCK WRAPPER ─────────────────────────────
def q_block(elements, q_number, q_text, hdr_color=MED_BLUE):
    """Add question header bar."""
    header_data = [[Paragraph(f"Q.{q_number}  {q_text}", Q_STYLE)]]
    t = Table(header_data, colWidths=[PAGE_W - 2*MARGIN])
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1), hdr_color),
        ('TOPPADDING',(0,0),(-1,-1),8),
        ('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),
        ('RIGHTPADDING',(0,0),(-1,-1),10),
        ('ROUNDEDCORNERS', [6]),
    ]))
    elements.append(KeepTogether([t]))

def section_box(elements, title, content_paragraphs, bg=LIGHT_BLUE, border=MED_BLUE):
    """Colored info box."""
    rows = [[Paragraph(title, BOX_TITLE)]]
    for p in content_paragraphs:
        rows.append([p])
    t = Table(rows, colWidths=[PAGE_W - 2*MARGIN - 0.4*cm])
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1), bg),
        ('BOX',(0,0),(-1,-1),1.5, border),
        ('TOPPADDING',(0,0),(-1,-1),6),
        ('BOTTOMPADDING',(0,0),(-1,-1),6),
        ('LEFTPADDING',(0,0),(-1,-1),10),
        ('RIGHTPADDING',(0,0),(-1,-1),10),
    ]))
    elements.append(t)
    elements.append(Spacer(1, 8))

# ─────────────── PAGE TEMPLATE ─────────────────────────────────
def on_page(canv, doc):
    canv.saveState()
    # Header bar
    canv.setFillColor(DARK_BLUE)
    canv.rect(0, PAGE_H-1.1*cm, PAGE_W, 1.1*cm, fill=1, stroke=0)
    canv.setFillColor(WHITE)
    canv.setFont('Helvetica-Bold', 9)
    canv.drawString(MARGIN, PAGE_H-0.72*cm, "FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica', 8)
    canv.drawRightString(PAGE_W-MARGIN, PAGE_H-0.72*cm, "Chapter 1: Medical Jurisprudence & Legal Concepts")
    # Footer
    canv.setFillColor(DARK_BLUE)
    canv.rect(0, 0, PAGE_W, 0.9*cm, fill=1, stroke=0)
    canv.setFillColor(WHITE)
    canv.setFont('Helvetica', 8)
    canv.drawString(MARGIN, 0.32*cm, "Ref: KS Narayan Reddy 36th Ed | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-MARGIN, 0.32*cm, f"Page {doc.page}")
    canv.restoreState()

# ═══════════════════════════════════════════════════════════════
#                       BUILD DOCUMENT
# ═══════════════════════════════════════════════════════════════
def build_chapter1():
    doc = SimpleDocTemplate(
        OUTPUT_PATH,
        pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=1.5*cm, bottomMargin=1.3*cm,
        title="Chapter 1 – Medical Jurisprudence & Legal Concepts",
        author="Forensic Medicine Question Bank"
    )
    E = []  # elements list

    # ══════════ COVER PAGE ══════════
    E.append(Spacer(1, 1.5*cm))
    cover_data = [[Paragraph("FORENSIC MEDICINE &<br/>TOXICOLOGY", TITLE_STYLE)]]
    cover_tbl = Table(cover_data, colWidths=[PAGE_W-2*MARGIN])
    cover_tbl.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1), DARK_BLUE),
        ('TOPPADDING',(0,0),(-1,-1),22),
        ('BOTTOMPADDING',(0,0),(-1,-1),22),
        ('ROUNDEDCORNERS',[10]),
    ]))
    E.append(cover_tbl)
    E.append(Spacer(1, 0.5*cm))

    sub_data = [[Paragraph("CHAPTER 1", make_style('c1s', fontSize=17, textColor=DARK_BLUE,
        fontName='Helvetica-Bold', alignment=TA_CENTER))]]
    sub_tbl = Table(sub_data, colWidths=[PAGE_W-2*MARGIN])
    sub_tbl.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1), LIGHT_BLUE),
        ('BOX',(0,0),(-1,-1),2,MED_BLUE),
        ('TOPPADDING',(0,0),(-1,-1),12),
        ('BOTTOMPADDING',(0,0),(-1,-1),12),
    ]))
    E.append(sub_tbl)
    E.append(Spacer(1,0.3*cm))

    title_data = [[Paragraph("Medical Jurisprudence<br/>&amp; Legal Concepts",
        make_style('t2', fontSize=22, textColor=DARK_BLUE, fontName='Helvetica-Bold',
        alignment=TA_CENTER, leading=30))]]
    t2 = Table(title_data, colWidths=[PAGE_W-2*MARGIN])
    t2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(t2)
    E.append(Spacer(1,0.5*cm))

    ref_data = [[Paragraph(
        "References: KS Narayan Reddy – The Essentials of Forensic Medicine &amp; Toxicology (36th Ed, 2026) &nbsp;|&nbsp; "
        "Parikh's Textbook of Medical Jurisprudence &nbsp;|&nbsp; PC Dikshit &nbsp;|&nbsp; DiMaio's Forensic Pathology",
        REF_STYLE)]]
    r_tbl = Table(ref_data, colWidths=[PAGE_W-2*MARGIN])
    r_tbl.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1), YELLOW_BG),
        ('BOX',(0,0),(-1,-1),1,ORANGE),
        ('TOPPADDING',(0,0),(-1,-1),8),
        ('BOTTOMPADDING',(0,0),(-1,-1),8),
    ]))
    E.append(r_tbl)
    E.append(Spacer(1,0.4*cm))

    # TOC
    toc_data = [
        [Paragraph("Q. No.", TBL_HDR), Paragraph("Topic", TBL_HDR)],
        [Paragraph("1, 86, 139", TBL_CELL_C), Paragraph("Summons / Subpoena & Implications of Ignoring", TBL_CELL)],
        [Paragraph("117", TBL_CELL_C), Paragraph("Conduct Money", TBL_CELL)],
        [Paragraph("42", TBL_CELL_C), Paragraph("Chief and Cross-Examination", TBL_CELL)],
        [Paragraph("43", TBL_CELL_C), Paragraph("Documentary Evidence", TBL_CELL)],
        [Paragraph("28, 106", TBL_CELL_C), Paragraph("Privileged Communication", TBL_CELL)],
        [Paragraph("75, 100", TBL_CELL_C), Paragraph("Doctrine of Res Ipsa Loquitur", TBL_CELL)],
        [Paragraph("22", TBL_CELL_C), Paragraph("Borrowed Servant Doctrine", TBL_CELL)],
        [Paragraph("107", TBL_CELL_C), Paragraph("Vicarious Liability", TBL_CELL)],
        [Paragraph("59", TBL_CELL_C), Paragraph("Infamous Conduct", TBL_CELL)],
        [Paragraph("64", TBL_CELL_C), Paragraph("Valid Consent", TBL_CELL)],
        [Paragraph("65", TBL_CELL_C), Paragraph("In Loco Parentis", TBL_CELL)],
        [Paragraph("8, 19", TBL_CELL_C), Paragraph("Informed Consent & Informed Refusal", TBL_CELL)],
        [Paragraph("37", TBL_CELL_C), Paragraph("IPC Section 84 (Legal Insanity)", TBL_CELL)],
        [Paragraph("76", TBL_CELL_C), Paragraph("IPC Section 320 (Grievous Hurt)", TBL_CELL)],
        [Paragraph("102, 150", TBL_CELL_C), Paragraph("Grievous Hurt (Detailed)", TBL_CELL)],
        [Paragraph("127", TBL_CELL_C), Paragraph("IPC Section 375 (Rape)", TBL_CELL)],
        [Paragraph("47, 101", TBL_CELL_C), Paragraph("Testamentary Capacity", TBL_CELL)],
        [Paragraph("136", TBL_CELL_C), Paragraph("Medico-legal Importance of Age", TBL_CELL)],
        [Paragraph("110", TBL_CELL_C), Paragraph("Right-Wrong Test (McNaghten)", TBL_CELL)],
        [Paragraph("25", TBL_CELL_C), Paragraph("Surrogacy & Medico-legal Significance", TBL_CELL)],
    ]
    toc_tbl = Table(toc_data, colWidths=[2.5*cm, PAGE_W-2*MARGIN-2.5*cm])
    toc_tbl.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,0), DARK_BLUE),
        ('TEXTCOLOR',(0,0),(-1,0), WHITE),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),
        ('GRID',(0,0),(-1,-1),0.4, GREY_MED),
        ('VALIGN',(0,0),(-1,-1),'MIDDLE'),
        ('TOPPADDING',(0,0),(-1,-1),5),
        ('BOTTOMPADDING',(0,0),(-1,-1),5),
        ('LEFTPADDING',(0,0),(-1,-1),7),
        ('BACKGROUND',(0,2),(-1,2),LIGHT_BLUE),
        ('BACKGROUND',(0,4),(-1,4),LIGHT_BLUE),
        ('BACKGROUND',(0,6),(-1,6),LIGHT_BLUE),
        ('BACKGROUND',(0,8),(-1,8),LIGHT_BLUE),
        ('BACKGROUND',(0,10),(-1,10),LIGHT_BLUE),
        ('BACKGROUND',(0,12),(-1,12),LIGHT_BLUE),
        ('BACKGROUND',(0,14),(-1,14),LIGHT_BLUE),
        ('BACKGROUND',(0,16),(-1,16),LIGHT_BLUE),
        ('BACKGROUND',(0,18),(-1,18),LIGHT_BLUE),
        ('BACKGROUND',(0,20),(-1,20),LIGHT_BLUE),
    ]))
    E.append(Paragraph("CHAPTER CONTENTS", make_style('toc_h', fontSize=12, textColor=DARK_BLUE,
        fontName='Helvetica-Bold', spaceAfter=6)))
    E.append(toc_tbl)
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q1 / Q86 / Q139 – SUMMONS / SUBPOENA
    # ═══════════════════════════════════════════════════════════════
    q_block(E, "1 / 86 / 139", "What is a Summons / Subpoena? What are the implications of ignoring it?", DARK_BLUE)
    E.append(Spacer(1,6))

    E.append(Paragraph("<b>Definition (KS Narayan Reddy, 36th Ed):</b>", BOLD_BODY))
    E.append(Paragraph(
        "A <b>subpoena</b> (Latin: <i>sub</i> = under, <i>poena</i> = penalty) is a legal document compelling a witness "
        "to attend a court of law on a specified date, time and place, under penalty. It may also require production "
        "of documents (<i>subpoena duces tectum</i>). It is governed by Sections 63–71, BNSS (formerly Sections 61–69, CrPC). "
        "It is issued in writing, in duplicate, signed by the presiding officer, and bears the court seal.", BODY_STYLE))
    E.append(Spacer(1,4))

    # Table: Summons details
    E.append(Paragraph("<b>Key Features at a Glance:</b>", BOLD_BODY))
    summons_tbl = make_table(
        ["Feature", "Details"],
        [
            ["Also called", "Subpoena"],
            ["Issued by", "Court (presiding officer), in writing, in duplicate"],
            ["Served by", "Police officer / officer of court / public servant / registered post"],
            ["Receipt", "Person signs back of one copy; other copy returned to court"],
            ["Contains", "Crime number, name of accused, date/time/place"],
            ["Govt servant", "Sent to head of office; head serves it & returns to court (S.68 BNSS)"],
            ["Priority", "Criminal > Civil court; Higher > Lower court"],
            ["Subpoena duces tectum", "Requires witness to bring books/documents (S.94 & 195 BNSS)"],
        ],
        col_widths=[5.5*cm, PAGE_W-2*MARGIN-5.5*cm],
        hdr_color=DARK_BLUE
    )
    E.append(summons_tbl)
    E.append(Spacer(1,8))

    # Flowchart: Implications of ignoring
    E.append(Paragraph("<b>FLOWCHART: Implications of Ignoring a Court Summons</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    nodes_summons = [
        ("DOCTOR / WITNESS\nReceives Summons", "terminal", MED_BLUE, WHITE),
        ("FAILS TO ATTEND\nCourt on Scheduled Date", "rect", LIGHT_RED, RED),
        ("TYPE OF CASE?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("CIVIL CASE\nLiable to pay DAMAGES\nto the party concerned", "rounded", LIGHT_GREEN, GREEN),
        ("CRIMINAL CASE\nCourt issues NOTICE\n(S.389 BNSS)", "rounded", LIGHT_RED, RED),
        ("Court hears the witness\nand examines reasons", "rect", LIGHT_BLUE, DARK_BLUE),
        ("No valid justification\nfound?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("FINE or IMPRISONMENT\nor BOTH\n(S.208, BNS)", "rounded", RED, WHITE),
        ("Bailable / Non-bailable\nWARRANT issued\n(S.90, BNSS)", "rounded", RED, WHITE),
        ("Contempt of Court\n(Willful disobedience)", "terminal", DARK_BLUE, WHITE),
    ]
    # Due to the branching nature, we'll use a 2-column linear approach in table
    E.append(Spacer(1,6))
    branch_data = [
        [Paragraph("<b>CIVIL CASE</b>", make_style('bc', fontSize=10, textColor=GREEN,
            fontName='Helvetica-Bold', alignment=TA_CENTER)),
         Paragraph("<b>CRIMINAL CASE</b>", make_style('bc2', fontSize=10, textColor=RED,
            fontName='Helvetica-Bold', alignment=TA_CENTER))],
        [Paragraph("Liable to pay <b>Damages</b> to the party", TBL_CELL),
         Paragraph("Court issues <b>Notice</b> (S.389 BNSS)", TBL_CELL)],
        [Paragraph("No further imprisonment in purely civil default", TBL_CELL),
         Paragraph("Court hears the witness; if no valid reason:", TBL_CELL)],
        [Paragraph("Can claim <b>Conduct Money</b> if not paid", TBL_CELL),
         Paragraph("<b>Fine</b> or <b>Imprisonment</b> or Both (S.208 BNS)", TBL_CELL)],
        [Paragraph("β€”", TBL_CELL),
         Paragraph("<b>Bailable / Non-bailable warrant</b> to secure presence (S.90 BNSS)", TBL_CELL)],
        [Paragraph("β€”", TBL_CELL),
         Paragraph("Charge of <b>Contempt of Court</b>", TBL_CELL)],
    ]
    avail = PAGE_W - 2*MARGIN
    half = avail/2
    branch_tbl = Table(branch_data, colWidths=[half, half])
    branch_tbl.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(0,0), LIGHT_GREEN),
        ('BACKGROUND',(1,0),(1,0), LIGHT_RED),
        ('BOX',(0,0),(0,-1),1.5, GREEN),
        ('BOX',(1,0),(1,-1),1.5, RED),
        ('INNERGRID',(0,0),(-1,-1),0.4, GREY_MED),
        ('VALIGN',(0,0),(-1,-1),'TOP'),
        ('TOPPADDING',(0,0),(-1,-1),5),
        ('BOTTOMPADDING',(0,0),(-1,-1),5),
        ('LEFTPADDING',(0,0),(-1,-1),7),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),
        ('FONTSIZE',(0,0),(-1,-1),9),
        ('ALIGN',(0,0),(-1,0),'CENTER'),
    ]))
    E.append(branch_tbl)
    E.append(Spacer(1,6))

    # Simple linear flowchart for doctor's steps
    fc1 = FlowchartDrawing([
        ("SUMMONS RECEIVED\nby Doctor/Witness", "terminal", DARK_BLUE, WHITE),
        ("Read carefully:\nDate, Time, Court, Crime No.", "rounded", LIGHT_BLUE, DARK_BLUE),
        ("Valid Urgent Reason\nto NOT attend?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Inform Court\nBEFORE the date", "rounded", LIGHT_GREEN, GREEN),
        ("ATTEND COURT\non Specified Date & Time", "terminal", GREEN, WHITE),
        ("Bring documents if\n'subpoena duces tectum'", "rounded", LIGHT_TEAL, TEAL),
        ("Give evidence under OATH\nin Witness Box", "terminal", DARK_BLUE, WHITE),
    ], node_h=36, gap=16,
    label_list=["", "YES", "", "NO", "", ""])
    E.append(Paragraph("<b>FLOWCHART: Correct Conduct When Summoned</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc1)
    E.append(Spacer(1,4))
    E.append(Paragraph(
        "<i>Note (Narayan Reddy): A summons must be obeyed. A witness may be excused only if he has a valid and urgent reason. "
        "If summoned by two courts same day – Criminal court has priority over Civil court; Higher court over lower.</i>", NOTE_STYLE))
    E.append(Spacer(1,10))

    # ═══ Q117 CONDUCT MONEY ═══
    q_block(E, "117", "What is Conduct Money?", TEAL)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Conduct money</b> is the fee offered or paid to a witness in <b>civil cases</b> at the time of serving "
        "the summons, to meet expenses for attending court. (KS Narayan Reddy)", BODY_STYLE))
    E.append(Spacer(1,4))
    cm_tbl = make_table(
        ["Aspect", "Civil Case", "Criminal Case"],
        [
            ["Conduct Money", "Paid at time of summons serving", "NOT paid at time of summons"],
            ["Reason (criminal)", "β€”", "Witness attends in interest of State"],
            ["If amount insufficient", "Doctor can inform Judge before giving evidence; Judge decides amount", "β€”"],
            ["Allowances (criminal)", "β€”", "Conveyance charges + Daily Allowance as per Govt rules"],
            ["Default", "Witness can object before testifying", "Contempt of court if doesn't attend"],
        ],
        col_widths=[4*cm, (PAGE_W-2*MARGIN-4*cm)/2, (PAGE_W-2*MARGIN-4*cm)/2],
        hdr_color=TEAL
    )
    E.append(cm_tbl)
    E.append(Spacer(1,6))
    fc_cm = FlowchartDrawing([
        ("SUMMONS SERVED\nin CIVIL Case", "terminal", TEAL, WHITE),
        ("Conduct Money\noffered along with summons?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Accept & Attend Court", "rounded", LIGHT_GREEN, GREEN),
        ("Amount seems\nINSUFFICIENT?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Attend Court\nInform Judge BEFORE\ngiving evidence", "rounded", LIGHT_BLUE, DARK_BLUE),
        ("Judge decides\nappropriate amount", "terminal", DARK_BLUE, WHITE),
    ], node_h=34, gap=15)
    E.append(Paragraph("<b>FLOWCHART: Conduct Money Decision</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_cm)
    E.append(Spacer(1,10))

    # ═══ Q42 CHIEF AND CROSS EXAMINATION ═══
    q_block(E, "42", "What is Chief and Cross-Examination in a Court of Law?", MED_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "Examination of a witness in court proceeds in a defined sequence governed by the Bharatiya Sakshya Adhiniyam (BSA) "
        "[formerly Indian Evidence Act].", BODY_STYLE))
    E.append(Spacer(1,4))
    exam_tbl = make_table(
        ["Type", "Conducted by", "Purpose", "Key Rules"],
        [
            ["<b>Examination-in-Chief\n(Direct Examination)</b>",
             "Party who calls the witness",
             "To elicit facts supporting own case",
             "Leading questions NOT allowed\n(except with court permission)"],
            ["<b>Cross-Examination</b>",
             "Opposite party (defense lawyer)",
             "To test accuracy, credibility, consistency;\nto introduce contradictions",
             "Leading questions ARE allowed;\nDoctor must answer truthfully;\nCan ask on any relevant matter"],
            ["<b>Re-Examination</b>",
             "Party who originally called witness",
             "To clarify matters raised in cross-examination",
             "Limited to matters arising from cross-examination;\nNew matter only with court leave"],
            ["<b>Court Questions</b>",
             "Judge / Magistrate",
             "To clarify any point for justice",
             "Can ask any question at any time;\nWitness must answer"],
        ],
        col_widths=[3.5*cm, 3.2*cm, 4.5*cm, PAGE_W-2*MARGIN-11.2*cm],
        hdr_color=MED_BLUE
    )
    E.append(exam_tbl)
    E.append(Spacer(1,8))
    fc_exam = FlowchartDrawing([
        ("WITNESS\ncalled to Witness Box", "terminal", DARK_BLUE, WHITE),
        ("OATH / AFFIRMATION\nadministered", "rounded", LIGHT_BLUE, DARK_BLUE),
        ("EXAMINATION-IN-CHIEF\nby calling party\n(No leading Qs)", "rect", LIGHT_GREEN, GREEN),
        ("CROSS-EXAMINATION\nby opposite party\n(Leading Qs allowed)", "rect", LIGHT_RED, RED),
        ("RE-EXAMINATION\nby original party\n(Only on cross-exam matters)", "rect", LIGHT_TEAL, TEAL),
        ("COURT QUESTIONS\nby Judge (anytime)", "rounded", LIGHT_ORANGE, ORANGE),
        ("WITNESS\nDISCHARGED", "terminal", DARK_BLUE, WHITE),
    ], node_h=36, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Sequence of Examination in Court</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_exam)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Doctor's conduct in witness box (Narayan Reddy):</b> Speak clearly; say 'I don't know' if unsure; "
        "don't volunteer beyond what is asked; be impartial; don't lose temper; don't answer hypothetical Qs unless court permits.", NOTE_STYLE))
    E.append(Spacer(1,10))

    # ═══ Q43 DOCUMENTARY EVIDENCE ═══
    q_block(E, "43", "What is Documentary Evidence?", PURPLE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "According to BSA (Bharatiya Sakshya Adhiniyam): <b>Documentary evidence</b> includes all documents produced for "
        "inspection of the court. Dealt under Sections 56–92, BSA.", BODY_STYLE))
    E.append(Spacer(1,4))
    doc_tbl = make_table(
        ["Type", "Definition", "Examples"],
        [
            ["<b>Primary Evidence</b>",
             "The document itself produced for court inspection (S.208 BNS)",
             "Original MLC register, original post-mortem report"],
            ["<b>Secondary Evidence</b>",
             "Certified copies, counterparts, copies compared with original",
             "Certified copy of medical record, photocopy of PM report"],
            ["<b>Public Document</b>",
             "Documents forming acts of sovereign authority, official bodies",
             "Birth/death certificates, court records"],
            ["<b>Private Document</b>",
             "All other documents",
             "Case files, prescriptions, hospital records"],
            ["<b>Medico-legal Reports</b>",
             "Reports prepared by doctor at request of IO/Magistrate;\nconsist of (1) observed facts (2) opinion",
             "Injury certificate, PM report, sexual assault report"],
        ],
        col_widths=[3.5*cm, 6*cm, PAGE_W-2*MARGIN-9.5*cm],
        hdr_color=PURPLE
    )
    E.append(doc_tbl)
    E.append(Spacer(1,8))
    fc_doc = FlowchartDrawing([
        ("DOCUMENTARY EVIDENCE", "terminal", PURPLE, WHITE),
        ("PRIMARY EVIDENCE\n(Original document itself)", "rect", LIGHT_PURPLE, PURPLE),
        ("SECONDARY EVIDENCE\n(Certified copies, counterparts)", "rect", LIGHT_BLUE, MED_BLUE),
        ("ORAL EVIDENCE\n(Witness testimony)", "rect", LIGHT_GREEN, GREEN),
        ("Expert/Medical Opinion\n(Corroborative only)", "rounded", LIGHT_ORANGE, ORANGE),
        ("Admitted as evidence\nONLY when doctor testifies\nunder oath in court", "terminal", DARK_BLUE, WHITE),
    ], node_h=34, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Types of Evidence & Admissibility</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_doc)
    E.append(Spacer(1,8))

    E.append(PageBreak())

    # ═══ Q28 / Q106 PRIVILEGED COMMUNICATION ═══
    q_block(E, "28 / 106", "What is Privileged Communication? Describe it.", TEAL)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Definition:</b> A privileged communication is a statement made <b>bonafide</b> by a doctor to a concerned authority, "
        "due to his duty to protect the interests of the community or the State. It is an exception to the general rule of "
        "<b>professional secrecy</b>. (KS Narayan Reddy, 36th Ed)", BODY_STYLE))
    E.append(Spacer(1,4))

    E.append(Paragraph("<b>Conditions to be 'Privileged' (Narayan Reddy):</b>", BOLD_BODY))
    cond_tbl = make_table(
        ["Condition", "Details"],
        [
            ["1. Bonafide duty", "Made by doctor due to duty to protect community/State interests"],
            ["2. Right recipient", "Made to person having direct interest; if given to more β†’ privilege fails"],
            ["3. Patient consent first", "Doctor must first persuade patient to consent before notifying authority"],
            ["4. Purpose", "To protect community; doctor NOT liable to damages if done bonafide"],
        ],
        hdr_color=TEAL
    )
    E.append(cond_tbl)
    E.append(Spacer(1,6))

    E.append(Paragraph("<b>EXAMPLES of Privileged Communication:</b>", BOLD_BODY))
    ex_tbl = make_table(
        ["Situation", "Action by Doctor"],
        [
            ["Infectious disease (cook/waiter/teacher with TB)", "Persuade to leave job; if refuses β†’ inform employer"],
            ["Engine driver / bus driver with epilepsy, HTN, alcoholism", "Persuade to change job; if refuses β†’ inform employer"],
            ["Notifiable diseases (cholera, plague, etc.)", "Statutory duty to notify Public Health authorities"],
            ["Venereal disease (syphilis) + about to marry", "Advise against marriage; if refuses β†’ disclose to partner/parents"],
            ["AIDS/HIV patient with sexual partner at risk", "Duty to inform partner (Supreme Court ruling)"],
            ["Fitness certificate for driving/work", "Can disclose relevant condition to licensing authority"],
        ],
        hdr_color=TEAL
    )
    E.append(ex_tbl)
    E.append(Spacer(1,8))

    fc_pc = FlowchartDrawing([
        ("DOCTOR KNOWS\nsensitive patient information", "terminal", TEAL, WHITE),
        ("Does it pose risk\nto COMMUNITY / STATE?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("PROFESSIONAL SECRECY\nmaintained (default)", "rounded", LIGHT_GREEN, GREEN),
        ("PERSUADE PATIENT\nto consent / act", "rect", LIGHT_BLUE, DARK_BLUE),
        ("Patient\ncooperates?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("No action needed;\ncontinue treatment", "rounded", LIGHT_GREEN, GREEN),
        ("PRIVILEGED COMMUNICATION\n→ Notify concerned authority\nBonafide, to right person only", "terminal", TEAL, WHITE),
    ], node_h=36, gap=15,
    label_list=["NO", "YES", "", "YESβ†’", "NO↓", ""])
    E.append(Paragraph("<b>FLOWCHART: When to Make Privileged Communication</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_pc)
    E.append(Spacer(1,10))

    # ═══ Q75 / Q100 RES IPSA LOQUITUR ═══
    q_block(E, "75 / 100", "What is the Doctrine of Res Ipsa Loquitur?", RED)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        '<b>Res ipsa loquitur</b> (Latin: "the thing speaks for itself") is a rule of evidence in the law of torts. '
        'Ordinarily, professional negligence must be proved by expert evidence. Under this doctrine, the patient need NOT prove '
        'negligence β€” the facts themselves imply it. (KS Narayan Reddy)', BODY_STYLE))
    E.append(Spacer(1,4))

    E.append(Paragraph("<b>3 Conditions Required (Narayan Reddy):</b>", BOLD_BODY))
    cond2_tbl = make_table(
        ["Condition", "Explanation"],
        [
            ["1. Injury wouldn't occur ordinarily\nwithout negligence", "In the absence of negligence, the injury would not have occurred"],
            ["2. Doctor had exclusive control", "Doctor had exclusive control over the injury-producing instrument or treatment"],
            ["3. No contributory negligence\nby patient", "Patient was NOT guilty of contributory negligence"],
        ],
        hdr_color=RED
    )
    E.append(cond2_tbl)
    E.append(Spacer(1,6))

    E.append(Paragraph("<b>Classic Examples (Narayan Reddy):</b>", BOLD_BODY))
    ex2_tbl = make_table(
        ["No.", "Example"],
        [
            ["1", "Prescribing overdose of medicine β†’ ill-effects"],
            ["2", "Giving poisonous medicine carelessly"],
            ["3", "Failure to give anti-tetanic serum β†’ tetanus"],
            ["4", "Burns from hot water bottle / X-ray therapy"],
            ["5", "Breaking of needles"],
            ["6", "Failure to remove swabs during operation β†’ complications/death\n(Landmark case: Mohn vs Osborne)"],
            ["7", "Blood transfusion misadventure"],
            ["8", "Loss of use of hand due to prolonged splinting"],
        ],
        hdr_color=RED
    )
    E.append(ex2_tbl)
    E.append(Spacer(1,8))

    fc_ril = FlowchartDrawing([
        ("PATIENT claims\nMEDICAL NEGLIGENCE", "terminal", DARK_BLUE, WHITE),
        ("Normal rule: Patient must\nPROVE negligence by\nexpert medical evidence", "rect", LIGHT_BLUE, DARK_BLUE),
        ("RES IPSA LOQUITUR\napplies?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Check 3 conditions:\n1. Injury unlikely w/o negligence\n2. Doctor had exclusive control\n3. No patient contributory fault", "rect", LIGHT_BLUE, DARK_BLUE),
        ("All 3\nconditions met?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Patient need NOT provide\nexpert evidence; facts SPEAK\nfor themselves", "rounded", LIGHT_RED, RED),
        ("NEGLIGENCE PRESUMED\nDoctor must disprove", "terminal", RED, WHITE),
    ], node_h=38, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Application of Res Ipsa Loquitur</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_ril)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Limitation:</b> Does NOT apply when injury may occur even with reasonable care (Doctrine of Calculated Risks). "
        "Cannot be applied against several defendants when one cannot be identified. Rarely used successfully by patients.", NOTE_STYLE))
    E.append(Spacer(1,10))

    E.append(PageBreak())

    # ═══ Q22 BORROWED SERVANT DOCTRINE ═══
    q_block(E, "22", "What is the Borrowed Servant Doctrine?", ORANGE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "The <b>Borrowed Servant Doctrine</b> applies when a healthcare employee (e.g., a nurse or technician) "
        "normally employed by a hospital (the 'general employer') is temporarily placed under the direction and control "
        "of a surgeon/doctor (the 'special employer') during a procedure.", BODY_STYLE))
    E.append(Spacer(1,4))
    bs_tbl = make_table(
        ["Aspect", "Details"],
        [
            ["Definition", "An employee 'borrowed' from general employer becomes servant of special employer for that task"],
            ["Liability", "If borrowed servant commits negligence under special employer's direction β†’ special employer (doctor/surgeon) is liable"],
            ["Key question", "Who had CONTROL over the servant at the time of negligent act?"],
            ["Classic example", "Hospital nurse follows surgeon's specific instruction during surgery; nurse commits error β†’ Surgeon may be liable"],
            ["Related doctrine", "Respondeat Superior: 'Let the master answer' β€” employer liable for employee's negligence"],
            ["Also linked to", "Captain of the Ship Doctrine: Surgeon is captain; all OR staff under his command β†’ he is responsible"],
        ],
        hdr_color=ORANGE
    )
    E.append(bs_tbl)
    E.append(Spacer(1,8))

    fc_bs = FlowchartDrawing([
        ("HOSPITAL EMPLOYEE\n(General Employer = Hospital)", "terminal", MED_BLUE, WHITE),
        ("Temporarily placed\nunder SURGEON'S control\nfor specific procedure", "rect", LIGHT_BLUE, DARK_BLUE),
        ("'BORROWED SERVANT'\nof Surgeon\n(Special Employer)", "rounded", LIGHT_ORANGE, ORANGE),
        ("Employee commits\nNEGLIGENT ACT", "rect", LIGHT_RED, RED),
        ("Was negligent act done\nunder SURGEON'S direction?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("SURGEON LIABLE\n(Borrowed Servant Doctrine /\nCaptain of the Ship)", "terminal", RED, WHITE),
    ], node_h=36, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Borrowed Servant Doctrine</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_bs)
    E.append(Spacer(1,10))

    # ═══ Q107 VICARIOUS LIABILITY ═══
    q_block(E, "107", "What is Vicarious Liability?", MED_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Vicarious liability</b> (Respondeat Superior = 'Let the master answer') means a doctor or hospital is held legally "
        "responsible for the negligent acts of their employees or agents, even if the doctor/hospital was not personally negligent.", BODY_STYLE))
    E.append(Spacer(1,4))
    vl_tbl = make_table(
        ["Principle", "Details"],
        [
            ["Respondeat Superior", "Employer responsible for employee's negligence during course of employment"],
            ["Condition", "Negligence must occur within scope of employment"],
            ["Hospital liability", "Hospital liable for acts of nurses, technicians, residents under its employ"],
            ["Doctor as employer", "If doctor employs a nurse privately β†’ doctor liable for nurse's negligence"],
            ["Corporate liability", "Hospital may be directly liable for negligent selection/supervision of staff"],
            ["Exception", "Independent contractor: Doctor not liable for another doctor acting independently"],
        ],
        hdr_color=MED_BLUE
    )
    E.append(vl_tbl)
    E.append(Spacer(1,8))

    fc_vl = FlowchartDrawing([
        ("NEGLIGENT ACT\nby Employee/Agent", "terminal", RED, WHITE),
        ("Was act within\nSCOPE OF EMPLOYMENT?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Employee alone\nresponsible", "rounded", LIGHT_GREEN, GREEN),
        ("Was employer in\nCONTROL of employee?", "diamond", LIGHT_BLUE, DARK_BLUE),
        ("EMPLOYER\n(Doctor / Hospital)\nVICAROUSLY LIABLE", "terminal", RED, WHITE),
    ], node_h=34, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Vicarious Liability</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_vl)
    E.append(Spacer(1,10))

    # ═══ Q59 INFAMOUS CONDUCT ═══
    q_block(E, "59", "What is Infamous Conduct?", DARK_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Infamous conduct</b> (Professional Misconduct) refers to conduct by a registered medical practitioner that is "
        "regarded as disgraceful or dishonorable by his professional brethren of good repute and competency. It is defined by the "
        "Medical Council of India (MCI) / National Medical Commission (NMC) regulations.", BODY_STYLE))
    E.append(Spacer(1,4))
    ic_tbl = make_table(
        ["Category", "Examples"],
        [
            ["Advertising", "Self-advertisement in any form; signboards beyond permitted size"],
            ["Secret remedies", "Using secret/unproven remedies"],
            ["Covering/Dichotomy", "Covering for an unregistered practitioner; fee-splitting"],
            ["Issuing false certificates", "Knowingly giving false death/birth/illness certificates"],
            ["Criminal act", "Conviction for criminal offence involving moral turpitude"],
            ["Sexual misconduct", "Sexual relationship with patient under care"],
            ["Alcohol/drug abuse", "Practicing under influence of alcohol/drugs"],
            ["Euthanasia", "Assisting in euthanasia (unless lawfully permitted)"],
            ["Unnecessary surgery", "Performing operations not in patient's best interest for financial gain"],
        ],
        hdr_color=DARK_BLUE
    )
    E.append(ic_tbl)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Consequence:</b> The Medical Council can erase the name of the doctor from the Medical Register β€” "
        "effectively removing the right to practice.", NOTE_STYLE))
    E.append(Spacer(1,6))
    fc_ic = FlowchartDrawing([
        ("COMPLAINT of\nProfessional Misconduct", "terminal", DARK_BLUE, WHITE),
        ("Referred to State\nMedical Council", "rect", LIGHT_BLUE, DARK_BLUE),
        ("Inquiry Committee\nconducts investigation", "rounded", LIGHT_TEAL, TEAL),
        ("Misconduct\nProved?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("PENALTIES:\nWarning / Suspension /\nErasure from Register", "rect", RED, WHITE),
        ("Right to Appeal\nto NMC / High Court", "terminal", MED_BLUE, WHITE),
    ], node_h=34, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Infamous Conduct Proceedings</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_ic)
    E.append(Spacer(1,10))

    E.append(PageBreak())

    # ═══ Q64 VALID CONSENT ═══
    q_block(E, "64", "What Constitutes Valid Consent?", GREEN)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Consent</b> is the voluntary agreement of a person to receive a medical procedure or examination. "
        "For consent to be valid (legally and ethically), it must meet specific criteria.", BODY_STYLE))
    E.append(Spacer(1,4))
    consent_tbl = make_table(
        ["Requirement", "Details"],
        [
            ["1. <b>Voluntary</b>", "Free from force, undue influence, fraud, misrepresentation"],
            ["2. <b>Informed</b>", "Patient understands the nature, purpose, risks, benefits, alternatives"],
            ["3. <b>Competent person</b>", "Person of sound mind; adult (>18 yrs in India); capable of understanding"],
            ["4. <b>Legal age</b>", "Age of consent: 18 yrs (general); 12 yrs (minor may consent for simple examination per IPC)"],
            ["5. <b>Specific</b>", "Given for specific procedure; consent for one procedure β‰  consent for another"],
            ["6. <b>Form</b>", "Can be oral (implied, express) or written; written preferred for invasive procedures"],
            ["7. <b>Revocable</b>", "Patient can withdraw consent at any time before the act"],
        ],
        hdr_color=GREEN
    )
    E.append(consent_tbl)
    E.append(Spacer(1,6))
    consent_types = make_table(
        ["Type of Consent", "Definition", "Example"],
        [
            ["<b>Implied</b>", "Inferred from patient's actions", "Patient extends arm for blood draw"],
            ["<b>Express (Verbal)</b>", "Oral agreement", "Patient verbally agrees to examination"],
            ["<b>Written</b>", "Signed consent form", "Pre-operative consent for surgery"],
            ["<b>Presumed</b>", "Emergency where consent cannot be obtained", "Unconscious trauma patient β†’ treat to save life"],
            ["<b>Proxy</b>", "Given by parent/guardian for minor/incompetent", "Parent consents for child's surgery"],
        ],
        hdr_color=GREEN
    )
    E.append(consent_types)
    E.append(Spacer(1,8))
    fc_consent = FlowchartDrawing([
        ("PATIENT requires\nmedical procedure", "terminal", DARK_BLUE, WHITE),
        ("Is patient\nCOMPETENT?\n(Adult, sound mind)", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("PROXY CONSENT\n(Guardian / Parent / Magistrate)", "rounded", LIGHT_PURPLE, PURPLE),
        ("INFORM patient:\nNature, Purpose, Risks,\nBenefits, Alternatives", "rect", LIGHT_BLUE, DARK_BLUE),
        ("Patient\nUNDERSTANDS?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Re-explain;\nuse interpreter if needed", "rounded", LIGHT_ORANGE, ORANGE),
        ("Patient\nCONSENTS\nVoluntarily?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("RESPECT REFUSAL\n(Document it)", "rounded", LIGHT_RED, RED),
        ("OBTAIN WRITTEN CONSENT\nProceed with procedure", "terminal", GREEN, WHITE),
    ], node_h=36, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Process of Obtaining Valid Consent</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_consent)
    E.append(Spacer(1,10))

    # ═══ Q65 IN LOCO PARENTIS ═══
    q_block(E, "65", "What are the Benefits of In Loco Parentis?", PURPLE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        '<b>In loco parentis</b> (Latin: "in the place of a parent") refers to a person or institution that takes on '
        'parental roles and responsibilities in the absence of or in addition to natural parents.', BODY_STYLE))
    E.append(Spacer(1,4))
    ilp_tbl = make_table(
        ["Aspect", "Details"],
        [
            ["Who can act", "School, boarding institution, guardian, hospital, state (for abandoned children)"],
            ["Medical context", "Treating doctor/hospital may act in loco parentis for minor if parents unreachable in emergency"],
            ["Consent", "Person in loco parentis can give proxy consent for medical treatment of minor"],
            ["Legal basis", "Recognized under common law and Indian family law"],
            ["Benefit 1", "Ensures child receives necessary medical treatment without delay"],
            ["Benefit 2", "Protects doctor legally when treating minor in emergency (presumed consent)"],
            ["Benefit 3", "Applicable in child welfare institutions, orphanages, boarding schools"],
            ["Benefit 4", "State as parens patriae (parent of the nation) can act for severely mentally ill adults too"],
            ["Limitation", "Does NOT override known wishes of parents; only for emergencies/absence"],
        ],
        hdr_color=PURPLE
    )
    E.append(ilp_tbl)
    E.append(Spacer(1,10))

    # ═══ Q8 / Q19 INFORMED CONSENT & REFUSAL ═══
    q_block(E, "8 / 19", "Components of Informed Consent for Surgery & Informed Refusal", MED_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Informed consent</b> is the process by which a patient, after being given all relevant information, "
        "voluntarily authorizes a medical intervention. It is both a legal and ethical obligation.", BODY_STYLE))
    E.append(Spacer(1,4))
    ic2_tbl = make_table(
        ["Component", "Details"],
        [
            ["1. Diagnosis", "Patient informed of diagnosis / suspected diagnosis"],
            ["2. Nature of procedure", "What the surgery involves; what will be done"],
            ["3. Purpose / Benefits", "Why it is being recommended; expected benefits"],
            ["4. Material risks", "All significant risks that a reasonable patient would want to know"],
            ["5. Alternatives", "Available alternative treatments including non-surgical options"],
            ["6. Consequences of refusal", "What happens if patient does not consent / have surgery"],
            ["7. Questions answered", "Patient given opportunity to ask questions; all answered"],
            ["8. Voluntary decision", "No coercion; decision freely made"],
            ["9. Documentation", "Written consent form signed by patient + witness"],
            ["10. Competence", "Patient must have decision-making capacity at time of consent"],
        ],
        hdr_color=MED_BLUE
    )
    E.append(ic2_tbl)
    E.append(Spacer(1,6))
    E.append(Paragraph("<b>INFORMED REFUSAL (Q.19):</b>", BOLD_BODY))
    E.append(Paragraph(
        "A competent adult patient has the right to refuse any medical treatment, even life-saving treatment. "
        "When a patient refuses:", BODY_STYLE))
    ref_tbl = make_table(
        ["Step", "Action"],
        [
            ["1", "Ensure patient is COMPETENT (adult, sound mind)"],
            ["2", "Ensure refusal is INFORMED β€” patient understands consequences"],
            ["3", "Explain consequences of refusal clearly (risk of death/disability)"],
            ["4", "Explore reasons for refusal; address fears/misconceptions"],
            ["5", "Document the refusal in writing; ask patient to sign 'Refusal Form'"],
            ["6", "Have a witness present"],
            ["7", "Respect the refusal β€” forced treatment = assault"],
            ["8", "Continue to offer care within patient's wishes"],
        ],
        hdr_color=MED_BLUE
    )
    E.append(ref_tbl)
    E.append(Spacer(1,8))

    fc_ic2 = FlowchartDrawing([
        ("SURGEON plans procedure\nfor PATIENT", "terminal", DARK_BLUE, WHITE),
        ("DISCLOSE:\nDiagnosis, Procedure, Risks,\nBenefits, Alternatives", "rect", LIGHT_BLUE, DARK_BLUE),
        ("Patient\nUnderstands & CONSENTS?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("INFORMED REFUSAL:\nRe-explain consequences;\nDocument refusal + signature", "rounded", LIGHT_RED, RED),
        ("WRITTEN CONSENT\nobtained", "rounded", LIGHT_GREEN, GREEN),
        ("PROCEED\nwith Surgery", "terminal", GREEN, WHITE),
    ], node_h=36, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Informed Consent Process for Surgery</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_ic2)
    E.append(Spacer(1,10))

    E.append(PageBreak())

    # ═══ Q37 IPC SECTION 84 ═══
    q_block(E, "37", "What is IPC Section 84? (Unsoundness of Mind / Legal Insanity)", DARK_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>IPC Section 84 (Now BNS Section 22):</b> 'Nothing is an offence which is done by a person who, at the time of "
        "doing it, by reason of unsoundness of mind, is incapable of knowing the nature of the act, or that he is doing what "
        "is either wrong or contrary to law.'", BODY_STYLE))
    E.append(Spacer(1,4))
    s84_tbl = make_table(
        ["Element", "Details"],
        [
            ["Based on", "McNaghten Rules (1843, England) β€” adopted in India"],
            ["Unsoundness of mind", "Not every mental illness β†’ must be total incapacity at time of act"],
            ["Three tests", "(1) Did not know nature of act\n(2) Did not know act was wrong\n(3) Did not know act was contrary to law"],
            ["Time", "Unsoundness must exist AT THE TIME of committing the act"],
            ["Burden of proof", "Lies on the accused (on balance of probabilities)"],
            ["Medical role", "Forensic psychiatrist evaluates mental state; opinion is advisory β€” court decides"],
            ["Outcome if proved", "Acquittal; but may be detained in mental institution (S.101, BNSS)"],
        ],
        hdr_color=DARK_BLUE
    )
    E.append(s84_tbl)
    E.append(Spacer(1,8))
    fc_s84 = FlowchartDrawing([
        ("ACCUSED commits\ncriminal ACT", "terminal", DARK_BLUE, WHITE),
        ("Defense pleads\nIPC S.84 / BNS S.22", "rect", LIGHT_BLUE, DARK_BLUE),
        ("Was accused of\nUNSOUND MIND at time of act?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Did NOT know:\n(a) Nature of act, OR\n(b) Act was wrong/contrary to law", "rect", LIGHT_PURPLE, PURPLE),
        ("McNaghten Test\nsatisfied?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("ACQUITTAL\n+ Detention in\nmental institution", "terminal", GREEN, WHITE),
    ], node_h=36, gap=14)
    E.append(Paragraph("<b>FLOWCHART: IPC Section 84 (Legal Insanity) Decision</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_s84)
    E.append(Spacer(1,10))

    # ═══ Q76 / Q102 / Q150 IPC S320 / GRIEVOUS HURT ═══
    q_block(E, "76 / 102 / 150", "IPC Section 320 – What Constitutes Grievous Hurt?", RED)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>IPC Section 320 (now BNS Section 116):</b> Lists 8 kinds of hurt that are designated as 'Grievous'. "
        "Any injury NOT in this list is 'Simple Hurt' (IPC S.319).", BODY_STYLE))
    E.append(Spacer(1,4))
    gh_tbl = make_table(
        ["No.", "Kind of Grievous Hurt"],
        [
            ["1st", "Emasculation (loss of male genitalia / testicular function)"],
            ["2nd", "Permanent privation of sight of either eye"],
            ["3rd", "Permanent privation of hearing of either ear"],
            ["4th", "Privation of any member or joint (permanent loss of a limb/joint)"],
            ["5th", "Destruction or permanent impairing of powers of any member or joint"],
            ["6th", "Permanent disfiguration of the head or face"],
            ["7th", "Fracture or dislocation of a bone or tooth"],
            ["8th", "Any hurt which endangers life or which causes the sufferer to be in severe bodily pain,\nor unable to follow ordinary pursuits for 20 days"],
        ],
        col_widths=[1.5*cm, PAGE_W-2*MARGIN-1.5*cm],
        hdr_color=RED
    )
    E.append(gh_tbl)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Mnemonic (8 Kinds): E-ESS-PPD-F</b>", MNEMONIC))
    E.append(Paragraph(
        "<b>E</b>masculation | <b>E</b>ye | <b>E</b>ar | <b>S</b>evering member | <b>S</b>tructure/power of joint | "
        "<b>P</b>ermanent disfiguration | <b>P</b>ermanent Fracture/Dislocation | <b>D</b>anger to life / 20 days incapacity",
        NOTE_STYLE))
    E.append(Spacer(1,10))

    # ═══ Q127 IPC S375 ═══
    q_block(E, "127", "What is IPC Section 375? (Rape)", DARK_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>IPC Section 375 (now BNS Section 63):</b> A man is said to commit 'rape' if he commits sexual penetration "
        "under any of the following circumstances:", BODY_STYLE))
    E.append(Spacer(1,4))
    rape_tbl = make_table(
        ["Clause", "Circumstance"],
        [
            ["1st", "Against her will"],
            ["2nd", "Without her consent"],
            ["3rd", "With consent obtained by putting her/her kin in fear of death or hurt"],
            ["4th", "With consent obtained by fraud / impersonation of husband"],
            ["5th", "With consent when she is of unsound mind / intoxicated / unable to understand"],
            ["6th", "With or without consent, when she is UNDER 18 YEARS of age (statutory rape)"],
            ["7th", "When she is unable to communicate consent"],
        ],
        col_widths=[1.5*cm, PAGE_W-2*MARGIN-1.5*cm],
        hdr_color=DARK_BLUE
    )
    E.append(rape_tbl)
    E.append(Spacer(1,4))
    E.append(Paragraph(
        "<b>Exception (BNS):</b> Sexual intercourse or acts by a man with his own wife, wife not being under 18 years of age, is not rape. "
        "<b>Punishment (S.64 BNS):</b> Minimum 7 years to life imprisonment.", NOTE_STYLE))
    E.append(Spacer(1,6))
    rape_med_tbl = make_table(
        ["Medico-legal Point", "Details"],
        [
            ["Age of consent", "18 years (India); sexual act with < 18 = rape regardless of consent"],
            ["Medical examination", "Done by doctor (female examiner preferred); document injuries, collect samples"],
            ["Two-finger test", "Abolished by Supreme Court; NOT to be performed"],
            ["Hymen status", "NOT proof of rape or virginity (types vary)"],
            ["Samples to collect", "Vaginal swabs, blood, urine, nails, hair, clothing"],
            ["Report", "MLR to be submitted to IO; maintain chain of custody"],
        ],
        hdr_color=DARK_BLUE
    )
    E.append(rape_med_tbl)
    E.append(Spacer(1,10))

    # ═══ Q47 / Q101 TESTAMENTARY CAPACITY ═══
    q_block(E, "47 / 101", "What is Testamentary Capacity?", TEAL)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "A <b>will (testament)</b> is a legal document expressing a person's wishes regarding disposal of property after death. "
        "<b>Testamentary capacity</b> means the mental and legal capacity to make a valid will.", BODY_STYLE))
    E.append(Spacer(1,4))
    tc_tbl = make_table(
        ["Requirement", "Explanation"],
        [
            ["1. Age", ">18 years (Indian Succession Act); soldier/mariner: any age"],
            ["2. Sound mind", "Must understand nature of making a will"],
            ["3. Knows nature of act", "Knows he is making a will and what a will does"],
            ["4. Knows extent of property", "Understands what property he has to bequeath"],
            ["5. Knows the beneficiaries", "Can identify who will benefit from the will"],
            ["6. No undue influence", "Free from coercion/pressure; decision is own"],
            ["7. No lucid interval required", "Mentally ill person can make will DURING lucid interval"],
        ],
        hdr_color=TEAL
    )
    E.append(tc_tbl)
    E.append(Spacer(1,6))
    fc_tc = FlowchartDrawing([
        ("Person wants\nto make a WILL", "terminal", TEAL, WHITE),
        ("Is person\n> 18 yrs old?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("INVALID (unless\nsoldier/mariner)", "rounded", LIGHT_RED, RED),
        ("Is person of\nSOUND MIND at time of making?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("If mentally ill:\nIs there a LUCID INTERVAL?", "diamond", LIGHT_BLUE, DARK_BLUE),
        ("VALID WILL\npossible during lucid interval", "rounded", LIGHT_GREEN, GREEN),
        ("Knows: Nature of act,\nExtent of property,\nBeneficiaries?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("VALID TESTAMENTARY\nCAPACITY", "terminal", GREEN, WHITE),
    ], node_h=36, gap=13)
    E.append(Paragraph("<b>FLOWCHART: Assessing Testamentary Capacity</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_tc)
    E.append(Spacer(1,10))

    E.append(PageBreak())

    # ═══ Q136 MEDICO-LEGAL IMPORTANCE OF AGE ═══
    q_block(E, "136", "What is the Medico-legal Importance of Age?", MED_BLUE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "Age is one of the most important parameters in forensic medicine. Many legal provisions depend on age, "
        "and the doctor is frequently called upon to assess age when documentary proof is unavailable.", BODY_STYLE))
    E.append(Spacer(1,4))
    age_tbl = make_table(
        ["Legal Context", "Age Threshold", "Significance"],
        [
            ["Age of consent (sexual intercourse)", "18 years", "< 18 = statutory rape regardless of consent"],
            ["POCSO Act", "< 18 years", "Sexual offence against a child"],
            ["Marriage (female)", "18 years", "Child marriage if < 18"],
            ["Marriage (male)", "21 years", "Child marriage if < 21"],
            ["Age of criminal responsibility", "7 years", "< 7 = absolute immunity (doli incapax)"],
            ["Age of criminal responsibility", "7–12 years", "Partial immunity; must prove maturity"],
            ["Juvenile (JJ Act)", "< 18 years", "Tried by Juvenile Justice Board"],
            ["Consent for treatment", "18 years (general)", "Below this, proxy consent needed"],
            ["Testamentary capacity", "18 years", "Cannot make valid will below 18"],
            ["Voting", "18 years", "Medico-legal age verification"],
            ["Capital punishment", "Not awarded if < 18 at time of offence", "Juvenile protection"],
            ["PM age estimation (body)", "Teeth, bones, epiphyses, radiological methods", "For unidentified bodies"],
        ],
        col_widths=[4.5*cm, 3.2*cm, PAGE_W-2*MARGIN-7.7*cm],
        hdr_color=MED_BLUE
    )
    E.append(age_tbl)
    E.append(Spacer(1,8))

    E.append(Paragraph("<b>Methods of Age Estimation (Forensic):</b>", BOLD_BODY))
    age_m_tbl = make_table(
        ["Method", "Applicable Age", "Details"],
        [
            ["Dental eruption", "0–25 years", "Primary teeth 6mo–2yr; Permanent 6–25yr; Gustafson's method for adults"],
            ["Epiphyseal fusion (X-ray)", "14–25 years", "Clavicle last (25 yrs); iliac crest (21 yrs)"],
            ["Ossification centers", "Fetal to 20 years", "Radiological assessment"],
            ["Secondary sexual characters", "12–18 years", "Breast, pubic hair, genitalia development"],
            ["Wrist/hand X-ray", "8–20 years", "Standard bone age charts (Greulich-Pyle)"],
            ["Skin & hair changes", "Adults & elderly", "Wrinkles, graying, baldness"],
        ],
        hdr_color=MED_BLUE
    )
    E.append(age_m_tbl)
    E.append(Spacer(1,10))

    # ═══ Q110 RIGHT-WRONG TEST ═══
    q_block(E, "110", "What is the Right-Wrong Test? (McNaghten Rules)", PURPLE)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "The <b>Right-Wrong Test</b> (McNaghten Test) is the legal standard for determining criminal responsibility "
        "in a person pleading insanity. It originated from the case of <i>R v. McNaghten (1843)</i>.", BODY_STYLE))
    E.append(Spacer(1,4))
    rw_tbl = make_table(
        ["Aspect", "Details"],
        [
            ["Origin", "R v. McNaghten (1843), House of Lords, England; adopted in India via IPC S.84"],
            ["Test question", "Did the accused know that what he was doing was WRONG or contrary to law?"],
            ["Full test", "(1) Did not know the NATURE of the act, OR\n(2) Did not know the act was WRONG, OR\n(3) Did not know act was CONTRARY TO LAW"],
            ["At the time of act", "Unsoundness must exist at the very time of committing the act"],
            ["Defects of the test", "Purely cognitive; ignores volitional (impulse) disorders; no consideration of irresistible impulse"],
            ["Irresistible impulse test", "Added by some jurisdictions; not standard in India; recognized only partially"],
            ["Medical evaluation", "Forensic psychiatrist assesses mental state; opinion advisory to court"],
            ["Outcome", "If test satisfied β†’ not guilty by reason of insanity β†’ may be committed to psychiatric institution"],
        ],
        col_widths=[4*cm, PAGE_W-2*MARGIN-4*cm],
        hdr_color=PURPLE
    )
    E.append(rw_tbl)
    E.append(Spacer(1,8))
    fc_rw = FlowchartDrawing([
        ("Accused pleads\nINSANITY (S.84 IPC)", "terminal", DARK_BLUE, WHITE),
        ("RIGHT-WRONG TEST\n(McNaghten Rules)", "rect", LIGHT_PURPLE, PURPLE),
        ("Did accused know\nNATURE of the act?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Did accused know\nact was WRONG?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("Did accused know\nact was CONTRARY TO LAW?", "diamond", LIGHT_ORANGE, DARK_BLUE),
        ("LEGALLY RESPONSIBLE\n(no insanity defense)", "rounded", LIGHT_RED, RED),
        ("INSANITY DEFENSE\nSUCCEEDS β†’ Acquittal\n+ Psychiatric detention", "terminal", GREEN, WHITE),
    ], node_h=36, gap=14)
    E.append(Paragraph("<b>FLOWCHART: Right-Wrong Test Application</b>", BOLD_BODY))
    E.append(Spacer(1,4))
    E.append(fc_rw)
    E.append(Spacer(1,10))

    # ═══ Q25 SURROGACY ═══
    q_block(E, "25", "Surrogacy and its Medico-legal Significance", TEAL)
    E.append(Spacer(1,6))
    E.append(Paragraph(
        "<b>Surrogacy</b> is an arrangement where a woman (surrogate mother) carries and delivers a child for another person "
        "or couple (intended parents). In India, it is now regulated by the <b>Surrogacy (Regulation) Act, 2021</b>.", BODY_STYLE))
    E.append(Spacer(1,4))
    surr_tbl = make_table(
        ["Type", "Description"],
        [
            ["<b>Gestational surrogacy</b>", "Surrogate carries embryo formed from eggs and sperm of intended parents (or donors); surrogate has NO genetic link"],
            ["<b>Traditional surrogacy</b>", "Surrogate's own egg fertilized; has genetic link to child (not allowed in India now)"],
            ["<b>Altruistic surrogacy</b>", "Surrogate receives no monetary compensation beyond medical expenses; allowed in India"],
            ["<b>Commercial surrogacy</b>", "Surrogate paid; BANNED in India under Surrogacy Act 2021"],
        ],
        hdr_color=TEAL
    )
    E.append(surr_tbl)
    E.append(Spacer(1,4))
    surr_ml_tbl = make_table(
        ["Medico-legal Aspect", "Details"],
        [
            ["Parenthood", "Intended parents are legal parents; birth certificate in their name"],
            ["Eligibility (India)", "Indian married couple; wife has medical indication; close relative as surrogate"],
            ["Surrogate eligibility", "Married woman, 25–35 yrs, own child, can be surrogate only once"],
            ["Contract", "Must be registered with appropriate authority; surrogate cannot claim custody"],
            ["Child's rights", "Child born has all rights of natural child of intended parents"],
            ["Exploitation concerns", "Commercial surrogacy banned to prevent exploitation of poor women"],
            ["Foreign nationals", "Surrogacy for foreigners/single persons NOT permitted in India (2021 Act)"],
        ],
        hdr_color=TEAL
    )
    E.append(surr_ml_tbl)
    E.append(Spacer(1,10))

    # ═══════════ QUICK REFERENCE SUMMARY TABLE ═══════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 1 β€” QUICK REFERENCE SUMMARY", make_style('sumH', fontSize=14,
        textColor=DARK_BLUE, fontName='Helvetica-Bold', spaceAfter=8, alignment=TA_CENTER)))
    E.append(Spacer(1,4))
    summary_tbl = make_table(
        ["Topic", "Key Points (1-liner)"],
        [
            ["Subpoena / Summons", "Legal order to attend court; civil β†’ damages if ignored; criminal β†’ fine/imprisonment/warrant"],
            ["Conduct Money", "Fee to civil witness at time of summons; not in criminal cases"],
            ["Chief Examination", "By calling party; no leading questions"],
            ["Cross Examination", "By opposite party; leading questions allowed; tests credibility"],
            ["Documentary Evidence", "All documents for court inspection; doctor must testify under oath for ML report to be admitted"],
            ["Privileged Communication", "Bonafide disclosure to right authority to protect community; exception to professional secrecy"],
            ["Res Ipsa Loquitur", "'Thing speaks for itself'; 3 conditions; patient need not prove negligence by expert"],
            ["Borrowed Servant", "Borrowed employee's negligence = special employer's liability if under their control"],
            ["Vicarious Liability", "Master responsible for servant's negligence during employment (Respondeat Superior)"],
            ["Infamous Conduct", "Disgraceful conduct by doctor; can lead to erasure from medical register"],
            ["Valid Consent", "Voluntary, informed, competent, specific, revocable"],
            ["In Loco Parentis", "Standing in parent's place; allows proxy consent for medical treatment of minor"],
            ["Informed Consent (surgery)", "10 components: diagnosis, procedure, risks, benefits, alternatives, consequences of refusal, etc."],
            ["Informed Refusal", "Competent adult can refuse any treatment; document + witness; respect autonomy"],
            ["IPC S.84 / BNS S.22", "Legal insanity; unsoundness of mind at time of act; McNaghten test; acquittal if proved"],
            ["IPC S.320 / BNS S.116", "8 kinds of grievous hurt: emasculation, eye, ear, member, joint, disfigurement, fracture, danger/20 days"],
            ["IPC S.375 / BNS S.63", "Rape: 7 clauses; < 18 = statutory rape; two-finger test abolished"],
            ["Testamentary Capacity", "Age >18; sound mind; knows act, property, beneficiaries; no undue influence; possible in lucid interval"],
            ["Age (medico-legal)", "Determines criminal responsibility, consent, marriage, juvenile status, capital punishment"],
            ["Right-Wrong Test", "McNaghten; did not know nature/wrongness/illegality of act; must be at time of act"],
            ["Surrogacy", "Altruistic allowed in India; commercial banned; gestational only; Surrogacy Act 2021"],
        ],
        col_widths=[4.5*cm, PAGE_W-2*MARGIN-4.5*cm],
        hdr_color=DARK_BLUE
    )
    E.append(summary_tbl)

    # Build
    doc.build(E, onFirstPage=on_page, onLaterPages=on_page)
    print(f"SUCCESS: {OUTPUT_PATH}")


if __name__ == "__main__":
    build_chapter1()
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter1_gen.py 2>&…

Editing File

~/forensic-medicine-pdfs/chapter1_gen.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/forensic-medicine-pdfs/chapter1_gen.py'
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter1_gen.py 2>&…

Running Command

ls -lh /home/daytona/workspace/forensic-medicine-pdfs/Chapter1_Medical_Jurisprud…

Chapter 1 PDF is ready! Here's your download link:

Chapter1 Medical Jurisprudence

PDF Document Β· PDF


What's inside the PDF (73 KB, A4 format):

Cover page with chapter title, reference books, and complete table of contents.
21 questions answered across these topics, each with:
Q. No.TopicFormat
1/86/139Summons / SubpoenaDefinition + comparison table + 2 flowcharts
117Conduct MoneyCivil vs Criminal table + flowchart
42Chief & Cross Examination4-type comparison table + sequence flowchart
43Documentary EvidenceTypes table + admissibility flowchart
28/106Privileged CommunicationConditions + Examples table + decision flowchart
75/100Res Ipsa Loquitur3 conditions + 8 examples table + application flowchart
22Borrowed Servant DoctrineKey points table + flowchart
107Vicarious LiabilityPrinciples table + liability flowchart
59Infamous Conduct9-category table + proceedings flowchart
64Valid ConsentRequirements + types tables + consent process flowchart
65In Loco ParentisBenefits + aspects table
8/19Informed Consent & Refusal10 components + refusal steps tables + flowchart
37IPC S.84 (Legal Insanity)McNaghten elements table + decision flowchart
76/102/150Grievous Hurt (8 kinds)Full table + mnemonic
127IPC S.375 (Rape)7 clauses + medico-legal points table
47/101Testamentary CapacityRequirements table + assessment flowchart
136Medico-legal Importance of AgeLegal thresholds + estimation methods tables
110Right-Wrong TestMcNaghten table + application flowchart
25SurrogacyTypes + medico-legal aspects tables
Final page: Quick-Reference Summary Table of all topics in one-liner format.

Say "Make Chapter 2" (Post-Mortem & Autopsy), "Make Chapter 3" (Thanatology), or "Make all remaining chapters" and I'll generate them the same way!

I am impressed with theabove pdf ....do same for others PDFs ....but please don't add colours to flow charts and tabular form answers because later i will print in black and white ....now make chapter 2 PDF and chapter 3 pdf separately

Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Writing File

~/forensic-medicine-pdfs/chapter2_gen.py

#!/usr/bin/env python3
"""
Chapter 2: Forensic Pathology - Post-Mortem Examination & Autopsy
BLACK AND WHITE version - print friendly
Reference: KS Narayan Reddy 36th Ed 2026, Parikh's, PC Dikshit, DiMaio's
"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
    SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
    PageBreak, HRFlowable, KeepTogether
)
from reportlab.graphics.shapes import Drawing, Rect, String, Line
from reportlab.platypus.flowables import Flowable

OUTPUT_PATH = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter2_PostMortem_Autopsy.pdf"

PAGE_W, PAGE_H = A4
MARGIN = 1.8 * cm

# ── STRICT B&W PALETTE ──────────────────────────────────────────
BLACK    = colors.black
WHITE    = colors.white
GREY_VL  = colors.HexColor("#f0f0f0")   # very light grey – table alt rows
GREY_L   = colors.HexColor("#d6d6d6")   # light grey – table header bg
GREY_M   = colors.HexColor("#aaaaaa")   # medium grey – borders
GREY_D   = colors.HexColor("#555555")   # dark grey – subheadings
GREY_VD  = colors.HexColor("#222222")   # near-black – body text

styles = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name=name, parent=styles.get('Normal', styles['Normal']), **kw)

TITLE_S   = S('T', fontSize=24, textColor=WHITE, fontName='Helvetica-Bold',
              alignment=TA_CENTER, leading=30, spaceAfter=6)
CHAP_S    = S('Ch', fontSize=16, textColor=BLACK, fontName='Helvetica-Bold',
              alignment=TA_CENTER, leading=22)
REF_S     = S('R', fontSize=8.5, textColor=GREY_D, fontName='Helvetica-Oblique',
              alignment=TA_CENTER)
Q_S       = S('Q', fontSize=13, textColor=WHITE, fontName='Helvetica-Bold',
              leading=18, leftIndent=8)
BODY_S    = S('B', fontSize=10, textColor=GREY_VD, leading=15, spaceAfter=4,
              fontName='Helvetica', alignment=TA_JUSTIFY)
BOLD_S    = S('Bd', fontSize=10, textColor=BLACK, leading=15, spaceAfter=3,
              fontName='Helvetica-Bold')
NOTE_S    = S('N', fontSize=9, textColor=GREY_D, fontName='Helvetica-Oblique',
              leading=13, leftIndent=10)
MNEM_S    = S('Mn', fontSize=10.5, textColor=BLACK, fontName='Helvetica-Bold',
              leading=15, leftIndent=10)
TH_S      = S('TH', fontSize=9, textColor=WHITE, fontName='Helvetica-Bold',
              alignment=TA_CENTER, leading=12)
TC_S      = S('TC', fontSize=8.5, textColor=GREY_VD, fontName='Helvetica',
              leading=12, alignment=TA_LEFT)
TC_C      = S('TCC', fontSize=8.5, textColor=GREY_VD, fontName='Helvetica',
              leading=12, alignment=TA_CENTER)
FC_S      = S('FC', fontSize=8.5, textColor=BLACK, fontName='Helvetica',
              leading=11, alignment=TA_CENTER)
FC_B      = S('FCB', fontSize=9, textColor=BLACK, fontName='Helvetica-Bold',
              leading=12, alignment=TA_CENTER)

# ── PAGE TEMPLATE ────────────────────────────────────────────────
def on_page(canv, doc):
    canv.saveState()
    canv.setFillColor(BLACK)
    canv.rect(0, PAGE_H - 1.1*cm, PAGE_W, 1.1*cm, fill=1, stroke=0)
    canv.setFillColor(WHITE)
    canv.setFont('Helvetica-Bold', 9)
    canv.drawString(MARGIN, PAGE_H - 0.72*cm, "FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica', 8)
    canv.drawRightString(PAGE_W - MARGIN, PAGE_H - 0.72*cm,
                         "Chapter 2: Post-Mortem Examination & Autopsy")
    canv.setFillColor(BLACK)
    canv.rect(0, 0, PAGE_W, 0.9*cm, fill=1, stroke=0)
    canv.setFillColor(WHITE)
    canv.setFont('Helvetica', 8)
    canv.drawString(MARGIN, 0.32*cm,
                    "Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W - MARGIN, 0.32*cm, f"Page {doc.page}")
    canv.restoreState()

# ── HELPERS ──────────────────────────────────────────────────────
def q_block(E, num, text):
    d = [[Paragraph(f"Q.{num}  {text}", Q_S)]]
    t = Table(d, colWidths=[PAGE_W - 2*MARGIN])
    t.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), BLACK),
        ('TOPPADDING', (0,0), (-1,-1), 8),
        ('BOTTOMPADDING', (0,0), (-1,-1), 8),
        ('LEFTPADDING', (0,0), (-1,-1), 10),
        ('RIGHTPADDING', (0,0), (-1,-1), 10),
    ]))
    E.append(KeepTogether([t]))
    E.append(Spacer(1, 6))

def make_table(headers, rows, col_widths=None, stripe=True):
    avail = PAGE_W - 2*MARGIN - 0.2*cm
    if col_widths is None:
        col_widths = [avail / len(headers)] * len(headers)
    data = [[Paragraph(h, TH_S) for h in headers]]
    for r in rows:
        data.append([Paragraph(str(c), TC_S) for c in r])
    t = Table(data, colWidths=col_widths, repeatRows=1)
    cmds = [
        ('BACKGROUND', (0,0), (-1,0), BLACK),
        ('TEXTCOLOR',  (0,0), (-1,0), WHITE),
        ('FONTNAME',   (0,0), (-1,0), 'Helvetica-Bold'),
        ('GRID',       (0,0), (-1,-1), 0.4, GREY_M),
        ('VALIGN',     (0,0), (-1,-1), 'TOP'),
        ('TOPPADDING', (0,0), (-1,-1), 4),
        ('BOTTOMPADDING', (0,0), (-1,-1), 4),
        ('LEFTPADDING', (0,0), (-1,-1), 5),
        ('RIGHTPADDING', (0,0), (-1,-1), 5),
    ]
    if stripe:
        for i in range(2, len(data), 2):
            cmds.append(('BACKGROUND', (0,i), (-1,i), GREY_VL))
    t.setStyle(TableStyle(cmds))
    return t

# ── FLOWCHART (B&W) ──────────────────────────────────────────────
class BW_Flowchart(Flowable):
    """Black-and-white vertical flowchart. shapes: rect, diamond, rounded, terminal"""
    def __init__(self, nodes, width=None, node_h=34, gap=16):
        super().__init__()
        self.nodes = nodes   # (text, shape)
        self.nw = width or (PAGE_W - 2*MARGIN - 0.5*cm)
        self.node_h = node_h
        self.gap = gap
        self.width = self.nw
        self.height = len(nodes) * (node_h + gap) - gap + 20

    def wrap(self, aW, aH):
        return self.width, self.height

    def draw(self):
        c = self.canv
        y = self.height - 10
        nw, nh, gap = self.nw, self.node_h, self.gap
        cx = nw / 2

        for i, (text, shape) in enumerate(self.nodes):
            top_y = y - nh
            mid_y = y - nh / 2
            c.setFillColor(WHITE)
            c.setStrokeColor(BLACK)
            c.setLineWidth(1.2)

            if shape == 'terminal':
                c.setFillColor(BLACK)
                c.roundRect(cx - nw*0.35, top_y, nw*0.70, nh, nh/2, fill=1, stroke=1)
            elif shape == 'diamond':
                p = c.beginPath()
                p.moveTo(cx,        y)
                p.lineTo(cx+nw*0.40, mid_y)
                p.lineTo(cx,        top_y)
                p.lineTo(cx-nw*0.40, mid_y)
                p.close()
                c.drawPath(p, fill=1, stroke=1)
            elif shape == 'rounded':
                c.roundRect(cx - nw*0.44, top_y, nw*0.88, nh, 8, fill=1, stroke=1)
            else:  # rect
                c.rect(cx - nw*0.44, top_y, nw*0.88, nh, fill=1, stroke=1)

            # Text
            if shape == 'terminal':
                c.setFillColor(WHITE)
                c.setFont('Helvetica-Bold', 8.5)
            elif shape == 'diamond':
                c.setFillColor(WHITE)
                c.setFont('Helvetica-Bold', 8)
            else:
                c.setFillColor(BLACK)
                c.setFont('Helvetica', 8.5)

            lines = text.split('\n')
            lh = 11
            ty = mid_y + len(lines) * lh / 2 - lh * 0.7
            for ln in lines:
                c.drawCentredString(cx, ty, ln)
                ty -= lh

            # Arrow
            if i < len(self.nodes) - 1:
                ay_top = top_y
                ay_bot = top_y - gap
                c.setStrokeColor(BLACK)
                c.setLineWidth(1.3)
                c.line(cx, ay_top, cx, ay_bot + 6)
                c.setFillColor(BLACK)
                p = c.beginPath()
                p.moveTo(cx, ay_bot)
                p.lineTo(cx - 5, ay_bot + 8)
                p.lineTo(cx + 5, ay_bot + 8)
                p.close()
                c.drawPath(p, fill=1, stroke=0)

            y = top_y - gap


# ════════════════════════════════════════════════════════════════
#                       BUILD DOCUMENT
# ════════════════════════════════════════════════════════════════
def build():
    doc = SimpleDocTemplate(
        OUTPUT_PATH, pagesize=A4,
        leftMargin=MARGIN, rightMargin=MARGIN,
        topMargin=1.5*cm, bottomMargin=1.3*cm,
        title="Chapter 2 – Post-Mortem Examination & Autopsy",
        author="Forensic Medicine Question Bank"
    )
    E = []

    # ── COVER ──────────────────────────────────────────────────
    E.append(Spacer(1, 1.5*cm))
    cover = Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY", TITLE_S)]],
                  colWidths=[PAGE_W - 2*MARGIN])
    cover.setStyle(TableStyle([
        ('BACKGROUND', (0,0), (-1,-1), BLACK),
        ('TOPPADDING', (0,0), (-1,-1), 20),
        ('BOTTOMPADDING', (0,0), (-1,-1), 20),
    ]))
    E.append(cover)
    E.append(Spacer(1, 0.5*cm))
    ch_box = Table([[Paragraph("CHAPTER 2", CHAP_S)]], colWidths=[PAGE_W - 2*MARGIN])
    ch_box.setStyle(TableStyle([
        ('BOX', (0,0), (-1,-1), 2, BLACK),
        ('TOPPADDING', (0,0), (-1,-1), 10),
        ('BOTTOMPADDING', (0,0), (-1,-1), 10),
    ]))
    E.append(ch_box)
    E.append(Spacer(1, 0.3*cm))
    title_box = Table(
        [[Paragraph("Post-Mortem Examination<br/>&amp; Forensic Autopsy",
                    S('tb', fontSize=20, textColor=BLACK, fontName='Helvetica-Bold',
                      alignment=TA_CENTER, leading=28))]],
        colWidths=[PAGE_W - 2*MARGIN])
    title_box.setStyle(TableStyle([
        ('TOPPADDING', (0,0), (-1,-1), 8), ('BOTTOMPADDING', (0,0), (-1,-1), 8)]))
    E.append(title_box)
    E.append(Spacer(1, 0.4*cm))
    ref_box = Table(
        [[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed", REF_S)]],
        colWidths=[PAGE_W - 2*MARGIN])
    ref_box.setStyle(TableStyle([
        ('BOX', (0,0), (-1,-1), 1, BLACK),
        ('BACKGROUND', (0,0), (-1,-1), GREY_VL),
        ('TOPPADDING', (0,0), (-1,-1), 7), ('BOTTOMPADDING', (0,0), (-1,-1), 7),
    ]))
    E.append(ref_box)
    E.append(Spacer(1, 0.4*cm))

    # TOC
    toc = make_table(
        ["Q. No.", "Topic"],
        [
            ["10", "Decomposition changes in drowned body (1 week post-mortem)"],
            ["32 / 81", "Exhumation – Indications, Authorization & Procedure"],
            ["38", "4 Types of Early Post-Mortem Changes"],
            ["40 / 85", "Viscera Preservation for Chemical Analysis in Poisoning"],
            ["140", "Methods of Organ Removal at Post-Mortem"],
            ["154", "Protocols for Sample Collection during Autopsy"],
            ["87", "Hydrostatic Test (Docimasia Pulmonaris)"],
            ["41", "Virtual Autopsy (Virtopsy)"],
            ["62", "Negative Autopsy"],
            ["151", "Inquest"],
        ],
        col_widths=[2.5*cm, PAGE_W - 2*MARGIN - 2.5*cm]
    )
    E.append(Paragraph("CHAPTER CONTENTS", S('toch', fontSize=11, textColor=BLACK,
        fontName='Helvetica-Bold', spaceAfter=5)))
    E.append(toc)
    E.append(PageBreak())

    # ════════════════════════════════════════════════════════════
    # Q151 – INQUEST
    # ════════════════════════════════════════════════════════════
    q_block(E, "151", "What is an Inquest?")
    E.append(Paragraph(
        "An <b>inquest</b> is an official inquiry into the cause and manner of a sudden, unnatural, or suspicious "
        "death, conducted by a legally authorized person (Magistrate or Police Officer).", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Type", "Conducted by", "Legal Provision", "Cases Covered"],
        [
            ["Police Inquest", "Sub-Inspector of Police or above",
             "S.194, BNSS (old S.174 CrPC)",
             "Sudden / suspicious / unnatural deaths; accidental, suicidal, homicidal"],
            ["Magistrate's Inquest", "Executive Magistrate",
             "S.196, BNSS (old S.176 CrPC)",
             "Deaths in police custody; mass disasters; exhumation order"],
            ["Coroner's Inquest", "Coroner (judicial officer)",
             "Coroner's Act (only Mumbai & Chennai)",
             "Unnatural deaths; jury of 5–23 persons delivers verdict"],
        ],
        col_widths=[3*cm, 3.5*cm, 3*cm, PAGE_W-2*MARGIN-9.5*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(make_table(
        ["Aspect of Police Inquest", "Details"],
        [
            ["Purpose", "To determine cause of death; preserve evidence; identify deceased"],
            ["Medical officer's role", "Perform PM examination; submit report to IO"],
            ["Inquest report", "Contains: description of body, injuries, apparent cause of death"],
            ["Body disposal", "IO may authorize burial after inquest"],
            ["PM not mandatory", "IO decides if PM needed (except suspicious / custody deaths)"],
            ["Documents prepared", "Inquest panchanama (witnessed by panchas)"],
        ]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Inquest Procedure</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("SUDDEN / UNNATURAL / SUSPICIOUS DEATH\nreported to Police", "terminal"),
        ("Sub-Inspector proceeds to scene\n(S.194 BNSS – Police Inquest)", "rect"),
        ("Scene preserved; body identified;\ncircumstances noted", "rect"),
        ("Inquest Panchanama prepared\n(in presence of witnesses/panchas)", "rounded"),
        ("Post-Mortem Examination\nordered (if required)", "diamond"),
        ("Medical Officer performs PM;\nsubmits report to IO", "rect"),
        ("IO forwards all documents\nto Magistrate", "rounded"),
        ("MAGISTRATE'S INQUEST\nif death in custody / mass disaster\n(S.196 BNSS)", "terminal"),
    ], node_h=36, gap=14))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # Q38 – 4 TYPES OF EARLY POST-MORTEM CHANGES
    # ════════════════════════════════════════════════════════════
    q_block(E, "38", "Enumerate 4 Types of Early Post-Mortem Changes")
    E.append(Paragraph(
        "Post-mortem changes begin immediately after death and are classified into <b>early</b> and <b>late</b> changes. "
        "The 4 major early post-mortem changes are:", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Early PM Change", "Onset", "Key Features"],
        [
            ["1. Cooling of the body\n(Algor Mortis)",
             "Begins immediately;\n~1Β°C/hr in first 12 hrs",
             "Body cools to ambient temp; Henssge's nomogram used for TSD estimation;\n"
             "affected by clothing, environment, body fat"],
            ["2. Post-mortem staining\n(Livor Mortis / Hypostasis)",
             "Starts 30 min–2 hrs;\nfixed by 6–12 hrs",
             "Blood gravitates to dependent areas; pink-purple discoloration;\n"
             "not on pressure points; cherry-red in CO poisoning"],
            ["3. Rigor Mortis",
             "Starts 2–6 hrs;\ncomplete 12 hrs;\ndisappears 24–48 hrs",
             "Stiffening of muscles due to ATP depletion β†’ actin-myosin cross-bridges;\n"
             "affects all muscles simultaneously; small muscles apparent first;\n"
             "broken rigor does not return"],
            ["4. Cooling of the eye\n(Tache Noire / Corneal clouding)",
             "Hours after death",
             "Tache noire: brown-black band on sclera when eyes open (desiccation);\n"
             "Corneal clouding: within 2–3 hours; iris details lost"],
        ],
        col_widths=[3.8*cm, 3.2*cm, PAGE_W-2*MARGIN-7*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Early Post-Mortem Changes (Sequence)</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("DEATH OCCURS\n(Somatic death)", "terminal"),
        ("0–30 min: Tache Noire\n(if eyes open); skin desiccation", "rect"),
        ("30 min–2 hrs:\nLIVOR MORTIS begins\n(blood gravitates to dependent parts)", "rect"),
        ("2–6 hrs:\nRIGOR MORTIS begins\n(ATP depletion β†’ actin-myosin binding)", "rect"),
        ("6–12 hrs: Livor FIXED;\nBody cools ~1Β°C/hr\n(ALGOR MORTIS)", "rect"),
        ("12 hrs: Rigor COMPLETE;\nCornea cloudy", "rounded"),
        ("24–48 hrs: Rigor PASSES OFF\n(autolysis of myosin/actin)", "rounded"),
        ("LATE CHANGES BEGIN\n(Decomposition / Putrefaction)", "terminal"),
    ], node_h=36, gap=14))
    E.append(Spacer(1, 10))

    E.append(PageBreak())

    # ════════════════════════════════════════════════════════════
    # Q10 – DECOMPOSITION IN DROWNED BODY
    # ════════════════════════════════════════════════════════════
    q_block(E, "10", "Body Recovered from River 1 Week After Drowning – Describe Decomposition Changes")
    E.append(Paragraph(
        "<b>Casper's Dictum:</b> 'In open air, a body decomposes twice as fast as in water, and eight times as fast "
        "as when buried in earth.' After 1 week in water (river/summer), the following changes are expected:", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Time in Water", "Decomposition Changes Expected"],
        [
            ["1–2 days", "Skin pale/wrinkled; livor mortis washes out; early maceration;\n"
             "putrefactive discoloration begins (greenish abdomen in warm water)"],
            ["3–4 days", "Skin maceration (washerwoman's hands/feet); skin slip;\n"
             "bloating of abdomen; gases in body cavities; distension of face"],
            ["5–7 days\n(EXPECTED at recovery)", "Skin: white-grey maceration; slippage over large areas;\n"
             "Face: bloated, unrecognizable, greenish-black;\n"
             "Abdomen: tympanitic, marbling (putrefactive veins);\n"
             "Eyes: sunken; tongue may protrude;\n"
             "Body may float due to gas formation (adipocere beginning);\n"
             "Smell: foul putrefactive odor;\n"
             "Washerwoman's hands and feet prominent"],
            ["2–3 weeks", "Adipocere formation begins (saponification of subcutaneous fat);\n"
             "hair loosens; nails detach; skin may peel off in large sheets"],
        ],
        col_widths=[3*cm, PAGE_W-2*MARGIN-3*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(make_table(
        ["Feature", "Details in Drowning Decomposition"],
        [
            ["Adipocere", "More likely in water; fat saponification; soapy, waxy; protects body from further decomposition"],
            ["Maceration", "Skin white, wrinkled, separates from dermis; palms/soles first affected"],
            ["Skin slip", "Epidermis peels off in gloves/sheets; may complicate fingerprinting"],
            ["Putrefaction order", "Abdomen β†’ face/neck β†’ chest β†’ limbs"],
            ["Factors affecting rate", "Water temperature (warm = faster); river current; exposure to fish/aquatic insects"],
            ["Casper's Dictum", "Water decomposition = Β½ of air; 1/8 of buried body"],
            ["Identification clues", "Clothing, jewelry, dental records, DNA (adipocere preserved); fingerprint from macerated skin"],
            ["Cause of death", "Even with advanced decomposition, drowning signs (emphysema aquosum, diatoms) may be found"],
        ]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Decomposition Changes in Water Over Time</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("BODY ENTERS WATER\n(Death from drowning)", "terminal"),
        ("Day 1–2:\nPallor; skin wrinkles;\nlivor washes out;\nputrefaction starts (warm water)", "rect"),
        ("Day 3–4:\nMaceration; skin slip;\nabdominal bloating;\nmarbling begins", "rect"),
        ("Day 5–7 (RECOVERY):\nFace bloated/greenish;\nWasherwoman's hands/feet;\ntympanitic abdomen;\nfoul smell", "rect"),
        ("Day 14–21:\nADIPOCERE formation;\nhair/nail detachment;\nskin sheets peel off", "rect"),
        ("1–3 months:\nComplete adipocere;\nskeletonization begins", "rounded"),
        ("CASPER'S DICTUM:\nWater = 2x slower than air\n= 8x slower than buried", "terminal"),
    ], node_h=38, gap=14))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # Q32 / Q81 – EXHUMATION
    # ════════════════════════════════════════════════════════════
    q_block(E, "32 / 81", "Describe Exhumation – Definition, Indications, Authorization & Procedure")
    E.append(Paragraph(
        "<b>Definition (KS Narayan Reddy):</b> Exhumation is the digging out of an already buried body legally from "
        "the grave. (Burial = inhumation; Digging out = exhumation). <b>There is no time limit for exhumation in India.</b>", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Aspect", "Details"],
        [
            ["Authorization", "Written order of Executive / Judicial Magistrate (S.196(4), BNSS)"],
            ["Conducted by", "Medical Officer + Magistrate + Police Officer; relatives may be present (S.196(5) BNSS)"],
            ["PM site", "Autopsies usually performed at the site of exhumation"],
            ["Time limit", "No time limit in India"],
            ["Cremation cases", "Exhumation not possible; ash may be examined (skeletal fragments)"],
        ]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>INDICATIONS FOR EXHUMATION:</b>", BOLD_S))
    E.append(make_table(
        ["Criminal Cases", "Civil Cases"],
        [
            ["Suspected homicide disguised as natural/suicidal death",
             "Accidental death claim (insurance)"],
            ["Suspected poisoning",
             "Workmen's compensation claim"],
            ["Criminal abortion death",
             "Professional negligence liability suit"],
            ["Criminal negligence",
             "Survivorship and inheritance claims"],
            ["Improper / absent first PM examination",
             "Disputed identity of deceased"],
        ]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>PROCEDURE (Step-by-step, Narayan Reddy):</b>", BOLD_S))
    E.append(make_table(
        ["Step", "Action"],
        [
            ["1", "Obtain detailed information about deceased, clothes worn at burial"],
            ["2", "Proceed to grave with Magistrate + Police officer; inform relatives (S.196(5) BNSS)"],
            ["3", "Positively identify grave: location, headstone, grave marker, distance from permanent landmarks"],
            ["4", "Conduct in natural daylight; screen off area if public spectators present"],
            ["5", "Uncover burial 10–15 cm at a time; note soil condition, water content, vegetable growth"],
            ["6", "Measure depth of grave (surface to skull; surface to feet)"],
            ["7", "Expose body using soft brush/whisk broom (not hard tools)"],
            ["8", "Photograph body in situ; draw diagram noting position (face up/down, limb positions)"],
            ["9", "Collect soil samples from around body (for toxicology comparison)"],
            ["10", "Transfer body for PM examination; collect viscera/samples for chemical analysis"],
            ["11", "Identify body by relatives/dental records/DNA if decomposed"],
            ["12", "Reburial after PM; Magistrate supervises"],
        ],
        col_widths=[1*cm, PAGE_W-2*MARGIN-1*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Exhumation Process</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("REQUEST for\nEXHUMATION", "terminal"),
        ("Magistrate issues\nWRITTEN ORDER\n(S.196(4) BNSS)", "rect"),
        ("Assemble team:\nMedical Officer + Magistrate\n+ Police Officer", "rect"),
        ("IDENTIFY GRAVE\n(headstone, marker, landmarks)", "diamond"),
        ("Excavate 10–15 cm at a time;\nNote soil, water, vegetation", "rect"),
        ("EXPOSE BODY with soft brush;\nPhotograph in situ", "rect"),
        ("Collect SOIL SAMPLES\naround body (toxicology control)", "rounded"),
        ("Transfer for POST-MORTEM;\nCollect viscera/specimens", "rect"),
        ("REBURIAL\nunder Magistrate's supervision", "terminal"),
    ], node_h=36, gap=14))
    E.append(Spacer(1, 10))

    E.append(PageBreak())

    # ════════════════════════════════════════════════════════════
    # Q40 / Q85 – VISCERA PRESERVATION IN POISONING
    # ════════════════════════════════════════════════════════════
    q_block(E, "40 / 85", "Viscera Preservation for Chemical Analysis in Suspected Poisoning")
    E.append(Paragraph(
        "During post-mortem examination in a case of suspected poisoning, specific viscera must be preserved "
        "in appropriate containers and preservatives to enable chemical/forensic analysis.", BODY_S))
    E.append(Spacer(1, 4))
    E.append(Paragraph("<b>Standard Viscera Preserved (Narayan Reddy / Parikh's):</b>", BOLD_S))
    E.append(make_table(
        ["Organ / Sample", "Amount", "Preservative Used", "Purpose"],
        [
            ["Stomach + contents", "Entire", "Saturated NaCl OR no preservative", "Identify poison; undigested food/tablets"],
            ["Small intestine + contents\n(20–30 cm from pylorus)", "Section", "Saturated NaCl", "Absorbing poison; drug residues"],
            ["Liver", "~500 g", "Saturated NaCl (1/3 with, 2/3 without)", "Metabolism of poisons; main analysis organ"],
            ["Kidney", "One whole kidney", "Saturated NaCl", "Excretion; heavy metals (arsenic, lead)"],
            ["Blood", "50–100 mL (heart blood)", "Fluoride-oxalate (alcohol, cyanide)", "Toxicology screen; alcohol level"],
            ["Urine", "Entire bladder", "No preservative OR fluoride", "Drug metabolites; alcohol"],
            ["Brain", "~500 g", "Saturated NaCl", "CNS depressants; organophosphates; volatile poisons"],
            ["Lungs", "Portion", "Saturated NaCl", "Volatile poisons (chloroform, HCN, CO)"],
            ["Vitreous humor", "Both eyes", "No preservative (sealed syringe)", "Alcohol (reliable); glucose, electrolytes post-mortem"],
            ["Bone (long bone)", "Femur section", "Dry / no preservative", "Arsenic, heavy metals (years later)"],
            ["Hair & Nails", "Clippings", "Dry, sealed bag", "Chronic arsenic/heavy metal poisoning"],
            ["Skin (injection site)", "Excised piece", "Formaldehyde / NaCl", "Injection marks; local poison deposit"],
        ],
        col_widths=[3.5*cm, 1.8*cm, 3.2*cm, PAGE_W-2*MARGIN-8.5*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>IMPORTANT RULES (Narayan Reddy):</b>", BOLD_S))
    E.append(make_table(
        ["Rule", "Details"],
        [
            ["Preservative of choice", "Saturated NaCl (common salt solution) β€” does NOT interfere with most chemical tests"],
            ["NEVER use formalin", "Formalin destroys organic poisons (alkaloids, barbiturates, alcohol)"],
            ["Separate containers", "Each organ in separate, clean, wide-mouth glass jar with airtight stopper"],
            ["Labeling", "Date, name, case no., organ, preservative used; doctor's seal and signature"],
            ["Chain of custody", "Sealed and handed to IO with proper documentation; cannot be broken"],
            ["Control sample", "Blank jar with preservative only (to rule out preservative contamination)"],
            ["Exhumation cases", "Soil sample also sent (to exclude soil contamination with arsenic)"],
            ["For CO poisoning", "Blood in fluoride-oxalate; also cardiac blood in sealed container"],
            ["For alcohol", "Vitreous humor + blood in fluoride-oxalate; urine unpreserved"],
        ]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Viscera Preservation Protocol</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("SUSPECTED POISONING CASE\nPost-mortem commenced", "terminal"),
        ("Systematic PM examination;\nNote injuries, organ changes", "rect"),
        ("COLLECT viscera:\nStomach, Small intestine, Liver,\nKidney, Brain, Lungs", "rect"),
        ("COLLECT fluids:\nBlood (heart), Urine, Vitreous humor", "rect"),
        ("SPECIAL SAMPLES:\nHair, Nails, Bone, Skin (inject site)", "rect"),
        ("Correct PRESERVATIVE in\nSEPARATE labeled glass jars\n(Sat. NaCl – NOT formalin)", "rounded"),
        ("Include CONTROL BLANK JAR\n(preservative only)", "diamond"),
        ("SEAL all jars; Doctor's\nsignature + case details", "rect"),
        ("Hand over to IO with\nCHAIN OF CUSTODY documentation", "terminal"),
    ], node_h=36, gap=14))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # Q140 – METHODS OF ORGAN REMOVAL AT PM
    # ════════════════════════════════════════════════════════════
    q_block(E, "140", "Methods of Organ Removal at Post-Mortem Examination")
    E.append(Paragraph(
        "After external examination and incision of the body, organs are removed using one of several established "
        "autopsy techniques. The incision used in routine ML autopsy is the <b>Y-shaped</b> or "
        "<b>modified Y-shaped</b> incision.", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Method / Technique", "Description", "Advantages", "When Used"],
        [
            ["<b>Virchow Technique</b>\n(In situ dissection)",
             "Each organ removed and examined individually, in sequence",
             "Detailed examination of each organ; preserves normal relationships initially",
             "Standard technique; most widely used"],
            ["<b>Rokitansky Technique</b>\n(Partial evisceration)",
             "Organs partially dissected in situ; some connections maintained during examination;\nthen organ removed",
             "Preserves anatomical relationships; thoracic organs examined together",
             "Traditional European method; teaching"],
            ["<b>Letulle Technique</b>\n(En masse removal)",
             "All organs removed en bloc as one mass; then separated on dissection table",
             "Rapid; preserves organ relationships; good for vascular examination",
             "Large-scale autopsy; trauma cases; vascular pathology"],
            ["<b>Ghon Technique</b>\n(Modified Letulle)",
             "Organs removed in groups (chest organs together; abdominal organs together)",
             "Compromise between individual and en masse removal",
             "Paediatric autopsies; teaching"],
        ],
        col_widths=[3.5*cm, 4.5*cm, 3*cm, PAGE_W-2*MARGIN-11*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>PM Incisions Used:</b>", BOLD_S))
    E.append(make_table(
        ["Incision Type", "Description", "Use"],
        [
            ["Y-shaped", "Two cuts from shoulders meeting at xiphisternum; continue to pubis", "Standard medico-legal autopsy"],
            ["Modified Y-shaped", "From mastoid process β†’ shoulders β†’ xiphisternum β†’ pubis", "Preserves neck for strangulation/hanging cases"],
            ["I-shaped (midline)", "Single straight cut chin to pubis", "Less common; some forensic centers"],
            ["T-shaped", "Horizontal cut at shoulders + vertical cut to pubis", "Alternative to Y"],
        ],
        col_widths=[3*cm, 6*cm, PAGE_W-2*MARGIN-9*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Organ Removal Sequence (Virchow – Standard)</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("EXTERNAL EXAMINATION\ncomplete; photographs taken", "terminal"),
        ("Y / Modified Y INCISION\n(skin + subcutaneous tissue)", "rect"),
        ("CHEST opened:\nRib cage cut; examine thoracic cavity", "rect"),
        ("HEART & LUNGS removed\n(in sequence or en bloc)", "rect"),
        ("ABDOMEN opened:\nExamine peritoneal cavity", "rect"),
        ("LIVER, SPLEEN, KIDNEYS,\nSTOMACH, INTESTINES removed", "rect"),
        ("BRAIN: Skull cap removed;\nDura examined; brain removed", "rect"),
        ("SPINAL CORD (if needed):\nVertebral column opened", "rounded"),
        ("All organs EXAMINED,\nweighed, sectioned; samples collected", "rect"),
        ("PM REPORT written;\nViscera preserved if poisoning", "terminal"),
    ], node_h=34, gap=13))
    E.append(Spacer(1, 10))

    E.append(PageBreak())

    # ════════════════════════════════════════════════════════════
    # Q154 – PROTOCOLS FOR SAMPLE COLLECTION DURING AUTOPSY
    # ════════════════════════════════════════════════════════════
    q_block(E, "154", "Protocols for Sample Collection During Autopsy")
    E.append(make_table(
        ["Sample Type", "Collection Method", "Container / Preservative", "Tests Performed"],
        [
            ["Blood (cardiac)", "Syringe from right heart / major vessel before opening",
             "Fluoride-oxalate (alcohol/CO); plain (toxicology); EDTA (DNA)",
             "Toxicology, DNA, grouping, culture"],
            ["Urine", "Syringe via bladder puncture", "Fluoride or plain sealed container",
             "Drug metabolites, alcohol, ketones"],
            ["Vitreous humor", "25G needle into lateral canthus; gentle aspiration",
             "Plain sealed syringe/vial", "Alcohol, glucose, K+, urea (reliable PM values)"],
            ["Bile", "Gall bladder aspiration", "Plain vial", "Drug metabolites (esp. opioids)"],
            ["CSF", "Needle via cisterna magna or lumbar area", "Plain vial",
             "Infections, drugs"],
            ["Gastric contents", "Entire stomach ligated + removed", "Wide-mouth glass jar, Sat. NaCl",
             "Poison identification, food contents"],
            ["Histology (tissues)", "Sections from heart, lung, liver, kidney, brain",
             "10% formalin", "Microscopic pathology"],
            ["Microbiology", "Heart blood, spleen, CSF in sterile containers",
             "Sterile containers, no preservative", "Culture and sensitivity"],
            ["Hair/Nails", "Cut from scalp root and fingertips", "Sealed dry envelope",
             "Chronic toxicology, DNA"],
            ["Swabs (sexual assault)", "Vaginal / anal / oral swabs", "Sterile dry swabs",
             "DNA, spermatozoa, STI"],
            ["Bone (marrow)", "Section of femur or rib", "Sealed dry", "DNA (decomposed); heavy metals"],
            ["Soil (exhumation)", "From 4 sides around body", "Sealed labeled bags", "Background arsenic / toxin levels"],
        ],
        col_widths=[2.8*cm, 3.5*cm, 3.5*cm, PAGE_W-2*MARGIN-9.8*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>CHAIN OF CUSTODY (essential steps):</b>", BOLD_S))
    E.append(make_table(
        ["Step", "Action"],
        [
            ["1", "Label each container: date, case no., deceased name, organ/fluid, preservative, doctor's name"],
            ["2", "Doctor seals each container with wax/tape and signs across the seal"],
            ["3", "Prepare forwarding letter mentioning all samples, their details, and tests requested"],
            ["4", "Hand over to Investigating Officer with acknowledgment receipt"],
            ["5", "IO sends to Forensic Science Laboratory (FSL) under seal"],
            ["6", "FSL officer verifies seals intact before opening"],
            ["7", "Any break in chain = evidence may be rejected by court"],
        ],
        col_widths=[1*cm, PAGE_W-2*MARGIN-1*cm]
    ))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # Q87 – HYDROSTATIC TEST (DOCIMASIA PULMONARIS)
    # ════════════════════════════════════════════════════════════
    q_block(E, "87", "What is the Hydrostatic Test (Docimasia Pulmonaris)?")
    E.append(Paragraph(
        "The <b>Hydrostatic test</b> (also called <b>Docimasia Pulmonaris</b> or <b>lung float test</b>) is performed "
        "at autopsy to determine whether a newborn infant had breathed air before death (i.e., was liveborn).", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Aspect", "Details"],
        [
            ["Principle", "Lungs that have breathed air contain air bubbles β†’ float on water;\nUnbreathed lungs are airless and dense β†’ sink"],
            ["Procedure",
             "1. Remove lungs intact without cutting\n"
             "2. Place entire lung mass in water β†’ note floating/sinking\n"
             "3. Separate each lobe β†’ test individually\n"
             "4. Cut small pieces β†’ squeeze underwater β†’ note air bubbles\n"
             "5. Press between blotter β†’ if squeaking sound β†’ air present"],
            ["Result (Breathed)", "Lungs float β†’ air present β†’ child was LIVEBORN"],
            ["Result (Not breathed)", "Lungs sink β†’ airless β†’ STILLBIRTH (or deadborn)"],
            ["Stomach-Bowel test\n(Breslau's 2nd life test)", "Air may be swallowed; stomach/intestines may float even in liveborn;\nfloating stomach+intestines confirms breathing+swallowing"],
        ],
        col_widths=[3.5*cm, PAGE_W-2*MARGIN-3.5*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>CAUSES OF FALSE RESULTS:</b>", BOLD_S))
    E.append(make_table(
        ["False Positive (lungs float but not breathed)", "False Negative (lungs sink but breathed)"],
        [
            ["Putrefaction gases in lung tissue (decomposition)",
             "Severe pneumonia / atelectasis"],
            ["Artificial respiration performed on dead neonate",
             "Premature infant with RDS (hyaline membrane)"],
            ["Post-mortem decomposition gas",
             "Macerated stillbirth with fluid-filled lungs"],
        ]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Hydrostatic Test</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("NEWBORN INFANT\nfound dead", "terminal"),
        ("Remove LUNGS intact\n(without cutting)", "rect"),
        ("Place in CONTAINER\nof WATER", "diamond"),
        ("LUNGS FLOAT?", "diamond"),
        ("YES → Air present\n→ LIVEBORN (breathed)", "rounded"),
        ("NO → Airless\n→ STILLBIRTH suspected", "rounded"),
        ("Cut small pieces;\nSqueeze UNDERWATER\n(bubbles = air = breathed)", "rect"),
        ("Also test STOMACH + BOWEL\n(Breslau's 2nd Life Test)", "rect"),
        ("REPORT:\nLiveborn or Stillborn", "terminal"),
    ], node_h=34, gap=13))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # Q41 – VIRTUAL AUTOPSY (VIRTOPSY)
    # ════════════════════════════════════════════════════════════
    q_block(E, "41", "What is Virtual Autopsy (Virtopsy)?")
    E.append(Paragraph(
        "<b>Virtual autopsy (Virtopsy)</b> is a non-invasive or minimally invasive autopsy technique that uses "
        "advanced imaging (CT, MRI, 3D surface scanning) and minimally invasive sampling to determine cause of death, "
        "without traditional dissection. Developed at the University of Bern, Switzerland.", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Component", "Details"],
        [
            ["CT scan (PMCT)", "Multi-slice CT; detects fractures, projectiles, gas, hemorrhage, organ injuries"],
            ["MRI (PMMR)", "Soft tissue detail; brain, spinal cord, cardiac pathology"],
            ["3D surface scan (photogrammetry)", "External injury mapping; wound tracks in 3D"],
            ["CT angiography (PMCTA)", "Injected contrast; detects vascular injuries, heart disease post-mortem"],
            ["Minimally invasive sampling", "Needle biopsy, vitreous aspiration; toxicology, histology, microbiology"],
        ]
    ))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Advantages", "Limitations"],
        [
            ["No religious / cultural objections (non-invasive)", "Expensive equipment and expertise"],
            ["Permanent digital record", "Cannot assess smell, texture, color as well"],
            ["3D reconstruction of wounds/injuries", "Not yet a complete replacement for conventional autopsy"],
            ["Useful in decomposed / mummified bodies", "Gas artifacts may mimic pathology"],
            ["Detects foreign bodies (bullets) precisely", "Limited soft tissue biopsy in some protocols"],
            ["Useful in mass disaster identification", "Not accepted in all jurisdictions for legal purposes"],
        ]
    ))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # Q62 – NEGATIVE AUTOPSY
    # ════════════════════════════════════════════════════════════
    q_block(E, "62", "What is a Negative Autopsy?")
    E.append(Paragraph(
        "A <b>negative autopsy</b> (also called <b>obscure autopsy</b>) is one where careful and complete post-mortem "
        "examination fails to reveal an adequate cause of death by naked eye (gross) examination alone.", BODY_S))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Aspect", "Details"],
        [
            ["Definition", "PM examination + initial investigation does NOT reveal cause of death"],
            ["Common causes", "Functional/metabolic deaths (cardiac arrhythmia, epilepsy, vasovagal, hypoglycemia);\n"
             "Minute structural lesions (coronary spasm); some poisonings (potassium, insulin, succinylcholine);\n"
             "SIDS (sudden infant death syndrome)"],
            ["Management", "Extensive histology; toxicology; microbiology; radiology; genetic testing;\n"
             "Review all clinical history + circumstances"],
            ["Microscopy", "Myocarditis, early infarction, pulmonary microemboli may only be visible microscopically"],
            ["Toxicology", "Volatile poisons, potassium, insulin, ricin may have no gross PM changes"],
            ["Legal significance", "Death certificate still required; 'unascertained' or 'undetermined' cause"],
            ["SIDS", "Most common cause of negative autopsy in infants < 1 year; diagnosis of exclusion"],
        ],
        col_widths=[3.5*cm, PAGE_W-2*MARGIN-3.5*cm]
    ))
    E.append(Spacer(1, 6))
    E.append(Paragraph("<b>FLOWCHART: Approach to Negative Autopsy</b>", BOLD_S))
    E.append(Spacer(1, 4))
    E.append(BW_Flowchart([
        ("COMPLETE PM EXAMINATION\nNo gross cause of death found", "terminal"),
        ("REVIEW: History, circumstances,\nclinical records", "rect"),
        ("HISTOPATHOLOGY:\nHeart, brain, liver, kidney, lungs\n(microscopic examination)", "rect"),
        ("TOXICOLOGY:\nBlood, urine, vitreous, gastric contents\nfor all possible poisons", "rect"),
        ("MICROBIOLOGY:\nBlood culture, CSF, tissue cultures", "rect"),
        ("RADIOLOGY:\nX-ray / CT for missed fractures,\nforeign bodies, gas", "rect"),
        ("GENETIC TESTING:\nChannelopathies (LQTS, Brugada);\nSIDS genetics", "rounded"),
        ("Still no cause found?", "diamond"),
        ("CAUSE: UNDETERMINED\nor UNASCERTAINED\n(Report to Magistrate)", "terminal"),
    ], node_h=34, gap=13))
    E.append(Spacer(1, 10))

    # ════════════════════════════════════════════════════════════
    # SUMMARY TABLE
    # ════════════════════════════════════════════════════════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 2 β€” QUICK REFERENCE SUMMARY", S('sumH', fontSize=13,
        textColor=BLACK, fontName='Helvetica-Bold', spaceAfter=8, alignment=TA_CENTER)))
    E.append(Spacer(1, 4))
    E.append(make_table(
        ["Topic", "Key 1-Liner"],
        [
            ["Inquest", "Police (S.194 BNSS) or Magistrate (S.196 BNSS) inquiry into unnatural death"],
            ["4 Early PM Changes", "Algor Mortis β†’ Livor Mortis β†’ Rigor Mortis β†’ Corneal changes"],
            ["Decomposition in water (1 wk)", "Maceration, washerwoman's hands, bloating, face unrecognizable; adipocere starts wk 2–3"],
            ["Casper's Dictum", "Air = 2Γ— water = 8Γ— buried earth in decomposition rate"],
            ["Exhumation", "Digging out buried body; order by Magistrate; no time limit; PM at site"],
            ["Exhumation indications", "Criminal: homicide, poisoning, criminal abortion; Civil: insurance, identity, negligence"],
            ["Viscera preservation", "Sat. NaCl; separate labeled glass jars; NEVER formalin; chain of custody"],
            ["Key organs preserved", "Stomach+contents, liver, kidney, blood, urine, vitreous, brain, lungs, hair"],
            ["Organ removal methods", "Virchow (individual), Rokitansky (partial), Letulle (en masse), Ghon (groups)"],
            ["Hydrostatic test", "Lungs float = breathed air = liveborn; lungs sink = stillborn; false+ in putrefaction"],
            ["Virtual autopsy", "CT + MRI + 3D scan; non-invasive; permanent record; expensive; not full replacement"],
            ["Negative autopsy", "No gross cause found; need histology + toxicology + microbiology + genetics"],
            ["Sample collection", "Label, seal, chain of custody; formalin for histology only"],
        ],
        col_widths=[4*cm, PAGE_W-2*MARGIN-4*cm]
    ))

    doc.build(E, onFirstPage=on_page, onLaterPages=on_page)
    print(f"SUCCESS: {OUTPUT_PATH}")

if __name__ == "__main__":
    build()
!

Failed to create session: unauthorized: authentication failed: Bearer token is invalid

We encountered an error while processing your request. Please try again or reach out to us for help.

βœ‰οΈhi@orris.care

Start again but not from starting ok

Running Command

ls /home/daytona/workspace/forensic-medicine-pdfs/

Writing File

~/forensic-medicine-pdfs/chapter2_gen.py

#!/usr/bin/env python3
"""Chapter 2: Post-Mortem Examination & Autopsy - B&W Print-Friendly"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
    TableStyle, PageBreak, KeepTogether)
from reportlab.platypus.flowables import Flowable

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter2_PostMortem_Autopsy.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK = colors.black; WHITE = colors.white
GL = colors.HexColor("#d6d6d6"); GVL = colors.HexColor("#f0f0f0")
GD = colors.HexColor("#555555"); GVD = colors.HexColor("#1a1a1a")

def S(n,**k): return ParagraphStyle(n,parent=getSampleStyleSheet()['Normal'],**k)
TITLE=S('Ti',fontSize=22,textColor=WHITE,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=28)
CHAP=S('Ch',fontSize=15,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER)
REF=S('Re',fontSize=8,textColor=GD,fontName='Helvetica-Oblique',alignment=TA_CENTER)
QS=S('Qs',fontSize=12,textColor=WHITE,fontName='Helvetica-Bold',leading=17,leftIndent=8)
BODY=S('Bo',fontSize=10,textColor=GVD,leading=15,spaceAfter=3,fontName='Helvetica',alignment=TA_JUSTIFY)
BOLD=S('Bl',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica-Bold')
NOTE=S('No',fontSize=9,textColor=GD,fontName='Helvetica-Oblique',leading=13,leftIndent=10)
TH=S('TH',fontSize=8.5,textColor=WHITE,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=12)
TC=S('TC',fontSize=8.5,textColor=GVD,fontName='Helvetica',leading=12,alignment=TA_LEFT)
TCC=S('TCC',fontSize=8.5,textColor=GVD,fontName='Helvetica',leading=12,alignment=TA_CENTER)

def hdr(canv,doc):
    canv.saveState()
    canv.setFillColor(BLACK); canv.rect(0,PAGE_H-1.1*cm,PAGE_W,1.1*cm,fill=1,stroke=0)
    canv.setFillColor(WHITE); canv.setFont('Helvetica-Bold',9)
    canv.drawString(M,PAGE_H-0.72*cm,"FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica',8)
    canv.drawRightString(PAGE_W-M,PAGE_H-0.72*cm,"Chapter 2: Post-Mortem Examination & Autopsy")
    canv.setFillColor(BLACK); canv.rect(0,0,PAGE_W,0.9*cm,fill=1,stroke=0)
    canv.setFillColor(WHITE); canv.setFont('Helvetica',8)
    canv.drawString(M,0.32*cm,"Ref: KS Narayan Reddy 36th Ed | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M,0.32*cm,f"Page {doc.page}")
    canv.restoreState()

def qb(E,num,txt):
    t=Table([[Paragraph(f"Q.{num}  {txt}",QS)]],colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),BLACK),
        ('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),('RIGHTPADDING',(0,0),(-1,-1),10)]))
    E.append(KeepTogether([t])); E.append(Spacer(1,5))

def tbl(headers,rows,cw=None,stripe=True):
    avail=PAGE_W-2*M-0.2*cm
    if not cw: cw=[avail/len(headers)]*len(headers)
    data=[[Paragraph(h,TH) for h in headers]]
    for r in rows: data.append([Paragraph(str(c),TC) for c in r])
    t=Table(data,colWidths=cw,repeatRows=1)
    cmds=[('BACKGROUND',(0,0),(-1,0),BLACK),('TEXTCOLOR',(0,0),(-1,0),WHITE),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),('GRID',(0,0),(-1,-1),0.4,GL),
        ('VALIGN',(0,0),(-1,-1),'TOP'),('TOPPADDING',(0,0),(-1,-1),4),
        ('BOTTOMPADDING',(0,0),(-1,-1),4),('LEFTPADDING',(0,0),(-1,-1),5),
        ('RIGHTPADDING',(0,0),(-1,-1),5)]
    if stripe:
        for i in range(2,len(data),2): cmds.append(('BACKGROUND',(0,i),(-1,i),GVL))
    t.setStyle(TableStyle(cmds)); return t

class FC(Flowable):
    def __init__(self,nodes,width=None,nh=34,gap=15):
        super().__init__()
        self.nodes=nodes; self.nw=width or (PAGE_W-2*M-0.5*cm)
        self.nh=nh; self.gap=gap
        self.width=self.nw; self.height=len(nodes)*(nh+gap)-gap+20
    def wrap(self,aW,aH): return self.width,self.height
    def draw(self):
        c=self.canv; y=self.height-10
        nw,nh,gap=self.nw,self.nh,self.gap; cx=nw/2
        for i,(text,shape) in enumerate(self.nodes):
            top=y-nh; mid=y-nh/2
            c.setStrokeColor(BLACK); c.setLineWidth(1.2)
            if shape=='terminal':
                c.setFillColor(BLACK)
                c.roundRect(cx-nw*.35,top,nw*.7,nh,nh/2,fill=1,stroke=1)
            elif shape=='diamond':
                c.setFillColor(GVL)
                p=c.beginPath(); p.moveTo(cx,y); p.lineTo(cx+nw*.40,mid)
                p.lineTo(cx,top); p.lineTo(cx-nw*.40,mid); p.close()
                c.drawPath(p,fill=1,stroke=1)
            elif shape=='rounded':
                c.setFillColor(GVL)
                c.roundRect(cx-nw*.44,top,nw*.88,nh,8,fill=1,stroke=1)
            else:
                c.setFillColor(GVL)
                c.rect(cx-nw*.44,top,nw*.88,nh,fill=1,stroke=1)
            c.setFillColor(WHITE if shape=='terminal' else BLACK)
            c.setFont('Helvetica-Bold' if shape in ('terminal','diamond') else 'Helvetica',8.5)
            lines=text.split('\n'); lh=11
            ty=mid+len(lines)*lh/2-lh*.7
            for ln in lines: c.drawCentredString(cx,ty,ln); ty-=lh
            if i<len(self.nodes)-1:
                ay=top-gap; c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx,top,cx,ay+6); c.setFillColor(BLACK)
                p=c.beginPath(); p.moveTo(cx,ay); p.lineTo(cx-5,ay+8); p.lineTo(cx+5,ay+8)
                p.close(); c.drawPath(p,fill=1,stroke=0)
            y=top-gap

def build():
    doc=SimpleDocTemplate(OUTPUT,pagesize=A4,leftMargin=M,rightMargin=M,
        topMargin=1.5*cm,bottomMargin=1.3*cm,
        title="Chapter 2 – Post-Mortem Examination & Autopsy")
    E=[]
    # COVER
    E.append(Spacer(1,1.5*cm))
    cv=Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY",TITLE)]],colWidths=[PAGE_W-2*M])
    cv.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),BLACK),
        ('TOPPADDING',(0,0),(-1,-1),18),('BOTTOMPADDING',(0,0),(-1,-1),18)]))
    E.append(cv); E.append(Spacer(1,.4*cm))
    cb=Table([[Paragraph("CHAPTER 2",CHAP)]],colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2=Table([[Paragraph("Post-Mortem Examination &amp; Forensic Autopsy",
        S('tb',fontSize=18,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.4*cm))
    rb=Table([[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed",REF)]],
        colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),('BACKGROUND',(0,0),(-1,-1),GVL),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))
    # TOC
    E.append(Paragraph("CHAPTER CONTENTS",S('toch',fontSize=11,textColor=BLACK,
        fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["151","What is an Inquest?"],
        ["38","4 Types of Early Post-Mortem Changes"],
        ["10","Decomposition Changes in Drowned Body (1 week)"],
        ["32 / 81","Exhumation – Indications, Authorization & Procedure"],
        ["40 / 85","Viscera Preservation for Chemical Analysis in Poisoning"],
        ["140","Methods of Organ Removal at Post-Mortem"],
        ["154","Protocols for Sample Collection during Autopsy"],
        ["87","Hydrostatic Test (Docimasia Pulmonaris)"],
        ["41","Virtual Autopsy (Virtopsy)"],
        ["62","Negative Autopsy"],
        ["171","Shotgun Entry Wound Characteristics at Various Ranges"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # Q151 INQUEST
    qb(E,"151","What is an Inquest?")
    E.append(Paragraph("An <b>inquest</b> is an official inquiry into the cause and manner of a sudden, unnatural, or suspicious death, conducted by a legally authorized person.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Type","Conducted By","Legal Provision","Cases Covered"],[
        ["Police Inquest","Sub-Inspector of Police or above","S.194, BNSS\n(old S.174 CrPC)","Sudden/suspicious/unnatural deaths; accidental, suicidal, homicidal"],
        ["Magistrate's Inquest","Executive Magistrate","S.196, BNSS\n(old S.176 CrPC)","Deaths in police custody; mass disasters; exhumation orders"],
        ["Coroner's Inquest","Coroner (judicial officer)","Coroner's Act\n(Mumbai & Chennai only)","Unnatural deaths; jury of 5–23; delivers verdict"],
    ],cw=[3*cm,3.5*cm,3*cm,PAGE_W-2*M-9.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Aspect of Police Inquest","Details"],[
        ["Purpose","To determine cause of death; preserve evidence; identify deceased"],
        ["Doctor's role","Perform PM examination; submit ML report to IO"],
        ["Inquest report","Description of body, injuries, apparent cause of death"],
        ["Panchanama","Witnessed by panchas (panchanama); details of scene, body position"],
        ["PM mandatory?","IO decides; mandatory in custody deaths and suspicious cases"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Inquest Procedure</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("SUDDEN / UNNATURAL / SUSPICIOUS DEATH\nreported to Police","terminal"),
        ("Sub-Inspector proceeds to scene\n(Police Inquest – S.194 BNSS)","rect"),
        ("Scene preserved; body identified;\ncircumstances recorded","rect"),
        ("Inquest Panchanama prepared\n(in presence of panchas/witnesses)","rounded"),
        ("Is PM examination needed?","diamond"),
        ("Medical Officer performs PM;\nsubmits ML Report to IO","rect"),
        ("Death in POLICE CUSTODY\nor MASS DISASTER?","diamond"),
        ("MAGISTRATE'S INQUEST\n(S.196 BNSS) – Higher inquiry","terminal"),
    ],nh=35,gap=13))
    E.append(Spacer(1,10))

    # Q38 EARLY PM CHANGES
    qb(E,"38","Enumerate 4 Types of Early Post-Mortem Changes")
    E.append(Paragraph("Post-mortem changes begin immediately after death. The 4 major <b>early</b> post-mortem changes are:",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["#","Early PM Change","Onset","Key Features"],[
        ["1","<b>Algor Mortis</b>\n(Cooling of the body)","Begins immediately;\n~1Β°C/hr for first 12 hrs","Body cools to ambient temp; Henssge nomogram for TSD;\naffected by clothing, fat, environment"],
        ["2","<b>Livor Mortis</b>\n(Post-mortem staining / Hypostasis)","Starts 30 min–2 hrs;\nfixed by 6–12 hrs","Blood gravitates to dependent areas; pink-purple color;\nnot on pressure points; cherry-red in CO poisoning"],
        ["3","<b>Rigor Mortis</b>","Starts 2–6 hrs;\ncomplete 12 hrs;\ndisappears 24–48 hrs","ATP depletion β†’ actin-myosin cross-bridges;\nall muscles simultaneously; small muscles apparent first"],
        ["4","<b>Tache Noire / Corneal clouding</b>","Tache noire: hours;\nCorneal clouding: 2–3 hrs","Tache noire = brown-black band on sclera (eyes open);\nCorneal clouding = whitish opacity; iris detail lost"],
    ],cw=[.7*cm,3.5*cm,3*cm,PAGE_W-2*M-7.2*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Sequence of Early Post-Mortem Changes</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("DEATH OCCURS","terminal"),
        ("IMMEDIATE: Primary relaxation;\nTache Noire (if eyes open)","rect"),
        ("30 min – 2 hrs:\nLIVOR MORTIS begins\n(dependent discoloration)","rect"),
        ("2 – 6 hrs:\nRIGOR MORTIS starts;\nAlgor Mortis ongoing (~1Β°C/hr)","rect"),
        ("6 – 12 hrs:\nLivor FIXED; Rigor spreading;\nCorneal clouding complete","rect"),
        ("12 hrs: Rigor FULLY ESTABLISHED\n(all muscles stiff)","rounded"),
        ("24 – 48 hrs: Rigor PASSES OFF\n(autolysis of actin-myosin)","rounded"),
        ("LATE CHANGES BEGIN:\nPutrefaction / Decomposition","terminal"),
    ],nh=35,gap=13))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q10 DECOMPOSITION IN DROWNED BODY
    qb(E,"10","Body Recovered from River 1 Week After Drowning – Decomposition Changes")
    E.append(Paragraph("<b>Casper's Dictum:</b> 'In open air, a body decomposes twice as fast as in water, and eight times as fast as when buried in earth.' After 1 week in water:",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Time in Water","Expected Changes"],[
        ["Day 1–2","Pallor; livor mortis washes out; skin begins to wrinkle;\nputrefaction discoloration (greenish abdomen in warm water)"],
        ["Day 3–4","Skin maceration ('washerwoman's hands/feet');\nskin slippage; abdominal bloating; marbling of veins begins"],
        ["Day 5–7\n(AT RECOVERY)","Face: bloated, greenish-black, unrecognizable;\nWasherwoman's hands/feet prominent;\nAbdomen: tympanitic, marbling;\nBody may float due to gas; foul putrefactive smell;\nEyes sunken; tongue may protrude;\nAdipose tissue saponification beginning"],
        ["Week 2–3","Adipocere formation (waxy-soapy fat);\nhair and nails loosen; skin sheets peel off"],
        ["Month 1–3","Extensive adipocere; skeletonization begins"],
    ],cw=[3*cm,PAGE_W-2*M-3*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Specific Feature","Details"],[
        ["Adipocere","Saponification of body fat; waxy-white-yellow-grey; protects body from further decomposition;\nmore common in water/moist environments"],
        ["Skin maceration","White-grey, wrinkled, sodden; separates from dermis; fingerprinting difficult"],
        ["Skin slip","Epidermis peels in gloves/sheets; useful for fingerprinting if handled carefully"],
        ["Putrefaction order","Abdomen β†’ Face/Neck β†’ Chest β†’ Limbs"],
        ["Diatoms (algae)","Found in bone marrow/organs confirms ante-mortem drowning even in decomposed body"],
        ["Identification","Clothing, jewelry, dental records, DNA from adipocere; fingerprint from peeled glove"],
        ["Cause of death"],["Even with decomposition: emphysema aquosum, froth, diatoms help confirm drowning"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Decomposition Sequence in Water</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("BODY ENTERS WATER\n(Drowning death)","terminal"),
        ("Day 1–2: Pallor; livor washes out;\nputrefaction begins (warm water)","rect"),
        ("Day 3–4: Maceration;\nWasherwoman's hands/feet;\nbloating starts","rect"),
        ("Day 5–7 (RECOVERY):\nFace bloated/unrecognizable;\nAdbomen tympanitic; foul smell;\nadipose saponification starts","rect"),
        ("Week 2–3:\nADIPOCERE fully forming;\nhair/nails loosening","rect"),
        ("Month 1–3:\nSkeletonization begins","rounded"),
        ("CASPER'S DICTUM:\nWater = Β½ rate of Air\nWater = β…› rate of Earth (buried)","terminal"),
    ],nh=37,gap=13))
    E.append(Spacer(1,10))

    # Q32/81 EXHUMATION
    qb(E,"32 / 81","Exhumation – Definition, Indications, Authorization & Procedure")
    E.append(Paragraph("<b>Definition (KS Narayan Reddy, 36th Ed):</b> Exhumation is the digging out of an already buried body legally from the grave. (Burial = inhumation). <b>No time limit for exhumation in India.</b>",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Authorization","Written order of Executive/Judicial Magistrate (S.196(4), BNSS)"],
        ["Conducted by","Medical Officer + Magistrate + Police Officer; relatives may be present (S.196(5) BNSS)"],
        ["PM location","Usually performed at site of exhumation"],
        ["Time limit","NONE in India"],
        ["Cremation cases","Exhumation not applicable; ash/bone fragments may be examined"],
    ]))
    E.append(Spacer(1,5))
    E.append(tbl(["CRIMINAL Indications","CIVIL Indications"],[
        ["Homicide disguised as natural/suicidal death","Accidental death / insurance claim"],
        ["Suspected poisoning","Workmen's compensation claim"],
        ["Death from criminal abortion","Professional negligence liability"],
        ["Criminal negligence","Survivorship and inheritance disputes"],
        ["Improper/absent first PM examination","Disputed identity of deceased"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>STEP-BY-STEP PROCEDURE:</b>",BOLD))
    E.append(tbl(["Step","Action"],[
        ["1","Obtain details: deceased identity, clothes worn at burial, time of burial"],
        ["2","Proceed to grave with Magistrate + Police Officer; inform relatives (S.196(5) BNSS)"],
        ["3","Positively identify grave: headstone, grave marker, GPS/landmarks, distance from permanent objects"],
        ["4","Conduct in natural daylight; screen off area from public spectators"],
        ["5","Excavate 10–15 cm at a time; note soil condition, water content, vegetable growth"],
        ["6","Measure grave depth: surface to skull; surface to feet"],
        ["7","Expose body with soft brush/whisk broom (never hard tools)"],
        ["8","Photograph body in situ; diagram body position (face up/down, limb position)"],
        ["9","Collect soil samples from all sides (toxicology control/comparison)"],
        ["10","Transfer body for PM examination; collect viscera and samples"],
        ["11","Identify body via relatives/dental records/DNA if decomposed"],
        ["12","Reburial after PM; supervised by Magistrate"],
    ],cw=[1*cm,PAGE_W-2*M-1*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Exhumation Process</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("REQUEST for Exhumation\n(criminal/civil reason)","terminal"),
        ("MAGISTRATE issues\nWRITTEN ORDER (S.196(4) BNSS)","rect"),
        ("Assemble: Medical Officer +\nMagistrate + Police Officer","rect"),
        ("IDENTIFY GRAVE positively\n(headstone, landmark, GPS)","diamond"),
        ("Excavate 10–15 cm at a time;\nnote soil, water, vegetation","rect"),
        ("EXPOSE BODY with soft brush;\nPhotograph in situ; draw diagram","rect"),
        ("Collect SOIL SAMPLES\n(toxicology control)","rounded"),
        ("POST-MORTEM at site;\ncollect viscera/specimens","rect"),
        ("SEAL samples; Chain of Custody\nto Magistrate / IO","rounded"),
        ("REBURIAL under\nMagistrate's supervision","terminal"),
    ],nh=34,gap=13))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q40/85 VISCERA PRESERVATION
    qb(E,"40 / 85","Viscera Preservation for Chemical Analysis in Suspected Poisoning")
    E.append(Paragraph("During PM in suspected poisoning, specific organs/fluids are collected in correct preservatives in separate labeled glass jars and sent to the Forensic Science Laboratory (FSL).",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Organ / Sample","Amount","Preservative","Purpose"],[
        ["Stomach + contents","Entire","Saturated NaCl OR\nno preservative","Identify poison; undigested tablets/food"],
        ["Small intestine + contents\n(first 20–30 cm from pylorus)","Section","Saturated NaCl","Absorbing zone; drug residues"],
        ["Liver","~500 g\n(1/3 with, 2/3 without preservative)","Saturated NaCl","Main toxicology organ; metabolizes poison"],
        ["Kidney","One whole kidney","Saturated NaCl","Excretion; heavy metals (arsenic, lead)"],
        ["Blood (heart)","50–100 mL","Fluoride-oxalate (alcohol/CO);\nplain (toxicology);\nEDTA (DNA)","Toxicology screen; blood alcohol; DNA"],
        ["Urine","Entire bladder","Fluoride or no preservative","Drug metabolites; alcohol; glucose"],
        ["Brain","~500 g","Saturated NaCl","CNS depressants; OP compounds; volatile poisons"],
        ["Lungs","Portion","Saturated NaCl","Volatile poisons (chloroform, HCN, alcohol)"],
        ["Vitreous humor","Both eyes","No preservative\n(sealed syringe/vial)","Alcohol (most reliable); glucose, K+, electrolytes"],
        ["Bone (femur)","Section","Dry / no preservative","Arsenic and heavy metals (even years later)"],
        ["Hair & Nails","Clippings","Dry, sealed bag","Chronic arsenic/heavy metal poisoning"],
        ["Skin (injection site)","Excised piece","Formaldehyde/NaCl","Injection marks; local poison deposit"],
    ],cw=[3.5*cm,2*cm,3*cm,PAGE_W-2*M-8.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["RULE","Details"],[
        ["Preservative of choice","Saturated NaCl (common salt) – does NOT interfere with chemical tests"],
        ["NEVER use FORMALIN","Formalin destroys organic poisons: alkaloids, barbiturates, alcohol, most drugs"],
        ["Separate containers","Each organ in separate wide-mouth airtight glass jar"],
        ["Labeling","Date, deceased name, case no., organ, preservative, doctor's signature + seal"],
        ["Chain of custody","Sealed jars handed to IO with receipt; seal must not be broken until FSL"],
        ["Blank control jar","Empty jar with only preservative sent along (to rule out preservative contamination)"],
        ["Exhumation cases","Soil sample also sent (to check background arsenic levels in soil)"],
        ["CO poisoning","Blood in fluoride-oxalate; sealed cardiac blood sample"],
        ["Alcohol cases","Vitreous + blood in fluoride-oxalate; urine unpreserved or fluoride"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Viscera Preservation Protocol</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("SUSPECTED POISONING\nPM commenced","terminal"),
        ("COLLECT viscera:\nStomach, S.Intestine, Liver,\nKidney, Brain, Lungs","rect"),
        ("COLLECT fluids:\nBlood (heart), Urine,\nVitreous humor","rect"),
        ("SPECIAL samples:\nHair, Nails, Bone,\nSkin at injection site","rect"),
        ("Correct PRESERVATIVE:\nSat. NaCl (organs)\nFluoride-oxalate (blood/urine)\nNO FORMALIN","rounded"),
        ("SEPARATE labeled\nairtight glass jars","rect"),
        ("Include BLANK CONTROL JAR\n(preservative only)","diamond"),
        ("SEAL each jar;\nDoctor signs across seal","rect"),
        ("Hand to IO with FORWARDING LETTER\n+ RECEIPT (Chain of Custody)","terminal"),
    ],nh=36,gap=13))
    E.append(Spacer(1,10))

    # Q140 ORGAN REMOVAL METHODS
    qb(E,"140","Methods of Organ Removal at Post-Mortem Examination")
    E.append(Paragraph("Standard PM incision: <b>Y-shaped</b> or <b>Modified Y-shaped</b>. After opening body cavities, organs are removed by one of these established techniques:",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Technique","Description","Advantage","Use"],[
        ["<b>Virchow</b>\n(Individual removal)","Each organ removed and examined separately, in sequence","Detailed individual organ exam;\nmost thorough","Standard forensic autopsy; most widely used"],
        ["<b>Rokitansky</b>\n(Partial / in situ dissection)","Organs partially examined in situ before removal; connections partly maintained","Preserves organ relationships;\ngood anatomical display","Teaching; traditional European method"],
        ["<b>Letulle</b>\n(En masse removal)","All organs removed as single en bloc mass; separated on dissection table","Rapid; excellent for vascular path;\npreserves natural connections","Trauma; vascular pathology; large PM load"],
        ["<b>Ghon</b>\n(Modified en masse – groups)","Organs removed in groups: chest together, abdomen together","Compromise; good for paediatrics","Paediatric PM; teaching"],
    ],cw=[3*cm,4.5*cm,3.2*cm,PAGE_W-2*M-10.7*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Incision","Path","Use"],[
        ["Y-shaped","Shoulders β†’ xiphisternum β†’ pubis","Standard medico-legal autopsy"],
        ["Modified Y-shaped","Mastoid β†’ shoulders β†’ xiphisternum β†’ pubis","When neck dissection needed (hanging, strangulation)"],
        ["I-shaped (midline)","Single cut: chin β†’ pubis","Less common"],
        ["T-shaped","Horizontal shoulders + vertical midline","Alternative to Y"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Standard Organ Removal Sequence (Virchow Technique)</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("EXTERNAL EXAMINATION complete;\nphotographs taken","terminal"),
        ("Y / Modified Y INCISION\n(skin + subcutaneous + muscle)","rect"),
        ("CHEST: Rib cage opened;\nthoracic cavity examined","rect"),
        ("HEART & LUNGS removed;\nexamined + weighed","rect"),
        ("ABDOMEN: Peritoneal cavity\nexamined; organs in situ first","rect"),
        ("LIVER, SPLEEN, KIDNEYS,\nSTOMACH, INTESTINES removed","rect"),
        ("BRAIN: Skull cap removed;\ndura examined; brain removed","rect"),
        ("All organs: EXAMINED,\nWEIGHED, SECTIONED;\nsamples collected","rounded"),
        ("PM REPORT drafted;\nviscera preserved if poisoning","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q154 SAMPLE COLLECTION
    qb(E,"154","Protocols for Sample Collection During Autopsy")
    E.append(tbl(["Sample","Collection Method","Container/Preservative","Tests"],[
        ["Blood (cardiac)","Syringe from right heart before opening","Fluoride-oxalate (alcohol/CO);\nplain (tox); EDTA (DNA)","Toxicology, DNA, blood group, culture"],
        ["Urine","Syringe via bladder puncture","Fluoride-oxalate or plain","Drug metabolites, alcohol, ketones"],
        ["Vitreous humor","25G needle lateral canthus; gentle aspiration","Plain sealed syringe/vial","Alcohol (reliable), glucose, K+, urea"],
        ["Bile","Gall bladder aspiration","Plain vial","Opioids, drug metabolites"],
        ["CSF","Cisterna magna needle/lumbar","Plain vial","Infection, drugs"],
        ["Gastric contents","Entire stomach ligated+removed","Wide-mouth glass jar; Sat. NaCl","Poison ID, food contents, tablets"],
        ["Tissue histology","Sections: heart, lung, liver, kidney, brain","10% FORMALIN only","Microscopic pathology"],
        ["Microbiology","Heart blood, spleen, CSF (sterile)","Sterile no-preservative containers","Culture + sensitivity"],
        ["Hair/Nails","Cut from scalp root + fingertips","Sealed dry envelope","Chronic toxicology, DNA"],
        ["Swabs (sexual assault)","Vaginal/anal/oral","Sterile dry swabs","DNA, sperm, STI"],
        ["Bone marrow","Section of femur or rib","Sealed dry","DNA (decomposed body); heavy metals"],
        ["Soil (exhumation only)","4 sides around body","Sealed labeled bags","Background arsenic/toxin levels"],
    ],cw=[2.5*cm,3.5*cm,3.3*cm,PAGE_W-2*M-9.3*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Chain of Custody Step","Action"],[
        ["1","Label each container: date, case no., name, organ/fluid, preservative, doctor's name+designation"],
        ["2","Doctor seals container with wax/tape; signs ACROSS the seal (tampering evident)"],
        ["3","Prepare forwarding letter listing all samples, tests requested, and case details"],
        ["4","Hand to Investigating Officer with signed acknowledgment receipt"],
        ["5","IO sends under seal to FSL; FSL verifies seals intact before opening"],
        ["6","Any broken seal = evidence may be challenged/rejected in court"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(Spacer(1,10))

    # Q87 HYDROSTATIC TEST
    qb(E,"87","What is the Hydrostatic Test (Docimasia Pulmonaris)?")
    E.append(Paragraph("<b>Hydrostatic test</b> (Docimasia Pulmonaris / lung float test) determines whether a newborn infant breathed air before death (i.e., was liveborn vs stillborn).",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Principle","Breathed lungs contain air β†’ FLOAT on water;\nUnbreathed lungs = airless + dense β†’ SINK"],
        ["Procedure","1. Remove lungs intact (without cutting)\n2. Place entire lung mass in water\n3. Test each lobe separately\n4. Cut small pieces; squeeze underwater β†’ look for air bubbles\n5. Press on blotter paper; squeaking/crepitation = air present"],
        ["LIVEBORN result","Lungs FLOAT β†’ air present β†’ child breathed"],
        ["STILLBORN result","Lungs SINK β†’ airless β†’ child did not breathe"],
        ["Breslau's 2nd Life Test\n(Stomach-Bowel test)","Air swallowed with first breath; stomach/intestines may float;\nfloating stomach = confirms breathing + swallowing"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["False POSITIVE (floats but not breathed)","False NEGATIVE (sinks but breathed)"],[
        ["Putrefaction gas in lung tissue","Severe pneumonia/atelectasis"],
        ["Artificial respiration on dead neonate","Premature infant with RDS (hyaline membrane)"],
        ["Post-mortem decomposition gases","Macerated stillbirth with fluid-filled lungs"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Hydrostatic Test</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("NEWBORN found dead –\nassess LIVEBORN vs STILLBORN","terminal"),
        ("Remove LUNGS intact\n(no cutting)","rect"),
        ("Place in CONTAINER of WATER","diamond"),
        ("Do lungs FLOAT?","diamond"),
        ("YES → Air present\n→ LIVEBORN (breathed air)","rounded"),
        ("NO → Airless\n→ STILLBIRTH suspected","rounded"),
        ("Cut small pieces;\nSqueeze UNDERWATER\n(bubbles = air = breathed)","rect"),
        ("Test STOMACH + BOWEL\n(Breslau's 2nd Life Test)","rect"),
        ("CONCLUSION:\nLiveborn or Stillborn;\nreport to Magistrate","terminal"),
    ],nh=34,gap=13))
    E.append(Spacer(1,10))

    # Q41 VIRTUAL AUTOPSY
    qb(E,"41","What is Virtual Autopsy (Virtopsy)?")
    E.append(Paragraph("<b>Virtual autopsy (Virtopsy)</b> is a non-invasive/minimally invasive PM technique using advanced imaging (CT, MRI, 3D scanning) + minimally invasive sampling. Developed at Univ. of Bern, Switzerland.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Imaging Component","Details"],[
        ["PMCT (Post-mortem CT)","Multi-slice CT; fractures, projectiles, gas, hemorrhage, organ injuries, skeletal trauma"],
        ["PMMR (Post-mortem MRI)","Soft tissue detail: brain, spinal cord, cardiac pathology; better than CT for soft tissue"],
        ["3D Surface Scan","External injury mapping; wound tracks reconstructed in 3D; documents bruises, abrasions"],
        ["PMCTA (CT Angiography)","Contrast injection; vascular injuries, coronary artery disease, cardiac pathology"],
        ["Minimally Invasive Sampling","Needle biopsy; vitreous aspiration; toxicology, histology, microbiology without full dissection"],
    ]))
    E.append(Spacer(1,5))
    E.append(tbl(["Advantages","Limitations"],[
        ["No religious/cultural objections (non-invasive)","Expensive equipment and expertise needed"],
        ["Permanent 3D digital record; shareable","Cannot assess smell, texture, consistency as well"],
        ["Precise 3D wound/fracture reconstruction","Not full replacement for conventional autopsy"],
        ["Useful in decomposed/mummified/burned bodies","Gas artifacts may mimic pathology on scan"],
        ["Finds foreign bodies (bullets) precisely","Limited soft-tissue biopsy in some protocols"],
        ["Useful in mass disaster victim identification","Not universally accepted for legal purposes"],
    ]))
    E.append(Spacer(1,10))

    # Q62 NEGATIVE AUTOPSY
    qb(E,"62","What is a Negative Autopsy?")
    E.append(Paragraph("A <b>negative (obscure) autopsy</b> is one where complete and thorough PM examination fails to reveal an adequate cause of death by gross (naked eye) examination alone.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Definition","PM + initial investigations do NOT reveal cause of death grossly"],
        ["Common causes","Cardiac arrhythmia (no structural lesion); epilepsy; vasovagal syncope;\nhypoglycemia; SIDS; some poisonings (KCl, insulin, succinylcholine, potassium)"],
        ["Management","Extensive histology + toxicology + microbiology + radiology + genetics"],
        ["Histology reveals","Myocarditis; early MI; pulmonary microemboli; fatty liver; CNS changes"],
        ["Toxicology","Volatile poisons (chloroform, HCN); potassium; insulin; ricin; novel drugs"],
        ["SIDS","Most common cause in infants < 1 year; diagnosis of absolute exclusion"],
        ["Legal outcome","'Cause of death: Unascertained/Undetermined' – reported to Magistrate"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Approach to Negative Autopsy</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("COMPLETE PM EXAMINATION:\nNo gross cause of death found","terminal"),
        ("Review: History, circumstances,\nclinical records, medications","rect"),
        ("HISTOPATHOLOGY:\nHeart, brain, liver, kidney, lungs\n(microscopy sections)","rect"),
        ("TOXICOLOGY:\nBlood, urine, vitreous, bile,\ngastric contents (full screen)","rect"),
        ("MICROBIOLOGY:\nBlood culture, CSF, tissue cultures","rect"),
        ("RADIOLOGY:\nCT / X-ray (missed fractures,\nforeign bodies, gas)","rect"),
        ("GENETIC TESTING:\nChannelopathies (LQTS, Brugada);\nSIDS panel","rounded"),
        ("Still no cause identified?","diamond"),
        ("CAUSE: UNDETERMINED\nReport to Magistrate\nInquest proceeds","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))

    # Q171 SHOTGUN ENTRY WOUNDS
    qb(E,"171","Characteristics of Entry Wounds Due to Shotgun at Various Ranges")
    E.append(Paragraph("A shotgun fires multiple pellets (shot) from a smoothbore barrel. The pattern and appearance of entry wounds changes dramatically with distance.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Range","Wound Appearance","Special Features"],[
        ["Contact\n(0 cm)","Single wound = barrel diameter;\nstar-shaped/cruciform tears;\ngas entry into tissues","Muzzle contusion ring; extensive burning;\ngas dissects tissues; stellate tear from gas; soot inside wound"],
        ["Close range\n(< 15 cm)","Single oval/circular wound;\nstill larger than barrel","Powder tattooing; scorching; soot deposits;\nwad mark if wad present; no pellet scatter"],
        ["Intermediate\n(15–60 cm)","Mainly single central wound with\nsatellite pellet holes at margins","'Rat hole' or 'cookie cutter' appearance;\ngrease/dirt collar; wad mark at 30–60 cm"],
        ["Long range\n(> 60 cm / 2 feet)","Multiple separate pellet holes;\nscatter pattern widens","Individual 4–6 mm holes;\nno central mass wound; wad falls before body;\nborder 'scalloped'; no burning or soot"],
        ["Extreme range\n(> 40 yards)","Pellets may not penetrate;\nonly superficial wounds or bruises","Only 1–2 pellets may enter; rest lodged in skin or bounce off"],
    ],cw=[2.5*cm,5*cm,PAGE_W-2*M-7.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Feature","Diagnostic Value"],[
        ["Soot / blackening","Contact or very close range"],
        ["Powder tattooing (stippling)","Intermediate range (< 60 cm); cannot be wiped off skin"],
        ["Single 'rat-hole' wound","Range < 60 cm; pellets travel as compact mass"],
        ["Multiple separate holes","Range > 60 cm; pellets scattered"],
        ["Wad mark","Circular bruise/abrasion separate from main wound; helps estimate range"],
        ["Muzzle stamp","Contact: outline of muzzle imprinted on skin"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Shotgun Wound Pattern by Range</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("SHOTGUN FIRED\nPellets leave barrel together","terminal"),
        ("CONTACT (0 cm):\nSingle star-shaped wound;\ngas tears; soot inside;\nburning of edges","rect"),
        ("CLOSE (< 15 cm):\nSingle wound + scorching;\npowder tattooing;\nwad mark possible","rect"),
        ("INTERMEDIATE (15–60 cm):\n'Rat hole' + satellite holes\nat wound margin;\nwad mark separate","rect"),
        ("LONG RANGE (> 60 cm):\nMultiple SEPARATE pellet holes;\nscattered pattern widens;\nno burning or soot","rect"),
        ("EXTREME (> 40 yards):\nPellets may not penetrate;\nsuperficial/absent wounds","rounded"),
        ("RANGE ESTIMATE from:\nSoot + Burning + Tattooing\n+ Pellet scatter pattern","terminal"),
    ],nh=37,gap=13))
    E.append(Spacer(1,10))

    # SUMMARY
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 2 β€” QUICK REFERENCE SUMMARY",S('sh',fontSize=13,textColor=BLACK,
        fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(Spacer(1,4))
    E.append(tbl(["Topic","Key 1-Liner"],[
        ["Inquest","Police (S.194 BNSS) or Magistrate (S.196 BNSS) inquiry into unnatural death"],
        ["4 Early PM Changes","Algor Mortis β†’ Livor Mortis β†’ Rigor Mortis β†’ Tache Noire/Corneal clouding"],
        ["Decomposition in water","Maceration; washerwoman's hands; bloating; adipocere from wk 2–3; Casper's Dictum"],
        ["Casper's Dictum","Air = 2Γ— water; Water = 8Γ— buried earth in decomposition rate"],
        ["Exhumation","Dig out buried body; Magistrate order; no time limit; PM at site"],
        ["Exhumation indications (criminal)","Homicide, poisoning, criminal abortion, criminal negligence, improper PM"],
        ["Viscera preservation","Saturated NaCl; separate jars; NEVER formalin; chain of custody"],
        ["Organ removal","Virchow (individual); Rokitansky (partial in situ); Letulle (en masse); Ghon (groups)"],
        ["Hydrostatic test","Lungs float = liveborn (breathed); sink = stillborn; false+ in putrefaction"],
        ["Virtual autopsy","CT+MRI+3D scan; non-invasive; expensive; not full replacement"],
        ["Negative autopsy","No gross cause β†’ need histology + toxicology + microbiology + genetics"],
        ["Shotgun contact","Single star wound; soot inside; gas tears; burning"],
        ["Shotgun >60 cm","Multiple separate pellet holes; no burning/soot; scatter pattern"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E,onFirstPage=hdr,onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__=="__main__":
    build()
Writing File

~/forensic-medicine-pdfs/chapter3_gen.py

#!/usr/bin/env python3
"""Chapter 3: Thanatology – Death & Post-Mortem Changes - B&W Print-Friendly"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
    TableStyle, PageBreak, KeepTogether)
from reportlab.platypus.flowables import Flowable

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter3_Thanatology.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK=colors.black; WHITE=colors.white
GL=colors.HexColor("#d6d6d6"); GVL=colors.HexColor("#f0f0f0")
GD=colors.HexColor("#555555"); GVD=colors.HexColor("#1a1a1a")

def S(n,**k): return ParagraphStyle(n,parent=getSampleStyleSheet()['Normal'],**k)
TITLE=S('Ti',fontSize=22,textColor=WHITE,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=28)
CHAP=S('Ch',fontSize=15,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER)
REF=S('Re',fontSize=8,textColor=GD,fontName='Helvetica-Oblique',alignment=TA_CENTER)
QS=S('Qs',fontSize=12,textColor=WHITE,fontName='Helvetica-Bold',leading=17,leftIndent=8)
BODY=S('Bo',fontSize=10,textColor=GVD,leading=15,spaceAfter=3,fontName='Helvetica',alignment=TA_JUSTIFY)
BOLD=S('Bl',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica-Bold')
NOTE=S('No',fontSize=9,textColor=GD,fontName='Helvetica-Oblique',leading=13,leftIndent=10)
MNEM=S('Mn',fontSize=10.5,textColor=BLACK,fontName='Helvetica-Bold',leading=15,leftIndent=10)
TH=S('TH',fontSize=8.5,textColor=WHITE,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=12)
TC=S('TC',fontSize=8.5,textColor=GVD,fontName='Helvetica',leading=12,alignment=TA_LEFT)

def hdr(canv,doc):
    canv.saveState()
    canv.setFillColor(BLACK); canv.rect(0,PAGE_H-1.1*cm,PAGE_W,1.1*cm,fill=1,stroke=0)
    canv.setFillColor(WHITE); canv.setFont('Helvetica-Bold',9)
    canv.drawString(M,PAGE_H-0.72*cm,"FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica',8)
    canv.drawRightString(PAGE_W-M,PAGE_H-0.72*cm,"Chapter 3: Thanatology – Death & Post-Mortem Changes")
    canv.setFillColor(BLACK); canv.rect(0,0,PAGE_W,0.9*cm,fill=1,stroke=0)
    canv.setFillColor(WHITE); canv.setFont('Helvetica',8)
    canv.drawString(M,0.32*cm,"Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M,0.32*cm,f"Page {doc.page}")
    canv.restoreState()

def qb(E,num,txt):
    t=Table([[Paragraph(f"Q.{num}  {txt}",QS)]],colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),BLACK),
        ('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),('RIGHTPADDING',(0,0),(-1,-1),10)]))
    E.append(KeepTogether([t])); E.append(Spacer(1,5))

def tbl(headers,rows,cw=None,stripe=True):
    avail=PAGE_W-2*M-0.2*cm
    if not cw: cw=[avail/len(headers)]*len(headers)
    data=[[Paragraph(h,TH) for h in headers]]
    for r in rows: data.append([Paragraph(str(c),TC) for c in r])
    t=Table(data,colWidths=cw,repeatRows=1)
    cmds=[('BACKGROUND',(0,0),(-1,0),BLACK),('TEXTCOLOR',(0,0),(-1,0),WHITE),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),('GRID',(0,0),(-1,-1),0.4,GL),
        ('VALIGN',(0,0),(-1,-1),'TOP'),('TOPPADDING',(0,0),(-1,-1),4),
        ('BOTTOMPADDING',(0,0),(-1,-1),4),('LEFTPADDING',(0,0),(-1,-1),5),
        ('RIGHTPADDING',(0,0),(-1,-1),5)]
    if stripe:
        for i in range(2,len(data),2): cmds.append(('BACKGROUND',(0,i),(-1,i),GVL))
    t.setStyle(TableStyle(cmds)); return t

class FC(Flowable):
    def __init__(self,nodes,width=None,nh=34,gap=15):
        super().__init__()
        self.nodes=nodes; self.nw=width or (PAGE_W-2*M-0.5*cm)
        self.nh=nh; self.gap=gap
        self.width=self.nw; self.height=len(nodes)*(nh+gap)-gap+20
    def wrap(self,aW,aH): return self.width,self.height
    def draw(self):
        c=self.canv; y=self.height-10
        nw,nh,gap=self.nw,self.nh,self.gap; cx=nw/2
        for i,(text,shape) in enumerate(self.nodes):
            top=y-nh; mid=y-nh/2
            c.setStrokeColor(BLACK); c.setLineWidth(1.2)
            if shape=='terminal':
                c.setFillColor(BLACK)
                c.roundRect(cx-nw*.35,top,nw*.7,nh,nh/2,fill=1,stroke=1)
            elif shape=='diamond':
                c.setFillColor(GVL)
                p=c.beginPath(); p.moveTo(cx,y); p.lineTo(cx+nw*.40,mid)
                p.lineTo(cx,top); p.lineTo(cx-nw*.40,mid); p.close()
                c.drawPath(p,fill=1,stroke=1)
            elif shape=='rounded':
                c.setFillColor(GVL)
                c.roundRect(cx-nw*.44,top,nw*.88,nh,8,fill=1,stroke=1)
            else:
                c.setFillColor(GVL)
                c.rect(cx-nw*.44,top,nw*.88,nh,fill=1,stroke=1)
            c.setFillColor(WHITE if shape=='terminal' else BLACK)
            c.setFont('Helvetica-Bold' if shape in('terminal','diamond') else 'Helvetica',8.5)
            lines=text.split('\n'); lh=11
            ty=mid+len(lines)*lh/2-lh*.7
            for ln in lines: c.drawCentredString(cx,ty,ln); ty-=lh
            if i<len(self.nodes)-1:
                ay=top-gap; c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx,top,cx,ay+6); c.setFillColor(BLACK)
                p=c.beginPath(); p.moveTo(cx,ay); p.lineTo(cx-5,ay+8); p.lineTo(cx+5,ay+8)
                p.close(); c.drawPath(p,fill=1,stroke=0)
            y=top-gap

def build():
    doc=SimpleDocTemplate(OUTPUT,pagesize=A4,leftMargin=M,rightMargin=M,
        topMargin=1.5*cm,bottomMargin=1.3*cm,
        title="Chapter 3 – Thanatology: Death & Post-Mortem Changes")
    E=[]
    # COVER
    E.append(Spacer(1,1.5*cm))
    cv=Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY",TITLE)]],colWidths=[PAGE_W-2*M])
    cv.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),BLACK),
        ('TOPPADDING',(0,0),(-1,-1),18),('BOTTOMPADDING',(0,0),(-1,-1),18)]))
    E.append(cv); E.append(Spacer(1,.4*cm))
    cb=Table([[Paragraph("CHAPTER 3",CHAP)]],colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2=Table([[Paragraph("Thanatology – Death &amp; Post-Mortem Changes",
        S('tb',fontSize=18,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.4*cm))
    rb=Table([[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed",REF)]],
        colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),('BACKGROUND',(0,0),(-1,-1),GVL),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))
    E.append(Paragraph("CHAPTER CONTENTS",S('toch',fontSize=11,textColor=BLACK,
        fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["11","Causes of Sudden Death"],
        ["12","Casper's Dictum"],
        ["13","Tache Noire"],
        ["30 / 84 / 89","Suspended Animation"],
        ["34","Differential Diagnosis of Rigor Mortis"],
        ["49","Post-Mortem Caloricity"],
        ["50","Difference Between Artificial Bruise and True Bruise"],
        ["77","Cadaveric Spasm"],
        ["93","Difference Between Rigor Mortis and Cadaveric Spasm"],
        ["130","Late Post-Mortem Changes"],
        ["155","Post-Mortem Staining (Livor Mortis)"],
        ["158","Difference Between Post-Mortem Staining and Bruising"],
        ["33","Brain Stem Death"],
        ["46","Immersion Syndrome"],
        ["55","Cafe Coronary"],
        ["57","Immersion Foot Syndrome (Trench Foot)"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # Q11 SUDDEN DEATH
    qb(E,"11","What Causes Sudden Death?")
    E.append(Paragraph("<b>Sudden death</b> is unexpected death occurring instantaneously or within 24 hours of onset of symptoms, in a person who appeared to be in good health. Most common cause: <b>cardiovascular disease</b>.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["System","Cause","Details"],[
        ["<b>Cardiovascular\n(Most common)</b>","Coronary artery disease (CAD)","Acute MI, coronary thrombosis; #1 cause of sudden death in adults > 35 yrs"],
        ["","Acute cardiac tamponade","Ruptured aortic aneurysm; hemopericardium"],
        ["","Massive pulmonary embolism","Saddle embolus; immediate cardiorespiratory arrest"],
        ["","Hypertensive heart disease","LV failure; hypertensive cerebral hemorrhage"],
        ["","Arrhythmias","VF, complete heart block; no structural lesion (channelopathies: LQTS, Brugada)"],
        ["<b>Respiratory</b>","Pulmonary embolism","DVT source; saddle embolus"],
        ["","Asthma","Status asthmaticus; sudden bronchospasm"],
        ["","Cafe Coronary","Food bolus impacted at larynx; mimics cardiac arrest"],
        ["<b>CNS</b>","Cerebral hemorrhage","Hypertensive; ruptured Berry aneurysm (SAH)"],
        ["","Epilepsy","SUDEP (Sudden Unexpected Death in Epilepsy)"],
        ["","Meningitis / encephalitis","Rapid fulminant course"],
        ["<b>Other</b>","Anaphylaxis","Bee sting, drugs, food allergy"],
        ["","Rupture of ectopic pregnancy","Hemoperitoneum; shock"],
        ["","Ruptured spleen","Trauma or spontaneous (malaria, infective mono)"],
        ["","Diabetic coma/hypoglycemia","Rapid onset; missed diagnosis"],
        ["","Electrolyte disorders","Hyperkalemia β†’ fatal arrhythmia"],
    ],cw=[2.8*cm,3.5*cm,PAGE_W-2*M-6.3*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Approach to Sudden Death Investigation</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("SUDDEN UNEXPECTED DEATH\n(< 24 hrs from onset)","terminal"),
        ("HISTORY: Age, prior illness,\nmedications, circumstances","rect"),
        ("SCENE EXAMINATION:\nposition, drugs, alcohol, trauma","rect"),
        ("POST-MORTEM EXAMINATION\n(complete; all systems)","rect"),
        ("Obvious CAUSE found?\n(MI, hemorrhage, embolism)","diamond"),
        ("HISTOPATHOLOGY:\nearly MI, myocarditis,\narrhythmic changes","rect"),
        ("TOXICOLOGY:\ndrugs, alcohol, poisons","rect"),
        ("GENETICS:\nLQTS, Brugada, CPVT\n(channelopathy panel)","rounded"),
        ("CAUSE OF DEATH\ndetermined / undetermined","terminal"),
    ],nh=34,gap=13))
    E.append(Spacer(1,10))

    # Q12 CASPER'S DICTUM
    qb(E,"12","What is Casper's Dictum?")
    E.append(Paragraph("<b>Casper's Dictum</b> (Johann Ludwig Casper, 1858): States the relative rate of decomposition in different environments.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Environment","Relative Rate","Time to Equivalent Decomposition"],[
        ["Open AIR","Fastest (Γ—8)","1 week in air"],
        ["WATER (immersed)","Intermediate (Γ—4)","2 weeks in water"],
        ["BURIED in earth","Slowest (Γ—1)","8 weeks buried"],
    ]))
    E.append(Spacer(1,4))
    E.append(Paragraph("<b>Rule:</b> 1 week in AIR = 2 weeks in WATER = 8 weeks BURIED",MNEM))
    E.append(Spacer(1,4))
    E.append(tbl(["Factor","Effect on Decomposition Rate"],[
        ["High temperature","Accelerates (bacteria, insects proliferate)"],
        ["Moisture/humidity","Accelerates putrefaction"],
        ["Water immersion","Slows; prevents insect access; promotes adipocere"],
        ["Burial (deep)","Slowest; insect access blocked; cold soil slows bacteria"],
        ["Trauma/wounds","Accelerates (entry for insects and bacteria)"],
        ["Adiposity","Slows (less surface area; adipocere forms)"],
        ["Clothing","Slows (partial insulation from environment)"],
        ["Embalming","Greatly slows"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>Medico-legal Importance:</b> Helps estimate post-mortem interval (PMI) / time since death when found in specific environments.",NOTE))
    E.append(Spacer(1,10))

    # Q13 TACHE NOIRE
    qb(E,"13","What is Tache Noire?")
    E.append(Paragraph("<b>Tache noire de la sclΓ©rotique</b> (French: 'black spot of the sclera') is a post-mortem change in the eye.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Brown-black horizontal band or triangular discoloration on the sclera, visible on either side of the cornea"],
        ["Cause","Desiccation (drying) of the sclera when eyelids remain OPEN after death"],
        ["Appearance","Yellowish initially β†’ brown β†’ black; position corresponds to exposed sclera"],
        ["Time of appearance","A few hours after death (rate depends on environmental humidity and air currents)"],
        ["Significance","Indicates eyes were OPEN after death; approximate PMI indicator; not pathological"],
        ["Differential","NOT a sign of disease; purely post-mortem desiccation artifact"],
        ["Related change","Corneal clouding: milky opacity of cornea within 2–3 hrs (both eyes); iris details indistinct by 3–5 hrs"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,10))

    # Q30/84/89 SUSPENDED ANIMATION
    qb(E,"30 / 84 / 89","Write About Suspended Animation")
    E.append(Paragraph("<b>Suspended animation</b> is a condition in which the vital functions (respiration, circulation, reflexes) are so depressed that they cannot be detected by ordinary clinical methods, though the person is actually alive. It mimics death β€” hence also called <b>'apparent death'</b>.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Cause","Mechanism"],[
        ["Drowning (near-drowning)","Diving reflex + cold water β†’ profound bradycardia; cerebral hypoxia without actual death"],
        ["Electrocution (non-fatal)","Cardiac stunning; VF that spontaneously reverts; respiratory paralysis"],
        ["Profound hypothermia","Body temp < 28Β°C β†’ apparent death; metabolism slows dramatically;\ncomplete recovery possible even at 20Β°C"],
        ["Severe syncope/shock","Vasovagal; profound bradycardia; BP undetectable"],
        ["Cholera (severe)","Extreme dehydration β†’ cold, clammy, pulseless appearance ('cholera asphyxia')"],
        ["Drug overdose (sedatives/opioids)","Deep coma; depressed respiration; absent reflexes"],
        ["Catalepsy / hysteria","Rare psychogenic; appears rigid, motionless"],
        ["Premature neonates","May appear lifeless at birth; revive with warmth + stimulation"],
        ["After anesthesia","Prolonged apnea; appears dead"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Features that help distinguish from TRUE DEATH","Details"],[
        ["Body warmth","Some warmth may persist"],
        ["Muscle tone","Not rigid (no rigor mortis)"],
        ["Corneal reflex","May be very faint but present"],
        ["Pupillary reaction","May be sluggish but present"],
        ["EEG","Shows electrical activity (not flat)"],
        ["ECG","May show very weak/slow activity"],
        ["Auscultation (prolonged)","Very slow heartbeat may be heard"],
        ["Modern method","EEG + ECG + SpO2 monitoring; legal safeguard before certifying death"],
    ],cw=[5*cm,PAGE_W-2*M-5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>Medico-legal Importance:</b> Risk of premature burial. India's law requires death certification by qualified doctor. Some cases of 'waking from grave' in history = suspended animation. <b>Brain stem death criteria</b> now used to prevent such errors.",NOTE))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Approach When Suspended Animation is Suspected</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("PERSON APPEARS DEAD\n(no pulse, no breathing detected)","terminal"),
        ("DO NOT certify immediately\nLook for signs of LIFE","rect"),
        ("Check: Warmth, Muscle tone,\nCorneal reflex, Pupil reaction","rect"),
        ("ECG + EEG monitoring\n(minimum 30 min)","rect"),
        ("SpO2 monitoring;\nAuscultate heart (prolonged)","rect"),
        ("Signs of life found?","diamond"),
        ("RESUSCITATE\nCall emergency team","rounded"),
        ("Signs of DEATH confirmed:\nRigor mortis, livor mortis,\nflat EEG, fixed pupils","rect"),
        ("CERTIFY DEATH\nIssue death certificate","terminal"),
    ],nh=34,gap=13))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q34 DIFFERENTIAL DIAGNOSIS RIGOR MORTIS
    qb(E,"34","Differential Diagnosis of Rigor Mortis")
    E.append(Paragraph("Several conditions can simulate or be confused with rigor mortis. These are the main differential diagnoses (KS Narayan Reddy):",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Condition","Similarity to Rigor","Differentiating Features"],[
        ["<b>Heat stiffening</b>","Body stiff; widespread","Occurs with exposure >65Β°C;\nmore intense than rigor;\nmuscles 'cook'; pugilistic attitude;\nalbumin coagulates; irreversible;\nno pallor β†’ flushing/charring of skin"],
        ["<b>Cold stiffening</b>","Body stiff; rigid extremities","Due to freezing of body fluids;\ndisappears on warming;\nno biochemical changes of rigor;\nno lactic acid formation"],
        ["<b>Cadaveric spasm</b>\n(Instantaneous rigor)","Sudden stiffness at death","No primary relaxation phase;\noccurs INSTANTLY at death;\nselective – one group of muscles;\nassociated with extreme emotion/violence;\nforensically significant (grasp of weapon)"],
        ["<b>Putrefactive rigidity</b>","Body hard in later stages","Occurs AFTER rigor resolves;\ngas in muscles (emphysema);\nbody bloated; foul smell;\nuniform distribution"],
        ["<b>Catalepsy</b>","Person appears stiff/rigid","ALIVE; voluntary muscles;\ncan be broken without injury;\nEEG active; reversible"],
        ["<b>Tetanus (post-mortem)</b>","Sustained muscle contraction","Diagnosed from history;\nmay begin before death;\nlock-jaw; opisthotonus"],
    ],cw=[3.5*cm,3*cm,PAGE_W-2*M-6.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Feature","Rigor Mortis","Cadaveric Spasm","Heat Stiffening","Cold Stiffening"],[
        ["Onset","2–6 hrs after death","INSTANT at death","During/after burning","After freezing"],
        ["Primary relaxation","YES (flaccid first)","NO (no relaxation phase)","NO","NO"],
        ["Muscles affected","All muscles","One/few groups","All (extensive)","All (fluid freezing)"],
        ["Reversibility","Passes off 24–48 hrs","Passes off with rigor","Irreversible","Reversible (warmth)"],
        ["Cause","ATP depletion","Extreme muscular activity/emotion","Protein coagulation","Freezing of tissue fluids"],
        ["Force needed to break","Moderate","Cannot be broken easily","Not applicable","Melts with warmth"],
    ],cw=[3.2*cm,2.6*cm,2.8*cm,2.8*cm,PAGE_W-2*M-11.4*cm]))
    E.append(Spacer(1,10))

    # Q49 PM CALORICITY
    qb(E,"49","What is Post-Mortem Caloricity?")
    E.append(Paragraph("<b>Post-mortem caloricity</b> (post-mortem fever / <i>calor mortis</i>) is a transient rise in body temperature immediately after death.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Rise in body temperature occurring shortly after death (before cooling begins)"],
        ["Cause","Continuation of metabolic processes (especially in liver and muscles) after somatic death;\nbacterial activity releasing heat; liberation of chemical energy"],
        ["Degree","Rise of 1–2Β°C above normal in some cases"],
        ["Duration","Short-lived (minutes to 1–2 hours); followed by progressive cooling (algor mortis)"],
        ["Where most prominent","Liver (metabolically most active); core body temperature"],
        ["Conditions where pronounced","Deaths from septicemia, tetanus, strychnine poisoning, pontine hemorrhage,\nheatstroke; infections with high bacterial load"],
        ["Forensic significance","If body temperature at PM is higher than ambient temp but algor not yet started β†’\nsuggestive of very recent death; modifies TSD (time since death) calculation"],
        ["Practical note","Henssge nomogram for TSD assumes normal starting temperature;\nPM caloricity may give falsely RECENT time of death estimate"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,10))

    # Q50 ARTIFICIAL vs TRUE BRUISE
    qb(E,"50","Difference Between Artificial Bruise and True Bruise")
    E.append(tbl(["Feature","TRUE Bruise (Ante-mortem)","ARTIFICIAL Bruise (Post-mortem / Simulated)"],[
        ["Definition","Extravasation of blood into tissues due to rupture of blood vessels by trauma during life","Discoloration mimicking bruise; may be PM artifact, or deliberately inflicted after death"],
        ["Cause","Blunt force trauma BEFORE death","PM lividity; dye/stain; post-mortem trauma; decomposition"],
        ["Swelling","Present (inflammatory response)","Absent"],
        ["Color progression","Red β†’ purple β†’ blue β†’ green β†’ yellow (healing)","No progression; stays fixed; or livor pattern"],
        ["Blood infiltration","Deep into tissues; permeates tissue planes","Superficial; washes out on section (PM livor)"],
        ["Histology","RBCs in tissue; fibrin; leukocytes (inflammatory cells)","No inflammatory cells; no fibrin; RBCs in vessels only"],
        ["Vital reaction","PRESENT (leucocytic infiltration)","ABSENT"],
        ["Firm pressure test","Color returns after pressure (blood in tissue)","Blanches on pressure (if livor, blood still in vessels)"],
        ["Incision","Blood oozes from cut surface","No ooze; dry cut surface; blood stays in vessels"],
        ["Location","Corresponds to impact site","Corresponds to dependent areas (if livor)"],
    ],cw=[3*cm,4*cm,PAGE_W-2*M-7*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>Key Test:</b> Cut the suspected bruise and wash with water. TRUE bruise: blood stains tissue and does NOT wash away. POST-MORTEM livor: blood washes away from tissue.",NOTE))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q77 CADAVERIC SPASM
    qb(E,"77","What is Cadaveric Spasm?")
    E.append(Paragraph("<b>Cadaveric spasm</b> (instantaneous rigor / cataleptic rigidity) is the immediate stiffening of a group of muscles at the moment of death, without the usual preliminary stage of primary flaccidity.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Instantaneous stiffening of one or a group of muscles at the exact moment of death"],
        ["Mechanism","Extreme nervous tension or physical exertion at time of death β†’ instant depletion of ATP in those specific muscles"],
        ["Muscles involved","Usually selective: hand, forearm, neck muscles (not all muscles like rigor)"],
        ["Time of onset","INSTANT at death – no relaxation phase precedes it"],
        ["Duration","Persists until putrefaction begins (same as rigor mortis)"],
        ["Distinguishing from rigor","No primary relaxation; instantaneous; selective muscles; cannot be produced artificially post-mortem"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Forensic Significance","Example"],[
        ["Indicates body position at exact moment of death","Drowning victim's hand clutching vegetation/rope – proves ante-mortem immersion"],
        ["Suicide vs Homicide","Weapon firmly grasped in hand after death β†’ suicide more likely (cadaveric spasm)"],
        ["Struggle before death","Victim's hand containing attacker's hair/cloth β†’ indicates fight"],
        ["Cannot be simulated post-mortem","Weapon cannot be artificially placed in hand after death with same firmness"],
        ["Conditions favoring cadaveric spasm","Violent death; extreme mental/physical stress; gunshot wounds to head; drowning"],
    ],cw=[5*cm,PAGE_W-2*M-5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Cadaveric Spasm – Mechanism & Significance</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("EXTREME physical/mental effort\nat moment of DEATH","terminal"),
        ("INSTANT ATP depletion\nin specific muscle group","rect"),
        ("NO primary relaxation phase\n(unlike rigor mortis)","rect"),
        ("INSTANTANEOUS STIFFENING\nof that muscle group","rect"),
        ("Body found with:\nWeapon / object firmly grasped","diamond"),
        ("FORENSIC VALUE:\n- Confirms ante-mortem grip\n- Indicates struggle / manner of death\n- Cannot be simulated post-mortem","rounded"),
        ("Passes off with normal RIGOR MORTIS\n(not separately distinguishable later)","terminal"),
    ],nh=36,gap=13))
    E.append(Spacer(1,10))

    # Q93 RIGOR MORTIS vs CADAVERIC SPASM
    qb(E,"93","Difference Between Rigor Mortis and Cadaveric Spasm")
    E.append(tbl(["Feature","Rigor Mortis","Cadaveric Spasm"],[
        ["Definition","Gradual stiffening of ALL muscles after death","Instantaneous stiffening of ONE/FEW muscle groups at death"],
        ["Primary relaxation","YES – muscles flaccid first (primary relaxation)","NO – stiffening is immediate; no relaxation precedes"],
        ["Onset","2–6 hours after death","INSTANT at moment of death"],
        ["Muscles affected","All skeletal muscles; starts small β†’ large","Selective: usually hands, forearms, neck"],
        ["Cause","ATP depletion over hours β†’ actin-myosin cross-bridges","Extreme nervous/physical stress β†’ sudden ATP exhaustion"],
        ["Artificial reproduction","Can appear naturally in all cases","CANNOT be reproduced after death (distinguishing feature)"],
        ["Force to break","Moderate force; breaks and does not return","Firm; very difficult to break artificially"],
        ["Forensic significance","Sign of death; TSD estimation","Indicates body position + action at exact moment of death"],
        ["Duration","24–48 hrs then disappears","Persists until putrefaction (same time course as rigor)"],
        ["Causes preceding death","Not specific","Violent death, drowning, electrocution, emotional extremes"],
    ]))
    E.append(Spacer(1,10))

    # Q130 LATE PM CHANGES
    qb(E,"130","What are the Late Post-Mortem Changes?")
    E.append(Paragraph("Late post-mortem changes begin after rigor mortis resolves (after 48 hrs) and include both <b>destructive</b> and <b>preservative</b> changes.",BODY))
    E.append(Spacer(1,4))
    E.append(Paragraph("<b>A. DESTRUCTIVE CHANGES:</b>",BOLD))
    E.append(tbl(["Change","Description","Timeline"],[
        ["<b>Putrefaction</b>","Decomposition by bacteria (anaerobic > aerobic);\ngreenish discoloration abdomen first;\nmarbling (putrefactive veins);\nbloating with gases (H2S, methane, CO2, NH3);\nbullae formation;\nskin slippage","48 hrs+ (summer);\n1 week (winter);\nfaster in tropics"],
        ["<b>Mummification</b>","Rapid desiccation of body in hot, dry, arid conditions;\nskin becomes dry, hard, leather-like;\nbrown-yellow-black color;\npreserves body outline","Hot dry climate;\n3+ months"],
        ["<b>Skeletonization</b>","All soft tissue lost; only bones and cartilage remain;\nfastest when exposed + insect activity","6 weeks–months\n(exposed, warm)"],
    ],cw=[3.5*cm,5.5*cm,PAGE_W-2*M-9*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>B. PRESERVATIVE CHANGES:</b>",BOLD))
    E.append(tbl(["Change","Description","Conditions Favoring"],[
        ["<b>Adipocere</b>","Saponification of body fat β†’ waxy, soapy, grayish-white substance;\ncontains palmitic, stearic, oleic acid soaps;\npreserves body outline; takes months to form;\nretains poison traces for analysis","Moist, warm environment;\nwater immersion;\nburied in damp soil;\nobese individuals"],
        ["<b>Mummification</b>","(Also preservative) – see above",
         "Hot, dry, arid climate;\nwell-ventilated;\ndeserts; attics"],
        ["<b>Peat bog preservation</b>","Tannic acid in peat preserves tissue;\nskin darkens; bones may dissolve",
         "Specific peat bog environments"],
    ],cw=[3.5*cm,5.5*cm,PAGE_W-2*M-9*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Order of Putrefaction","Details"],[
        ["First to putrefy","Brain, stomach, intestines, lungs (soft, moist, rich in bacteria)"],
        ["Second","Liver, spleen, kidney"],
        ["Third","Heart, bladder"],
        ["Last","Uterus, prostate (dense, fibrous);\nbones (last of all)"],
        ["External","Abdomen greenish first (S.intestine bacteria) β†’ face/neck β†’ chest β†’ limbs"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Late Post-Mortem Changes</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("Rigor Mortis RESOLVES\n(after 48 hrs)","terminal"),
        ("BACTERIAL PUTREFACTION begins\n(anaerobic > aerobic bacteria)","rect"),
        ("GREEN DISCOLORATION\nAbdomen (first) β†’ face/neck β†’ chest β†’ limbs","rect"),
        ("MARBLING of veins;\nBLOATING with gases;\nSkin BLISTERS","rect"),
        ("SKIN SLIPPAGE;\nOrgan liquefaction;\nFoul smell","rect"),
        ("Environment determines\nnext change:","diamond"),
        ("HOT+DRY:\nMUMMIFICATION\n(desiccation; leather-like)","rounded"),
        ("WET/MOIST:\nADIPOCERE\n(fat saponification; waxy)","rounded"),
        ("SKELETONIZATION\n(all soft tissue lost; bones remain)","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q155 PM STAINING
    qb(E,"155","What is Post-Mortem Staining (Livor Mortis / Hypostasis)?")
    E.append(Paragraph("<b>Post-mortem staining</b> (livor mortis / lividity / hypostasis / suggillation) is the pink-purple discoloration of the skin seen in dependent parts of the body after death, due to gravitational settling of blood.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Cause","After cardiac arrest, blood gravitates to lowest dependent areas;\nRBCs settle in dermal capillaries β†’ pinkish-purple discoloration"],
        ["Onset","30 min – 2 hours after death"],
        ["Fully developed","6–8 hours"],
        ["Fixed (non-blanchable)","6–12 hours (blood coagulates in vessels; extravasates)"],
        ["Color","Pink-purple (normal); Cherry-red (CO, HCN poisoning, refrigerated body);\nGrayish (severe anemia); Chocolate-brown (methemoglobin – nitrite/aniline)"],
        ["Distribution","Dependent parts (back if supine; front if prone);\nAbsent over pressure areas (e.g., shoulder blades, buttocks);\nAbsent in areas of decomposition"],
        ["Disappears on pressure before fixation","< 6–8 hrs: blanches on pressure (blood still in vessels)"],
        ["Fixed after ~12 hrs","Does NOT blanch β†’ blood extravasated into tissues"],
        ["Shifting","Before fixation: if body repositioned, livor shifts to new dependent areas;\nAfter fixation: does NOT shift β†’ indicates body was moved post-mortem"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Color Variation","Cause"],[
        ["Cherry-red","CO poisoning; HCN poisoning; refrigerated body (oxyHb preserved)"],
        ["Chocolate-brown","Methemoglobin (nitrite poisoning, aniline dyes, dapsone)"],
        ["Pink (normal)","Deoxygenated blood"],
        ["Pale/faint","Severe anemia; massive blood loss; severe edema"],
        ["Greenish","Early putrefaction superimposed on livor"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Livor Mortis – Timeline & Forensic Uses</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("CARDIAC ARREST\n(Blood ceases to circulate)","terminal"),
        ("Blood gravitates to\nDEPENDENT PARTS (gravity)","rect"),
        ("30 min–2 hrs:\nPINK-PURPLE discoloration\nappears on skin (dependent)","rect"),
        ("6–8 hrs: FULLY DEVELOPED;\nBlanches on pressure\n(blood in vessels)","rect"),
        ("6–12 hrs: FIXED\n(blood extravasates;\ndoes NOT blanch)","rect"),
        ("FORENSIC USES:\n1. Sign of death\n2. TSD estimation\n3. Body position at death\n4. Was body MOVED after death?\n5. Color β†’ type of poisoning","rounded"),
        ("IF LIVOR fixed but body position\ndoes NOT match livor location\n→ Body was MOVED post-mortem","terminal"),
    ],nh=36,gap=13))
    E.append(Spacer(1,10))

    # Q158 PM STAINING vs BRUISING
    qb(E,"158","Difference Between Post-Mortem Staining and Bruising")
    E.append(tbl(["Feature","Post-Mortem Staining (Livor Mortis)","Bruise (Contusion)"],[
        ["Timing","After death (post-mortem)","During life (ante-mortem)"],
        ["Cause","Gravitational settling of blood in dermal vessels","Trauma β†’ rupture of blood vessels β†’ blood in tissues"],
        ["Location","DEPENDENT (back, buttocks, calves – if supine)","At site of IMPACT (any location, not gravity-dependent"],
        ["Color","Uniform pink-purple over large area","Purplish; may be patterned (imprint of object)"],
        ["Color change (healing)","No progression","Red β†’ purple β†’ blue β†’ green β†’ yellow (days)"],
        ["Pressure (early)","Blanches (blood still in vessels)","Does NOT blanch (blood in tissue)"],
        ["Incision","Blood washes away; vessels intact","Blood stains tissue; does NOT wash away"],
        ["Swelling","ABSENT","PRESENT (inflammatory response)"],
        ["Histology","No inflammatory cells; RBCs in intact vessels","Inflammatory cells (leucocytes); fibrin; RBCs in tissue"],
        ["Vital reaction","ABSENT","PRESENT"],
        ["Margins","Ill-defined, diffuse","May be well-defined; patterned if weapon involved"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>PRACTICAL TEST:</b> Incise the suspected area and wash with water under running tap. Bruise = blood stains tissue, doesn't wash off. Livor = blood in vessels washes away, tissue appears pale.",NOTE))
    E.append(Spacer(1,10))

    # Q33 BRAIN STEM DEATH
    qb(E,"33","Describe Brain Stem Death")
    E.append(Paragraph("<b>Brain stem death</b> (BSD) is irreversible cessation of all brain stem functions, while cardiac function may be maintained artificially. It is accepted as legal death in most countries.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Precondition","Details"],[
        ["Known diagnosis","There must be a known cause of irreversible brain damage (trauma, hypoxia, hemorrhage)"],
        ["Reversible causes excluded","Hypothermia (>35Β°C), metabolic/electrolyte disorders, drugs/sedatives must be excluded before testing"],
        ["Apnea (ventilated)","Patient on ventilator; cannot breathe spontaneously"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>CLINICAL TESTS FOR BRAIN STEM DEATH:</b>",BOLD))
    E.append(tbl(["Test","Procedure","Result in BSD"],[
        ["1. Pupillary reflex","Bright light β†’ both eyes","Fixed, dilated pupils; NO constriction"],
        ["2. Corneal reflex","Touch cornea with cotton wool","NO blinking"],
        ["3. Vestibulo-ocular reflex\n(Caloric test)","Ice cold water into ear canal","NO eye movement (absent doll's eye movement)"],
        ["4. Motor response to pain","Supraorbital or nail bed pressure","NO grimacing; NO motor response"],
        ["5. Gag reflex","Stimulate posterior pharynx","NO gag or cough"],
        ["6. Cough reflex","Suction catheter down trachea","NO cough"],
        ["7. APNEA TEST (most important)","Disconnect ventilator; give 100% O2;\nwait for PaCO2 to rise > 6.65 kPa (50 mmHg)","NO respiratory effort = brain stem dead"],
    ],cw=[3.5*cm,4*cm,PAGE_W-2*M-7.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Additional Points","Details"],[
        ["Who can diagnose","Two senior doctors; NOT from transplant team; NOT the treating doctor"],
        ["Number of tests","Usually repeated twice (different times)"],
        ["EEG","NOT required in UK/India for certification; required in some countries"],
        ["Time of death","Legally = time of first set of confirmatory tests"],
        ["Organ donation","Body may be maintained for organ harvest after BSD certification"],
        ["Legal status (India)","Transplantation of Human Organs Act 1994 (amended 2011) recognizes brain stem death"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Brain Stem Death Certification</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("Patient on VENTILATOR\nKnown irreversible brain damage","terminal"),
        ("PRECONDITIONS met:\nNo hypothermia; no drugs;\nno metabolic cause","rect"),
        ("1st SET of BSD TESTS\n(7 clinical tests)","rect"),
        ("All tests NEGATIVE\n(no brainstem reflexes)?","diamond"),
        ("REPEAT after interval\n2nd SET of BSD tests","rect"),
        ("All still NEGATIVE?","diamond"),
        ("TWO SENIOR DOCTORS\ncertify BSD (not from transplant team)","rect"),
        ("LEGAL TIME OF DEATH =\ntime of 1st confirmatory test","rounded"),
        ("Organ donation possible;\nventilator may be switched off","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # Q46 IMMERSION SYNDROME
    qb(E,"46","What is Immersion Syndrome?")
    E.append(Paragraph("<b>Immersion syndrome</b> (hydrocution / sudden immersion death) is sudden death occurring on immersion in cold water, even in good swimmers, in the absence of drowning.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Also called","Hydrocution; Hydrocution death; 'sudden drowning' (misnomer)"],
        ["Mechanism","Sudden cold water contact triggers massive vagal reflex:\n(1) Reflex cardiac arrest (vagal inhibition)\n(2) Laryngospasm β†’ prevents water entry but also stops breathing\n(3) Shock β†’ hypotension + arrhythmia"],
        ["Trigger","Contact of cold water with face/nostrils (most sensitive trigger);\nalso back of neck, perineum"],
        ["Predisposing factors","Hot body entering very cold water; alcohol intake before swimming;\nexhaustion; full stomach; fear"],
        ["PM findings","Lungs NOT waterlogged (no inhaled water);\nno drowning signs internally;\nsubconjunctival petechiae possible;\nhypothermia changes"],
        ["Cause of death","Vagal inhibition / reflex cardiac arrest (NOT asphyxia)"],
        ["Forensic significance","Death by 'drowning' but no true aspiration; body found in water; may be confused with homicide"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Immersion Syndrome</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("HOT body suddenly enters\nCOLD water","terminal"),
        ("Cold water contacts FACE\n/ nostrils / neck","rect"),
        ("MASSIVE VAGAL REFLEX\n(Bezold-Jarisch reflex)","rect"),
        ("Reflex CARDIAC ARREST\nor severe bradycardia","rect"),
        ("LARYNGOSPASM +\nAPNEA","rect"),
        ("DEATH (no water\nin lungs = not true drowning)","terminal"),
    ],nh=32,gap=12))
    E.append(Spacer(1,10))

    # Q55 CAFE CORONARY
    qb(E,"55","What is Cafe Coronary?")
    E.append(Paragraph("<b>Cafe coronary</b> is sudden death due to acute upper airway obstruction caused by a bolus of food (usually meat) impacted at the level of the larynx/hypopharynx, mimicking a cardiac arrest (hence 'coronary').",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Named after","Occurs often in restaurants/cafes – sudden collapse after eating"],
        ["Mechanism","Large food bolus β†’ impacts cricopharynx/laryngeal inlet β†’ complete airway obstruction β†’ asphyxia β†’ cardiac arrest"],
        ["Predisposing factors","Alcoholism (reduced gag reflex); poor dentition; eating hastily;\ndentures; meat eaters; elderly; neurological swallowing disorders"],
        ["Clinical features","Sudden collapse; silent (cannot speak, scream, or cough); clutches throat ('universal choking sign'); cyanosis; unconsciousness β†’ cardiac arrest"],
        ["Heimlich maneuver","Emergency: abdominal thrust to expel bolus (standard first aid)"],
        ["PM findings","Food bolus at laryngeal inlet; congested, cyanosed face;\nasphyxial signs (petechiae, congestion, cyanosis); normal coronary arteries"],
        ["Why confused with MI","Sudden death at table; no witnesses; coronary artery disease common in same age group"],
        ["Forensic note","Always check larynx/pharynx at PM – bolus may be removed by ambulance team before PM"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Cafe Coronary</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("EATING (usually meat,\nalcohol involved)","terminal"),
        ("Large FOOD BOLUS enters\nlaryngopharynx","rect"),
        ("IMPACTION at laryngeal inlet\n(cricopharynx)","rect"),
        ("Complete AIRWAY OBSTRUCTION\n(cannot speak, cough, scream)","rect"),
        ("ASPHYXIA β†’ Cyanosis β†’ Loss\nof consciousness β†’ Cardiac arrest","rect"),
        ("If witnessed:\nHEIMLICH MANEUVER\n(abdominal thrust)","diamond"),
        ("Bolus expelled → airway clear\n→ recovery possible","rounded"),
        ("If unwitnessed:\nDEATH; PM confirms food at larynx;\nasphyxial signs; NORMAL coronaries","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))

    # Q57 IMMERSION FOOT
    qb(E,"57","What is Immersion Foot Syndrome (Trench Foot)?")
    E.append(Paragraph("<b>Immersion foot (Trench foot)</b> is a non-freezing cold injury caused by prolonged exposure of feet to cold, wet conditions (not necessarily freezing temperature).",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Also called","Trench foot (WWI soldiers); Paddy foot; Immersion foot syndrome"],
        ["Cause","Prolonged (hours–days) exposure to cold water/mud (0–10Β°C); NOT freezing; sustained moisture"],
        ["Mechanism","Vasoconstriction β†’ tissue hypoxia β†’ endothelial damage β†’ local inflammation;\nthen hyperemia phase on rewarming"],
        ["Stages","1. Pre-hyperemic: cold, pale, numb, pulseless foot\n2. Hyperemic: rewarming β†’ bounding pulses, burning, swelling, blisters, pain\n3. Post-hyperemic (chronic): hyperhidrosis, cold sensitivity, chronic pain, Raynaud's"],
        ["Clinical features","Pale/blue foot; numbness; no pulse; tingling; blistering; ulceration if severe"],
        ["Treatment","Gentle rewarming; keep dry; elevation; pain management; NO rubbing/heat pads"],
        ["Prevention","Dry, waterproof boots; regular foot inspection; change wet socks; avoid constricting footwear"],
        ["Forensic/ML significance","Found in flood victims, shipwreck survivors, war casualties, homeless individuals;\nSkin changes may be confused with decomposition changes at PM"],
        ["Difference from frostbite","Frostbite = FREEZING; Trench foot = COLD+WET but above freezing"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,10))

    # SUMMARY
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 3 β€” QUICK REFERENCE SUMMARY",S('sh',fontSize=13,textColor=BLACK,
        fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(Spacer(1,4))
    E.append(tbl(["Topic","Key 1-Liner"],[
        ["Sudden Death","Most common cause: CAD; others: PE, SAH, arrhythmia, asthma, anaphylaxis"],
        ["Casper's Dictum","1 wk air = 2 wks water = 8 wks buried (decomposition rate)"],
        ["Tache Noire","Brown-black scleral band; desiccation; eyes open after death; PMI indicator"],
        ["Suspended Animation","Apparent death; vital signs undetectable; drowning/hypothermia/overdose; risk of premature burial"],
        ["PM Caloricity","Transient rise in body temp after death; heat from metabolism/bacteria; modifies TSD"],
        ["Rigor Mortis","Starts 2–6 hrs; complete 12 hrs; resolves 24–48 hrs; ATP depletion; all muscles"],
        ["Cadaveric Spasm","Instantaneous; one/few muscles; no relaxation phase; forensic: object in hand proves ante-mortem grip"],
        ["Rigor vs Cadaveric Spasm","Rigor: gradual, all muscles; Cadaveric spasm: instant, selective, no relaxation phase"],
        ["True vs Artificial Bruise","True: vital reaction, RBCs in tissue, no washout; PM staining: washes off, no inflammation"],
        ["Late PM Changes","Putrefaction (destructive); Adipocere + Mummification (preservative)"],
        ["Livor Mortis","Gravitational; 30 min–2 hrs; fixed 6–12 hrs; cherry-red = CO; blanches before fixation"],
        ["PM Staining vs Bruise","Livor: dependent, washes off, no vital reaction; Bruise: impact site, doesn't wash, vital reaction present"],
        ["Brain Stem Death","7 tests: pupils, corneal, caloric, pain, gag, cough, apnea; 2 doctors; = legal death"],
        ["Immersion Syndrome","Sudden death in cold water; vagal reflex cardiac arrest; NOT true drowning; no water in lungs"],
        ["Cafe Coronary","Food bolus at larynx; asphyxia; mimics MI; Heimlich maneuver; normal coronaries at PM"],
        ["Immersion Foot","Cold+wet (not freezing); 3 stages: pre-hyperemic, hyperemic, post-hyperemic; trench foot"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E,onFirstPage=hdr,onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__=="__main__":
    build()
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter2_gen.py 2>&…

Running Command

ls -lh /home/daytona/workspace/forensic-medicine-pdfs/*.pdf

Both PDFs are ready! Here are your download links:

Chapter2 PostMortem Autopsy

PDF Document Β· PDF

(51 KB)

Chapter3 Thanatology

PDF Document Β· PDF

(58 KB)

What's inside each PDF (B&W, print-ready):

Chapter 2 - Post-Mortem Examination & Autopsy

Q.TopicFormat
151Inquest (Police vs Magistrate vs Coroner)Table + Flowchart
384 Types of Early PM ChangesTable + Sequence Flowchart
10Decomposition in drowned body (1 wk)Timeline table + Flowchart
32/81Exhumation – full indications + procedureTables + Flowchart
40/85Viscera preservation in poisoningOrgan table + Rules table + Flowchart
140Organ removal methods (Virchow, Letulle, etc.)Technique + Incision tables + Flowchart
154Sample collection protocols + chain of custodyTables
87Hydrostatic test (liveborn vs stillborn)Table + Flowchart
41Virtual Autopsy (Virtopsy)Advantages vs Limitations table
62Negative AutopsyTable + Flowchart
171Shotgun wound patterns at various rangesRange table + Diagnostic table + Flowchart

Chapter 3 - Thanatology

Q.TopicFormat
11Causes of Sudden DeathSystem-wise table + Flowchart
12Casper's DictumTable + Rule
13Tache NoireFull details table
30/84/89Suspended AnimationCauses + Signs tables + Flowchart
34Differential Diagnosis of Rigor MortisComparison table (6 conditions)
49Post-Mortem CaloricityTable
50Artificial vs True BruiseFull comparison table
77Cadaveric SpasmTable + Flowchart
93Rigor Mortis vs Cadaveric Spasm10-feature comparison table
130Late PM ChangesDestructive + Preservative tables + Flowchart
155Post-Mortem Staining (Livor Mortis)Table + Color table + Flowchart
158PM Staining vs Bruising11-feature comparison table
33Brain Stem DeathPreconditions + 7 Tests + Flowchart
46Immersion SyndromeTable + Flowchart
55Cafe CoronaryTable + Flowchart
57Immersion Foot SyndromeFull table
Say "Make Chapter 4" (Mechanical Injuries) whenever you're ready!

Yes make chapter 4 pdf no black and white ....I need only white

Writing File

~/forensic-medicine-pdfs/chapter4_gen.py

#!/usr/bin/env python3
"""Chapter 4: Mechanical Injuries – Wounds & Trauma
   PURE WHITE version: white background, black text/borders only, no fills/shading
   Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's"""

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

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter4_Mechanical_Injuries.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK = colors.black
WHITE = colors.white

def S(n,**k):
    return ParagraphStyle(n, parent=getSampleStyleSheet()['Normal'], **k)

TITLE = S('Ti', fontSize=22, textColor=BLACK, fontName='Helvetica-Bold',
           alignment=TA_CENTER, leading=28)
CHAP  = S('Ch', fontSize=15, textColor=BLACK, fontName='Helvetica-Bold', alignment=TA_CENTER)
REF   = S('Re', fontSize=8,  textColor=BLACK, fontName='Helvetica-Oblique', alignment=TA_CENTER)
QS    = S('Qs', fontSize=12, textColor=BLACK, fontName='Helvetica-Bold', leading=17, leftIndent=8)
BODY  = S('Bo', fontSize=10, textColor=BLACK, leading=15, spaceAfter=3,
           fontName='Helvetica', alignment=TA_JUSTIFY)
BOLD  = S('Bl', fontSize=10, textColor=BLACK, leading=15, spaceAfter=3, fontName='Helvetica-Bold')
NOTE  = S('No', fontSize=9,  textColor=BLACK, fontName='Helvetica-Oblique', leading=13, leftIndent=10)
MNEM  = S('Mn', fontSize=10.5, textColor=BLACK, fontName='Helvetica-Bold', leading=15, leftIndent=10)
TH    = S('TH', fontSize=8.5, textColor=BLACK, fontName='Helvetica-Bold',
           alignment=TA_CENTER, leading=12)
TC    = S('TC', fontSize=8.5, textColor=BLACK, fontName='Helvetica', leading=12, alignment=TA_LEFT)
TCC   = S('TCC',fontSize=8.5, textColor=BLACK, fontName='Helvetica', leading=12, alignment=TA_CENTER)

# ── PAGE HEADER/FOOTER ───────────────────────────────────────────
def hdr(canv, doc):
    canv.saveState()
    # top border line only
    canv.setStrokeColor(BLACK); canv.setLineWidth(1.5)
    canv.line(M, PAGE_H-1.0*cm, PAGE_W-M, PAGE_H-1.0*cm)
    canv.setFillColor(BLACK); canv.setFont('Helvetica-Bold', 9)
    canv.drawString(M, PAGE_H-0.78*cm, "FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica', 8)
    canv.drawRightString(PAGE_W-M, PAGE_H-0.78*cm, "Chapter 4: Mechanical Injuries – Wounds & Trauma")
    # bottom border line
    canv.line(M, 0.85*cm, PAGE_W-M, 0.85*cm)
    canv.setFont('Helvetica', 8)
    canv.drawString(M, 0.32*cm, "Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M, 0.32*cm, f"Page {doc.page}")
    canv.restoreState()

# ── Q-BLOCK: thick border box, white bg, bold text ───────────────
def qb(E, num, txt):
    t = Table([[Paragraph(f"Q.{num}  {txt}", QS)]], colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),(-1,-1), WHITE),
        ('BOX',           (0,0),(-1,-1), 2, BLACK),
        ('TOPPADDING',    (0,0),(-1,-1), 8),
        ('BOTTOMPADDING', (0,0),(-1,-1), 8),
        ('LEFTPADDING',   (0,0),(-1,-1), 10),
        ('RIGHTPADDING',  (0,0),(-1,-1), 10),
    ]))
    E.append(KeepTogether([t]))
    E.append(Spacer(1, 5))

# ── TABLE: pure white, black borders, bold header row ────────────
def tbl(headers, rows, cw=None):
    avail = PAGE_W - 2*M - 0.2*cm
    if not cw:
        cw = [avail/len(headers)]*len(headers)
    data = [[Paragraph(h, TH) for h in headers]]
    for r in rows:
        data.append([Paragraph(str(c), TC) for c in r])
    t = Table(data, colWidths=cw, repeatRows=1)
    t.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),(-1,-1), WHITE),
        ('TEXTCOLOR',     (0,0),(-1,-1), BLACK),
        ('FONTNAME',      (0,0),(-1,0),  'Helvetica-Bold'),
        ('FONTNAME',      (0,1),(-1,-1), 'Helvetica'),
        ('FONTSIZE',      (0,0),(-1,-1), 8.5),
        ('GRID',          (0,0),(-1,-1), 0.6, BLACK),
        ('LINEBELOW',     (0,0),(-1,0),  1.2, BLACK),
        ('VALIGN',        (0,0),(-1,-1), 'TOP'),
        ('TOPPADDING',    (0,0),(-1,-1), 4),
        ('BOTTOMPADDING', (0,0),(-1,-1), 4),
        ('LEFTPADDING',   (0,0),(-1,-1), 5),
        ('RIGHTPADDING',  (0,0),(-1,-1), 5),
    ]))
    return t

# ── FLOWCHART: pure white boxes, black borders/text/arrows ───────
class FC(Flowable):
    """Pure white flowchart: all boxes white, borders black, text black."""
    def __init__(self, nodes, width=None, nh=34, gap=15):
        super().__init__()
        self.nodes  = nodes          # list of (text, shape)
        self.nw     = width or (PAGE_W - 2*M - 0.5*cm)
        self.nh     = nh
        self.gap    = gap
        self.width  = self.nw
        self.height = len(nodes)*(nh+gap) - gap + 20

    def wrap(self, aW, aH):
        return self.width, self.height

    def draw(self):
        c   = self.canv
        y   = self.height - 10
        nw, nh, gap = self.nw, self.nh, self.gap
        cx  = nw / 2

        for i, (text, shape) in enumerate(self.nodes):
            top = y - nh
            mid = y - nh/2
            c.setFillColor(WHITE)
            c.setStrokeColor(BLACK)
            lw = 1.8 if shape == 'terminal' else 1.2
            c.setLineWidth(lw)

            if shape == 'terminal':
                c.roundRect(cx - nw*.38, top, nw*.76, nh, nh/2, fill=1, stroke=1)
            elif shape == 'diamond':
                p = c.beginPath()
                p.moveTo(cx,        y)
                p.lineTo(cx+nw*.42, mid)
                p.lineTo(cx,        top)
                p.lineTo(cx-nw*.42, mid)
                p.close()
                c.drawPath(p, fill=1, stroke=1)
            elif shape == 'rounded':
                c.roundRect(cx - nw*.44, top, nw*.88, nh, 8, fill=1, stroke=1)
            else:  # rect
                c.rect(cx - nw*.44, top, nw*.88, nh, fill=1, stroke=1)

            # text
            c.setFillColor(BLACK)
            bold = shape in ('terminal', 'diamond')
            c.setFont('Helvetica-Bold' if bold else 'Helvetica', 8.5)
            lines = text.split('\n')
            lh = 11
            ty = mid + len(lines)*lh/2 - lh*.7
            for ln in lines:
                c.drawCentredString(cx, ty, ln)
                ty -= lh

            # arrow
            if i < len(self.nodes) - 1:
                ay = top - gap
                c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx, top, cx, ay+6)
                c.setFillColor(BLACK)
                p = c.beginPath()
                p.moveTo(cx, ay); p.lineTo(cx-5, ay+8); p.lineTo(cx+5, ay+8)
                p.close(); c.drawPath(p, fill=1, stroke=0)
            y = top - gap

# ════════════════════════════════════════════════════════════════
def build():
    doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
        leftMargin=M, rightMargin=M, topMargin=1.4*cm, bottomMargin=1.2*cm,
        title="Chapter 4 – Mechanical Injuries")
    E = []

    # ── COVER PAGE ───────────────────────────────────────────────
    E.append(Spacer(1, 1.2*cm))
    bdr = Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY", TITLE)]],
                colWidths=[PAGE_W-2*M])
    bdr.setStyle(TableStyle([
        ('BACKGROUND',    (0,0),(-1,-1), WHITE),
        ('BOX',           (0,0),(-1,-1), 3, BLACK),
        ('TOPPADDING',    (0,0),(-1,-1), 18),
        ('BOTTOMPADDING', (0,0),(-1,-1), 18),
    ]))
    E.append(bdr); E.append(Spacer(1, .4*cm))
    cb = Table([[Paragraph("CHAPTER 4", CHAP)]], colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2 = Table([[Paragraph("Mechanical Injuries – Wounds &amp; Trauma",
        S('tb',fontSize=18,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.3*cm))
    rb = Table([[Paragraph(
        "References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed",
        REF)]], colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))

    E.append(Paragraph("CHAPTER CONTENTS",
        S('toch',fontSize=11,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["29","Abrasion – Description, Types, Medico-legal Importance"],
        ["141","Medico-legal Importance of Abrasions"],
        ["82 / 137","Contusion (Bruise) – Description"],
        ["50","Difference: Artificial Bruise vs True Bruise"],
        ["118","Laceration – Description"],
        ["5","Deep Stab Wound to Forearm – Description"],
        ["71","Difference: Firearm Entry vs Exit Wounds"],
        ["73","Difference: Homicidal vs Suicidal Cut Throat Wounds"],
        ["26 / 45","Primary & Secondary Impact Injuries"],
        ["134","Difference: Ante-mortem vs Post-mortem Wounds"],
        ["3","Signs of Head Injury"],
        ["23","Lucid Interval – Definition & Example"],
        ["142","Counter-coup Lesions"],
        ["156","Types of Skull Fractures"],
        ["122","Burking"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # ════════════ Q29 / Q141 ABRASION ════════════════════════════
    qb(E,"29 / 141","Describe Abrasion in Detail & its Medico-legal Importance")
    E.append(Paragraph(
        "<b>Definition:</b> An abrasion is a superficial injury of the skin caused by tangential or "
        "perpendicular friction/pressure, which damages the epidermis (and occasionally the superficial "
        "dermis), but does NOT penetrate the full thickness of the skin. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Type of Abrasion","Mechanism","Appearance","Example"],[
        ["<b>Scratch (Linear)</b>","Sharp object drawn across skin","Single/multiple parallel lines;\nepidermis scraped off","Fingernail scratch; thorn"],
        ["<b>Graze (Sliding)</b>","Body slides over rough surface\n(tangential force)","Elongated; parallel ridges & furrows;\ndirection of scraping determinable;\nepidermis 'piled up' at far end","Road rash (RTA); fall on gravel"],
        ["<b>Pressure/Impact (Crushing)</b>","Perpendicular force on skin","Round/oval; epidermis crushed;\nshows pattern of causative object","Boot mark; tyre tread"],
        ["<b>Friction burn</b>","High-speed friction\n(rope, belt)","Deep abrasion with heat;\nlooks like burn + abrasion","Ligature mark; rope drag"],
    ],cw=[3.2*cm,3.2*cm,3.8*cm,PAGE_W-2*M-10.2*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>HEALING OF ABRASION (Age estimation of wound):</b>",BOLD))
    E.append(tbl(["Time","Appearance"],[
        ["Fresh (0–6 hrs)","Moist, reddish, oozing serum; epidermis disrupted"],
        ["6–12 hrs","Drying; pale yellow to red crust (scab) forming"],
        ["12–24 hrs","Crust (scab) formed; firm"],
        ["2–3 days","Crust raised above skin level; edges healing"],
        ["4–7 days","Crust begins to separate at edges; new epithelium under"],
        ["1–2 weeks","Crust falls off; pinkish new skin visible"],
        ["2–4 weeks","Complete healing; may leave temporary pigmentation"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>MEDICO-LEGAL IMPORTANCE (Q.141):</b>",BOLD))
    E.append(tbl(["Importance","Details"],[
        ["1. Proof of violence","Confirms that force was applied to body; proves trauma occurred"],
        ["2. Direction of force","Graze: epidermis piled up at far end β†’ indicates direction of force/movement"],
        ["3. Age of injury","Healing stages (scab β†’ crust β†’ epithelialization) help estimate when injury occurred"],
        ["4. Pattern identification","Patterned abrasions may show the weapon/object used (tyre tread, boot sole)"],
        ["5. Site corresponds to impact","Abrasion at exact point of contact; helps reconstruct events"],
        ["6. Fingernail marks","Crescentic/linear abrasions β†’ defense wounds; struggle; strangulation (neck)"],
        ["7. Ligature mark","Friction burns β†’ identify ligature material (rope, belt, wire)"],
        ["8. Sexual assault","Perianal/vulval abrasions in sexual assault; penile abrasions"],
        ["9. Ante-mortem vs PM","Ante-mortem: scab formation, inflammatory response; PM: no scab, no vital reaction"],
        ["10. Associated injuries","May overlie deeper injuries (bruise, fracture); clue to deeper violence"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Medico-legal Evaluation of Abrasion</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("ABRASION found on body","terminal"),
        ("Describe: Site, Size, Shape,\nColor, Direction of ridges","rect"),
        ("Is it ANTE-MORTEM?\n(scab, inflammation, vital reaction)","diamond"),
        ("Age of wound:\nFresh / 12–24 hrs / 2–3 days / 1 wk","rect"),
        ("PATTERN present?\n(tyre tread, boot, rope, nail)","diamond"),
        ("Identify weapon/object from pattern;\nPhotograph + document","rounded"),
        ("Direction of force:\n(piled up epidermis at far end)","rect"),
        ("CONCLUSIONS:\nForce used, object, direction,\ntime of injury, manner","terminal"),
    ],nh=34,gap=13))
    E.append(Spacer(1,10))

    # ════════════ Q82 / Q137 CONTUSION ═══════════════════════════
    qb(E,"82 / 137","What is Contusion (Bruise)? Describe in Detail.")
    E.append(Paragraph(
        "<b>Definition:</b> A contusion (bruise) is an injury caused by blunt force that ruptures blood "
        "vessels in the subcutaneous tissue or deeper, causing extravasation of blood into tissues, "
        "<b>without breaking the skin surface</b>. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Mechanism","Blunt force β†’ rupture of capillaries/venules β†’ blood extravasation into tissue planes"],
        ["Skin intact","Yes – skin surface not broken (distinguishes from laceration/incised wound)"],
        ["Color changes\n(temporal sequence)","0–2 days: Red-purple\n2–4 days: Blue-purple\n4–6 days: Green\n6–10 days: Yellow\n10–14 days: Normal\n(Note: timing is approximate; varies with depth, site, skin tone)"],
        ["Swelling","Present (inflammatory response)"],
        ["Tenderness","Present"],
        ["Deeper tissues","May involve muscle, periosteum; occasionally visible only at PM (deep bruise)"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Type","Description","Example"],[
        ["<b>Intradermal bruise</b>","Small petechial hemorrhages within skin","Petechiae in asphyxia; subconjunctival hemorrhage"],
        ["<b>Subcutaneous bruise</b>","Blood in subcutaneous fat","Common bruise from blunt trauma"],
        ["<b>Deep bruise</b>","In muscle / fascia; may not be visible externally","Punch to thigh; internal organ bruising"],
        ["<b>Patterned bruise</b>","Shape of weapon imprinted","Tyre tread; belt buckle; hand slap"],
        ["<b>Periorbital hematoma</b>\n('Black eye')","Bruise around orbit","Direct blow to eye; or tracking from frontal fracture"],
        ["<b>Tramline bruise</b>","Two parallel lines with pale center","Rod/stick impact; blood pushed laterally from central compression zone"],
    ],cw=[3.5*cm,4*cm,PAGE_W-2*M-7.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Medico-legal Importance","Details"],[
        ["Proof of violence","Confirms blunt force applied"],
        ["Age estimation","Color progression helps date the bruise (approximate)"],
        ["Pattern identification","Shape may reveal weapon (belt, rod, tyre, hand)"],
        ["Site vs blow site","Bruise may not be at exact impact point (tracks along tissue planes)"],
        ["Spontaneous bruising","May occur in blood disorders (hemophilia, thrombocytopenia); LP, anticoagulants"],
        ["Defense wounds","Bruises on forearms/hands suggest victim tried to defend"],
        ["PM bruises","No vital reaction; blood in vessels; washes away on section"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Color Changes of Bruise Over Time</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("BLUNT FORCE TRAUMA\nBlood extravasates into tissue","terminal"),
        ("0–2 days:\nRED β†’ PURPLE\n(fresh blood; oxyhemoglobin)","rect"),
        ("2–4 days:\nBLUE-PURPLE\n(deoxyhemoglobin)","rect"),
        ("4–6 days:\nGREEN\n(biliverdin from Hb breakdown)","rect"),
        ("6–10 days:\nYELLOW\n(bilirubin)","rect"),
        ("10–14 days:\nNORMAL SKIN COLOR\n(complete resorption)","rounded"),
        ("Note: Deep bruises may\nappear LATER on surface","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ════════════ Q50 TRUE vs ARTIFICIAL BRUISE ══════════════════
    qb(E,"50","Difference Between True Bruise (Ante-mortem) and Artificial Bruise (Post-mortem)")
    E.append(tbl(["Feature","TRUE Bruise (Ante-mortem)","ARTIFICIAL / PM Bruise"],[
        ["Timing","During LIFE (ante-mortem)","After death (PM) OR simulated"],
        ["Cause","Blunt trauma during life β†’ vessel rupture","PM livor; dye; PM trauma; decomposition artifact"],
        ["Swelling","PRESENT (inflammatory)","ABSENT"],
        ["Color progression","Yes: red β†’ blue β†’ green β†’ yellow","No change; stays fixed (or livor pattern)"],
        ["Blood in tissue","Deep; permeates tissue planes","Superficial; only in vessels (if livor)"],
        ["Histology","RBCs in tissue + fibrin + leucocytes","No inflammation; RBCs confined to vessels"],
        ["Vital reaction","PRESENT","ABSENT"],
        ["Pressure test","Color returns after pressure","Blanches (if early livor, blood still movable)"],
        ["Incision + washing","Blood STAINS tissue; does NOT wash off","Blood WASHES AWAY; tissue pale"],
        ["Location","Corresponds to impact site","Dependent areas (livor pattern) or random (dye)"],
        ["Firm borders","Usually definable","Diffuse, ill-defined"],
    ]))
    E.append(Spacer(1,4))
    E.append(Paragraph(
        "<b>Practical test (Narayam Reddy):</b> Incise the area β†’ wash with water. "
        "TRUE bruise: blood stains tissue and DOES NOT wash away. "
        "PM livor: blood in vessels, washes away leaving pale tissue.",NOTE))
    E.append(Spacer(1,10))

    # ════════════ Q118 LACERATION ════════════════════════════════
    qb(E,"118","What is Laceration?")
    E.append(Paragraph(
        "<b>Definition:</b> A laceration is a tear or split in the skin and underlying tissues caused by "
        "<b>blunt force</b> that compresses or stretches tissues beyond their elastic limit. "
        "The skin is torn, NOT cut. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Feature","Laceration","Incised Wound (for comparison)"],[
        ["Cause","Blunt force (stretch/compress)","Sharp cutting instrument"],
        ["Edges","IRREGULAR, ragged, crushed","REGULAR, clean, sharp"],
        ["Margins","Bruised and abraded","Clean; no bruising"],
        ["Wound bed","Tissue bridges (nerves, vessels, connective tissue) cross the wound","No bridges; clean separation"],
        ["Hair follicles","Crushed/torn in wound margins","Cut cleanly"],
        ["Bleeding","Less (crushed vessels close)","More (clean vessel cut, stays open)"],
        ["Depth","Variable; may reach bone","Variable"],
        ["Shape","Stellate, irregular, curved","Linear, spindle-shaped"],
        ["Contamination","Often contaminated (road grit, clothing fibers)","Usually clean"],
    ]))
    E.append(Spacer(1,5))
    E.append(tbl(["Types of Laceration","Mechanism","Example"],[
        ["Split laceration","Skin split over bony prominence by direct blow","Eyebrow; scalp (blow with rod/bat)"],
        ["Stretch laceration","Skin overstretched β†’ tears away from underlying tissue","Tyre running over limb"],
        ["Avulsion","Tissue torn away from attachment","Degloving injury; scalp avulsion"],
        ["Penetrating laceration","Object penetrates with tearing force","Sharp end of rod; horn injury"],
        ["Cut laceration\n(Chop wound)","Heavy sharp instrument with some blunt force","Axe chop; machete"],
    ],cw=[3.5*cm,3.5*cm,PAGE_W-2*M-7*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Medico-legal Importance","Details"],[
        ["Distinguishes blunt from sharp force","Bridges present = blunt; no bridges = sharp"],
        ["Weapon identification","Stellate tear = rounded blunt object; linear = rod/stick; V-shaped = angular weapon"],
        ["Age estimation","Healing stages (like abrasion)"],
        ["Direction of force","Can sometimes be determined from wound shape"],
        ["Defense wounds","Lacerations on palms/forearms in victims defending from blows"],
        ["Mistaken for incised wound","Important: skin lacerations over scalp may look like incised wounds – always check wound bed for bridges"],
    ]))
    E.append(Spacer(1,10))

    # ════════════ Q5 STAB WOUND ══════════════════════════════════
    qb(E,"5","Deep Stab Wound to Forearm in a 15-year-old – Describe the Wound in Detail")
    E.append(Paragraph(
        "A <b>stab wound</b> (puncture wound / penetrating wound) is caused by a sharp-pointed instrument "
        "penetrating the tissues. The depth exceeds the surface dimensions.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Feature","Details"],[
        ["Definition","Entry wound depth > surface width/length; caused by thrusting a pointed/sharp object"],
        ["Wound shape","Slit-like (single-edged blade) or spindle-shaped (double-edged blade) or round (pointed instrument like ice pick)"],
        ["Edges","CLEAN, regular (sharp weapon) vs irregular with crush margin (pointed blunt)"],
        ["Wound margins","Abrasion collar if weapon had a collar/guard; bruising if blunt shoulder of weapon"],
        ["Depth vs surface","Depth > surface appearance; may penetrate to bone, vessels, nerves"],
        ["Bridges","NO tissue bridges (unlike laceration); clean track"],
        ["Direction of track","Can be probed carefully; helps determine angle of attack and position of victim/attacker"],
        ["Single vs double edge","Single edge: one sharp edge (angle) + one blunt edge (squared end)\nDouble edge: both edges sharp (V-shaped wound)"],
        ["Hemorrhage","May be extensive (if deep vessel, radial artery in forearm)"],
        ["Associated injuries","Tendon/nerve/vessel damage in forearm stab wound"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>For THIS case (forearm stab wound, 15-yr-old student):</b>",BOLD))
    E.append(tbl(["Examine","Document"],[
        ["Site","Exact location on forearm: volar/dorsal, distance from anatomical landmarks"],
        ["Size","Length Γ— width of surface wound; estimated depth (if probe used)"],
        ["Shape","Slit-like/spindle/irregular; which end is acute (sharp), which is square (blunt)"],
        ["Edges","Clean or ragged; beveled or not"],
        ["Margins","Abraded collar? Bruised? Contusion ring? (indicates blunt shoulder of weapon)"],
        ["Track direction","Angle of entry (perpendicular, oblique); direction relative to bone axis"],
        ["Depth","Estimated depth; structures potentially involved (tendon, nerve, artery)"],
        ["Associated features","Defense wounds? (palmar side = likely defensive); homicidal vs self-inflicted?"],
        ["Weapon inference","Single-edged (knife) vs double-edged; width of weapon = wound length at rest"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Documentation of Stab Wound</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("STAB WOUND – Patient / Body","terminal"),
        ("Site: exact anatomical location\n+ measurement from landmarks","rect"),
        ("Shape: slit/spindle/round/irregular","rect"),
        ("Edges: clean / ragged / beveled\n(one acute end = single edge blade)","rect"),
        ("Margins: abrasion collar? bruise?\n(indicates weapon shoulder/guard)","rect"),
        ("Track: angle of entry, direction,\nestimated depth","rect"),
        ("Structures involved:\nvessels, nerves, tendons, bone","diamond"),
        ("Infer WEAPON:\nsingle / double edge; blade width;\nself-inflicted vs homicidal?","rounded"),
        ("DOCUMENT: Photograph, diagram,\nMLC report; preserve clothing","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ════════════ Q71 FIREARM ENTRY vs EXIT ══════════════════════
    qb(E,"71","Difference Between Firearm Entry and Exit Wounds")
    E.append(tbl(["Feature","ENTRY Wound","EXIT Wound"],[
        ["Size","SMALLER than bullet diameter\n(skin is elastic; contracts)","LARGER than bullet diameter\n(bullet + deformed tissue + fragments exit)"],
        ["Shape","Round / oval (if perpendicular)\nOval (if angled)","Irregular, stellate, slit-like,\nor larger oval"],
        ["Edges","INVERTED (turned inward)","EVERTED (turned outward / ragged)"],
        ["Abrasion collar","PRESENT (contact with bullet rim\nas it enters)","ABSENT"],
        ["Contusion ring\n(bullet wipe)","PRESENT (lubricant/dirt wiped\nfrom bullet)","ABSENT"],
        ["Burning / singeing","Present (if close/contact range)","Absent"],
        ["Powder tattooing","Present (if < 60 cm)","Absent"],
        ["Soot deposition","Present (contact/close)","Absent"],
        ["Beveling (skull)","Internal table beveled outward","External table beveled outward"],
        ["Bone fragments","Pushed inward (into body)","Pushed outward"],
        ["Underlying hemorrhage","Yes","Yes"],
        ["Number","Usually = number of bullets","May be less (bullet may be retained)"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>Exceptions and special cases:</b>",BOLD))
    E.append(tbl(["Exception","Details"],[
        ["Shored exit wound","If body part against hard surface β†’ exit wound has abrasion collar (mimics entry)"],
        ["Keyhole wound","Tangential bullet entry/exit at same site; combined entry+exit"],
        ["Re-entry wound","Bullet exits, ricochets off surface, re-enters β†’ looks unusual"],
        ["Intermediate target","Bullet deformed before entry β†’ ragged, atypical entry wound"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Determining Entry vs Exit Wound</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("GUNSHOT WOUND found","terminal"),
        ("ABRASION COLLAR\npresent?","diamond"),
        ("YES β†’ ENTRY WOUND\n(also check: soot, tattooing, singeing)","rounded"),
        ("NO abrasion collar:\nEdges EVERTED?\nIrregular/larger wound?","diamond"),
        ("YES β†’ EXIT WOUND\n(no burning; no tattooing)","rounded"),
        ("Check skull: BEVELING\n(Internal bevel = entry;\nExternal bevel = exit)","rect"),
        ("EXCEPTIONS:\nShored exit (collar present);\nKeyhole; Re-entry","rounded"),
        ("CONCLUSION:\nEntry / Exit\n+ Range estimation","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))

    # ════════════ Q73 HOMICIDAL vs SUICIDAL CUT THROAT ═══════════
    qb(E,"73","Difference Between Homicidal and Suicidal Cut Throat Wounds")
    E.append(tbl(["Feature","SUICIDAL Cut Throat","HOMICIDAL Cut Throat"],[
        ["Number of wounds","Single main wound +\nhesitation cuts (tentative incisions)","Usually single deep wound;\nmay be multiple slashing wounds"],
        ["Hesitation cuts\n(Tentative marks)","PRESENT: multiple superficial parallel\ncuts near main wound (victim 'testing')","ABSENT (attacker strikes decisively)"],
        ["Site","Usually left side of neck\n(right-handed person)","Any location; varies with attacker position"],
        ["Direction","Horizontal or slightly oblique;\nupward at far end (left to right in right-handed)","Often oblique; may be across entire neck;\nvariable direction"],
        ["Depth","Variable; usually deep at one end,\nshallower at other end ('tail' of wound)","Often uniformly deep; may be very deep;\nboth ends may be deep"],
        ["Defense wounds","ABSENT\n(victim self-inflicted; no struggle)","PRESENT on hands, forearms, palms\n(victim tried to defend)"],
        ["Other injuries","ABSENT elsewhere\n(no other wounds)","MAY be present: other stab wounds,\nblunt injuries, restraint marks"],
        ["Clothes","Removed or pulled aside\n(victim deliberately exposed neck)","Clothes intact; wound through clothing"],
        ["Scene","Blood at scene; weapon near body;\nno signs of struggle","Signs of struggle; blood splatter;\nvictim found away from weapon"],
        ["Grip marks","ABSENT","May be present on neck/arms\n(attacker's grip)"],
        ["Carotid injury","May or may not be cut","Often both carotids cut"],
        ["Soot / powder burns","If firearm used (rare)","Possible if close range firearm"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Suicidal vs Homicidal Cut Throat</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("CUT THROAT WOUND found","terminal"),
        ("HESITATION CUTS present?","diamond"),
        ("YES β†’ suggests SUICIDAL\n(tentative marks near main wound)","rounded"),
        ("DEFENSE WOUNDS present?","diamond"),
        ("YES β†’ suggests HOMICIDAL\n(forearms, palms, fingers cut)","rounded"),
        ("Check SCENE:\nSigns of struggle?","diamond"),
        ("NO struggle, weapon near body\n→ SUICIDAL","rounded"),
        ("Struggle evident, clothes intact\n→ HOMICIDAL","rounded"),
        ("FINAL CONCLUSION:\nCorrelate all features;\nreport to Magistrate","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ════════════ Q26 / Q45 PRIMARY & SECONDARY IMPACT INJURIES ══
    qb(E,"26 / 45","Define Primary and Secondary Impact Injuries")
    E.append(Paragraph(
        "These terms are used in <b>Road Traffic Accident (RTA)</b> injury analysis, particularly when a "
        "pedestrian is struck by a vehicle. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Type","Definition","Example","Location on Body"],[
        ["<b>Primary Impact Injury</b>","Injury caused by the FIRST direct contact between vehicle and pedestrian\n(the initial blow from the vehicle)","Bumper fracture of tibia/fibula;\nbumper bruise on lower leg","Usually at the level of the vehicle's front bumper: tibia, fibula, knee (lower 1/3 of leg in adults)"],
        ["<b>Secondary Impact Injury</b>","Injury caused when the body, after being thrown by the first impact, hits the BONNET, windscreen, or another part of the vehicle","Lacerations of scalp from windscreen;\nfractures from bonnet edge","Upper body: head, trunk, shoulder"],
        ["<b>Tertiary Impact Injury</b>","Injury caused when the body hits the GROUND after being thrown off","Contusions, lacerations from road surface;\nfractures from ground impact","Variable; depends on how body falls"],
        ["<b>Wringer/Rolling Injury</b>","Body run over by vehicle tyres;\ntyre tread patterned bruises","Tyre tread marks; crush injuries","At any point of body contact with tyre"],
    ],cw=[3.5*cm,4.5*cm,3*cm,PAGE_W-2*M-11*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>BUMPER FRACTURE (Signature injury of RTA):</b>",BOLD))
    E.append(tbl(["Feature","Details"],[
        ["Definition","Fracture of tibia Β± fibula at the level of car bumper impact"],
        ["Height","Varies with vehicle type; usually lower 1/3 of leg in adults (sedan bumper ~50 cm height)"],
        ["Pattern","Wedge-shaped fracture; wider base on side of impact"],
        ["Significance","Indicates direction of vehicle travel; height of impact = bumper height of vehicle;\ncan identify type of vehicle"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: RTA Injury Sequence</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("VEHICLE hits PEDESTRIAN","terminal"),
        ("PRIMARY IMPACT:\nBumper strikes lower limbs\n→ Bumper fracture (tibia/fibula)","rect"),
        ("Body thrown UPWARD and FORWARD\nonto vehicle","rect"),
        ("SECONDARY IMPACT:\nBody hits bonnet/windscreen\n→ Head/trunk injuries","rect"),
        ("Body thrown OFF vehicle\nonto ROAD","rect"),
        ("TERTIARY IMPACT:\nBody hits ground/road surface\n→ Contusions, lacerations, fractures","rect"),
        ("Vehicle may ROLL OVER body:\nWRINGER INJURIES\n(tyre tread marks)","rounded"),
        ("FORENSIC ANALYSIS:\nHeight of injury = bumper height;\ndirection from wedge fracture","terminal"),
    ],nh=35,gap=13))
    E.append(Spacer(1,10))

    # ════════════ Q134 ANTE-MORTEM vs PM WOUNDS ══════════════════
    qb(E,"134","Difference Between Ante-mortem and Post-mortem Wounds")
    E.append(tbl(["Feature","ANTE-MORTEM Wound","POST-MORTEM Wound"],[
        ["Timing","Inflicted BEFORE death (during life)","Inflicted AFTER death"],
        ["Vital reaction","PRESENT:\n- Inflammatory response\n- Leucocytic infiltration (histology)","ABSENT:\nNo inflammation; no cell response"],
        ["Bleeding","Profuse; spurting (if artery cut)","Minimal; oozing only; no pressure"],
        ["Blood in tissue","Deeply infiltrated into tissue planes;\nstains tissue","Superficial; blood washes away;\ntissue pale on washing"],
        ["Retraction of wound edges","PRESENT (skin and tissue retract)","ABSENT or minimal"],
        ["Clotting","Clot formation in wound / vessels","No true clotting (PM coagulation only)"],
        ["Histology","Leucocytes, fibrin, RBCs in tissue;\nvascular dilation","No leucocytes; RBCs only in vessels"],
        ["Signs of healing","If survived hours-days: granulation,\nepithelial regeneration","No healing whatsoever"],
        ["Bruising around wound","Present (bruising = vital reaction)","ABSENT"],
        ["Swelling","Present","Absent"],
        ["Erythema / redness","Present (hyperemia)","Absent"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph(
        "<b>Key PM test:</b> Cut the wound and wash under water. Ante-mortem: blood stains tissue, "
        "does not wash away. Post-mortem: blood in vessels washes away, pale tissue.",NOTE))
    E.append(Spacer(1,10))

    # ════════════ Q3 HEAD INJURY ══════════════════════════════════
    qb(E,"3","What are the Signs of Head Injury?")
    E.append(Paragraph(
        "Head injuries may be <b>open</b> (scalp/skull breach) or <b>closed</b>. Signs depend on the type "
        "and severity.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Category","Sign","Details"],[
        ["<b>External Signs</b>","Scalp wound","Abrasion, laceration, contusion of scalp;\nhair matted with blood"],
        ["","Battle's sign","Bruising over mastoid process (postauricular)\n→ indicates base of skull fracture (posterior fossa)"],
        ["","Raccoon eyes / Panda sign","Periorbital bruising (bilateral)\n→ indicates anterior fossa basal skull fracture"],
        ["","CSF otorrhoea/rhinorrhoea","CSF leaking from ear/nose\n→ base of skull fracture; ring sign/halo test positive"],
        ["","Hemotympanum","Blood behind eardrum β†’ base of skull fracture"],
        ["<b>Neurological Signs</b>","Altered consciousness","GCS < 15; confusion; disorientation; coma"],
        ["","Lucid interval","Period of consciousness after head injury, followed by deterioration\n→ extradural hematoma (middle meningeal artery)"],
        ["","Pupil changes","Unilateral dilated fixed pupil β†’ ipsilateral herniation (III nerve compression);\nBilateral fixed dilated β†’ brainstem failure"],
        ["","Focal deficits","Hemiplegia, aphasia, visual field defects"],
        ["","Seizures","Early or late post-traumatic epilepsy"],
        ["<b>Vital Signs</b>","Cushing's triad","Hypertension + Bradycardia + Irregular respiration\n→ raised ICP; imminent herniation"],
        ["","Vomiting","Especially projectile β†’ raised ICP"],
        ["<b>Signs at PM</b>","Contrecoup lesions","Bruising of brain opposite to impact site"],
        ["","Epidural hematoma","Lens-shaped collection; temporal region; middle meningeal artery"],
        ["","Subdural hematoma","Crescent-shaped; bridging veins"],
        ["","SAH","Blood in subarachnoid space; ruptured aneurysm or trauma"],
    ],cw=[3*cm,3.5*cm,PAGE_W-2*M-6.5*cm]))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ════════════ Q23 LUCID INTERVAL ══════════════════════════════
    qb(E,"23","What is a Lucid Interval? Give an Example.")
    E.append(Paragraph(
        "<b>Lucid interval</b> is a temporary period of apparent recovery of consciousness following head "
        "injury, during which the patient appears normal or near-normal, followed by subsequent neurological "
        "deterioration and loss of consciousness. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Period of apparent consciousness / normal behavior after head trauma, before secondary deterioration"],
        ["Classic cause","<b>Extradural hematoma (EDH)</b> – rupture of middle meningeal artery\nβ†’ blood accumulates slowly between skull and dura"],
        ["Mechanism","Initial concussion β†’ momentary LOC β†’ recovery (lucid interval) β†’ expanding hematoma β†’ rising ICP β†’ herniation β†’ coma β†’ death if untreated"],
        ["Duration","Minutes to hours (EDH); rarely days (chronic SDH)"],
        ["Classic example","Patient hit on temple (temporal bone fracture) β†’ stunned briefly β†’ walks, talks β†’ later deteriorates β†’ 'talk and die' syndrome"],
        ["Other causes","Subdural hematoma (less common); epidural in posterior fossa;\nsome contusions with secondary edema"],
        ["Forensic significance","Victim may have moved, called for help, or been found apparently well BEFORE collapsing;\nconcludes 'not immediately fatal' – medico-legal importance in homicide"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Lucid Interval in Extradural Hematoma</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("HEAD TRAUMA\n(Temporal region – pterion)","terminal"),
        ("Middle Meningeal Artery\nRUPTURES","rect"),
        ("Initial CONCUSSION\n(brief LOC / confusion)","rect"),
        ("LUCID INTERVAL:\nPatient conscious, talks, walks\n(blood slowly accumulating)","rounded"),
        ("Expanding EXTRADURAL HEMATOMA\n(blood between skull & dura)","rect"),
        ("Rising INTRACRANIAL PRESSURE\n(Cushing's triad: HTN, bradycardia, irregular RR)","rect"),
        ("UNCAL HERNIATION:\nIpsilateral pupil dilates\n(III nerve compression)","rect"),
        ("COMA β†’ Brain death\nif NOT surgically treated","terminal"),
    ],nh=35,gap=12))
    E.append(Spacer(1,10))

    # ════════════ Q142 COUNTER-COUP LESIONS ══════════════════════
    qb(E,"142","What are Counter-coup Lesions?")
    E.append(Paragraph(
        "A <b>coup lesion</b> is brain injury at the site of impact. A <b>contrecoup (counter-coup) lesion</b> "
        "is brain injury at the site OPPOSITE to the impact, caused by movement of the brain within the skull.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Coup lesion","Injury at the SAME SIDE as impact; due to direct compression"],
        ["Contrecoup lesion","Injury on the OPPOSITE side of impact; due to brain movement and negative pressure"],
        ["Mechanism","Moving head strikes stationary object β†’ brain decelerates suddenly β†’ brain rebounds β†’ opposite side hits skull β†’ contrecoup"],
        ["Where more severe","Contrecoup often MORE severe than coup lesion (paradoxically)"],
        ["Classic scenario","Fall on back of head β†’ frontal/temporal pole contrecoup injury"],
        ["Type of injury","Brain contusion (bruising of cortex); subdural hematoma; SAH at contrecoup site"],
        ["Frontal/temporal predilection","Contrecoup injuries favor frontal poles and temporal poles (rough floor of anterior/middle cranial fossa)"],
        ["Coup in fixed head","If head is stationary and struck by object β†’ coup > contrecoup"],
        ["Forensic use","Helps determine position of head at time of impact; coup = point of impact; contrecoup = movement"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Coup vs Contrecoup Injury</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("MOVING HEAD strikes\nSTATIONARY OBJECT\n(e.g., fall on back of head)","terminal"),
        ("COUP injury:\nAt impact site (occipital)\n– direct compression","rect"),
        ("Brain continues to MOVE\nforward (inertia)","rect"),
        ("Brain slams into OPPOSITE\ninner skull surface","rect"),
        ("CONTRECOUP injury:\nFrontal + temporal poles\n(more severe than coup)","rect"),
        ("FORENSIC VALUE:\nCoup site = WHERE head hit;\nContrecoup = DIRECTION of impact","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))

    # ════════════ Q156 TYPES OF SKULL FRACTURES ══════════════════
    qb(E,"156","What are the Types of Skull Fractures?")
    E.append(tbl(["Type","Description","Common Cause","Significance"],[
        ["<b>Linear fracture</b>","Simple crack in skull;\nno displacement;\nmost common type","Blunt force over wide area","Underlying EDH possible;\nmay cross meningeal grooves β†’ vessel tear"],
        ["<b>Depressed fracture</b>","Fragment(s) driven inward\nbelow inner table level","Localized blunt force\n(hammer, stone)","Inner table β†’ dura/brain compression;\noften requires surgical elevation"],
        ["<b>Comminuted fracture</b>","Multiple fragments; spider-web pattern","Severe blunt force","Indicates severe force; fragment injury to brain"],
        ["<b>Pond fracture</b>","Smoothly depressed; ping-pong ball type;\nno fragmentation","Infants (yielding skull)","Infant trauma; non-accidental injury?"],
        ["<b>Gutter fracture</b>","Groove/channel cut through skull by bullet travelling parallel to skull surface","Tangential bullet wound","Bullet track visible; no entry into cranium"],
        ["<b>Ring fracture</b>","Circular fracture around foramen magnum","Fall from height;\nfalling on feet/buttocks","Force transmitted through spine/head;\nassociated with brainstem injury"],
        ["<b>Hinge fracture</b>","Transverse fracture through\nbase of skull","High-speed impact;\nfrontal blow","Splits skull base; associated with extensive basal fracture and bleeding"],
        ["<b>Contrecoup fracture</b>","At site opposite to impact","Fall on back","Rare; indicates unusual force direction"],
    ],cw=[3*cm,3.5*cm,2.5*cm,PAGE_W-2*M-9*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>SIGNS OF BASE OF SKULL FRACTURE:</b>",BOLD))
    E.append(tbl(["Sign","Indicates"],[
        ["Battle's sign (mastoid bruise)","Posterior fossa fracture"],
        ["Raccoon eyes (periorbital bruise)","Anterior fossa fracture"],
        ["CSF rhinorrhoea","Anterior fossa; cribriform plate fracture"],
        ["CSF otorrhoea","Petrous temporal bone fracture"],
        ["Hemotympanum","Petrous temporal fracture"],
        ["CN palsy (VII, VIII most common)","Petrous temporal fracture"],
    ]))
    E.append(Spacer(1,10))

    # ════════════ Q122 BURKING ════════════════════════════════════
    qb(E,"122","What is Burking?")
    E.append(Paragraph(
        "<b>Burking</b> is a method of homicide combining simultaneous <b>smothering + compression of chest</b> "
        "to cause asphyxia, named after <b>William Burke</b> (Edinburgh, 1828) who killed victims by this "
        "method to sell bodies to anatomists.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Named after","William Burke (Edinburgh, 1828); partner William Hare; sold bodies to Dr. Robert Knox"],
        ["Method","Attacker sits on victim's chest β†’ compresses thorax β†’ simultaneously covers nose and mouth (smothering) OR compresses neck"],
        ["Mechanism of death","Combined mechanical asphyxia:\n(1) Chest compression β†’ prevents respiration\n(2) Smothering β†’ blocks airway entry\nBoth acting simultaneously"],
        ["Why used historically","Left minimal marks β†’ body looked like natural death β†’ suitable for selling to anatomists"],
        ["PM findings","Asphyxial signs: petechiae (subconjunctival, petechial hemorrhage face);\ncyanosis; congestion;\nminimal external injuries (if done carefully);\nrib fractures may be seen (if heavy compression)"],
        ["Forensic challenge","May be mistaken for natural asphyxia or SIDS in infants"],
        ["Modern relevance","Child abuse; positional asphyxia (obese person sitting on infant/child);\nrestrained prisoners"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Burking Mechanism</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("ATTACKER sits on\nVICTIM'S CHEST","terminal"),
        ("CHEST COMPRESSION:\nRibs compressed β†’ lungs\ncannot expand (no respiration)","rect"),
        ("SIMULTANEOUSLY:\nNose + Mouth covered\n(smothering)","rect"),
        ("COMBINED ASPHYXIA:\nNo air intake;\nNo chest expansion","rect"),
        ("ASPHYXIAL DEATH:\nCyanosis; petechiae;\ncongestion","rect"),
        ("MINIMAL EXTERNAL MARKS\n(designed to look natural)","rounded"),
        ("PM: check ribs for fractures;\nasphyxial signs; face petechiae;\nNo other trauma","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))

    # ════════════ SUMMARY TABLE ════════════════════════════════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 4 β€” QUICK REFERENCE SUMMARY",
        S('sh',fontSize=13,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(Spacer(1,4))
    E.append(tbl(["Topic","Key 1-Liner"],[
        ["Abrasion","Superficial; epidermis only; types: scratch, graze, pressure, friction burn; scab forms in 12–24 hrs"],
        ["Abrasion ML importance","Direction of force; age of injury; weapon pattern; ante-mortem vs PM; defense wounds"],
        ["Contusion","Blood extravasation without skin break; color: red→purple→blue→green→yellow; vital reaction present"],
        ["True vs Artificial bruise","True: blood stains tissue, doesn't wash off, vital reaction; PM livor: washes away, no inflammation"],
        ["Laceration","Blunt force tear; irregular edges; tissue bridges (distinguishes from incised wound)"],
        ["Stab wound","Depth > surface; clean edges; no bridges; single vs double edge; abrasion collar if weapon has shoulder"],
        ["Entry vs Exit wound","Entry: smaller, inverted, abrasion collar; Exit: larger, everted, no collar"],
        ["Cut throat suicidal","Hesitation cuts; left side; no defense wounds; clothes removed; weapon near body"],
        ["Cut throat homicidal","No hesitation cuts; defense wounds; clothes intact; signs of struggle"],
        ["Primary impact injury","First vehicle contact; bumper fracture tibia/fibula at bumper height"],
        ["Secondary impact","Body hits bonnet/windscreen; head/trunk injuries"],
        ["AM vs PM wounds","AM: vital reaction, bleeding, bruising; PM: no inflammation, blood washes away"],
        ["Head injury signs","Battle's sign; raccoon eyes; CSF leak; lucid interval; Cushing's triad; pupil changes"],
        ["Lucid interval","Consciousness after injury then deterioration; EDH (middle meningeal artery)"],
        ["Contrecoup","Injury opposite impact site; fall on back β†’ frontal pole injury; more severe than coup"],
        ["Skull fractures","Linear (most common); Depressed; Ring (fall from height); Hinge (base of skull)"],
        ["Burking","Chest compression + smothering = combined asphyxia; named after William Burke 1828"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E, onFirstPage=hdr, onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__ == "__main__":
    build()
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter4_gen.py 2>&…

Running Command

ls -lh /home/daytona/workspace/forensic-medicine-pdfs/*.pdf

Chapter 4 is ready! Download here:

Chapter4 Mechanical Injuries

PDF Document Β· PDF

(57 KB)

Pure white background throughout - black text, black borders, black arrows. Perfect for printing.

What's inside Chapter 4:

Q.TopicFormat
29/141Abrasion – Types, Healing stages, ML ImportanceTables + Flowchart
82/137Contusion – Types, Color changes, ML ImportanceTables + Color Flowchart
50True Bruise vs Artificial Bruise11-feature comparison table
118Laceration – Types, vs Incised woundTables
5Stab Wound in 15-yr-old – documentationTables + Flowchart
71Firearm Entry vs Exit Wounds12-feature table + Flowchart
73Homicidal vs Suicidal Cut Throat12-feature table + Flowchart
26/45Primary, Secondary, Tertiary Impact (RTA)Table + Bumper fracture + Flowchart
134Ante-mortem vs Post-mortem Wounds11-feature table
3Signs of Head InjurySystem-wise table
23Lucid IntervalTable + EDH Flowchart
142Counter-coup LesionsTable + Flowchart
156Types of Skull FracturesTable + Base of skull signs
122BurkingTable + Flowchart

Updated chapter status:
  • βœ… Chapter 1 - Medical Jurisprudence (colored)
  • βœ… Chapter 2 - Post-Mortem & Autopsy (B&W)
  • βœ… Chapter 3 - Thanatology (B&W)
  • βœ… Chapter 4 - Mechanical Injuries (pure white)
Say "Make Chapter 5" (Burns & Thermal Injuries) whenever you're ready!

Yes

Writing File

~/forensic-medicine-pdfs/chapter5_gen.py

#!/usr/bin/env python3
"""Chapter 5: Burns & Thermal/Chemical Injuries – Pure White, Print-Ready
   Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
    TableStyle, PageBreak, KeepTogether)
from reportlab.platypus.flowables import Flowable

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter5_Burns_Injuries.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK = colors.black
WHITE = colors.white

def S(n,**k):
    return ParagraphStyle(n, parent=getSampleStyleSheet()['Normal'], **k)

TITLE = S('Ti', fontSize=22, textColor=BLACK, fontName='Helvetica-Bold', alignment=TA_CENTER, leading=28)
CHAP  = S('Ch', fontSize=15, textColor=BLACK, fontName='Helvetica-Bold', alignment=TA_CENTER)
REF   = S('Re', fontSize=8,  textColor=BLACK, fontName='Helvetica-Oblique', alignment=TA_CENTER)
QS    = S('Qs', fontSize=12, textColor=BLACK, fontName='Helvetica-Bold', leading=17, leftIndent=8)
BODY  = S('Bo', fontSize=10, textColor=BLACK, leading=15, spaceAfter=3, fontName='Helvetica', alignment=TA_JUSTIFY)
BOLD  = S('Bl', fontSize=10, textColor=BLACK, leading=15, spaceAfter=3, fontName='Helvetica-Bold')
NOTE  = S('No', fontSize=9,  textColor=BLACK, fontName='Helvetica-Oblique', leading=13, leftIndent=10)
MNEM  = S('Mn', fontSize=10.5, textColor=BLACK, fontName='Helvetica-Bold', leading=15, leftIndent=10)
TH    = S('TH', fontSize=8.5, textColor=BLACK, fontName='Helvetica-Bold', alignment=TA_CENTER, leading=12)
TC    = S('TC', fontSize=8.5, textColor=BLACK, fontName='Helvetica', leading=12, alignment=TA_LEFT)

def hdr(canv, doc):
    canv.saveState()
    canv.setStrokeColor(BLACK); canv.setLineWidth(1.5)
    canv.line(M, PAGE_H-1.0*cm, PAGE_W-M, PAGE_H-1.0*cm)
    canv.setFillColor(BLACK); canv.setFont('Helvetica-Bold', 9)
    canv.drawString(M, PAGE_H-0.78*cm, "FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica', 8)
    canv.drawRightString(PAGE_W-M, PAGE_H-0.78*cm, "Chapter 5: Burns & Thermal/Chemical Injuries")
    canv.line(M, 0.85*cm, PAGE_W-M, 0.85*cm)
    canv.setFont('Helvetica', 8)
    canv.drawString(M, 0.32*cm, "Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M, 0.32*cm, f"Page {doc.page}")
    canv.restoreState()

def qb(E, num, txt):
    t = Table([[Paragraph(f"Q.{num}  {txt}", QS)]], colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),('RIGHTPADDING',(0,0),(-1,-1),10),
    ]))
    E.append(KeepTogether([t])); E.append(Spacer(1,5))

def tbl(headers, rows, cw=None):
    avail = PAGE_W-2*M-0.2*cm
    if not cw: cw = [avail/len(headers)]*len(headers)
    data = [[Paragraph(h,TH) for h in headers]]
    for r in rows: data.append([Paragraph(str(c),TC) for c in r])
    t = Table(data, colWidths=cw, repeatRows=1)
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1),WHITE),('TEXTCOLOR',(0,0),(-1,-1),BLACK),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),('FONTNAME',(0,1),(-1,-1),'Helvetica'),
        ('FONTSIZE',(0,0),(-1,-1),8.5),('GRID',(0,0),(-1,-1),0.6,BLACK),
        ('LINEBELOW',(0,0),(-1,0),1.2,BLACK),('VALIGN',(0,0),(-1,-1),'TOP'),
        ('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4),
        ('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),
    ]))
    return t

class FC(Flowable):
    def __init__(self, nodes, width=None, nh=34, gap=15):
        super().__init__()
        self.nodes=nodes; self.nw=width or (PAGE_W-2*M-0.5*cm)
        self.nh=nh; self.gap=gap
        self.width=self.nw; self.height=len(nodes)*(nh+gap)-gap+20
    def wrap(self,aW,aH): return self.width,self.height
    def draw(self):
        c=self.canv; y=self.height-10
        nw,nh,gap=self.nw,self.nh,self.gap; cx=nw/2
        for i,(text,shape) in enumerate(self.nodes):
            top=y-nh; mid=y-nh/2
            c.setFillColor(WHITE); c.setStrokeColor(BLACK)
            lw=1.8 if shape=='terminal' else 1.2; c.setLineWidth(lw)
            if shape=='terminal':
                c.roundRect(cx-nw*.38,top,nw*.76,nh,nh/2,fill=1,stroke=1)
            elif shape=='diamond':
                p=c.beginPath(); p.moveTo(cx,y); p.lineTo(cx+nw*.42,mid)
                p.lineTo(cx,top); p.lineTo(cx-nw*.42,mid); p.close()
                c.drawPath(p,fill=1,stroke=1)
            elif shape=='rounded':
                c.roundRect(cx-nw*.44,top,nw*.88,nh,8,fill=1,stroke=1)
            else:
                c.rect(cx-nw*.44,top,nw*.88,nh,fill=1,stroke=1)
            c.setFillColor(BLACK)
            bold=shape in('terminal','diamond')
            c.setFont('Helvetica-Bold' if bold else 'Helvetica',8.5)
            lines=text.split('\n'); lh=11
            ty=mid+len(lines)*lh/2-lh*.7
            for ln in lines: c.drawCentredString(cx,ty,ln); ty-=lh
            if i<len(self.nodes)-1:
                ay=top-gap; c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx,top,cx,ay+6); c.setFillColor(BLACK)
                p=c.beginPath(); p.moveTo(cx,ay); p.lineTo(cx-5,ay+8); p.lineTo(cx+5,ay+8)
                p.close(); c.drawPath(p,fill=1,stroke=0)
            y=top-gap

# ════════════════════════════════════════════════════════════════
def build():
    doc = SimpleDocTemplate(OUTPUT, pagesize=A4,
        leftMargin=M, rightMargin=M, topMargin=1.4*cm, bottomMargin=1.2*cm,
        title="Chapter 5 – Burns & Thermal/Chemical Injuries")
    E = []

    # COVER
    E.append(Spacer(1,1.2*cm))
    bdr=Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY",TITLE)]],colWidths=[PAGE_W-2*M])
    bdr.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),3,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),18),('BOTTOMPADDING',(0,0),(-1,-1),18)]))
    E.append(bdr); E.append(Spacer(1,.4*cm))
    cb=Table([[Paragraph("CHAPTER 5",CHAP)]],colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2=Table([[Paragraph("Burns &amp; Thermal / Chemical Injuries",
        S('tb',fontSize=18,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.3*cm))
    rb=Table([[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed",REF)]],
        colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))
    E.append(Paragraph("CHAPTER CONTENTS",S('toch',fontSize=11,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["9","Burns in 30-yr-old – Assess Area (Rule of Nines) & Depth"],
        ["144","Rule of Nines (Wallace Rule)"],
        ["14","Filigree Burns (Lightning Burns)"],
        ["67 / 159","Difference: Ante-mortem vs Post-mortem Burns"],
        ["80 / 91 / 125","Joule Burns (Electrical Burns)"],
        ["94","Differences: Dry Heat vs Moist Heat vs Chemical Burns"],
        ["18","Concentrated Acid Burns – Management"],
        ["162","Vitriolage"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # Q9 / Q144 – BURN ASSESSMENT: AREA & DEPTH + RULE OF NINES
    # ══════════════════════════════════════════════════════════════
    qb(E,"9 / 144","Burns in a 30-yr-old Woman – Assess Burn Area & Depth | Rule of Nines (Wallace Rule)")
    E.append(Paragraph(
        "A 30-year-old woman sustained burns while cooking. Assessment requires TWO steps: "
        "<b>(1) Area of burn</b> – using Rule of Nines, and <b>(2) Depth of burn</b> – using clinical criteria.",BODY))
    E.append(Spacer(1,4))

    E.append(Paragraph("<b>PART A: RULE OF NINES (Wallace Rule of Nines, 1951) – Burn Area Assessment</b>",BOLD))
    E.append(tbl(["Body Region","Adult % (Rule of Nines)","Notes"],[
        ["Head & Neck","9%","Single unit"],
        ["Each Upper Limb","9% each (total 18%)","Arm: 4%, Forearm: 3%, Hand: 2%"],
        ["Anterior Trunk","18%","Chest: 9%; Abdomen: 9%"],
        ["Posterior Trunk","18%","Upper back: 9%; Lower back: 9%"],
        ["Each Lower Limb","18% each (total 36%)","Thigh: 9%, Leg+foot: 9%"],
        ["Perineum / Genitalia","1%","Single unit"],
        ["TOTAL","100%",""],
        ["Palmar surface of patient's hand","~1%","Lund-Browder chart more accurate for children"],
    ]))
    E.append(Spacer(1,4))
    E.append(Paragraph("<b>In this case (cooking burns – typically face, arms, anterior trunk):</b>",BOLD))
    E.append(Paragraph(
        "Face + Neck = 9%; Both hands/forearms = ~12%; Anterior trunk = 18%. "
        "Total estimated TBSA (Total Body Surface Area) = depends on extent. "
        "<b>Burns > 15% TBSA in adults = major burn requiring hospital admission.</b>",BODY))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>PART B: DEPTH OF BURN ASSESSMENT</b>",BOLD))
    E.append(tbl(["Degree / Depth","Layers Affected","Clinical Features","Healing","Example"],[
        ["<b>1st Degree</b>\n(Superficial / Epidermal)","Epidermis only\n(outer layer)","Redness (erythema); pain;\nDRY; NO blisters;\nNO skin loss","3–5 days;\nno scarring","Sunburn; brief flash"],
        ["<b>2nd Degree – Superficial</b>\n(Superficial Partial Thickness)","Epidermis +\nsuperficial dermis","BLISTERS; moist; pink/red;\npainful; blanches on pressure","10–14 days;\nminimal scarring","Scalding; brief flame"],
        ["<b>2nd Degree – Deep</b>\n(Deep Partial Thickness)","Epidermis +\ndeep dermis","Pale/white; blisters;\nless painful (deep nerve damage);\ndoes NOT blanch","21–35 days;\nscarring likely;\nmay need grafting","Prolonged flame/scald"],
        ["<b>3rd Degree</b>\n(Full Thickness)","Entire skin\n(epidermis + dermis)","Leathery, white/brown/black;\nDRY; painless (nerve destroyed);\ncharring possible;\nno blisters","Does NOT self-heal;\nmust be grafted;\nscarring","Prolonged flame; electrical"],
        ["<b>4th Degree</b>","Skin + subcutaneous +\nmuscle/bone","Black; charred; dry;\ninvolves deep structures","Amputation often needed","Electrical; prolonged fire"],
    ],cw=[3.5*cm,2.8*cm,3.5*cm,2.5*cm,PAGE_W-2*M-12.3*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>MANAGEMENT PRINCIPLES (Acid/Cooking Burns):</b>",BOLD))
    E.append(tbl(["Step","Action"],[
        ["1. STOP THE BURNING","Remove from heat source; remove burning clothing (not stuck to skin)"],
        ["2. COOL THE BURN","Run cool water 20 min (NOT ice – causes vasoconstriction)"],
        ["3. ASSESS area + depth","Rule of Nines; clinical depth assessment"],
        ["4. Airway","If face/neck burned or inhalation injury β†’ early intubation"],
        ["5. IV fluids","Parkland formula: 4 mL Γ— kg Γ— %TBSA (Ringer's Lactate); first half in 8 hrs"],
        ["6. Analgesia","IV morphine; paracetamol"],
        ["7. Wound care","Non-adherent dressings; silver sulfadiazine for superficial; debridement + grafting for deep"],
        ["8. Tetanus prophylaxis","All burn patients"],
        ["9. Nutrition","Early enteral feeding; high protein; hypermetabolic state"],
        ["10. Referral","Burns > 10% TBSA; face/hands/genitalia; full thickness; inhalation β†’ burns unit"],
    ],cw=[1.8*cm,PAGE_W-2*M-1.8*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Assessment of Burns</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("BURN INJURY","terminal"),
        ("STOP burning: remove from source;\nremove clothing","rect"),
        ("COOL with running water 20 min\n(NOT ice)","rect"),
        ("Assess AREA:\nRule of Nines (% TBSA)","rect"),
        ("Assess DEPTH:\n1st / 2nd / 3rd / 4th degree","rect"),
        ("MAJOR BURN?\n(>15% TBSA adult; >10% child;\nface/hands/airway)","diamond"),
        ("IV access; Parkland formula;\nAirway management;\nICU admission","rect"),
        ("WOUND CARE:\ndressings; silver sulfadiazine;\ngrafting if full thickness","rect"),
        ("MONITOR:\nFluids, urine output, sepsis,\nnutrition, rehabilitation","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,8))

    # RULE OF NINES DIAGRAM (text-based ASCII in a bordered table)
    E.append(Paragraph("<b>RULE OF NINES – DIAGRAMMATIC REPRESENTATION</b>",BOLD))
    E.append(Spacer(1,4))
    diag_data = [
        [Paragraph("<b>ANTERIOR</b>",S('dc',fontSize=9,fontName='Helvetica-Bold',alignment=TA_CENTER)),
         Paragraph("<b>BODY REGION</b>",S('dc2',fontSize=9,fontName='Helvetica-Bold',alignment=TA_CENTER)),
         Paragraph("<b>POSTERIOR</b>",S('dc3',fontSize=9,fontName='Helvetica-Bold',alignment=TA_CENTER))],
        [Paragraph("9%",TC), Paragraph("HEAD & NECK",S('bm',fontSize=9,fontName='Helvetica-Bold',alignment=TA_CENTER)), Paragraph("(included)",TC)],
        [Paragraph("9%",TC), Paragraph("CHEST (anterior trunk upper)",S('bm2',fontSize=9,alignment=TA_CENTER)), Paragraph("9%",TC)],
        [Paragraph("9%",TC), Paragraph("ABDOMEN (anterior trunk lower)",S('bm3',fontSize=9,alignment=TA_CENTER)), Paragraph("9%",TC)],
        [Paragraph("9% each",TC), Paragraph("UPPER LIMBS (Γ—2 = 18%)",S('bm4',fontSize=9,alignment=TA_CENTER)), Paragraph("(included)",TC)],
        [Paragraph("18% each",TC), Paragraph("LOWER LIMBS (Γ—2 = 36%)",S('bm5',fontSize=9,alignment=TA_CENTER)), Paragraph("(included)",TC)],
        [Paragraph("1%",TC), Paragraph("PERINEUM",S('bm6',fontSize=9,alignment=TA_CENTER)), Paragraph("β€”",TC)],
        [Paragraph("",TC), Paragraph("<b>TOTAL = 100%</b>",S('tot',fontSize=10,fontName='Helvetica-Bold',alignment=TA_CENTER)), Paragraph("",TC)],
    ]
    avail=PAGE_W-2*M-0.2*cm
    diag_tbl=Table(diag_data,colWidths=[avail*0.2,avail*0.6,avail*0.2])
    diag_tbl.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1),WHITE),('GRID',(0,0),(-1,-1),0.6,BLACK),
        ('LINEBELOW',(0,0),(-1,0),1.2,BLACK),('ALIGN',(0,0),(-1,-1),'CENTER'),
        ('VALIGN',(0,0),(-1,-1),'MIDDLE'),
        ('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4),
    ]))
    E.append(diag_tbl)
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # Q14 – FILIGREE BURNS (LIGHTNING BURNS)
    # ══════════════════════════════════════════════════════════════
    qb(E,"14","What are Filigree Burns (Lightning Burns)?")
    E.append(Paragraph(
        "<b>Filigree burns</b> (also called <b>arborescent burns</b>, <b>Lichtenberg figures</b>, or "
        "<b>lightning flowers</b>) are the characteristic skin markings produced by lightning strike.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Also called","Arborescent burns; Lichtenberg figures; Lightning flowers; Fern-leaf pattern; Keraunographic markings"],
        ["Appearance","Tree-branch / fern-leaf / lightning-bolt pattern on skin;\nreddish-pink or brown branching marks radiating outward"],
        ["Mechanism","High voltage lightning (10–100 million volts) causes current to flow along skin surface (flashover);\nelectron avalanche in skin produces this pattern;\nNOT a true burn but capillary rupture + skin damage"],
        ["Location","Usually on trunk, shoulders, neck; follows path of least resistance (moist areas)"],
        ["Duration","Temporary (transient): appear within minutes; may fade within hours to days;\nnot always present at PM if delayed"],
        ["Pathognomonic","PATHOGNOMONIC of lightning strike – no other cause produces this pattern"],
        ["Other lightning injuries","Cardiac arrest; respiratory arrest; retinal detachment;\ncataract; ruptured eardrum; blast injuries;\nfootprint pattern (current enters feet if standing);\nclothes blown off"],
        ["Cause of death in lightning","Ventricular fibrillation (VF) β†’ cardiac arrest;\ncardiorespiratory arrest"],
        ["PM findings","Filigree burns on skin; singed hair; punctate entry/exit burns;\nmetallic objects melted; magnetically charged"],
        ["Forensic significance","Confirms cause of death as lightning; PATHOGNOMONIC"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Lightning Strike Injuries</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("LIGHTNING STRIKE\n(10–100 million volts)","terminal"),
        ("DIRECT STRIKE or FLASHOVER\nthrough skin surface","rect"),
        ("FILIGREE BURNS on skin\n(fern-leaf / arborescent pattern)\n– PATHOGNOMONIC","rounded"),
        ("CARDIAC ARREST\n(VF – most common cause of death)","rect"),
        ("RESPIRATORY ARREST\n(respiratory centre damage)","rect"),
        ("OTHER: Retinal detachment;\ncataract; ruptured eardrum;\nblast effect","rect"),
        ("RESUSCITATION possible\n(no 'spent' charge –\nsafe to touch victim)","diamond"),
        ("DEATH: VF + respiratory arrest;\nPM: filigree burns + metallic melting","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))

    # ══════════════════════════════════════════════════════════════
    # Q67 / Q159 – ANTE-MORTEM vs POST-MORTEM BURNS
    # ══════════════════════════════════════════════════════════════
    qb(E,"67 / 159","Difference Between Ante-mortem and Post-mortem Burns")
    E.append(Paragraph(
        "Distinguishing ante-mortem from post-mortem burns is crucial for determining whether the deceased "
        "was alive when the fire started – key in arson/murder investigations. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Feature","ANTE-MORTEM Burns","POST-MORTEM Burns"],[
        ["Vital reaction","PRESENT:\n- Inflammatory response at burn margins\n- Leucocytic infiltration (histology)\n- Erythema, blistering","ABSENT:\nNo inflammation; no leucocytes"],
        ["Blisters","Present: filled with SERUM/plasma\n(protein-rich); thin-walled","May be present: filled with GAS\n(putrefaction gas or steam);\nthick-walled"],
        ["Blister content","Serum: protein-rich, slightly turbid","Gas or watery fluid; no protein"],
        ["Redness (erythema)","Vivid red; hyperemia at margins","Absent or pale; no vascular response"],
        ["Carbon monoxide in blood","HbCO saturation ELEVATED\n(> 10%; often > 50%)\n→ victim breathed smoke","HbCO normal (< 10%)\n→ did not breathe smoke"],
        ["Soot in airway","PRESENT in trachea, bronchi, alveoli\n(inhaled before death)","ABSENT (no breathing after death)"],
        ["Pugilistic attitude","Present (muscle contraction from heat)\n– ALSO in PM burns (heat artifact)","Present (does NOT distinguish)"],
        ["Skin splitting","Present but with vital reaction","Present but no vital reaction"],
        ["Histology","Leucocyte infiltration; vessel dilation; fibrin","No leucocytes; no fibrin"],
        ["Cause of death","May be burns, smoke inhalation, CO poisoning","Burns inflicted after death; actual COD different"],
        ["'Heat hematoma'","May form from heat (bilateral)\nbut skull fractures also possible from fall","Epidural heat hematoma can form PM;\nshould not be confused with traumatic EDH"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>KEY TESTS TO DETERMINE ANTE-MORTEM BURNS:</b>",BOLD))
    E.append(tbl(["Test","Ante-mortem Result","Post-mortem Result"],[
        ["HbCO in blood","ELEVATED (> 10–50%)","Normal (< 10%)"],
        ["Soot in trachea/bronchi","PRESENT","ABSENT"],
        ["Histology of skin","Leucocytes + fibrin at margins","No leucocytes"],
        ["Blister fluid","Protein-rich serum","Gas or watery fluid"],
        ["Vital reaction","Present","Absent"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Determining Ante-mortem vs Post-mortem Burns</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("BURNED BODY found","terminal"),
        ("Check AIRWAY:\nSoot in trachea/bronchi?","diamond"),
        ("YES → Victim BREATHED SMOKE\n→ ANTE-MORTEM burn","rounded"),
        ("Check BLOOD:\nHbCO > 10%?","diamond"),
        ("YES → CO inhaled before death\n→ ANTE-MORTEM","rounded"),
        ("HISTOLOGY of burn margin:\nLeucocytes / fibrin present?","diamond"),
        ("YES → Vital reaction\n→ ANTE-MORTEM","rounded"),
        ("NO to all:\nNo soot; normal HbCO;\nno vital reaction","rect"),
        ("POST-MORTEM burn\n(body was dead before fire)","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # Q80 / Q91 / Q125 – JOULE BURNS (ELECTRICAL)
    # ══════════════════════════════════════════════════════════════
    qb(E,"80 / 91 / 125","What are Joule Burns? (Electrical Burns)")
    E.append(Paragraph(
        "<b>Joule burns</b> (electrical burns) are injuries caused by the passage of electrical current through "
        "the body. Named after James Prescott Joule (heat produced = IΒ²RT). "
        "Also called <b>electrothermal burns</b> or <b>contact burns</b>.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Cause","Passage of electrical current β†’ heat generated (Joule's law: H = IΒ²RT)"],
        ["Entry mark\n(Joule burn mark)","At point of electrical CONTACT:\nSmall, round/oval, punched-out crater;\nCharacteristic raised, firm, yellowish-white center;\nbrown/blackened edges;\nhyperemic margin (ante-mortem vital reaction);\nSize = approx. size of contact area"],
        ["Exit mark","At point where current leaves body (earthing point);\nSimilar appearance but often larger, more irregular;\nmay be on soles/heels if standing"],
        ["Metallic impregnation","Copper/iron deposits in skin at entry point\n(from conductor);\ngives blue/greenish discoloration"],
        ["'Electric mark' (Tardieu)","Pale, firm, slightly elevated area\nat current entry point"],
        ["Electroporation","High voltage: cell membranes disrupted;\nmassive internal injury without external signs"],
        ["Internal damage","Track of current: deep burns, muscle necrosis,\nvascular thrombosis, nerve damage;\noften more extensive than external appearance"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Factor","Effect on Severity"],[
        ["Voltage","High voltage (> 1000V) = more tissue destruction; flashover; arc burns"],
        ["Current type","AC (alternating) more dangerous than DC; tetanic contraction β†’ victim cannot release grip"],
        ["Resistance","Wet skin = lower resistance = more current flows = worse injury"],
        ["Duration of contact","Longer = more heat generated (H = IΒ²RT)"],
        ["Path of current","Through heart β†’ VF; through brain β†’ respiratory arrest; through hands/feet = less critical"],
    ]))
    E.append(Spacer(1,5))
    E.append(tbl(["Cause of Death in Electrocution","Details"],[
        ["Ventricular fibrillation (VF)","Most common; even low domestic current (50–100 mA, AC) can cause VF"],
        ["Respiratory paralysis","Current through respiratory centre or diaphragm"],
        ["Tetanic contraction of respiratory muscles","AC causes sustained spasm β†’ respiratory arrest"],
        ["Burns (delayed)","Major burns β†’ sepsis; organ failure"],
        ["Fall from height","Reflex muscle contraction throws victim"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Joule Burns – Entry to Death</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("ELECTRICAL CONTACT\n(conductor touches body)","terminal"),
        ("ENTRY MARK (Joule burn):\nSmall, round, punched-out;\nfirm yellow-white center;\nbrown edges; vital reaction","rect"),
        ("Current travels THROUGH body\n(path of least resistance)","rect"),
        ("INTERNAL DAMAGE:\nMuscle necrosis; vascular thrombosis;\nmore extensive than external","rect"),
        ("EXIT MARK:\nEarth/ground contact point;\nsimilar but often larger","rect"),
        ("CAUSE OF DEATH?\n(VF / Respiratory arrest / Burns)","diamond"),
        ("VF: cardiac arrest\n(most common – even 100 mA AC)","rounded"),
        ("Respiratory arrest:\ncurrent through brain/diaphragm","rounded"),
        ("PM: entry + exit marks;\nmetallic impregnation;\nhistology confirms vital reaction","terminal"),
    ],nh=35,gap=12))
    E.append(Spacer(1,10))

    # ══════════════════════════════════════════════════════════════
    # Q94 – DRY HEAT vs MOIST HEAT vs CHEMICAL BURNS
    # ══════════════════════════════════════════════════════════════
    qb(E,"94","Differences Between Burns from Dry Heat, Moist Heat, and Chemicals")
    E.append(tbl(["Feature","DRY HEAT Burns","MOIST HEAT (Scalds)","CHEMICAL Burns"],[
        ["Agent","Flame, radiant heat,\nhot solid objects","Hot water, steam,\nhot liquids","Acids, alkalis,\nphosphorus, solvents"],
        ["Appearance","Charring; eschar formation;\ncrisping of skin;\nleathery","Blisters predominant;\nmoist, red surface;\nno charring","Variable: acid = coagulative necrosis\n(brown/black eschar);\nalkali = liquefactive necrosis\n(soft, soapy, deep)"],
        ["Depth","Depends on temp + duration;\noften deeper centrally","Usually superficial-partial;\nsteam can be full thickness","Depends on agent + duration;\nalkali penetrates deeper than acid"],
        ["Blisters","May be present but often\nrupture (flame)","LARGE blisters;\nprominent feature","Less blistering; eschar more typical"],
        ["Margins","Well-defined line;\npatterned (if contact)","Drip/splash pattern;\nirregular run-down pattern","Irregular; may spread as chemical absorbed"],
        ["Eschar / Crust","Dry, firm eschar (if full thickness)","Moist, soft if superficial","Acid: hard leathery eschar;\nAlkali: soft gelatinous eschar"],
        ["Pain","Initial pain; painless if full thickness","Very painful\n(superficial nerve endings)","Acid: burning pain;\nAlkali: pain may be delayed"],
        ["Color","Red β†’ brown β†’ black (charring)","Red-pink; white-grey if deep","Acid: brown/black;\nAlkali: grey-white-green;\nHF acid: penetrating"],
        ["Systemic effects","Inhalation injury; CO poisoning\n(from fire)","Fluid loss; infection","Systemic absorption;\nHF: hypocalcemia;\nChromic acid: renal failure"],
        ["Forensic features","Pugilistic attitude (heat contract);\nHbCO elevated if alive","'Glove-stocking' pattern (immersion);\ndrip marks = splash","Specific chemical odor;\ncaustic tissue appearance;\ncriminal assault (vitriolage)"],
    ],cw=[3*cm,3.3*cm,3.5*cm,PAGE_W-2*M-9.8*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Type of Burn β†’ Identification</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("BURN INJURY – determine type","terminal"),
        ("CHARRING present?\nDry, leathery, crisp eschar?","diamond"),
        ("YES β†’ DRY HEAT (flame/contact);\nCheck HbCO; inhalation injury","rounded"),
        ("Large BLISTERS; moist surface;\ndrip/splash pattern?","diamond"),
        ("YES β†’ MOIST HEAT (scald);\ndrip = pour; glove = immersion","rounded"),
        ("Eschar without charring;\nChemical odor;\nIrregular spread?","diamond"),
        ("YES β†’ CHEMICAL BURN;\nAcid (hard eschar) vs\nAlkali (soft gelatinous)","rounded"),
        ("Fern-leaf pattern;\nsingle entry/exit point?","diamond"),
        ("YES β†’ ELECTRICAL / LIGHTNING","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ══════════════════════════════════════════════════════════════
    # Q18 – ACID BURNS MANAGEMENT
    # ══════════════════════════════════════════════════════════════
    qb(E,"18","40-year-old Man Exposed to Concentrated Acid – Describe Management")
    E.append(Paragraph(
        "Concentrated acid causes <b>coagulative necrosis</b> of tissues. The coagulum (eschar) formed "
        "acts as a barrier limiting deeper penetration (unlike alkali). Immediate decontamination is critical.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Phase","Step","Details"],[
        ["IMMEDIATE\n(Scene)","1. Remove from source","Move victim away from acid; do NOT run if acid on clothes"],
        ["","2. Remove clothing/jewelry","Cut off acid-soaked clothes; remove jewelry (metal reacts with acid); wear gloves"],
        ["","3. Irrigate immediately","Copious water irrigation: minimum 20–30 minutes\n(do NOT use alkali to neutralize – exothermic reaction causes more damage)"],
        ["","4. Do NOT neutralize","No baking soda, no alkali – neutralization releases heat"],
        ["HOSPITAL\n(ED)","5. Airway","If acid splashed on face/inhaled β†’ stridor, bronchospasm β†’ early intubation"],
        ["","6. Irrigation continues","Irrigate until pH of run-off water is neutral (pH paper test)"],
        ["","7. Eyes (if involved)","Urgent ophthalmology; continuous saline irrigation; visual loss risk"],
        ["","8. IV access + fluids","Two large-bore IVs; Ringer's Lactate; Parkland formula if > 15% TBSA"],
        ["","9. Analgesia","IV opioids (morphine); do NOT apply any ointments initially"],
        ["","10. Wound assessment","Assess depth + area; eschar formation; chemical burns may initially look superficial then deepen"],
        ["SPECIFIC ACIDS","HF (hydrofluoric) acid","Calcium gluconate gel/injection at wound; systemic hypocalcemia; cardiac monitoring"],
        ["","Carbolic acid (phenol)","Polyethylene glycol irrigation; systemic toxicity (convulsions, cardiac)"],
        ["","H2SO4 (sulfuric)","Copious water only; produces heat with water β†’ irrigate slowly"],
        ["ONGOING","Wound dressing","Non-adherent dressings; silver sulfadiazine; debridement; grafting for deep burns"],
        ["","Tetanus + antibiotics","Tetanus prophylaxis; antibiotics if infection signs"],
        ["FORENSIC NOTE","Documentation","Photograph immediately; MLC report; body diagrams; chain of custody for clothing samples"],
    ],cw=[2.5*cm,3*cm,PAGE_W-2*M-5.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Management of Acid Burns</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("CONCENTRATED ACID EXPOSURE","terminal"),
        ("REMOVE from source;\nRemove acid-soaked clothing (gloves on)","rect"),
        ("COPIOUS WATER IRRIGATION\n20–30 min (NOT neutralization)","rect"),
        ("AIRWAY threatened?\n(face/neck/inhalation)","diamond"),
        ("YES: Early INTUBATION;\nanaesthesia support","rounded"),
        ("HOSPITAL: Continue irrigation\nuntil run-off pH neutral","rect"),
        ("IV ACCESS + Fluids\n(Parkland formula if > 15% TBSA)","rect"),
        ("EYES involved?\nUrgent ophthalmology; continuous saline","rounded"),
        ("HF Acid?\nCalcium gluconate + cardiac monitor","rounded"),
        ("WOUND ASSESSMENT:\ndepth, area; dressings;\ngrafting for deep burns","rect"),
        ("DOCUMENT for MLC:\nphotograph; clothing samples;\nchain of custody","terminal"),
    ],nh=34,gap=11))
    E.append(Spacer(1,10))

    # ══════════════════════════════════════════════════════════════
    # Q162 – VITRIOLAGE
    # ══════════════════════════════════════════════════════════════
    qb(E,"162","What is Vitriolage?")
    E.append(Paragraph(
        "<b>Vitriolage</b> (acid throwing / acid attack) is the deliberate throwing of a caustic substance "
        "(usually concentrated sulfuric acid – 'oil of vitriol') on another person's face/body with intent "
        "to disfigure, harm, or kill. It is a criminal offence.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Deliberate act of throwing acid/caustic substance on a person causing burns, disfigurement, permanent injury"],
        ["Common agents","Concentrated H2SO4 (oil of vitriol – most common);\nHNO3 (nitric acid); HCl (hydrochloric acid);\nNaOH (caustic soda – alkali)"],
        ["Motive","Personal vendetta; domestic violence; rejection; property disputes; dowry disputes; gender-based violence"],
        ["Target areas","Face (most common – to disfigure permanently);\nneck, arms, genitalia"],
        ["Injuries","Disfigurement; blindness; hearing loss; psychological trauma;\nrespiratory injury (vapors)"],
        ["IPC provisions","IPC Section 326A: Voluntarily causing grievous hurt by use of acid (10 yrs to life);\nIPC Section 326B: Attempt to throw acid (5–7 yrs);\nBNS: Sections 124, 125"],
        ["Acid sale regulation","Acid sale regulated; ID proof required; records maintained (Supreme Court order 2013)"],
        ["Medical management","Same as acid burns (above); early decontamination; airway; IV fluids; grafting"],
        ["Forensic documentation","Photograph immediately; describe burns site/pattern; collect clothing; victim's statement;\nchain of custody; MLC report"],
        ["Prognosis","Permanent disfigurement; multiple surgeries; psychological support essential"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,10))

    # ══════════════════════════════════════════════════════════════
    # SUMMARY TABLE
    # ══════════════════════════════════════════════════════════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 5 β€” QUICK REFERENCE SUMMARY",
        S('sh',fontSize=13,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(Spacer(1,4))
    E.append(tbl(["Topic","Key 1-Liner"],[
        ["Rule of Nines","Head 9%; each arm 9%; ant trunk 18%; post trunk 18%; each leg 18%; perineum 1%"],
        ["Burn depth","1st: epidermal; 2nd superficial: blisters; 2nd deep: pale, less pain; 3rd: full thickness, painless; 4th: bone/muscle"],
        ["Major burn criteria","Adults: > 15% TBSA; children: > 10%; face/hands/airway involved"],
        ["Parkland formula","4 mL Γ— kg Γ— %TBSA; Ringer's Lactate; half in first 8 hrs"],
        ["Filigree burns","Fern-leaf/arborescent pattern; pathognomonic of lightning strike; transient; caused by flashover"],
        ["Lightning death","Cardiac arrest (VF); respiratory arrest; filigree burns + metallic melting at PM"],
        ["AM vs PM burns","AM: soot in airway, HbCO elevated, vital reaction (leucocytes); PM: none of these"],
        ["Joule burns","Electrical contact mark; small round punched-out crater; firm yellow-white center; entry + exit marks"],
        ["Electrical COD","VF most common (100 mA AC); respiratory arrest; AC > DC; wet skin = worse"],
        ["Dry heat burns","Charring; eschar; pugilistic attitude; HbCO if enclosed space fire"],
        ["Moist heat burns","Large blisters; drip pattern; glove-stocking = immersion"],
        ["Chemical burns","Acid = coagulative necrosis (hard eschar); Alkali = liquefactive necrosis (soft/deep)"],
        ["Acid burn management","Copious water 20–30 min; NO neutralization; airway; IV fluids; HF β†’ Ca gluconate"],
        ["Vitriolage","Deliberate acid throwing; IPC 326A (10 yrs–life); 326B (attempt 5–7 yrs); face most targeted"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E, onFirstPage=hdr, onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__ == "__main__":
    build()
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter5_gen.py 2>&…

Running Command

ls -lh /home/daytona/workspace/forensic-medicine-pdfs/*.pdf

Chapter 5 is ready!

Chapter5 Burns Injuries

PDF Document Β· PDF

(42 KB) β€” Pure white, print-ready

What's inside Chapter 5:

Q.TopicFormat
9/144Burns assessment: Rule of Nines + Depth gradingTables + Diagram + Flowchart
144Rule of Nines (Wallace Rule) diagrammatic tableLabeled body region table
14Filigree Burns (Lightning)Table + Flowchart
67/159Ante-mortem vs Post-mortem Burns11-feature comparison table + Flowchart
80/91/125Joule Burns (Electrical)Tables + Flowchart
94Dry Heat vs Moist Heat vs Chemical BurnsFull 10-feature comparison table + Identification Flowchart
18Acid Burns ManagementStep-by-step table + Flowchart
162VitriolageTable with IPC sections

Running total – PDFs completed:
ChapterTopicStatus
1Medical Jurisprudenceβœ…
2Post-Mortem & Autopsyβœ…
3Thanatologyβœ…
4Mechanical Injuriesβœ…
5Burns & Thermal/Chemicalβœ…
6Asphyxia & Respiratory DeathsPending
7Ballistics & FirearmsPending
8ToxicologyPending
9Narcotic & Substance AbusePending
10Reproductive Forensics & MTPPending
11Forensic PsychiatryPending
12Identification & AnthropologyPending
13MiscellaneousPending
Say "Yes" for Chapter 6 (Asphyxia), or name any specific chapter you want next!

Yes

Writing File

~/forensic-medicine-pdfs/chapter6_gen.py

#!/usr/bin/env python3
"""Chapter 6: Asphyxia & Respiratory Deaths – Pure White, Print-Ready
   Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
    TableStyle, PageBreak, KeepTogether)
from reportlab.platypus.flowables import Flowable

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter6_Asphyxia.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK = colors.black; WHITE = colors.white

def S(n,**k):
    return ParagraphStyle(n, parent=getSampleStyleSheet()['Normal'], **k)

TITLE=S('Ti',fontSize=22,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=28)
CHAP=S('Ch',fontSize=15,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER)
REF=S('Re',fontSize=8,textColor=BLACK,fontName='Helvetica-Oblique',alignment=TA_CENTER)
QS=S('Qs',fontSize=12,textColor=BLACK,fontName='Helvetica-Bold',leading=17,leftIndent=8)
BODY=S('Bo',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica',alignment=TA_JUSTIFY)
BOLD=S('Bl',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica-Bold')
NOTE=S('No',fontSize=9,textColor=BLACK,fontName='Helvetica-Oblique',leading=13,leftIndent=10)
MNEM=S('Mn',fontSize=10.5,textColor=BLACK,fontName='Helvetica-Bold',leading=15,leftIndent=10)
TH=S('TH',fontSize=8.5,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=12)
TC=S('TC',fontSize=8.5,textColor=BLACK,fontName='Helvetica',leading=12,alignment=TA_LEFT)

def hdr(canv,doc):
    canv.saveState()
    canv.setStrokeColor(BLACK); canv.setLineWidth(1.5)
    canv.line(M,PAGE_H-1.0*cm,PAGE_W-M,PAGE_H-1.0*cm)
    canv.setFillColor(BLACK); canv.setFont('Helvetica-Bold',9)
    canv.drawString(M,PAGE_H-0.78*cm,"FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica',8)
    canv.drawRightString(PAGE_W-M,PAGE_H-0.78*cm,"Chapter 6: Asphyxia & Respiratory Deaths")
    canv.line(M,0.85*cm,PAGE_W-M,0.85*cm)
    canv.setFont('Helvetica',8)
    canv.drawString(M,0.32*cm,"Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M,0.32*cm,f"Page {doc.page}")
    canv.restoreState()

def qb(E,num,txt):
    t=Table([[Paragraph(f"Q.{num}  {txt}",QS)]],colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),('RIGHTPADDING',(0,0),(-1,-1),10)]))
    E.append(KeepTogether([t])); E.append(Spacer(1,5))

def tbl(headers,rows,cw=None):
    avail=PAGE_W-2*M-0.2*cm
    if not cw: cw=[avail/len(headers)]*len(headers)
    data=[[Paragraph(h,TH) for h in headers]]
    for r in rows: data.append([Paragraph(str(c),TC) for c in r])
    t=Table(data,colWidths=cw,repeatRows=1)
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1),WHITE),('TEXTCOLOR',(0,0),(-1,-1),BLACK),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),('FONTNAME',(0,1),(-1,-1),'Helvetica'),
        ('FONTSIZE',(0,0),(-1,-1),8.5),('GRID',(0,0),(-1,-1),0.6,BLACK),
        ('LINEBELOW',(0,0),(-1,0),1.2,BLACK),('VALIGN',(0,0),(-1,-1),'TOP'),
        ('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4),
        ('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),
    ]))
    return t

class FC(Flowable):
    def __init__(self,nodes,width=None,nh=34,gap=15):
        super().__init__()
        self.nodes=nodes; self.nw=width or (PAGE_W-2*M-0.5*cm)
        self.nh=nh; self.gap=gap
        self.width=self.nw; self.height=len(nodes)*(nh+gap)-gap+20
    def wrap(self,aW,aH): return self.width,self.height
    def draw(self):
        c=self.canv; y=self.height-10
        nw,nh,gap=self.nw,self.nh,self.gap; cx=nw/2
        for i,(text,shape) in enumerate(self.nodes):
            top=y-nh; mid=y-nh/2
            c.setFillColor(WHITE); c.setStrokeColor(BLACK)
            lw=1.8 if shape=='terminal' else 1.2; c.setLineWidth(lw)
            if shape=='terminal':
                c.roundRect(cx-nw*.38,top,nw*.76,nh,nh/2,fill=1,stroke=1)
            elif shape=='diamond':
                p=c.beginPath(); p.moveTo(cx,y); p.lineTo(cx+nw*.42,mid)
                p.lineTo(cx,top); p.lineTo(cx-nw*.42,mid); p.close()
                c.drawPath(p,fill=1,stroke=1)
            elif shape=='rounded':
                c.roundRect(cx-nw*.44,top,nw*.88,nh,8,fill=1,stroke=1)
            else:
                c.rect(cx-nw*.44,top,nw*.88,nh,fill=1,stroke=1)
            c.setFillColor(BLACK)
            c.setFont('Helvetica-Bold' if shape in('terminal','diamond') else 'Helvetica',8.5)
            lines=text.split('\n'); lh=11
            ty=mid+len(lines)*lh/2-lh*.7
            for ln in lines: c.drawCentredString(cx,ty,ln); ty-=lh
            if i<len(self.nodes)-1:
                ay=top-gap; c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx,top,cx,ay+6); c.setFillColor(BLACK)
                p=c.beginPath(); p.moveTo(cx,ay); p.lineTo(cx-5,ay+8); p.lineTo(cx+5,ay+8)
                p.close(); c.drawPath(p,fill=1,stroke=0)
            y=top-gap

# ═══════════════════════════════════════════════════════════════
def build():
    doc=SimpleDocTemplate(OUTPUT,pagesize=A4,leftMargin=M,rightMargin=M,
        topMargin=1.4*cm,bottomMargin=1.2*cm,title="Chapter 6 – Asphyxia & Respiratory Deaths")
    E=[]

    # COVER
    E.append(Spacer(1,1.2*cm))
    bdr=Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY",TITLE)]],colWidths=[PAGE_W-2*M])
    bdr.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),3,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),18),('BOTTOMPADDING',(0,0),(-1,-1),18)]))
    E.append(bdr); E.append(Spacer(1,.4*cm))
    cb=Table([[Paragraph("CHAPTER 6",CHAP)]],colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2=Table([[Paragraph("Asphyxia &amp; Respiratory Deaths",
        S('tb',fontSize=18,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.3*cm))
    rb=Table([[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed",REF)]],
        colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))
    E.append(Paragraph("CHAPTER CONTENTS",S('toch',fontSize=11,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["4","Post-Mortem Signs of Asphyxia"],
        ["7 / 135","Difference: Hanging vs Strangulation"],
        ["83","HCN (Hydrogen Cyanide) Poisoning"],
        ["120","Parrot's Perch Position"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q4 – POST-MORTEM SIGNS OF ASPHYXIA
    # ═══════════════════════════════════════════════════════════════
    qb(E,"4","Describe the Post-Mortem Signs of Asphyxia")
    E.append(Paragraph(
        "<b>Asphyxia</b> (Greek: 'without pulse') is a condition caused by interference with respiration, "
        "resulting in deficiency of O2 and excess of CO2 in the blood and tissues, leading to unconsciousness "
        "and death. (KS Narayan Reddy, 36th Ed)",BODY))
    E.append(Spacer(1,4))

    E.append(Paragraph("<b>CLASSIFICATION OF ASPHYXIA:</b>",BOLD))
    E.append(tbl(["Type","Mechanism","Examples"],[
        ["<b>Mechanical Asphyxia</b>","Physical obstruction of airway or chest movement",
         "Hanging, strangulation, smothering, choking, traumatic (burking)"],
        ["<b>Toxic Asphyxia</b>","Chemical interference with O2 transport or utilization",
         "CO poisoning, HCN, methemoglobin formers"],
        ["<b>Pathological Asphyxia</b>","Disease process interfering with respiration",
         "Epiglottitis, laryngeal edema, severe asthma"],
        ["<b>Environmental Asphyxia</b>","Oxygen-deficient environment",
         "Confined spaces, mines, high altitude"],
    ]))
    E.append(Spacer(1,6))

    E.append(Paragraph("<b>STAGES OF ASPHYXIA (Mechanical):</b>",BOLD))
    E.append(tbl(["Stage","Duration","Features"],[
        ["1. Dyspnoeic stage","0–1 min","Hypoxia β†’ increased respiratory effort; cyanosis begins; rising BP"],
        ["2. Convulsive stage","1–2 min","Hypercapnia β†’ convulsions; loss of consciousness; BP falls"],
        ["3. Pre-terminal apnoea","2–3 min","Respiratory centre depressed; brief pause in breathing"],
        ["4. Terminal gasping","3–4 min","Agonal gasping; BP very low; heart still beating"],
        ["5. Death","4–5 min","Cardiac arrest; brain death"],
    ]))
    E.append(Spacer(1,6))

    E.append(Paragraph("<b>POST-MORTEM SIGNS OF ASPHYXIA (General):</b>",BOLD))
    E.append(Paragraph("<b>MNEMONIC: PC-FEDS</b> – Petechiae, Cyanosis, Fluidity of blood, Engorgement, Distension of right heart, Subpleural hemorrhages",MNEM))
    E.append(Spacer(1,4))
    E.append(tbl(["Sign","Description","Significance"],[
        ["<b>1. Petechiae\n(Tardieu's spots)</b>",
         "Pinpoint hemorrhages on:\n- Conjunctiva (subconjunctival)\n- Sclera\n- Face, forehead, scalp\n- Pleura (subpleural) – Tardieu's spots\n- Pericardium",
         "Classic asphyxial sign;\ncaused by raised venous pressure β†’ capillary rupture;\nmost reliable sign"],
        ["<b>2. Cyanosis</b>",
         "Blue-purple discoloration of:\nLips, face, fingernails, mucous membranes",
         "Desaturation of blood;\ndeoxyHb > 5 g/dL;\nalso present in CO poisoning (but cherry-red)"],
        ["<b>3. Congestion / Engorgement</b>",
         "Engorged veins of face, neck, conjunctiva;\nbulging eyes (proptosis);\nengorgement of internal organs (liver, spleen, brain)",
         "Obstruction of venous return;\nface becomes puffy, swollen"],
        ["<b>4. Fluidity of blood</b>",
         "Blood remains LIQUID (does not clot) at PM;\nbright red on right side (O2 depleted slowly);\ndark red on left side",
         "Fibrinolysis in asphyxia;\npostmortem fluidity increases with duration of asphyxia"],
        ["<b>5. Distension of\nright heart</b>",
         "Right side of heart distended with dark blood;\nleft side relatively empty",
         "Pulmonary obstruction β†’ blood backs up in right side"],
        ["<b>6. Lung changes</b>",
         "Emphysema (over-inflation);\npulmonary edema;\nSubpleural Tardieu's spots;\nfrothy fluid in airways (drowning)",
         "Over-inflation from struggle to breathe;\nedema from hypoxia"],
        ["<b>7. Froth / foam</b>",
         "Fine frothy foam at mouth/nostrils (mushroom-shaped froth in drowning)",
         "Air + mucus + water beaten by respiratory effort"],
        ["<b>8. External signs\n(neck injuries)</b>",
         "Ligature mark / finger nail abrasions / bruising of neck\n(depends on type of asphyxia)",
         "Helps identify mechanism"],
    ],cw=[3.5*cm,5*cm,PAGE_W-2*M-8.5*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>TARDIEU'S SPOTS (special mention):</b>",BOLD))
    E.append(tbl(["Aspect","Details"],[
        ["What","Subpleural petechial hemorrhages; also subpericardial"],
        ["Named after","Auguste Ambroise Tardieu (French forensic physician)"],
        ["Mechanism","Raised intrathoracic pressure β†’ capillary rupture beneath pleura"],
        ["Location","Visceral pleura (especially posterior lower lobes); pericardium; thymus in children"],
        ["Significance","Classic sign of asphyxia; seen in hanging, strangulation, smothering, drowning"],
        ["Differentiation","Also seen in: septicemia, cardiac failure β†’ NOT pathognomonic alone; interpret with other signs"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Post-Mortem Signs of Asphyxia</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("ASPHYXIA\n(oxygen deprivation)","terminal"),
        ("Raised venous pressure +\nCapillary engorgement","rect"),
        ("PETECHIAE:\nConjunctiva; face; sclera;\nSubpleural (Tardieu's spots)","rect"),
        ("CYANOSIS:\nLips, nails, face, mucous membranes\n(deoxyHb > 5 g/dL)","rect"),
        ("CONGESTION:\nEngorged neck veins;\nbulging eyes; swollen face","rect"),
        ("FLUIDITY OF BLOOD:\nLiquid at PM; fibrinolysis","rect"),
        ("RIGHT HEART:\nDistended with dark blood","rect"),
        ("LUNGS:\nEmphysema; edema;\nTardieu's spots (subpleural)","rect"),
        ("EXTERNAL:\nLigature mark / nail marks /\nbruising (depends on type)","terminal"),
    ],nh=34,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q7 / Q135 – HANGING vs STRANGULATION
    # ═══════════════════════════════════════════════════════════════
    qb(E,"7 / 135","Difference Between Hanging and Strangulation")
    E.append(Paragraph(
        "Both hanging and strangulation compress the neck structures causing asphyxia, but they differ "
        "fundamentally in mechanism, ligature mark characteristics, and medico-legal implications.",BODY))
    E.append(Spacer(1,4))

    E.append(tbl(["Feature","HANGING","STRANGULATION"],[
        ["<b>Definition</b>",
         "Constriction of neck by ligature, with body weight acting as constricting force",
         "Constriction of neck by ligature or hands (throttling), WITHOUT body weight"],
        ["<b>Manner</b>",
         "Usually SUICIDAL (most common);\nAccidental (auto-erotic);\nHomicidal (rare – judicial hanging)",
         "Usually HOMICIDAL;\nAccidental (rarely);\nSuicidal (very rare – nearly impossible by own hands)"],
        ["<b>Force</b>","Body weight (entire or partial)","External force: ligature pulled by another person;\nor manual pressure (throttling)"],
        ["<b>Types</b>",
         "Complete: feet off ground\nIncomplete: some support (knees/feet touching)\nTypical: knot at nape\nAtypical: knot elsewhere",
         "Ligature strangulation: cord/belt\nThrottling (manual): hands\nMugging (arm strangulation):\nforearm around neck"],
        ["<b>Ligature mark –\nPosition</b>",
         "HIGH on neck (above thyroid cartilage);\nOBLIQUE (upward toward knot);\nNOT encircling (gap at knot site)",
         "LOW on neck (at or below thyroid cartilage);\nHORIZONTAL;\nCOMPLETE ENCIRCLING (no gap)"],
        ["<b>Ligature mark –\nDirection</b>",
         "OBLIQUE (V-shaped upward);\nGap at highest point (knot location)","HORIZONTAL (transverse);\nComplete circumferential"],
        ["<b>Ligature mark –\nDepth</b>","Deep; well-defined;\nparchment-like","Deep; well-defined;\nmay have more bruising if manual"],
        ["<b>Neck structures</b>",
         "Carotids compressed (mainly);\nJugular veins compressed;\nHyoid fracture (uncommon except judicial)",
         "All neck structures compressed;\nHyoid fracture MORE common;\ncricoid/thyroid cartilage fractures common"],
        ["<b>Face</b>",
         "PALE (carotid compressed β†’ no blood reaching face);\nor congested if venous only obstructed",
         "CONGESTED, CYANOSED (venous obstruction predominates);\npetechiae more prominent"],
        ["<b>Petechiae</b>","Less prominent (arterial cutoff)","VERY PROMINENT on face, eyes, conjunctiva"],
        ["<b>Tongue</b>","May protrude (partial)","Often protrudes and is cyanosed"],
        ["<b>Saliva</b>","Drooling from mouth corner (direction helps TSD)","Not characteristic"],
        ["<b>Froth</b>","May be present","Often frothy blood-tinged saliva"],
        ["<b>PM position</b>","Body found suspended (complete);\nor with some support (incomplete)","Body usually found lying; not suspended"],
        ["<b>Asphyxia signs</b>","Present","Present (more marked)"],
        ["<b>Mechanism of death</b>",
         "1. Asphyxia (most common)\n2. Venous obstruction β†’ cerebral congestion\n3. Arterial occlusion β†’ cerebral ischemia\n4. Vagal inhibition (reflex cardiac arrest)\n5. Fracture dislocation of spine (judicial only)",
         "1. Asphyxia\n2. Venous obstruction\n3. Vagal inhibition\n4. Carotid sinus reflex"],
        ["<b>Manner</b>","Mostly suicidal","Mostly homicidal"],
    ],cw=[3.2*cm,5.2*cm,PAGE_W-2*M-8.4*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>TYPES OF HANGING (classification):</b>",BOLD))
    E.append(tbl(["Classification","Types","Details"],[
        ["By body position",
         "Complete hanging\nIncomplete hanging",
         "Complete: entire body weight on ligature (feet off ground)\nIncomplete: part of body touching ground/surface; only partial weight"],
        ["By knot position",
         "Typical hanging\nAtypical hanging",
         "Typical: knot at nape of neck (back)\nAtypical: knot anywhere else (side, front)"],
        ["By manner",
         "Suicidal\nAccidental\nHomicidal\nJudicial",
         "Suicidal: most common\nAccidental: auto-erotic; children playing\nHomicidal: very rare; requires incapacitated victim\nJudicial: capital punishment; fracture-dislocation C2-C3"],
    ],cw=[3*cm,3.5*cm,PAGE_W-2*M-6.5*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>THROTTLING vs LIGATURE STRANGULATION:</b>",BOLD))
    E.append(tbl(["Feature","Throttling (Manual)","Ligature Strangulation"],[
        ["Mechanism","Hands/fingers compress neck","Ligature tightened around neck"],
        ["Mark","Finger nail abrasions (crescentic);\nfingertip bruises","Ligature groove (horizontal, encircling)"],
        ["Hyoid fracture","More common (direct finger pressure)","Present but less common than throttling"],
        ["Manner","Virtually always HOMICIDAL","Homicidal (mainly); occasionally suicidal"],
        ["Multiple marks","Multiple separate bruises (fingerprints)","Single continuous groove"],
        ["Petechiae","Very prominent (face, eyes)","Prominent"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Hanging vs Strangulation – Key Decision Points</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("BODY FOUND with NECK COMPRESSION\n(ligature mark present)","terminal"),
        ("Was body SUSPENDED\n(hanging position)?","diamond"),
        ("YES β†’ HANGING:\nCheck ligature mark position\n(oblique, upward, gap at knot)","rounded"),
        ("NO β†’ STRANGULATION:\nCheck mark\n(horizontal, complete encircling)","rounded"),
        ("HANGING:\nSuicidal (most common);\nFace: pale or congested;\nless petechiae","rect"),
        ("STRANGULATION:\nHomicidal (most common);\nFace: congested/cyanosed;\nprominent petechiae","rect"),
        ("Check for MANUAL marks:\nnail abrasions + fingertip bruises\n→ THROTTLING (homicidal)","rect"),
        ("FINAL: Manner of death:\nSuicide / Homicide / Accident","terminal"),
    ],nh=36,gap=13))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q83 – HCN POISONING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"83","Describe HCN (Hydrogen Cyanide) Poisoning")
    E.append(Paragraph(
        "<b>Hydrogen cyanide (HCN)</b> is a rapid-acting cellular poison that causes <b>histotoxic anoxia</b> "
        "by blocking cytochrome oxidase (complex IV of mitochondrial electron transport chain), preventing "
        "cells from using oxygen despite adequate O2 in blood. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))

    E.append(tbl(["Aspect","Details"],[
        ["Chemical","HCN (prussic acid); also CN⁻ from potassium cyanide (KCN), sodium cyanide (NaCN)"],
        ["Sources","Almonds (amygdalin); bitter almonds; cherry laurel; cyanide salts;\nsmoke from burning plastics/wool; fumigants; electroplating industry;\nNitroprusside infusion (thiocyanate)"],
        ["Mechanism","CN⁻ binds to Fe³⁺ of cytochrome oxidase (complex IV) β†’ electron transport blocked\nβ†’ cells cannot use O2 β†’ histotoxic anoxia β†’ lactic acidosis"],
        ["Fatal dose","HCN gas: 300 ppm (rapid death); 150–200 ppm (1 hr exposure)\nKCN oral: 150–300 mg\nNaCN oral: 100–200 mg"],
        ["Smell","Bitter almonds (50% of people cannot detect; genetic anosmia)"],
        ["Speed","EXTREMELY rapid: seconds (gas inhalation); minutes (oral)"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>CLINICAL FEATURES (Stages):</b>",BOLD))
    E.append(tbl(["Stage","Time","Features"],[
        ["Stage 1\n(Initial)","Seconds–minutes",
         "Bitter almond taste; burning in mouth/throat;\nheadache; dizziness; anxiety; flushing"],
        ["Stage 2\n(Excitation)","Minutes",
         "Palpitations; hyperpnoea (rapid deep breathing);\nnausea; vomiting; confusion; excitement"],
        ["Stage 3\n(Convulsive)","Minutes",
         "Convulsions; loss of consciousness;\ncyanosis (paradoxically LATE – blood O2 normal);\nopisthotonos"],
        ["Stage 4\n(Paralytic)","Minutes–hours",
         "Respiratory paralysis; cardiac arrest;\ndeath within 4–5 minutes of severe exposure"],
    ],cw=[2.5*cm,2.5*cm,PAGE_W-2*M-5*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>KEY PARADOX:</b> Blood remains BRIGHT CHERRY RED (venous blood = arterial color) because cells cannot use O2 β†’ venous blood stays oxygenated β†’ no cyanosis initially.",NOTE))
    E.append(Spacer(1,5))

    E.append(tbl(["PM Findings","Details"],[
        ["Blood color","BRIGHT CHERRY RED (venous blood oxygenated – O2 not utilized)"],
        ["Smell","Bitter almond odor from stomach/organs (if early PM)"],
        ["Livor mortis","Bright red (cherry red)"],
        ["Organs","Congested; bright red color throughout"],
        ["Stomach mucosa","Congested; may show petechiae; smell of bitter almonds"],
        ["Histology","Cellular hypoxia; neurons damaged; eosinophilic neuronal change"],
        ["Chemical test","Prussian blue test (blood + KOH + FeSO4 + HCl β†’ blue color)"],
    ]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>TREATMENT OF CYANIDE POISONING:</b>",BOLD))
    E.append(tbl(["Step","Treatment","Mechanism"],[
        ["1","REMOVE from source; fresh air; 100% O2","Competitive displacement of CN from enzymes"],
        ["2","Dicobalt edetate (Kelocyanor) 300 mg IV","Chelates CN; drug of choice in UK"],
        ["3","Hydroxocobalamin 5 g IV","Binds CN β†’ cyanocobalamin (excreted); SAFEST – used in France/USA"],
        ["4","Amyl nitrite (inhale) + Sodium nitrite IV","Converts Hb β†’ metHb β†’ metHb binds CN preferentially,\nfrees cytochrome oxidase"],
        ["5","Sodium thiosulfate IV (12.5 g)","Provides sulfur β†’ CN β†’ SCN⁻ (thiocyanate) β†’ excreted;\ngiven AFTER nitrites"],
        ["6","Supportive: Correct acidosis (NaHCO3);\nseizure control (benzodiazepines)",""],
        ["7","Glucose (high dose)","Provides alternate metabolic pathway"],
    ],cw=[0.8*cm,4.5*cm,PAGE_W-2*M-5.3*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: HCN Poisoning – Mechanism & Treatment</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("HCN EXPOSURE\n(inhalation / ingestion)","terminal"),
        ("CN⁻ binds cytochrome oxidase\nβ†’ blocks electron transport chain","rect"),
        ("Cells CANNOT use O2\n(HISTOTOXIC ANOXIA)","rect"),
        ("VENOUS BLOOD = O2 rich\n(cherry-red color);\nLactic acidosis","rect"),
        ("CONVULSIONS β†’ Respiratory\nparalysis β†’ Cardiac arrest","rect"),
        ("TREATMENT:\n1. Remove + O2\n2. Hydroxocobalamin OR Dicobalt edetate\n3. Sodium nitrite + Sodium thiosulfate","rounded"),
        ("ANTIDOTE MECHANISM:\nCN captured by cobalt / metHb /\nthiosulfate β†’ non-toxic excretion","rect"),
        ("PM: Cherry-red blood;\nbitter almond smell;\nPrussian blue test positive","terminal"),
    ],nh=36,gap=12))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q120 – PARROT'S PERCH POSITION
    # ═══════════════════════════════════════════════════════════════
    qb(E,"120","What is Parrot's Perch Position?")
    E.append(Paragraph(
        "<b>Parrot's perch position</b> (also called <b>strappado</b> or <b>Palestinian hanging</b>) is a "
        "method of torture/restraint in which the victim's hands are tied behind the back and the person "
        "is suspended or hung by the wrists tied behind.",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Description","Victim's arms tied behind back at wrists;\nsuspended by wrists (arms behind back) from above;\nor placed in this posture and suspended"],
        ["Also called","Strappado; Palestinian hanging; reverse hanging"],
        ["Injuries caused",
         "1. Asphyxia (chest restricted; cannot breathe properly)\n"
         "2. Shoulder dislocation (posterior; both shoulders)\n"
         "3. Brachial plexus injury (stretch injury)\n"
         "4. Rotator cuff tears\n"
         "5. Wrist bruising / ligature marks (at binding point)\n"
         "6. Compressive nerve palsies"],
        ["Asphyxia mechanism","Arms behind back fix scapulae β†’ restricts chest expansion β†’ respiratory failure"],
        ["Medicolegal significance",
         "Method of torture (police custody; war crimes)\n"
         "Evidence: posterior shoulder dislocations + bilateral brachial plexus stretch injury\n"
         "Pattern of injuries is PATHOGNOMONIC of this position"],
        ["Context","Custody deaths; torture victims; war crimes documentation;\n"
         "Human rights medicine"],
        ["At PM","Bilateral shoulder joint injuries;\nbilateral brachial plexus stretch;\nwrist ligature marks;\nasphyxial signs"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Parrot's Perch – Injury Sequence</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("WRISTS TIED BEHIND BACK\nVictim suspended by wrists","terminal"),
        ("SHOULDERS forced into\nextreme POSTERIOR position","rect"),
        ("BILATERAL POSTERIOR\nSHOULDER DISLOCATION","rect"),
        ("BRACHIAL PLEXUS\nSTRETCH INJURY (bilateral)","rect"),
        ("CHEST EXPANSION restricted\n(scapulae fixed by arm position)","rect"),
        ("ASPHYXIA develops\n(cannot breathe adequately)","rect"),
        ("DEATH from\nRESPIRATORY FAILURE","terminal"),
    ],nh=32,gap=12))
    E.append(Spacer(1,10))

    # ════ ADDITIONAL ASPHYXIA TYPES REFERENCE TABLE ════════════════
    E.append(PageBreak())
    qb(E,"Reference","Types of Asphyxia – Comprehensive Comparison Table")
    E.append(tbl(["Type","Mechanism","Common Manner","Key PM Findings","Distinguishing Feature"],[
        ["<b>Hanging</b>","Ligature + body weight compresses neck",
         "Suicidal (most common)","Oblique ligature mark; gap at knot;\nsaliva drooling; pale or congested face",
         "Oblique mark; body suspended"],
        ["<b>Ligature\nStrangulation</b>","Ligature tightened around neck by another person",
         "Homicidal","Horizontal encircling ligature mark;\ncongestd face; prominent petechiae",
         "Horizontal complete mark; homicidal"],
        ["<b>Throttling\n(Manual Strangl.)</b>","Hands/fingers compress neck",
         "Homicidal","Fingernail crescentic abrasions;\nfingertip bruises on neck;\nhyoid fracture common",
         "Individual fingertip marks; nail marks"],
        ["<b>Smothering</b>","Obstruction of external air passages (nose/mouth covered)",
         "Homicidal\n(infants/elderly)","Petechiae on face/conjunctiva;\nmay be minimal signs;\nfibres/lint in mouth",
         "Minimal marks; fibres in airway"],
        ["<b>Choking</b>","Internal obstruction of airway (foreign body)",
         "Accidental","Food/foreign body at larynx or bronchus;\ncafe coronary pattern;\nasphyxial signs",
         "Foreign body in airway"],
        ["<b>Burking</b>","Smothering + chest compression\nsimultaneously",
         "Homicidal","Asphyxial signs;\npossible rib fractures;\nminimal neck marks",
         "Rib fractures + asphyxia; no neck mark"],
        ["<b>Traumatic\nasphyxia</b>","Compression of chest/abdomen (crush injury)",
         "Accidental","Mask of traumatic asphyxia:\nextreme petechiae face/neck;\nflorid cyanosis;\ncompressive injuries to trunk",
         "Crush injury to chest/abdomen"],
        ["<b>Drowning</b>","Water entry into airways + lungs",
         "Accidental","Emphysema aquosum (over-inflated lungs);\nfrothy foam; washerwoman's changes;\ndiatoms in bone marrow",
         "Frothy foam; diatoms; wet lungs"],
        ["<b>Overlaying\n(Positional)</b>","Body weight over victim's face/trunk",
         "Accidental\n(infants)","Asphyxial signs; no marks;\nSIDS-like appearance",
         "Position-dependent; infant victim"],
    ],cw=[2.8*cm,3.5*cm,2.2*cm,3.5*cm,PAGE_W-2*M-12*cm]))
    E.append(Spacer(1,10))

    # ════ SUMMARY TABLE ════════════════════════════════════════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 6 β€” QUICK REFERENCE SUMMARY",
        S('sh',fontSize=13,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(Spacer(1,4))
    E.append(tbl(["Topic","Key 1-Liner"],[
        ["Asphyxia definition","Deficiency of O2 + excess CO2 due to interference with respiration"],
        ["PM signs (mnemonic)","PC-FEDS: Petechiae, Cyanosis, Fluid blood, Engorgement, Distended right heart, Subpleural spots"],
        ["Tardieu's spots","Subpleural petechial hemorrhages; classic asphyxia sign; also in septicemia"],
        ["Hanging – ligature mark","HIGH on neck; OBLIQUE; gap at knot; usually suicidal"],
        ["Strangulation – ligature mark","LOW on neck; HORIZONTAL; COMPLETE encircling; usually homicidal"],
        ["Throttling mark","Fingernail crescentic abrasions + fingertip bruises; hyoid fracture common; homicidal"],
        ["Face in hanging","Pale (if arterial) or congested; less petechiae than strangulation"],
        ["Face in strangulation","Congested, cyanosed; very prominent petechiae on face and eyes"],
        ["HCN mechanism","Blocks cytochrome oxidase β†’ histotoxic anoxia β†’ cells can't use O2"],
        ["HCN blood","Cherry-red (venous blood oxygenated); bitter almond smell"],
        ["HCN antidote","Hydroxocobalamin (drug of choice); OR dicobalt edetate; + sodium thiosulfate"],
        ["HCN test","Prussian blue test positive"],
        ["Parrot's perch","Hands tied behind; suspended by wrists; bilateral posterior shoulder dislocation + brachial plexus stretch + asphyxia"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E,onFirstPage=hdr,onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__=="__main__":
    build()
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter6_gen.py 2>&…

Running Command

ls -lh /home/daytona/workspace/forensic-medicine-pdfs/Chapter6_Asphyxia.pdf

Chapter 6 ready!

Chapter6 Asphyxia

PDF Document Β· PDF

(33 KB) β€” Pure white, print-ready

What's inside Chapter 6:

Q.TopicFormat
4PM Signs of AsphyxiaClassification + Stages + PC-FEDS mnemonic table + Tardieu's spots + Flowchart
7/135Hanging vs Strangulation17-feature mega comparison table
Types of HangingClassification table
Throttling vs Ligature StrangulationComparison table
Hanging vs StrangulationDecision Flowchart
83HCN PoisoningMechanism + Stages + PM findings + Treatment table + Flowchart
120Parrot's Perch PositionTable + Flowchart
ReferenceAll Asphyxia Types Compared9-type master comparison table (hanging, throttling, smothering, choking, burking, drowning, traumatic, overlaying)

Progress so far:
Chapterβœ…
1Medical Jurisprudenceβœ…
2Post-Mortem & Autopsyβœ…
3Thanatologyβœ…
4Mechanical Injuriesβœ…
5Burns & Thermalβœ…
6Asphyxiaβœ…
7Ballistics & Firearms⏳
8Toxicology⏳
9–13Remaining chapters⏳
Say "Yes" for Chapter 7 (Ballistics & Firearms)!

Chapter 7 and 8

Writing File

~/forensic-medicine-pdfs/chapter7_gen.py

#!/usr/bin/env python3
"""Chapter 7: Ballistics & Firearms – Pure White, Print-Ready
   Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
    TableStyle, PageBreak, KeepTogether)
from reportlab.platypus.flowables import Flowable

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter7_Ballistics_Firearms.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK = colors.black; WHITE = colors.white

def S(n,**k):
    return ParagraphStyle(n, parent=getSampleStyleSheet()['Normal'], **k)

TITLE=S('Ti',fontSize=22,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=28)
CHAP=S('Ch',fontSize=15,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER)
REF=S('Re',fontSize=8,textColor=BLACK,fontName='Helvetica-Oblique',alignment=TA_CENTER)
QS=S('Qs',fontSize=12,textColor=BLACK,fontName='Helvetica-Bold',leading=17,leftIndent=8)
BODY=S('Bo',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica',alignment=TA_JUSTIFY)
BOLD=S('Bl',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica-Bold')
NOTE=S('No',fontSize=9,textColor=BLACK,fontName='Helvetica-Oblique',leading=13,leftIndent=10)
MNEM=S('Mn',fontSize=10.5,textColor=BLACK,fontName='Helvetica-Bold',leading=15,leftIndent=10)
TH=S('TH',fontSize=8.5,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=12)
TC=S('TC',fontSize=8.5,textColor=BLACK,fontName='Helvetica',leading=12,alignment=TA_LEFT)

def hdr(canv,doc):
    canv.saveState()
    canv.setStrokeColor(BLACK); canv.setLineWidth(1.5)
    canv.line(M,PAGE_H-1.0*cm,PAGE_W-M,PAGE_H-1.0*cm)
    canv.setFillColor(BLACK); canv.setFont('Helvetica-Bold',9)
    canv.drawString(M,PAGE_H-0.78*cm,"FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica',8)
    canv.drawRightString(PAGE_W-M,PAGE_H-0.78*cm,"Chapter 7: Ballistics & Firearms")
    canv.line(M,0.85*cm,PAGE_W-M,0.85*cm)
    canv.setFont('Helvetica',8)
    canv.drawString(M,0.32*cm,"Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M,0.32*cm,f"Page {doc.page}")
    canv.restoreState()

def qb(E,num,txt):
    t=Table([[Paragraph(f"Q.{num}  {txt}",QS)]],colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),('RIGHTPADDING',(0,0),(-1,-1),10)]))
    E.append(KeepTogether([t])); E.append(Spacer(1,5))

def tbl(headers,rows,cw=None):
    avail=PAGE_W-2*M-0.2*cm
    if not cw: cw=[avail/len(headers)]*len(headers)
    data=[[Paragraph(h,TH) for h in headers]]
    for r in rows: data.append([Paragraph(str(c),TC) for c in r])
    t=Table(data,colWidths=cw,repeatRows=1)
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1),WHITE),('TEXTCOLOR',(0,0),(-1,-1),BLACK),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),('FONTNAME',(0,1),(-1,-1),'Helvetica'),
        ('FONTSIZE',(0,0),(-1,-1),8.5),('GRID',(0,0),(-1,-1),0.6,BLACK),
        ('LINEBELOW',(0,0),(-1,0),1.2,BLACK),('VALIGN',(0,0),(-1,-1),'TOP'),
        ('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4),
        ('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),
    ]))
    return t

class FC(Flowable):
    def __init__(self,nodes,width=None,nh=34,gap=15):
        super().__init__()
        self.nodes=nodes; self.nw=width or (PAGE_W-2*M-0.5*cm)
        self.nh=nh; self.gap=gap
        self.width=self.nw; self.height=len(nodes)*(nh+gap)-gap+20
    def wrap(self,aW,aH): return self.width,self.height
    def draw(self):
        c=self.canv; y=self.height-10
        nw,nh,gap=self.nw,self.nh,self.gap; cx=nw/2
        for i,(text,shape) in enumerate(self.nodes):
            top=y-nh; mid=y-nh/2
            c.setFillColor(WHITE); c.setStrokeColor(BLACK)
            lw=1.8 if shape=='terminal' else 1.2; c.setLineWidth(lw)
            if shape=='terminal':
                c.roundRect(cx-nw*.38,top,nw*.76,nh,nh/2,fill=1,stroke=1)
            elif shape=='diamond':
                p=c.beginPath(); p.moveTo(cx,y); p.lineTo(cx+nw*.42,mid)
                p.lineTo(cx,top); p.lineTo(cx-nw*.42,mid); p.close()
                c.drawPath(p,fill=1,stroke=1)
            elif shape=='rounded':
                c.roundRect(cx-nw*.44,top,nw*.88,nh,8,fill=1,stroke=1)
            else:
                c.rect(cx-nw*.44,top,nw*.88,nh,fill=1,stroke=1)
            c.setFillColor(BLACK)
            c.setFont('Helvetica-Bold' if shape in('terminal','diamond') else 'Helvetica',8.5)
            lines=text.split('\n'); lh=11
            ty=mid+len(lines)*lh/2-lh*.7
            for ln in lines: c.drawCentredString(cx,ty,ln); ty-=lh
            if i<len(self.nodes)-1:
                ay=top-gap; c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx,top,cx,ay+6); c.setFillColor(BLACK)
                p=c.beginPath(); p.moveTo(cx,ay); p.lineTo(cx-5,ay+8); p.lineTo(cx+5,ay+8)
                p.close(); c.drawPath(p,fill=1,stroke=0)
            y=top-gap

# ═══════════════════════════════════════════════════════════════
def build():
    doc=SimpleDocTemplate(OUTPUT,pagesize=A4,leftMargin=M,rightMargin=M,
        topMargin=1.4*cm,bottomMargin=1.2*cm,title="Chapter 7 – Ballistics & Firearms")
    E=[]

    # COVER
    E.append(Spacer(1,1.2*cm))
    bdr=Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY",TITLE)]],colWidths=[PAGE_W-2*M])
    bdr.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),3,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),18),('BOTTOMPADDING',(0,0),(-1,-1),18)]))
    E.append(bdr); E.append(Spacer(1,.4*cm))
    cb=Table([[Paragraph("CHAPTER 7",CHAP)]],colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2=Table([[Paragraph("Ballistics &amp; Firearms",
        S('tb',fontSize=18,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.3*cm))
    rb=Table([[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's Forensic Pathology 3rd Ed",REF)]],
        colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))
    E.append(Paragraph("CHAPTER CONTENTS",S('toch',fontSize=11,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["1 / 22","Contact, Near, Intermediate & Distant Gunshot Wounds – Entry vs Exit"],
        ["15","Grease / Dirt Ring (Wiping Ring) in GSW"],
        ["33","Rifling and its Forensic Significance"],
        ["47","Pellet / Shotgun Wounds"],
        ["55 / 100","Differences: Entry Wound vs Exit Wound"],
        ["72","Tattooing and Blackening in Firearm Injuries"],
        ["88","Weapon types: Revolver vs Pistol vs Rifle vs Shotgun"],
        ["110","Ricochet Wounds"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q1/22 – CONTACT, NEAR, INTERMEDIATE, DISTANT GSW
    # ═══════════════════════════════════════════════════════════════
    qb(E,"1 / 22","Describe Gunshot Wounds at Different Ranges: Contact, Near, Intermediate & Distant")
    E.append(Paragraph(
        "The appearance of a gunshot entry wound changes dramatically with range because the secondary "
        "projectiles from firing (flame, smoke, soot, unburnt powder, wad) disperse with distance. "
        "Only the bullet reaches distant targets. (DiMaio's Forensic Pathology; KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))

    E.append(Paragraph("<b>COMPONENTS DISCHARGED FROM MUZZLE:</b>",BOLD))
    E.append(tbl(["Component","Range it travels","Effect on wound"],[
        ["Bullet","All ranges (indefinitely)","Primary projectile; makes wound channel"],
        ["Flame / hot gases","< 5 cm","Burns; char; stellate tear (contact)"],
        ["Soot / smoke (carbon particles)","< 15–20 cm","Blackening of skin around wound"],
        ["Unburnt/partially burnt powder (propellant)","15–60 cm","Tattooing (stippling) – embedded in skin"],
        ["Wad (shotgun only)","Up to 1–2 m","Separate wad injury; useful for range estimation"],
    ]))
    E.append(Spacer(1,5))

    E.append(tbl(["Range","Distance","Wound Characteristics","Muzzle Gases Effect"],[
        ["<b>HARD CONTACT\n(muzzle touching skin)</b>",
         "0 cm\n(muzzle on skin)",
         "- Punched-out round hole\n- Abrasion collar present\n- GAS enters wound β†’ inflates skin β†’ STELLATE (star-shaped) tear over bone\n- Muzzle contusion ring (imprint of muzzle)\n- Soot INSIDE wound (not on surface)\n- Charring of wound edges\n- No external blackening/tattooing",
         "All gases forced INTO wound;\nno external soot/smoke"],
        ["<b>LOOSE CONTACT /\nSOFT CONTACT</b>",
         "0–1 cm",
         "- Round/oval wound\n- Some soot externally around wound\n- Flame burns around entry\n- Less stellate than hard contact\n- Abrasion collar present",
         "Most gases enter wound;\nsome escape between gap"],
        ["<b>NEAR RANGE\n(Close range)</b>",
         "1–15 cm",
         "- Round wound with abrasion collar\n- BLACKENING (soot) around wound on skin surface\n- Singeing of hair (if present)\n- Flame burns (< 5 cm range)\n- No tattooing (too close for powder to embed)",
         "Soot deposits on skin surface"],
        ["<b>INTERMEDIATE\nRANGE</b>",
         "15–60 cm\n(up to ~2 feet)",
         "- Round wound with abrasion collar\n- TATTOOING (stippling): unburnt powder grains embedded in skin\n- Cannot be wiped off (embedded)\n- No soot/blackening\n- No flame burns",
         "Soot dispersed; powder grains reach skin"],
        ["<b>DISTANT / LONG\nRANGE</b>",
         "> 60 cm\n(beyond 2 feet)",
         "- Round/oval wound with abrasion collar only\n- GREASE RING (dirt ring, wiping ring)\n- NO soot, NO tattooing, NO blackening, NO burns\n- Only bullet reaches target",
         "All secondary missiles dispersed;\nbullet only"],
    ],cw=[3.2*cm,2.2*cm,5.8*cm,PAGE_W-2*M-11.2*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>FLOWCHART: Estimating Range from GSW Appearance</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("GUNSHOT ENTRY WOUND – examine features","terminal"),
        ("STELLATE tear + soot INSIDE wound +\nmuzzle contusion ring?","diamond"),
        ("YES β†’ HARD CONTACT WOUND\n(muzzle pressed on skin)","rounded"),
        ("BLACKENING (soot) on skin surface\n+ singeing of hair?","diamond"),
        ("YES β†’ NEAR RANGE (< 15 cm)\n(close range)","rounded"),
        ("TATTOOING (stippling) – powder grains\nembedded in skin? Cannot wipe off?","diamond"),
        ("YES β†’ INTERMEDIATE RANGE\n(15–60 cm)","rounded"),
        ("Only ABRASION COLLAR +\nGrease ring; no soot/tattoo?","diamond"),
        ("YES β†’ DISTANT RANGE\n(> 60 cm)","terminal"),
    ],nh=35,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q55/100 – ENTRY vs EXIT WOUND
    # ═══════════════════════════════════════════════════════════════
    qb(E,"55 / 100","Differences Between Entry Wound and Exit Wound in Firearm Injuries")
    E.append(tbl(["Feature","ENTRY WOUND","EXIT WOUND"],[
        ["<b>Size</b>","Smaller (approx. calibre of bullet)","LARGER (bullet tumbles + expands; tissue pushed out)"],
        ["<b>Shape</b>","Round / oval (perpendicular hit);\nOval/elongated (tangential)","Irregular; stellate; ragged; slit-like"],
        ["<b>Edges</b>","INVERTED (pushed inward);\nsmooth; punched-in appearance","EVERTED (pushed outward);\nragged; irregular"],
        ["<b>Abrasion collar\n(Graze ring)</b>","PRESENT:\nfirm, brownish ring of abrasion;\n3–5 mm wide","ABSENT (no abrasion collar)"],
        ["<b>Grease / Dirt ring</b>","PRESENT (at distant range):\nring of grease/soot from bullet surface","ABSENT"],
        ["<b>Soot / Blackening</b>","Present (close range only)","ABSENT"],
        ["<b>Tattooing</b>","Present (intermediate range only)","ABSENT"],
        ["<b>Bevelling\n(bone)</b>","Internal bevel: bone cavity wider INSIDE skull\n(bullet enters β†’ expands inward)","External bevel: bone cavity wider OUTSIDE skull"],
        ["<b>Haemorrhage</b>","Less external bleeding (vessels spasm)","MORE bleeding (larger defect; no tamponade)"],
        ["<b>Foreign material</b>","Soot, powder, wad (close range)","Usually none"],
        ["<b>Contusion ring</b>","Present (marginal contusion around entry)","Absent"],
        ["<b>Mechanism</b>","Bullet enters; skin stretches then\nsnaps back around smaller hole","Bullet exits; skin forced outward;\nno abrasion on exit"],
        ["<b>Forensic value</b>","Determines range + direction of fire","Determines direction; trajectory"],
    ]))
    E.append(Spacer(1,5))
    E.append(NOTE.leading and None or None)
    E.append(Paragraph(
        "<b>EXCEPTIONS:</b> Shored exit wound (exit against firm surface/clothing) β†’ may mimic entry with abrasion collar on exit. "
        "Intermediate range wounds may have stippling masking entry features.",NOTE))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q15 – GREASE RING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"15","What is the Grease Ring (Dirt Ring / Wiping Ring) in GSW?")
    E.append(tbl(["Aspect","Details"],[
        ["Definition","A ring of grease, dirt, and metal deposits left on the skin around the entry wound, deposited as the bullet passes through the skin surface"],
        ["Also called","Dirt ring; wiping ring; ring of dirt; grease collar"],
        ["Mechanism","Bullet surface is coated with grease/lubricant + metal particles + soot from barrel\nAs bullet passes through skin, skin acts like a wiper β†’ deposits ring of grease+dirt around hole"],
        ["Appearance","Greyish-black or brownish ring around the entry hole;\n1–3 mm wide;\ncannot be wiped away (embedded in skin)"],
        ["Range","Present ONLY at DISTANT range (> 60 cm)\nAt close range, soot/blackening overpowers/obscures it"],
        ["Significance","1. Confirms entry wound\n2. Indicates distant range (> 60 cm)\n3. Part of 'abrasion collar' complex\n4. Helps distinguish entry from exit wound"],
        ["Abrasion collar","= Combination of:\n(a) Grease/dirt ring + (b) Contusion ring around entry\nWidest when bullet hits at 90Β° (perpendicular);\nOval/eccentric when bullet hits at angle"],
    ],cw=[3*cm,PAGE_W-2*M-3*cm]))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q72 – TATTOOING AND BLACKENING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"72","Describe Tattooing and Blackening in Firearm Injuries")
    E.append(tbl(["Feature","BLACKENING (Fouling / Smudging)","TATTOOING (Stippling / Powder Burns)"],[
        ["Cause","Soot / carbon particles deposited on skin","Unburnt / partially burnt powder grains\nembedded in skin"],
        ["Range","< 15–20 cm (close range)","15–60 cm (intermediate range)"],
        ["Appearance","Sooty black smudge around wound;\ncovers large area","Discrete reddish-brown dots/punctate marks\naround wound; speckled pattern"],
        ["Can be wiped off?","YES – can be wiped off (surface deposit)","NO – CANNOT be wiped off\n(physically embedded in dermis)"],
        ["Pattern","Diffuse; around entry wound","Stellate distribution; multiple punctate marks"],
        ["Histology","Soot on surface of skin","Powder granules in dermis; surrounded by inflammatory cells"],
        ["Forensic value","Indicates close range (< 15–20 cm);\nhelps estimate range","Most reliable for range estimation;\npermanent; present at PM;\n15–60 cm range"],
        ["Coexistence","Blackening + tattooing can coexist\nat 10–15 cm range","Pure tattooing at 15–60 cm (no soot)"],
    ]))
    E.append(Spacer(1,5))
    E.append(Paragraph(
        "<b>NOTE:</b> Tattooing is the MOST RELIABLE range indicator because it is embedded and cannot be washed off. "
        "In decomposed bodies, histology can still detect embedded powder grains.",NOTE))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q33 – RIFLING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"33","What is Rifling and its Forensic Significance?")
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Spiral grooves cut into the interior (bore) of a gun barrel to impart spin to the bullet"],
        ["Purpose","Spinning stabilizes bullet in flight β†’ greater accuracy, range, and penetration"],
        ["Components","LANDS: raised portions between grooves (higher)\nGROOVES: cut spiral channels (lower)\nTwist: direction of spiral (left or right)"],
        ["Calibre","Internal diameter of barrel = diameter of bullet (measured between LANDS)\nExpressed in inches (e.g., .303, .45) or mm (e.g., 9 mm)"],
        ["Rifling marks on bullet","As bullet passes through rifled barrel:\nlands engrave parallel STRIATIONS (land marks) on bullet surface\nGrooves leave raised ridges on bullet"],
        ["Class characteristics","Number of lands and grooves; width; depth; direction of twist;\nunique to make/model of firearm"],
        ["Individual characteristics","Microscopic striations unique to ONE specific weapon\n(manufacturing marks + wear pattern)"],
        ["Forensic significance",
         "1. WEAPON IDENTIFICATION: striations on recovered bullet compared with test-fired bullet from suspect weapon\n"
         "2. CALIBRE DETERMINATION from bullet diameter\n"
         "3. DIRECTION OF FIRE: twist direction visible on bullet\n"
         "4. Gun linked to crime scene bullet by ballistic comparison\n"
         "5. Examinable even with deformed bullets (partial striations)"],
        ["Not rifled (smooth bore)","Shotguns: smooth bore (no rifling); fires pellets/shot; lower accuracy"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q47 – PELLET / SHOTGUN WOUNDS
    # ═══════════════════════════════════════════════════════════════
    qb(E,"47","Describe Pellet / Shotgun Wounds")
    E.append(Paragraph(
        "Shotguns fire multiple spherical pellets (shot) from a smooth bore barrel. The pellet cloud "
        "disperses (spreads) with distance, producing distinctive wound patterns. (DiMaio's; KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Range","Wound Pattern","Diameter of Wound"],[
        ["< 30 cm (Contact)","Single large ragged hole; stellate laceration;\ncribriform (sieve-like) pattern if bone;\nwad enters wound;\nblackening + burning","Single hole = muzzle diameter (~2–3 cm)"],
        ["30 cm – 1 m","Single hole with irregular ragged edges;\nsome pellets beginning to separate;\nblackening present","Hole 2–5 cm; some individual pellet holes at margins"],
        ["1–2 m","Partial separation of pellets;\ncentral hole + satellite pellet holes around it","Central hole 2–3 cm + multiple small holes around"],
        ["2–4 m","Pellets fully separated;\nmultiple individual punctate holes;\nno central hole;\n\"pepper pot\" appearance","Spread ~30 cm diameter at 4 m"],
        ["> 4–5 m","Widely scattered individual pellet holes;\nmay miss target partially","Each hole = individual pellet size (~3–5 mm)"],
    ]))
    E.append(Spacer(1,4))
    E.append(tbl(["Special Features","Details"],[
        ["Wad injury","Cardboard/plastic wad from shotgun cartridge can enter wound at close range;\ncan be confused with bullet;\nfound in wound track"],
        ["Satellite holes","Small individual pellet entry wounds around main wound;\nbegin to appear at ~1–2 m"],
        ["\"Pepper pot\" appearance","Classic shotgun appearance at 2–4 m;\nmultiple small holes over wide area"],
        ["Range estimation","Diameter of pellet spread used to estimate range:\nApprox. 2.5 cm spread per 1 m distance (rough guide;\nvaries by choke and shot size)"],
        ["Choke","Constriction at muzzle of shotgun; restricts pellet spread;\ncylinder bore = wide spread; full choke = tight spread"],
        ["Exit wound","Rare (pellets usually lodge in body);\nif present: multiple tiny holes"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Shotgun Wound Range Estimation</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("SHOTGUN WOUND – assess pattern","terminal"),
        ("Single large stellate hole +\nblueing/burning + wad in wound?","diamond"),
        ("YES β†’ CONTACT / < 30 cm","rounded"),
        ("Single large hole with\nblackening + irregular edges?","diamond"),
        ("YES β†’ < 1 m (close range)","rounded"),
        ("Central hole + satellite\npellet holes at margins?","diamond"),
        ("YES β†’ 1–2 m (intermediate)","rounded"),
        ("Multiple separate small holes;\n'Pepper pot'; no central hole?","diamond"),
        ("YES β†’ 2–4 m","rounded"),
        ("Widely scattered individual\npellet holes?","diamond"),
        ("YES β†’ > 4–5 m (distant)","terminal"),
    ],nh=33,gap=10))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q88 – WEAPON TYPES
    # ═══════════════════════════════════════════════════════════════
    qb(E,"88","Describe Different Types of Firearms: Revolver, Pistol, Rifle, Shotgun")
    E.append(tbl(["Feature","REVOLVER","PISTOL (Semi-auto)","RIFLE","SHOTGUN"],[
        ["Bore","Rifled","Rifled","Rifled","SMOOTH (no rifling)"],
        ["Magazine","Rotating cylinder\n(6–8 rounds)","Detachable box magazine\n(7–17+ rounds)","Box/clip magazine\n(3–30 rounds)","Tubular magazine\nor break-action\n(2–8 rounds)"],
        ["Calibre","Medium\n(.32, .38, .357)","Medium\n(9 mm, .45 ACP)","High power\n(.303, .308, 5.56 mm)","Gauge (not calibre):\n12 gauge, 20 gauge"],
        ["Bullet","Single lead/FMJ bullet","Single bullet","Single bullet\n(high velocity)","Multiple pellets (shot)\nor single slug"],
        ["Action","Single/double action;\ncylinder rotates per shot","Semi-automatic:\nslide ejects case,\nchambered next round","Bolt action / semi-auto /\nfull auto","Break action / pump /\nsemi-auto"],
        ["Ejected cases","NOT ejected automatically\n(remain in cylinder)","Ejected automatically;\nleft at scene","Varies (bolt = manual;\nsemi = auto ejected)","Not ejected (break)\nor manual"],
        ["Forensic advantage\nof revolver","Cases NOT left at scene\n→ less forensic evidence","Cases left at scene\n→ fingerprints; marks;\nCSI evidence","Long range; ballistic\ncharacteristics","Pellet spread →\nrange estimation"],
        ["Range","Short-medium\n(50–100 m)","Short-medium\n(50–100 m)","Long range\n(300–1000+ m)","Short range\n(< 50 m effective)"],
        ["Wound","Single bullet wound;\nabrasion collar","Single bullet wound;\nabrasion collar","Single high-velocity\nwound; extensive internal\ndamage; large exit","Multiple pellet holes\nor single large hole;\nrange-dependent"],
    ],cw=[2.8*cm,2.8*cm,3*cm,3*cm,PAGE_W-2*M-11.6*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>GAUGE vs CALIBRE (Shotgun):</b>",BOLD))
    E.append(tbl(["Term","Definition"],[
        ["Calibre (rifle/pistol)","Diameter of bore in inches or mm (e.g., .303 inches = 7.7 mm)"],
        ["Gauge (shotgun)","Number of spherical lead balls of bore diameter needed to make 1 lb\nSmaller gauge number = LARGER bore\n12 gauge > 20 gauge in bore size"],
        ["Bore (shotgun)","UK term = gauge"],
    ]))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q110 – RICOCHET WOUNDS
    # ═══════════════════════════════════════════════════════════════
    qb(E,"110","What are Ricochet Wounds?")
    E.append(tbl(["Aspect","Details"],[
        ["Definition","Wound caused by a bullet that has deflected off an intermediate surface before striking the victim"],
        ["Mechanism","Bullet strikes hard surface (wall, floor, road) at an angle → deflects (ricochets)\n→ loses velocity; becomes tumbling/yawing → atypical wound"],
        ["Appearance",
         "1. IRREGULAR, ragged entry wound (no neat abrasion collar)\n"
         "2. Oval or elongated (bullet tumbling/yawing)\n"
         "3. May be larger than calibre (bullet deformed/fragmented)\n"
         "4. May lack typical abrasion collar (deformed bullet)\n"
         "5. Multiple small entry wounds if bullet fragments"],
        ["Abrasion collar","Irregular or absent (deformed bullet)"],
        ["Foreign material","Surface material from deflecting surface (paint, concrete dust, metal fragments) in wound"],
        ["Trajectory","Cannot be used to trace back directly to shooter (deflected path)"],
        ["Forensic significance",
         "1. Scene reconstruction: find deflection point\n"
         "2. Atypical wound may be confused with other injuries\n"
         "3. Multiple small wounds from fragmentation\n"
         "4. Paint/surface material in wound identifies deflection surface\n"
         "5. Lower velocity than direct shot (less penetration)"],
        ["Indirect fire","Also possible: bullet through intermediary object (wood, glass) before entering body β†’ deformed bullet, atypical wound"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,10))

    # ════ SUMMARY TABLE ════════════════════════════════════════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 7 β€” QUICK REFERENCE SUMMARY",
        S('sh',fontSize=13,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(tbl(["Topic","Key 1-Liner"],[
        ["Contact GSW","Stellate tear; soot INSIDE wound; muzzle imprint; gases inflate skin over bone"],
        ["Near range (< 15 cm)","Blackening/soot on surface; singeing; can be wiped off"],
        ["Intermediate range (15–60 cm)","Tattooing/stippling: embedded powder grains; CANNOT be wiped off"],
        ["Distant range (> 60 cm)","Abrasion collar + grease ring only; no soot, no tattooing"],
        ["Entry wound","Smaller; round; INVERTED edges; abrasion collar; grease ring present"],
        ["Exit wound","Larger; irregular; EVERTED edges; no abrasion collar; more bleeding"],
        ["Bone bevelling","Entry: internal bevel (wider inside); Exit: external bevel (wider outside)"],
        ["Grease ring","Distant range; ring of grease/metal from bullet surface; cannot be wiped off"],
        ["Tattooing","Most reliable range indicator; embedded in dermis; permanent"],
        ["Rifling","Spiral grooves β†’ spin β†’ accuracy; striations on bullet β†’ weapon ID"],
        ["Shotgun contact","Single large stellate hole; wad in wound; cribriform pattern on bone"],
        ["Shotgun pepper-pot","2–4 m range; multiple separate pellet holes; no central hole"],
        ["Revolver","Rifled; cylinder; cases NOT ejected β†’ less CSI evidence"],
        ["Shotgun","Smooth bore; gauge (not calibre); pellets; range estimation by spread"],
        ["Ricochet wound","Irregular entry; no typical abrasion collar; surface material in wound; atypical trajectory"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E,onFirstPage=hdr,onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__=="__main__":
    build()
Writing File

~/forensic-medicine-pdfs/chapter8_gen.py

#!/usr/bin/env python3
"""Chapter 8: Toxicology – General & Specific Poisons – Pure White, Print-Ready
   Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's"""

from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (SimpleDocTemplate, Paragraph, Spacer, Table,
    TableStyle, PageBreak, KeepTogether)
from reportlab.platypus.flowables import Flowable

OUTPUT = "/home/daytona/workspace/forensic-medicine-pdfs/Chapter8_Toxicology.pdf"
PAGE_W, PAGE_H = A4
M = 1.8*cm
BLACK = colors.black; WHITE = colors.white

def S(n,**k):
    return ParagraphStyle(n, parent=getSampleStyleSheet()['Normal'], **k)

TITLE=S('Ti',fontSize=22,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=28)
CHAP=S('Ch',fontSize=15,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER)
REF=S('Re',fontSize=8,textColor=BLACK,fontName='Helvetica-Oblique',alignment=TA_CENTER)
QS=S('Qs',fontSize=12,textColor=BLACK,fontName='Helvetica-Bold',leading=17,leftIndent=8)
BODY=S('Bo',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica',alignment=TA_JUSTIFY)
BOLD=S('Bl',fontSize=10,textColor=BLACK,leading=15,spaceAfter=3,fontName='Helvetica-Bold')
NOTE=S('No',fontSize=9,textColor=BLACK,fontName='Helvetica-Oblique',leading=13,leftIndent=10)
MNEM=S('Mn',fontSize=10.5,textColor=BLACK,fontName='Helvetica-Bold',leading=15,leftIndent=10)
TH=S('TH',fontSize=8.5,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=12)
TC=S('TC',fontSize=8.5,textColor=BLACK,fontName='Helvetica',leading=12,alignment=TA_LEFT)

def hdr(canv,doc):
    canv.saveState()
    canv.setStrokeColor(BLACK); canv.setLineWidth(1.5)
    canv.line(M,PAGE_H-1.0*cm,PAGE_W-M,PAGE_H-1.0*cm)
    canv.setFillColor(BLACK); canv.setFont('Helvetica-Bold',9)
    canv.drawString(M,PAGE_H-0.78*cm,"FORENSIC MEDICINE & TOXICOLOGY")
    canv.setFont('Helvetica',8)
    canv.drawRightString(PAGE_W-M,PAGE_H-0.78*cm,"Chapter 8: Toxicology – General & Specific Poisons")
    canv.line(M,0.85*cm,PAGE_W-M,0.85*cm)
    canv.setFont('Helvetica',8)
    canv.drawString(M,0.32*cm,"Ref: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's")
    canv.drawRightString(PAGE_W-M,0.32*cm,f"Page {doc.page}")
    canv.restoreState()

def qb(E,num,txt):
    t=Table([[Paragraph(f"Q.{num}  {txt}",QS)]],colWidths=[PAGE_W-2*M])
    t.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8),
        ('LEFTPADDING',(0,0),(-1,-1),10),('RIGHTPADDING',(0,0),(-1,-1),10)]))
    E.append(KeepTogether([t])); E.append(Spacer(1,5))

def tbl(headers,rows,cw=None):
    avail=PAGE_W-2*M-0.2*cm
    if not cw: cw=[avail/len(headers)]*len(headers)
    data=[[Paragraph(h,TH) for h in headers]]
    for r in rows: data.append([Paragraph(str(c),TC) for c in r])
    t=Table(data,colWidths=cw,repeatRows=1)
    t.setStyle(TableStyle([
        ('BACKGROUND',(0,0),(-1,-1),WHITE),('TEXTCOLOR',(0,0),(-1,-1),BLACK),
        ('FONTNAME',(0,0),(-1,0),'Helvetica-Bold'),('FONTNAME',(0,1),(-1,-1),'Helvetica'),
        ('FONTSIZE',(0,0),(-1,-1),8.5),('GRID',(0,0),(-1,-1),0.6,BLACK),
        ('LINEBELOW',(0,0),(-1,0),1.2,BLACK),('VALIGN',(0,0),(-1,-1),'TOP'),
        ('TOPPADDING',(0,0),(-1,-1),4),('BOTTOMPADDING',(0,0),(-1,-1),4),
        ('LEFTPADDING',(0,0),(-1,-1),5),('RIGHTPADDING',(0,0),(-1,-1),5),
    ]))
    return t

class FC(Flowable):
    def __init__(self,nodes,width=None,nh=34,gap=15):
        super().__init__()
        self.nodes=nodes; self.nw=width or (PAGE_W-2*M-0.5*cm)
        self.nh=nh; self.gap=gap
        self.width=self.nw; self.height=len(nodes)*(nh+gap)-gap+20
    def wrap(self,aW,aH): return self.width,self.height
    def draw(self):
        c=self.canv; y=self.height-10
        nw,nh,gap=self.nw,self.nh,self.gap; cx=nw/2
        for i,(text,shape) in enumerate(self.nodes):
            top=y-nh; mid=y-nh/2
            c.setFillColor(WHITE); c.setStrokeColor(BLACK)
            lw=1.8 if shape=='terminal' else 1.2; c.setLineWidth(lw)
            if shape=='terminal':
                c.roundRect(cx-nw*.38,top,nw*.76,nh,nh/2,fill=1,stroke=1)
            elif shape=='diamond':
                p=c.beginPath(); p.moveTo(cx,y); p.lineTo(cx+nw*.42,mid)
                p.lineTo(cx,top); p.lineTo(cx-nw*.42,mid); p.close()
                c.drawPath(p,fill=1,stroke=1)
            elif shape=='rounded':
                c.roundRect(cx-nw*.44,top,nw*.88,nh,8,fill=1,stroke=1)
            else:
                c.rect(cx-nw*.44,top,nw*.88,nh,fill=1,stroke=1)
            c.setFillColor(BLACK)
            c.setFont('Helvetica-Bold' if shape in('terminal','diamond') else 'Helvetica',8.5)
            lines=text.split('\n'); lh=11
            ty=mid+len(lines)*lh/2-lh*.7
            for ln in lines: c.drawCentredString(cx,ty,ln); ty-=lh
            if i<len(self.nodes)-1:
                ay=top-gap; c.setStrokeColor(BLACK); c.setLineWidth(1.3)
                c.line(cx,top,cx,ay+6); c.setFillColor(BLACK)
                p=c.beginPath(); p.moveTo(cx,ay); p.lineTo(cx-5,ay+8); p.lineTo(cx+5,ay+8)
                p.close(); c.drawPath(p,fill=1,stroke=0)
            y=top-gap

# ═══════════════════════════════════════════════════════════════
def build():
    doc=SimpleDocTemplate(OUTPUT,pagesize=A4,leftMargin=M,rightMargin=M,
        topMargin=1.4*cm,bottomMargin=1.2*cm,title="Chapter 8 – Toxicology")
    E=[]

    # COVER
    E.append(Spacer(1,1.2*cm))
    bdr=Table([[Paragraph("FORENSIC MEDICINE &amp; TOXICOLOGY",TITLE)]],colWidths=[PAGE_W-2*M])
    bdr.setStyle(TableStyle([('BACKGROUND',(0,0),(-1,-1),WHITE),('BOX',(0,0),(-1,-1),3,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),18),('BOTTOMPADDING',(0,0),(-1,-1),18)]))
    E.append(bdr); E.append(Spacer(1,.4*cm))
    cb=Table([[Paragraph("CHAPTER 8",CHAP)]],colWidths=[PAGE_W-2*M])
    cb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),2,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),10),('BOTTOMPADDING',(0,0),(-1,-1),10)]))
    E.append(cb); E.append(Spacer(1,.3*cm))
    tb2=Table([[Paragraph("Toxicology – General &amp; Specific Poisons",
        S('tb',fontSize=17,textColor=BLACK,fontName='Helvetica-Bold',alignment=TA_CENTER,leading=26))]],
        colWidths=[PAGE_W-2*M])
    tb2.setStyle(TableStyle([('TOPPADDING',(0,0),(-1,-1),8),('BOTTOMPADDING',(0,0),(-1,-1),8)]))
    E.append(tb2); E.append(Spacer(1,.3*cm))
    rb=Table([[Paragraph("References: KS Narayan Reddy 36th Ed 2026 | Parikh's | PC Dikshit | DiMaio's",REF)]],
        colWidths=[PAGE_W-2*M])
    rb.setStyle(TableStyle([('BOX',(0,0),(-1,-1),1,BLACK),
        ('TOPPADDING',(0,0),(-1,-1),7),('BOTTOMPADDING',(0,0),(-1,-1),7)]))
    E.append(rb); E.append(Spacer(1,.4*cm))
    E.append(Paragraph("CHAPTER CONTENTS",S('toch',fontSize=11,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=5)))
    E.append(tbl(["Q. No.","Topic"],[
        ["3 / 50","Classification of Poisons & General Principles of Toxicology"],
        ["11","Organophosphorus (OP) Poisoning – Features & Management"],
        ["19","Arsenic Poisoning – Acute & Chronic"],
        ["26","Dhatura (Atropine/Hyoscine) Poisoning"],
        ["35","Snake Bite – Types & Management"],
        ["60","Alcohol (Ethanol) – Medico-legal Aspects"],
        ["75","Carbon Monoxide (CO) Poisoning"],
        ["95 / 130","Barbiturate Poisoning vs Opiate Poisoning"],
        ["112","Corrosive Poisons – Mineral Acids & Alkalis"],
    ],cw=[2.5*cm,PAGE_W-2*M-2.5*cm]))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q3/50 – CLASSIFICATION OF POISONS
    # ═══════════════════════════════════════════════════════════════
    qb(E,"3 / 50","Classification of Poisons & General Principles of Toxicology")
    E.append(Paragraph(
        "<b>Poison:</b> Any substance which, when introduced into the living body in relatively small quantities, "
        "causes injury or death by its chemical action. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(Paragraph("<b>CLASSIFICATION OF POISONS:</b>",BOLD))
    E.append(tbl(["Class","Subclass","Examples"],[
        ["<b>1. Corrosives</b>","Strong acids\nStrong alkalis\nMetallic salts",
         "H2SO4, HCl, HNO3, carbolic acid\nNaOH (caustic soda), KOH, NH3\nFeSO4, CuSO4"],
        ["<b>2. Irritants</b>",
         "Inorganic: metallic\nInorganic: non-metallic\nOrganic\nMechanical",
         "Arsenic, lead, mercury, copper, phosphorus\nHalides, boric acid\nCroton oil, cantharidin, ricin, abrin\nGround glass, diamond dust"],
        ["<b>3. Neurotics\n(Systemic)</b>",
         "Cerebral (narcotic/sedative)\nSpinal (convulsant)\nPeripheral (paralytic)",
         "Opium, alcohol, chloroform, CO\nStrychnine, nux vomica\nCurare, conium"],
        ["<b>4. Cardiac</b>","","Digitalis, aconite, veratrum, nicotine, tobacco"],
        ["<b>5. Asphyxiants</b>","","CO, HCN, H2S, SO2"],
        ["<b>6. Deliriants /\nHallucinogens</b>","","Dhatura, cannabis, cocaine, LSD, belladonna"],
        ["<b>7. Miscellaneous</b>","Insecticides\nHerbicides\nVenom",
         "Organophosphorus, carbamates, organochlorine\nParaquat\nSnake, scorpion, bee"],
    ],cw=[3*cm,3.5*cm,PAGE_W-2*M-6.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Toxicological Concept","Definition"],[
        ["Lethal dose (LD50)","Dose that kills 50% of test animals; standard measure of acute toxicity"],
        ["Minimum lethal dose (MLD)","Smallest dose that has caused death in humans"],
        ["Therapeutic index","LD50 / ED50; wide TI = safer drug (e.g., penicillin); narrow TI = dangerous (e.g., digoxin, phenytoin)"],
        ["Tolerance","Repeated exposure β†’ reduced effect β†’ need higher dose (e.g., opioids, alcohol)"],
        ["Idiosyncrasy","Abnormal sensitivity (genetic) to a drug unrelated to dose"],
        ["Synergism","Two drugs produce greater effect together than sum of individual effects"],
        ["Antagonism","One drug reduces effect of another"],
        ["Cumulation","Drug accumulates in body (slow elimination) β†’ toxicity at therapeutic doses (e.g., lead, mercury, digitalis)"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q11 – OP POISONING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"11","Organophosphorus (OP) Poisoning – Features & Management")
    E.append(Paragraph(
        "OP compounds (pesticides) are the <b>most common cause of poisoning death in India</b>. "
        "They inhibit acetylcholinesterase β†’ accumulation of acetylcholine β†’ over-stimulation of "
        "muscarinic and nicotinic receptors. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))

    E.append(tbl(["Feature","Details"],[
        ["Examples","Malathion, parathion, diazinon, chlorpyrifos, dichlorvos (DDVP); nerve agents (sarin, VX)"],
        ["Mechanism","Inhibits acetylcholinesterase (AChE)\n→ ACh accumulates at synapses\n→ Excessive muscarinic + nicotinic stimulation"],
        ["Route","Ingestion (most common in India), inhalation, skin absorption"],
        ["Smell","Garlic-like odour (organophosphorus)"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>CLINICAL FEATURES – MNEMONIC: SLUDGE + Nicotinic + CNS</b>",BOLD))
    E.append(MNEM and Paragraph("<b>MUSCARINIC (SLUDGE-M):</b> Salivation, Lacrimation, Urination, Defecation, GI distress (cramps/vomiting), Emesis, Miosis (pinpoint pupils), Bradycardia, Bronchospasm/secretions",MNEM) or None)
    E.append(Paragraph("<b>MUSCARINIC (SLUDGE-M):</b> Salivation, Lacrimation, Urination, Defecation, GI distress, Emesis, Miosis, Bradycardia, Bronchospasm",MNEM))
    E.append(Spacer(1,3))
    E.append(tbl(["System","Features","Receptor"],[
        ["<b>Muscarinic\n(SLUDGE-M)</b>",
         "S – Salivation (excessive drooling)\nL – Lacrimation (tears)\nU – Urination (incontinence)\nD – Defecation (diarrhoea)\nG – GI cramps / vomiting\nE – Emesis\nM – Miosis (pinpoint pupils), bradycardia, bronchospasm, bronchorrhoea, sweating",
         "Muscarinic\n(smooth muscle, glands,\nheart)"],
        ["<b>Nicotinic\n(muscles + ganglia)</b>",
         "Muscle fasciculations, twitching β†’ weakness β†’ PARALYSIS\nTachycardia (early), hypertension (early)\nMydriasis can occur\nRespiratory muscle paralysis β†’ respiratory failure",
         "Nicotinic\n(skeletal muscle, ganglia)"],
        ["<b>CNS</b>",
         "Anxiety, restlessness, confusion\nSeizures (convulsions)\nComa\nCentral respiratory depression",
         "Both"],
    ],cw=[3*cm,5.5*cm,PAGE_W-2*M-8.5*cm]))
    E.append(Spacer(1,5))

    E.append(tbl(["PM Findings","Details"],[
        ["Pupils","Pinpoint (miosis) – most characteristic"],
        ["Smell","Garlic odour from stomach contents / body"],
        ["Lungs","Pulmonary oedema; frothy secretions in airways; bronchospasm signs"],
        ["Stomach","Odour; mucosal hyperemia; undigested food"],
        ["Blood","Serum cholinesterase level very low (diagnostic)"],
        ["Brain","Cerebral oedema; no specific histology"],
    ],cw=[3*cm,PAGE_W-2*M-3*cm]))
    E.append(Spacer(1,5))

    E.append(Paragraph("<b>MANAGEMENT:</b>",BOLD))
    E.append(FC([
        ("OP POISONING\n(ingestion / inhalation / skin)","terminal"),
        ("DECONTAMINATE:\nRemove clothing; wash skin with soap+water;\nGastric lavage (within 1–2 hrs if oral)","rect"),
        ("AIRWAY: Suction secretions;\nintubate if respiratory failure;\n100% O2","rect"),
        ("ATROPINE IV:\n2–4 mg every 5–10 min until secretions DRY\n(not just HR or pupils – give until lungs clear)","rounded"),
        ("PRALIDOXIME (PAM) 1–2 g IV:\nReactivates AChE (if given early – before 'aging')\nMust be given WITHIN 24–48 hrs","rounded"),
        ("BENZODIAZEPINES:\nFor seizures (diazepam IV)","rect"),
        ("MONITOR:\nSerum cholinesterase; pulse; secretions;\nrespiratory rate; O2 sat","rect"),
        ("ATROPINE endpoint:\nDry secretions; clear chest on auscultation\n(NOT tachycardia or mydriasis)","terminal"),
    ],nh=35,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q19 – ARSENIC POISONING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"19","Arsenic Poisoning – Acute and Chronic")
    E.append(Paragraph(
        "Arsenic is a <b>classic homicidal poison</b> (historically called 'inheritance powder'). "
        "It is tasteless, odourless, and resembles flour. Persists indefinitely in hair, nails, and bones. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Feature","ACUTE Arsenic Poisoning","CHRONIC Arsenic Poisoning"],[
        ["Dose","Arsenic trioxide: ~100–200 mg (fatal)","Repeated small doses over months/years"],
        ["Onset","30 min–2 hrs after ingestion","Weeks to months"],
        ["GI features",
         "Severe nausea, vomiting, diarrhoea\n'Rice water' stools (cholera-like)\nMetallic taste; burning in mouth/throat\nAbdominal cramps",
         "Mild GI upset; nausea; anorexia;\nweight loss"],
        ["Neurological",
         "Convulsions; delirium; coma (severe cases);\nfollowed by collapse and death",
         "Peripheral neuropathy:\nglove-stocking pattern;\nweakness; paraesthesia"],
        ["Skin",
         "Severe irritation; desquamation\n(less prominent acutely)",
         "Classic SKIN CHANGES:\n1. Raindrop pigmentation (hyperpigmented+hypopigmented)\n2. Keratosis (palms and soles)\n3. Mees' lines: transverse white bands on nails\n4. Skin cancer risk"],
        ["Hair & Nails","–",
         "Mees' lines on nails (1 line per episode)\nArsenic deposited in hair (Reinsch test)\nAlopecia (hair loss)"],
        ["Other",
         "Cardiovascular collapse;\nrespiratory failure;\njaundice (liver damage)",
         "Liver: cirrhosis; portal hypertension\nKidney: tubular damage\nBlood: anaemia, leukopenia\nLung: cancer risk"],
        ["COD (acute)","Circulatory collapse + respiratory failure","Malignancy / organ failure"],
        ["PM findings (acute)",
         "Gastroenteritis pattern;\nmucosal hyperemia/erosion;\nliver/kidney congestion;\nbrick-red gastric mucosa",
         "Hyperkeratosis; skin changes;\nhair/nail arsenic levels elevated"],
        ["Tests",
         "Marsh test (classical); Reinsch test;\nAtomic Absorption Spectroscopy (AAS) – definitive",
         "Hair/nail arsenic: Reinsch test;\nAAS; urine arsenic"],
    ],cw=[3*cm,4.5*cm,PAGE_W-2*M-7.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Arsenic Test","Principle","Result"],[
        ["Marsh test","Arsenic + H2SO4 + Zn → AsH3 gas → heated tube\n→ arsenic mirror (metallic deposit)","Black/brown metallic mirror = arsenic"],
        ["Reinsch test","Copper strip inserted into acidified boil of sample;\narsenic deposits on copper","Black deposit on copper strip"],
        ["AAS (Atomic Absorption Spectroscopy)","Gold standard; quantitative; used in forensic labs","Arsenic concentration in ppm"],
    ],cw=[3*cm,5*cm,PAGE_W-2*M-8*cm]))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q26 – DHATURA POISONING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"26","Dhatura (Atropine / Hyoscine) Poisoning")
    E.append(Paragraph(
        "<b>Dhatura (Datura stramonium)</b> is a plant ('thorn apple') containing anticholinergic alkaloids: "
        "<b>atropine, hyoscine (scopolamine), hyoscyamine</b>. Classic homicidal/criminal poison in India "
        "used to stupefy victims. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Aspect","Details"],[
        ["Plant","Datura stramonium (thorn apple); Datura metel; all parts toxic (seeds most potent)"],
        ["Active alkaloids","Atropine (racemic hyoscyamine); Hyoscine (scopolamine); Hyoscyamine"],
        ["Mechanism","ANTICHOLINERGIC: blocks muscarinic ACh receptors\n→ 'dry, hot, blind, mad, red, tachycardia'"],
        ["Use as criminal poison","Slipped into food/drink to stupefy victims β†’ robbery/sexual assault;\nalso used in ritual crimes"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,4))
    E.append(Paragraph("<b>CLINICAL FEATURES – MNEMONIC: 'Hot as a hare, Dry as a bone, Blind as a bat, Mad as a hatter, Red as a beet, Fast as a fiddle'</b>",MNEM))
    E.append(Spacer(1,3))
    E.append(tbl(["Mnemonic","Feature","Mechanism"],[
        ["Hot as a hare","Hyperthermia; fever","Anhidrosis (no sweating) + metabolic rate"],
        ["Dry as a bone","Dry mouth, dry skin, anhidrosis;\nconstipation, urinary retention","Block of secretory glands + bladder"],
        ["Blind as a bat","Mydriasis (dilated pupils);\ncycloplegia (blurred vision)","Ciliary muscle + iris sphincter blocked"],
        ["Mad as a hatter","Confusion, delirium, hallucinations;\nagitation, excitement","Central anticholinergic effect"],
        ["Red as a beet","Flushing of skin (cutaneous vasodilation)","Compensatory vasodilation for heat"],
        ["Fast as a fiddle","Tachycardia","Vagal block; SA node released"],
    ],cw=[3.5*cm,3.5*cm,PAGE_W-2*M-7*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Management","Details"],[
        ["Gastric lavage","Within 2 hrs; activated charcoal 50 g (absorbs alkaloids)"],
        ["Physostigmine","0.5–2 mg IV slowly – SPECIFIC ANTIDOTE\n(anticholinesterase β†’ increases ACh β†’ reverses anticholinergic effects)\nRepeat if needed; use only for severe CNS symptoms"],
        ["Symptomatic","IV fluids; cooling measures (hyperthermia); diazepam (convulsions);\nurinary catheter (urinary retention)"],
        ["Avoid","Phenothiazines (worsen anticholinergic effects)"],
    ],cw=[3*cm,PAGE_W-2*M-3*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: Dhatura Poisoning – Recognition & Management</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("DHATURA INGESTION\n(Datura stramonium)","terminal"),
        ("ANTICHOLINERGIC SYNDROME:\nDry mouth; mydriasis; tachycardia;\nhyperthermia; flushing; confusion","rect"),
        ("Distinguish from\nSympathomimetic syndrome?","diamond"),
        ("ANTICHOLINERGIC: skin DRY, hot\nSYMPATHOMIMETIC: skin MOIST, diaphoretic","rounded"),
        ("GASTRIC LAVAGE + Activated charcoal\n(if within 2 hrs)","rect"),
        ("PHYSOSTIGMINE 0.5–2 mg IV\n(specific antidote for severe CNS effects)","rounded"),
        ("Symptomatic: cooling; diazepam;\nIV fluids; catheter","rect"),
        ("MONITOR:\nHR; temperature; urine output;\nconsciousness","terminal"),
    ],nh=35,gap=12))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q35 – SNAKE BITE
    # ═══════════════════════════════════════════════════════════════
    qb(E,"35","Snake Bite – Types of Venom & Management")
    E.append(Paragraph(
        "India is a high-burden snakebite country. The <b>Big Four</b> medically important snakes: "
        "Russell's viper, Saw-scaled viper, Common cobra, Common krait. (KS Narayan Reddy; WHO)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["Type of Venom","Mechanism","Main Snakes","Clinical Features"],[
        ["<b>NEUROTOXIC</b>","Blocks ACh at neuromuscular junction:\nPre-synaptic: destroys nerve terminal\n(e.g., beta-bungarotoxin – irreversible)\nPost-synaptic: competes with ACh at receptor\n(e.g., alpha-bungarotoxin – reversible)",
         "Krait (Bungarus)\nCobra (Naja)\nMamba\nSea snake",
         "Ptosis; diplopia; ophthalmoplegia;\ndysarthria; dysphagia;\nProgressive descending flaccid paralysis;\nRespiratory failure; NO coagulopathy;\nLocal: minimal (krait – no swelling);\nCobra: local necrosis"],
        ["<b>HAEMOTOXIC /\nVASCULOTOXIC</b>",
         "Phospholipase; hyaluronidase;\nProcoagulant enzymes β†’ DIC\nHaemolysin; cytotoxin",
         "Russell's viper (Daboia)\nSaw-scaled viper\nGreen pit viper",
         "Local: severe pain; swelling; necrosis;\nblistering; gangrene\nSystemic: bleeding from all sites;\nhaematuria; haematemesis;\nDIC; acute kidney injury (AKI);\nspontaneous haemorrhage"],
        ["<b>CYTOTOXIC /\nNECROTOXIC</b>","Cell membrane destruction;\nTissue necrosis",
         "Spitting cobra\nRinghals",
         "Local tissue necrosis;\ngangrene; compartment syndrome;\nmay lose limb"],
        ["<b>MYOTOXIC</b>","Phospholipase A2 β†’ muscle breakdown;\nrhabdomyolysis",
         "Sea snakes\nSome vipers",
         "Myalgia; myoglobinuria;\nAKI; hyperkalemia"],
    ],cw=[3*cm,3.5*cm,3*cm,PAGE_W-2*M-9.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>MANAGEMENT:</b>",BOLD))
    E.append(tbl(["Step","Action"],[
        ["1. FIRST AID","Immobilise limb (splint); rest; calm victim; DO NOT cut/suck/tourniquet;\nPressure immobilisation bandage ONLY for neurotoxic (krait/cobra) – NOT for viper bites"],
        ["2. HOSPITAL: ABC","Airway; IV access; blood tests: CBC, BT/CT, 20-minute whole blood clotting test (WBCT), PT/INR, renal function, urinalysis"],
        ["3. 20-min WBCT","If blood does NOT clot in 20 min β†’ HAEMOTOXIC envenomation β†’ give ASV"],
        ["4. ASV (Anti-snake Venom)","ONLY definitive treatment\nPolyvalent ASV covers all Big Four\nDose: 10 vials initially; repeat if not improved\nTest dose NOT recommended (no benefit)\nGive IV; watch for anaphylaxis"],
        ["5. Neostigmine + Atropine","For neurotoxic (cobra): neostigmine 0.5–2.5 mg + atropine 0.6 mg IV; titrate;\nReversible post-synaptic block responds; pre-synaptic (krait) does NOT"],
        ["6. Ventilation","Mechanical ventilation for respiratory failure (krait bites)"],
        ["7. Haemodialysis","For AKI from viper bite"],
        ["8. Blood products","FFP/platelets for DIC"],
        ["9. Surgical","Fasciotomy if compartment syndrome;\ndebridement of necrotic tissue"],
    ],cw=[2.8*cm,PAGE_W-2*M-2.8*cm]))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q60 – ALCOHOL (ETHANOL) – MEDICO-LEGAL
    # ═══════════════════════════════════════════════════════════════
    qb(E,"60","Alcohol (Ethanol) – Medico-legal Aspects")
    E.append(tbl(["Blood Alcohol\nConcentration (BAC)","Clinical State","Behaviour"],[
        ["< 50 mg/100 mL\n(< 0.05%)","Sobriety","Normal; subtle impairment of fine judgment (measurable only by tests)"],
        ["50–100 mg/100 mL\n(0.05–0.10%)","Euphoria / Impairment","Mild impairment of judgment; loss of inhibitions; talkativeness"],
        ["100–150 mg/100 mL","Excitement","Obvious intoxication; slurred speech; incoordination"],
        ["150–250 mg/100 mL","Confusion / Incoordination","Staggering; dysarthria; ataxia; emotional lability"],
        ["250–350 mg/100 mL","Stupor","Cannot stand; incontinence; nearly unconscious"],
        ["350–450 mg/100 mL","Coma","Unconscious; no response to stimuli; risk of death"],
        ["> 450 mg/100 mL","Death","Respiratory paralysis; cardiovascular collapse"],
    ],cw=[3.5*cm,3*cm,PAGE_W-2*M-6.5*cm]))
    E.append(Spacer(1,5))
    E.append(tbl(["Medico-legal Aspect","Details"],[
        ["Legal driving limit (India)","30 mg/100 mL blood (Motor Vehicles Act, amended 2019;\npreviously 30 mg/100 mL)"],
        ["Legal driving limit (UK)","80 mg/100 mL blood (or 35 ΞΌg/100 mL breath)"],
        ["Testing (India)","Breathalyzer (roadside); blood test (medico-legal); urine test"],
        ["Widmark formula","BAC = (Dose in g) / (body weight kg Γ— r)\nr = 0.68 (men), 0.55 (women)\nUsed to calculate estimated BAC"],
        ["Elimination rate","~15–20 mg/100 mL/hr (first-order kinetics at low; zero-order at high)"],
        ["Ante-mortem vs PM","PM redistribution: BAC increases after death;\nvitreous humor alcohol more reliable (less PM change);\nvitreous:blood ratio ~1.2:1"],
        ["Forensic significance","Drunkenness: diminished responsibility (not defence to crime in India);\nSection 510 IPC: misconduct in public by drunk person;\n304A IPC: culpable homicide while drunk driving;\nMVA: drunk driving offence"],
        ["Denatured alcohol / methanol","Methanol: metabolized to formaldehyde + formate β†’ metabolic acidosis;\nblindness (optic nerve damage); \nantidote: ethanol (competitive) or fomepizole"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q75 – CO POISONING
    # ═══════════════════════════════════════════════════════════════
    qb(E,"75","Carbon Monoxide (CO) Poisoning")
    E.append(Paragraph(
        "CO is an odourless, colourless, tasteless gas produced by incomplete combustion. "
        "It binds haemoglobin 240x more avidly than O2 β†’ carboxyhaemoglobin (HbCO) β†’ tissue hypoxia. (KS Narayan Reddy)",BODY))
    E.append(Spacer(1,4))
    E.append(tbl(["HbCO Saturation","Symptoms"],[
        ["0–10%","Normal (smokers up to 10%); headache possible"],
        ["10–20%","Headache; fatigue; dyspnoea on exertion"],
        ["20–40%","Severe headache; dizziness; confusion; nausea; impaired judgment"],
        ["40–60%","Convulsions; loss of consciousness; tachycardia; syncope"],
        ["> 60%","Coma; Cheyne-Stokes respiration; cardiovascular collapse; death"],
        ["> 70%","Rapidly fatal (minutes)"],
    ]))
    E.append(Spacer(1,5))
    E.append(tbl(["Feature","Details"],[
        ["Sources","Incomplete combustion: car exhaust; coal fires; charcoal braziers;\ndefective heaters; industrial furnaces; fires"],
        ["Mechanism","HbCO: O2 displaced from Hb (240x affinity);\nLeft shift of O2-Hb dissociation curve (O2 not released to tissues);\nCO binds cytochrome oxidase (cellular hypoxia)"],
        ["Cherry-red colour","HbCO is cherry-red β†’ skin, livor, blood = cherry red/pink\n(diagnostic at PM); seen in: CO + HCN + cold exposure"],
        ["Diagnosis","HbCO level by co-oximetry (spectrophotometry)"],
        ["PM findings","Cherry-red blood + organs; cherry-red livor mortis;\ncongestion; pulmonary oedema; petechiae;\nbrain: bilateral basal ganglia necrosis (globus pallidus – delayed sequelae)"],
        ["Treatment","REMOVE from source;\n100% O2 via tight mask (accelerates HbCO dissociation:\nhalf-life 5 hr room air β†’ 1 hr 100% O2 β†’ 20 min hyperbaric O2);\nHYPERBARIC O2: for HbCO > 25%; pregnancy; LOC; cardiac involvement;\nSupportive: seizures, cardiac, fluids"],
        ["Delayed sequelae","2–3 weeks post-recovery: neuropsychiatric syndrome;\nGlobus pallidus necrosis (Parkinsonism, dementia, personality change)"],
        ["Accidental/suicidal/homicidal","Most: accidental (faulty heaters, fires);\nSuicidal: car exhaust inhalation;\nHomicidal: rare; confining victim in enclosed space with CO source"],
    ],cw=[3.5*cm,PAGE_W-2*M-3.5*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>FLOWCHART: CO Poisoning – Diagnosis & Management</b>",BOLD))
    E.append(Spacer(1,4))
    E.append(FC([
        ("CO EXPOSURE\n(enclosed space + combustion source)","terminal"),
        ("CO + Hb β†’ HbCO\n(240x affinity; O2 displaced)","rect"),
        ("O2 cannot be delivered to tissues\n→ CELLULAR HYPOXIA","rect"),
        ("SYMPTOMS: Headache → confusion\n→ convulsions → coma → death\nSkin/blood: CHERRY RED","rect"),
        ("MEASURE HbCO by\nco-oximetry","diamond"),
        ("HbCO > 25% OR\nLOC / pregnancy / cardiac?","diamond"),
        ("YES β†’ HYPERBARIC O2\n(half-life 20 min)","rounded"),
        ("NO β†’ 100% O2 via tight mask\n(half-life 1 hr)","rounded"),
        ("SUPPORTIVE:\nSeizures β†’ diazepam;\nCardiac monitoring;\nICP management","rect"),
        ("Monitor for DELAYED SEQUELAE\n(2–3 weeks: basal ganglia damage)","terminal"),
    ],nh=35,gap=11))
    E.append(Spacer(1,10))
    E.append(PageBreak())

    # ═══════════════════════════════════════════════════════════════
    # Q95/130 – BARBITURATE vs OPIATE
    # ═══════════════════════════════════════════════════════════════
    qb(E,"95 / 130","Barbiturate Poisoning vs Opiate Poisoning – Comparison")
    E.append(tbl(["Feature","BARBITURATE POISONING","OPIATE POISONING"],[
        ["Examples","Phenobarbitone; amylobarbitone;\npentobarbitone; thiopentone",
         "Morphine; heroin; codeine;\npethidine; methadone; fentanyl"],
        ["Mechanism","Enhances GABA-A (Cl⁻ channel) β†’ CNS depression",
         "Binds mu/kappa/delta opioid receptors\n→ CNS + respiratory depression"],
        ["Pupils","Dilated (mydriasis) or normal","PINPOINT (miosis) – CLASSIC"],
        ["Respiratory","Depression (dose-dependent)","Profound respiratory depression;\nrate may drop to < 4/min"],
        ["Cardiovascular","Hypotension; bradycardia","Hypotension; bradycardia"],
        ["Reflexes","Reduced / absent","Reduced; flaccidity"],
        ["Skin","Cold; cyanosed (if hypoxic)","Flushed; warm; sweating (morphine histamine release)"],
        ["Bowel sounds","Reduced","Markedly REDUCED (constipation)"],
        ["Temperature","Hypothermia","Hypothermia or normal"],
        ["Seizures","Possible (paradoxical excitation early)","Unusual (meperidine: normeperidine β†’ seizures)"],
        ["PM findings","Pulmonary oedema; brain oedema;\nserum barbiturate level; no specific antidote",
         "Pulmonary oedema;\npinpoint pupils at PM;\nserum opiate level;\ninjection marks (IV users);\ntolerance history"],
        ["ANTIDOTE","NONE specific\n(supportive only: airway, ventilation)","NALOXONE (opioid antagonist)\n0.4–2 mg IV; repeat q2–3 min;\ninfusion if needed (short half-life)"],
        ["Treatment","Activated charcoal;\nsupportive: intubation + ventilation;\nalkalinise urine (phenobarbitone);\nhaemoperfusion (severe)","Naloxone + airway management;\ngastric lavage (oral ingestion);\nactivated charcoal"],
    ],cw=[3*cm,4.3*cm,PAGE_W-2*M-7.3*cm]))
    E.append(Spacer(1,10))

    # ═══════════════════════════════════════════════════════════════
    # Q112 – CORROSIVE POISONS
    # ═══════════════════════════════════════════════════════════════
    qb(E,"112","Corrosive Poisons – Mineral Acids & Alkalis")
    E.append(tbl(["Feature","MINERAL ACIDS","ALKALIS (Caustic)"],[
        ["Examples","H2SO4 (sulphuric acid – 'oil of vitriol')\nHCl (hydrochloric acid – 'spirit of salt')\nHNO3 (nitric acid – 'aqua fortis')\nCarbolic acid (phenol)",
         "NaOH (caustic soda)\nKOH (caustic potash)\nNH3 (ammonia)\nCa(OH)2 (slaked lime)"],
        ["Mechanism","COAGULATIVE necrosis\n(protein coagulation β†’ firm eschar β†’ limits spread)",
         "LIQUEFACTIVE necrosis\n(saponification of fats + dissolves proteins β†’ soft, deep spread)"],
        ["Eschar","HARD, firm, dry eschar\n(limits further penetration)","SOFT, soapy, gelatinous eschar\n(continues to penetrate deeply)"],
        ["Depth","Limited by eschar formation","DEEPER (continues to penetrate)"],
        ["Appearance","H2SO4: black/brown charring\nHCl: white/grey eschar\nHNO3: yellow (xanthoproteic rxn)\nCarbolic: white then brown eschar",
         "Grey-white; soapy; soft;\nmucus-coated"],
        ["Pain","Immediate burning pain","Burning pain; often delayed initially"],
        ["Odour","H2SO4: acrid\nHCl: pungent HCl fumes\nHNO3: acrid brown fumes\nCarbolic: phenol smell",
         "NH3: pungent ammonia smell;\nNaOH: odourless"],
        ["Systemic effects","Hepatotoxicity (carbolic);\nrenal failure;\nmetabolic acidosis",
         "Oesophageal stricture (late);\nserious GI damage;\nHypocalcemia (HF)"],
        ["Late complication","Stricture of oesophagus/pylorus","Oesophageal stricture (COMMON);\n alkaline burns β†’ worse stricture formation"],
        ["Treatment","Dilute with water/milk;\nno neutralisation (exothermic);\nairway; IV fluids;\nendoscopy after 24–48 hrs",
         "Dilute with water/milk;\nno neutralisation;\nendoscopy; PPI;\nTPN; oesophageal dilatation later"],
        ["PM findings","Burnt lips/mouth/oesophagus/stomach;\ncoagulative necrosis;\nperforation possible",
         "Liquefactive necrosis;\noesophagus/stomach softened;\nno charring"],
    ],cw=[3*cm,4.2*cm,PAGE_W-2*M-7.2*cm]))
    E.append(Spacer(1,5))
    E.append(Paragraph("<b>MNEMONIC – Acid colour of eschar:</b> Sulphuric = <b>S</b>ooty black; Hydrochloric = white/<b>H</b>azy; Nitric = <b>N</b>itrogenous yellow; Carbolic = white then brown",NOTE))
    E.append(Spacer(1,10))

    # ════ SUMMARY TABLE ════════════════════════════════════════════
    E.append(PageBreak())
    E.append(Paragraph("CHAPTER 8 β€” QUICK REFERENCE SUMMARY",
        S('sh',fontSize=13,textColor=BLACK,fontName='Helvetica-Bold',spaceAfter=8,alignment=TA_CENTER)))
    E.append(tbl(["Poison","Key Feature / Antidote"],[
        ["OP compounds","SLUDGE-M + fasciculations; Rx: Atropine (dry secretions) + Pralidoxime (reactivates AChE within 48 hrs)"],
        ["Arsenic (acute)","Rice-water stools; cholera-like; Marsh test; Reinsch test positive"],
        ["Arsenic (chronic)","Raindrop pigmentation; Mees' lines; keratosis; neuropathy"],
        ["Dhatura","Anticholinergic: dry, hot, blind, mad, red, fast; Rx: Physostigmine"],
        ["Snake – neurotoxic","Descending paralysis; ptosis; respiratory failure; Krait/Cobra; Rx: ASV + neostigmine (cobra)"],
        ["Snake – haemotoxic","Bleeding; DIC; AKI; 20-min WBCT fails to clot; Russell's viper; Rx: ASV + dialysis"],
        ["CO poisoning","Cherry-red; HbCO elevated; Rx: 100% O2; HBO if >25% or LOC"],
        ["CO PM","Cherry-red livor + blood; basal ganglia necrosis (delayed)"],
        ["HCN","Cherry-red blood; bitter almond smell; histotoxic anoxia; Rx: hydroxocobalamin"],
        ["Barbiturate","CNS depression; mydriasis; no antidote; supportive + ventilation"],
        ["Opiates","Pinpoint pupils; respiratory depression; NALOXONE is antidote"],
        ["Mineral acids","Coagulative necrosis; hard eschar; H2SO4 = black; HNO3 = yellow; HCl = white"],
        ["Alkalis","Liquefactive necrosis; soft deep eschar; oesophageal stricture common"],
        ["Alcohol (India)","Legal limit: 30 mg/100 mL; vitreous humor more reliable PM; methanol β†’ blindness"],
    ],cw=[4*cm,PAGE_W-2*M-4*cm]))

    doc.build(E,onFirstPage=hdr,onLaterPages=hdr)
    print(f"SUCCESS: {OUTPUT}")

if __name__=="__main__":
    build()
Running Command

cd /home/daytona/workspace/forensic-medicine-pdfs && python3 chapter7_gen.py 2>&…

Your credits are exhausted. You can purchase a top-up or subscribe to a plan to continue using Orris. If you're already subscribed, your daily credits will reset tomorrow.
This is a shared conversation. Sign in to Orris to start your own chat.