Cholecystectomy open and closed with operative steps indication and complications with position and port placement

Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Reading File
Loading Image
Reading File
Finding Sources
Reading File
Finding Sources
Reading File
Reading File
Loading Image
Loading Image
I now have all the information I need from authoritative sources. Let me compile the comprehensive answer.

Cholecystectomy: Open and Laparoscopic

Sources: Schwartz's Principles of Surgery 11e, Bailey & Love's Short Practice of Surgery 28e, Maingot's Abdominal Operations, Mulholland & Greenfield's Surgery 7e, Fischer's Mastery of Surgery 8e

Historical Background

Carl Langenbuch performed the first open cholecystectomy in 1882. Philippe Mouret introduced laparoscopic cholecystectomy in France in 1987, which rapidly became the gold standard. Over 750,000 cholecystectomies are performed annually in the United States alone. - Schwartz's Principles of Surgery, p. 1438

Indications

Symptomatic (Absolute/Strong)

IndicationNotes
Biliary colic / Symptomatic cholelithiasisMost common indication; once symptomatic, >80% chance of recurrence or complication
Acute cholecystitisEarly (same-admission) laparoscopic approach preferred
Chronic cholecystitisRecurrent attacks
CholedocholithiasisWith or without cholangitis
Gallstone pancreatitisCholecystectomy during same admission or within 2 weeks
Cholangitis / Obstructive jaundiceAfter biliary decompression
Acalculous cholecystitis / Biliary dyskinesiaTypical symptoms, HIDA ejection fraction <35%
Cholecystoenteric fistulaGallstone ileus, Mirizzi syndrome

Prophylactic Indications (Asymptomatic Gallstones)

Asymptomatic gallstones carry <20% lifetime risk of symptoms; prophylactic surgery is only justified in:
  • Sickle cell disease (difficult to distinguish hepatic crisis from acute cholecystitis)
  • Open bariatric surgery (rapid weight loss causes gallstones in ~30% of cases)
  • Long-term total parenteral nutrition
  • Chronic immunosuppression (post-transplant - masked inflammation)
  • Gallbladder polyp >10 mm (malignant potential)
  • Porcelain gallbladder (selected cases with malignant risk)
  • Large gallstones >2.5 cm (cancer risk, esp. Native Americans)
  • Congenital hemolytic anemias (hereditary spherocytosis)
  • No access to healthcare (military, missionaries)
  • Maingot's Abdominal Operations, p. 1015; Mulholland & Greenfield's Surgery, p. 3066

Preoperative Preparation

  • Full blood count, renal and liver function tests, coagulation screen (PT)
  • ECG and chest radiograph if medically indicated
  • Antibiotic prophylaxis: second-generation cephalosporin at induction
  • DVT prophylaxis: LMWH + antiembolic (TED) stockings
  • Patient to void before the operation room to avoid catheterization
  • Orogastric tube if stomach distended; removed at end of procedure
  • Informed consent: procedure, alternatives, risks including bile duct injury and conversion
  • Bailey & Love's, p. 1270

Predictors of Difficult Cholecystectomy

DomainFactors
HistoryMale sex, age >65, presentation >72-96 hours from onset, previous upper abdominal surgery, prior cholecystostomy
ExaminationMorbid obesity, high ASA score
LabsAbnormal liver function tests
ImagingThick-walled gallbladder (>4-5 mm), pericholecystic fluid, impacted stone in neck, Mirizzi syndrome

Laparoscopic Cholecystectomy (Closed/MIS)

Position

  • Supine with the surgeon standing at the patient's left side
  • Alternative: split-leg (French) position with surgeon between the patient's legs - gives ergonomic access to the right upper quadrant
  • Tuck one arm if intraoperative cholangiogram is planned (to allow fluoroscopy machine to be maneuvered)
  • Table tilted reverse Trendelenburg + left lateral tilt to allow the bowel to fall away from the operative field
  • Schwartz's Principles of Surgery, p. 1439

Pneumoperitoneum

  • CO₂ gas to 12-15 mmHg
  • Three techniques:
    1. Closed Veress needle technique - supraumbilical region (alternate access site if previous surgery/scars)
    2. Open Hasson technique (cut-down, safer in previous surgery)
    3. Optical viewing trocar technique

Port Placement (4-Port Standard Technique)

Laparoscopic cholecystectomy port placement and operative steps
Figure: (A) Port placement - camera port at umbilicus + 3 additional ports. (B) Fundus retracted cephalad, infundibulum retracted inferolaterally to open Calot's triangle. (C) Intraoperative view showing Critical View of Safety (CVS) - cystic artery and duct clearly identified. (D) Clip placement on cystic duct. (E) Cholangiogram catheter insertion. (F) Clips placed, cystic duct divided. - Schwartz's Principles of Surgery
PortSizeLocationPurpose
Port 1 (Camera)5 or 10 mmSupra-umbilicalLaparoscope (30° preferred)
Port 2 (Working)10 or 12 mmEpigastrium (midline, subxiphoid)Main working port - dissection, clips, stapler
Port 35 mmRight mid-clavicular line (RUQ)Grasper for infundibulum retraction
Port 45 mmRight flank / anterior axillary lineLocking grasper for fundus retraction
Additional ports may be added for retraction in difficult cases. - Schwartz's Principles of Surgery, p. 1439

Operative Steps - Laparoscopic Cholecystectomy

Step 1: Establish pneumoperitoneum and insert ports as above.
Step 2: Retraction
  • Port 4 (right flank): assistant grasps the fundus and retracts it towards the patient's right shoulder (cephalad, over the liver edge)
  • Port 3 (RMC): surgeon grasps the infundibulum (Hartmann's pouch) and retracts it inferolaterally (towards the patient's right side)
  • This opens the hepatocystic triangle, increases the angle between the cystic duct and CBD, and limits dissection above Rouvière's sulcus
  • B-SAFE landmarks: Bile duct, Sulcus of Rouvière, hepatic Artery, umbilical Fissure, Enteric/duodenum - used to orient the cognitive map
