attachment
attachment

Explain in this where there are nodules and opacity

analyse_media
Here is a breakdown of where the nodules and opacities are on this chest X-ray (67-year-old, PA view, with hemoptysis + right chest pain + fever):

RIGHT LUNG - Primary Abnormalities

1. Dense Consolidation (Opacity) - Right Upper Zone to Mid Zone

  • Location: Right upper lobe (RUL), extending to the right mid-zone
  • Character: Large, dense, homogeneous white opacity - this is the most prominent abnormal finding
  • Lower border: Sharply cut off by the minor (horizontal) fissure - this sharp edge is the hallmark of true lobar consolidation confined to the RUL
  • Air bronchograms: Faint dark branching tubes are visible within the white opacity, confirming alveolar filling (not just collapse)

2. Reticulonodular Opacities - Right Mid to Lower Zone

  • Location: Below the horizontal fissure, right mid and lower lung zones
  • Character: Patchy, ill-defined, grainy/nodular opacities - less dense than the upper consolidation
  • These likely represent bronchogenic spread from the upper lobe process, aspiration, or reactive interstitial changes

SUPPORTING FINDINGS

FindingDetail
Tracheal deviationMild shift to the right - suggests volume loss from the RUL consolidation
Right hemidiaphragmSlightly elevated - consistent with right lung volume loss
Right costophrenic anglePartially blunted - possible small reactive pleural effusion
Left lungLargely clear, no focal opacities or nodules
Left costophrenic angleSharp and normal

Differential Diagnosis (given clinical triad)

  1. Pulmonary TB (reactivation) - RUL consolidation is the classic site; in a 67-year-old with hemoptysis, this is high on the list. Cavitation may not be visible on plain film.
  2. Post-obstructive pneumonia from bronchogenic carcinoma - Hemoptysis in a 67-year-old + RUL collapse/consolidation = must rule out endobronchial mass
  3. Lobar pneumonia (Klebsiella or Streptococcus pneumoniae) - Fever and dense consolidation fit, but hemoptysis is less typical
Next step: Contrast-enhanced CT chest - to look for cavitation, endobronchial lesion, mediastinal lymph nodes, and characterize the reticulonodular component better.

Create a summary document comparing TB vs lung cancer presentation in elderly patients

Asking for Preferences
Reading File
Finding Sources
Finding Sources
Finding Sources
Finding Sources
Reading File
Reading File
Finding Sources
Finding Sources
Reading File
Reading File
Running Command

mkdir -p /home/daytona/workspace/tb-vs-lungca && ls /home/daytona/workspace/tb-v…

Writing File

~/tb-vs-lungca/generate_pdf.py

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

OUTPUT = "/home/daytona/workspace/tb-vs-lungca/TB_vs_LungCancer_Elderly.pdf"

doc = SimpleDocTemplate(
    OUTPUT,
    pagesize=A4,
    rightMargin=2*cm, leftMargin=2*cm,
    topMargin=2.2*cm, bottomMargin=2*cm
)

W, H = A4
styles = getSampleStyleSheet()

