10 page case history report on cholecystitis
Make it look like a real patient
"acute cholecystitis"
acute cholecystitis current clinical practice guideline diagnosis treatment 2024
~/
mkdir -p "/tmp/workspace/cholecystitis-case-report/src" "/tmp/workspace/cholecystitis-case-report/output" && printf '%s' 'ready'
cat > "/tmp/workspace/cholecystitis-case-report/src/create_report.py" <<'PY' from docx import Document from docx.shared import Inches, Pt, RGBColor from docx.enum.text import WD_ALIGN_PARAGRAPH from docx.enum.table import WD_TABLE_ALIGNMENT, WD_CELL_VERTICAL_ALIGNMENT from docx.oxml import OxmlElement from docx.oxml.ns import qn from docx.enum.section import WD_SECTION from docx.enum.style import WD_STYLE_TYPE from docx.enum.text import WD_BREAK OUT='/tmp/workspace/cholecystitis-case-report/output/Case_History_Acute_Calculous_Cholecystitis.docx' doc=Document() sec=doc.sections[0] sec.top_margin=Inches(.65); sec.bottom_margin=Inches(.65); sec.left_margin=Inches(.72); sec.right_margin=Inches(.72) sec.header_distance=Inches(.3); sec.footer_distance=Inches(.3) styles=doc.styles styles['Normal'].font.name='Arial'; styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'),'Arial'); styles['Normal'].font.size=Pt(10) styles['Normal'].paragraph_format.space_after=Pt(4) styles['Normal'].paragraph_format.line_spacing=1.05 for name,size,color in [('Title',20,'17365D'),('Heading 1',15,'17365D'),('Heading 2',11,'1F4E79')]: st=styles[name]; st.font.name='Arial'; st.font.size=Pt(size); st.font.bold=True; st.font.color.rgb=RGBColor.from_string(color); st.paragraph_format.space_before=Pt(6); st.paragraph_format.space_after=Pt(4) # header/footer header=sec.header.paragraphs[0]; header.text='DE-IDENTIFIED TEACHING CASE | GENERAL SURGERY'; header.style='Caption'; header.alignment=WD_ALIGN_PARAGRAPH.RIGHT footer=sec.footer.paragraphs[0]; footer.alignment=WD_ALIGN_PARAGRAPH.CENTER footer.add_run('Acute calculous cholecystitis case history | ') fld=OxmlElement('w:fldSimple'); fld.set(qn('w:instr'),'PAGE'); footer._p.append(fld) def shade(cell,color): tcPr=cell._tc.get_or_add_tcPr(); shd=OxmlElement('w:shd'); shd.set(qn('w:fill'),color); tcPr.append(shd) def celltext(cell,txt,bold=False): cell.text=''; p=cell.paragraphs[0]; r=p.add_run(txt); r.bold=bold; p.paragraph_format.space_after=Pt(1); p.paragraph_format.space_before=Pt(1) def table(rows, widths=None): t=doc.add_table(rows=0, cols=2); t.alignment=WD_TABLE_ALIGNMENT.CENTER; t.style='Table Grid' for i,(a,b) in enumerate(rows): c=t.add_row().cells; celltext(c[0],a,True); celltext(c[1],b) shade(c[0],'D9EAF7'); c[0].vertical_alignment=WD_CELL_VERTICAL_ALIGNMENT.CENTER if widths: for row in t.rows: row.cells[0].width=Inches(widths[0]); row.cells[1].width=Inches(widths[1]) doc.add_paragraph('') def bullets(items): for x in items: doc.add_paragraph(x,style='List Bullet') def para(text,boldlead=None): p=doc.add_paragraph() if boldlead: p.add_run(boldlead).bold=True; p.add_run(text) else:p.add_run(text) def page(title, subtitle=None): if len(doc.paragraphs)>1: doc.add_page_break() doc.add_heading(title,0 if title.startswith('CASE HISTORY') else 1) if subtitle: p=doc.add_paragraph(subtitle); p.style='Subtitle' def smallnote(txt): p=doc.add_paragraph(txt); p.style='Caption'; p.paragraph_format.space_before=Pt(4) # 1 page('CASE HISTORY REPORT','Acute calculous cholecystitis - simulated, de-identified clinical record') p=doc.add_paragraph(); p.alignment=WD_ALIGN_PARAGRAPH.CENTER; r=p.add_run('For academic and clinical documentation practice only'); r.italic=True para('This is a realistic but fictional patient case. Names, registration number, address, hospital, and dates have been invented. It is not a record of a real person and should not be used for patient care.') doc.add_heading('Patient identification',1) table([('Name','Ms. R.K. (initials used for privacy)'),('Age / sex','42 years / female'),('Hospital number','SIM-GS-2026-1042'),('Date and time of admission','26 October 2026, 10:30 AM'),('Unit','General Surgery - Emergency Admission Unit'),('Informant and reliability','Patient herself; reliable'),('Provisional diagnosis at admission','Acute calculous cholecystitis')]) doc.add_heading('Presenting complaint',1) para('Right upper abdominal pain for 20 hours, associated with nausea, two episodes of non-bilious vomiting, and low-grade fever.') doc.add_heading('Clinical synopsis',1) para('A previously independent woman with obesity and dyslipidemia presented after persistent postprandial right upper quadrant pain that did not settle with an over-the-counter antacid. Examination found right upper quadrant tenderness and a positive Murphy sign. Leukocytosis and raised C-reactive protein supported inflammation. Ultrasound demonstrated gallstones, gallbladder distension, wall thickening, pericholecystic fluid, and sonographic Murphy sign, without common bile duct dilatation. The case was classified as mild acute calculous cholecystitis and managed with resuscitation, analgesia, antibiotics, and same-admission laparoscopic cholecystectomy.') smallnote('Prepared as a structured undergraduate/postgraduate surgical case history. Medication choices and operative decisions are illustrative and institution-dependent.') #2 page('1. HISTORY OF PRESENT ILLNESS') para('The patient was well until approximately 20 hours before admission, when she developed pain in the epigastrium about one hour after a fatty evening meal. Over the next 3 to 4 hours, the pain localized to the right hypochondrium and became constant. It was severe, rated 8/10, dull aching with intermittent colicky exacerbations, and radiated to the right scapular region. It was aggravated by movement, coughing, and deep inspiration. There was no meaningful relief with rest, antacid, or oral paracetamol.') para('Nausea began with the pain, followed by two small-volume episodes of non-bilious, non-bloody vomiting. She reported subjective fever and chills overnight but no rigors. She denied jaundice, pruritus, pale stools, dark urine, hematemesis, melena, diarrhea, constipation, dysuria, urinary frequency, vaginal bleeding, or vaginal discharge. There was no chest pain, dyspnea, cough, or syncope.') para('She recalled two previous brief episodes of similar right upper abdominal discomfort in the preceding six months, each occurring after a rich meal and resolving spontaneously within 2 to 3 hours. She had never undergone biliary imaging and had not sought medical attention for those episodes. There was no known history of pancreatitis, hepatitis, peptic ulcer disease, or inflammatory bowel disease.') doc.add_heading('Chronology',1) table([('Day -1, 2:00 PM','Fatty meal followed by epigastric discomfort.'),('Day -1, 6:00 PM','Pain localized to right upper quadrant and persisted.'),('Day -1, night','Nausea, vomiting, subjective fever; no jaundice.'),('Day 0, 9:30 AM','Attended emergency department owing to unremitting pain.'),('Day 0, 10:30 AM','Admitted under general surgery after assessment and ultrasound.')]) doc.add_heading('Relevant positive and negative features',1) bullets(['Positive: persistent right upper quadrant pain, feverishness, vomiting, local tenderness, previous meal-related episodes.','Negative: no jaundice or cholangitic features; no biochemical pancreatitis; no shock or altered mental status.','No recent surgery, critical illness, prolonged fasting, or total parenteral nutrition to suggest acalculous disease.']) #3 page('2. PAST, PERSONAL, AND FAMILY HISTORY') doc.add_heading('Past medical history',1) table([('Dyslipidemia','Diagnosed 2 years earlier; lifestyle management only.'),('Obesity','BMI 31.4 kg/m². No recent rapid weight-loss regimen.'),('Diabetes mellitus','No history; HbA1c on admission 5.6%.'),('Hypertension / cardiac disease','No history.'),('Liver disease / hepatitis','No history.'),('Previous operations','Lower-segment cesarean section 12 years earlier; uncomplicated.'),('Drug allergy','No known drug allergies.'),('Blood transfusion','None.'),('Prior hospitalization','Only for childbirth.')]) doc.add_heading('Medication history',1) para('No regular prescription medicines. Occasional paracetamol for headache. No anticoagulants, corticosteroids, oral contraceptive pills, GLP-1 receptor agonists, or herbal preparations. She had not taken antibiotics in the preceding three months.') doc.add_heading('Menstrual and obstetric history',1) para('Menarche at 13 years; cycles regular. Last menstrual period 12 days before admission. Gravida 2, para 2, both term deliveries. Urine pregnancy test on admission was negative. There is no current pregnancy or postpartum state.') doc.add_heading('Personal and social history',1) table([('Diet','Mixed diet with frequent fried foods; irregular meal timing because of shift work.'),('Appetite / weight','Normal appetite before illness; weight stable over 12 months.'),('Bowel / bladder','Regular bowel habit; no urinary symptoms.'),('Sleep','Disturbed only since onset of pain.'),('Tobacco','Never smoked.'),('Alcohol','Occasional social intake, less than 2 drinks per month.'),('Occupation','School administrator; independent in all activities of daily living.')]) doc.add_heading('Family history',1) para('Mother underwent cholecystectomy for symptomatic gallstones at age 51. No family history of hemolytic anemia, inflammatory bowel disease, hepatobiliary malignancy, or inherited liver disorder.') doc.add_heading('Risk profile',1) para('Female sex, obesity, dietary pattern, and possible family predisposition provide a plausible background for cholesterol gallstone disease. She did not have hemolysis, cirrhosis, ileal disease, pregnancy, or prolonged fasting.') #4 page('3. GENERAL AND SYSTEMIC EXAMINATION') doc.add_heading('General physical examination',1) table([('General condition','Alert, oriented, uncomfortable because of pain; not toxic appearing.'),('Build and nutrition','Moderately built and nourished; BMI 31.4 kg/m².'),('Temperature','38.2 °C oral.'),('Pulse','96/min, regular, normal volume.'),('Blood pressure','124/78 mmHg, right arm, supine.'),('Respiratory rate','18/min.'),('SpO₂','99% on room air.'),('Hydration','Mildly dry oral mucosa; no clinical shock.'),('Pallor / icterus','Absent / absent.'),('Cyanosis / clubbing','Absent / absent.'),('Lymph nodes / edema','No significant lymphadenopathy; no pedal edema.')]) doc.add_heading('Abdominal examination',1) para('Inspection: abdomen moved with respiration, not distended; umbilicus central; no scars except a healed Pfannenstiel scar; no visible veins, masses, hernia, or pulsations.') para('Palpation: localized guarding and marked tenderness in the right hypochondrium. Inspiratory arrest occurred during deep palpation at the right mid-clavicular subcostal point, constituting a positive clinical Murphy sign. No palpable gallbladder or hepatosplenomegaly. No rebound tenderness or generalized rigidity.') para('Percussion: normal liver dullness; no shifting dullness. Auscultation: bowel sounds present and normoactive. Renal angle tenderness absent.') doc.add_heading('Other systems',1) bullets(['Respiratory: trachea central, bilateral air entry equal, no crackles or pleural rub.','Cardiovascular: normal S1 and S2, no added sounds or murmur.','Central nervous system: grossly normal, Glasgow Coma Scale 15/15.','Skin and eyes: no jaundice, rash, xanthelasma, or stigmata of chronic liver disease.']) doc.add_heading('Bedside assessment',1) para('The patient met local inflammatory criteria through right upper quadrant tenderness and Murphy sign, along with fever and leukocytosis. The absence of jaundice, hypotension, confusion, generalized peritonitis, or organ dysfunction argued against severe disease, cholangitis, perforation, or septic shock at presentation.') #5 page('4. CLINICAL ASSESSMENT AND DIFFERENTIAL DIAGNOSIS') doc.add_heading('Problem representation',1) para('A 42-year-old woman with obesity and previous transient postprandial biliary-type pain presented with 20 hours of persistent right upper quadrant pain, fever, nausea and vomiting, focal tenderness with Murphy sign, inflammatory markers, and sonographic gallstones with gallbladder inflammatory changes, without jaundice or organ dysfunction.') doc.add_heading('Working diagnosis',1) para('Acute calculous cholecystitis, likely mild (Grade I) by Tokyo severity concepts. Cystic duct obstruction by an impacted gallstone was considered the initiating event.') doc.add_heading('Differential diagnosis',1) table([('Biliary colic','Prior episodes were compatible, but current pain persisted beyond the expected short attack and was accompanied by fever, leukocytosis, and gallbladder inflammatory findings.'),('Acute cholangitis','Considered because of biliary pain and fever; less likely because there was no jaundice, no common bile duct dilatation, and bilirubin/ALP were not obstructive.'),('Gallstone pancreatitis','Excluded by normal serum lipase and absence of characteristic epigastric pain radiating to the back.'),('Acute hepatitis','Less likely with normal transaminases and localized Murphy sign.'),('Peptic ulcer disease/perforation','No epigastric peritonitis, hematemesis, free air signs, or ulcer history.'),('Right lower lobe pneumonia','No respiratory symptoms or abnormal chest examination.'),('Renal colic/pyelonephritis','No urinary symptoms, hematuria, or renal angle tenderness.'),('Acute appendicitis','Pain location and ultrasound findings make this unlikely.'),('Acute coronary syndrome','Low probability, but ECG and troponin were normal as part of emergency evaluation.')]) doc.add_heading('Diagnostic basis',1) para('Acute cholecystitis is supported by the combination of local signs, systemic inflammation, and characteristic imaging. In this case, the three domains were all fulfilled. The ultrasound also helped exclude ductal dilatation and supported a calculous rather than acalculous process.') smallnote('Textbook basis: ultrasound findings consistent with acute cholecystitis include gallstones, wall thickening, gallbladder enlargement, pericholecystic fluid, and sonographic Murphy sign. Mulholland and Greenfield’s Surgery, 7th ed., p. 3054.') #6 page('5. INVESTIGATIONS') doc.add_heading('Laboratory results on admission',1) table([('Hemoglobin','12.8 g/dL (reference 12.0-15.5)'),('Total leukocyte count','14.7 × 10⁹/L (reference 4.0-11.0)'),('Neutrophils','82%'),('Platelets','312 × 10⁹/L'),('C-reactive protein','68 mg/L (elevated)'),('Serum bilirubin, total/direct','0.8 / 0.2 mg/dL'),('AST / ALT','28 / 31 U/L'),('ALP / GGT','108 / 46 U/L'),('Serum lipase','31 U/L (normal)'),('Creatinine / eGFR','0.72 mg/dL / >90 mL/min/1.73 m²'),('Sodium / potassium','138 / 4.0 mmol/L'),('Random blood glucose','104 mg/dL'),('Urinalysis','No blood, nitrites, or leukocytes'),('Urine β-hCG','Negative'),('Blood cultures','Two sets obtained before antibiotics; no growth at 48 hours.')]) doc.add_heading('Imaging',1) para('Right upper quadrant ultrasound, 26 October 2026: Gallbladder is distended. Multiple mobile echogenic calculi are present, the largest measuring 12 mm. A 9 mm calculus is impacted in the gallbladder neck. Wall thickness is 5.2 mm. Small rim of pericholecystic fluid is present. Sonographic Murphy sign is positive. Common bile duct measures 4.8 mm with no intraductal calculus visualized. Liver echotexture and pancreas are unremarkable. No ascites.') para('Impression: Cholelithiasis with imaging features of acute calculous cholecystitis. No sonographic evidence of choledocholithiasis.') doc.add_heading('Additional tests',1) bullets(['ECG: normal sinus rhythm; no ischemic changes.','Chest radiograph: no acute cardiopulmonary abnormality.','Preoperative anesthesia assessment: American Society of Anesthesiologists physical status II.']) doc.add_heading('Interpretation',1) para('Neutrophilic leukocytosis and CRP elevation corroborated acute inflammation. Normal bilirubin, cholestatic enzymes, and common bile duct caliber made retained common duct stone and ascending cholangitis less likely. Normal lipase argued against pancreatitis. Since the ultrasound was diagnostic and there were no discordant features, hepatobiliary scintigraphy, CT, MRCP, and ERCP were not required in this uncomplicated presentation.') #7 page('6. FINAL DIAGNOSIS AND INITIAL MANAGEMENT') doc.add_heading('Final diagnosis',1) para('Mild acute calculous cholecystitis caused by an impacted gallstone at the gallbladder neck, with cholelithiasis. There was no evidence of choledocholithiasis, acute cholangitis, gallstone pancreatitis, emphysematous cholecystitis, gangrene, perforation, or organ dysfunction.') doc.add_heading('Severity and operative fitness',1) para('The patient had no hypotension requiring vasopressors, altered consciousness, respiratory, renal, hepatic, hematologic, or cardiovascular failure. The inflammatory process was localized and early. She was judged appropriate for early laparoscopic cholecystectomy during the index admission after resuscitation and anesthetic review.') doc.add_heading('Emergency department and ward plan',1) table([('Nil by mouth','Maintained initially; oral intake resumed after recovery according to clinical progress.'),('Intravenous fluids','Balanced crystalloid infusion with reassessment of urine output, vitals, and electrolytes.'),('Analgesia','IV paracetamol; opioid rescue analgesia as required. NSAID use considered if no renal/GI contraindication.'),('Antiemetic','Ondansetron as needed for vomiting.'),('Antibiotic therapy','IV ceftriaxone plus metronidazole, adjusted to local antimicrobial policy, allergy profile, severity, and culture data.'),('Thromboprophylaxis','Mechanical prophylaxis and early mobilization; pharmacologic prophylaxis per local perioperative protocol.'),('Monitoring','Temperature chart, pain score, abdominal signs, vital signs, intake-output, WBC/CRP trend.'),('Definitive treatment','Laparoscopic cholecystectomy after informed consent.')]) doc.add_heading('Consent discussion',1) para('The surgeon discussed the diagnosis, expected benefits of removing the gallbladder, nonoperative alternatives, and possible risks: bleeding, infection, bile leak, common bile duct injury, retained stone, conversion to open procedure, adjacent organ injury, port-site hernia, venous thromboembolism, and anesthetic complications. The patient demonstrated understanding and gave written consent.') smallnote('Teaching point: initial stabilization commonly includes fasting, IV fluids, analgesia, and antibiotics where clinically indicated, followed by cholecystectomy based on severity and operative risk. The exact regimen is governed by local guidance.') #8 page('7. OPERATIVE NOTE') doc.add_heading('Procedure',1) table([('Date / time','27 October 2026, 9:15 AM'),('Operation','Early laparoscopic cholecystectomy'),('Anesthesia','General endotracheal anesthesia'),('Primary surgeon','Consultant general surgeon with resident assistance'),('Preoperative diagnosis','Acute calculous cholecystitis'),('Postoperative diagnosis','Acute calculous cholecystitis with impacted neck stone'),('Wound classification','Clean-contaminated'),('Estimated blood loss','25 mL'),('Specimen','Gallbladder sent for histopathology'),('Complications','None encountered'),('Drain','Not placed')]) doc.add_heading('Operative findings',1) para('The gallbladder was distended and edematous with acute inflammatory changes, fibrinous exudate over the fundus, and adhesions of omentum to the body and neck. There was no gangrene, perforation, abscess, or bile peritonitis. A firm calculus was palpable within the neck. The common bile duct was not dilated.') doc.add_heading('Procedure details',1) para('Following safety checks, pneumoperitoneum was established and standard four-port laparoscopy performed. Adhesions were carefully released. The gallbladder was decompressed to aid retraction. The hepatocystic triangle was dissected with attention to obtain the critical view of safety: two and only two structures entering the gallbladder and the lower third of the gallbladder separated from the liver bed. The cystic artery and cystic duct were clipped and divided. The gallbladder was removed from the liver bed using electrocautery, placed in a retrieval bag, and extracted through the umbilical port. Hemostasis was confirmed; there was no bile leak. Ports were closed in the standard manner.') doc.add_heading('Immediate postoperative orders',1) bullets(['Recovery-room monitoring of airway, hemodynamics, pain, nausea, and surgical sites.','Oral fluids when fully awake, advancing to a light diet as tolerated.','Multimodal analgesia and antiemetic therapy as needed.','Ambulation on the day of surgery and breathing exercises.','Review CBC and liver biochemistry if clinically indicated; no routine imaging planned in an uncomplicated recovery.']) #9 page('8. POSTOPERATIVE COURSE, DISCHARGE, AND FOLLOW-UP') doc.add_heading('Inpatient progress',1) table([('Postoperative day 0','Hemodynamically stable; pain 3/10 on oral analgesia; tolerated sips of water and later light diet. No vomiting.'),('Postoperative day 1','Afebrile; mobilizing independently; tolerating regular low-fat diet; passing urine; port sites clean and dry. Abdomen soft with mild expected incisional tenderness.'),('Postoperative labs','WBC 10.6 × 10⁹/L; bilirubin and transaminases remained normal.'),('Discharge','28 October 2026, approximately 24 hours after surgery, in stable condition.')]) doc.add_heading('Histopathology',1) para('Gallbladder: acute-on-chronic cholecystitis with mucosal ulceration, transmural acute inflammatory infiltrate, edema, and cholelithiasis. No dysplasia or malignancy identified.') doc.add_heading('Discharge plan',1) bullets(['Regular diet as tolerated; temporarily avoid very fatty foods if they provoke dyspepsia. Maintain hydration and gradual return to normal activity.','Keep port sites clean and dry. Showering permitted according to local wound-care instructions; avoid soaking until wounds heal.','Use prescribed non-opioid analgesia first line; take rescue medication only as directed.','Avoid heavy lifting and strenuous abdominal exercise for the period advised by the operating team.','Review in surgical outpatient clinic in 1 to 2 weeks for wound assessment and pathology discussion.']) doc.add_heading('Return precautions',1) para('The patient was advised to seek urgent assessment for fever, worsening abdominal pain, persistent vomiting, progressive jaundice, dark urine, pale stools, redness or purulent discharge from wounds, chest pain, shortness of breath, or inability to tolerate fluids.') doc.add_heading('Follow-up visit: 10 November 2026',1) para('She reported complete resolution of preoperative biliary pain. Appetite and bowel habit were normal. She required no further analgesia. All port sites were healed without erythema or discharge. No jaundice or abdominal tenderness was present. She was discharged from routine surgical follow-up with advice to return if symptoms recurred.') #10 page('9. DISCUSSION, LEARNING POINTS, AND REFERENCES') doc.add_heading('Discussion',1) para('Acute calculous cholecystitis generally follows persistent obstruction of the cystic duct or gallbladder neck by a stone. Obstruction causes bile stasis, gallbladder distension, wall edema, mucosal injury, and inflammation. Secondary bacterial infection can complicate the course. In the presented case, the history of prior brief postprandial episodes probably represented biliary colic, whereas the persistence of pain with fever and inflammatory markers signaled progression to acute cholecystitis.') para('The diagnostic confidence in this case came from convergence of local signs, systemic inflammation, and ultrasound findings. This is preferable to relying on a single test. Ultrasound is the first-line imaging modality in many settings because it demonstrates stones, wall thickening, distension, pericholecystic fluid, and sonographic Murphy sign, while also assessing the bile duct. Further imaging is reserved for uncertain cases or suspected complications/ductal stones.') para('This patient was stable with no organ dysfunction and no evidence of common duct obstruction. After initial resuscitation, early laparoscopic cholecystectomy provided definitive treatment within the index admission. The operation was uncomplicated because anatomy was safely identified using the critical view of safety. Histology confirmed acute-on-chronic inflammation, which fitted her preceding episodes.') doc.add_heading('Learning points',1) bullets(['Persistent right upper quadrant pain with fever and Murphy sign should prompt assessment for acute cholecystitis rather than labeling the episode as simple biliary colic.','Check for jaundice, cholestatic liver tests, duct dilatation, and systemic toxicity, as these change the likelihood of choledocholithiasis, cholangitis, and severity.','Use clinical findings, inflammatory tests, and imaging together.','Stabilize with fasting, fluids, analgesia, antiemetics, and appropriately selected antibiotics while planning source control.','Early laparoscopic cholecystectomy is appropriate for many fit patients with mild disease, but timing and technique must be individualized.','A difficult dissection requires a safety-first approach, senior support, and consideration of bail-out strategies rather than unsafe pursuit of anatomy.']) doc.add_heading('Selected references',1) para('1. Goldman-Cecil Medicine. Acute Calculus Cholecystitis. 27th ed. Elsevier. pp. 1635-1636.','') para('2. Mulholland and Greenfield’s Surgery: Scientific Principles and Practice. Cholecystitis. 7th ed. Elsevier. p. 3054.','') para('3. Sleisenger and Fordtran’s Gastrointestinal and Liver Disease. Acute Cholecystitis. 11th ed. Elsevier. pp. 1241-1244.','') para('4. Schwartz’s Principles of Surgery. Symptomatic Gallstones. 11th ed. McGraw-Hill.','') para('5. Childs DD, Lalwani N, Craven T, et al. A meta-analysis of the performance of ultrasound, hepatobiliary scintigraphy, CT and MRI in the diagnosis of acute cholecystitis. Abdominal Radiology. 2024. PMID: 37982832.','') smallnote('Recent-evidence note: the 2024 imaging meta-analysis supports the need to interpret imaging within the clinical context; the report is a teaching simulation and does not replace local protocols or specialist judgment.') # core properties doc.core_properties.title='Case History Report - Acute Calculous Cholecystitis' doc.core_properties.subject='De-identified simulated general surgery case history' doc.core_properties.author='Orris' doc.save(OUT) print(OUT) PY python "/tmp/workspace/cholecystitis-case-report/src/create_report.py"
~/cholecystitis-case-report/output
python - <<'PY' from docx import Document p='/tmp/workspace/cholecystitis-case-report/output/Case_History_Acute_Calculous_Cholecystitis.docx' d=Document(p) print('paragraphs',len(d.paragraphs),'tables',len(d.tables),'sections',len(d.sections)) text='\n'.join(x.text for x in d.paragraphs) for s in ['Acute calculous cholecystitis','HISTORY OF PRESENT ILLNESS','INVESTIGATIONS','OPERATIVE NOTE','DISCUSSION, LEARNING POINTS, AND REFERENCES']: print(s, s in text) print('pagebreaks',sum(1 for x in d.paragraphs if 'w:type="page"' in x._p.xml)) PY
Create a PDF version of the cholecystitis case report
~/
~/cholecystitis-case-report
python - <<'PY' from docx import Document p='/tmp/workspace/cholecystitis-case-report/output/Case_History_Acute_Calculous_Cholecystitis.docx' d=Document(p) print('Source:',p) print('Paragraphs:',len(d.paragraphs),'Tables:',len(d.tables)) for x in d.paragraphs[:12]: if x.text.strip(): print(x.style.name, repr(x.text[:110])) PY
cat > "/tmp/workspace/cholecystitis-case-report/src/create_pdf.py" <<'PY' from docx import Document from docx.table import Table from docx.text.paragraph import Paragraph from docx.oxml.ns import qn from reportlab.lib.pagesizes import A4 from reportlab.lib import colors from reportlab.lib.colors import HexColor from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle from reportlab.lib.enums import TA_CENTER, TA_LEFT from reportlab.lib.units import inch from reportlab.platypus import SimpleDocTemplate, Paragraph as RP, Spacer, Table as RT, TableStyle, PageBreak, KeepTogether from reportlab.pdfbase.ttfonts import TTFont from reportlab.pdfbase import pdfmetrics from reportlab.pdfbase.pdfmetrics import stringWidth from reportlab.lib.utils import simpleSplit from reportlab.pdfbase.pdfdoc import PDFInfo from pypdf import PdfReader import os SRC='/tmp/workspace/cholecystitis-case-report/output/Case_History_Acute_Calculous_Cholecystitis.docx' OUT='/tmp/workspace/cholecystitis-case-report/output/Case_History_Acute_Calculous_Cholecystitis.pdf' # Helvetica is embedded as a built-in PDF font and renders cleanly on all readers. styles=getSampleStyleSheet() normal=ParagraphStyle('Body',parent=styles['BodyText'],fontName='Helvetica',fontSize=8.25,leading=9.55,spaceAfter=2.5,textColor=HexColor('#202020'),alignment=TA_LEFT) title=ParagraphStyle('CaseTitle',parent=styles['Title'],fontName='Helvetica-Bold',fontSize=18,leading=20,spaceAfter=3,textColor=HexColor('#17365D'),alignment=TA_CENTER) subtitle=ParagraphStyle('Subtitle',parent=normal,fontName='Helvetica-Oblique',fontSize=9.5,leading=11,spaceAfter=5,alignment=TA_CENTER,textColor=HexColor('#4F4F4F')) h1=ParagraphStyle('H1',parent=styles['Heading1'],fontName='Helvetica-Bold',fontSize=12.5,leading=14.5,spaceBefore=4,spaceAfter=3,textColor=HexColor('#17365D')) h2=ParagraphStyle('H2',parent=styles['Heading2'],fontName='Helvetica-Bold',fontSize=9.7,leading=11.3,spaceBefore=3.5,spaceAfter=2,textColor=HexColor('#1F4E79')) caption=ParagraphStyle('Caption',parent=normal,fontName='Helvetica-Oblique',fontSize=6.8,leading=8.2,spaceBefore=2,spaceAfter=1,textColor=HexColor('#555555')) # Escape the document text for ReportLab's mini-XML from xml.sax.saxutils import escape def clean(text): return escape((text or '').replace('\u00a0',' ').replace(' ',' ')).replace('\n','<br/>') def para_style(p): n=p.style.name if p.style else 'Normal' txt=p.text.strip() if n=='Title': return title if n=='Subtitle': return subtitle if n.startswith('Heading 1') or n.startswith('Heading 2') or n=='Heading 1': return h1 if n.startswith('Heading 1') else h2 if n=='Caption': return caption if n.startswith('List Bullet'): return ParagraphStyle('Bullet',parent=normal,leftIndent=11,firstLineIndent=-7,bulletIndent=0,spaceAfter=1.2) return normal def has_page_break(p): # report a page break appearing in any run for br in p._p.iter(qn('w:br')): if br.get(qn('w:type'))=='page': return True # fallback for w:lastRenderedPageBreak return bool(p._p.findall('.//' + qn('w:lastRenderedPageBreak'))) def iter_block_items(parent): parent_elm=parent.element.body for child in parent_elm.iterchildren(): if child.tag==qn('w:p'): yield Paragraph(child,parent) elif child.tag==qn('w:tbl'): yield Table(child,parent) def table_flow(t): data=[] for row in t.rows: vals=[] for j,c in enumerate(row.cells): s=' '.join(p.text.strip() for p in c.paragraphs if p.text.strip()) vals.append(RP(clean(s), ParagraphStyle('cellL' if j==0 else 'cellR',parent=normal,fontName='Helvetica-Bold' if j==0 else 'Helvetica',fontSize=7.2,leading=8.3,spaceAfter=0))) data.append(vals) w=7.45*inch tab=RT(data,colWidths=[1.8*inch,w-1.8*inch],repeatRows=0,hAlign='CENTER') tab.setStyle(TableStyle([ ('GRID',(0,0),(-1,-1),0.35,HexColor('#AAB9C8')), ('BACKGROUND',(0,0),(0,-1),HexColor('#D9EAF7')), ('VALIGN',(0,0),(-1,-1),'MIDDLE'), ('LEFTPADDING',(0,0),(-1,-1),4),('RIGHTPADDING',(0,0),(-1,-1),4), ('TOPPADDING',(0,0),(-1,-1),2.3),('BOTTOMPADDING',(0,0),(-1,-1),2.3), ])) return [tab,Spacer(1,2)] docx=Document(SRC) story=[] for block in iter_block_items(docx): if isinstance(block, Paragraph): txt=block.text.strip() # Make explicit source-page transitions without adding an empty flowable. if has_page_break(block) and not txt: story.append(PageBreak()); continue if txt: st=para_style(block) if (block.style.name if block.style else '')=='List Bullet': story.append(RP(clean(txt),st,bulletText='•')) else: story.append(RP(clean(txt),st)) if has_page_break(block): story.append(PageBreak()) else: story.extend(table_flow(block)) # Header and footer page_no=[0] def on_page(canvas, doc): page_no[0]+=1 canvas.saveState() W,H=A4 canvas.setStrokeColor(HexColor('#B8C8D8')); canvas.setLineWidth(.45) canvas.line(.48*inch,H-.36*inch,W-.48*inch,H-.36*inch) canvas.setFont('Helvetica',6.8); canvas.setFillColor(HexColor('#526D87')) canvas.drawRightString(W-.48*inch,H-.28*inch,'DE-IDENTIFIED TEACHING CASE | GENERAL SURGERY') canvas.line(.48*inch,.38*inch,W-.48*inch,.38*inch) canvas.setFont('Helvetica',6.8); canvas.setFillColor(HexColor('#526D87')) canvas.drawCentredString(W/2,.24*inch,f'Acute calculous cholecystitis case history | {page_no[0]}') canvas.restoreState() pdf=SimpleDocTemplate(OUT,pagesize=A4,rightMargin=.48*inch,leftMargin=.48*inch,topMargin=.48*inch,bottomMargin=.5*inch,title='Case History Report - Acute Calculous Cholecystitis',author='Orris',subject='De-identified simulated general surgery case history') pdf.build(story,onFirstPage=on_page,onLaterPages=on_page) reader=PdfReader(OUT) print(f'Created: {OUT}') print(f'Pages: {len(reader.pages)}') print(f'First page chars: {len(reader.pages[0].extract_text() or "")}') PY python "/tmp/workspace/cholecystitis-case-report/src/create_pdf.py"
~/cholecystitis-case-report/output
python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/cholecystitis-case-report/output/Case_History_Acute_Calculous_Cholecystitis.pdf' r=PdfReader(p) print('pages=',len(r.pages),'bytes=',__import__('os').path.getsize(p)) for i,pg in enumerate(r.pages,1): tx=pg.extract_text() or '' print(i, len(tx), tx[:60].replace('\n',' | ')) assert len(r.pages)==10 assert all((pg.extract_text() or '').strip() for pg in r.pages) PY
Case History Acute Calculous Cholecystitis
PDF Document · PDF