Step 3: Dissect the hepatocystic triangle (Calot's triangle)
  • Using hook electrocautery (monopolar ~30 W, short intermittent bursts) from the epigastric port
  • Clear all fat, fibrous, and areolar tissue from the hepatocystic triangle
  • Dissect both the anterior AND posterior aspects of the triangle
  • Safe zone: cephalad to the R4U line (from roof of Rouvière's sulcus to the umbilical fissure)
Step 4: Achieve the Critical View of Safety (CVS) The CVS (Strasberg) requires ALL three criteria:
  1. The hepatocystic triangle is cleared of all fat and fibrous tissue
  2. The lower one-third of the gallbladder is separated from the cystic plate/liver bed
  3. Only two structures are seen entering the gallbladder (cystic duct + cystic artery)
CVS must be documented - photographically or on video. Difficulty achieving CVS is a red flag to stop dissection.
Step 5: Divide cystic artery and cystic duct
  • Two clips proximally (at the base), one clip on the gallbladder side for both structures
  • Divide between clips with scissors
  • If cystic duct is too dilated for clips: use endoloop, laparoscopic stapler, or suture closure
Step 6: Intraoperative cholangiogram (optional but recommended selectively)
  • Selective indications: abnormal LFTs, prior pancreatitis, jaundice, dilated CBD on USS, large duct + small stones, failed preoperative ERCP, or unclear anatomy
  • Routine use detects CBD stones in ~7% of patients
  • Technique: clip on proximal cystic duct → small anterior incision → insert cholangiogram catheter → fluoroscopy with contrast injection. Ideal cholangiogram shows filling of right and left hepatic ducts + drainage into duodenum + no filling defects
Step 7: Dissect gallbladder from liver bed
  • Electrocautery dissection, staying on the cystic plate
  • Watch for aberrant posterior bile ducts or arteries
  • Before final division, use gallbladder as retractor for final field evaluation
Step 8: Final inspection and removal
  • Check for bleeding, bile staining, confirm clip placement on cystic duct and artery
  • Remove gallbladder via epigastric or umbilical port (often with retrieval bag; enlarge fascia if needed for large stones)
  • Irrigate and retrieve any spilled stones
  • Drain placement (under right liver lobe, via 5-mm port) if: severe inflammation, gangrene, spillage of bile, or anticipated accumulation - not routine
  • Close fascial defects >10 mm at ports
  • Schwartz's Principles of Surgery, pp. 1439-1443; Bailey & Love's, pp. 1270-1272

Tenets for Safe Cholecystectomy (Bailey & Love's Table 71.5)

StepPurpose
Correct retraction (fundus → right shoulder; infundibulum → inferolaterally)Opens hepatocystic triangle; increases cystic duct-CBD angle
Recognize red flag signs (failure of progression, disorientation, poor visualization)"Time out" - stop, reorient, seek second opinion
Achieve CVSConclusive identification before any clip placement
Expose cystic plate (lower ⅓ of GB from liver)Confirms correct dissection plane
Separate GB from fossa, leaving cystic plate on liverPrevents liver sinus bleeding and bile leak

Bailout Strategies (when CVS cannot be achieved)

  1. Abort the procedure and return electively
  2. Convert to open cholecystectomy
  3. Tube cholecystostomy (14 Fr Foley catheter - bridge to definitive procedure)
  4. Subtotal cholecystectomy (open or laparoscopic) - safer than risky dissection
  5. Fundus-first approach

Open Cholecystectomy

Indications for Open Approach

  • Hemodynamic instability
  • Uncontrolled coagulopathy
  • Frank peritonitis
  • Severe COPD or CHF (EF <20%) - cannot tolerate pneumoperitoneum
  • Conversion from laparoscopic (5% elective; 10-30% emergency/complicated)
  • Concurrent laparotomy for another indication
  • Schwartz's Principles of Surgery, p. 1439

Position

  • Supine
  • Bolster/roll under the right side to extend the right upper quadrant (optional)
  • Arms extended on arm boards

Incision Options

  1. Right subcostal (Kocher) incision - most common; centered over the lateral border of the rectus muscle, about 2-3 cm below the costal margin
  2. Upper midline laparotomy - faster access, better for exploration
  3. Right upper transverse incision - alternative

Operative Steps - Open Cholecystectomy

Step 1: Exposure
  • Kocher incision; deepen through subcutaneous fat, anterior rectus sheath, rectus muscle, posterior sheath, peritoneum
  • Place packs on the hepatic flexure of colon, duodenum, and lesser omentum
  • Retract with the assistant's hand ("It is the left hand of the assistant that does all the work" - Moynihan) or self-retaining retractor (e.g., Finochietto, Thompson)
Step 2: Expose the gallbladder
  • Identify the fundus of the gallbladder
  • An Allis/Duval/artery forceps is placed on the infundibulum for traction
Step 3: Dissect Calot's triangle (fundus-first OR infundibulum-first)
  • Retrograde (top-down / fundus-first): dissect gallbladder off liver bed starting at fundus, working toward porta hepatis - used in difficult/inflamed cases
  • Antegrade (infundibulum-first): dissect from neck downward - traditional technique
  • Clear the hepatocystic triangle of all peritoneal and fibrofatty tissue to identify the cystic duct and cystic artery
Step 4: Define and ligate cystic artery
  • The cystic artery typically arises from the right hepatic artery within Calot's triangle
  • Ligate with 2-0 absorbable ties and divide (or clips)
Step 5: Define and ligate cystic duct
  • Pass ligatures around the cystic duct and tie (2-0 absorbable)
  • Place a locking clip or ligature on the proximal cystic duct near the CBD junction (confirming it is NOT the CBD)
  • Divide between ligatures
Calot's triangle anatomy showing ligatures around cystic artery and cystic duct
Figure: Ligatures passed and tied around the cystic artery and cystic duct. The shaded area represents Calot's triangle. - Bailey & Love's Surgery
Step 6: Intraoperative cholangiogram (selective, same criteria as laparoscopic)
Step 7: Dissect gallbladder from liver bed
  • Sharp or electrocautery dissection, leaving cystic plate on liver
  • Control any bleeding from liver sinuses with diathermy or hemostatic agents
Step 8: Partial/Subtotal cholecystectomy (if anatomy unclear)
  • Remove as much gallbladder mucosa as possible
  • Oversew or close the cystic duct stump with absorbable sutures
  • Wide drainage of the area
Step 9: Closure
  • Check for bile leak or bleeding
  • Drain placement if indicated (sub-hepatic drain)
  • Close peritoneum and fascial layers in anatomic layers
  • Skin closure

Intraoperative Cholangiogram (IOC)

Selective Indications
History of jaundice or abnormal LFTs
Prior biliary pancreatitis
Dilated CBD on preoperative ultrasound
Large duct, small stones on imaging
Failed or unavailable preoperative ERCP
Intraoperative anatomical uncertainty
Routine IOC detects CBD stones in ~7% of cases. - Schwartz's Principles of Surgery, p. 1443

Complications

Intraoperative

ComplicationNotes
Bile duct injury (BDI)Most feared; laparoscopic 0.3-0.6%, open 0.2-0.3%
Right hepatic artery injuryOften accompanies BDI due to proximity
Bowel injuryEspecially at Veress needle or trocar insertion
Major vascular injuryAorta, IVC, portal vein - Veress/trocar insertion
BleedingFrom cystic artery, liver bed, trocar sites
Gallbladder perforation / stone spillageOccurs in 5-40% of laparoscopic cases; spilled stones should all be retrieved

Postoperative - Early

ComplicationNotes
Bile leakFrom cystic duct stump, duct of Luschka, or bile duct injury; presents with RUQ pain, fever, bilioma
Postoperative jaundiceMust be urgently investigated (USS → MRCP/ERCP)
Intra-abdominal abscessEspecially if stones spilled
Wound infectionLower with laparoscopic approach
BleedingPort site, cystic artery stump clip dislodgement
Retained CBD stonesMay cause jaundice, cholangitis
Acute pancreatitisCBD stone migration
Port-site herniaFascial defects >10 mm must be closed

Postoperative - Late

ComplicationNotes
Bile duct stricturePost-injury; presents with cholestatic jaundice, cholangitis
Biliary fistulaChronic bile leak
PeritonitisFrom unrecognized bile leak
Stone abscess / fistulaFrom retained spilled stones (months to years later)
Post-cholecystectomy syndromeResidual or recurrent symptoms (~10-15%)
Pulmonary complicationsMore common with open approach

Overall Mortality

  • Open cholecystectomy: <1%; increases with age, comorbidities, acute presentation
  • Laparoscopic: ~0.1%
  • Bailey & Love's, p. 1273; Mulholland & Greenfield's Surgery, p. 3066

Strasberg Classification of Bile Duct Injuries

Strasberg classification of bile duct injuries
Strasberg classification: (a) Bile leak from cystic duct stump or minor biliary radical. (b) Occluded right posterior sectoral duct. (c) Bile leak from divided right posterior sectoral duct. (d) Bile leak from main bile duct without tissue loss. E1-E6: Transections/strictures of the main bile duct at various levels from the hilum. - Bailey & Love's Surgery, p. 1273

Management of Postoperative Jaundice / Suspected BDI

  1. Resuscitation + appropriate IV antibiotics
  2. Urgent RUQ ultrasound (intra/extrahepatic ductal dilatation? fluid collection?)
  3. MRCP to define anatomy (non-invasive)
  4. ERCP when therapeutic intervention needed (stone removal, stent across bile leak)
  5. Surgical repair (hepaticojejunostomy) for major duct injuries - ideally at a specialist hepatobiliary center

Conversion to Open

  • Not a failure; should always be an option and discussed preoperatively
  • Elective conversion rate: ~5%
  • Emergency/complicated cases: 10-30%
  • Indications for conversion:
    • Unable to tolerate pneumoperitoneum
    • Intraoperative complication not manageable laparoscopically
    • Cannot achieve CVS / anatomical structures not clearly identified
    • No progress after a set time period
    • Suspected or confirmed bile duct injury requiring open repair

Comparison: Open vs. Laparoscopic

FeatureLaparoscopicOpen
Incision4 small (5-12 mm) port sitesKocher / midline (10-15 cm)
PneumoperitoneumCO₂, 12-15 mmHgNot required
PainSignificantly lessMore
Hospital stayDay case to 1-2 days3-5 days
Return to work1-2 weeks4-6 weeks
Wound infectionLowerHigher
Bile duct injury rate0.3-0.6% (historically higher; now converging)0.2-0.3%
Mortality~0.1%<1%
VisualizationMagnified laparoscopic viewDirect
Gold standard?YesWhen lap not feasible/safe

Key teaching point: The Critical View of Safety (CVS) is the single most important operative principle in cholecystectomy. No structure should be clipped or divided until CVS is conclusively achieved and documented. When CVS cannot be safely obtained, a bailout strategy should be employed rather than continuing dissection in a dangerous field. - Bailey & Love's Surgery 28e, p. 1271

Create a surgical procedure guide PDF for intraoperative reference

Reading File
Running Command

ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"

Writing File

~/cholecystectomy-guide/build_pdf.py

#!/usr/bin/env python3
"""
Cholecystectomy Surgical Procedure Guide - Intraoperative Reference PDF
Generated with ReportLab
"""

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

OUTPUT_PATH = "/home/daytona/workspace/cholecystectomy-guide/Cholecystectomy_Surgical_Guide.pdf"

# ── Color palette ──────────────────────────────────────────────────────────
C_NAVY      = HexColor("#1a2e4a")
C_BLUE      = HexColor("#1e5fa8")
C_LIGHT_BLUE= HexColor("#dbeafe")
C_TEAL      = HexColor("#0f766e")
C_TEAL_LT   = HexColor("#ccfbf1")
C_RED       = HexColor("#b91c1c")
C_RED_LT    = HexColor("#fee2e2")
C_AMBER     = HexColor("#d97706")
C_AMBER_LT  = HexColor("#fef3c7")
C_GREEN     = HexColor("#15803d")
C_GREEN_LT  = HexColor("#dcfce7")
C_GRAY_DARK = HexColor("#374151")
C_GRAY      = HexColor("#6b7280")
C_GRAY_LT   = HexColor("#f3f4f6")
C_WHITE     = colors.white
C_BLACK     = colors.black
C_HEADER_BG = HexColor("#1a2e4a")
C_DIVIDER   = HexColor("#e5e7eb")

W, H = A4  # 210 x 297 mm

# ── Document setup ─────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
    OUTPUT_PATH,
    pagesize=A4,
    topMargin=18*mm, bottomMargin=18*mm,
    leftMargin=16*mm, rightMargin=16*mm,
    title="Cholecystectomy Surgical Procedure Guide",
    author="Orris Medical AI",
    subject="Intraoperative Reference"
)

# ── Styles ─────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()

def S(name, **kw):
    return ParagraphStyle(name, **kw)

sTitle = S("sTitle",
    fontName="Helvetica-Bold", fontSize=22,
    textColor=C_WHITE, alignment=TA_CENTER,
    spaceAfter=2*mm, leading=26)

sSubtitle = S("sSubtitle",
    fontName="Helvetica", fontSize=11,
    textColor=HexColor("#cbd5e1"), alignment=TA_CENTER,
    spaceAfter=2*mm)

sDisclaimer = S("sDisclaimer",
    fontName="Helvetica-Oblique", fontSize=7.5,
    textColor=HexColor("#94a3b8"), alignment=TA_CENTER)

sSectionHeader = S("sSectionHeader",
    fontName="Helvetica-Bold", fontSize=11,
    textColor=C_WHITE, leading=15, spaceAfter=0)

sSubSection = S("sSubSection",
    fontName="Helvetica-Bold", fontSize=9.5,
    textColor=C_NAVY, leading=13, spaceBefore=4*mm, spaceAfter=1.5*mm)

sBody = S("sBody",
    fontName="Helvetica", fontSize=8.5,
    textColor=C_GRAY_DARK, leading=12.5,
    spaceAfter=1.5*mm)

sBold = S("sBold",
    fontName="Helvetica-Bold", fontSize=8.5,
    textColor=C_NAVY, leading=12.5, spaceAfter=1*mm)

sBullet = S("sBullet",
    fontName="Helvetica", fontSize=8.5,
    textColor=C_GRAY_DARK, leading=12, leftIndent=8*mm,
    bulletIndent=2*mm, spaceAfter=1*mm)

sWarning = S("sWarning",
    fontName="Helvetica-Bold", fontSize=8.5,
    textColor=C_RED, leading=12, spaceAfter=1*mm)

sStep = S("sStep",
    fontName="Helvetica-Bold", fontSize=8.5,
    textColor=C_TEAL, leading=12.5)

sStepBody = S("sStepBody",
    fontName="Helvetica", fontSize=8.2,
    textColor=C_GRAY_DARK, leading=12, leftIndent=5*mm, spaceAfter=1.5*mm)

sTableHeader = S("sTableHeader",
    fontName="Helvetica-Bold", fontSize=8,
    textColor=C_WHITE, alignment=TA_CENTER, leading=10)

sTableCell = S("sTableCell",
    fontName="Helvetica", fontSize=7.8,
    textColor=C_GRAY_DARK, leading=10.5)

sTableCellB = S("sTableCellB",
    fontName="Helvetica-Bold", fontSize=7.8,
    textColor=C_NAVY, leading=10.5)

sSmall = S("sSmall",
    fontName="Helvetica", fontSize=7.5,
    textColor=C_GRAY, leading=10)

sAlert = S("sAlert",
    fontName="Helvetica-Bold", fontSize=8.5,
    textColor=C_RED, leading=12)

sGreen = S("sGreen",
    fontName="Helvetica-Bold", fontSize=8.5,
    textColor=C_GREEN, leading=12)

# ── Helpers ────────────────────────────────────────────────────────────────
def section_header(title, color=C_HEADER_BG):
    tbl = Table([[Paragraph(title.upper(), sSectionHeader)]], colWidths=[W - 32*mm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND", (0,0), (-1,-1), color),
        ("TOPPADDING",    (0,0), (-1,-1), 5),
        ("BOTTOMPADDING", (0,0), (-1,-1), 5),
        ("LEFTPADDING",   (0,0), (-1,-1), 8),
        ("RIGHTPADDING",  (0,0), (-1,-1), 6),
        ("ROUNDEDCORNERS", [4,4,4,4]),
    ]))
    return KeepTogether([Spacer(1, 4*mm), tbl, Spacer(1, 2*mm)])

def hr(color=C_DIVIDER):
    return HRFlowable(width="100%", thickness=0.5, color=color, spaceAfter=2*mm, spaceBefore=1*mm)

def two_col_table(rows, col1_w=55*mm, col2_w=None, header_color=C_NAVY):
    """Generic 2-column table with styled header row."""
    col2_w = col2_w or (W - 32*mm - col1_w)
    header_row = rows[0]
    data = [
        [Paragraph(str(header_row[0]), sTableHeader), Paragraph(str(header_row[1]), sTableHeader)]
    ] + [
        [Paragraph(str(r[0]), sTableCellB), Paragraph(str(r[1]), sTableCell)]
        for r in rows[1:]
    ]
    tbl = Table(data, colWidths=[col1_w, col2_w])
    style = TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), header_color),
        ("BACKGROUND",    (0,1), (-1,-1), C_WHITE),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
        ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("RIGHTPADDING",  (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ])
    tbl.setStyle(style)
    return tbl

