Clinical case proforma of swelling surgery
mkdir -p /tmp/workspace/swelling-proforma && python3 << 'EOF' from reportlab.lib.pagesizes import A4 from reportlab.lib.units import cm from reportlab.lib import colors from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable ) from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY doc = SimpleDocTemplate( "/tmp/workspace/swelling-proforma/Swelling_Surgery_Proforma.pdf", pagesize=A4, rightMargin=1.8*cm, leftMargin=1.8*cm, topMargin=1.5*cm, bottomMargin=1.5*cm ) styles = getSampleStyleSheet() # Custom styles title_style = ParagraphStyle( 'Title', parent=styles['Heading1'], fontSize=14, textColor=colors.HexColor('#1a3a5c'), alignment=TA_CENTER, spaceAfter=2 ) subtitle_style = ParagraphStyle( 'Subtitle', parent=styles['Normal'], fontSize=10, textColor=colors.HexColor('#1a3a5c'), alignment=TA_CENTER, spaceAfter=8 ) section_style = ParagraphStyle( 'Section', parent=styles['Heading2'], fontSize=10, textColor=colors.white, backColor=colors.HexColor('#1a3a5c'), spaceBefore=8, spaceAfter=4, leftIndent=-4, rightIndent=-4, borderPad=3 ) subsection_style = ParagraphStyle( 'SubSection', parent=styles['Heading3'], fontSize=9, textColor=colors.HexColor('#1a3a5c'), spaceBefore=4, spaceAfter=2, fontName='Helvetica-Bold' ) field_style = ParagraphStyle( 'Field', parent=styles['Normal'], fontSize=8.5, spaceBefore=2, spaceAfter=1, leading=14 ) note_style = ParagraphStyle( 'Note', parent=styles['Normal'], fontSize=7.5, textColor=colors.HexColor('#555555'), fontName='Helvetica-Oblique' ) def section_header(text): return Paragraph(f" {text}", section_style) def subsection(text): return Paragraph(text, subsection_style) def field(label, lines=1, width=None): underline = "_" * (width or 60) if lines == 1: return Paragraph(f"<b>{label}:</b> {underline}", field_style) else: parts = [Paragraph(f"<b>{label}:</b>", field_style)] for _ in range(lines): parts.append(Paragraph("_" * 80, field_style)) return parts def blank_row(height=0.5*cm): return Spacer(1, height) def hr(): return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#cccccc'), spaceAfter=4) # ---- Build content ---- story = [] # Header story.append(Paragraph("CLINICAL CASE PROFORMA", title_style)) story.append(Paragraph("SWELLING — SURGICAL CASE HISTORY & EXAMINATION", subtitle_style)) story.append(Paragraph("(MBBS Undergraduate Surgery Posting)", subtitle_style)) story.append(HRFlowable(width="100%", thickness=2, color=colors.HexColor('#1a3a5c'), spaceAfter=6)) # Patient Details Table story.append(section_header("A. PATIENT IDENTIFICATION")) story.append(blank_row(0.3*cm)) id_data = [ ["Name:", "_"*30, "IP/OP No.:", "_"*20], ["Age:", "_"*30, "Date of Admission:", "_"*20], ["Sex:", "M / F / O", "Date of Examination:", "_"*20], ["Occupation:", "_"*30, "Ward / Bed No.:", "_"*20], ["Address:", "_"*30, "Examined by:", "_"*20], ] id_table = Table(id_data, colWidths=[3*cm, 6.5*cm, 4*cm, 5.5*cm]) id_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('TEXTCOLOR', (0,0), (-1,-1), colors.HexColor('#1a3a5c')), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f0f4f8'), colors.white]), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(id_table) story.append(blank_row()) # ---- CHIEF COMPLAINT ---- story.append(section_header("B. CHIEF COMPLAINT")) story.append(blank_row(0.3*cm)) cc_data = [ ["Chief Complaint:", "Swelling over _________________________ since ____________"], ["Other Complaints:", "_"*70], ["", "_"*70], ] cc_table = Table(cc_data, colWidths=[4*cm, 15*cm]) cc_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 3), ])) story.append(cc_table) story.append(blank_row()) # ---- HISTORY OF PRESENT ILLNESS ---- story.append(section_header("C. HISTORY OF PRESENT ILLNESS (SWELLING)")) story.append(blank_row(0.3*cm)) hopi_items = [ ("1. Site", "Exact anatomical location: _______________________________"), ("2. Onset", "Sudden / Gradual Date/Duration: _______________"), ("3. Duration", "______ days / months / years"), ("4. Progress", "Increasing / Decreasing / Stationary / Fluctuating in size"), ("5. Rate of growth", "Slow / Moderate / Rapid"), ("6. Pain", "Present / Absent Character: ___________ Radiation: ___________"), ("7. Skin changes", "Redness / Warmth / Ulceration / Discharge / Nil"), ("8. Discharge", "Present / Absent Type: Pus / Serous / Blood / Cheesy Amount: ___"), ("9. Change in swelling", "Appears/disappears with posture / Straining / Nil change"), ("10. Associated symptoms", "Fever / Loss of weight / Loss of appetite / Fatigue / Nil"), ("11. Trauma", "History of injury: Yes / No Details: _________________________"), ("12. Similar swellings", "Elsewhere in body: Yes / No Details: ______________________"), ] hopi_data = [[Paragraph(f"<b>{k}</b>", field_style), Paragraph(v, field_style)] for k,v in hopi_items] hopi_table = Table(hopi_data, colWidths=[4*cm, 15*cm]) hopi_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('TOPPADDING', (0,0), (-1,-1), 3), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f7f9fb'), colors.white]), ('LINEBELOW', (0,-1), (-1,-1), 0.3, colors.HexColor('#dddddd')), ])) story.append(hopi_table) story.append(blank_row()) # ---- PAST HISTORY ---- story.append(section_header("D. PAST HISTORY")) story.append(blank_row(0.3*cm)) past_items = [ "Similar swelling in the past: Yes / No Details: ___________________", "Previous surgery / biopsy: Yes / No Details: ___________________", "Tuberculosis: Yes / No Diabetes: Yes / No Hypertension: Yes / No", "Other significant illness: _______________________________________________", "Medications: ____________________________________________________________", ] for item in past_items: story.append(Paragraph(f"• {item}", field_style)) story.append(blank_row()) # ---- FAMILY HISTORY ---- story.append(section_header("E. FAMILY HISTORY")) story.append(blank_row(0.3*cm)) story.append(Paragraph("• Similar swelling in family: Yes / No Details: ________________________", field_style)) story.append(Paragraph("• Malignancy in family: Yes / No Type/Relation: ______________________", field_style)) story.append(Paragraph("• Tuberculosis / Infectious disease in family: Yes / No", field_style)) story.append(blank_row()) # ---- PERSONAL HISTORY ---- story.append(section_header("F. PERSONAL HISTORY")) story.append(blank_row(0.3*cm)) pers_items = [ "Diet: Veg / Mixed Appetite: Normal / Decreased", "Bowel & Bladder: Normal / Abnormal Details: ________________________", "Sleep: Normal / Disturbed", "Addictions: Tobacco / Alcohol / Smoking / Nil Details: ________________", "Menstrual history (if female): LMP: ______ Cycle: Regular / Irregular Duration: ___", ] for item in pers_items: story.append(Paragraph(f"• {item}", field_style)) story.append(blank_row()) # ---- GENERAL PHYSICAL EXAMINATION ---- story.append(section_header("G. GENERAL PHYSICAL EXAMINATION")) story.append(blank_row(0.3*cm)) gpe_data = [ ["Build & Nourishment:", "Well / Moderate / Poor", "Pallor:", "Present / Absent"], ["Cachexia / wt. loss:", "Present / Absent", "Icterus:", "Present / Absent"], ["Cyanosis:", "Present / Absent", "Clubbing:", "Grade: _______"], ["Lymphadenopathy:", "Present / Absent Describe: ________________", "Oedema:", "Present / Absent"], ["Pulse:", "______ bpm Rhythm: ________", "BP:", "______ / ______ mmHg"], ["Temp:", "______°F / °C", "RR:", "______ / min"], ["JVP:", "Normal / Raised", "SpO2:", "_______ %"], ] gpe_table = Table(gpe_data, colWidths=[4*cm, 6*cm, 3*cm, 6*cm]) gpe_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f0f4f8'), colors.white]), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ('SPAN', (1, 3), (1, 3)), ])) story.append(gpe_table) story.append(blank_row()) # ---- LOCAL EXAMINATION ---- story.append(section_header("H. LOCAL EXAMINATION OF THE SWELLING")) story.append(blank_row(0.3*cm)) story.append(Paragraph( '<i>Note: Always examine by Inspection first, then Palpation, then Percussion, then Auscultation (IPPA)</i>', note_style )) story.append(blank_row(0.3*cm)) # INSPECTION TABLE story.append(subsection("1. INSPECTION")) insp_items = [ ("Site & Position", "Exact anatomical location: _____________________________________"), ("Size", "Approximate dimensions: _________ × _________ cm"), ("Shape", "Round / Oval / Irregular / Lobulated / Describe: ___________"), ("Margin / Edge", "Well-defined / Ill-defined / Regular / Irregular"), ("Number", "Single / Multiple If multiple: Discrete / Matted / Confluent"), ("Surface", "Smooth / Nodular / Bosselated / Uneven"), ("Colour of overlying skin", "Normal / Erythema / Hyperpigmentation / Bluish / Describe: ___"), ("Skin over swelling", "Normal / Stretched / Ulcerated / Punctum / Peau d'orange"), ("Visible pulsation", "Present / Absent"), ("Visible peristalsis", "Present / Absent"), ("Engorged veins", "Present / Absent Direction: __________________________"), ("Discharge / sinus", "Present / Absent Character: _________________________"), ("Movement with respiration", "Present / Absent"), ("Movement with deglutition", "Present / Absent (for neck swellings)"), ("Movement with tongue protrusion", "Present / Absent (for midline neck swellings)"), ] insp_data = [[Paragraph(f"<b>{k}</b>", field_style), Paragraph(v, field_style)] for k,v in insp_items] insp_table = Table(insp_data, colWidths=[5*cm, 14*cm]) insp_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('TOPPADDING', (0,0), (-1,-1), 3), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f7f9fb'), colors.white]), ])) story.append(insp_table) story.append(blank_row()) # PALPATION TABLE story.append(subsection("2. PALPATION")) palp_items = [ ("Temperature", "Normal / Raised / Reduced (compare with opposite side)"), ("Tenderness", "Present / Absent Degree: Mild / Moderate / Severe"), ("Size (exact)", "________ × ________ × ________ cm"), ("Shape", "Round / Oval / Irregular / Lobulated"), ("Surface", "Smooth / Nodular / Bosselated"), ("Margin / Edge", "Well-defined / Ill-defined"), ("Consistency", "Soft / Firm / Hard / Rubbery / Cystic / Bony hard"), ("Fluctuation", "Present / Absent (Test: Two-finger / Cross-fluctuation)"), ("Fluid thrill", "Present / Absent (for large cystic swellings)"), ("Transillumination", "Positive / Negative / Not applicable"), ("Compressibility", "Compressible / Non-compressible Refills on release: Yes / No"), ("Reducibility", "Reducible / Irreducible (for hernia / varix)"), ("Pulsatility", "Expansile / Transmitted / Absent"), ("Skin over swelling", "Pinchable / Not pinchable (skin involvement)"), ("Plane / Layer", "Skin / Subcutaneous / Deep fascia / Muscle / Bone"), ("Attachments", "Fixed to skin: Yes/No Fixed to deep structures: Yes/No"), ("Mobility", "Mobile / Restricted / Fixed Direction of mobility: ____________"), ("Regional lymph nodes", "Enlarged: Yes / No Site: _________________________________"), (" If enlarged — Size:", "________cm Consistency: ________ Tender: Yes/No"), (" If enlarged — Number:", "_______ Discrete/Matted: _______ Fixed/Mobile: _______"), ("Cough impulse", "Present / Absent (Hernias, varicocele)"), ("Bruit / Thrill", "Present / Absent (Vascular lesions)"), ("Pressure effects", "Distal oedema: Y/N Nerve compression: Y/N Vessel compression: Y/N"), ("Transverse slip sign", "Present / Absent (for nerve tumours)"), ("Tethering to muscle", "Test: Make muscle taut (against resistance) Fixed/Free: _______"), ] palp_data = [[Paragraph(f"<b>{k}</b>", field_style), Paragraph(v, field_style)] for k,v in palp_items] palp_table = Table(palp_data, colWidths=[5*cm, 14*cm]) palp_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('TOPPADDING', (0,0), (-1,-1), 3), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f7f9fb'), colors.white]), ])) story.append(palp_table) story.append(blank_row()) # PERCUSSION & AUSCULTATION story.append(subsection("3. PERCUSSION")) story.append(Paragraph("Note: _______________________________________________________________________", field_style)) story.append(Paragraph("Resonant / Dull / Tympanitic (relevant for abdominal/thoracic swellings)", field_style)) story.append(blank_row(0.3*cm)) story.append(subsection("4. AUSCULTATION")) story.append(Paragraph("Bruit: Present / Absent Bowel sounds (if applicable): Present / Absent", field_style)) story.append(Paragraph("Notes: ______________________________________________________________________", field_style)) story.append(blank_row()) # ---- SYSTEMIC EXAMINATION ---- story.append(section_header("I. SYSTEMIC EXAMINATION")) story.append(blank_row(0.3*cm)) sys_items = [ ("Cardiovascular System", "S1 S2 heard: Y/N Murmur: Y/N Notes: ________________________"), ("Respiratory System", "Air entry: Bilateral equal Y/N Added sounds: ____________________"), ("Abdomen", "Liver: _______ Spleen: _______ Ascites: Y/N Bowel sounds: ___"), ("CNS", "Conscious / Oriented GCS: ___/15 Focal deficit: Y/N ____________"), ("Musculoskeletal", "Spine: ____________ Other joints: ____________________________________"), ] sys_data = [[Paragraph(f"<b>{k}</b>", field_style), Paragraph(v, field_style)] for k,v in sys_items] sys_table = Table(sys_data, colWidths=[5*cm, 14*cm]) sys_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f0f4f8'), colors.white]), ])) story.append(sys_table) story.append(blank_row()) # ---- PROVISIONAL DIAGNOSIS ---- story.append(section_header("J. PROVISIONAL DIAGNOSIS")) story.append(blank_row(0.3*cm)) prov_data = [ ["Primary diagnosis:", "_"*60], ["Differential diagnosis 1:", "_"*57], ["Differential diagnosis 2:", "_"*57], ["Differential diagnosis 3:", "_"*57], ["Basis of diagnosis:", "_"*60], ["Suspected pathology:", "Congenital / Traumatic / Inflammatory / Neoplastic (Benign/Malignant) / Other"], ] prov_table = Table(prov_data, colWidths=[5*cm, 14*cm]) prov_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [colors.HexColor('#f7f9fb'), colors.white]), ('BOTTOMPADDING', (0,0), (-1,-1), 5), ('TOPPADDING', (0,0), (-1,-1), 5), ])) story.append(prov_table) story.append(blank_row()) # ---- INVESTIGATIONS ---- story.append(section_header("K. INVESTIGATIONS ADVISED")) story.append(blank_row(0.3*cm)) story.append(subsection("Routine Blood Investigations")) story.append(Paragraph( "CBC (TC: ___ DC: N___L___E___M___B___ Hb: ___ g/dl PCV: ___ Platelets: ___) " "ESR: ___mm/hr RBS: ___mg/dl BT: ___ CT: ___ HIV/HBsAg: ___", field_style )) story.append(blank_row(0.3*cm)) # Investigation table inv_data = [ ["Investigation", "Ordered (Y/N)", "Result / Finding"], ["Urine R/M + Culture", "", ""], ["LFT / RFT", "", ""], ["Serology (VDRL/MT/RA)", "", ""], ["X-Ray (Plain — specify part)", "", ""], ["Ultrasound (specify region)", "", ""], ["CT scan / MRI (specify)", "", ""], ["FNAC / FNAB", "", ""], ["Incision / Excision Biopsy", "", ""], ["Aspiration cytology", "", ""], ["Bone scan / PET CT", "", ""], ["Other: _________________", "", ""], ] inv_table = Table(inv_data, colWidths=[7*cm, 4*cm, 8*cm]) inv_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'), ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#1a3a5c')), ('TEXTCOLOR', (0,0), (-1,0), colors.white), ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#aaaaaa')), ('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#f7f9fb'), colors.white]), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('ALIGN', (1,0), (1,-1), 'CENTER'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(inv_table) story.append(blank_row()) # ---- DIAGNOSIS AFTER INVESTIGATIONS ---- story.append(section_header("L. FINAL DIAGNOSIS (AFTER INVESTIGATIONS)")) story.append(blank_row(0.3*cm)) story.append(Paragraph("Final Diagnosis: __________________________________________________________", field_style)) story.append(Paragraph("Confirm benign / malignant / inflammatory / other: _________________________________", field_style)) story.append(Paragraph("Stage (if malignant): T___ N___ M___ Overall Stage: ______", field_style)) story.append(blank_row()) # ---- TREATMENT PLAN ---- story.append(section_header("M. TREATMENT PLAN")) story.append(blank_row(0.3*cm)) story.append(subsection("Pre-operative Preparation")) story.append(Paragraph("Blood grouping & cross-matching: ______ Fitness: ______ Consent: obtained / not yet", field_style)) story.append(Paragraph("Anaesthesia plan: GA / LA / Regional / Spinal", field_style)) story.append(Paragraph("Other preparations: _______________________________________________", field_style)) story.append(blank_row(0.3*cm)) story.append(subsection("Operative Plan")) story.append(Paragraph("Procedure: Excision / Incision & drainage / Lumpectomy / Wide local excision / Other: ______", field_style)) story.append(Paragraph("Special considerations: _______________________________________________", field_style)) story.append(blank_row(0.3*cm)) story.append(subsection("Post-operative Plan")) story.append(Paragraph("Wound care / Drain / Suture removal: ________________________________________", field_style)) story.append(Paragraph("Send specimen for HPE: Yes / No Antibiotics: ____________________", field_style)) story.append(Paragraph("Follow-up: ___________________________________________________________________", field_style)) story.append(blank_row()) # ---- CLINICAL DRAWINGS ---- story.append(section_header("N. CLINICAL DRAWINGS / DIAGRAM OF SWELLING")) story.append(blank_row(0.3*cm)) draw_data = [ ["ANTERIOR VIEW", "POSTERIOR VIEW / LATERAL VIEW"], [" \n\n\n\n\n\n\n\n\n ", " \n\n\n\n\n\n\n\n\n "], ["Label the site of swelling, regional lymph nodes, anatomical landmarks", ""] ] draw_table = Table(draw_data, colWidths=[9.5*cm, 9.5*cm]) draw_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'), ('BACKGROUND', (0,0), (-1,0), colors.HexColor('#dce6f1')), ('TEXTCOLOR', (0,0), (-1,0), colors.HexColor('#1a3a5c')), ('ALIGN', (0,0), (-1,-1), 'CENTER'), ('GRID', (0,0), (-1,-1), 0.8, colors.HexColor('#1a3a5c')), ('MINROWHEIGHT', (0,1), (-1,1), 4*cm), ('BOTTOMPADDING', (0,0), (-1,-1), 6), ('TOPPADDING', (0,0), (-1,-1), 6), ])) story.append(draw_table) story.append(blank_row()) # ---- NOTES ---- story.append(section_header("O. NOTES / ADDITIONAL FINDINGS")) story.append(blank_row(0.3*cm)) for _ in range(5): story.append(Paragraph("_"*100, field_style)) story.append(blank_row()) # ---- SIGNATURE ---- story.append(section_header("P. SIGNATURES")) story.append(blank_row(0.3*cm)) sig_data = [ ["Student Signature:", "_"*30, "Date:", "__________"], ["Guide / Tutor Signature:", "_"*30, "Grade / Marks:", "__________"], ] sig_table = Table(sig_data, colWidths=[5*cm, 6*cm, 3.5*cm, 4.5*cm]) sig_table.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'), ('BOTTOMPADDING', (0,0), (-1,-1), 6), ('TOPPADDING', (0,0), (-1,-1), 6), ])) story.append(sig_table) story.append(blank_row(0.3*cm)) # Footer note story.append(HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#1a3a5c'))) story.append(blank_row(0.2*cm)) story.append(Paragraph( "Reference: S Das — A Manual on Clinical Surgery, 13th Ed. | Bailey & Love's Short Practice of Surgery, 28th Ed. | Pye's Surgical Handicraft, 22nd Ed.", note_style )) doc.build(story) print("PDF generated successfully!") EOF
Swelling Surgery Proforma
PDF Document · PDF
Sebaceous cyst case clinical proforma
mkdir -p /tmp/workspace/sebaceous-cyst-proforma && python3 << 'PYEOF' from reportlab.lib.pagesizes import A4 from reportlab.lib.units import cm from reportlab.lib import colors from reportlab.platypus import ( SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle, HRFlowable, KeepTogether ) from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT doc = SimpleDocTemplate( "/tmp/workspace/sebaceous-cyst-proforma/Sebaceous_Cyst_Proforma.pdf", pagesize=A4, rightMargin=1.8*cm, leftMargin=1.8*cm, topMargin=1.4*cm, bottomMargin=1.4*cm ) styles = getSampleStyleSheet() NAVY = colors.HexColor('#1a3a5c') LTBLUE = colors.HexColor('#dce6f1') ROW0 = colors.HexColor('#f0f4f8') ROW1 = colors.white LGRAY = colors.HexColor('#f7f9fb') GRAY = colors.HexColor('#555555') title_style = ParagraphStyle('T', parent=styles['Normal'], fontSize=14, textColor=NAVY, alignment=TA_CENTER, fontName='Helvetica-Bold', spaceAfter=1) subtitle_style = ParagraphStyle('ST', parent=styles['Normal'], fontSize=9.5, textColor=NAVY, alignment=TA_CENTER, spaceAfter=2) section_style = ParagraphStyle('Sec', parent=styles['Normal'], fontSize=9.5, textColor=colors.white, backColor=NAVY, fontName='Helvetica-Bold', spaceBefore=7, spaceAfter=3, leftIndent=-4, rightIndent=-4, borderPad=3) subsec_style = ParagraphStyle('Sub', parent=styles['Normal'], fontSize=9, textColor=NAVY, fontName='Helvetica-Bold', spaceBefore=4, spaceAfter=2) field_style = ParagraphStyle('F', parent=styles['Normal'], fontSize=8.5, spaceBefore=1, spaceAfter=1, leading=14) note_style = ParagraphStyle('N', parent=styles['Normal'], fontSize=7.5, textColor=GRAY, fontName='Helvetica-Oblique') highlight_style = ParagraphStyle('HL', parent=styles['Normal'], fontSize=8, textColor=NAVY, backColor=LTBLUE, fontName='Helvetica-Bold', borderPad=2, spaceBefore=3, spaceAfter=3, leftIndent=4) def sec(text): return Paragraph(f" {text}", section_style) def subsec(text): return Paragraph(text, subsec_style) def f(text): return Paragraph(text, field_style) def gap(h=0.35*cm): return Spacer(1, h) def hr(): return HRFlowable(width="100%", thickness=0.5, color=colors.HexColor('#bbbbbb'), spaceAfter=3) def two_col_table(rows, col1=5*cm, col2=14*cm, alt=True): data = [[Paragraph(f"<b>{k}</b>", field_style), Paragraph(v, field_style)] for k,v in rows] bg = [ROW0, ROW1] if alt else [ROW1, ROW1] t = Table(data, colWidths=[col1, col2]) t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('TOPPADDING', (0,0), (-1,-1), 3), ('ROWBACKGROUNDS', (0,0), (-1,-1), bg), ])) return t story = [] # ── TITLE ────────────────────────────────────────────────────────────────────── story.append(Paragraph("CLINICAL CASE PROFORMA", title_style)) story.append(Paragraph("SEBACEOUS CYST (Epidermoid / Pilar Cyst)", subtitle_style)) story.append(Paragraph("MBBS Undergraduate Surgery Posting", subtitle_style)) story.append(HRFlowable(width="100%", thickness=2, color=NAVY, spaceAfter=5)) # ── HIGHLIGHT BOX ────────────────────────────────────────────────────────────── story.append(Paragraph( "CLINICAL DEFINITION: A sebaceous cyst is a retention cyst of the sebaceous gland caused by " "blockage of its duct (which opens into a hair follicle). It contains sebum — a yellowish-white " "cheesy pultaceous material. The pathognomonic sign is a PUNCTUM (black dot = blocked gland opening) " "on the surface. NOT found on palm or sole (no sebaceous glands there).", highlight_style )) story.append(gap()) # ── A. PATIENT IDENTIFICATION ────────────────────────────────────────────────── story.append(sec("A. PATIENT IDENTIFICATION")) story.append(gap(0.2*cm)) id_data = [ ["Name:", "_"*30, "IP/OP No.:", "_"*18], ["Age:", "_"*30, "Date of Admission:", "_"*18], ["Sex:", "M / F / O", "Date of Examination:", "_"*18], ["Occupation:", "_"*30, "Ward / Bed No.:", "_"*18], ["Address:", "_"*30, "Examined by:", "_"*18], ] id_t = Table(id_data, colWidths=[3*cm, 6.5*cm, 4*cm, 5.5*cm]) id_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [ROW0, ROW1]), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(id_t) story.append(gap()) # ── B. CHIEF COMPLAINT ───────────────────────────────────────────────────────── story.append(sec("B. CHIEF COMPLAINT")) story.append(gap(0.2*cm)) cc_data = [ ["Chief Complaint:", "Swelling over __________________________ since _____________"], ["Other Complaints:", "Pain / Discharge / Itching / Cosmetic concern / Nil"], ["", "_"*70], ] cc_t = Table(cc_data, colWidths=[4*cm, 15*cm]) cc_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 3), ])) story.append(cc_t) story.append(gap()) # ── C. HISTORY OF PRESENT ILLNESS ───────────────────────────────────────────── story.append(sec("C. HISTORY OF PRESENT ILLNESS")) story.append(gap(0.2*cm)) hopi = [ ("1. Site", "Scalp / Face (forehead, cheek, behind ear) / Neck / Scrotum / Back / Other: _______"), (" (Note)", "Sebaceous cysts DO NOT occur on palm or sole — absence here supports diagnosis"), ("2. Onset", "Sudden / Gradual Exact date/duration: ___________________________"), ("3. Duration", "_______ days / months / years"), ("4. Rate of growth", "Slow (months-years) / Recent rapid increase (suggests infection/malignant change)"), ("5. Pain", "Absent (typical) / Present — character: ____________ onset of pain: ___________"), (" (Note)", "Pain onset suggests secondary infection or malignant change — clarify when pain began"), ("6. Discharge", "Absent / Present — Character: Cheesy / Purulent / Bloody Odour: Rancid / Nil"), (" Expressed from punctum?", "Yes (supports sebaceous cyst) / No"), ("7. Fever", "Present / Absent If present, onset relative to swelling: ____________________"), ("8. Number", "Single / Multiple (Multiple cysts common on scalp and scrotum)"), ("9. Recurrence", "First episode / Previously excised — recurred: Yes / No"), ("10. Cosmetic/functional concern", "Yes / No Details: ________________________________________"), ("11. Trauma history", "Yes / No (Epidermoid cyst may arise post-trauma via epidermal implantation)"), ("12. Similar swelling elsewhere", "Yes / No Site: ___________________________________________"), ] story.append(two_col_table(hopi, col1=5.5*cm, col2=13.5*cm)) story.append(gap()) # ── D. PAST HISTORY ─────────────────────────────────────────────────────────── story.append(sec("D. PAST HISTORY")) story.append(gap(0.2*cm)) for item in [ "Previous sebaceous cyst excision: Yes / No Recurrence: Yes / No", "H/o incision & drainage for infected cyst: Yes / No When: _________________", "Diabetes mellitus: Yes / No (Recurrent infections in DM)", "Hypertension / Cardiac / Renal disease: ___________________________________", "Drug allergy (esp. LA — lignocaine): Yes / No Drug: _____________________", "Other significant illness: ________________________________________________", ]: story.append(f(f"• {item}")) story.append(gap()) # ── E. FAMILY HISTORY ───────────────────────────────────────────────────────── story.append(sec("E. FAMILY HISTORY")) story.append(gap(0.2*cm)) for item in [ "Similar cysts in family members: Yes / No (Gardner syndrome — familial polyposis + epidermoid cysts)", "Family history of malignancy: Yes / No Details: ______________________________", ]: story.append(f(f"• {item}")) story.append(gap()) # ── F. PERSONAL HISTORY ─────────────────────────────────────────────────────── story.append(sec("F. PERSONAL HISTORY")) story.append(gap(0.2*cm)) for item in [ "Diet: Veg / Mixed Appetite: Normal / Decreased", "Bowel & Bladder: Normal / Abnormal", "Addictions: Tobacco / Alcohol / Nil", "Occupation (exposure to oils/chemicals — industrial acne/cysts): ___________________", "Menstrual history (if female): LMP: ______ Cycle: Regular / Irregular", ]: story.append(f(f"• {item}")) story.append(gap()) # ── G. GENERAL PHYSICAL EXAMINATION ────────────────────────────────────────── story.append(sec("G. GENERAL PHYSICAL EXAMINATION")) story.append(gap(0.2*cm)) gpe_data = [ ["Build & Nourishment:", "Well / Moderate / Poor", "Pallor:", "Present / Absent"], ["Icterus:", "Present / Absent", "Cyanosis:", "Present / Absent"], ["Clubbing:", "Grade: _______", "Lymphadenopathy:", "Present / Absent"], ["Oedema:", "Present / Absent", "Skin condition:", "Acne / Oily skin / Normal"], ["Pulse:", "______ bpm", "BP:", "______ / ______ mmHg"], ["Temp:", "______°F / °C", "RR:", "______ / min"], ] gpe_t = Table(gpe_data, colWidths=[4*cm, 6*cm, 3.5*cm, 5.5*cm]) gpe_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [ROW0, ROW1]), ('VALIGN', (0,0), (-1,-1), 'MIDDLE'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(gpe_t) story.append(gap()) # ── H. LOCAL EXAMINATION ────────────────────────────────────────────────────── story.append(sec("H. LOCAL EXAMINATION OF THE SWELLING")) story.append(Paragraph( " Examine by IPPA order. For sebaceous cyst, INSPECTION for punctum and " "PALPATION for fluctuation + skin fixity are the key steps.", note_style )) story.append(gap(0.25*cm)) # INSPECTION story.append(subsec("1. INSPECTION")) insp = [ ("Site", "Scalp / Face / Behind ear / Neck / Scrotum / Back / Other: _________________"), ("Number", "Single / Multiple (If multiple, note distribution)"), ("Size (approx.)", "________ × ________ cm (Can range from pea-sized to several cm)"), ("Shape", "Round / Oval (Sebaceous cysts are usually round/oval and smooth)"), ("Surface", "Smooth / Irregular Bosselated: Yes / No"), ("Overlying skin colour", "Normal / Erythema (infected) / Hyperpigmented / Shiny (tense)"), ("PUNCTUM", "Present (BLACK DOT) ✓ / Absent Position: Central / Eccentric"), (" (Clinical significance)", "Punctum = blocked sebaceous duct opening — PATHOGNOMONIC of sebaceous cyst"), ("Skin ulceration/sinus", "Present / Absent (Chronic infection or Cock's peculiar tumour)"), ("Alopecia over cyst", "Present / Absent (Baldness over a large scalp sebaceous cyst — characteristic)"), ("Sebaceous horn", "Present / Absent (Inspissated sebum extruded from wide punctum)"), ("Visible discharge", "Present / Absent Character: _______________________________________"), ("Engorged overlying veins", "Present / Absent"), ("Pulsation", "Present / Absent"), ] story.append(two_col_table(insp, col1=5*cm, col2=14*cm)) story.append(gap(0.3*cm)) # PALPATION story.append(subsec("2. PALPATION")) palp = [ ("Temperature", "Normal (non-infected) / Raised (infected — compare with opposite side)"), ("Tenderness", "Absent (typical) / Present — Mild / Moderate / Severe (infection / inflammation)"), ("Size (exact)", "________ × ________ × ________ cm"), ("Shape", "Round / Oval Well-rounded and smooth"), ("Surface", "Smooth / Irregular"), ("Margin / Edge", "Well-defined / Ill-defined Margin 'yields to palpating finger' (S Das)"), ("Consistency", "Soft-cystic / Firm (Cheesy contents = may feel firm)"), ("FLUCTUATION TEST", "Positive ✓ / Negative (Always +ve in sebaceous cyst — S Das)"), ("TRANSILLUMINATION", "Negative ✓ / Positive (Always -ve — contents are opaque/cheesy — S Das)"), ("Skin attachment", "FIXED TO SKIN ✓ / Not fixed (skin cannot be pinched away from cyst)"), (" Deep attachment", "NOT fixed to deep structures ✓ / Fixed (freely mobile over muscle/fascia)"), ("Compressibility", "Compressible / Non-compressible"), ("Reducibility", "Non-reducible (confirms non-hernia)"), ("Pulsatility", "Absent / Present (if over vessel — transmitted)"), ("Cough impulse", "Absent / Present"), ("Squeezing punctum", "Cheesy material expressible: Yes (diagnostic) / No"), ("Bruit", "Absent / Present"), ("Regional lymph nodes", "Not enlarged (typical) / Enlarged — Site: ___________________________"), (" If enlarged:", "Size: ___cm Consistency: ___________ Tender: Yes/No Mobile/Fixed: ___"), ("Transverse slip sign", "Absent / Present (nerve tumour — not expected here)"), ("Tethering to muscle", "Make muscle taut → Mobility: unchanged (not tethered to muscle) ✓"), ] story.append(two_col_table(palp, col1=5.5*cm, col2=13.5*cm)) story.append(gap(0.3*cm)) # PERCUSSION & AUSCULTATION story.append(subsec("3. PERCUSSION")) story.append(f("Dull / Resonant Notes: _______________________________________________")) story.append(gap(0.2*cm)) story.append(subsec("4. AUSCULTATION")) story.append(f("Bruit: Present / Absent (Not expected in sebaceous cyst)")) story.append(gap()) # ── I. DIAGNOSIS OF TISSUE OF ORIGIN ────────────────────────────────────────── story.append(sec("I. DIAGNOSIS — TISSUE LAYER OF ORIGIN")) story.append(gap(0.2*cm)) story.append(Paragraph( " Determine the layer from which the swelling arises (systematic approach from S Das):", note_style )) story.append(gap(0.15*cm)) layer_data = [ ["Skin origin?", "Skin cannot be pinched away — YES → consistent with sebaceous cyst"], ["Subcutaneous?", "Moves freely over deep fascia/muscle — YES → subcutaneous"], ["Muscle origin?", "Make muscle taut → mobility unchanged → NOT from muscle"], ["Nerve origin?", "No transverse slip sign → NOT from nerve"], ["Bone origin?", "No bony hard base, not fixed to bone → NOT from bone"], ["CONCLUSION", "Swelling arising from SKIN (sebaceous gland) — fixed to skin, free from deep structures"], ] layer_t = Table(layer_data, colWidths=[4*cm, 15*cm]) layer_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (0,5), (0,5), 'Helvetica-Bold'), ('BACKGROUND', (0,5), (-1,5), LTBLUE), ('ROWBACKGROUNDS', (0,0), (-1,4), [ROW0, ROW1]), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(layer_t) story.append(gap()) # ── J. SYSTEMIC EXAMINATION ─────────────────────────────────────────────────── story.append(sec("J. SYSTEMIC EXAMINATION")) story.append(gap(0.2*cm)) sys_rows = [ ("CVS", "S1 S2 heard: Y/N Murmur: Y/N"), ("Respiratory", "Air entry equal bilateral: Y/N Added sounds: ___________________________"), ("Abdomen", "Liver: _______ Spleen: _______ Any other mass: ________________________"), ("CNS", "GCS: ___/15 Oriented: Y/N Focal deficit: Y/N"), ] story.append(two_col_table(sys_rows, col1=4*cm, col2=15*cm)) story.append(gap()) # ── K. PROVISIONAL DIAGNOSIS ────────────────────────────────────────────────── story.append(sec("K. PROVISIONAL DIAGNOSIS")) story.append(gap(0.2*cm)) prov_data2 = [ ["Primary Diagnosis:", "Sebaceous (epidermoid) cyst of the ___________________________"], ["State:", "Uninfected / Infected (suppurating) / Cock's peculiar tumour / Sebaceous horn"], ["Differential Dx 1:", "Dermoid cyst (no punctum, occurs at lines of fusion e.g. outer angle of eye, midline)"], ["Differential Dx 2:", "Lipoma (soft, lobulated, not fixed to skin, no punctum, transillumination may be +ve)"], ["Differential Dx 3:", "Implantation dermoid (h/o trauma, palm/sole, no punctum)"], ["Differential Dx 4:", "Lymph node enlargement (regional, hard/firm, possible tenderness)"], ["Differential Dx 5:", "Fibroma / Neurofibroma (if deep, transverse slip sign +ve for nerve tumour)"], ["Basis of diagnosis:", "Punctum + fixed to skin + fluctuation +ve + transillumination -ve + site (scalp/face/scrotum)"], ] prov_t = Table(prov_data2, colWidths=[5*cm, 14*cm]) prov_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [ROW0, ROW1]), ('BACKGROUND', (0,7), (-1,7), LTBLUE), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(prov_t) story.append(gap()) # ── L. COMPLICATIONS BOX ────────────────────────────────────────────────────── story.append(sec("L. COMPLICATIONS OF SEBACEOUS CYST (S Das)")) story.append(gap(0.2*cm)) comp_data = [ ["(a) Infection", "Cyst becomes enlarged, painful, red, tender — most common complication"], ["(b) Ulceration", "Overlying skin breaks down"], ["(c) Rupture & sinus formation", "Chronic discharge from a sinus tract"], ["(d) Calcification", "Hardening of cyst contents"], ["(e) Carcinomatous change", "Rare — epidermoid carcinoma arising in cyst wall"], ["(f) Cock's peculiar tumour", "Ruptured cyst + chronic infection → boggy, fungating, discharging mass"], ["(g) Sebaceous horn", "Inspissated sebum extruded from wide punctum hardens into a horn"], ] comp_t = Table(comp_data, colWidths=[5*cm, 14*cm]) comp_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [ROW0, ROW1]), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 4), ('TOPPADDING', (0,0), (-1,-1), 4), ])) story.append(comp_t) story.append(gap()) # ── M. INVESTIGATIONS ───────────────────────────────────────────────────────── story.append(sec("M. INVESTIGATIONS")) story.append(gap(0.2*cm)) story.append(Paragraph( " Sebaceous cyst is a CLINICAL diagnosis — investigations are mainly pre-operative and " "to rule out complications or confirm histology.", note_style )) story.append(gap(0.2*cm)) inv_data = [ ["Investigation", "Indication / Rationale", "Ordered Y/N", "Result"], ["CBC + ESR", "Pre-op; ESR raised in infection/malignant change", "", ""], ["RBS / HbA1c", "Rule out DM (recurrent infections)", "", ""], ["BT / CT / PT-INR", "Pre-operative fitness", "", ""], ["Blood group & cross-match", "Pre-op if GA planned", "", ""], ["HIV / HBsAg", "Pre-op screening", "", ""], ["Urine R/M", "Routine pre-op", "", ""], ["FNAC", "If malignancy suspected; atypical features", "", ""], ["HPE of excised specimen", "MANDATORY after excision — confirms diagnosis + rules out carcinoma", "", ""], ["USG (if needed)", "Depth/extent of cyst, rule out deep extension or vascular lesion", "", ""], ["X-ray skull/local part", "If bony erosion suspected (large scalp cyst)", "", ""], ["Swab C/S", "If infected — identify organism (MRSA increasingly common)", "", ""], ] inv_t = Table(inv_data, colWidths=[4.5*cm, 7*cm, 3*cm, 4.5*cm]) inv_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8), ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'), ('BACKGROUND', (0,0), (-1,0), NAVY), ('TEXTCOLOR', (0,0), (-1,0), colors.white), ('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#aaaaaa')), ('ROWBACKGROUNDS', (0,1), (-1,-1), [LGRAY, colors.white]), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('ALIGN', (2,0), (2,-1), 'CENTER'), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('TOPPADDING', (0,0), (-1,-1), 3), ])) story.append(inv_t) story.append(gap()) # ── N. TREATMENT PLAN ───────────────────────────────────────────────────────── story.append(sec("N. TREATMENT PLAN")) story.append(gap(0.2*cm)) story.append(subsec("Definitive Treatment: Surgical Excision (Shelling Out)")) story.append(Paragraph( " Definitive treatment = complete excision of cyst WITH its wall (capsule). Incomplete removal leads to recurrence.", note_style )) story.append(gap(0.2*cm)) treat_data = [ ["Current state:", "Uninfected → proceed to elective excision / Infected → I&D first, then excision later"], ["Anaesthesia:", "Local infiltration (lignocaine 1-2% + adrenaline) / GA (if multiple cysts)"], ["Technique (Pye's):", "Elliptical incision centred on punctum, longer than cyst, ~1/3 of diameter in width"], [" Step 1:", "Mark the punctum; make elliptical incision around punctum including it in specimen"], [" Step 2:", "Dissect ellipse; seek plane of cleavage; shell out cyst without rupture if possible"], [" Step 3:", "If rupture occurs — meticulously remove ALL cyst wall (to prevent recurrence)"], [" Step 4:", "Haemostasis; obliterate dead space with absorbable sutures if needed; skin closure"], ["Infected cyst (I&D):", "Incise, express thick cheesy material manually (too thick to drain), pack wound"], [" Capsule removal:", "Pearly white capsule MUST be removed to prevent recurrence (on first follow-up if inflamed)"], ["Cock's peculiar tumour:", "Wide excision of the fungating mass with surrounding margin"], ["Sebaceous horn:", "Excision of horn and cyst base"], ["Specimen:", "Send ALL excised tissue for histopathological examination (HPE)"], ["Wound closure:", "Primary closure / Secondary healing (if infected) Suture: _______________"], ["Drain:", "Yes / No Type: ___________________ Removal on day: _______________"], ["Suture removal:", "Day __________ (usually day 7-10)"], ] treat_t = Table(treat_data, colWidths=[5*cm, 14*cm]) treat_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('ROWBACKGROUNDS', (0,0), (-1,-1), [ROW0, ROW1]), ('VALIGN', (0,0), (-1,-1), 'TOP'), ('BOTTOMPADDING', (0,0), (-1,-1), 3), ('TOPPADDING', (0,0), (-1,-1), 3), ])) story.append(treat_t) story.append(gap(0.3*cm)) story.append(subsec("Post-operative Instructions")) for item in [ "Wound care: keep dry for 48 h, daily dressing, watch for signs of infection", "Antibiotics: Yes / No If yes: ___________________________________________________", "Analgesics: ___________________________________________________________________", "Diet / Activity: No special restrictions", "Follow-up: After _______ days for wound check & suture removal", "HPE result to be collected at follow-up: Yes / No", "Recurrence counselling: if any cyst wall remnant left, recurrence possible", ]: story.append(f(f"• {item}")) story.append(gap()) # ── O. CLINICAL DRAWING ─────────────────────────────────────────────────────── story.append(sec("O. CLINICAL DRAWING — DIAGRAM OF SWELLING")) story.append(gap(0.2*cm)) draw_data = [ ["ANATOMICAL DIAGRAM (mark site, size, punctum, regional lymph nodes)", "CYST CROSS-SECTION DIAGRAM"], ["\n\n\n\n\n\n\n\n ", "\n\n\n\n\n\n\n\n "], ["Mark: Site / Size / Punctum position / Skin erythema / Regional nodes", "Label: Skin, Punctum, Cyst wall (capsule), Cheesy contents (sebum), Subcutaneous tissue"], ] draw_t = Table(draw_data, colWidths=[9.5*cm, 9.5*cm]) draw_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8), ('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'), ('BACKGROUND', (0,0), (-1,0), LTBLUE), ('TEXTCOLOR', (0,0), (-1,0), NAVY), ('ALIGN', (0,0), (-1,-1), 'CENTER'), ('GRID', (0,0), (-1,-1), 0.8, NAVY), ('MINROWHEIGHT', (0,1), (-1,1), 4*cm), ('VALIGN', (0,2), (-1,2), 'TOP'), ('FONTSIZE', (0,2), (-1,2), 7.5), ('TEXTCOLOR', (0,2), (-1,2), GRAY), ('BOTTOMPADDING', (0,0), (-1,-1), 5), ('TOPPADDING', (0,0), (-1,-1), 5), ])) story.append(draw_t) story.append(gap()) # ── P. FINAL DIAGNOSIS ──────────────────────────────────────────────────────── story.append(sec("P. FINAL DIAGNOSIS (AFTER INVESTIGATIONS & HPE)")) story.append(gap(0.2*cm)) story.append(f("Final diagnosis (clinical): ____________________________________________________________")) story.append(f("HPE result: Epidermoid cyst / Pilar cyst / Steatocystoma / Epidermoid carcinoma / Other: ___")) story.append(f("Benign / Malignant If malignant: refer for oncology management")) story.append(gap()) # ── Q. NOTES ────────────────────────────────────────────────────────────────── story.append(sec("Q. ADDITIONAL NOTES")) story.append(gap(0.2*cm)) for _ in range(4): story.append(f("_" * 100)) story.append(gap()) # ── R. SIGNATURES ───────────────────────────────────────────────────────────── story.append(sec("R. SIGNATURES")) story.append(gap(0.2*cm)) sig_data = [ ["Student Signature:", "_"*30, "Date:", "__________"], ["Guide / Tutor Signature:", "_"*30, "Grade / Marks:", "__________"], ] sig_t = Table(sig_data, colWidths=[5*cm, 6*cm, 3.5*cm, 4.5*cm]) sig_t.setStyle(TableStyle([ ('FONTSIZE', (0,0), (-1,-1), 8.5), ('FONTNAME', (0,0), (0,-1), 'Helvetica-Bold'), ('FONTNAME', (2,0), (2,-1), 'Helvetica-Bold'), ('BOTTOMPADDING', (0,0), (-1,-1), 6), ('TOPPADDING', (0,0), (-1,-1), 6), ])) story.append(sig_t) story.append(gap(0.25*cm)) # ── FOOTER ──────────────────────────────────────────────────────────────────── story.append(HRFlowable(width="100%", thickness=0.5, color=NAVY)) story.append(gap(0.15*cm)) story.append(Paragraph( "Reference: S Das — A Manual on Clinical Surgery, 13th Ed. | Pye's Surgical Handicraft, 22nd Ed. | " "Roberts & Hedges' Clinical Procedures in Emergency Medicine | Bailey & Love's Short Practice of Surgery, 28th Ed.", note_style )) doc.build(story) print("PDF generated!") PYEOF
Sebaceous Cyst Proforma
PDF Document · PDF