# ---- custom styles ----
title_style = ParagraphStyle(
    "DocTitle", fontSize=20, leading=26, alignment=TA_CENTER,
    textColor=colors.HexColor("#1a3c5e"), fontName="Helvetica-Bold",
    spaceAfter=4
)
subtitle_style = ParagraphStyle(
    "SubTitle", fontSize=11, leading=14, alignment=TA_CENTER,
    textColor=colors.HexColor("#4a4a4a"), fontName="Helvetica",
    spaceAfter=2
)
date_style = ParagraphStyle(
    "DateStyle", fontSize=9, alignment=TA_CENTER,
    textColor=colors.HexColor("#888888"), spaceAfter=12
)
section_style = ParagraphStyle(
    "Section", fontSize=13, leading=18, fontName="Helvetica-Bold",
    textColor=colors.HexColor("#1a3c5e"), spaceBefore=14, spaceAfter=4
)
sub_section_style = ParagraphStyle(
    "SubSection", fontSize=10.5, leading=14, fontName="Helvetica-Bold",
    textColor=colors.HexColor("#2c5f8a"), spaceBefore=8, spaceAfter=3
)
body_style = ParagraphStyle(
    "Body", fontSize=9.5, leading=13.5, fontName="Helvetica",
    textColor=colors.HexColor("#222222"), spaceAfter=4, alignment=TA_JUSTIFY
)
bullet_style = ParagraphStyle(
    "Bullet", fontSize=9.5, leading=13, fontName="Helvetica",
    textColor=colors.HexColor("#222222"), spaceAfter=2,
    leftIndent=14, bulletIndent=4
)
footer_style = ParagraphStyle(
    "Footer", fontSize=7.5, alignment=TA_CENTER,
    textColor=colors.HexColor("#aaaaaa")
)
source_style = ParagraphStyle(
    "Source", fontSize=8, leading=11, fontName="Helvetica-Oblique",
    textColor=colors.HexColor("#555555"), spaceAfter=2, leftIndent=10
)
callout_style = ParagraphStyle(
    "Callout", fontSize=9.5, leading=13, fontName="Helvetica-BoldOblique",
    textColor=colors.HexColor("#8b0000"), alignment=TA_CENTER,
    spaceAfter=2, spaceBefore=4
)

# ---- colour palette ----
TB_COL   = colors.HexColor("#e8f4f8")   # light blue
LC_COL   = colors.HexColor("#fff3e0")   # light orange
HDR_BLUE = colors.HexColor("#1a3c5e")
HDR_ORG  = colors.HexColor("#b85c00")
ROW_ALT  = colors.HexColor("#f4f9fb")
GRID     = colors.HexColor("#c0c0c0")

def hr(c="#c0c0c0", t=0.5):
    return HRFlowable(width="100%", thickness=t, color=colors.HexColor(c), spaceAfter=6, spaceBefore=2)

def section(text):
    return Paragraph(text, section_style)

def subsection(text):
    return Paragraph(text, sub_section_style)

def body(text):
    return Paragraph(text, body_style)

def bullet(text):
    return Paragraph(f"•  {text}", bullet_style)

def source(text):
    return Paragraph(f"<i>Source: {text}</i>", source_style)

# =====================================================================
story = []

# --- HEADER BANNER ---
story.append(Spacer(1, 0.3*cm))
story.append(Paragraph("TB vs Lung Cancer in Elderly Patients", title_style))
story.append(Paragraph("A Clinical Comparison Summary", subtitle_style))
story.append(Paragraph("Prepared July 2026 | Based on Harrison's, Goldman-Cecil, Fishman's, Grainger & Allison's", date_style))
story.append(hr("#1a3c5e", 1.5))
story.append(Spacer(1, 0.2*cm))

# --- INTRODUCTION ---
story.append(section("1.  Background & Clinical Relevance"))
story.append(body(
    "Pulmonary tuberculosis (TB) and primary lung cancer share a striking overlap in their clinical and "
    "radiological presentations, particularly in elderly patients (age &gt;60 years). Both conditions can "
    "manifest with chronic cough, haemoptysis, weight loss, fever, and upper lobe opacities on chest "
    "radiograph. Misdiagnosis is common and delays treatment. A 67-year-old patient with haemoptysis, "
    "right chest pain, fever, and right upper lobe consolidation (as in this case) represents the classic "
    "diagnostic dilemma."
))
story.append(body(
    "In high-prevalence TB settings, TB is assumed first. In low-prevalence settings, obstructive malignancy "
    "must always be excluded. Either condition can co-exist: TB-associated scar carcinoma and post-TB "
    "bronchiectasis are well-recognised entities."
))
story.append(Spacer(1, 0.3*cm))

# =====================================================================
# SECTION 2 - BIG COMPARISON TABLE
# =====================================================================
story.append(section("2.  Side-by-Side Comparison"))
story.append(hr())

col_w = [3.8*cm, 7.5*cm, 7.5*cm]