def three_col_table(rows, widths, header_color=C_NAVY):
    data = [
        [Paragraph(str(r), sTableHeader) for r in rows[0]]
    ] + [
        [Paragraph(str(r[0]), sTableCellB), Paragraph(str(r[1]), sTableCell), Paragraph(str(r[2]), sTableCell)]
        for r in rows[1:]
    ]
    tbl = Table(data, colWidths=widths)
    tbl.setStyle(TableStyle([
        ("BACKGROUND",    (0,0), (-1,0), header_color),
        ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
        ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
        ("TOPPADDING",    (0,0), (-1,-1), 4),
        ("BOTTOMPADDING", (0,0), (-1,-1), 4),
        ("LEFTPADDING",   (0,0), (-1,-1), 5),
        ("RIGHTPADDING",  (0,0), (-1,-1), 5),
        ("VALIGN",        (0,0), (-1,-1), "TOP"),
    ]))
    return tbl

def alert_box(text, bg=C_RED_LT, border=C_RED, text_style=None):
    ts = text_style or sAlert
    tbl = Table([[Paragraph(text, ts)]], colWidths=[W - 32*mm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (-1,-1), bg),
        ("LINEABOVE",    (0,0), (-1,-1), 2, border),
        ("LINELEFT",     (0,0), (0,-1), 3, border),
        ("TOPPADDING",   (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
        ("LEFTPADDING",  (0,0), (-1,-1), 8),
        ("RIGHTPADDING", (0,0), (-1,-1), 6),
    ]))
    return KeepTogether([tbl, Spacer(1, 2*mm)])

