steps of harvesting fascia late graft for ear surgery
fascia lata graft harvest lateral thigh incision tympanoplasty
For ear surgery specifically, only a small segment (~1.5-2 cm x 1.5-2 cm) of this fascia is required to cover the tympanic membrane perforation. The graft is typically thinned by removing any attached fat or connective tissue and allowed to partially dry on a flat surface before placement to facilitate handling.
| Feature | Detail |
|---|---|
| Graft size needed | ~1.5-2 cm square (small compared to sling harvest) |
| Why fascia lata? | Tougher/thicker than temporalis fascia; useful for large/total perforations or when temporalis unavailable |
| Graft preparation | Defat, dry on paper/foil, trim to size |
| Alternative | Temporalis fascia (more commonly used; same region as surgical field) |
| Donor site morbidity | Numbness at lateral thigh (~lateral femoral cutaneous nerve), harvest site pain; generally well tolerated |
Create a step-by-step procedure guide (PDF) for fascia lata harvest
ls -la /tmp/workspace/ 2>/dev/null && mkdir -p /tmp/workspace/fascia-lata-guide
~/fascia-lata-guide/generate_pdf.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import cm, mm
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_LEFT, TA_CENTER, TA_JUSTIFY
from reportlab.platypus import PageBreak
from reportlab.lib.colors import HexColor, white, black
import datetime
OUTPUT = "/tmp/workspace/fascia-lata-guide/Fascia_Lata_Harvest_Procedure_Guide.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
NAVY = HexColor("#1A3A5C")
TEAL = HexColor("#1A7F8E")
LIGHT_TEAL = HexColor("#D6EFF2")
ORANGE = HexColor("#D45F00")
LIGHT_GREY = HexColor("#F4F6F8")
MID_GREY = HexColor("#9BA8B0")
DARK_GREY = HexColor("#3D4F5C")
STEP_BG = HexColor("#EAF4F6")
WARN_BG = HexColor("#FFF3E6")
WARN_BORDER = HexColor("#D45F00")
NOTE_BG = HexColor("#EDF7F0")
NOTE_BORDER = HexColor("#2A9D5C")
W, H = A4
# ── Document setup ───────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
topMargin=2.2*cm, bottomMargin=2.2*cm,
leftMargin=2.0*cm, rightMargin=2.0*cm,
title="Fascia Lata Harvest – Procedure Guide",
author="Orris Medical Reference",
subject="Surgical Procedure Guide"
)
styles = getSampleStyleSheet()
# ── Custom styles ────────────────────────────────────────────────────────────
def S(name, **kw):
return ParagraphStyle(name, **kw)
TITLE_STYLE = S("Title2",
fontName="Helvetica-Bold", fontSize=22, leading=28,
textColor=white, alignment=TA_CENTER, spaceAfter=4)
SUBTITLE_STYLE = S("Subtitle2",
fontName="Helvetica", fontSize=11, leading=15,
textColor=HexColor("#C8E8EE"), alignment=TA_CENTER, spaceAfter=2)
META_STYLE = S("Meta",
fontName="Helvetica", fontSize=8.5, leading=12,
textColor=HexColor("#C8E8EE"), alignment=TA_CENTER)
SECTION_HEADER = S("SectionHeader",
fontName="Helvetica-Bold", fontSize=13, leading=17,
textColor=white, spaceBefore=10, spaceAfter=6)
STEP_NUM = S("StepNum",
fontName="Helvetica-Bold", fontSize=11, leading=14,
textColor=TEAL)
STEP_TEXT = S("StepText",
fontName="Helvetica", fontSize=10, leading=15,
textColor=DARK_GREY, spaceAfter=2, alignment=TA_JUSTIFY)
STEP_TEXT_BOLD = S("StepTextBold",
fontName="Helvetica-Bold", fontSize=10, leading=15,
textColor=DARK_GREY)
BULLET = S("Bullet",
fontName="Helvetica", fontSize=9.5, leading=14,
textColor=DARK_GREY, leftIndent=12, spaceAfter=1)
WARN_STYLE = S("Warn",
fontName="Helvetica-BoldOblique", fontSize=9.5, leading=14,
textColor=ORANGE)
NOTE_STYLE = S("Note",
fontName="Helvetica-Oblique", fontSize=9.5, leading=14,
textColor=HexColor("#1A6B3C"))
TABLE_HEAD = S("TableHead",
fontName="Helvetica-Bold", fontSize=9, leading=12,
textColor=white, alignment=TA_CENTER)
TABLE_CELL = S("TableCell",
fontName="Helvetica", fontSize=9, leading=13,
textColor=DARK_GREY)
TABLE_CELL_B = S("TableCellB",
fontName="Helvetica-Bold", fontSize=9, leading=13,
textColor=DARK_GREY)
FOOTER_STYLE = S("Footer",
fontName="Helvetica", fontSize=7.5, leading=10,
textColor=MID_GREY, alignment=TA_CENTER)
BODY_STYLE = S("Body",
fontName="Helvetica", fontSize=10, leading=15,
textColor=DARK_GREY, alignment=TA_JUSTIFY, spaceAfter=4)
# ── Helper: section banner ───────────────────────────────────────────────────
def section_banner(text, color=TEAL):
data = [[Paragraph(text, SECTION_HEADER)]]
t = Table(data, colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING", (0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("ROUNDEDCORNERS", [4]),
]))
return t
# ── Helper: numbered step ────────────────────────────────────────────────────
def step_row(num, title, detail, substeps=None):
num_para = Paragraph(f"Step {num}", STEP_NUM)
title_para = Paragraph(f"<b>{title}</b>", STEP_TEXT_BOLD)
detail_para = Paragraph(detail, STEP_TEXT)
inner = [num_para, Spacer(1, 2), title_para, Spacer(1, 3), detail_para]
if substeps:
for s in substeps:
inner.append(Paragraph(f"• {s}", BULLET))
inner_table = Table([[item] for item in inner], colWidths=[doc.width - 2.4*cm])
inner_table.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 1),
("BOTTOMPADDING", (0,0), (-1,-1), 1),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
]))
num_block = Table([[Paragraph(str(num), S("N",
fontName="Helvetica-Bold", fontSize=14, leading=18,
textColor=white, alignment=TA_CENTER))]],
colWidths=[1.4*cm], rowHeights=[1.4*cm])
num_block.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 0),
("RIGHTPADDING", (0,0), (-1,-1), 0),
("ALIGN", (0,0), (-1,-1), "CENTER"),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
outer = Table([[num_block, inner_table]],
colWidths=[1.6*cm, doc.width - 1.6*cm])
outer.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), STEP_BG),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING", (0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 4),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
("LINEBELOW", (0,0), (-1,-1), 0.5, HexColor("#C8D8DC")),
]))
return outer
# ── Helper: warning box ──────────────────────────────────────────────────────
def warning_box(text):
data = [[Paragraph(f"⚠ {text}", WARN_STYLE)]]
t = Table(data, colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), WARN_BG),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("LINEAFTER", (0,0), (0,-1), 3, WARN_BORDER),
("LINEBEFORE", (0,0), (0,-1), 3, WARN_BORDER),
]))
return t
# ── Helper: note box ─────────────────────────────────────────────────────────
def note_box(text):
data = [[Paragraph(f"ℹ {text}", NOTE_STYLE)]]
t = Table(data, colWidths=[doc.width])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NOTE_BG),
("TOPPADDING", (0,0), (-1,-1), 7),
("BOTTOMPADDING",(0,0), (-1,-1), 7),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
("LINEBEFORE", (0,0), (0,-1), 3, NOTE_BORDER),
]))
return t
# ── Page numbering ────────────────────────────────────────────────────────────
def add_page_number(canvas, doc):
canvas.saveState()
canvas.setFont("Helvetica", 8)
canvas.setFillColor(MID_GREY)
page_num = canvas.getPageNumber()
text = f"Page {page_num} | Fascia Lata Harvest – Procedure Guide | For educational purposes only"
canvas.drawCentredString(W / 2, 1.2*cm, text)
# header line
canvas.setStrokeColor(TEAL)
canvas.setLineWidth(1.5)
canvas.line(2.0*cm, H - 1.5*cm, W - 2.0*cm, H - 1.5*cm)
canvas.restoreState()
# ═══════════════════════════════════════════════════════════════════════════════
# BUILD STORY
# ═══════════════════════════════════════════════════════════════════════════════
story = []
# ── COVER HEADER ────────────────────────────────────────────────────────────
header_data = [[
Paragraph("FASCIA LATA HARVEST", TITLE_STYLE),
], [
Paragraph("Step-by-Step Surgical Procedure Guide", SUBTITLE_STYLE),
], [
Paragraph("For Ear Surgery (Tympanoplasty / Myringoplasty) & Related Procedures", SUBTITLE_STYLE),
], [
Paragraph(f"Orris Medical Reference | {datetime.date.today().strftime('%B %Y')}", META_STYLE),
]]
header_table = Table(header_data, colWidths=[doc.width])
header_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), NAVY),
("TOPPADDING", (0,0), (0,0), 18),
("BOTTOMPADDING", (0,-1),(-1,-1), 16),
("TOPPADDING", (0,1), (-1,-1), 3),
("BOTTOMPADDING", (0,0), (-1,-2), 3),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
]))
story.append(header_table)
story.append(Spacer(1, 0.5*cm))
# ── OVERVIEW BOX ────────────────────────────────────────────────────────────
overview_text = (
"Fascia lata is the deep investing fascia of the lateral thigh, running from the "
"greater trochanter proximally to the lateral femoral condyle distally along the iliotibial band. "
"First described by Zollner (1956) for tympanic membrane repair, it provides a tough, flat, "
"avascular graft suitable for large or total perforations. It is used when temporalis fascia "
"is unavailable (revision cases, endoscopic approaches) or when an exceptionally sturdy graft is required."
)
overview_data = [[Paragraph(overview_text, BODY_STYLE)]]
overview_table = Table(overview_data, colWidths=[doc.width])
overview_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
("LINEAFTER", (0,0), (0,-1), 4, TEAL),
("LINEBEFORE", (0,0), (0,-1), 4, TEAL),
]))
story.append(overview_table)
story.append(Spacer(1, 0.5*cm))
# ── EQUIPMENT TABLE ──────────────────────────────────────────────────────────
story.append(section_banner("Equipment & Instruments Required"))
story.append(Spacer(1, 0.3*cm))
eq_headers = [
Paragraph("Item", TABLE_HEAD),
Paragraph("Specification / Notes", TABLE_HEAD),
]
eq_rows = [
["Scalpel + Blades", "No. 15 blade (skin incision); No. 10 for deeper tissue"],
["Metzenbaum scissors", "Fine-tip, curved – subcutaneous dissection"],
["Right-angle clamp", "3–4 cm reach for grasping distal fascial edge"],
["Crawford fascial stripper", "For percutaneous/small-incision strip harvest"],
["Malleable retractor (thin)", "Passed superficially and deep to fascia"],
["PDS sutures (No. 1)", "Two per graft – secure each free end"],
["Saline bowl", "Graft storage until needed"],
["Self-retaining retractor", "Skin edge retraction"],
["Electrocautery / bipolar", "Haemostasis of subcutaneous vessels"],
["Compressive bandage", "Applied post-closure; left 8 h"],
["Marking pen", "Incision site and graft dimensions"],
["Sterile ruler", "Confirm graft dimensions"],
]
eq_table_data = [eq_headers]
for row in eq_rows:
eq_table_data.append([
Paragraph(row[0], TABLE_CELL_B),
Paragraph(row[1], TABLE_CELL),
])
eq_table = Table(eq_table_data, colWidths=[5.5*cm, doc.width - 5.5*cm])
eq_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("BACKGROUND", (0,1), (-1,-1), white),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, LIGHT_GREY]),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#C0CCCC")),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(eq_table)
story.append(Spacer(1, 0.5*cm))
# ── PHASE 1: PREPARATION ──────────────────────────────────────────────────────
story.append(section_banner("Phase 1 – Patient Positioning & Preparation", color=NAVY))
story.append(Spacer(1, 0.3*cm))
story.append(KeepTogether([
step_row(1, "Limb Selection",
"Choose the ipsilateral lateral thigh (or either leg). The anterolateral thigh provides "
"the iliotibial band and fascia lata – a wide, flat aponeurotic sheet ideal for grafting.",
["Either leg is acceptable; some surgeons prefer ipsilateral to ease two-team approach",
"Ensure no prior incisions, scarring, or infection at the donor site"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(2, "Position & Secure the Extremity",
"Elevate and support the knee slightly (e.g., 1-L IV bag or padded bolster under the knee). "
"Internally rotate the hip and secure the limb to the table with 3-inch tape below the operative site.",
["Ensure IPC device is placed below the patella on the harvest side before securing",
"Correct internal rotation exposes the anterolateral surface optimally"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(3, "Prep & Drape",
"Prep the anterolateral thigh from greater trochanter (proximal) to patella (distal). "
"Drape to expose this entire corridor.",
["Use standard iodine or chlorhexidine prep per institutional protocol",
"Maintain a wide sterile field – the stripper will travel proximally"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(4, "Identify & Mark Landmarks",
"Palpate and mark the greater trochanter and the lateral femoral condyle – "
"the proximal and distal attachments of the fascia lata along the iliotibial band.",
["These landmarks define the course of the graft strip",
"Mark the planned incision just above the patella over the iliotibial band",
"For ear surgery a small piece (~2 x 2 cm) suffices; plan a proportionally smaller harvest"]),
Spacer(1, 4),
]))
story.append(warning_box(
"CAUTION: Lateral femoral cutaneous nerve runs near the harvest site. "
"Avoid wide medial dissection to reduce risk of numbness along the lateral thigh."
))
story.append(Spacer(1, 0.5*cm))
# ── PHASE 2: INCISION ─────────────────────────────────────────────────────────
story.append(section_banner("Phase 2 – Skin Incision & Exposure", color=NAVY))
story.append(Spacer(1, 0.3*cm))
story.append(KeepTogether([
step_row(5, "Skin Incision",
"Make a 3-cm longitudinal incision beginning just above the patella, centered over the "
"iliotibial band (lateral aspect of the distal thigh).",
["Use a No. 15 blade for a clean, controlled cut",
"For a full-length strip with the Crawford stripper, a single 3-cm incision is sufficient",
"Larger open incision (5–7 cm) may be needed if stripper is not available"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(6, "Subcutaneous Dissection",
"Deepen the incision through subcutaneous fat using Metzenbaum scissors or electrocautery. "
"Achieve haemostasis of any superficial vessels before proceeding.",
["Dissect bluntly to avoid inadvertent fascial cuts",
"Identify the glistening white fascia lata once fat is cleared",
"Retract skin edges with a self-retaining retractor"]),
Spacer(1, 4),
]))
story.append(Spacer(1, 0.5*cm))
# ── PHASE 3: HARVEST ─────────────────────────────────────────────────────────
story.append(section_banner("Phase 3 – Graft Harvest", color=NAVY))
story.append(Spacer(1, 0.3*cm))
story.append(KeepTogether([
step_row(7, "Mark the Fascial Strip",
"On the exposed fascia lata, mark two parallel longitudinal lines 2 cm apart "
"using a marking pen. For ear surgery, a smaller width (1–1.5 cm) is adequate.",
["Confirm the required graft size for the perforation before making fascial incisions",
"For tympanoplasty: ~2 x 2 cm piece is typically sufficient",
"For sling/reconstructive procedures: full strip 2 cm x 8–20 cm"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(8, "Make Parallel Fascial Incisions",
"Incise the fascia along both marked lines with a scalpel or scissors, "
"staying parallel and the correct distance apart for the required graft width.",
["Incise only the fascia – do not cut into underlying muscle",
"Confirm both incision lines are full-thickness through fascia"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(9, "Free the Distal End",
"Bluntly lift the distal fascial strip off the underlying muscle belly. "
"Grasp the free distal edge with a right-angle clamp as far distally as possible (3–4 cm).",
["Transect the distal end sharply to create one free edge",
"Immediately secure the free distal end with a No. 1 PDS suture (tagged)"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(10, "Elevate Proximally with Retractor",
"Place a thin malleable retractor deep and superficial to the fascia strip. "
"Holding the distal end under gentle tension, use the retractor to strip the fascia "
"off the muscle belly while separating it from both adipose tissue and muscle fibers.",
["Maintain constant gentle tension on the distal suture tag",
"Separate fat from superficial surface and muscle fibers from deep surface",
"Advance carefully to avoid tearing the strip"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(11, "Proximal Division with Crawford Stripper",
"With the distal end under tension and the strip elevated, insert the Crawford fascial stripper "
"over the strip and advance it proximally. The stripper extends the fascial incision and divides "
"it before removal in a single pass.",
["Classic full-length harvest: 20 cm x 2 cm strip",
"Modern shorter harvest: 8 cm is commonly sufficient",
"For ear surgery: harvest only what is needed (~2–3 cm length)"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(12, "Secure Proximal End & Remove Graft",
"After proximal division, immediately place a second No. 1 PDS suture on the proximal free end. "
"Transfer the graft to a saline-filled bowl until needed.",
["Keep graft moist at all times",
"Tag both ends with labelled sutures if orientation matters",
"For tympanoplasty: trim to required size, defat carefully, and allow to semi-dry on a flat surface"]),
Spacer(1, 4),
]))
story.append(note_box(
"For ear surgery: trim the graft to ~2 x 2 cm, remove any attached fat with fine scissors, "
"and allow it to partially dry on a clean flat surface (e.g., a sterile cotton patty or foil) "
"for 5–10 minutes. This stiffens it slightly and makes placement under the tympanic membrane easier."
))
story.append(Spacer(1, 0.5*cm))
# ── PHASE 4: CLOSURE ─────────────────────────────────────────────────────────
story.append(section_banner("Phase 4 – Haemostasis & Wound Closure", color=NAVY))
story.append(Spacer(1, 0.3*cm))
story.append(KeepTogether([
step_row(13, "Immediate Compression & Haemostasis",
"Apply immediate digital compression to the thigh at the harvest site to constrict "
"perforating vessels.",
["Carefully evaluate the wound for any arterial bleeding",
"Achieve haemostasis with bipolar or suture ligation before closure",
"Do NOT attempt to close the fascia lata itself – this risks excessive tension"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(14, "Wound Irrigation",
"Irrigate the wound thoroughly with warm normal saline or dilute antiseptic solution "
"to clear any debris, fat, and small clots.",
["Confirm haemostasis after irrigation under direct vision"]),
Spacer(1, 4),
]))
story.append(KeepTogether([
step_row(15, "Three-Layer Wound Closure",
"Close the wound in three layers – do NOT close the fascia lata (this is intentional).",
["Layer 1 – Deep subcutaneous: interrupted absorbable sutures (e.g., 2-0 Vicryl)",
"Layer 2 – Superficial subcutaneous: interrupted or running absorbable sutures",
"Layer 3 – Skin: interrupted non-absorbable sutures or staples",
"IMPORTANT: The fascial defect is left open to prevent compartment syndrome"]),
Spacer(1, 4),
]))
story.append(warning_box(
"DO NOT close the fascia lata. Fascial closure risks increased compartment pressure. "
"Close only the subcutaneous layers and skin."
))
story.append(Spacer(1, 0.3*cm))
story.append(KeepTogether([
step_row(16, "Compressive Dressing",
"Apply a firm compressive bandage/wrap to the entire thigh at the completion of thigh closure. "
"Replace the IPC device over the bandage.",
["Compressive wrap reduces haematoma formation",
"Leave in place for 8 hours postoperatively",
"Encourage early ambulation after the pressure dressing is removed"]),
Spacer(1, 4),
]))
story.append(Spacer(1, 0.5*cm))
# ── GRAFT PREP FOR EAR ───────────────────────────────────────────────────────
story.append(section_banner("Graft Preparation Specific to Ear Surgery", color=ORANGE))
story.append(Spacer(1, 0.3*cm))
prep_steps = [
("Trim to size", "Cut the harvested fascia to approximately 2 x 2 cm (or slightly larger than the perforation)."),
("Remove fat", "Use fine scissors to carefully remove all attached fat from both surfaces. The graft should be uniformly thin and translucent."),
("Dry the graft", "Place on a sterile cotton patty or foil and allow to semi-dry for 5–10 min. This gives it slight rigidity, making placement easier."),
("Underlay vs. overlay", "Fascia lata is most commonly used as an underlay graft (medial to the tympanic membrane remnant). Trim edges to ensure a 2–3 mm overlap all around the perforation margin."),
("Graft placement", "Position the graft medial to the handle of malleus and tympanic membrane remnants. Gelfoam support may be placed in the middle ear to support the graft."),
]
for i, (title, detail) in enumerate(prep_steps, 1):
data = [[
Paragraph(f"{i}. {title}", TABLE_CELL_B),
Paragraph(detail, TABLE_CELL),
]]
t = Table(data, colWidths=[4.5*cm, doc.width - 4.5*cm])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), WARN_BG),
("BACKGROUND", (1,0), (1,-1), white if i % 2 else LIGHT_GREY),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#DDCCCC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(t)
story.append(Spacer(1, 0.5*cm))
# ── COMPLICATIONS TABLE ───────────────────────────────────────────────────────
story.append(section_banner("Potential Complications & Management", color=NAVY))
story.append(Spacer(1, 0.3*cm))
comp_headers = [
Paragraph("Complication", TABLE_HEAD),
Paragraph("Incidence", TABLE_HEAD),
Paragraph("Prevention / Management", TABLE_HEAD),
]
comp_rows = [
["Lateral thigh numbness", "~7–10%", "Avoid medial dissection; usually resolves spontaneously"],
["Harvest site haematoma", "Uncommon", "Thorough haemostasis; compressive dressing x 8 h"],
["Harvest site pain/tendinitis", "~5–7%", "Analgesics; early ambulation; physiotherapy if persistent"],
["Wound infection", "Rare", "Aseptic technique; standard antibiotic prophylaxis"],
["Graft failure (ear)", "Variable", "Adequate graft size; proper underlay technique; dry ear pre-op"],
["Lateral femoral cutaneous nerve injury", "Low", "Keep incision at distal thigh; blunt dissection medially"],
["Thigh compartment syndrome", "Extremely rare", "DO NOT close fascia lata; compressive bandage only"],
]
comp_data = [comp_headers]
for row in comp_rows:
comp_data.append([Paragraph(c, TABLE_CELL) for c in row])
comp_table = Table(comp_data, colWidths=[4.8*cm, 2.5*cm, doc.width - 7.3*cm])
comp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), NAVY),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, LIGHT_GREY]),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#B0C0CC")),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(comp_table)
story.append(Spacer(1, 0.5*cm))
# ── POSTOP CARE ──────────────────────────────────────────────────────────────
story.append(section_banner("Postoperative Care – Donor Site", color=TEAL))
story.append(Spacer(1, 0.3*cm))
postop_items = [
("Compressive bandage", "Leave in place for 8 hours; then remove and reassess."),
("DVT prophylaxis", "IPC devices + pharmacological prophylaxis per risk stratification (low-dose LMWH or UFH if indicated)."),
("Ambulation", "Encourage early ambulation as soon as anaesthetic allows – ideally within hours of surgery."),
("Wound check", "Inspect at 48–72 hours; ensure no haematoma, signs of infection, or compartment symptoms."),
("Analgesia", "Simple analgesia (paracetamol ± NSAID) is usually sufficient. Opioids rarely required."),
("Suture removal", "Non-absorbable skin sutures or staples removed at 10–14 days."),
("Activity restriction", "Avoid heavy leg exertion for 2 weeks. Return to normal activity thereafter."),
]
for item in postop_items:
data = [[Paragraph(item[0], TABLE_CELL_B), Paragraph(item[1], TABLE_CELL)]]
t = Table(data, colWidths=[4.5*cm, doc.width - 4.5*cm])
t.setStyle(TableStyle([
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#C0CCCC")),
("VALIGN", (0,0), (-1,-1), "TOP"),
("BACKGROUND", (0,0), (0,-1), LIGHT_TEAL),
]))
story.append(t)
story.append(Spacer(1, 0.5*cm))
# ── FASCIA LATA vs. TEMPORALIS COMPARISON ────────────────────────────────────
story.append(section_banner("Fascia Lata vs. Temporalis Fascia – Quick Comparison", color=TEAL))
story.append(Spacer(1, 0.3*cm))
cmp_headers = [
Paragraph("Feature", TABLE_HEAD),
Paragraph("Fascia Lata", TABLE_HEAD),
Paragraph("Temporalis Fascia", TABLE_HEAD),
]
cmp_rows = [
["First use in ear surgery", "Zollner, 1956", "Heerman, 1958"],
["Harvest site", "Lateral thigh", "Temporal region (same surgical field)"],
["Thickness", "Thicker & tougher", "Thinner, more pliable"],
["Two-team harvest", "Yes (simultaneous)", "No (same field)"],
["Graft size", "Larger pieces available", "Limited by temporal area"],
["Best indication", "Large/total perforation, revision, no local fascia", "Most tympanoplasties (first choice)"],
["Donor site morbidity", "Thigh numbness, pain, rare tendinitis", "Minimal; small temporal scar"],
]
cmp_data = [cmp_headers]
for row in cmp_rows:
cmp_data.append([Paragraph(c, TABLE_CELL) for c in row])
cmp_table = Table(cmp_data, colWidths=[4.5*cm, (doc.width-4.5*cm)/2, (doc.width-4.5*cm)/2])
cmp_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [white, LIGHT_GREY]),
("GRID", (0,0), (-1,-1), 0.4, HexColor("#B0C0CC")),
("TOPPADDING", (0,0), (-1,-1), 6),
("BOTTOMPADDING", (0,0), (-1,-1), 6),
("LEFTPADDING", (0,0), (-1,-1), 7),
("RIGHTPADDING", (0,0), (-1,-1), 7),
("VALIGN", (0,0), (-1,-1), "TOP"),
]))
story.append(cmp_table)
story.append(Spacer(1, 0.5*cm))
# ── REFERENCES ────────────────────────────────────────────────────────────────
story.append(HRFlowable(width="100%", thickness=1, color=TEAL, spaceAfter=8))
story.append(Paragraph("References & Sources", S("RefHead",
fontName="Helvetica-Bold", fontSize=10, leading=14, textColor=NAVY, spaceAfter=4)))
refs = [
"Campbell-Walsh-Wein Urology (11th Ed). Chapter 125: Pubovaginal Sling – Graft Harvest for Autologous Pubovaginal Sling, pp. 3744–3746.",
"Hinman's Atlas of Urologic Surgery (4th Ed). Chapter 98: Retropubic Component – Alternative Fascial Harvest Technique, p. 757.",
"Scott-Brown's Otorhinolaryngology Head & Neck Surgery – Vol 2. History of Tympanoplasty, p. 1065.",
"Zollner F. (1956). First description of fascia lata as a tympanoplasty graft material.",
"Dwyer PL, Kreder KJ. (2008). Surgical approaches to the pelvic floor. Surgical techniques.",
"Karam AK, Bhatia NN. (1990). Modifications in fascia lata harvest technique.",
"For educational purposes only. Always refer to current institutional protocols and supervising surgeon guidance.",
]
for r in refs:
story.append(Paragraph(f"• {r}", S("Ref",
fontName="Helvetica", fontSize=8.5, leading=13, textColor=DARK_GREY,
leftIndent=8, spaceAfter=3)))
# ── BUILD ─────────────────────────────────────────────────────────────────────
doc.build(story, onFirstPage=add_page_number, onLaterPages=add_page_number)
print(f"PDF generated: {OUTPUT}")
cd /tmp/workspace/fascia-lata-guide && python generate_pdf.py 2>&1
ls -lh /tmp/workspace/fascia-lata-guide/
Fascia Lata Harvest Procedure Guide
PDF Document · PDF