table_data = [
    # header
    [
        Paragraph("<b>Feature</b>", ParagraphStyle("H", fontSize=10, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER)),
        Paragraph("<b>Pulmonary Tuberculosis</b>", ParagraphStyle("H", fontSize=10, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER)),
        Paragraph("<b>Lung Cancer (NSCLC/SCLC)</b>", ParagraphStyle("H", fontSize=10, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER)),
    ],
    # demographics
    [
        Paragraph("<b>Typical age</b>", bullet_style),
        Paragraph("Any age; reactivation TB peaks in elderly males", body_style),
        Paragraph("Peak 50-70 years; strong male predominance in smokers", body_style),
    ],
    [
        Paragraph("<b>Risk factors</b>", bullet_style),
        Paragraph("HIV, diabetes, malnutrition, immunosuppression, crowding, prior TB infection, silicosis", body_style),
        Paragraph("Cigarette smoking (80-90%), asbestos, radon, COPD, family history, occupational carcinogens", body_style),
    ],
    [
        Paragraph("<b>Onset</b>", bullet_style),
        Paragraph("Subacute to chronic — weeks to months of progressive symptoms", body_style),
        Paragraph("Insidious; 25% asymptomatic at diagnosis (found incidentally on CXR/CT)", body_style),
    ],
    # symptoms
    [
        Paragraph("<b>Cough</b>", bullet_style),
        Paragraph("Present in most; productive, mucopurulent, may be blood-streaked", body_style),
        Paragraph("8-75% frequency; can be dry or productive; new persistent cough in a smoker is a red flag", body_style),
    ],
    [
        Paragraph("<b>Haemoptysis</b>", bullet_style),
        Paragraph("Common (up to 30%); classically small-volume, blood-streaked sputum; massive haemoptysis in cavitary disease", body_style),
        Paragraph("6-35% frequency; often small-volume; massive haemoptysis less typical than TB", body_style),
    ],
    [
        Paragraph("<b>Fever</b>", bullet_style),
        Paragraph("Low-grade evening fever ('hectic fever') is classic; may have drenching night sweats", body_style),
        Paragraph("0-20%; fever suggests post-obstructive pneumonia or tumour necrosis, not the primary tumour", body_style),
    ],
    [
        Paragraph("<b>Weight loss</b>", bullet_style),
        Paragraph("Progressive, often significant; part of classic triad with fever and night sweats", body_style),
        Paragraph("0-68%; weight loss comparable to cough as a presenting symptom; cancer cachexia in advanced disease", body_style),
    ],
    [
        Paragraph("<b>Night sweats</b>", bullet_style),
        Paragraph("Classic constitutional symptom; drenching night sweats in active TB", body_style),
        Paragraph("Uncommon as primary symptom; may occur with paraneoplastic syndromes or post-obstructive infection", body_style),
    ],
    [
        Paragraph("<b>Chest pain</b>", bullet_style),
        Paragraph("Pleuritic pain if pleural involvement; generally mild", body_style),
        Paragraph("20-49%; pain from pleural/chest wall invasion; Pancoast tumour causes shoulder/arm pain", body_style),
    ],
    [
        Paragraph("<b>Dyspnoea</b>", bullet_style),
        Paragraph("Late feature unless extensive parenchymal disease or effusion", body_style),
        Paragraph("3-60%; endobronchial obstruction causes air-trapping, wheezing, or lobar collapse", body_style),
    ],
    [
        Paragraph("<b>Clubbing</b>", bullet_style),
        Paragraph("Rare; can occur in chronic pulmonary TB or empyema", body_style),
        Paragraph("0-20%; hypertrophic pulmonary osteoarthropathy (HPOA) associated particularly with adenocarcinoma", body_style),
    ],
    # radiology
    [
        Paragraph("<b>CXR location</b>", bullet_style),
        Paragraph("Classically upper lobe (posterior segment RUL and apical-posterior LUL); bilateral apical disease in miliary TB", body_style),
        Paragraph("No fixed lobar predilection, but right upper lobe is most common for NSCLC; central vs peripheral varies by histology", body_style),
    ],
    [
        Paragraph("<b>CXR character</b>", bullet_style),
        Paragraph("Patchy/nodular infiltrates, ill-defined consolidation; cavitation is characteristic of reactivation TB", body_style),
        Paragraph("Solitary pulmonary nodule or mass; hilar enlargement; post-obstructive consolidation; pleural effusion", body_style),
    ],
    [
        Paragraph("<b>Cavitation</b>", bullet_style),
        Paragraph("Highly characteristic of reactivation TB; thick-walled cavity with air-fluid level", body_style),
        Paragraph("Can occur (particularly squamous cell carcinoma); thick irregular wall; no satellite nodules", body_style),
    ],
    [
        Paragraph("<b>Fissure sign</b>", bullet_style),
        Paragraph("Minor fissure elevation with RUL collapse/consolidation; 'Golden S sign' not typical for TB", body_style),
        Paragraph("'Golden S sign' (reversed S-shape of minor fissure) is classic for central obstructing RUL mass", body_style),
    ],
    [
        Paragraph("<b>Lymphadenopathy</b>", bullet_style),
        Paragraph("Hilar and paratracheal nodes; may calcify ('egg-shell' calcification in some)", body_style),
        Paragraph("Mediastinal and hilar nodes common; non-calcified; central location suggests N2/N3 disease", body_style),
    ],
    [
        Paragraph("<b>Pleural effusion</b>", bullet_style),
        Paragraph("Exudative; lymphocyte-predominant; ADA elevated; culture-positive in <30%", body_style),
        Paragraph("Exudative; malignant cells on cytology; poor prognostic sign (stage IIIB/IV)", body_style),
    ],
    # labs
    [
        Paragraph("<b>Sputum AFB smear</b>", bullet_style),
        Paragraph("Positive in 50-80% of smear-positive TB; 3 samples on separate mornings recommended", body_style),
        Paragraph("Negative (unless co-existing TB)", body_style),
    ],
    [
        Paragraph("<b>GeneXpert MTB/RIF</b>", bullet_style),
        Paragraph(">95% sensitive in smear-positive; ~70% in smear-negative; also detects rifampicin resistance", body_style),
        Paragraph("Negative", body_style),
    ],
    [
        Paragraph("<b>Sputum cytology</b>", bullet_style),
        Paragraph("Negative for malignant cells", body_style),
        Paragraph("Positive in 20-30%; low sensitivity for peripheral lesions; useful for central tumours", body_style),
    ],
    [
        Paragraph("<b>Bronchoscopy</b>", bullet_list),
        Paragraph("BAL AFB culture; transbronchial biopsy for miliary/endobronchial TB; therapeutic if haemoptysis", body_style),
        Paragraph("Tissue biopsy for histology and molecular profiling (EGFR, ALK, PD-L1); essential for treatment planning", body_style),
    ],
    [
        Paragraph("<b>CT chest</b>", bullet_style),
        Paragraph("Centrilobular nodules, 'tree-in-bud' pattern, upper lobe fibrosis, cavitation, satellite lesions", body_style),
        Paragraph("Spiculated mass with pleural tethering; post-obstructive collapse; mediastinal invasion; PET/CT for staging", body_style),
    ],
    [
        Paragraph("<b>Blood markers</b>", bullet_style),
        Paragraph("ESR elevated; lymphocytosis; ADA in pleural fluid; IGRA/TST for latent TB (cannot confirm active disease)", body_style),
        Paragraph("CEA, CYFRA 21-1, NSE (limited specificity); LDH elevated; hyponatraemia (SIADH in SCLC)", body_style),
    ],
    # treatment
    [
        Paragraph("<b>Treatment</b>", bullet_style),
        Paragraph("HRZE x 2 months then HR x 4 months (6-month standard regimen); DOT recommended in elderly for adherence", body_style),
        Paragraph("NSCLC: surgery (early), platinum-doublet chemo, immunotherapy (PD-1/L1), targeted therapy (EGFR/ALK); SCLC: chemo-radiation", body_style),
    ],
    [
        Paragraph("<b>Prognosis</b>", bullet_style),
        Paragraph("Cure rate >85% with drug-sensitive TB and good adherence; worse in elderly with co-morbidities", body_style),
        Paragraph("5-year survival ~20% overall; stage I resected NSCLC ~70%; SCLC <10% at 5 years", body_style),
    ],
]