def step_box(num, title, body_lines):
    """Numbered step box."""
    num_cell = Paragraph(f"<b>{num}</b>", S("n",
        fontName="Helvetica-Bold", fontSize=13,
        textColor=C_WHITE, alignment=TA_CENTER, leading=16))
    title_p = Paragraph(title, S("st",
        fontName="Helvetica-Bold", fontSize=9,
        textColor=C_NAVY, leading=13))
    body_content = [title_p] + [Paragraph(f"• {l}", sStepBody) for l in body_lines]
    tbl = Table([[num_cell, body_content]], colWidths=[10*mm, W - 32*mm - 12*mm])
    tbl.setStyle(TableStyle([
        ("BACKGROUND",   (0,0), (0,-1), C_TEAL),
        ("BACKGROUND",   (1,0), (1,-1), C_WHITE),
        ("LINEBELOW",    (0,0), (-1,-1), 0.5, C_DIVIDER),
        ("TOPPADDING",   (0,0), (-1,-1), 5),
        ("BOTTOMPADDING",(0,0), (-1,-1), 5),
        ("LEFTPADDING",  (0,0), (0,-1), 2),
        ("RIGHTPADDING", (0,0), (0,-1), 2),
        ("LEFTPADDING",  (1,0), (1,-1), 6),
        ("VALIGN",       (0,0), (-1,-1), "TOP"),
        ("ROUNDEDCORNERS", [3,3,3,3]),
    ]))
    return KeepTogether([tbl, Spacer(1, 1.5*mm)])

# ══════════════════════════════════════════════════════════════════════════
# BUILD CONTENT
# ══════════════════════════════════════════════════════════════════════════
story = []

# ── COVER HEADER ──────────────────────────────────────────────────────────
cover = Table(
    [[
        Paragraph("CHOLECYSTECTOMY", sTitle),
        Paragraph("Surgical Procedure Guide", sSubtitle),
        Paragraph("Open &amp; Laparoscopic | Intraoperative Reference", sSubtitle),
        Spacer(1, 3*mm),
        Paragraph("For use by qualified surgical teams in an operative setting.", sDisclaimer),
        Paragraph("Schwartz's 11e · Bailey &amp; Love 28e · Maingot's · Fischer's Mastery 8e", sDisclaimer),
    ]],
    colWidths=[W - 32*mm]
)
cover.setStyle(TableStyle([
    ("BACKGROUND",   (0,0), (-1,-1), C_NAVY),
    ("TOPPADDING",   (0,0), (-1,-1), 12),
    ("BOTTOMPADDING",(0,0), (-1,-1), 10),
    ("LEFTPADDING",  (0,0), (-1,-1), 14),
    ("RIGHTPADDING", (0,0), (-1,-1), 14),
    ("ROUNDEDCORNERS", [6,6,6,6]),
]))
story.append(cover)
story.append(Spacer(1, 4*mm))

# ── 1. INDICATIONS ────────────────────────────────────────────────────────
story.append(section_header("1. Indications for Cholecystectomy", C_BLUE))

ind_rows = [
    ["Indication", "Notes"],
    ["Biliary colic / Symptomatic cholelithiasis", "Most common. >80% recurrence/complication risk once symptomatic."],
    ["Acute cholecystitis", "Early (same-admission) laparoscopic preferred."],
    ["Chronic cholecystitis", "Recurrent symptomatic attacks."],
    ["Choledocholithiasis", "With or without cholangitis."],
    ["Gallstone pancreatitis", "Same admission or within 2 weeks."],
    ["Cholangitis / Obstructive jaundice", "After biliary decompression (ERCP/PTC)."],
    ["Acalculous cholecystitis / Biliary dyskinesia", "Typical biliary symptoms + HIDA EF <35%."],
    ["Mirizzi syndrome / Cholecystoenteric fistula", "Complex – higher conversion risk."],
]
story.append(two_col_table(ind_rows, col1_w=65*mm))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("Prophylactic Indications (Asymptomatic Gallstones)", sSubSection))
story.append(Paragraph(
    "Asymptomatic gallstones carry &lt;20% lifetime risk of symptoms. "
    "Prophylactic cholecystectomy is justified in:", sBody))
bullets_prop = [
    "Sickle cell disease (vaso-occlusive crisis mimics acute cholecystitis)",
    "Gallbladder polyp ≥10 mm (malignant potential)",
    "Open bariatric surgery (concurrent; laparoscopic bariatric – avoid due to added risk)",
    "Porcelain gallbladder / Gallstones >2.5 cm in high-risk populations (Native Americans)",
    "Long-term total parenteral nutrition",
    "Chronic immunosuppression post solid-organ transplant",
    "Congenital hemolytic anemias (hereditary spherocytosis, thalassaemia)",
    "No access to healthcare (military, missionaries)",
]
for b in bullets_prop:
    story.append(Paragraph(f"• {b}", sBullet))
story.append(Spacer(1, 2*mm))

# ── 2. CONTRAINDICATIONS / CONVERSION ────────────────────────────────────
story.append(section_header("2. Contraindications & Conversion Criteria", C_RED))

story.append(Paragraph("Absolute Contraindications to Laparoscopic Approach", sSubSection))
abs_ci = [
    ["Condition", "Rationale"],
    ["Hemodynamic instability", "Cannot tolerate pneumoperitoneum; open preferred"],
    ["Uncontrolled coagulopathy", "Bleeding risk precludes laparoscopy"],
    ["Frank peritonitis", "Requires open exploration"],
    ["Severe COPD / CHF (EF <20%)", "Cannot tolerate CO₂ pneumoperitoneum"],
]
story.append(two_col_table(abs_ci, col1_w=65*mm, header_color=C_RED))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("Indications to Convert to Open (Intraoperatively)", sSubSection))
conv = [
    ["Trigger", "Action"],
    ["Unable to tolerate pneumoperitoneum", "Convert immediately"],
    ["Cannot achieve Critical View of Safety (CVS)", "Bailout strategy → convert if needed"],
    ["Intraoperative complication not manageable laparoscopically", "Convert + repair"],
    ["No progress after a set time period", "Convert; do not persist"],
    ["Suspected or confirmed bile duct injury", "Convert for open repair at HPB center"],
]
story.append(two_col_table(conv, col1_w=70*mm, header_color=C_AMBER))
story.append(Spacer(1, 1*mm))
story.append(Paragraph(
    "Conversion rate: ~5% elective | 10–30% emergency/complicated cases. "
    "Conversion is NOT a failure; discuss preoperatively with patient.", sSmall))
