Spincal fluid rupture diet
CSF cerebrospinal fluid leak diet recommendations
| Do | Avoid |
|---|---|
| Rest lying flat as much as possible | Heavy lifting (>2.5 kg / 5 lbs) |
| Elevate feet slightly (Trendelenburg) | Bending, twisting, straining |
| Increase fluid & sodium intake | Blowing nose forcefully |
| Moderate caffeine | Coughing/sneezing with mouth closed |
| Gradual return to activity | Strenuous exercise during healing |
Important: Always follow your doctor's specific dietary and activity instructions, as recommendations may differ depending on whether you have low CSF pressure (typical leak) or rebound high CSF pressure (after the leak seals).
Create a printable recovery meal plan with high-sodium, high-protein options
ls -la /home/daytona/workspace/
mkdir -p /home/daytona/workspace/csf-meal-plan
~/csf-meal-plan/generate_meal_plan.py
from reportlab.lib.pagesizes import letter
from reportlab.lib import colors
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.units import inch
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, KeepTogether
)
from reportlab.lib.enums import TA_CENTER, TA_LEFT
from reportlab.platypus import PageBreak
OUTPUT = "/home/daytona/workspace/csf-meal-plan/CSF_Leak_Recovery_Meal_Plan.pdf"
# ── Colour palette ──────────────────────────────────────────────────────────
TEAL = colors.HexColor("#1A7F8E")
TEAL_LITE = colors.HexColor("#E6F4F6")
AMBER = colors.HexColor("#E8A020")
AMBER_LITE= colors.HexColor("#FFF8EC")
GREY_DARK = colors.HexColor("#2C3E50")
GREY_MID = colors.HexColor("#7F8C8D")
GREY_LITE = colors.HexColor("#F5F6FA")
WHITE = colors.white
doc = SimpleDocTemplate(
OUTPUT,
pagesize=letter,
rightMargin=0.65*inch, leftMargin=0.65*inch,
topMargin=0.65*inch, bottomMargin=0.65*inch,
)
styles = getSampleStyleSheet()
# Custom styles
H1 = ParagraphStyle("H1", parent=styles["Normal"],
fontSize=22, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_CENTER, spaceAfter=4)
SUBTITLE = ParagraphStyle("SUBTITLE", parent=styles["Normal"],
fontSize=11, textColor=WHITE, fontName="Helvetica",
alignment=TA_CENTER, spaceAfter=0)
H2 = ParagraphStyle("H2", parent=styles["Normal"],
fontSize=13, textColor=WHITE, fontName="Helvetica-Bold",
alignment=TA_LEFT, spaceAfter=2, spaceBefore=2)
H3 = ParagraphStyle("H3", parent=styles["Normal"],
fontSize=10, textColor=GREY_DARK, fontName="Helvetica-Bold",
spaceAfter=2, spaceBefore=6)
BODY = ParagraphStyle("BODY", parent=styles["Normal"],
fontSize=9, textColor=GREY_DARK, fontName="Helvetica",
spaceAfter=2, leading=13)
SMALL = ParagraphStyle("SMALL", parent=styles["Normal"],
fontSize=8, textColor=GREY_MID, fontName="Helvetica-Oblique",
spaceAfter=1, leading=11)
TIP = ParagraphStyle("TIP", parent=styles["Normal"],
fontSize=9, textColor=colors.HexColor("#7B4F00"), fontName="Helvetica",
spaceAfter=1, leading=13, leftIndent=6)
WARN = ParagraphStyle("WARN", parent=styles["Normal"],
fontSize=8.5, textColor=colors.HexColor("#8B0000"), fontName="Helvetica-BoldOblique",
spaceAfter=1, leading=12)
# ── Header banner ───────────────────────────────────────────────────────────
def header_table():
top = Table(
[[Paragraph("CSF Leak Recovery", H1)],
[Paragraph("7-Day High-Sodium · High-Protein Meal Plan", SUBTITLE)]],
colWidths=[7.2*inch]
)
top.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("ROUNDEDCORNERS", [8]),
("TOPPADDING", (0,0), (-1,-1), 10),
("BOTTOMPADDING", (0,0), (-1,-1), 10),
("LEFTPADDING", (0,0), (-1,-1), 12),
("RIGHTPADDING", (0,0), (-1,-1), 12),
]))
return top
# ── Section heading ──────────────────────────────────────────────────────────
def section_head(text, color=TEAL):
t = Table([[Paragraph(text, H2)]], colWidths=[7.2*inch])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), color),
("ROUNDEDCORNERS", [5]),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
]))
return t
# ── Tip box ─────────────────────────────────────────────────────────────────
def tip_box(lines, bg=AMBER_LITE, border=AMBER):
content = [[Paragraph(l, TIP)] for l in lines]
t = Table(content, colWidths=[7.0*inch])
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), bg),
("BOX", (0,0), (-1,-1), 1.2, border),
("ROUNDEDCORNERS", [5]),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 10),
("RIGHTPADDING", (0,0), (-1,-1), 10),
]))
return t
# ── Meal-day table ───────────────────────────────────────────────────────────
MEAL_HEADER_STYLE = ParagraphStyle("MH", parent=styles["Normal"],
fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
MEAL_BODY_STYLE = ParagraphStyle("MB", parent=styles["Normal"],
fontSize=8.5, textColor=GREY_DARK, fontName="Helvetica", leading=12)
MEAL_NA_STYLE = ParagraphStyle("MNA", parent=styles["Normal"],
fontSize=8.5, textColor=TEAL, fontName="Helvetica-Bold", alignment=TA_CENTER)
def meal_table(day_data):
"""day_data = list of (meal, food, sodium, protein, notes)"""
header = ["Meal", "Food / Preparation", "Sodium\n(mg)", "Protein\n(g)", "Recovery Notes"]
col_w = [0.85*inch, 2.8*inch, 0.75*inch, 0.75*inch, 2.05*inch]
rows = [[Paragraph(h, MEAL_HEADER_STYLE) for h in header]]
for row in day_data:
rows.append([
Paragraph(row[0], MEAL_BODY_STYLE),
Paragraph(row[1], MEAL_BODY_STYLE),
Paragraph(str(row[2]), MEAL_NA_STYLE),
Paragraph(str(row[3]), MEAL_NA_STYLE),
Paragraph(row[4], MEAL_BODY_STYLE),
])
t = Table(rows, colWidths=col_w, repeatRows=1)
t.setStyle(TableStyle([
# Header
("BACKGROUND", (0,0), (-1,0), TEAL),
("TEXTCOLOR", (0,0), (-1,0), WHITE),
("ALIGN", (0,0), (-1,0), "CENTER"),
("TOPPADDING", (0,0), (-1,0), 6),
("BOTTOMPADDING",(0,0), (-1,0), 6),
# Data rows alternating
("ROWBACKGROUNDS",(0,1),(-1,-1), [WHITE, GREY_LITE]),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
("TOPPADDING", (0,1), (-1,-1), 5),
("BOTTOMPADDING",(0,1), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 5),
("RIGHTPADDING", (0,0), (-1,-1), 5),
# Grid
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#D0D0D0")),
("LINEBELOW", (0,0), (-1,0), 1.5, TEAL),
]))
return t
# ── Totals row ───────────────────────────────────────────────────────────────
TOTAL_STYLE = ParagraphStyle("TOT", parent=styles["Normal"],
fontSize=9, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
def totals_row(sodium, protein):
t = Table(
[[Paragraph("Daily Totals", TOTAL_STYLE),
Paragraph(f"Sodium: ~{sodium} mg", TOTAL_STYLE),
Paragraph(f"Protein: ~{protein} g", TOTAL_STYLE)]],
colWidths=[2.4*inch, 2.4*inch, 2.4*inch]
)
t.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,-1), TEAL),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING",(0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 8),
("RIGHTPADDING", (0,0), (-1,-1), 8),
("BOX", (0,0), (-1,-1), 0.4, colors.HexColor("#D0D0D0")),
]))
return t
# ══════════════════════════════════════════════════════════════════════════════
# MEAL DATA (meal, food, sodium_mg, protein_g, notes)
# ══════════════════════════════════════════════════════════════════════════════
days = {
"Day 1 — Monday": {
"meals": [
("Breakfast", "2 scrambled eggs + 2 strips turkey bacon + whole-wheat toast with salted butter", 820, 28, "Eggs support collagen synthesis; turkey bacon adds sodium"),
("Snack", "1 cup chicken broth (low-fat) + 10 salted crackers", 680, 8, "Liquid sodium boost; rest flat after eating"),
("Lunch", "Tuna salad wrap: canned tuna, mayo, pickles, whole-wheat tortilla", 900, 35, "Canned tuna is high-protein; pickles add sodium"),
("Snack", "Greek yogurt (plain, full-fat) + 1 tsp salt flakes sprinkled", 390, 17, "Greek yogurt: ~17g protein per cup"),
("Dinner", "Grilled salmon fillet + miso soup + steamed edamame with sea salt", 1,100, 48, "Miso is very high sodium; salmon provides omega-3s for healing"),
("Evening", "Warm mug of bone broth + 2 hard-boiled eggs", 510, 20, "Bone broth replenishes collagen and electrolytes"),
],
"sodium": 4400, "protein": 156
},
"Day 2 — Tuesday": {
"meals": [
("Breakfast", "Cottage cheese (full-fat) with everything-bagel seasoning + 1 slice rye toast", 760, 26, "Cottage cheese ~25g protein; rye adds staying power"),
("Snack", "Handful of salted mixed nuts + electrolyte drink", 580, 9, "Nuts provide healthy fats + protein"),
("Lunch", "Lentil soup with ham + 2 slices sourdough with salted butter", 1,050, 34, "Lentils: complete protein; ham boosts sodium"),
("Snack", "String cheese × 2 + 15 pretzels", 760, 14, "Easy, no-cooking snack; good for rest days"),
("Dinner", "Chicken thigh stir-fry with soy sauce, broccoli, brown rice", 1,200, 46, "Soy sauce is a key sodium source; chicken thighs > breast for calories"),
("Evening", "Warm milk + 1 tsp Milo or cocoa", 130, 8, "Milk supports healing; warm drink aids sleep"),
],
"sodium": 4480, "protein": 137
},
"Day 3 — Wednesday": {
"meals": [
("Breakfast", "Smoked salmon bagel: cream cheese, capers, red onion", 1,100, 32, "Smoked salmon very high sodium + protein; capers add electrolytes"),
("Snack", "Tomato juice (V8, low-sodium reduced) + boiled egg", 450, 10, "Lycopene + protein; drink sitting up slowly"),
("Lunch", "Turkey and Swiss sandwich on rye + dill pickle spear + broth", 1,050, 42, "Turkey is lean and high-protein; pickle spike sodium"),
("Snack", "Hummus (salted) + cucumber slices + 10 rice crackers", 540, 8, "Chickpeas provide plant protein"),
("Dinner", "Beef and vegetable stew with sea salt + mashed potatoes with butter/salt", 1,200, 45, "Beef is collagen-rich; potatoes provide potassium balance"),
("Evening", "Protein shake with whole milk (chocolate flavour)", 350, 25, "Easy to consume lying flat; high protein"),
],
"sodium": 4690, "protein": 162
},
"Day 4 — Thursday": {
"meals": [
("Breakfast", "3-egg omelette with ham, cheddar cheese, and salsa", 950, 38, "Ham + cheese = sodium + protein dual boost"),
("Snack", "Celery sticks with peanut butter + sprinkle of sea salt", 300, 8, "Peanut butter provides healthy fats + protein"),
("Lunch", "Clam chowder (canned) + sourdough bread roll with salted butter", 1,350, 30, "Clam chowder is among highest-sodium soups; shellfish = zinc + protein"),
("Snack", "Edamame in pods, sea salt + electrolyte water", 480, 14, "Edamame = complete plant protein"),
("Dinner", "Baked cod with lemon-butter sauce + roasted asparagus with salt + quinoa", 870, 48, "Cod: lean, high protein; quinoa: complete amino acids"),
("Evening", "Low-fat cottage cheese + 1 tbsp honey", 380, 14, "Slow-digesting casein protein aids overnight healing"),
],
"sodium": 4330, "protein": 152
},
"Day 5 — Friday": {
"meals": [
("Breakfast", "Overnight oats with whey protein powder, milk, chia seeds, salted almond butter", 640, 35, "Whey protein for rapid tissue repair; chia = omega-3s"),
("Snack", "Sliced deli turkey (low-sodium) rolled with Swiss cheese × 3 rolls", 580, 18, "No-cook rollups; easy to prepare lying down"),
("Lunch", "Miso ramen with soft-boiled egg, tofu, seaweed, noodles", 1,450, 40, "Miso broth very high sodium; tofu adds plant protein"),
("Snack", "Cheddar cheese cubes + 15 salted crackers", 680, 12, "Calcium supports nerve health"),
("Dinner", "Shrimp and rice bowl with teriyaki sauce + steamed bok choy with oyster sauce", 1,200, 44, "Shrimp = very high protein-to-calorie ratio; oyster sauce boosts sodium"),
("Evening", "Warm bone broth mug + handful of salted cashews", 520, 16, "Collagen amino acids + healthy fats"),
],
"sodium": 5070, "protein": 165
},
"Day 6 — Saturday": {
"meals": [
("Breakfast", "Smoked mackerel on toast with cream cheese + capers", 980, 30, "Mackerel very high omega-3 + protein; capers add sodium"),
("Snack", "Greek yogurt parfait with granola + pinch of sea salt", 360, 18, "Probiotics support gut health during recovery"),
("Lunch", "Egg salad sandwich on whole-wheat + cup of tomato soup with salt", 1,050, 32, "Eggs = complete protein; tomato soup adds lycopene"),
("Snack", "Protein bar (20g+ protein, e.g. Quest/RXBar)", 380, 20, "Convenient; minimal preparation needed"),
("Dinner", "Pork tenderloin with soy-ginger glaze + stir-fried bok choy + jasmine rice", 1,150, 50, "Pork tenderloin = very lean, high protein; soy adds sodium"),
("Evening", "Warm golden milk with protein powder + pinch of salt", 270, 20, "Turmeric: anti-inflammatory; casein protein overnight"),
],
"sodium": 4190, "protein": 170
},
"Day 7 — Sunday": {
"meals": [
("Breakfast", "Shakshuka: 3 eggs poached in seasoned tomato sauce + pita bread", 1,050, 30, "Tomato sauce + spices boost sodium; eggs = collagen support"),
("Snack", "Jerky (beef or turkey, 1 oz) + electrolyte drink", 590, 15, "Jerky = ultra-high sodium snack; portable and easy"),
("Lunch", "Grilled cheese on sourdough + bowl of chicken noodle soup", 1,250, 28, "Classic sodium-rich combo; soup keeps hydration up"),
("Snack", "Hard-boiled eggs × 2 + a few olives (green, brine-cured)", 460, 12, "Olives are exceptionally high in sodium"),
("Dinner", "Roast chicken with salt-herb crust + roasted root vegetables + gravy", 1,100, 52, "Collagen-rich skin; gravy adds sodium; root veg = potassium"),
("Evening", "Protein shake (vanilla, whole milk) + 1 tbsp peanut butter", 340, 28, "High-protein evening recovery; easy preparation"),
],
"sodium": 4790, "protein": 165
},
}
# ══════════════════════════════════════════════════════════════════════════════
# BUILD PDF
# ══════════════════════════════════════════════════════════════════════════════
story = []
# ── Cover / intro ────────────────────────────────────────────────────────────
story.append(header_table())
story.append(Spacer(1, 10))
intro_text = (
"This 7-day meal plan is designed for patients recovering from a <b>CSF (cerebrospinal fluid) leak</b>. "
"Each day targets <b>~4,000–5,000 mg sodium</b> and <b>~140–170 g protein</b> to help restore CSF volume, "
"support dural tissue repair, and maintain overall healing. All meals are easy to prepare and suitable "
"for patients who need to rest frequently."
)
story.append(Paragraph(intro_text, BODY))
story.append(Spacer(1, 6))
# Key principles box
story.append(tip_box([
"🧂 <b>Sodium goal:</b> 4,000–5,000 mg/day — helps retain fluid to replenish CSF volume",
"🥩 <b>Protein goal:</b> ≥ 1.5 g/kg body weight/day — supports dura mater and tissue repair",
"💧 <b>Hydration:</b> 2–3 litres of water/fluid daily alongside sodium intake",
"☕ <b>Caffeine:</b> 2–4 cups of coffee/day — stimulates CSF production via choroid plexus",
"🌾 <b>Fibre:</b> Include fruits, veg, and whole grains to prevent constipation and straining",
"⚠️ Adjust sodium recommendations if you develop rebound high ICP — consult your doctor",
]))
story.append(Spacer(1, 8))
# ── Daily meals ──────────────────────────────────────────────────────────────
for day_name, data in days.items():
block = []
block.append(section_head(f" {day_name}"))
block.append(Spacer(1, 4))
block.append(meal_table(data["meals"]))
block.append(Spacer(1, 2))
block.append(totals_row(f"{data['sodium']:,}", data["protein"]))
block.append(Spacer(1, 10))
story.append(KeepTogether(block))
# ── Foods reference table ────────────────────────────────────────────────────
story.append(PageBreak())
story.append(section_head(" High-Sodium Foods Quick Reference", color=AMBER))
story.append(Spacer(1, 6))
ref_header = ["Food", "Serving", "Sodium (mg)", "Protein (g)"]
ref_data = [
("Miso soup", "1 cup", "1,100", "6"),
("Soy sauce", "1 tbsp", "900", "1"),
("Canned tuna", "1 can (5oz)","460", "30"),
("Smoked salmon", "3 oz", "560", "16"),
("Turkey deli meat", "3 oz", "700", "15"),
("Canned clam chowder","1 cup", "870", "12"),
("Cottage cheese", "1 cup", "750", "25"),
("Greek yogurt", "1 cup", "85", "17"),
("Beef jerky", "1 oz", "620", "15"),
("Bone broth", "1 cup", "480", "10"),
("Cheddar cheese", "1 oz", "180", "7"),
("Olives (green)", "10 olives","630", "0"),
("Pickles", "1 spear", "280", "0"),
("Pretzels", "1 oz", "385", "3"),
("Chicken breast", "4 oz", "260", "35"),
("Shrimp (boiled)", "4 oz", "280", "27"),
("Egg (large)", "1 egg", "70", "6"),
("Whey protein powder","1 scoop", "160", "25"),
]
REF_H = ParagraphStyle("RH", parent=styles["Normal"],
fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
REF_B = ParagraphStyle("RB", parent=styles["Normal"],
fontSize=8.5, textColor=GREY_DARK, fontName="Helvetica", alignment=TA_LEFT)
REF_N = ParagraphStyle("RN", parent=styles["Normal"],
fontSize=8.5, textColor=TEAL, fontName="Helvetica-Bold", alignment=TA_CENTER)
ref_rows = [[Paragraph(h, REF_H) for h in ref_header]]
for i, row in enumerate(ref_data):
ref_rows.append([
Paragraph(row[0], REF_B),
Paragraph(row[1], REF_B),
Paragraph(row[2], REF_N),
Paragraph(row[3], REF_N),
])
ref_table = Table(ref_rows, colWidths=[2.2*inch, 1.5*inch, 1.7*inch, 1.7*inch])
ref_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), AMBER),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, AMBER_LITE]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#D0D0D0")),
("LINEBELOW", (0,0), (-1,0), 1.5, AMBER),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(ref_table)
story.append(Spacer(1, 14))
# ── Hydration & caffeine section ─────────────────────────────────────────────
story.append(section_head(" Hydration & Caffeine Guide", color=colors.HexColor("#2471A3")))
story.append(Spacer(1, 6))
hydration_data = [
["Time of Day", "Fluid Recommendation", "Purpose"],
["On waking", "1 glass water (250 ml) + electrolytes", "Rehydrate after overnight fast"],
["With breakfast", "Coffee or tea (1–2 cups)", "Stimulate CSF production"],
["Mid-morning", "Electrolyte drink or broth", "Maintain sodium levels"],
["With lunch", "1 glass water", "Digestion and hydration"],
["Afternoon", "Coffee (1–2 cups) or herbal tea", "Second caffeine dose"],
["With dinner", "1 glass water or juice", "Hydration with sodium-rich meal"],
["Evening", "Warm bone broth or warm milk", "Collagen and calcium; aids sleep"],
]
HYD_H = ParagraphStyle("HH", parent=styles["Normal"],
fontSize=8.5, textColor=WHITE, fontName="Helvetica-Bold", alignment=TA_CENTER)
HYD_B = ParagraphStyle("HB", parent=styles["Normal"],
fontSize=8.5, textColor=GREY_DARK, fontName="Helvetica", leading=12)
hyd_rows = []
for i, row in enumerate(hydration_data):
if i == 0:
hyd_rows.append([Paragraph(c, HYD_H) for c in row])
else:
hyd_rows.append([Paragraph(c, HYD_B) for c in row])
hyd_table = Table(hyd_rows, colWidths=[1.5*inch, 3.0*inch, 2.65*inch])
hyd_table.setStyle(TableStyle([
("BACKGROUND", (0,0), (-1,0), colors.HexColor("#2471A3")),
("ROWBACKGROUNDS", (0,1), (-1,-1), [WHITE, colors.HexColor("#EAF2FB")]),
("GRID", (0,0), (-1,-1), 0.4, colors.HexColor("#D0D0D0")),
("LINEBELOW", (0,0), (-1,0), 1.5, colors.HexColor("#2471A3")),
("TOPPADDING", (0,0), (-1,-1), 5),
("BOTTOMPADDING", (0,0), (-1,-1), 5),
("LEFTPADDING", (0,0), (-1,-1), 6),
("RIGHTPADDING", (0,0), (-1,-1), 6),
("VALIGN", (0,0), (-1,-1), "MIDDLE"),
]))
story.append(hyd_table)
story.append(Spacer(1, 12))
# ── Warning box ──────────────────────────────────────────────────────────────
story.append(tip_box([
"⚠️ <b>Important:</b> These recommendations apply to patients with LOW intracranial pressure (CSF leak / spontaneous intracranial hypotension). "
"If your CSF leak has sealed and you develop HIGH intracranial pressure (rebound ICP) — characterised by headache when lying flat, pulsatile tinnitus, "
"or visual changes — REDUCE sodium intake and consult your neurologist or neurosurgeon immediately.",
"🩺 <b>This plan is not a substitute for medical advice.</b> Always follow your treating physician's specific dietary instructions.",
], bg=colors.HexColor("#FDF2F2"), border=colors.HexColor("#C0392B")))
story.append(Spacer(1, 8))
story.append(Paragraph(
"Prepared for CSF Leak Recovery Support | Consult your healthcare team before making dietary changes | May 2026",
SMALL
))
# ── Build ────────────────────────────────────────────────────────────────────
doc.build(story)
print("PDF created:", OUTPUT)
cd /home/daytona/workspace/csf-meal-plan && python generate_meal_plan.py 2>&1
cd /home/daytona/workspace/csf-meal-plan && python -c " import re with open('gen…
cd /home/daytona/workspace/csf-meal-plan && python generate_meal_plan.py 2>&1
CSF Leak Recovery Meal Plan
PDF Document · PDF