ts = TableStyle([
    # Header row
    ("BACKGROUND", (0, 0), (-1, 0), HDR_BLUE),
    ("BACKGROUND", (1, 0), (1, 0), HDR_BLUE),
    ("BACKGROUND", (2, 0), (2, 0), HDR_ORG),
    ("FONTNAME",   (0, 0), (-1, 0), "Helvetica-Bold"),
    ("FONTSIZE",   (0, 0), (-1, 0), 10),
    # Feature column
    ("BACKGROUND", (0, 1), (0, -1), colors.HexColor("#f0f4f8")),
    # Alternating row colours
    *[("BACKGROUND", (1, r), (1, r), TB_COL if r % 2 == 0 else colors.white) for r in range(1, len(table_data))],
    *[("BACKGROUND", (2, r), (2, r), LC_COL if r % 2 == 0 else colors.HexColor("#fffaf5")) for r in range(1, len(table_data))],
    # Grid
    ("GRID",      (0, 0), (-1, -1), 0.4, GRID),
    ("LINEBELOW", (0, 0), (-1, 0), 1.5, HDR_BLUE),
    # Padding
    ("TOPPADDING",    (0, 0), (-1, -1), 5),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
    # Vertical alignment
    ("VALIGN", (0, 0), (-1, -1), "TOP"),
])