story.append(Spacer(1, 2*mm))

# ── 3. PREOPERATIVE PREPARATION ───────────────────────────────────────────
story.append(section_header("3. Preoperative Checklist", C_TEAL))

pre_data = [
    ["Checklist Item", "Detail"],
    ["Bloods", "FBC, U&E, LFTs, coagulation (PT/INR)"],
    ["Imaging", "RUQ ultrasound (confirm stones, CBD diameter, anatomy)"],
    ["ECG / CXR", "If medically indicated (age >40, cardiac/respiratory history)"],
    ["Antibiotic prophylaxis", "2nd-generation cephalosporin (e.g., cefuroxime 1.5g IV) at induction"],
    ["DVT prophylaxis", "LMWH (e.g., enoxaparin 40mg SC) + TED stockings"],
    ["Bladder", "Patient to void before OR; avoid urinary catheterization"],
    ["Orogastric tube", "Insert if stomach distended; remove at end of procedure"],
    ["Consent", "Procedure, alternatives, BDI risk (~0.3–0.6%), conversion to open"],
    ["Team briefing / WHO checklist", "Confirm site marking, allergies, antibiotic given"],
]
story.append(two_col_table(pre_data, col1_w=52*mm))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("Predictors of Difficult Cholecystectomy", sSubSection))
diff_data = [
    ["Domain", "Risk Factors"],
    ["History", "Male sex, age >65 yrs, onset >72–96 hrs (acute cholecystitis), prior upper abdominal surgery, prior cholecystostomy"],
    ["Examination", "Morbid obesity, high ASA score, palpable gallbladder mass"],
    ["Laboratory", "Elevated WCC, abnormal LFTs, elevated bilirubin"],
    ["Imaging (USS/CT/MRCP)", "Wall thickness >4–5 mm, pericholecystic fluid, impacted stone in neck, contracted gallbladder, Mirizzi syndrome, suspected fistula"],
]
story.append(two_col_table(diff_data, col1_w=42*mm, header_color=C_AMBER))
story.append(Spacer(1, 2*mm))

# ── 4. LAPAROSCOPIC CHOLECYSTECTOMY ───────────────────────────────────────
story.append(PageBreak())
story.append(section_header("4. Laparoscopic Cholecystectomy", C_NAVY))

story.append(Paragraph("Patient Position", sSubSection))
pos_lap = [
    ["Position", "Details"],
    ["Primary position", "Supine; surgeon on patient's LEFT side"],
    ["Alternative", "Split-leg (French) position; surgeon between patient's legs – ergonomic for RUQ"],
    ["Table tilt", "Reverse Trendelenburg (15–20°) + left lateral tilt – bowel falls away from operative field"],
    ["Arm", "Tuck one arm (ipsilateral) if cholangiogram planned – allows fluoroscopy machine access"],
    ["Monitor", "Placed at patient's right shoulder/head end"],
]
story.append(two_col_table(pos_lap, col1_w=45*mm))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("Port Placement (Standard 4-Port)", sSubSection))
port_data = [
    ["Port", "Size", "Location", "Purpose"],
    ["Port 1 – Camera", "5 or 10 mm", "Supra-umbilical (umbilicus)", "30° laparoscope (camera port)"],
    ["Port 2 – Main working", "10 or 12 mm", "Epigastrium (subxiphoid, midline)", "Clips, scissors, dissector, cholangiogram"],
    ["Port 3 – Infundibulum", "5 mm", "Right mid-clavicular line (RUQ)", "Grasper – retract infundibulum inferolaterally"],
    ["Port 4 – Fundus", "5 mm", "Right flank / anterior axillary line", "Locking grasper – retract fundus to right shoulder"],
]
port_tbl = Table(
    [[Paragraph(r, sTableHeader) for r in port_data[0]]] +
    [[Paragraph(str(c), sTableCellB if i==0 else sTableCell) for i,c in enumerate(row)]
     for row in port_data[1:]],
    colWidths=[35*mm, 20*mm, 55*mm, 62*mm]
)
port_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_NAVY),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
    ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(port_tbl)
story.append(Paragraph(
    "Additional ports may be placed as needed for retraction in difficult cases. "
    "Hasson (open) technique preferred if previous surgery/scars at umbilicus. "
    "Fascial defects >10 mm must be closed at end.", sSmall))
story.append(Spacer(1, 3*mm))

story.append(Paragraph("Operative Steps", sSubSection))

steps_lap = [
    ("1", "Establish Pneumoperitoneum",
     ["CO₂ to 12–15 mmHg",
      "Technique: Closed Veress needle (supraumbilical), OR Open Hasson cut-down, OR Optical viewing trocar",
      "Confirm intraperitoneal position before insufflation (aspiration test, saline hanging drop)",
      "Insert camera port first; inspect for entry injuries before other ports"]),
    ("2", "Insert Remaining Ports",
     ["Under direct vision (not blind)",
      "Port 2 (epigastric) → working port",
      "Port 3 (RMC line) → infundibulum grasper",
      "Port 4 (right flank) → fundus grasper"]),
    ("3", "Retraction – Open Hepatocystic Triangle",
     ["Port 4 (assistant): Grasp fundus → retract CEPHALAD over liver edge toward patient's RIGHT SHOULDER",
      "Port 3 (surgeon): Grasp infundibulum → retract INFEROLATERALLY (toward patient's right side)",
      "This opens the hepatocystic triangle, increases cystic duct–CBD angle, limits dissection to safe zone",
      "B-SAFE landmarks: Bile duct | Sulcus of Rouvière | hepatic Artery | umbilical Fissure | Enteric (duodenum)"]),
    ("4", "Dissect Hepatocystic Triangle",
     ["Hook electrocautery (monopolar ~30 W, low setting, intermittent short bursts – avoid thermal spread)",
      "Clear ALL fat, fibrous, and areolar tissue from BOTH anterior AND posterior aspects of the triangle",
      "Safe zone: cephalad to R4U line (Rouvière's sulcus → umbilical fissure across base of segment IV)",
      "Do NOT use blind/deep cautery; divide small amounts of tissue at a time"]),
    ("5", "Achieve Critical View of Safety (CVS) ← MANDATORY",
     ["THREE criteria ALL must be met before ANY clipping:",
      "① Hepatocystic triangle CLEARED of all fat/fibrous tissue",
      "② Lower ⅓ of gallbladder SEPARATED from cystic plate/liver bed",
      "③ ONLY TWO structures seen entering the gallbladder (cystic duct + cystic artery)",
      "DOCUMENT CVS by photograph or video clip in the operative record",
      "If CVS cannot be achieved → STOP → employ bailout strategy"]),
    ("6", "Divide Cystic Artery and Cystic Duct",
     ["Clip cystic artery: 2 clips proximally + 1 clip on gallbladder side → divide",
      "Clip cystic duct: 2 clips at base (proximal) + 1 clip on gallbladder side → divide",
      "Dilated cystic duct (too wide for clips): use endoloop, laparoscopic stapler, or suture ligation",
      "CONFIRM: only cystic structures divided – NOT the CBD or right hepatic artery"]),
    ("7", "Intraoperative Cholangiogram (Selective)",
     ["Indications: abnormal LFTs, prior pancreatitis/jaundice, dilated CBD on USS, unclear anatomy",
      "Technique: proximal clip on cystic duct → small anterior incision → insert cholangiogram catheter",
      "Ideal IOC: fills right + left hepatic ducts, drains into duodenum, no filling defects, no air bubbles",
      "Routine IOC detects CBD stones in ~7% of patients"]),
    ("8", "Dissect Gallbladder from Liver Bed",
     ["Electrocautery dissection on the cystic plate (staying on the gallbladder side)",
      "Watch for aberrant posterior bile ducts or arteries",
      "Before final detachment: use gallbladder as retractor for a final field evaluation",
      "Check: bleeding points, bile staining, clip positions on cystic duct and artery"]),
    ("9", "Remove Gallbladder & Close",
     ["Remove via epigastric or umbilical port (retrieval bag recommended – prevents stone spillage)",
      "Enlarge fascial incision if needed for large or inflamed gallbladder",
      "Retrieve ALL spilled stones (risk of delayed abscess, fistula)",
      "Drain: NOT routine; use if gangrenous, bile spill, or anticipated accumulation",
      "Close fascial defects ≥10 mm to prevent port-site hernia",
      "Skin closure with absorbable sutures or skin glue"]),
]

