Gynae Kay Hawalay Say Aik PDF Book Bana Day Jis Gynae Kay Hawalay Say Knowledge Ho 100 Pages Ho
mkdir -p /home/daytona/workspace/gynae-book && ls /home/daytona/workspace/gynae-…
~/gynae-book/build_gynae_pdf.py
#!/usr/bin/env python3
"""
Gynaecology Reference Book - PDF Generator
Based on Berek & Novak's Gynecology (authoritative medical textbook)
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch, cm
from reportlab.lib.colors import HexColor, white, black
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
PageBreak, HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY, TA_RIGHT
from reportlab.pdfgen import canvas
from reportlab.lib import colors
OUTPUT = "/home/daytona/workspace/gynae-book/Gynaecology_Complete_Guide.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
DEEP_TEAL = HexColor("#006466")
MID_TEAL = HexColor("#0D9488")
LIGHT_TEAL = HexColor("#CCFBF1")
ACCENT = HexColor("#F97316")
SOFT_GRAY = HexColor("#F8FAFC")
MED_GRAY = HexColor("#94A3B8")
DARK_GRAY = HexColor("#1E293B")
TABLE_HEAD = HexColor("#0F766E")
TABLE_ALT = HexColor("#F0FDFA")
# ── Styles ───────────────────────────────────────────────────────────────────
styles = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
cover_title = S("CoverTitle", fontSize=36, leading=44, textColor=white,
alignment=TA_CENTER, fontName="Helvetica-Bold", spaceAfter=10)
cover_sub = S("CoverSub", fontSize=20, leading=28, textColor=LIGHT_TEAL,
alignment=TA_CENTER, fontName="Helvetica", spaceAfter=6)
cover_auth = S("CoverAuth", fontSize=13, leading=18, textColor=white,
alignment=TA_CENTER, fontName="Helvetica")
chap_heading = S("ChapHeading", fontSize=26, leading=32, textColor=white,
fontName="Helvetica-Bold", alignment=TA_LEFT, spaceAfter=4)
chap_num = S("ChapNum", fontSize=13, leading=18, textColor=LIGHT_TEAL,
fontName="Helvetica-Bold", alignment=TA_LEFT, spaceAfter=2)
h1 = S("H1", fontSize=16, leading=20, textColor=DEEP_TEAL,
fontName="Helvetica-Bold", spaceBefore=14, spaceAfter=6)
h2 = S("H2", fontSize=13, leading=17, textColor=MID_TEAL,
fontName="Helvetica-Bold", spaceBefore=10, spaceAfter=4)
h3 = S("H3", fontSize=11, leading=15, textColor=DARK_GRAY,
fontName="Helvetica-BoldOblique", spaceBefore=7, spaceAfter=3)
body = S("Body", fontSize=10, leading=15, textColor=DARK_GRAY,
fontName="Helvetica", alignment=TA_JUSTIFY, spaceBefore=3, spaceAfter=3)
bullet = S("Bullet", fontSize=10, leading=15, textColor=DARK_GRAY,
fontName="Helvetica", leftIndent=18, firstLineIndent=-10,
spaceBefore=2, spaceAfter=2)
note = S("Note", fontSize=9, leading=13, textColor=HexColor("#64748B"),
fontName="Helvetica-Oblique", leftIndent=10)
keybox = S("KeyBox", fontSize=10, leading=14, textColor=DEEP_TEAL,
fontName="Helvetica-Bold", leftIndent=10)
toc_entry = S("TOC", fontSize=11, leading=16, textColor=DARK_GRAY,
fontName="Helvetica", spaceBefore=1)
toc_ch = S("TOCCH", fontSize=12, leading=17, textColor=DEEP_TEAL,
fontName="Helvetica-Bold", spaceBefore=4)
W, H = A4
MARGIN = 2.2*cm
# ── Helper builders ───────────────────────────────────────────────────────────
def hrule(color=MID_TEAL, thickness=1.5):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=6, spaceBefore=4)
def colored_box(text, bg=LIGHT_TEAL, txt_color=DEEP_TEAL, padding=8):
data = [[Paragraph(text, S("kb", fontSize=10, leading=14,
textColor=txt_color, fontName="Helvetica-Bold"))]]
t = Table(data, colWidths=[W - 2*MARGIN - 2])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("LEFTPADDING", (0,0), (-1,-1), padding),
("RIGHTPADDING", (0,0), (-1,-1), padding),
("TOPPADDING", (0,0), (-1,-1), padding),
("BOTTOMPADDING",(0,0), (-1,-1), padding),
("ROUNDEDCORNERS", [6]),
]))
return t
def data_table(headers, rows, col_widths=None):
if col_widths is None:
avail = W - 2*MARGIN - 4
col_widths = [avail / len(headers)] * len(headers)
hdr_style = S("th", fontSize=9, leading=12, textColor=white,
fontName="Helvetica-Bold", alignment=TA_CENTER)
cell_style = S("td", fontSize=9, leading=12, textColor=DARK_GRAY,
fontName="Helvetica", alignment=TA_LEFT)
data = [[Paragraph(h, hdr_style) for h in headers]]
for i, row in enumerate(rows):
data.append([Paragraph(str(c), cell_style) for c in row])
t = Table(data, colWidths=col_widths, repeatRows=1)
ts = [
("BACKGROUND", (0,0), (-1,0), TABLE_HEAD),
("TEXTCOLOR", (0,0), (-1,0), white),
("ROWBACKGROUNDS",(0,1),(-1,-1), [white, TABLE_ALT]),
("GRID", (0,0), (-1,-1), 0.5, MED_GRAY),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
]
t.setStyle(TableStyle(ts))
return t
def chapter_header_block(num, title, subtitle=""):
bg_data = [[
Table([[
Paragraph(f"CHAPTER {num}", chap_num),
Paragraph(title, chap_heading),
]] + ([[Paragraph(subtitle, S("cs", fontSize=11, leading=15,
textColor=LIGHT_TEAL, fontName="Helvetica"))]]
if subtitle else []),
colWidths=[W - 2*MARGIN - 2],
)
]]
outer = Table(bg_data, colWidths=[W - 2*MARGIN])
outer.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DEEP_TEAL),
("LEFTPADDING", (0,0), (-1,-1), 16),
("TOPPADDING", (0,0), (-1,-1), 14),
("BOTTOMPADDING",(0,0),(-1,-1), 14),
("RIGHTPADDING",(0,0), (-1,-1), 16),
]))
return outer
# ═══════════════════════════════════════════════════════════════════════════
# PAGE CALLBACKS
# ═══════════════════════════════════════════════════════════════════════════
class NumberedCanvas(canvas.Canvas):
def __init__(self, *args, **kwargs):
canvas.Canvas.__init__(self, *args, **kwargs)
self._saved_page_states = []
def showPage(self):
self._saved_page_states.append(dict(self.__dict__))
self._startPage()
def save(self):
num_pages = len(self._saved_page_states)
for state in self._saved_page_states:
self.__dict__.update(state)
self.draw_page_number(num_pages)
canvas.Canvas.showPage(self)
canvas.Canvas.save(self)
def draw_page_number(self, page_count):
pg = self._pageNumber
if pg <= 2:
return # skip cover and TOC page numbers
self.setFont("Helvetica", 8)
self.setFillColor(MED_GRAY)
self.drawRightString(W - MARGIN, 1.0*cm,
f"Gynaecology Complete Guide | Page {pg - 2}")
self.setStrokeColor(LIGHT_TEAL)
self.setLineWidth(0.5)
self.line(MARGIN, 1.4*cm, W - MARGIN, 1.4*cm)
# header line
self.setStrokeColor(MED_GRAY)
self.setLineWidth(0.3)
self.line(MARGIN, H - 1.5*cm, W - MARGIN, H - 1.5*cm)
self.setFont("Helvetica", 7)
self.setFillColor(MED_GRAY)
self.drawString(MARGIN, H - 1.3*cm,
"Based on Berek & Novak's Gynecology (16th Ed.)")
self.drawRightString(W - MARGIN, H - 1.3*cm, "Orris Medical Reference")
# ═══════════════════════════════════════════════════════════════════════════
# CONTENT
# ═══════════════════════════════════════════════════════════════════════════
story = []
P = lambda t, s=body: Paragraph(t, s)
SP = lambda n=0.3: Spacer(1, n*cm)
# ─── COVER ──────────────────────────────────────────────────────────────────
cover_bg = Table(
[[
Table([[
Paragraph("GYNAECOLOGY", cover_title),
SP(0.3),
Paragraph("Complete Reference Guide", cover_sub),
SP(0.2),
Paragraph("Berek & Novak's Gynecology — Key Concepts", cover_sub),
SP(0.5),
HRFlowable(width="60%", thickness=1, color=LIGHT_TEAL, spaceAfter=10),
SP(0.4),
Paragraph("Reproductive Physiology · Menstrual Disorders · Contraception", cover_auth),
Paragraph("Endometriosis · PCOS · Ovarian Cancer · Cervical Pathology", cover_auth),
Paragraph("Uterine Disorders · STIs · Infertility · Menopause", cover_auth),
SP(1.5),
Paragraph("Based on Berek & Novak's Gynecology, 16th Edition", cover_auth),
SP(0.2),
Paragraph("Compiled for Medical Students, Nurses & Practitioners", cover_auth),
SP(0.3),
Paragraph("May 2026", S("d", fontSize=11, textColor=LIGHT_TEAL,
fontName="Helvetica", alignment=TA_CENTER)),
]], colWidths=[W - 4*cm])
]],
colWidths=[W - 4*cm],
rowHeights=[H - 4*cm]
)
cover_bg.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), DEEP_TEAL),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("LEFTPADDING", (0,0), (-1,-1), 2*cm),
("TOPPADDING", (0,0), (-1,-1), 3*cm),
("BOTTOMPADDING", (0,0), (-1,-1), 2*cm),
]))
story.append(cover_bg)
story.append(PageBreak())
# ─── TABLE OF CONTENTS ──────────────────────────────────────────────────────
story.append(P("<b>TABLE OF CONTENTS</b>",
S("toch", fontSize=20, leading=26, textColor=DEEP_TEAL,
fontName="Helvetica-Bold", alignment=TA_CENTER)))
story.append(SP(0.3))
story.append(hrule(DEEP_TEAL, 2))
story.append(SP(0.2))
toc_items = [
("1", "Initial Assessment, History & Physical Examination", "3"),
("2", "Female Pelvic Anatomy", "8"),
("3", "Reproductive Physiology & Hormones", "14"),
("4", "Menstrual Cycle & Menstrual Disorders", "21"),
("5", "Contraception", "28"),
("6", "Polycystic Ovary Syndrome (PCOS)", "35"),
("7", "Endometriosis", "41"),
("8", "Uterine Fibroids (Leiomyomata)", "47"),
("9", "Sexually Transmitted Infections (STIs)", "53"),
("10", "Cervical Cancer & Cervical Pathology", "59"),
("11", "Ovarian Cancer", "66"),
("12", "Endometrial Cancer", "72"),
("13", "Infertility", "78"),
("14", "Menopause & Hormone Therapy", "85"),
("15", "Pelvic Floor Disorders", "91"),
("16", "Key Drugs in Gynaecology", "96"),
]
for num, title, pg in toc_items:
row_data = [[
Paragraph(f"<b>Ch {num}</b>", S("tcn", fontSize=11, leading=15,
textColor=DEEP_TEAL, fontName="Helvetica-Bold")),
Paragraph(title, toc_entry),
Paragraph(pg, S("tpg", fontSize=11, leading=15,
textColor=MED_GRAY, fontName="Helvetica", alignment=TA_RIGHT)),
]]
t = Table(row_data, colWidths=[1.4*cm, W - 2*MARGIN - 2.8*cm, 1.2*cm])
t.setStyle(TableStyle([
("VALIGN", (0,0),(-1,-1), "MIDDLE"),
("TOPPADDING", (0,0),(-1,-1), 4),
("BOTTOMPADDING", (0,0),(-1,-1), 4),
("LINEBELOW", (0,0),(-1,-1), 0.3, HexColor("#E2E8F0")),
]))
story.append(t)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 1: INITIAL ASSESSMENT
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(1, "Initial Assessment", "History, Communication & Physical Examination"))
story.append(SP(0.4))
story.append(P("""
Gynaecology demands assessment of the <b>whole patient</b> — not just her pelvic organs.
A thorough history, empathic communication, and a systematic physical examination
form the cornerstone of gynaecologic practice.
"""))
story.append(SP(0.2))
story.append(P("1.1 Communication Skills", h1))
story.append(P("""
Good communication rests on four pillars: <b>empathy, attentive listening, expert knowledge,
and rapport</b>. These skills can be learned and refined throughout a clinician's career.
"""))
kp_data = [
"Non-judgmental approach toward sexual practices, gender identity, and orientation.",
"Confidentiality is the foundation of the physician-patient relationship.",
"Incomplete health information produces anxiety, dissatisfaction, and poor treatment adherence.",
"After examination, inform the patient of findings — clothed — before she leaves.",
]
for kp in kp_data:
story.append(P(f"• {kp}", bullet))
story.append(SP(0.3))
story.append(colored_box("KEY CONCEPT: The intimate nature of gynaecologic conditions requires "
"particular sensitivity. Patients must feel safe discussing personal concerns."))
story.append(SP(0.3))
story.append(P("1.2 Taking a Gynaecological History", h1))
story.append(P("""
A structured history includes the following components:
"""))
hist_headers = ["Component", "Key Questions to Ask"]
hist_rows = [
["Chief Complaint", "Nature, onset, duration, severity, alleviating/aggravating factors"],
["Menstrual History", "LMP, cycle length (normal 21-35 days), duration, flow, dysmenorrhoea"],
["Obstetric History", "Gravida, para, abortions, ectopic pregnancies, birth complications"],
["Sexual History", "Partners, contraception use, STI history, dyspareunia"],
["Contraceptive History", "Current method, duration, side effects, compliance"],
["Past Gynaec History", "Previous pelvic infections, surgeries, smear results"],
["Family History", "Ovarian/breast/colorectal/endometrial cancer in first-degree relatives"],
["Social History", "Smoking, alcohol, occupation, domestic situation, stress"],
["Medications", "Hormonal treatments, anticoagulants, antiepileptics"],
["Systemic Review", "Urinary symptoms, bowel habits, weight change, hirsutism, galactorrhoea"],
]
story.append(data_table(hist_headers, hist_rows, [4*cm, W - 2*MARGIN - 6*cm]))
story.append(SP(0.4))
story.append(P("1.3 Physical Examination", h1))
story.append(P("""
A complete gynaecological examination includes <b>general, abdominal, and pelvic examination</b>.
Always ensure a chaperone is present, explain each step to the patient, and obtain consent.
"""))
story.append(P("Pelvic Examination Steps:", h3))
exam_steps = [
("Inspection", "External genitalia — vulva, perineum, anus for lesions, discharge, atrophy"),
("Speculum Examination", "Visualise vaginal walls, cervix; collect smear (Pap) and swabs"),
("Bimanual Examination", "Uterine size, position, mobility, adnexal masses, cervical excitation"),
("Rectovaginal Exam", "Posterior cul-de-sac nodularity (endometriosis), rectal involvement"),
]
for step, detail in exam_steps:
story.append(P(f"<b>{step}:</b> {detail}", bullet))
story.append(SP(0.3))
story.append(colored_box("REMEMBER: Cervical excitation (chandelier sign) on bimanual exam "
"suggests pelvic inflammatory disease (PID) until proven otherwise.",
bg=HexColor("#FFF7ED"), txt_color=HexColor("#C2410C")))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 2: ANATOMY
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(2, "Female Pelvic Anatomy", "Structures, Relations & Clinical Relevance"))
story.append(SP(0.4))
story.append(P("2.1 Vulva and Perineum", h1))
story.append(P("""
The <b>vulva</b> includes the mons pubis, labia majora, labia minora, clitoris, vestibule,
vestibular bulbs, and Bartholin's glands. The <b>perineum</b> is bounded by the pubic symphysis
anteriorly, coccyx posteriorly, and ischial tuberosities laterally.
"""))
story.append(P("2.2 Vagina", h1))
story.append(P("""
The vagina is a <b>fibromuscular tube</b> 7-10 cm long connecting vulva to uterus.
Its anterior wall is related to the bladder and urethra; the posterior wall is related to
the rectum. The vaginal fornices (anterior, posterior, lateral) surround the cervix.
The posterior fornix is the deepest and clinically used for culdocentesis.
"""))
story.append(P("2.3 Uterus", h1))
anat_headers = ["Part", "Description", "Clinical Relevance"]
anat_rows = [
["Fundus", "Dome-shaped top above tubal ostia", "Fundal height assessment in pregnancy"],
["Body (Corpus)", "Main muscular part; cavity lined by endometrium", "Site of fibroids, endometrial cancer"],
["Isthmus", "Junction of body and cervix; 0.5 cm", "Stretched in pregnancy; caesarean incision site"],
["Cervix", "Lower cylindrical part; internal + external os", "Smear sampling; cervical cancer site"],
["Endometrium", "Inner functional and basal layers", "Shed in menstruation; implantation site"],
["Myometrium", "Three smooth muscle layers", "Fibroids; uterine contractions"],
["Perimetrium", "Outer peritoneal covering", "Involved in endometriosis"],
]
story.append(data_table(anat_headers, anat_rows, [2.5*cm, 5.5*cm, W-2*MARGIN-10*cm]))
story.append(SP(0.3))
story.append(P("2.4 Fallopian Tubes", h1))
story.append(P("""
Each tube is 10-12 cm long with four parts: <b>interstitial (intramural), isthmus, ampulla,
and infundibulum</b> (with fimbriae). The <b>ampulla</b> is the most common site of fertilisation
and ectopic pregnancy. Cilia and peristalsis propel the ovum toward the uterus.
"""))
story.append(P("2.5 Ovaries", h1))
story.append(P("""
The ovaries are <b>almond-shaped, 3×2×1 cm</b> in reproductive age women.
They produce oocytes and hormones (oestrogen, progesterone, androgens, inhibin).
Blood supply: ovarian artery (from aorta) + ovarian branch of uterine artery.
Lymphatics drain to <b>para-aortic nodes</b> (clinically important in ovarian cancer staging).
"""))
story.append(P("2.6 Pelvic Support Structures", h1))
support_data = [
("Cardinal (Mackenrodt's) Ligaments", "Main support; from cervix to pelvic sidewall; most important for uterine support"),
("Uterosacral Ligaments", "Cervix to sacrum; maintain uterine position; contain nerve fibres"),
("Round Ligaments", "Fundus to labia majora via inguinal canal; hold uterus in anteversion"),
("Broad Ligament", "Double peritoneal fold; contains tubes, ovarian ligament, uterine vessels"),
("Pubocervical Fascia", "Supports bladder neck and anterior vaginal wall"),
("Rectovaginal Fascia", "Posterior vaginal wall support"),
("Levator Ani Muscle", "Primary pelvic floor muscle; pubococcygeus + iliococcygeus + puborectalis"),
]
for name, desc in support_data:
story.append(P(f"<b>{name}:</b> {desc}", bullet))
story.append(SP(0.3))
story.append(colored_box("CLINICAL NOTE: Damage to the cardinal and uterosacral ligaments during childbirth "
"leads to uterine prolapse. The levator ani is the most important muscle of pelvic floor support."))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 3: REPRODUCTIVE PHYSIOLOGY
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(3, "Reproductive Physiology", "Hormones, Feedback & the Menstrual Cycle"))
story.append(SP(0.4))
story.append(P("3.1 Hypothalamic-Pituitary-Ovarian (HPO) Axis", h1))
story.append(P("""
The HPO axis controls female reproduction through a <b>pulsatile hormonal cascade</b>:
"""))
axis_steps = [
"Hypothalamus secretes <b>GnRH</b> (Gonadotropin-Releasing Hormone) in pulses every 60-90 minutes.",
"GnRH stimulates the anterior pituitary to release <b>FSH</b> (Follicle-Stimulating Hormone) and <b>LH</b> (Luteinising Hormone).",
"FSH promotes follicular development in the ovary; LH triggers ovulation and luteinisation.",
"Ovarian oestrogen exerts <b>negative feedback</b> on the pituitary (early cycle) and <b>positive feedback</b> (LH surge near ovulation).",
"After ovulation, progesterone from the corpus luteum exerts negative feedback on both hypothalamus and pituitary.",
]
for step in axis_steps:
story.append(P(f"• {step}", bullet))
story.append(SP(0.3))
story.append(P("3.2 Key Reproductive Hormones", h1))
hormone_headers = ["Hormone", "Source", "Main Actions", "Normal Levels"]
hormone_rows = [
["FSH", "Anterior pituitary", "Follicular recruitment and maturation; stimulates aromatase", "Follicular: 3-10 IU/L"],
["LH", "Anterior pituitary", "Triggers ovulation; stimulates androgen production (theca cells)", "Follicular: 2-15 IU/L; Surge: >20 IU/L"],
["Oestradiol (E2)", "Granulosa cells", "Endometrial proliferation; -ve/+ve HPO feedback; vaginal trophism", "Follicular: 150-400 pmol/L"],
["Progesterone", "Corpus luteum", "Endometrial secretory change; thermogenic effect; cervical mucus thickening", "Luteal: >30 nmol/L (confirms ovulation)"],
["Inhibin B", "Granulosa cells", "Selectively suppresses FSH", "Early follicular phase"],
["AMH", "Granulosa cells (small follicles)", "Ovarian reserve marker; inhibits follicular recruitment", "Reproductive age: 1-35 pmol/L"],
["Androgens (T, DHEAS)", "Theca cells + adrenal", "Libido; precursors for oestrogen synthesis", "T < 2.5 nmol/L"],
]
story.append(data_table(hormone_headers, hormone_rows, [2.5*cm, 3*cm, 6*cm, 4*cm]))
story.append(SP(0.3))
story.append(P("3.3 Follicular Development", h1))
story.append(P("""
<b>Primordial follicles</b> (resting pool) undergo recruitment under FSH. The dominant follicle
(Graafian follicle, ~20 mm) is selected by day 7. It secretes rising oestradiol that
triggers the <b>LH surge</b> approximately 36 hours before ovulation. After ovulation, the
granulosa and theca cells luteinise to form the <b>corpus luteum</b>, which produces
progesterone for 14 days. If no implantation occurs, the corpus luteum regresses
(luteolysis) and menstruation follows.
"""))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 4: MENSTRUAL DISORDERS
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(4, "Menstrual Cycle & Menstrual Disorders",
"AUB, Dysmenorrhoea, Amenorrhoea & PALM-COEIN"))
story.append(SP(0.4))
story.append(P("4.1 Normal Menstruation — Parameters", h1))
normal_men = [
("Cycle length", "21–35 days"),
("Duration of flow", "3–7 days"),
("Blood loss", "20–80 mL per cycle (median 35 mL)"),
("Menarche", "10–16 years (mean 12.5 years)"),
("Menopause", "45–55 years (mean 51 years)"),
]
for param, value in normal_men:
story.append(P(f"<b>{param}:</b> {value}", bullet))
story.append(SP(0.3))
story.append(P("4.2 Abnormal Uterine Bleeding (AUB) — PALM-COEIN Classification", h1))
story.append(P("""
The <b>FIGO PALM-COEIN</b> system classifies AUB causes into structural (PALM) and
non-structural (COEIN) categories:
"""))
palm_headers = ["Acronym", "Cause", "Key Features"]
palm_rows = [
["P – Polyp", "Endometrial/cervical polyps", "Intermenstrual bleeding; often postcoital"],
["A – Adenomyosis", "Endometrial glands in myometrium", "Dysmenorrhoea; bulky tender uterus; heavy regular periods"],
["L – Leiomyoma", "Uterine fibroids", "Heavy periods; bulk symptoms; submucous type causes AUB"],
["M – Malignancy", "Endometrial/cervical/uterine sarcoma", "PMB; irregular bleeding; must exclude in all ages"],
["C – Coagulopathy", "von Willebrand, platelet disorders", "Onset at menarche; positive bleeding history screen"],
["O – Ovulatory", "Anovulatory cycles (PCOS, thyroid)", "Irregular, heavy or prolonged bleeding"],
["E – Endometrial", "Primary endometrial disorder", "Regular cycle with HMB; normal structural workup"],
["I – Iatrogenic", "IUD, hormones, anticoagulants", "History of hormone/drug use"],
["N – Not yet classified", "Rare/unclassified causes", "Diagnosis of exclusion"],
]
story.append(data_table(palm_headers, palm_rows, [2.5*cm, 4.5*cm, W-2*MARGIN-9*cm]))
story.append(SP(0.3))
story.append(P("4.3 Amenorrhoea", h1))
story.append(P("""
<b>Primary amenorrhoea:</b> No menses by age 15 (with secondary sex characteristics) or 13 (without).
<b>Secondary amenorrhoea:</b> Cessation of menses for ≥3 months in a previously menstruating woman.
"""))
story.append(P("Causes by Level:", h3))
am_causes = [
("Hypothalamic", "Functional hypothalamic amenorrhoea (FHA): weight loss, exercise, stress; Kallmann syndrome"),
("Pituitary", "Hyperprolactinaemia (prolactinoma); Sheehan's syndrome; empty sella"),
("Ovarian", "Primary ovarian insufficiency (POI); Turner syndrome (45,X); PCOS"),
("Uterine/Outflow", "Asherman's syndrome; imperforate hymen; transverse vaginal septum; cervical stenosis"),
("Systemic", "Thyroid disease; adrenal disorders; chronic illness; medications"),
]
for level, cause in am_causes:
story.append(P(f"<b>{level}:</b> {cause}", bullet))
story.append(SP(0.2))
story.append(P("4.4 Dysmenorrhoea", h1))
story.append(P("""
<b>Primary dysmenorrhoea:</b> Painful periods without pelvic pathology. Caused by excess
prostaglandin (PGF2α) production leading to uterine contractions and ischaemia.
Treated with NSAIDs (first-line) and combined oral contraceptives.
<br/><br/>
<b>Secondary dysmenorrhoea:</b> Caused by pelvic pathology — endometriosis (most common),
adenomyosis, fibroids, PID. Onset usually after age 20. Requires investigation and
treatment of the underlying condition.
"""))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 5: CONTRACEPTION
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(5, "Contraception",
"Methods, Efficacy, Mechanisms & Counselling"))
story.append(SP(0.4))
story.append(P("""
Contraceptive counselling should be individualised, considering efficacy, side effects,
reversibility, patient preference, and medical eligibility criteria (WHO MEC).
"""))
story.append(P("5.1 Efficacy — Pearl Index", h1))
story.append(P("""
The <b>Pearl Index</b> = number of pregnancies per 100 woman-years of use.
<b>Perfect use</b> assumes consistent, correct use; <b>typical use</b> accounts for real-world compliance.
"""))
contra_headers = ["Method", "Typical Use Failure (%/yr)", "Perfect Use (%/yr)", "Duration"]
contra_rows = [
["No contraception", "85", "85", "—"],
["Condom (male)", "13", "2", "Each act"],
["Combined Oral Pill (COC)", "7", "0.3", "Daily"],
["Progestogen-only Pill (POP)", "7", "0.3", "Daily (3-hourly window)"],
["Copper IUD (Cu-IUD)", "0.8", "0.6", "5–10 years"],
["Levonorgestrel IUS (Mirena)", "0.1", "0.1", "5–8 years"],
["Implant (Nexplanon)", "0.05", "0.05", "3 years"],
["DMPA Injection", "4", "0.2", "12 weeks"],
["Female sterilisation", "0.5", "0.5", "Permanent"],
["Emergency Pill (LNG)", "—", "~1–2 per act", "Within 72 h"],
]
story.append(data_table(contra_headers, contra_rows,
[5*cm, 3.5*cm, 3.5*cm, W-2*MARGIN-14*cm]))
story.append(SP(0.3))
story.append(P("5.2 Combined Oral Contraceptives (COC)", h1))
story.append(P("""
COCs contain <b>synthetic oestrogen (ethinyl oestradiol)</b> and a progestogen.
They work by: (1) inhibiting ovulation via HPO axis suppression, (2) thickening
cervical mucus, and (3) thinning the endometrium.
"""))
story.append(P("<b>Benefits:</b> Reduced dysmenorrhoea, lighter periods, acne improvement, "
"protection against ovarian and endometrial cancer.", bullet))
story.append(P("<b>Contraindications (UKMEC 4):</b> Current VTE/DVT, migraine with aura, "
"current breast cancer, cardiovascular disease, age ≥35 + smoking ≥15/day, "
"hypertension (>160/100), post-partum breastfeeding <6 weeks.", bullet))
story.append(SP(0.2))
story.append(P("5.3 Intrauterine Devices (IUDs)", h1))
story.append(P("""
<b>Copper IUD:</b> Non-hormonal; copper ions are spermicidal and prevent fertilisation;
also prevents implantation. Suitable for emergency contraception up to 5 days post-coitus.
<br/><br/>
<b>LNG-IUS (Mirena):</b> Releases 20 mcg levonorgestrel/day locally; prevents implantation,
thickens cervical mucus, thins endometrium. Treats heavy menstrual bleeding (HMB);
first-line treatment for HMB in women desiring contraception.
"""))
story.append(SP(0.2))
story.append(P("5.4 Emergency Contraception", h1))
ec_options = [
("Levonorgestrel 1.5 mg", "Within 72 hours (may be used up to 120 h); inhibits/delays ovulation"),
("Ulipristal acetate (UPA, ellaOne)", "Within 120 hours; selective progesterone receptor modulator; slightly more effective than LNG"),
("Copper IUD", "Within 5 days; most effective EC (>99%); also provides ongoing contraception"),
]
for method, detail in ec_options:
story.append(P(f"<b>{method}:</b> {detail}", bullet))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 6: PCOS
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(6, "Polycystic Ovary Syndrome (PCOS)",
"Diagnosis, Pathophysiology & Management"))
story.append(SP(0.4))
story.append(P("""
PCOS is the most common endocrine disorder in women of reproductive age,
affecting <b>5–15%</b> of women. It is a leading cause of anovulatory infertility.
"""))
story.append(P("6.1 Rotterdam Diagnostic Criteria (2003)", h1))
story.append(P("Diagnosis requires <b>2 of 3</b> criteria:"))
story.append(SP(0.1))
rc_criteria = [
"Oligo-ovulation or anovulation (irregular cycles >35 days or <8 cycles/year)",
"Clinical or biochemical hyperandrogenism (hirsutism, acne, alopecia; elevated testosterone or DHEAS)",
"Polycystic ovarian morphology on USS (≥20 follicles 2–9 mm in one ovary OR ovarian volume >10 mL)",
]
for c in rc_criteria:
story.append(P(f"✔ {c}", bullet))
story.append(SP(0.2))
story.append(colored_box("IMPORTANT: Other causes of hyperandrogenism must be excluded — "
"congenital adrenal hyperplasia (CAH), Cushing's syndrome, androgen-secreting tumour, thyroid disease."))
story.append(SP(0.2))
story.append(P("6.2 Pathophysiology", h1))
story.append(P("""
PCOS involves a complex interplay of <b>insulin resistance, gonadotrophin dysregulation,
and androgen excess</b>:
"""))
patho = [
"Insulin resistance → hyperinsulinaemia → increased LH-driven androgen production in theca cells.",
"Elevated LH:FSH ratio (often >2:1) → excess androgen, impaired follicular maturation.",
"Androgen excess → conversion to oestrone in adipose tissue → persistent oestrogen without cyclic progesterone → anovulation.",
"Elevated AMH levels reflect increased antral follicle count.",
]
for p in patho:
story.append(P(f"• {p}", bullet))
story.append(SP(0.2))
story.append(P("6.3 Clinical Features", h1))
pcos_features = [
("Menstrual", "Oligomenorrhoea or amenorrhoea; rarely polymenorrhoea"),
("Androgenic", "Hirsutism (Ferriman-Gallwey score ≥8), acne, androgenic alopecia"),
("Metabolic", "Obesity (BMI >25 in 50–60%); insulin resistance; type 2 diabetes risk × 7"),
("Reproductive", "Anovulatory infertility; miscarriage risk; ovarian hyperstimulation risk"),
("Long-term", "Endometrial hyperplasia/cancer (unopposed oestrogen); CVD risk; OSA"),
]
for domain, feature in pcos_features:
story.append(P(f"<b>{domain}:</b> {feature}", bullet))
story.append(SP(0.2))
story.append(P("6.4 Management", h1))
story.append(P("<b>Lifestyle:</b> Weight loss of 5–10% restores ovulation in 55% of obese women; first-line for all women.", bullet))
story.append(P("<b>Menstrual regulation:</b> COC (most common); cyclical progestogen (for endometrial protection).", bullet))
story.append(P("<b>Hyperandrogenism:</b> COC + anti-androgens (spironolactone, cyproterone acetate); topical eflornithine for hirsutism.", bullet))
story.append(P("<b>Ovulation induction:</b> Letrozole (1st line); clomifene citrate; metformin (adjunct); gonadotrophins; laparoscopic ovarian drilling (LOD).", bullet))
story.append(P("<b>Metabolic:</b> Metformin; weight loss; screen for T2DM, dyslipidaemia.", bullet))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 7: ENDOMETRIOSIS
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(7, "Endometriosis",
"Pathology, Staging & Treatment"))
story.append(SP(0.4))
story.append(P("""
Endometriosis is defined as the presence of <b>endometrial glands and stroma outside the
uterine cavity</b>. It affects <b>10–15%</b> of women of reproductive age and up to 50% of
those with infertility. The most common sites are the ovaries, pelvic peritoneum,
uterosacral ligaments, and rectovaginal septum.
"""))
story.append(P("7.1 Pathogenesis Theories", h1))
theories = [
("Retrograde Menstruation (Sampson)", "Most accepted; endometrial cells pass through tubes, implant on peritoneum"),
("Coelomic Metaplasia", "Peritoneal cells undergo metaplastic transformation"),
("Lymphovascular Spread", "Explains extra-pelvic endometriosis (lung, brain)"),
("Stem Cell Theory", "Bone marrow-derived stem cells differentiate into endometrial tissue"),
]
for theory, detail in theories:
story.append(P(f"<b>{theory}:</b> {detail}", bullet))
story.append(SP(0.2))
story.append(P("7.2 Classification — rASRM Staging (I–IV)", h1))
endo_stages = [
("Stage I (Minimal)", "Superficial implants only; no significant adhesions; score 1–5"),
("Stage II (Mild)", "Small deep implants; peritubal/periovarian adhesions; score 6–15"),
("Stage III (Moderate)", "Deep implants; endometrioma; moderate adhesions; score 16–40"),
("Stage IV (Severe)", "Large endometriomas; dense pelvic adhesions; obliterated pouch of Douglas; score >40"),
]
for stage, desc in endo_stages:
story.append(P(f"<b>{stage}:</b> {desc}", bullet))
story.append(P("""<i>Note: Staging correlates poorly with symptoms. Stage I/II can cause severe pain;
Stage IV may be asymptomatic.</i>""", note))
story.append(SP(0.2))
story.append(P("7.3 Clinical Features", h1))
story.append(P("The <b>'4 Ds'</b> of endometriosis:", h3))
four_ds = [
"Dysmenorrhoea (often worsening, progressive)",
"Dyspareunia (deep; worse premenstrually)",
"Dyschezia (pain on defaecation; suggests rectovaginal involvement)",
"Dysfunctional uterine bleeding (irregular, heavy)",
]
for d in four_ds:
story.append(P(f"• {d}", bullet))
story.append(P("Also: subfertility, chronic pelvic pain, cyclical haematuria/haemoptysis (if bladder/lung involved).", body))
story.append(SP(0.2))
story.append(P("7.4 Diagnosis & Management", h1))
story.append(P("""
<b>Gold standard diagnosis:</b> Laparoscopy with histological confirmation.
Transvaginal USS (TVS) can detect ovarian endometriomas (ground-glass appearance).
MRI is useful for deep infiltrating endometriosis (DIE). CA-125 is elevated but non-specific.
"""))
endo_rx = [
("Medical (pain)", "NSAIDs; COC (continuous/tricycling); progestogens; GnRH agonists + add-back HRT; LNG-IUS"),
("Surgical", "Laparoscopic ablation or excision of implants; cystectomy for endometriomas; hysterectomy ± BSO for severe cases"),
("Fertility", "IVF for associated infertility; surgical treatment does not clearly improve IVF outcomes"),
]
story.append(data_table(["Approach", "Options"],
[[a, b] for a, b in endo_rx], [3*cm, W-2*MARGIN-5*cm]))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 8: UTERINE FIBROIDS
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(8, "Uterine Fibroids (Leiomyomata)",
"Classification, Complications & Treatment"))
story.append(SP(0.4))
story.append(P("""
Uterine leiomyomata (fibroids) are <b>benign monoclonal tumours</b> of smooth muscle cells.
They are the most common benign gynaecological tumours, present in <b>20–50%</b> of women
of reproductive age. More common and more severe in Afro-Caribbean women.
"""))
story.append(P("8.1 FIGO Leiomyoma Classification (Types 0–8)", h1))
fibroid_class = [
("Type 0", "Pedunculated intracavitary — entirely within endometrial cavity"),
("Type 1", "Submucosal — <50% intramural"),
("Type 2", "Submucosal — ≥50% intramural"),
("Type 3", "Intramural — contacts endometrium"),
("Type 4", "Intramural — entirely within myometrium"),
("Type 5", "Subserosal — ≥50% intramural"),
("Type 6", "Subserosal — <50% intramural"),
("Type 7", "Subserosal pedunculated"),
("Type 8", "Other — cervical, parasitic"),
]
story.append(data_table(["Type", "Description"],
[[t, d] for t, d in fibroid_class], [2*cm, W-2*MARGIN-4*cm]))
story.append(SP(0.3))
story.append(P("8.2 Symptoms & Complications", h1))
fibroid_sx = [
"Heavy menstrual bleeding (HMB) — especially submucous types",
"Bulk symptoms — pelvic pressure, urinary frequency, constipation, back pain",
"Dysmenorrhoea, intermenstrual bleeding",
"Subfertility — submucous fibroids distort uterine cavity",
"Obstetric complications — malpresentation, placenta praevia, PPH, Caesarean section",
"Red degeneration — acute pain in pregnancy (necrosis from rapid growth)",
"Torsion of pedunculated fibroid — acute abdominal pain",
]
for sx in fibroid_sx:
story.append(P(f"• {sx}", bullet))
story.append(SP(0.2))
story.append(P("8.3 Management", h1))
fibroid_rx = [
("Conservative", "Observation; treat only if symptomatic; pre-menopausal patients: fibroids regress after menopause"),
("Medical", "LNG-IUS (HMB); GnRH agonists (pre-op shrinkage); ulipristal acetate (5 mg intermittent course); tranexamic acid/NSAIDs (HMB)"),
("Surgical", "Myomectomy (fertility-preserving); hysterectomy (definitive); laparoscopic vs open depending on size/number"),
("Radiological", "Uterine artery embolisation (UAE) — preserves uterus; MRI-guided focused ultrasound surgery (FUS)"),
]
story.append(data_table(["Approach", "Details"],
[[a, b] for a, b in fibroid_rx], [3*cm, W-2*MARGIN-5*cm]))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 9: STIs
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(9, "Sexually Transmitted Infections (STIs)",
"PID, Chlamydia, Gonorrhoea, Herpes & Syphilis"))
story.append(SP(0.4))
story.append(P("9.1 Pelvic Inflammatory Disease (PID)", h1))
story.append(P("""
PID is infection of the upper female genital tract — uterus, fallopian tubes, ovaries,
and pelvic peritoneum. Most cases are caused by <b>Chlamydia trachomatis</b> and/or
<b>Neisseria gonorrhoeae</b>, though polymicrobial infection is common.
"""))
story.append(P("Diagnostic Criteria (minimum):", h3))
pid_diag = [
"Bilateral lower abdominal/pelvic tenderness",
"Cervical motion tenderness (CMT / chandelier sign)",
"Uterine tenderness or adnexal tenderness",
]
for d in pid_diag:
story.append(P(f"• {d}", bullet))
story.append(P("Additional features: fever >38.3°C, elevated CRP/WBC, mucopurulent cervical discharge, "
"laparoscopic evidence of inflammation.", body))
story.append(SP(0.15))
story.append(P("<b>Complications of untreated PID:</b> Tubo-ovarian abscess (TOA); Fitz-Hugh-Curtis syndrome "
"(perihepatitis — right upper quadrant pain); ectopic pregnancy risk ×6–10; tubal infertility; "
"chronic pelvic pain.", bullet))
story.append(SP(0.2))
story.append(P("PID Treatment (BASHH/RCOG):", h3))
pid_rx = [
"Outpatient: Ceftriaxone 500 mg IM stat + doxycycline 100 mg BD 14 days + metronidazole 400 mg BD 14 days",
"Inpatient (TOA, severe, pregnant, surgical emergency): IV cefoxitin + doxycycline; or IV clindamycin + gentamicin",
"Partner notification and treatment is mandatory",
]
for r in pid_rx:
story.append(P(f"• {r}", bullet))
story.append(SP(0.3))
story.append(P("9.2 Common STIs — Summary", h1))
sti_headers = ["STI", "Organism", "Key Features", "Treatment"]
sti_rows = [
["Chlamydia", "C. trachomatis", "Often asymptomatic; NAAT swab; commonest STI in UK", "Doxycycline 100mg BD 7d"],
["Gonorrhoea", "N. gonorrhoeae", "Purulent discharge; NAAT + culture; increasing resistance", "Ceftriaxone 1g IM"],
["Syphilis", "T. pallidum", "Primary (painless chancre); secondary (rash on palms/soles); RPR/TPHA", "Benzathine penicillin G"],
["Genital Herpes", "HSV-1/2", "Painful vesicles/ulcers; recurrent; PCR swab", "Aciclovir 200–400mg TDS 5d"],
["Trichomonas", "T. vaginalis", "Yellow-green frothy discharge; strawberry cervix", "Metronidazole 2g stat"],
["Bacterial Vaginosis", "Gardnerella + anaerobes", "Fishy odour; thin grey discharge; not true STI; Amsel criteria", "Metronidazole 400mg BD 5-7d"],
["Candida", "C. albicans", "Thick white discharge; itching; pseudohyphae on microscopy", "Clotrimazole pessary or fluconazole 150mg"],
]
story.append(data_table(sti_headers, sti_rows, [2.5*cm, 3*cm, 5.5*cm, W-2*MARGIN-13*cm]))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 10: CERVICAL CANCER
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(10, "Cervical Cancer & Cervical Pathology",
"HPV, CIN, Screening & Management"))
story.append(SP(0.4))
story.append(P("""
Cervical cancer is the <b>4th most common cancer in women worldwide</b>.
Almost all cases (99.7%) are caused by persistent infection with high-risk
<b>Human Papillomavirus (HPV)</b>. The introduction of HPV vaccination and organised
cervical screening programmes has dramatically reduced mortality.
"""))
story.append(P("10.1 HPV — Oncogenic Subtypes", h1))
hpv_data = [
("High-risk (HR-HPV)", "Types 16 & 18 — cause 70% of cervical cancers; also 31, 33, 45, 52, 58"),
("Low-risk", "Types 6 & 11 — cause 90% of genital warts (condylomata acuminata)"),
]
for cat, detail in hpv_data:
story.append(P(f"<b>{cat}:</b> {detail}", bullet))
story.append(P("""
<b>HPV vaccination (Gardasil 9 — 9-valent):</b> Covers HPV 6, 11, 16, 18, 31, 33, 45, 52, 58.
Given to girls and boys aged 11–13 years. Highly effective when given before sexual debut.
"""))
story.append(SP(0.2))
story.append(P("10.2 Cervical Intraepithelial Neoplasia (CIN)", h1))
cin_data = [
("CIN 1", "Low-grade; mild dysplasia involving lower 1/3 of epithelium; usually regresses spontaneously"),
("CIN 2", "Moderate dysplasia; middle 2/3 of epithelium; 40–50% regress; treat if persistent >2 years"),
("CIN 3", "High-grade; full thickness or near-full thickness; CGIN (glandular) also high-risk; treat all"),
]
story.append(data_table(["Grade", "Description"], [[g, d] for g, d in cin_data], [2*cm, W-2*MARGIN-4*cm]))
story.append(SP(0.2))
story.append(P("10.3 UK Cervical Screening Programme", h1))
screen_data = [
("Age 25–49", "3-yearly smear (cervical sample for HPV primary screening + cytology if HPV+)"),
("Age 50–64", "5-yearly smear"),
("Age ≥65", "Only if recent abnormal result"),
("Abnormal", "Colposcopy → biopsy → CIN grade → LLETZ/laser/cone biopsy if CIN2/3"),
]
for age, action in screen_data:
story.append(P(f"<b>{age}:</b> {action}", bullet))
story.append(SP(0.2))
story.append(P("10.4 FIGO Staging of Cervical Cancer", h1))
figo_cc = [
("Stage I", "Confined to cervix"),
("Stage IA", "Microscopic — IA1: ≤3 mm invasion; IA2: 3–5 mm"),
("Stage IB", "Clinically visible — IB1: <2cm; IB2: 2–4cm; IB3: ≥4cm"),
("Stage II", "Beyond cervix but not pelvic wall/lower 1/3 vagina"),
("Stage III", "Lower 1/3 vagina or pelvic wall; hydronephrosis"),
("Stage IV", "Bladder/rectal mucosa (IVA) or distant metastasis (IVB)"),
]
story.append(data_table(["Stage", "Description"], [[s, d] for s, d in figo_cc], [2.5*cm, W-2*MARGIN-4.5*cm]))
story.append(SP(0.2))
story.append(colored_box("TREATMENT OVERVIEW: Stage IA1 — cone biopsy/LLETZ; IA2–IB1 — radical hysterectomy + pelvic LN dissection OR CTRT; "
"IB2–IVA — concurrent chemoradiotherapy (cisplatin-based); IVB — systemic chemotherapy ± pembrolizumab."))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 11: OVARIAN CANCER
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(11, "Ovarian Cancer",
"Types, Staging, Diagnosis & Management"))
story.append(SP(0.4))
story.append(P("""
Ovarian cancer is the <b>5th most common cancer in women</b> and the leading cause of
gynaecological cancer death (due to late presentation). The <b>5-year survival for Stage III/IV
is <30%</b>, compared to >90% for Stage I.
"""))
story.append(P("11.1 Classification", h1))
oc_types = [
("Epithelial (90%)", "Serous (most common), mucinous, endometrioid, clear cell, transitional; arise from surface epithelium"),
("Germ Cell Tumours", "Dysgerminoma, teratoma, yolk sac tumour; young women; often unilateral; chemosensitive"),
("Sex Cord-Stromal", "Granulosa cell (oestrogen-producing → precocious puberty/AUB); Sertoli-Leydig (androgen-producing → virilisation)"),
("Metastatic", "Krukenberg tumour: gastric cancer metastasis to ovary; bilateral; signet ring cells"),
]
for oc_type, detail in oc_types:
story.append(P(f"<b>{oc_type}:</b> {detail}", bullet))
story.append(SP(0.2))
story.append(P("11.2 Risk Factors & Genetics", h1))
oc_risk = [
("BRCA1 mutation", "Lifetime ovarian cancer risk 40–46%; also ↑ breast cancer risk"),
("BRCA2 mutation", "Lifetime ovarian cancer risk 10–27%"),
("Lynch syndrome", "MLH1/MSH2 mutations; risk of ovarian, endometrial, colorectal cancer"),
("Hormonal", "Nulliparity, early menarche, late menopause (↑ ovulatory cycles)"),
("Protective", "COC use (50% risk reduction); multiparity; breastfeeding; bilateral salpingo-oophorectomy"),
]
story.append(data_table(["Factor", "Detail"], [[f, d] for f, d in oc_risk], [4*cm, W-2*MARGIN-6*cm]))
story.append(SP(0.2))
story.append(P("11.3 Symptoms (often late and non-specific)", h1))
oc_sx = [
"Persistent bloating / abdominal distension",
"Pelvic or abdominal pain",
"Difficulty eating / early satiety",
"Urinary urgency or frequency",
"Change in bowel habit (new onset in women >50)",
]
for sx in oc_sx:
story.append(P(f"• {sx}", bullet))
story.append(colored_box("NICE Guideline: If symptoms occur >12 times/month — CA-125. If ≥35 IU/mL, transvaginal USS urgently."))
story.append(SP(0.2))
story.append(P("11.4 Staging (FIGO) & Treatment", h1))
oc_stage = [
("Stage I", "Confined to ovaries", "Surgery: TAH + BSO + omentectomy + pelvic/para-aortic LN dissection"),
("Stage II", "Pelvic extension", "Surgery + adjuvant carboplatin/paclitaxel chemotherapy"),
("Stage III", "Peritoneal spread or retroperitoneal LN", "Debulking surgery + platinum-based chemotherapy"),
("Stage IV", "Distant metastases", "Neo-adjuvant chemo → interval debulking → chemo; or palliative"),
]
story.append(data_table(["Stage", "Extent", "Treatment"], [[s, e, t] for s, e, t in oc_stage],
[2*cm, 5*cm, W-2*MARGIN-9*cm]))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 12: ENDOMETRIAL CANCER
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(12, "Endometrial Cancer",
"Types, Risk Factors, Staging & Treatment"))
story.append(SP(0.4))
story.append(P("""
Endometrial cancer is the <b>most common gynaecological malignancy in developed countries</b>.
The vast majority present with <b>postmenopausal bleeding (PMB)</b>, facilitating early diagnosis.
Overall 5-year survival is ~75–80% due to early presentation.
"""))
story.append(P("12.1 Type I vs Type II Endometrial Cancer", h1))
ec_types_headers = ["Feature", "Type I (Oestrogen-dependent)", "Type II (Oestrogen-independent)"]
ec_types_rows = [
["Proportion", "80–85%", "15–20%"],
["Histology", "Endometrioid adenocarcinoma", "Serous papillary; clear cell; carcinosarcoma"],
["Grade", "Low-grade (G1/G2)", "High-grade (G3)"],
["Precursor", "Endometrial hyperplasia (with atypia)", "p53 mutation; atrophic endometrium"],
["Risk factors", "Obesity, nulliparity, late menopause, unopposed oestrogen, PCOS", "Advanced age; Lynch syndrome; BRCA1/2"],
["Prognosis", "Good", "Poor"],
]
story.append(data_table(ec_types_headers, ec_types_rows, [3.5*cm, 5.5*cm, W-2*MARGIN-11*cm]))
story.append(SP(0.2))
story.append(P("12.2 Endometrial Hyperplasia", h1))
story.append(P("""
<b>Endometrial hyperplasia without atypia:</b> Low risk of progression to cancer (1–3%);
treat with progestogen (oral or LNG-IUS); surveillance endometrial biopsy.
<br/><br/>
<b>Endometrial hyperplasia with atypia (EHA):</b> High risk of progression (20–30%);
concurrent endometrial cancer in up to 50% of hysterectomy specimens;
<b>total hysterectomy recommended</b>. If surgery not possible: high-dose progestogen + close surveillance.
"""))
story.append(SP(0.2))
story.append(P("12.3 FIGO Staging", h1))
ec_stage_rows = [
("IA", "Tumour confined to endometrium or <50% myometrial invasion"),
("IB", "≥50% myometrial invasion"),
("II", "Cervical stroma invasion"),
("IIIA", "Uterine serosa or adnexa"),
("IIIB", "Vaginal/parametrial involvement"),
("IIIC1", "Pelvic lymph node involvement"),
("IIIC2", "Para-aortic lymph node involvement"),
("IVA", "Bladder/bowel mucosa"),
("IVB", "Distant metastases"),
]
story.append(data_table(["Stage", "Description"], [[s, d] for s, d in ec_stage_rows], [2*cm, W-2*MARGIN-4*cm]))
story.append(SP(0.2))
story.append(P("12.4 Treatment", h1))
story.append(P("<b>Surgery:</b> Total hysterectomy + bilateral salpingo-oophorectomy (TAH+BSO) is standard. "
"Laparoscopic or robotic preferred. Lymph node assessment (sentinel or full dissection) depending on risk stratification.", bullet))
story.append(P("<b>Adjuvant therapy:</b> Based on ESMO/ESGO risk stratification — vaginal brachytherapy (VBT) for intermediate-risk; "
"external beam radiotherapy (EBRT) for high-intermediate risk; chemotherapy (carboplatin/paclitaxel) for high-risk/advanced.", bullet))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 13: INFERTILITY
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(13, "Infertility",
"Causes, Investigation & Assisted Reproduction"))
story.append(SP(0.4))
story.append(P("""
<b>Infertility</b> is defined as failure to conceive after <b>12 months of regular unprotected
intercourse</b> (6 months if age ≥35). It affects ~1 in 7 couples. Female factors account
for ~35%, male factors ~30%, combined ~20%, unexplained ~15%.
"""))
story.append(P("13.1 Causes", h1))
infertility_causes = [
("Ovulatory dysfunction (35%)", "PCOS (most common), hypothalamic amenorrhoea, hyperprolactinaemia, POI, thyroid disease"),
("Tubal/peritoneal (35%)", "PID (Chlamydia), endometriosis, pelvic adhesions, previous ectopic"),
("Uterine/cervical (10%)", "Fibroids (submucous), polyps, Asherman's, cervical stenosis, DES exposure"),
("Male factor (30%)", "Azoospermia, oligospermia, asthenospermia, teratospermia — semen analysis"),
("Unexplained (15%)", "Normal investigations; may involve subtle ovulatory dysfunction or implantation failure"),
]
story.append(data_table(["Cause (Frequency)", "Detail"], [[c, d] for c, d in infertility_causes], [5*cm, W-2*MARGIN-7*cm]))
story.append(SP(0.2))
story.append(P("13.2 Investigation", h1))
invest_f = [
"Mid-luteal progesterone (Day 21 in 28-day cycle): >30 nmol/L confirms ovulation",
"AMH, AFC (antral follicle count) — ovarian reserve assessment",
"FSH, LH, oestradiol (Day 2-5): elevated FSH suggests diminished ovarian reserve",
"Thyroid function; prolactin; testosterone",
"Hysterosalpingography (HSG) or HyCoSy — tubal patency",
"Laparoscopy ± hysteroscopy if suspected endometriosis/adhesions",
]
for i in invest_f:
story.append(P(f"• {i}", bullet))
story.append(SP(0.2))
story.append(P("13.3 Assisted Reproductive Technology (ART)", h1))
art_options = [
("Ovulation Induction", "Letrozole or clomifene + trigger injection; monitored USS cycles; risk of multiple pregnancy"),
("IUI (Intrauterine Insemination)", "Prepared sperm placed into uterine cavity; used in unexplained, mild male factor, donor sperm"),
("IVF (In Vitro Fertilisation)", "Ovarian stimulation → egg collection → fertilisation in lab → embryo transfer; 25–40% success/cycle"),
("ICSI (Intracytoplasmic Sperm Injection)", "Single sperm injected into egg; used for severe male factor"),
("Egg Donation", "Donor oocytes; for POI, poor responders, advanced age"),
("Surrogacy", "Gestational (IVF embryo in surrogate) or traditional; legal framework varies by country"),
("Fertility Preservation", "Egg/embryo/sperm freezing before chemotherapy or gender-affirming treatment"),
]
story.append(data_table(["Method", "Details"], [[m, d] for m, d in art_options], [4*cm, W-2*MARGIN-6*cm]))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 14: MENOPAUSE
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(14, "Menopause & Hormone Replacement Therapy",
"Physiology, Symptoms & HRT"))
story.append(SP(0.4))
story.append(P("""
<b>Menopause</b> is defined as 12 consecutive months of amenorrhoea due to permanent
ovarian failure. The average age in the UK is <b>51 years</b>.
<b>Premature ovarian insufficiency (POI)</b> occurs before age 40.
"""))
story.append(P("14.1 Perimenopause & Symptoms", h1))
meno_sx = [
("Vasomotor", "Hot flushes (75%), night sweats — due to oestrogen withdrawal affecting thermoregulation"),
("Psychological", "Mood disturbance, depression, anxiety, cognitive symptoms, poor sleep"),
("Urogenital", "Vaginal dryness, dyspareunia, urinary frequency, urgency, recurrent UTIs (GSM — Genitourinary Syndrome of Menopause)"),
("Musculoskeletal", "Joint pains, muscle aches; fibromyalgia-type symptoms"),
("Sexual", "Reduced libido, arousal difficulties, anorgasmia"),
("Long-term", "Osteoporosis (↑ fracture risk); cardiovascular disease (↑ after menopause)"),
]
story.append(data_table(["Domain", "Symptoms"], [[d, s] for d, s in meno_sx], [3.5*cm, W-2*MARGIN-5.5*cm]))
story.append(SP(0.2))
story.append(P("14.2 Hormone Replacement Therapy (HRT)", h1))
story.append(P("""
HRT remains the most effective treatment for menopausal symptoms.
Current guidelines (NICE 2015, updated 2023; NAMS 2022; BMS 2020) endorse its use
for symptomatic women after discussing individualised benefits and risks.
"""))
hrt_types = [
("Oestrogen-only HRT", "For women post-hysterectomy; systemic oestrogen (oral, patch, gel, spray)"),
("Combined HRT", "Oestrogen + progestogen for women with intact uterus (protects against endometrial hyperplasia)"),
("Sequential combined", "Continuous oestrogen + cyclical progestogen (14 days/month); produces monthly bleed; for perimenopause"),
("Continuous combined", "Daily oestrogen + progestogen; no bleed; for post-menopause (≥1 year amenorrhoea)"),
("Local oestrogen", "Vaginal tablets, cream, ring — for GSM; minimal systemic absorption; safe with intact uterus"),
("Tibolone", "Synthetic steroid with oestrogenic, progestogenic, androgenic activity; no bleed"),
]
story.append(data_table(["Type", "Detail"], [[t, d] for t, d in hrt_types], [4*cm, W-2*MARGIN-6*cm]))
story.append(SP(0.2))
story.append(P("14.3 Benefits & Risks of HRT", h1))
hrt_risks = [
("Breast cancer", "Small increased risk with combined HRT (<1 in 1000 women/year); oestrogen-only: no significant increase"),
("VTE", "Oral HRT ↑ VTE risk; transdermal HRT does NOT increase VTE risk — prefer transdermal in women at VTE risk"),
("Endometrial cancer", "Oestrogen alone ↑ risk → always add progestogen in intact uterus; LNG-IUS preferred"),
("CVD", "Started within 10 years of menopause ('window of opportunity') — may have cardioprotective effect"),
("Benefits", "Vasomotor relief; bone protection (reduces osteoporotic fractures); GSM; mood/sleep improvement"),
]
story.append(data_table(["Risk/Benefit", "Evidence"], [[r, e] for r, e in hrt_risks], [4*cm, W-2*MARGIN-6*cm]))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 15: PELVIC FLOOR DISORDERS
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(15, "Pelvic Floor Disorders",
"Prolapse, Urinary Incontinence & Fistulae"))
story.append(SP(0.4))
story.append(P("15.1 Pelvic Organ Prolapse (POP)", h1))
story.append(P("""
Prolapse occurs when pelvic organs descend into or through the vaginal canal due to
weakness of support structures. Affects up to <b>50% of parous women</b>; symptomatic in ~20%.
"""))
pop_types = [
("Cystocele", "Anterior vaginal wall prolapse; bladder descends — most common type"),
("Urethrocele", "Urethra prolapse along anterior vaginal wall"),
("Uterine prolapse", "Uterus descends into vaginal canal; classified I–IV (procidentia = full eversion)"),
("Vault prolapse", "Post-hysterectomy; vaginal vault descends"),
("Enterocele", "Small bowel enters posterior vaginal wall"),
("Rectocele", "Posterior vaginal wall prolapse; rectum herniates into vagina"),
]
story.append(data_table(["Type", "Description"], [[t, d] for t, d in pop_types], [3*cm, W-2*MARGIN-5*cm]))
story.append(SP(0.2))
story.append(P("POP-Q staging: Stage 0 (no prolapse) to Stage IV (complete eversion).", body))
story.append(SP(0.2))
story.append(P("15.2 Urinary Incontinence", h1))
ui_types = [
("Stress Urinary Incontinence (SUI)", "Leakage on coughing, sneezing, exercise; due to urethral sphincter weakness or hypermobility; Rx: pelvic floor exercises (PFMT) → mid-urethral tape (TVT/TOT)"),
("Urge Incontinence (OAB)", "Sudden urge to void; detrusor overactivity; Rx: bladder training → antimuscarinics (oxybutynin, solifenacin) → mirabegron → botox"),
("Mixed Incontinence", "SUI + urge; most common type in older women; treat predominant symptom first"),
("Overflow Incontinence", "Continuous dribble; voiding dysfunction, urinary retention; Rx: treat cause, intermittent catheterisation"),
]
story.append(data_table(["Type", "Features & Management"], [[t, d] for t, d in ui_types], [4*cm, W-2*MARGIN-6*cm]))
story.append(SP(0.2))
story.append(P("15.3 Vesico-Vaginal Fistula (VVF)", h1))
story.append(P("""
VVF is an abnormal communication between bladder and vagina causing continuous urinary
incontinence. <b>Causes:</b> obstetric (obstructed labour — most common in developing countries),
surgical (hysterectomy), radiotherapy, malignancy, Crohn's disease.
<b>Investigation:</b> cystoscopy, IVU/CT urogram, methylene blue dye test.
<b>Treatment:</b> surgical repair (vaginal or abdominal approach; delayed 3–6 months post-injury
to allow resolution of inflammation; radiated fistulae need tissue interposition — Martius flap).
"""))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# CHAPTER 16: KEY DRUGS IN GYNAECOLOGY
# ══════════════════════════════════════════════════════════════════════════
story.append(chapter_header_block(16, "Key Drugs in Gynaecology",
"Pharmacology Reference for Common Gynaecological Medications"))
story.append(SP(0.4))
drug_headers = ["Drug", "Class", "Indication", "Key Points"]
drug_rows = [
["Metformin", "Biguanide", "PCOS (insulin resistance)", "Improves IR; helps ovulation; GI side effects; withhold before contrast"],
["Letrozole", "Aromatase inhibitor", "Ovulation induction (PCOS)", "1st-line OI per ESHRE 2023; better pregnancy rates than clomifene"],
["Clomifene", "SERM", "Ovulation induction", "5-day course Day 2-6; USS monitoring; anti-oestrogenic cervical mucus effect"],
["GnRH agonist (Leuprolide, Goserelin)", "GnRH analogue", "Endometriosis, fibroids, IVF downregulation", "Initial flare then downregulation; SE: menopausal symptoms, bone loss"],
["GnRH antagonist (Cetrorelix)", "GnRH analogue", "IVF — prevent premature LH surge", "Immediate suppression; no flare"],
["Progesterone (natural)", "Progestogen", "Luteal support in IVF; threatened miscarriage", "Vaginal pessaries in ART; PROMISE trial"],
["Mifepristone", "Antiprogestogen", "Medical abortion (with misoprostol)", "200 mg oral; blocks progesterone receptor"],
["Misoprostol", "Prostaglandin E1", "Medical abortion; cervical priming; PPH", "Sublingual/vaginal 800 mcg; 36-48h after mifepristone"],
["Tranexamic acid", "Antifibrinolytic", "Heavy menstrual bleeding", "500-1000 mg TDS during menstruation; non-hormonal"],
["Mefenamic acid", "NSAID / PG inhibitor", "Dysmenorrhoea, HMB", "500 mg TDS; start at onset of period"],
["Danazol", "Androgen derivative", "Endometriosis; HMB", "Side effects: androgenic (acne, weight gain, voice change); now rarely used"],
["Ulipristal acetate", "SPRM", "Emergency contraception; fibroids", "ellaOne (EC); Esmya (fibroid Rx, hepatotoxicity risk)"],
["Spironolactone", "Aldosterone antagonist/anti-androgen", "Hirsutism in PCOS", "50-200 mg OD; teratogenic — contraception mandatory"],
["Carboplatin", "Platinum agent", "Ovarian, endometrial cancer", "AUC dosing; SE: myelosuppression, nephrotoxicity, nausea"],
["Paclitaxel", "Taxane", "Ovarian, endometrial cancer", "First-line with carboplatin; SE: peripheral neuropathy, alopecia, neutropenia"],
["Pembrolizumab", "Anti-PD-1 checkpoint inhibitor", "MSI-H endometrial cancer; advanced cervical cancer", "Approved in combination; immune-mediated adverse effects"],
["Bevacizumab", "Anti-VEGF (angiogenesis inhibitor)", "Ovarian cancer maintenance", "Added to 1st/2nd line chemo; SE: HTN, proteinuria, thromboembolic events"],
["Olaparib", "PARP inhibitor", "BRCA-mutated ovarian cancer maintenance", "Oral; synthetic lethality in BRCA-deficient tumours; SE: fatigue, anaemia"],
]
story.append(data_table(drug_headers, drug_rows, [3.5*cm, 3.5*cm, 4*cm, W-2*MARGIN-13*cm]))
story.append(SP(0.4))
story.append(hrule(DEEP_TEAL, 2))
story.append(SP(0.2))
story.append(P("""
<b>Disclaimer:</b> This reference guide is based on Berek & Novak's Gynecology (16th Edition)
and current clinical guidelines. Always consult up-to-date clinical resources and guidelines
before prescribing or making clinical decisions. Drug doses and treatment protocols
may vary by local formulary and should be verified.
""", note))
story.append(SP(0.2))
story.append(P("Compiled by Orris Medical AI · May 2026", S("credit", fontSize=9, textColor=MED_GRAY,
alignment=TA_CENTER, fontName="Helvetica-Oblique")))
# ══════════════════════════════════════════════════════════════════════════
# BUILD
# ══════════════════════════════════════════════════════════════════════════
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=MARGIN,
rightMargin=MARGIN,
topMargin=2.5*cm,
bottomMargin=2*cm,
title="Gynaecology Complete Guide",
author="Orris Medical AI",
subject="Gynaecology Reference Based on Berek & Novak",
)
doc.build(story, canvasmaker=NumberedCanvas)
print(f"PDF created: {OUTPUT}")
cd /home/daytona/workspace/gynae-book && python build_gynae_pdf.py 2>&1
~/gynae-book/build_gynae_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/gynae-book/build_gynae_pdf.py'
~/gynae-book/build_gynae_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/gynae-book/build_gynae_pdf.py'
~/gynae-book/build_gynae_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/gynae-book/build_gynae_pdf.py'
cd /home/daytona/workspace/gynae-book && python build_gynae_pdf.py 2>&1
python3 -c " from pypdf import PdfReader r = PdfReader('/home/daytona/workspace/…
cd /home/daytona/workspace/gynae-book && python3 -c " # Check how many lines the…