main_table = Table(table_data, colWidths=col_w, repeatRows=1)
main_table.setStyle(ts)
story.append(main_table)
story.append(Spacer(1, 0.4*cm))

# =====================================================================
# SECTION 3 - DISTINGUISHING FEATURES IN ELDERLY
# =====================================================================
story.append(PageBreak())
story.append(section("3.  Special Considerations in Elderly Patients (Age ≥60)"))
story.append(hr())

story.append(subsection("3.1  Why the Elderly are Diagnostically Challenging"))
for txt in [
    "Atypical TB presentations are more common in elderly: fewer night sweats, less fever, predominance of lower lobe disease (mimicking bacterial pneumonia), and negative TST due to immunosenescence.",
    "Elderly smokers with COPD have chronic cough as a baseline — new haemoptysis or change in cough character must always prompt CT chest.",
    "Both conditions cause significant weight loss and fatigue, which may be attributed to 'normal ageing' and delay investigation.",
    "Multiple co-morbidities (DM, renal impairment, cardiac disease) complicate both diagnosis (reduced sputum production, renal dose adjustments for anti-TB drugs) and treatment planning for cancer.",
    "Cognitive impairment may reduce symptom reporting accuracy, leading to late-stage presentation for both diseases.",
]:
    story.append(bullet(txt))
story.append(Spacer(1, 0.2*cm))

story.append(subsection("3.2  Red Flags Favouring Lung Cancer Over TB"))
cancer_flags = [
    "No fever or low-grade fever without night sweats (TB fever is classically hectic and nocturnal)",
    "Sputum AFB smear x3 negative with GeneXpert MTB/RIF negative",
    "Mass lesion with spiculated margins, pleural tethering, or satellite nodules on CT",
    "Hilar or mediastinal lymphadenopathy without calcification",
    "SVC obstruction (facial oedema, arm swelling, dilated chest wall veins)",
    "Hoarseness (recurrent laryngeal nerve involvement by mediastinal nodes)",
    "Bone pain or neurological symptoms suggesting metastases",
    "Clubbing or hypertrophic pulmonary osteoarthropathy",
    "Hyponatraemia (SIADH - common paraneoplastic syndrome in SCLC)",
    "Golden S sign on CXR - reversed S-curve of minor fissure",
    "Non-resolving pneumonia after two courses of antibiotics",
    "Heavy smoking history (>40 pack-years)",
]
for f in cancer_flags:
    story.append(bullet(f))
story.append(Spacer(1, 0.2*cm))