for num, title, body in steps_lap:
    story.append(step_box(num, title, body))

story.append(Spacer(1, 2*mm))

# CVS alert box
story.append(alert_box(
    "⚠  CRITICAL VIEW OF SAFETY (CVS): No structure is to be clipped or divided until ALL THREE CVS criteria "
    "are satisfied and documented. This is the single most important safety principle in cholecystectomy.",
    bg=C_RED_LT, border=C_RED
))

# Bailout strategies
story.append(Paragraph("Bailout Strategies (When CVS Cannot Be Achieved)", sSubSection))
bail_data = [
    ["Strategy", "When to Use"],
    ["1. Abort + return electively", "Acute inflammation too severe; stable patient – plan interval cholecystectomy"],
    ["2. Convert to open cholecystectomy", "Ongoing difficulty, suspected injury, anatomical uncertainty"],
    ["3. Tube cholecystostomy (14 Fr Foley)", "Decompression only; bridge to definitive procedure in unstable patient"],
    ["4. Subtotal cholecystectomy (fenestrating or reconstituting)", "Safer than risky dissection; leave cystic duct/part of wall if adherent"],
    ["5. Fundus-first (retrograde) approach", "Severe adhesions/inflammation at Calot's – dissect from fundus downward"],
]
story.append(two_col_table(bail_data, col1_w=70*mm, header_color=C_AMBER))
story.append(Spacer(1, 2*mm))

# ── 5. OPEN CHOLECYSTECTOMY ───────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header("5. Open Cholecystectomy", C_TEAL))

story.append(Paragraph("Patient Position & Incision", sSubSection))
open_pos = [
    ["Parameter", "Detail"],
    ["Position", "Supine; optional right-sided bolster/roll under flank to extend RUQ"],
    ["Incision options", "① Right subcostal (Kocher) – most common; 2–3 cm below costal margin, over lateral rectus border\n② Upper midline – faster, better for exploration\n③ Right upper transverse – alternative"],
    ["Retraction", "Self-retaining retractor (Finochietto, Thompson) OR assistant's left hand – \"the left hand of the assistant does all the work\" (Moynihan)"],
    ["Exposure", "Packs on hepatic flexure of colon, duodenum, lesser omentum"],
]
story.append(two_col_table(open_pos, col1_w=42*mm))
story.append(Spacer(1, 2*mm))

story.append(Paragraph("Operative Steps – Open Cholecystectomy", sSubSection))

steps_open = [
    ("1", "Incision & Entry",
     ["Kocher incision: skin → subcut fat → anterior rectus sheath → split/divide rectus → posterior sheath → peritoneum",
      "Confirm gallbladder position; run fingers along undersurface of liver"]),
    ("2", "Exposure",
     ["Place moist packs: hepatic flexure of colon, duodenum, lesser omentum",
      "Retract liver superiorly with liver retractor",
      "Place Duval/Allis forceps on infundibulum for traction"]),
    ("3", "Identify Triangle of Calot",
     ["Dissect peritoneum over hepatoduodenal ligament",
      "Palpate CBD (usually right-sided, rounded cord) to confirm location BEFORE any dissection",
      "Clear fat/areolar tissue from Calot's triangle (cystic duct + cystic artery + liver margin)"]),
    ("4", "Ligate Cystic Artery",
     ["Trace artery from Calot's triangle to gallbladder wall",
      "Pass 2-0 absorbable ligatures (or clips) proximal and distal",
      "Divide between ligatures",
      "Beware: right hepatic artery can be mistaken for cystic artery – confirm origin"]),
    ("5", "Ligate Cystic Duct",
     ["Dissect cystic duct free from CBD junction under direct vision",
      "Confirm NOT dividing CBD (palpate, intraoperative cholangiogram if uncertain)",
      "Ligate with 2-0 absorbable sutures (proximal + distal) and divide",
      "Leave adequate cystic duct stump (≥5 mm) to prevent stump leak"]),
    ("6", "Intraoperative Cholangiogram (Selective)",
     ["Same indications as laparoscopic (see Section 4)",
      "Proximal tie on cystic duct → small anterior ductal incision → insert cholangiogram catheter → contrast under fluoroscopy"]),
    ("7", "Dissect Gallbladder from Liver Bed",
     ["Retrograde (fundus-first) OR antegrade (infundibulum-first) dissection",
      "Electrocautery or sharp dissection on cystic plate",
      "Secure hemostasis from liver bed with diathermy / hemostatic agents",
      "If gallbladder perforates: retrieve all stones; bile irrigation"]),
    ("8", "Partial/Subtotal Cholecystectomy (If Anatomy Unclear)",
     ["Remove as much gallbladder mucosa as possible (ablate remaining mucosa with diathermy)",
      "Oversew or close cystic duct stump with absorbable sutures",
      "Wide drainage of the area – mandatory"]),
    ("9", "Closure",
     ["Check for bile leak (bile staining, bilious fluid) and bleeding",
      "Drain placement (sub-hepatic closed-suction drain) if: severe inflammation, uncertain duct stump, bile spill",
      "Close peritoneum (1-0 absorbable continuous) → posterior sheath → rectus → anterior sheath (1-0 absorbable loop or PDS)",
      "Skin: subcuticular absorbable or staples"]),
]

for num, title, body in steps_open:
    story.append(step_box(num, title, body))

story.append(Spacer(1, 2*mm))

# ── 6. INTRAOPERATIVE CHOLANGIOGRAM ──────────────────────────────────────
story.append(section_header("6. Intraoperative Cholangiogram (IOC)", C_BLUE))

ioc_data = [
    ["IOC: Selective Indications", "Technique Summary"],
    ["History of jaundice or abnormal LFTs", "1. Clip proximal cystic duct"],
    ["Prior biliary pancreatitis", "2. Small anterior incision on cystic duct"],
    ["Dilated CBD on preoperative ultrasound", "3. Insert and secure cholangiogram catheter"],
    ["Large duct + small stones on imaging", "4. Inject dilute contrast (50%) under fluoroscopy (live)"],
    ["Failed or unavailable preoperative ERCP", "5. Avoid air bubbles (mimic filling defects)"],
    ["Intraoperative anatomical uncertainty", "Ideal result: R+L hepatic ducts filled, drainage into duodenum, no defects"],
]
story.append(two_col_table(ioc_data, col1_w=75*mm))
story.append(Paragraph(
    "Routine IOC detects CBD stones in ~7% of patients. "
    "No consensus on routine vs selective use; all surgeons performing cholecystectomy "
    "should be proficient with the technique. (Schwartz's 11e)", sSmall))
story.append(Spacer(1, 2*mm))

# ── 7. COMPLICATIONS ──────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_header("7. Complications", C_RED))

