Types of skin graft
| Type | Source | Notes |
|---|---|---|
| Autograft | Same individual | Gold standard; no rejection |
| Allograft (homograft) | Another human (cadaveric) | Temporary; eventually rejected |
| Xenograft (heterograft) | Different species (e.g., pig) | Temporary biological dressing |
| Synthetic/dermal substitutes | Manufactured (e.g., Integra, MatriDerm) | Require a well-vascularised bed; usually need a secondary STSG |

| Grade | Thickness |
|---|---|
| Thin | 0.005 - 0.010 inch |
| Medium | ~0.010 - 0.015 inch |
| Thick | >0.015 inch |

| Property | FTSG | STSG | Composite |
|---|---|---|---|
| Tissue match | Good to excellent | Poor to fair | Good |
| Nutritional requirements | High | Low | High |
| Vascularity requirement | High | Low | Very high |
| Contraction risk | Low | High | Low |
| Durability | Good to excellent | Fair to good | Fair |
| Sensation | Good | Fair | Fair |
| Adnexal functions | Excellent | Poor | Good |
| Graft | Typical Donor Site | Donor Site Healing |
|---|---|---|
| Thin STSG | Thigh, scalp | Secondary intention (~2 weeks) |
| Thick STSG | Thigh, back | Secondary intention (slower) |
| FTSG | Post-auricular, groin crease, supraclavicular | Primary closure |
| Composite | Ear helical root | May need flap or complex closure |
Can you create a pdf of types of skin grafts
ls -la /tmp/workspace/ 2>/dev/null || mkdir -p /tmp/workspace && echo "created"
mkdir -p /tmp/workspace/skin-graft-pdf && python3 -c "import reportlab; print('reportlab ok')"
~/skin-graft-pdf/generate_pdf.py
import urllib.request
import os
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, Image, KeepTogether
)
from reportlab.platypus.flowables import HRFlowable
from reportlab.graphics.shapes import Drawing, Rect, String, Line
from reportlab.graphics import renderPDF
OUTPUT = "/tmp/workspace/skin-graft-pdf/Types_of_Skin_Graft.pdf"
# ── Download diagrams ─────────────────────────────────────────────────────────
img_dir = "/tmp/workspace/skin-graft-pdf/imgs"
os.makedirs(img_dir, exist_ok=True)
imgs = {
"anatomy": "https://cdn.orris.care/cdss_images/f959600fd7372d62892ac2eca8898e07c0d5dcfd5f87fa99215a86e92c88e54a.png",
"cross": "https://cdn.orris.care/cdss_images/4ba1b93738d679554068854c6cd0cdf895ef4c3a0df2b509da7aa270b0e4154c.png",
}
for name, url in imgs.items():
path = os.path.join(img_dir, f"{name}.png")
if not os.path.exists(path):
try:
urllib.request.urlretrieve(url, path)
print(f"Downloaded {name}")
except Exception as e:
print(f"Failed {name}: {e}")
# ── Colour palette ────────────────────────────────────────────────────────────
TEAL = colors.HexColor("#1A6B72")
LIGHT_TEAL = colors.HexColor("#E8F5F6")
DARK_TEAL = colors.HexColor("#0D4A50")
GOLD = colors.HexColor("#C8861A")
LIGHT_GOLD = colors.HexColor("#FDF3E0")
GREY_LIGHT = colors.HexColor("#F5F5F5")
GREY_MED = colors.HexColor("#CCCCCC")
DARK_GREY = colors.HexColor("#333333")
WHITE = colors.white
RED_SOFT = colors.HexColor("#C0392B")
GREEN_SOFT = colors.HexColor("#27AE60")
# ── Document setup ────────────────────────────────────────────────────────────
doc = SimpleDocTemplate(
OUTPUT,
pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.5*cm, bottomMargin=2.5*cm,
title="Types of Skin Graft",
author="Orris Medical Reference",
)
W = A4[0] - 4*cm # usable width
# ── Styles ────────────────────────────────────────────────────────────────────
base = getSampleStyleSheet()
def S(name, **kw):
return ParagraphStyle(name, **kw)
title_style = S("Title",
fontName="Helvetica-Bold", fontSize=22, textColor=WHITE,
alignment=TA_CENTER, spaceAfter=4)
subtitle_style = S("Subtitle",
fontName="Helvetica", fontSize=11, textColor=LIGHT_TEAL,
alignment=TA_CENTER, spaceAfter=6)
h1 = S("H1",
fontName="Helvetica-Bold", fontSize=13, textColor=DARK_TEAL,
spaceBefore=14, spaceAfter=4, borderPad=4)
h2 = S("H2",
fontName="Helvetica-Bold", fontSize=11, textColor=TEAL,
spaceBefore=10, spaceAfter=3)
body = S("Body",
fontName="Helvetica", fontSize=9.5, textColor=DARK_GREY,
leading=14, spaceAfter=4, alignment=TA_JUSTIFY)
bullet = S("Bullet",
fontName="Helvetica", fontSize=9.5, textColor=DARK_GREY,
leading=13, leftIndent=12, bulletIndent=0, spaceAfter=2)
note = S("Note",
fontName="Helvetica-Oblique", fontSize=8.5, textColor=colors.HexColor("#666666"),
leading=12, spaceAfter=4, alignment=TA_CENTER)
caption = S("Caption",
fontName="Helvetica-Oblique", fontSize=8, textColor=colors.HexColor("#555555"),
alignment=TA_CENTER, spaceAfter=6)
table_header = S("TH",
fontName="Helvetica-Bold", fontSize=8.5, textColor=WHITE,
alignment=TA_CENTER, leading=11)
table_cell = S("TC",
fontName="Helvetica", fontSize=8.5, textColor=DARK_GREY,
alignment=TA_CENTER, leading=11)
table_cell_l = S("TCL",
fontName="Helvetica", fontSize=8.5, textColor=DARK_GREY,
alignment=TA_LEFT, leading=11)
adv_style = S("Adv",
fontName="Helvetica", fontSize=9, textColor=colors.HexColor("#1A5C1A"),
leading=13, leftIndent=10, spaceAfter=2)
dis_style = S("Dis",
fontName="Helvetica", fontSize=9, textColor=RED_SOFT,
leading=13, leftIndent=10, spaceAfter=2)
# ── Helper flowables ──────────────────────────────────────────────────────────
def hr(color=GREY_MED, thickness=0.5):
return HRFlowable(width="100%", thickness=thickness, color=color, spaceAfter=4, spaceBefore=4)
def section_banner(text, color=TEAL, text_color=WHITE):
"""A coloured banner row acting as a section header."""
t = Table([[Paragraph(text, S("BannerText",
fontName="Helvetica-Bold", fontSize=12, textColor=text_color, leading=14))]],
colWidths=[W])
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),
]))
return t
def info_box(text, bg=LIGHT_TEAL, border=TEAL):
t = Table([[Paragraph(text, S("IB",
fontName="Helvetica", fontSize=9.5, textColor=DARK_GREY, leading=14))]], colWidths=[W])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1, border),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING",(0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
return t
def two_col_adv_dis(advantages, disadvantages):
"""Side-by-side advantages / disadvantages table."""
adv_items = "\n".join([f"• {a}" for a in advantages])
dis_items = "\n".join([f"• {d}" for d in disadvantages])
adv_p = Paragraph(
"<b><font color='#1A5C1A'>✔ Advantages</font></b><br/>" +
"<br/>".join([f"<font color='#1A5C1A'>• {a}</font>" for a in advantages]),
S("AdvBox", fontName="Helvetica", fontSize=9, textColor=DARK_GREY, leading=13))
dis_p = Paragraph(
"<b><font color='#C0392B'>✘ Disadvantages</font></b><br/>" +
"<br/>".join([f"<font color='#C0392B'>• {d}</font>" for d in disadvantages]),
S("DisBox", fontName="Helvetica", fontSize=9, textColor=DARK_GREY, leading=13))
col = (W - 0.4*cm) / 2
t = Table([[adv_p, dis_p]], colWidths=[col, col], hAlign="LEFT")
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (0,-1), colors.HexColor("#EAF7EA")),
("BACKGROUND", (1,0), (1,-1), colors.HexColor("#FDECEA")),
("BOX", (0,0), (0,-1), 0.5, GREEN_SOFT),
("BOX", (1,0), (1,-1), 0.5, RED_SOFT),
("TOPPADDING", (0,0), (-1,-1), 8),
("BOTTOMPADDING",(0,0), (-1,-1), 8),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("VALIGN", (0,0), (-1,-1), "TOP"),
("COLPADDING", (0,0), (-1,-1), 4),
]))
return t
# ── Content builder ───────────────────────────────────────────────────────────
story = []
# ─── Cover banner ─────────────────────────────────────────────────────────────
cover = Table(
[[Paragraph("TYPES OF SKIN GRAFT", title_style)],
[Paragraph("A Comprehensive Surgical Reference", subtitle_style)],
[Paragraph("Sources: Bailey & Love's Surgery 28e | Pfenninger & Fowler's Primary Care | Fischer's Mastery of Surgery | Dermatology 5e", note)]],
colWidths=[W]
)
cover.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 12),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 14),
("RIGHTPADDING", (0,0), (-1,-1), 14),
]))
story.append(cover)
story.append(Spacer(1, 0.5*cm))
# ─── Definition box ───────────────────────────────────────────────────────────
story.append(info_box(
"<b>Definition:</b> A skin graft is tissue transferred from a donor site to a recipient wound "
"<b>without bringing its own blood supply</b>. It depends entirely on the vascularity of the "
"recipient bed for 'take' (revascularisation). Graft failure occurs from shear forces, "
"haematoma/seroma formation, or infection (notably beta-haemolytic streptococci, staphylococci, Pseudomonas)."
))
story.append(Spacer(1, 0.35*cm))
# ─── Classification by donor source ───────────────────────────────────────────
story.append(section_banner("1. CLASSIFICATION BY DONOR SOURCE"))
story.append(Spacer(1, 0.2*cm))
donor_data = [
[Paragraph("<b>Type</b>", table_header), Paragraph("<b>Source</b>", table_header),
Paragraph("<b>Key Notes</b>", table_header)],
[Paragraph("Autograft", table_cell), Paragraph("Same individual", table_cell_l),
Paragraph("Gold standard — no rejection risk", table_cell_l)],
[Paragraph("Allograft (Homograft)", table_cell), Paragraph("Cadaveric human donor", table_cell_l),
Paragraph("Temporary; eventually rejected by immune system", table_cell_l)],
[Paragraph("Xenograft (Heterograft)", table_cell), Paragraph("Different species (e.g., pig)", table_cell_l),
Paragraph("Temporary biological dressing only", table_cell_l)],
[Paragraph("Synthetic / Dermal Substitute", table_cell), Paragraph("Manufactured (e.g., Integra, MatriDerm, BTM)", table_cell_l),
Paragraph("Requires well-vascularised bed; usually needs secondary STSG", table_cell_l)],
]
col_w = [3.8*cm, 4.5*cm, W - 8.3*cm]
dt = Table(donor_data, colWidths=col_w)
dt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("BACKGROUND", (0,1), (-1,1), GREY_LIGHT),
("BACKGROUND", (0,2), (-1,2), WHITE),
("BACKGROUND", (0,3), (-1,3), GREY_LIGHT),
("BACKGROUND", (0,4), (-1,4), WHITE),
("ROWBACKGROUNDS",(0,1), (-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.5, GREY_MED),
("INNERGRID", (0,0), (-1,-1), 0.3, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(dt)
story.append(Spacer(1, 0.4*cm))
# ─── Classification by thickness heading ──────────────────────────────────────
story.append(section_banner("2. CLASSIFICATION BY THICKNESS (PRIMARY SURGICAL CLASSIFICATION)"))
story.append(Spacer(1, 0.2*cm))
# Diagrams
anatomy_path = os.path.join(img_dir, "anatomy.png")
cross_path = os.path.join(img_dir, "cross.png")
if os.path.exists(anatomy_path) and os.path.exists(cross_path):
img1 = Image(anatomy_path, width=8*cm, height=7*cm, kind="proportional")
img2 = Image(cross_path, width=6*cm, height=7*cm, kind="proportional")
cap1 = Paragraph("Fig 1. Skin anatomy and harvesting depths<br/><i>(Bailey & Love's 28e)</i>", caption)
cap2 = Paragraph("Fig 2. STSG vs FTSG cross-section<br/><i>(Pfenninger & Fowler's)</i>", caption)
img_table = Table([[img1, img2]], colWidths=[W*0.55, W*0.45])
cap_table = Table([[cap1, cap2]], colWidths=[W*0.55, W*0.45])
img_table.setStyle(TableStyle([
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("ALIGN", (0,0), (-1,-1), "CENTER"),
]))
cap_table.setStyle(TableStyle([
("ALIGN", (0,0), (-1,-1), "CENTER"),
]))
story.append(img_table)
story.append(cap_table)
story.append(Spacer(1, 0.3*cm))
# ─── STSG ─────────────────────────────────────────────────────────────────────
story.append(KeepTogether([
section_banner("A. SPLIT-THICKNESS SKIN GRAFT (STSG / Thiersch Graft)", color=DARK_TEAL),
Spacer(1, 0.15*cm),
info_box(
"<b>Composition:</b> Epidermis + a variable portion of dermis (not full dermis). "
"Remaining dermis at donor site regenerates spontaneously.<br/>"
"<b>Harvesting:</b> Electric/battery dermatome at 45-60° with even pressure. "
"Common donor sites: thigh, scalp. Dermatome at 0.2-0.3 mm (0.014-0.016 inch). "
"After harvest, donor site shows light punctuate bleeding (papillary dermis only - "
"fat lobules must NOT be visible).",
bg=LIGHT_TEAL, border=TEAL),
Spacer(1, 0.2*cm),
]))
# Sub-grades
grade_data = [
[Paragraph("<b>Grade</b>", table_header), Paragraph("<b>Thickness</b>", table_header),
Paragraph("<b>Key Property</b>", table_header)],
[Paragraph("Thin", table_cell), Paragraph("0.005 - 0.010 inch", table_cell),
Paragraph("Fastest vascularisation; heals rapidly; poor cosmesis", table_cell_l)],
[Paragraph("Medium", table_cell), Paragraph("0.010 - 0.015 inch", table_cell),
Paragraph("Balance of take rate and cosmetic appearance", table_cell_l)],
[Paragraph("Thick", table_cell), Paragraph("> 0.015 inch", table_cell),
Paragraph("Better cosmesis and wear resistance; slower healing", table_cell_l)],
]
gt = Table(grade_data, colWidths=[3*cm, 4*cm, W - 7*cm])
gt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), DARK_TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.5, GREY_MED),
("INNERGRID", (0,0), (-1,-1), 0.3, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(Paragraph("Sub-grades by thickness:", h2))
story.append(gt)
story.append(Spacer(1, 0.2*cm))
story.append(Paragraph("Meshing:", h2))
story.append(info_box(
"STSGs can be <b>meshed</b> or <b>pie-crusted</b> (small slits cut into the graft) to expand "
"coverage by 1.5x to 9x (ratios 1:1.5, 1:2, 1:3, 1:6, 1:9). Meshing allows drainage of blood/serum "
"and improves graft 'take' over large defects such as burns.",
bg=LIGHT_GOLD, border=GOLD))
story.append(Spacer(1, 0.2*cm))
story.append(two_col_adv_dis(
advantages=[
"Can cover large areas; can be meshed for greater expansion",
"Requires less recipient-bed vascularity",
"Donor site heals by secondary intention (~2 weeks)",
"Thin grafts vascularize quickly",
"Can act as a 'window' for tumour recurrence surveillance",
],
disadvantages=[
"High contraction risk — avoid over joints",
"Poor cosmetic match (colour, texture, hair growth)",
"Mesh pattern permanent — avoid face/anterior neck",
"Less durable; prone to friction injury",
"Will not grow over bone without periosteum",
"Requires a dermatome; operating suite for large grafts",
]
))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph(
"<b>Best for:</b> Large wounds, burns, trauma reconstruction, high-risk tumour sites.",
S("Pref", fontName="Helvetica-BoldOblique", fontSize=9.5,
textColor=DARK_TEAL, spaceAfter=6)))
story.append(Spacer(1, 0.3*cm))
# ─── FTSG ─────────────────────────────────────────────────────────────────────
story.append(KeepTogether([
section_banner("B. FULL-THICKNESS SKIN GRAFT (FTSG / Wolfe Graft)", color=colors.HexColor("#5B2C6F")),
Spacer(1, 0.15*cm),
info_box(
"<b>Composition:</b> Epidermis + entire dermis. Retains dermal elasticity, minimal contracture. "
"Harvested by sharp scalpel dissection. Donor site must be <b>primarily closed</b>, limiting graft size.<br/>"
"<b>Common donor sites:</b> Post-auricular region (classic Wolfe graft), groin crease, "
"supraclavicular skin, inner upper arm — all areas with sufficient skin laxity.",
bg=colors.HexColor("#F5EEF8"), border=colors.HexColor("#5B2C6F")),
Spacer(1, 0.2*cm),
]))
story.append(two_col_adv_dis(
advantages=[
"Excellent colour, contour and texture match",
"Minimal secondary contracture",
"More durable; resists friction and wear",
"Can cover bone without periosteum",
"Better sensation and adnexal function",
],
disadvantages=[
"Limited by donor site size — cannot be meshed",
"Requires excellent recipient bed vascularity",
"Takes the longest time to vascularize",
"Time-consuming; technically demanding",
"Large donor sites may need STSG coverage",
]
))
story.append(Spacer(1, 0.15*cm))
story.append(Paragraph(
"<b>Best for:</b> Facial defects, syndactyly release (hand), joints (contracture prevention), contracture release post-burns.",
S("Pref2", fontName="Helvetica-BoldOblique", fontSize=9.5,
textColor=colors.HexColor("#5B2C6F"), spaceAfter=6)))
story.append(Spacer(1, 0.3*cm))
# ─── Composite ────────────────────────────────────────────────────────────────
story.append(KeepTogether([
section_banner("C. COMPOSITE GRAFT", color=GOLD),
Spacer(1, 0.15*cm),
info_box(
"<b>Composition:</b> Skin + another tissue type (cartilage, fat, or perichondrium).<br/>"
"<b>Example:</b> Skin-cartilage graft from helical root of ear to reconstruct nasal alar "
"after skin cancer excision. Hair-bearing composite scalp graft to reconstruct eyebrow.<br/>"
"<b>Limitation:</b> Best for defects <b><2 cm</b> in diameter. Higher failure risk under "
"vascular compromise.",
bg=LIGHT_GOLD, border=GOLD),
Spacer(1, 0.2*cm),
]))
story.append(two_col_adv_dis(
advantages=[
"Single-stage procedure",
"Good functional and aesthetic results for small defects",
"Provides structural support (cartilage component)",
"Low contraction risk",
],
disadvantages=[
"Size limited to <2 cm diameter",
"High failure risk under vascular compromise",
"Limited donor tissue availability",
"Increased infection and displacement risk",
"Donor site may need flap or complex closure",
]
))
story.append(Spacer(1, 0.3*cm))
# ─── Perichondrial cutaneous graft ────────────────────────────────────────────
story.append(KeepTogether([
section_banner("D. PERICHONDRIAL CUTANEOUS GRAFT", color=colors.HexColor("#17A589")),
Spacer(1, 0.15*cm),
info_box(
"Contains skin with its underlying perichondrium. "
"<b>Indication:</b> Repair of deep nasal tip and alar defects, especially with exposed cartilage. "
"Thicker than FTSG; contracts less; better chance of survival under vascular compromise.",
bg=colors.HexColor("#E8F8F5"), border=colors.HexColor("#17A589")),
]))
story.append(Spacer(1, 0.4*cm))
# ─── Comparison table ─────────────────────────────────────────────────────────
story.append(section_banner("3. COMPARISON TABLE (Dermatology 5e — Table 148.1)"))
story.append(Spacer(1, 0.2*cm))
headers = ["Property", "FTSG", "STSG", "Composite"]
rows = [
["Tissue match", "Good-Excellent", "Poor-Fair", "Good"],
["Nutritional req.", "High", "Low", "High"],
["Vascularity req.", "High", "Low", "Very High"],
["Contraction risk", "Low", "High", "Low"],
["Durability", "Good-Excellent", "Fair-Good", "Fair"],
["Sensation", "Good", "Fair", "Fair"],
["Adnexal functions", "Excellent", "Poor", "Good"],
]
comp_data = [[Paragraph(f"<b>{h}</b>", table_header) for h in headers]]
for i, row in enumerate(rows):
bg = GREY_LIGHT if i % 2 == 0 else WHITE
comp_data.append([Paragraph(row[j],
table_cell_l if j == 0 else table_cell) for j in range(4)])
cw = [4*cm, (W-4*cm)/3, (W-4*cm)/3, (W-4*cm)/3]
ct = Table(comp_data, colWidths=cw)
ct.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.5, GREY_MED),
("INNERGRID", (0,0), (-1,-1), 0.3, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(ct)
story.append(Spacer(1, 0.4*cm))
# ─── Donor site table ─────────────────────────────────────────────────────────
story.append(section_banner("4. DONOR SITE SUMMARY"))
story.append(Spacer(1, 0.2*cm))
ds_data = [
[Paragraph(h, table_header) for h in ["Graft Type", "Typical Donor Sites", "Donor Site Healing"]],
[Paragraph("Thin STSG", table_cell),
Paragraph("Thigh, scalp", table_cell_l),
Paragraph("Secondary intention (~2 weeks)", table_cell_l)],
[Paragraph("Thick STSG", table_cell),
Paragraph("Thigh, back", table_cell_l),
Paragraph("Secondary intention (slower)", table_cell_l)],
[Paragraph("FTSG", table_cell),
Paragraph("Post-auricular, groin crease, supraclavicular", table_cell_l),
Paragraph("Primary closure required", table_cell_l)],
[Paragraph("Composite", table_cell),
Paragraph("Ear helical root, earlobe", table_cell_l),
Paragraph("May need flap or complex closure", table_cell_l)],
]
dst = Table(ds_data, colWidths=[3.5*cm, 7*cm, W - 10.5*cm])
dst.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.5, GREY_MED),
("INNERGRID", (0,0), (-1,-1), 0.3, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(dst)
story.append(Spacer(1, 0.4*cm))
# ─── Graft take phases ────────────────────────────────────────────────────────
story.append(section_banner("5. PHASES OF GRAFT 'TAKE' (REVASCULARISATION)"))
story.append(Spacer(1, 0.2*cm))
phase_data = [
[Paragraph(h, table_header) for h in ["Phase", "Timing", "Description"]],
[Paragraph("1. Imbibition", table_cell),
Paragraph("0 - 48 hrs", table_cell),
Paragraph("Graft absorbs plasmatic fluid from wound bed for passive nutrition", table_cell_l)],
[Paragraph("2. Inosculation", table_cell),
Paragraph("2 - 4 days", table_cell),
Paragraph("Alignment and connection of graft and recipient vessels", table_cell_l)],
[Paragraph("3. Neovascularisation", table_cell),
Paragraph("4 - 7 days", table_cell),
Paragraph("Ingrowth of new capillaries from the wound bed", table_cell_l)],
]
pt = Table(phase_data, colWidths=[3.5*cm, 3*cm, W - 6.5*cm])
pt.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), TEAL),
("ROWBACKGROUNDS",(0,1), (-1,-1), [GREY_LIGHT, WHITE]),
("BOX", (0,0), (-1,-1), 0.5, GREY_MED),
("INNERGRID", (0,0), (-1,-1), 0.3, GREY_MED),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(pt)
story.append(Spacer(1, 0.3*cm))
story.append(info_box(
"<b>Causes of graft failure:</b> Shear forces disrupting graft-bed contact | "
"Haematoma or seroma formation (lifts graft off bed) | "
"Infection — especially beta-haemolytic Streptococcus, Staphylococcus, Pseudomonas | "
"Avascular wound bed",
bg=colors.HexColor("#FDECEA"), border=RED_SOFT))
story.append(Spacer(1, 0.4*cm))
# ─── Footer note ──────────────────────────────────────────────────────────────
story.append(hr(GREY_MED, 1))
story.append(Paragraph(
"Sources: Bailey & Love's Short Practice of Surgery 28e (p.708) | "
"Pfenninger & Fowler's Procedures for Primary Care 3e (p.257-259) | "
"Dermatology 2-Volume Set 5e (Table 148.1) | "
"Fischer's Mastery of Surgery 8e (p.7670) | "
"Rockwood & Green's Fractures in Adults 10e (p.732)",
S("Footer", fontName="Helvetica-Oblique", fontSize=7.5,
textColor=colors.HexColor("#888888"), alignment=TA_CENTER, leading=11)))
# ── Build ─────────────────────────────────────────────────────────────────────
doc.build(story)
print(f"PDF saved to {OUTPUT}")
cd /tmp/workspace/skin-graft-pdf && python3 generate_pdf.py 2>&1
ls -lh /tmp/workspace/skin-graft-pdf/Types_of_Skin_Graft.pdf
Types of Skin Graft
PDF Document · PDF