story.append(subsection("3.3  Red Flags Favouring TB Over Lung Cancer"))
tb_flags = [
    "Exposure history: contact with known TB case, residence in endemic area, prior TB",
    "Drenching night sweats + hectic fever + progressive weight loss (classic TB triad)",
    "Tree-in-bud nodules on CT (centrilobular spread of infection - highly specific for TB/NTM)",
    "Cavitatory upper lobe lesion with satellite nodules",
    "Sputum AFB smear or GeneXpert MTB/RIF positive",
    "ADA >40 U/L in pleural/CSF fluid",
    "Response to empirical anti-TB therapy (diagnostic ex-juvantibus)",
    "HIV positive (dramatically increases TB risk)",
    "Bilateral apical infiltrates",
    "History of immunosuppressive therapy (steroids, biologics, TNF-alpha inhibitors)",
]
for f in tb_flags:
    story.append(bullet(f))
story.append(Spacer(1, 0.3*cm))

# =====================================================================
# SECTION 4 - DIAGNOSTIC APPROACH
# =====================================================================
story.append(section("4.  Recommended Diagnostic Approach"))
story.append(hr())

story.append(body(
    "When TB and lung cancer cannot be distinguished clinically, a stepwise investigation approach "
    "is recommended. Both diagnoses must be actively excluded before committing to one treatment."
))

step_data = [
    [Paragraph("<b>Step</b>", ParagraphStyle("SH", fontSize=9.5, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER)),
     Paragraph("<b>Investigation</b>", ParagraphStyle("SH", fontSize=9.5, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER)),
     Paragraph("<b>Key findings</b>", ParagraphStyle("SH", fontSize=9.5, fontName="Helvetica-Bold", textColor=colors.white, alignment=TA_CENTER))],
    ["1", "Chest PA radiograph", "Lobar distribution, cavitation, mass effect, fissure signs, hilar enlargement"],
    ["2", "Sputum AFB smear x3 + GeneXpert MTB/RIF", "Confirms TB and detects rifampicin resistance if positive"],
    ["3", "Sputum cytology x3", "Malignant cells in ~20-30% of central lung cancers"],
    ["4", "CT chest (contrast-enhanced)", "Spiculation, pleural tethering, tree-in-bud, cavitation morphology, nodes, staging"],
    ["5", "Bronchoscopy + BAL + biopsy", "Histology for malignancy; BAL culture/PCR for TB; direct visualisation of endobronchial lesion"],
    ["6", "PET-CT (if malignancy suspected)", "Metabolic staging; identifies distant metastases; guides resectability"],
    ["7", "Pleural fluid (if effusion present)", "ADA, LDH, protein, cytology, culture"],
    ["8", "IGRA / TST", "Evidence of TB exposure (cannot confirm active disease)"],
    ["9", "Molecular profiling (biopsy)", "EGFR, ALK, ROS1, KRAS, PD-L1 expression for targeted therapy eligibility"],
]

step_ts = TableStyle([
    ("BACKGROUND", (0, 0), (-1, 0), HDR_BLUE),
    ("TEXTCOLOR",  (0, 0), (-1, 0), colors.white),
    ("FONTNAME",   (0, 0), (-1, 0), "Helvetica-Bold"),
    *[("BACKGROUND", (0, r), (-1, r), ROW_ALT if r % 2 == 0 else colors.white) for r in range(1, len(step_data))],
    ("GRID",      (0, 0), (-1, -1), 0.4, GRID),
    ("TOPPADDING",    (0, 0), (-1, -1), 5),
    ("BOTTOMPADDING", (0, 0), (-1, -1), 5),
    ("LEFTPADDING",   (0, 0), (-1, -1), 7),
    ("RIGHTPADDING",  (0, 0), (-1, -1), 7),
    ("VALIGN", (0, 0), (-1, -1), "TOP"),
    ("ALIGN",  (0, 0), (0, -1), "CENTER"),
])

step_table = Table(step_data, colWidths=[1.2*cm, 5.5*cm, 12.1*cm])
step_table.setStyle(step_ts)
story.append(step_table)
story.append(Spacer(1, 0.4*cm))