story.append(Paragraph("Intraoperative Complications", sSubSection))
intraop_comp = [
    ["Complication", "Incidence / Notes", "Immediate Action"],
    ["Bile duct injury (BDI)", "Lap: 0.3–0.6% | Open: 0.2–0.3%\nMost feared; major cause of litigation", "Stop dissection. Convert to open. Refer to HPB centre if complex repair needed."],
    ["Right hepatic artery injury", "Often accompanies BDI (close anatomic proximity)", "Control bleeding. Vascular repair or ligation if necessary."],
    ["Major vascular injury (aorta/IVC/portal vein)", "Trocar/Veress insertion – rare but life-threatening", "Direct pressure immediately. Call for vascular surgeon. Open laparotomy."],
    ["Bowel injury (stomach/duodenum/colon)", "Veress or trocar insertion", "Repair immediately (primary or with loop if contaminated)."],
    ["Gallbladder perforation / Stone spillage", "5–40% of laparoscopic cases", "Irrigate thoroughly. Retrieve ALL stones. Document in operative note."],
    ["Bleeding from cystic artery / liver bed", "Common", "Clip, tie or cauterise. Do not clip blindly."],
]
comp_tbl = Table(
    [[Paragraph(r, sTableHeader) for r in intraop_comp[0]]] +
    [[Paragraph(str(c), sTableCellB if i==0 else sTableCell) for i,c in enumerate(row)]
     for row in intraop_comp[1:]],
    colWidths=[45*mm, 55*mm, 72*mm]
)
comp_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_RED),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_RED_LT]),
    ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(comp_tbl)
story.append(Spacer(1, 3*mm))

story.append(Paragraph("Postoperative Complications", sSubSection))
postop_comp = [
    ["Complication", "Presentation", "Investigation / Management"],
    ["Bile leak", "RUQ pain, fever, bilioma on USS", "USS → MRCP/ERCP (stent if cystic stump leak). Drain if collection."],
    ["Bile duct stricture / injury", "Jaundice, cholangitis (early or late)", "USS → MRCP. ERCP/stent or surgical hepaticojejunostomy at HPB centre."],
    ["Retained CBD stones", "Jaundice, cholangitis (Charcot's triad)", "MRCP → ERCP with sphincterotomy + stone extraction."],
    ["Intra-abdominal abscess", "Fever, RUQ pain, sepsis (esp. if stones spilled)", "CT abdomen → radiological drainage ± antibiotics."],
    ["Port-site / wound hernia", "Bulge at port site; can obstruct", "Repair electively (or urgently if obstructed)."],
    ["Acute pancreatitis", "Epigastric pain, raised amylase", "Conservative management; ERCP if CBD stone."],
    ["Post-cholecystectomy syndrome", "Residual/recurrent RUQ symptoms (~10–15%)", "Exclude retained stone (MRCP), sphincter of Oddi dysfunction (ERCP manometry)."],
    ["Pulmonary complications", "Atelectasis, pneumonia (more common – open)", "Physiotherapy, analgesia, early mobilisation."],
]
postop_tbl = Table(
    [[Paragraph(r, sTableHeader) for r in postop_comp[0]]] +
    [[Paragraph(str(c), sTableCellB if i==0 else sTableCell) for i,c in enumerate(row)]
     for row in postop_comp[1:]],
    colWidths=[42*mm, 48*mm, 82*mm]
)
postop_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_NAVY),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
    ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(postop_tbl)
story.append(Spacer(1, 3*mm))

# Strasberg classification table
story.append(Paragraph("Strasberg Classification of Bile Duct Injuries", sSubSection))
stras_data = [
    ["Type", "Description", "Management Principle"],
    ["A", "Bile leak from cystic duct stump or duct of Luschka (minor radical in GB fossa)", "ERCP + stent; drain collection"],
    ["B", "Occluded (clipped) right posterior sectoral duct – no leak", "Depends on symptoms; often conservative vs Roux-en-Y"],
    ["C", "Bile leak from divided (unoccluded) right posterior sectoral duct", "ERCP if amenable; otherwise Roux-en-Y hepaticojejunostomy"],
    ["D", "Lateral laceration/leak from main bile duct without tissue loss", "ERCP + stent (minor); primary repair or hepaticojejunostomy (major)"],
    ["E1", "Transected main bile duct; stricture >2 cm from hilum", "Hepaticojejunostomy at HPB centre"],
    ["E2", "Transected main bile duct; stricture <2 cm from hilum", "Hepaticojejunostomy at HPB centre"],
    ["E3", "Stricture at hilum; R + L ducts in communication", "High hepaticojejunostomy"],
    ["E4", "Stricture at hilum; R + L ducts separated", "Complex biliary reconstruction"],
    ["E5", "Right aberrant sectoral duct + main duct involved", "Complex biliary reconstruction"],
]
stras_tbl = Table(
    [[Paragraph(r, sTableHeader) for r in stras_data[0]]] +
    [[Paragraph(str(c), sTableCellB if i==0 else sTableCell) for i,c in enumerate(row)]
     for row in stras_data[1:]],
    colWidths=[15*mm, 80*mm, 77*mm]
)
stras_tbl.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_RED),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_RED_LT]),
    ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(stras_tbl)
story.append(Spacer(1, 2*mm))

story.append(alert_box(
    "SUSPECTED POSTOPERATIVE BDI PROTOCOL: Resuscitate → IV antibiotics → Urgent RUQ USS → "
    "MRCP (anatomy) → ERCP if therapeutic intervention needed → Surgical repair (hepaticojejunostomy) "
    "for major injuries AT AN HPB CENTRE. Do NOT attempt repair without expertise.",
    bg=C_RED_LT, border=C_RED
))

# ── 8. OPEN vs LAPAROSCOPIC COMPARISON ───────────────────────────────────
story.append(PageBreak())
story.append(section_header("8. Open vs Laparoscopic – Comparison", C_NAVY))

comp_table_data = [
    ["Parameter", "Laparoscopic", "Open"],
    ["Gold standard?", "YES – treatment of choice", "When lap not feasible/safe"],
    ["Incision", "4 × 5–12 mm ports", "Kocher / midline (10–15 cm)"],
    ["Pneumoperitoneum", "CO₂, 12–15 mmHg required", "Not required"],
    ["Pain (postop)", "Significantly less", "More; requires adequate analgesia"],
    ["Hospital stay", "Day case to 1–2 days", "3–5 days"],
    ["Return to work", "1–2 weeks", "4–6 weeks"],
    ["Wound infection", "Lower", "Higher"],
    ["Bile duct injury rate", "0.3–0.6% (historically higher; converging)", "0.2–0.3%"],
    ["Stone spillage risk", "5–40%", "Less common; direct retrieval"],
    ["Mortality", "~0.1%", "<1%"],
    ["Visualization", "Magnified laparoscopic view (10–30°)", "Direct (wide field)"],
    ["Conversion", "~5% elective; 10–30% emergency", "N/A (already open)"],
]

comp_tbl2 = Table(
    [[Paragraph(r, sTableHeader) for r in comp_table_data[0]]] +
    [[Paragraph(str(c), sTableCellB if i==0 else
      (S("g", fontName="Helvetica-Bold", fontSize=7.8, textColor=C_GREEN, leading=10.5) if i==1 else sTableCell)
      ) for i,c in enumerate(row)]
     for row in comp_table_data[1:]],
    colWidths=[45*mm, 72*mm, 55*mm]
)
comp_tbl2.setStyle(TableStyle([
    ("BACKGROUND",    (0,0), (-1,0), C_NAVY),
    ("ROWBACKGROUNDS",(0,1), (-1,-1), [C_WHITE, C_GRAY_LT]),
    ("GRID",          (0,0), (-1,-1), 0.4, C_DIVIDER),
    ("TOPPADDING",    (0,0), (-1,-1), 4),
    ("BOTTOMPADDING", (0,0), (-1,-1), 4),
    ("LEFTPADDING",   (0,0), (-1,-1), 5),
    ("RIGHTPADDING",  (0,0), (-1,-1), 5),
    ("VALIGN",        (0,0), (-1,-1), "TOP"),
]))
story.append(comp_tbl2)
story.append(Spacer(1, 2*mm))

# ── 9. KEY ANATOMICAL LANDMARKS ───────────────────────────────────────────
story.append(section_header("9. Key Anatomical Landmarks & Safety Principles", C_TEAL))

story.append(Paragraph("Triangle of Calot (Hepatocystic Triangle)", sSubSection))
story.append(Paragraph(
    "Bounded by: <b>cystic duct</b> (inferiorly), <b>common hepatic duct</b> (medially), and "
    "<b>inferior surface of the liver / cystic plate</b> (superiorly). "
    "Contains the cystic artery and lymph node of Calot (Lund's node). "
    "Note: 'Triangle of Calot' strictly includes the cystic artery; the broader 'hepatocystic triangle' "
    "is the modern preferred term used in CVS criteria.", sBody))

anat_data = [
    ["Landmark", "Significance"],
    ["Rouvière's sulcus", "Constant hepatic fissure on right liver surface. Safe dissection zone is CEPHALAD to a line from its roof to the umbilical fissure (R4U line)."],
    ["Cystic plate", "Peritoneal reflection where GB attaches to liver. Exposing the medial ⅓ of the cystic plate is the 3rd CVS criterion."],
    ["Lund's node (Node of Calot)", "Lymph node at junction of cystic duct and hepatic duct; landmark for cystic artery."],
    ["Hartmann's pouch", "Infundibulum of GB; the grasping point for inferolateral retraction."],
    ["Duct of Luschka", "Small bile duct from liver directly into GB bed; if injured → Type A bile leak."],
    ["Right hepatic artery", "Typically passes behind CHD into Calot's triangle; caterpillar hump variant mimics cystic artery."],
    ["B-SAFE method", "5 landmarks: Bile duct | Sulcus of Rouvière | hepatic Artery | umbilical Fissure | Enteric (duodenum). Use to orient cognitive map during difficult dissection."],
]
story.append(two_col_table(anat_data, col1_w=50*mm))
story.append(Spacer(1, 2*mm))

story.append(alert_box(
    "SAFE ENERGY USE (Hook Cautery): Low setting ~30 W | Intermittent short bursts | "
    "Small tissue bites at a time | AVOID blind cautery near hepatocystic triangle | "
    "Ultrasonic energy = less lateral spread (but cumbersome in tight triangle).",
    bg=C_AMBER_LT, border=C_AMBER,
    text_style=S("amb", fontName="Helvetica-Bold", fontSize=8.2, textColor=C_AMBER, leading=12)
))

# ── 10. QUICK REFERENCE / SAFETY CHECKLIST ───────────────────────────────
story.append(section_header("10. Intraoperative Safety Checklist", C_GREEN))

checklist_data = [
    ["☐ Pre-incision WHO surgical safety check completed"],
    ["☐ Antibiotic given within 60 minutes of incision"],
    ["☐ DVT prophylaxis in place"],
    ["☐ Patient positioned correctly (supine / split-leg); table tilted"],
    ["☐ 4 ports placed under direct vision"],
    ["☐ B-SAFE landmarks identified"],
    ["☐ Correct retraction: fundus → right shoulder; infundibulum → inferolateral"],
    ["☐ Hepatocystic triangle dissected ANTERIORLY and POSTERIORLY"],
    ["☐ CVS criteria ALL met – confirmed by surgeon"],
    ["☐ CVS DOCUMENTED (photo or video)"],
    ["☐ Only 2 structures entering gallbladder before clipping"],
    ["☐ Cystic duct clipped: 2 proximal + 1 distal → divided"],
    ["☐ Cystic artery clipped: 2 proximal + 1 distal → divided"],
    ["☐ IOC performed if indicated; results reviewed"],
    ["☐ Gallbladder dissected off cystic plate (not avulsed)"],
    ["☐ Final field check: bleeding? bile staining? clip positions?"],
    ["☐ ALL spilled stones retrieved"],
    ["☐ Retrieval bag used for specimen"],
    ["☐ Drain placed if indicated (gangrenous GB / bile spill)"],
    ["☐ Fascial defects ≥10 mm closed"],
    ["☐ Instrument and swab count confirmed correct"],
    ["☐ Post-procedure briefing with team completed"],
]

check_tbl = Table(
    [[Paragraph(r[0], sBody)] for r in checklist_data],
    colWidths=[W - 32*mm]
)
check_tbl.setStyle(TableStyle([
    ("ROWBACKGROUNDS", (0,0), (-1,-1), [C_GREEN_LT, C_WHITE]),
    ("GRID",           (0,0), (-1,-1), 0.3, C_DIVIDER),
    ("TOPPADDING",     (0,0), (-1,-1), 3),
    ("BOTTOMPADDING",  (0,0), (-1,-1), 3),
    ("LEFTPADDING",    (0,0), (-1,-1), 8),
    ("RIGHTPADDING",   (0,0), (-1,-1), 6),
]))
story.append(check_tbl)
story.append(Spacer(1, 3*mm))

# ── FOOTER / REFERENCES ───────────────────────────────────────────────────
story.append(hr(C_DIVIDER))
story.append(Paragraph(
    "<b>References:</b> Schwartz's Principles of Surgery 11e (pp. 1438–1443) · "
    "Bailey &amp; Love's Short Practice of Surgery 28e (pp. 1270–1274) · "
    "Maingot's Abdominal Operations (pp. 1014–1016) · "
    "Mulholland &amp; Greenfield's Surgery 7e (pp. 3065–3066) · "
    "Fischer's Mastery of Surgery 8e · "
    "Current Surgical Therapy 14e",
    sSmall))
story.append(Paragraph(
    "<b>Disclaimer:</b> This guide is intended as a quick intraoperative reference for qualified surgical teams and "
    "does not replace surgical judgment, institutional protocols, or applicable training. "
    "Generated by Orris Medical AI · June 2026.",
    sSmall))

# ── BUILD ──────────────────────────────────────────────────────────────────
os.makedirs(os.path.dirname(OUTPUT_PATH), exist_ok=True)
doc.build(story)
print(f"PDF generated successfully: {OUTPUT_PATH}")
Running Command

cd /home/daytona/workspace/cholecystectomy-guide && python3 build_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/cholecystectomy-guide/

Your PDF is ready for download:

Cholecystectomy Surgical Guide

PDF Document · PDF


The guide is 35 KB, A4 format, designed for intraoperative reference. Here's what's included across the pages:
SectionContent
1. IndicationsSymptomatic + prophylactic indications with notes
2. Contraindications & ConversionAbsolute CI to laparoscopic + intraoperative conversion triggers
3. Preoperative ChecklistBloods, antibiotics, DVT prophylaxis, consent items, predictors of difficult cholecystectomy
4. Laparoscopic CholecystectomyPosition, 4-port placement table, 9 numbered operative steps (color-coded), CVS alert box, bailout strategies
5. Open CholecystectomyPosition, incision options, 9 operative steps including subtotal technique
6. Intraoperative CholangiogramSelective indications + step-by-step technique
7. ComplicationsIntraoperative + postoperative tables; Strasberg BDI classification (A/B/C/D/E1–E5); BDI management protocol
8. Open vs LaparoscopicSide-by-side comparison table
9. Anatomical LandmarksCalot's triangle, Rouvière's sulcus, B-SAFE, R4U line, cystic plate, Duct of Luschka
10. Safety Checklist22-item intraoperative WHO-style checklist
This is a shared conversation. Sign in to Orris to start your own chat.