# =====================================================================
# SECTION 5 - COEXISTENCE
# =====================================================================
story.append(section("5.  When Both Coexist: TB-Associated Lung Cancer"))
story.append(hr())
for txt in [
    "Patients with prior pulmonary TB have a 2-3 fold increased risk of developing lung cancer (scar carcinoma). The fibrotic scar from healed TB creates a microenvironment promoting malignant transformation.",
    "Simultaneous active TB and lung cancer occurs in 1-3% of lung cancer patients in endemic areas. CT findings of malignancy (spiculated mass) superimposed on background TB fibrosis are the key indicator.",
    "Never assume a negative sputum culture rules out malignancy. Conversely, a positive GeneXpert does not rule out an underlying obstructive cancer causing post-obstructive TB.",
    "In this scenario, a contrast-enhanced CT chest with bronchoscopy and biopsy is essential to characterise both processes simultaneously.",
]:
    story.append(bullet(txt))
story.append(Spacer(1, 0.3*cm))

# =====================================================================
# SECTION 6 - KEY REFERENCES
# =====================================================================
story.append(section("6.  References"))
story.append(hr())
refs = [
    "Harrison's Principles of Internal Medicine, 22nd Edition (2025) - Chapter 83: Lung Cancer; Chapter 167: Tuberculosis",
    "Goldman-Cecil Medicine International Edition - Chapter 85: Pulmonary Tuberculosis",
    "Fishman's Pulmonary Diseases and Disorders, 2-Volume Set - Chapter 112: Lung Cancer Staging",
    "Grainger & Allison's Diagnostic Radiology - Chapter 8: Lung Cancer Imaging & Staging",
    "Symptom to Diagnosis: An Evidence-Based Guide, 4th Edition - Chapter 32: Weight Loss",
    "Sabiston Textbook of Surgery, 11th Edition - Chapter on NSCLC Diagnosis",
    "Textbook of Family Medicine, 9th Edition - Pulmonary Nodule and Cancer Presentation",
]
for r in refs:
    story.append(source(r))

story.append(Spacer(1, 0.5*cm))
story.append(hr("#1a3c5e", 1))
story.append(Paragraph(
    "This document is a clinical education summary generated for educational purposes. "
    "Clinical decisions should always be based on individual patient assessment and current institutional guidelines.",
    footer_style
))

# BUILD
doc.build(story)
print(f"PDF saved to {OUTPUT}")
Running Command

cd /home/daytona/workspace/tb-vs-lungca && python generate_pdf.py 2>&1

Editing File

~/tb-vs-lungca/generate_pdf.py

Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/tb-vs-lungca/generate_pdf.py'
Running Command

cd /home/daytona/workspace/tb-vs-lungca && python generate_pdf.py 2>&1

Running Command

ls -lh /home/daytona/workspace/tb-vs-lungca/TB_vs_LungCancer_Elderly.pdf

Your PDF is ready. Download it here:

TB vs LungCancer Elderly

PDF Document · PDF


Here is what the document contains:
Page 1 - Main Comparison Table (25 rows) A colour-coded side-by-side table (blue = TB, orange = Lung Cancer) covering:
  • Demographics and risk factors
  • All key symptoms: cough, haemoptysis, fever, weight loss, night sweats, chest pain, dyspnoea, clubbing
  • Radiology: CXR location, character, cavitation, fissure signs, lymphadenopathy, pleural effusion
  • Labs: AFB smear, GeneXpert, sputum cytology, bronchoscopy, CT, blood markers
  • Treatment and prognosis
Page 2 - Special Considerations in the Elderly
  • Why elderly patients are diagnostically harder (atypical TB, baseline chronic cough in smokers, late presentation)
  • 12 red flags favouring lung cancer
  • 10 red flags favouring TB
Page 2 - Stepwise Diagnostic Approach 9-step investigation ladder from CXR through to molecular profiling, with what each step is looking for
Page 2 - When Both Coexist TB-associated scar carcinoma, simultaneous TB + cancer, and why one positive result never rules out the other
Sources drawn from Harrison's 22E, Goldman-Cecil Medicine, Fishman's Pulmonary Diseases, Grainger & Allison's Radiology, and Sabiston Surgery.
This is a shared conversation. Sign in to Orris to start your own chat.