Calcium oxalate increase during lab reports
calcium oxalate crystals increased urine lab report causes significance


| Finding | Significance |
|---|---|
| Few crystals in a concentrated urine sample | Often incidental / dietary |
| Persistent high crystal load | Risk factor for kidney stone formation |
| Large monohydrate crystals | More strongly associated with active stone disease |
| Crystals + hematuria | Suggests active stone passage |
| Crystals + acute kidney injury + history of toxic ingestion | Suspect ethylene glycol poisoning |
Check this patient is suffering from early morning back side pain before pee after pee its disappeared
early morning back pain before urination relieved after voiding kidney stone symptoms calcium oxalate
| Parameter | Result | Significance |
|---|---|---|
| Colour | Pale yellow | Normal |
| Appearance | Clear | Normal |
| Reaction | Acidic | Favors calcium oxalate crystal formation |
| Albumin / Sugar | Nil | No kidney damage marker, no diabetes |
| Red Blood Cells | 2-4 /hpf | Microscopic hematuria - abnormal (normal: 0-2) |
| Pus Cells | 1-2 /hpf | Borderline - mild inflammation |
| Epithelial Cells | 2-4 /hpf | Mild - can be from urethral lining |
| Casts | Nil | No glomerular/tubular damage |
| Crystals | Cal-Oxal: + | Calcium oxalate crystals PRESENT |
This patient's early morning back pain + calcium oxalate crystals + RBCs in urine = calcium oxalate nephrolithiasis/crystalluria causing intermittent partial ureteral obstruction. The pain resolves after voiding because the back-pressure is released. This is treatable and largely preventable with hydration and dietary changes. A urologist visit and kidney ultrasound are strongly recommended.
Generate a patient-friendly diet sheet avoiding high-oxalate foods
ls /home/daytona/workspace/ 2>/dev/null || echo "workspace empty or missing"
mkdir -p /home/daytona/workspace/diet-sheet
~/diet-sheet/diet_sheet.js
const pptxgen = require("pptxgenjs");
const pres = new pptxgen();
pres.layout = 'LAYOUT_WIDE'; // 13.3" x 7.5"
// Color palette
const C = {
darkGreen: "1A5276",
midGreen: "1E8449",
lightGreen: "D5F5E3",
orange: "E67E22",
lightOrange: "FDEBD0",
red: "C0392B",
lightRed: "FADBD8",
white: "FFFFFF",
offWhite: "F8F9FA",
textDark: "1C2833",
textMid: "2C3E50",
yellow: "F9E79F",
yellowBg: "FEFCBF",
teal: "148F77",
lightTeal: "D1F2EB",
};
// ─── SLIDE 1: COVER ───────────────────────────────────────────────────────────
{
const s = pres.addSlide();
// Full dark background
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 7.5, fill: { color: C.darkGreen } });
// Decorative accent bar
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 0.12, fill: { color: C.midGreen } });
s.addShape(pres.ShapeType.rect, { x: 0, y: 7.38, w: 13.3, h: 0.12, fill: { color: C.midGreen } });
// Decorative side panel
s.addShape(pres.ShapeType.rect, { x: 9.5, y: 0, w: 3.8, h: 7.5, fill: { color: "154360", transparency: 0 } });
// Big icon placeholder with fruit/veg emoji text
s.addText("🥗", { x: 9.8, y: 1.5, w: 3.2, h: 3, fontSize: 110, align: "center" });
// Kidney icon
s.addText("🫘", { x: 10.2, y: 4.8, w: 2.4, h: 1.5, fontSize: 60, align: "center" });
// Headline
s.addText("LOW-OXALATE DIET PLAN", {
x: 0.5, y: 1.2, w: 8.7, h: 0.9,
fontSize: 38, bold: true, color: C.white,
fontFace: "Calibri", align: "left", margin: 0,
charSpacing: 3
});
// Subtitle
s.addText("For Patients with Calcium Oxalate Kidney Crystals & Stones", {
x: 0.5, y: 2.2, w: 8.7, h: 0.55,
fontSize: 18, bold: false, color: "A9DFBF",
fontFace: "Calibri", align: "left", margin: 0
});
// Divider line
s.addShape(pres.ShapeType.rect, { x: 0.5, y: 2.9, w: 5, h: 0.05, fill: { color: C.orange } });
// Body intro
s.addText(
"This guide shows you exactly what to eat, what to avoid, and how to stay hydrated to prevent stone formation and reduce pain.",
{
x: 0.5, y: 3.1, w: 8.5, h: 1.0,
fontSize: 15, color: "D6EAF8",
fontFace: "Calibri", align: "left", margin: 0
}
);
// Tag line chips
const tags = ["💧 Drink More Water", "🥦 Eat Smart", "🚫 Limit Oxalate", "💊 Follow Doctor's Advice"];
tags.forEach((t, i) => {
s.addShape(pres.ShapeType.roundRect, {
x: 0.5 + i * 2.15, y: 4.3, w: 2.0, h: 0.5,
fill: { color: C.teal }, line: { color: C.lightTeal, width: 1 },
rectRadius: 0.15
});
s.addText(t, {
x: 0.5 + i * 2.15, y: 4.3, w: 2.0, h: 0.5,
fontSize: 11, bold: true, color: C.white,
align: "center", valign: "middle", margin: 0
});
});
// Footer
s.addText("For educational purposes. Always follow your doctor's and dietitian's specific advice.", {
x: 0.5, y: 6.9, w: 9, h: 0.4,
fontSize: 10, color: "7DCEA0", italic: true, align: "left", margin: 0
});
}
// ─── SLIDE 2: FOODS TO AVOID (HIGH OXALATE) ──────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 7.5, fill: { color: C.offWhite } });
// Header bar
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 1.0, fill: { color: C.red } });
s.addText("🚫 FOODS TO AVOID — High Oxalate (Increases Stone Risk)", {
x: 0.3, y: 0, w: 12.7, h: 1.0,
fontSize: 24, bold: true, color: C.white,
align: "left", valign: "middle", margin: 0
});
// Categories
const avoidCategories = [
{
icon: "🥬", title: "Vegetables",
items: ["Spinach", "Beets & Beetroot", "Swiss chard", "Okra (Bhindi)", "Celery", "Leeks"],
x: 0.3, y: 1.2
},
{
icon: "🍫", title: "Sweets & Drinks",
items: ["Chocolate & Cocoa", "Strong tea (black/green)", "Cold drinks / Soda", "Ovaltine / Bournvita", "Tomato juice", "Carrot juice (excess)"],
x: 3.5, y: 1.2
},
{
icon: "🥜", title: "Nuts & Grains",
items: ["Almonds", "Cashews", "Peanuts", "Wheat bran", "Wheat germ", "Soy products"],
x: 6.7, y: 1.2
},
{
icon: "🍓", title: "Fruits",
items: ["Starfruit (very high!)", "Rhubarb", "Figs", "Kiwi fruit", "Raspberries (limit)", "Dried fruits (excess)"],
x: 9.9, y: 1.2
}
];
avoidCategories.forEach(cat => {
// Card background
s.addShape(pres.ShapeType.roundRect, {
x: cat.x, y: cat.y, w: 3.0, h: 5.7,
fill: { color: C.lightRed }, line: { color: C.red, width: 1.5 },
rectRadius: 0.18
});
// Icon + title
s.addText(cat.icon + " " + cat.title, {
x: cat.x + 0.1, y: cat.y + 0.1, w: 2.8, h: 0.6,
fontSize: 16, bold: true, color: C.red,
align: "center", valign: "middle", margin: 0
});
// Divider
s.addShape(pres.ShapeType.rect, { x: cat.x + 0.2, y: cat.y + 0.72, w: 2.6, h: 0.04, fill: { color: C.red } });
// Items
const itemTexts = cat.items.map(item => ({ text: "✗ " + item, options: { bullet: false, breakLine: true, color: C.textDark } }));
s.addText(itemTexts, {
x: cat.x + 0.15, y: cat.y + 0.85, w: 2.7, h: 4.6,
fontSize: 13, fontFace: "Calibri",
valign: "top", margin: 0, lineSpacingMultiple: 1.4
});
});
// Warning box
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 7.0, w: 12.7, h: 0.38,
fill: { color: "F9EBEA" }, line: { color: C.red, width: 1 }, rectRadius: 0.1
});
s.addText("⚠️ Even moderate amounts of these foods can raise oxalate levels. Don't eat them daily — occasional small portions may be okay with plenty of water.", {
x: 0.4, y: 7.0, w: 12.5, h: 0.38,
fontSize: 11, color: C.red, bold: true, align: "center", valign: "middle", margin: 0
});
}
// ─── SLIDE 3: FOODS TO EAT FREELY (SAFE / LOW OXALATE) ───────────────────────
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 7.5, fill: { color: C.offWhite } });
// Header bar
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 1.0, fill: { color: C.midGreen } });
s.addText("✅ SAFE FOODS — Low Oxalate (Eat Freely)", {
x: 0.3, y: 0, w: 12.7, h: 1.0,
fontSize: 24, bold: true, color: C.white,
align: "left", valign: "middle", margin: 0
});
const safeCategories = [
{
icon: "🥩", title: "Proteins",
items: ["Chicken", "Fish (all types)", "Eggs", "Lentils (moong dal)", "Kidney beans (rajma) - small portions", "Tofu (small amount)"],
x: 0.3, y: 1.2
},
{
icon: "🥛", title: "Dairy (Important!)",
items: ["Milk (cow/buffalo)", "Yogurt / Curd", "Paneer (cottage cheese)", "Buttermilk (chaas)", "Cheese (in moderation)", "Low-fat dairy preferred"],
x: 3.5, y: 1.2
},
{
icon: "🍚", title: "Grains & Staples",
items: ["White rice", "White bread / Roti", "Pasta / Noodles", "Corn / Maize", "Oats", "Poha (flattened rice)"],
x: 6.7, y: 1.2
},
{
icon: "🍎", title: "Fruits & Vegetables",
items: ["Apple, Banana, Mango", "Papaya, Guava, Melon", "Cauliflower, Cabbage", "Onion, Garlic", "Peas (in moderation)", "Cucumber, Bottle gourd"],
x: 9.9, y: 1.2
}
];
safeCategories.forEach(cat => {
s.addShape(pres.ShapeType.roundRect, {
x: cat.x, y: cat.y, w: 3.0, h: 5.7,
fill: { color: C.lightGreen }, line: { color: C.midGreen, width: 1.5 },
rectRadius: 0.18
});
s.addText(cat.icon + " " + cat.title, {
x: cat.x + 0.1, y: cat.y + 0.1, w: 2.8, h: 0.6,
fontSize: 16, bold: true, color: C.midGreen,
align: "center", valign: "middle", margin: 0
});
s.addShape(pres.ShapeType.rect, { x: cat.x + 0.2, y: cat.y + 0.72, w: 2.6, h: 0.04, fill: { color: C.midGreen } });
const itemTexts = cat.items.map(item => ({ text: "✓ " + item, options: { breakLine: true, color: C.textDark } }));
s.addText(itemTexts, {
x: cat.x + 0.15, y: cat.y + 0.85, w: 2.7, h: 4.6,
fontSize: 13, fontFace: "Calibri",
valign: "top", margin: 0, lineSpacingMultiple: 1.4
});
});
// Key tip: dairy with meals
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 7.0, w: 12.7, h: 0.38,
fill: { color: C.lightTeal }, line: { color: C.teal, width: 1 }, rectRadius: 0.1
});
s.addText("💡 TIP: Eat dairy (milk, curd) WITH your meals — calcium in dairy binds oxalate in the gut and prevents it from being absorbed into the blood.", {
x: 0.4, y: 7.0, w: 12.5, h: 0.38,
fontSize: 11, color: C.darkGreen, bold: true, align: "center", valign: "middle", margin: 0
});
}
// ─── SLIDE 4: SAMPLE DAY MEAL PLAN ────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 7.5, fill: { color: C.offWhite } });
// Header
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 1.0, fill: { color: C.teal } });
s.addText("🍽️ SAMPLE ONE-DAY MEAL PLAN", {
x: 0.3, y: 0, w: 12.7, h: 1.0,
fontSize: 24, bold: true, color: C.white,
align: "left", valign: "middle", margin: 0
});
const meals = [
{
time: "Early Morning\n(6–7 AM)",
icon: "🌅",
meal: "2 glasses of warm water\n(Before anything else)",
color: C.lightTeal, border: C.teal
},
{
time: "Breakfast\n(8–9 AM)",
icon: "🥛",
meal: "Poha / Upma / Oats porridge\n+ 1 glass of milk\n+ 1 banana or apple",
color: C.lightGreen, border: C.midGreen
},
{
time: "Mid-Morning\n(11 AM)",
icon: "💧",
meal: "1–2 glasses of water\n+ Coconut water (optional)\n(No soda / cold drinks)",
color: "EBF5FB", border: "2E86C1"
},
{
time: "Lunch\n(1–2 PM)",
icon: "🍚",
meal: "Rice + Dal (moong/masoor)\n+ Sabzi (cauliflower/cabbage/peas)\n+ Curd (1 bowl)\n+ Salad: cucumber, onion",
color: C.lightGreen, border: C.midGreen
},
{
time: "Evening Snack\n(4–5 PM)",
icon: "🍎",
meal: "Seasonal fruit (apple/papaya/guava)\n+ 1 glass of buttermilk\n(Avoid nuts as snack)",
color: C.lightOrange, border: C.orange
},
{
time: "Dinner\n(7–8 PM)",
icon: "🍗",
meal: "2 Rotis + Chicken / Fish curry\n+ Bottle gourd / Lauki sabzi\n+ Small bowl of curd",
color: C.lightGreen, border: C.midGreen
},
{
time: "Bedtime\n(9–10 PM)",
icon: "🌙",
meal: "1 glass of warm milk\nor 1 glass of water\n(Helps dilute overnight urine)",
color: "F4ECF7", border: "7D3C98"
}
];
const cols = [0.2, 1.95, 3.7, 5.45, 7.2, 8.95, 10.7];
meals.forEach((m, i) => {
const x = cols[i];
const w = 1.65;
// Card
s.addShape(pres.ShapeType.roundRect, {
x, y: 1.1, w, h: 6.1,
fill: { color: m.color }, line: { color: m.border, width: 1.5 },
rectRadius: 0.15
});
// Time header
s.addShape(pres.ShapeType.roundRect, {
x: x + 0.05, y: 1.15, w: w - 0.1, h: 0.9,
fill: { color: m.border }, rectRadius: 0.12
});
s.addText(m.time, {
x: x + 0.05, y: 1.15, w: w - 0.1, h: 0.9,
fontSize: 10, bold: true, color: C.white,
align: "center", valign: "middle", margin: 0
});
// Icon
s.addText(m.icon, {
x: x + 0.1, y: 2.1, w: w - 0.2, h: 0.7,
fontSize: 30, align: "center", margin: 0
});
// Meal text
s.addText(m.meal, {
x: x + 0.1, y: 2.85, w: w - 0.2, h: 4.15,
fontSize: 10.5, color: C.textDark, fontFace: "Calibri",
align: "center", valign: "top", margin: 0, lineSpacingMultiple: 1.35
});
});
// Arrow connectors (decorative dots between meals)
for (let i = 0; i < 6; i++) {
s.addText("→", {
x: cols[i] + 1.6, y: 4.05, w: 0.35, h: 0.35,
fontSize: 14, bold: true, color: C.teal, align: "center", margin: 0
});
}
}
// ─── SLIDE 5: HYDRATION & GOLDEN RULES ────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 7.5, fill: { color: "EAF2FF" } });
// Header
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 1.0, fill: { color: "2E86C1" } });
s.addText("💧 HYDRATION GUIDE + GOLDEN RULES TO PREVENT STONES", {
x: 0.3, y: 0, w: 12.7, h: 1.0,
fontSize: 22, bold: true, color: C.white,
align: "left", valign: "middle", margin: 0
});
// Left: Hydration column
s.addShape(pres.ShapeType.roundRect, {
x: 0.3, y: 1.15, w: 5.8, h: 6.0,
fill: { color: "D6EAF8" }, line: { color: "2E86C1", width: 2 }, rectRadius: 0.2
});
s.addText("💧 DAILY WATER TARGET", {
x: 0.4, y: 1.2, w: 5.6, h: 0.55,
fontSize: 17, bold: true, color: "1A5276",
align: "center", valign: "middle", margin: 0
});
// Water glass visual
const glasses = ["🥤","🥤","🥤","🥤","🥤","🥤","🥤","🥤"];
s.addText(glasses.join(" "), {
x: 0.5, y: 1.85, w: 5.4, h: 0.8,
fontSize: 28, align: "center", margin: 0
});
s.addText("8 glasses = ~2.5 to 3 Litres per day", {
x: 0.5, y: 2.65, w: 5.4, h: 0.45,
fontSize: 16, bold: true, color: "1A5276", align: "center", margin: 0
});
s.addShape(pres.ShapeType.rect, { x: 0.6, y: 3.15, w: 5.0, h: 0.04, fill: { color: "2E86C1" } });
const hydrationTips = [
"🌅 2 glasses immediately on waking up",
"🍽️ 1 glass before each meal",
"🌙 1 glass before bedtime (key!)",
"💛 Urine should be pale yellow",
"🚫 Avoid sugary sodas & cold drinks",
"✅ Lemon water, coconut water are great",
"🌡️ Drink extra in summer / after exercise"
];
s.addText(hydrationTips.map((t, i) => ({ text: t, options: { breakLine: i < hydrationTips.length - 1 } })), {
x: 0.5, y: 3.3, w: 5.4, h: 3.6,
fontSize: 13, color: "1A5276", fontFace: "Calibri",
valign: "top", margin: 0, lineSpacingMultiple: 1.5
});
// Right: Golden rules
s.addShape(pres.ShapeType.roundRect, {
x: 6.5, y: 1.15, w: 6.5, h: 6.0,
fill: { color: C.lightGreen }, line: { color: C.midGreen, width: 2 }, rectRadius: 0.2
});
s.addText("🏆 GOLDEN RULES", {
x: 6.6, y: 1.2, w: 6.3, h: 0.55,
fontSize: 17, bold: true, color: C.darkGreen,
align: "center", valign: "middle", margin: 0
});
s.addShape(pres.ShapeType.rect, { x: 6.7, y: 1.8, w: 6.1, h: 0.04, fill: { color: C.midGreen } });
const rules = [
["1", "Drink 2.5–3 L of water EVERY day", C.teal],
["2", "Do NOT avoid dairy / calcium", C.midGreen],
["3", "Eat dairy WITH high-oxalate foods (binds oxalate in gut)", C.darkGreen],
["4", "Reduce salt intake — high salt = more calcium in urine", C.orange],
["5", "Limit animal protein (red meat, organ meat)", C.orange],
["6", "Avoid Vitamin C supplements > 500 mg/day", C.red],
["7", "Never hold urine for long — urinate regularly", C.teal],
["8", "Follow up with your doctor every 3–6 months", C.darkGreen],
];
rules.forEach((r, i) => {
const yPos = 1.95 + i * 0.58;
s.addShape(pres.ShapeType.ellipse, {
x: 6.7, y: yPos, w: 0.42, h: 0.42,
fill: { color: r[2] }
});
s.addText(r[0], {
x: 6.7, y: yPos, w: 0.42, h: 0.42,
fontSize: 13, bold: true, color: C.white,
align: "center", valign: "middle", margin: 0
});
s.addText(r[1], {
x: 7.2, y: yPos + 0.01, w: 5.6, h: 0.4,
fontSize: 13, color: C.textDark, fontFace: "Calibri",
valign: "middle", margin: 0
});
});
}
// ─── SLIDE 6: CLOSING / REMINDER ──────────────────────────────────────────────
{
const s = pres.addSlide();
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 7.5, fill: { color: C.darkGreen } });
s.addShape(pres.ShapeType.rect, { x: 0, y: 0, w: 13.3, h: 0.12, fill: { color: C.orange } });
s.addShape(pres.ShapeType.rect, { x: 0, y: 7.38, w: 13.3, h: 0.12, fill: { color: C.orange } });
s.addText("🌿", { x: 0.3, y: 0.5, w: 2, h: 2, fontSize: 90, align: "center" });
s.addText("💊", { x: 10.8, y: 0.5, w: 2, h: 2, fontSize: 90, align: "center" });
s.addText("💧", { x: 0.3, y: 5.0, w: 2, h: 2, fontSize: 90, align: "center" });
s.addText("🫀", { x: 10.8, y: 5.0, w: 2, h: 2, fontSize: 90, align: "center" });
s.addText("Remember", {
x: 2.5, y: 0.8, w: 8.3, h: 0.7,
fontSize: 18, italic: true, color: "A9DFBF",
align: "center", margin: 0
});
s.addText("Your Kidneys Work Hard\nFor You — Help Them!", {
x: 2.5, y: 1.6, w: 8.3, h: 1.5,
fontSize: 36, bold: true, color: C.white,
align: "center", margin: 0, lineSpacingMultiple: 1.2
});
s.addShape(pres.ShapeType.rect, { x: 3.5, y: 3.25, w: 6.3, h: 0.06, fill: { color: C.orange } });
const reminders = [
"✅ Follow this low-oxalate diet every day",
"💧 Never skip your water intake",
"🏥 Get a kidney ultrasound done",
"🧪 Repeat urine test in 4–6 weeks",
"💬 Ask your doctor about potassium citrate"
];
s.addText(
reminders.map((r, i) => ({ text: r, options: { breakLine: i < reminders.length - 1 } })),
{
x: 2.8, y: 3.45, w: 7.7, h: 3.3,
fontSize: 17, color: "D6EAF8", fontFace: "Calibri",
align: "center", valign: "top", margin: 0, lineSpacingMultiple: 1.5
}
);
s.addText("This diet sheet is based on established nephrological guidelines. Consult your doctor or registered dietitian for personalized advice.", {
x: 1.5, y: 6.9, w: 10.3, h: 0.4,
fontSize: 10, italic: true, color: "7DCEA0",
align: "center", margin: 0
});
}
// ─── SAVE ─────────────────────────────────────────────────────────────────────
pres.writeFile({ fileName: "/home/daytona/workspace/diet-sheet/Low_Oxalate_Diet_Sheet.pptx" })
.then(() => console.log("SUCCESS: File saved."))
.catch(e => console.error("ERROR:", e));
cd /home/daytona/workspace/diet-sheet && node diet_sheet.js 2>&1
ls -lh /home/daytona/workspace/diet-sheet/Low_Oxalate_Diet_Sheet.pptx
Low Oxalate Diet Sheet
Presentation · PPTX
| Slide | Content |
|---|---|
| 1 - Cover | Title slide with patient intro and key action tags |
| 2 - Foods to AVOID | 4 color-coded red cards: Vegetables, Sweets & Drinks, Nuts & Grains, Fruits - with ✗ marks |
| 3 - Safe Foods | 4 green cards: Proteins, Dairy, Grains & Staples, Fruits & Vegetables - with ✓ marks |
| 4 - Sample Day Meal Plan | 7-meal timeline from Early Morning to Bedtime with food suggestions |
| 5 - Hydration + Golden Rules | Water target (8 glasses / 2.5-3L), timing tips, and 8 golden rules |
| 6 - Closing Reminder | Motivational close with action checklist (follow-up, ultrasound, repeat urine test) |
Create a printable one-page quick reference card for the patient to carry
ls /home/daytona/workspace/diet-sheet/
~/diet-sheet/quick_ref_card.py
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import mm, cm
from reportlab.pdfgen import canvas
from reportlab.lib.colors import HexColor
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.ttfonts import TTFont
import os
# ── Colours ──────────────────────────────────────────────────────────────────
DARK_GREEN = HexColor("#1A5276")
MID_GREEN = HexColor("#1E8449")
LIGHT_GREEN = HexColor("#D5F5E3")
RED = HexColor("#C0392B")
LIGHT_RED = HexColor("#FADBD8")
ORANGE = HexColor("#E67E22")
LIGHT_ORG = HexColor("#FDEBD0")
TEAL = HexColor("#148F77")
LIGHT_TEAL = HexColor("#D1F2EB")
BLUE = HexColor("#2E86C1")
LIGHT_BLUE = HexColor("#D6EAF8")
YELLOW = HexColor("#F9E79F")
WHITE = colors.white
BLACK = HexColor("#1C2833")
GREY = HexColor("#7F8C8D")
W, H = A4 # 595 x 842 pts (portrait)
M = 12 # margin pts
output = "/home/daytona/workspace/diet-sheet/Patient_QuickRef_Card.pdf"
c = canvas.Canvas(output, pagesize=A4)
# ── helpers ───────────────────────────────────────────────────────────────────
def rect(x, y, w, h, fill, radius=0, stroke_color=None, stroke_w=0.5):
c.setFillColor(fill)
if stroke_color:
c.setStrokeColor(stroke_color)
c.setLineWidth(stroke_w)
else:
c.setStrokeColor(fill)
c.setLineWidth(0)
c.roundRect(x, y, w, h, radius, fill=1, stroke=1 if stroke_color else 0)
def text(txt, x, y, size=9, color=BLACK, bold=False, align="left", max_width=None):
c.setFillColor(color)
face = "Helvetica-Bold" if bold else "Helvetica"
c.setFont(face, size)
if align == "center" and max_width:
tw = c.stringWidth(txt, face, size)
x = x + (max_width - tw) / 2
elif align == "right" and max_width:
tw = c.stringWidth(txt, face, size)
x = x + max_width - tw
c.drawString(x, y, txt)
def wrapped_text(txt, x, y, w, size=8.5, color=BLACK, bold=False, line_height=11):
"""Draw wrapped text within width w, returns y after last line."""
face = "Helvetica-Bold" if bold else "Helvetica"
c.setFont(face, size)
c.setFillColor(color)
words = txt.split()
line = ""
cy = y
for word in words:
test = (line + " " + word).strip()
if c.stringWidth(test, face, size) <= w:
line = test
else:
c.drawString(x, cy, line)
cy -= line_height
line = word
if line:
c.drawString(x, cy, line)
cy -= line_height
return cy
def bullet_list(items, x, y, w, size=8.5, color=BLACK, bullet_color=None, line_h=12, bullet="•"):
bc = bullet_color or color
face = "Helvetica"
bold_face = "Helvetica-Bold"
cy = y
for item in items:
c.setFillColor(bc)
c.setFont(bold_face, size)
bw = c.stringWidth(bullet + " ", bold_face, size)
c.drawString(x, cy, bullet)
c.setFillColor(color)
c.setFont(face, size)
# wrap rest
words = item.split()
line = ""
first = True
for word in words:
test = (line + " " + word).strip()
if c.stringWidth(test, face, size) <= (w - bw):
line = test
else:
c.drawString(x + bw, cy, line)
cy -= line_h
line = word
first = False
if line:
c.drawString(x + bw, cy, line)
cy -= line_h
return cy
# ═══════════════════════════════════════════════════════════════════════════════
# HEADER BAND
# ═══════════════════════════════════════════════════════════════════════════════
rect(0, H - 46, W, 46, DARK_GREEN)
# Accent stripe top
rect(0, H - 4, W, 4, MID_GREEN)
text("LOW-OXALATE DIET", M + 2, H - 22, size=17, color=WHITE, bold=True)
text("Quick Reference Card | Calcium Oxalate Kidney Crystals & Stones", M + 2, H - 38, size=9, color=HexColor("#A9DFBF"))
# Right side of header: tagline
text("💧 Drink More • 🥗 Eat Smart • 🚫 Limit Oxalate", W - 210, H - 28, size=8.5, color=HexColor("#D5F5E3"))
# ═══════════════════════════════════════════════════════════════════════════════
# ROW 1 (3 columns): Avoid | Safe | Water
# ═══════════════════════════════════════════════════════════════════════════════
COL_Y = H - 52 # top of row 1
COL_H = 185 # height of row 1 boxes
COL_GAP = 5
COL_W = (W - 2*M - 2*COL_GAP) / 3 # ≈ 185 pts each
col1_x = M
col2_x = M + COL_W + COL_GAP
col3_x = M + 2*(COL_W + COL_GAP)
row1_y = COL_Y - COL_H # bottom y of row 1
# ── Column 1: AVOID ──────────────────────────────────────────────────────────
rect(col1_x, row1_y, COL_W, COL_H, LIGHT_RED, radius=5, stroke_color=RED, stroke_w=1.2)
rect(col1_x, row1_y + COL_H - 20, COL_W, 20, RED, radius=5)
rect(col1_x, row1_y + COL_H - 20, COL_W, 10, RED) # square off bottom corners of header
text("🚫 FOODS TO AVOID", col1_x + 6, row1_y + COL_H - 14, size=9.5, color=WHITE, bold=True)
avoid_items = [
"Spinach, Beets, Okra (Bhindi)",
"Swiss chard, Celery, Leeks",
"Chocolate & Cocoa products",
"Strong black / green tea",
"Almonds, Cashews, Peanuts",
"Wheat bran, Wheat germ",
"Rhubarb, Starfruit (very high!)",
"Kiwi, Raspberries (excess)",
"Soy products, Tofu (large qty)",
"Cold drinks & Sugary soda",
"Vitamin C supplements > 500 mg",
]
bullet_list(avoid_items, col1_x + 6, row1_y + COL_H - 28, COL_W - 10,
size=8, color=HexColor("#7B241C"), bullet_color=RED, line_h=11, bullet="✗")
# ── Column 2: SAFE ───────────────────────────────────────────────────────────
rect(col2_x, row1_y, COL_W, COL_H, LIGHT_GREEN, radius=5, stroke_color=MID_GREEN, stroke_w=1.2)
rect(col2_x, row1_y + COL_H - 20, COL_W, 20, MID_GREEN, radius=5)
rect(col2_x, row1_y + COL_H - 20, COL_W, 10, MID_GREEN)
text("✅ SAFE FOODS (Eat Freely)", col2_x + 6, row1_y + COL_H - 14, size=9.5, color=WHITE, bold=True)
safe_items = [
"Chicken, Fish, Eggs",
"Milk, Curd, Paneer, Buttermilk",
"White rice, Roti, Bread, Oats",
"Apple, Banana, Mango, Papaya",
"Guava, Watermelon, Cucumber",
"Cauliflower, Cabbage, Peas",
"Onion, Garlic, Bottle gourd",
"Moong dal, Masoor dal",
"Corn / Poha / Pasta",
"Coconut water (excellent!)",
"Lemon water (very helpful)",
]
bullet_list(safe_items, col2_x + 6, row1_y + COL_H - 28, COL_W - 10,
size=8, color=HexColor("#1D6A3A"), bullet_color=MID_GREEN, line_h=11, bullet="✓")
# ── Column 3: WATER ──────────────────────────────────────────────────────────
rect(col3_x, row1_y, COL_W, COL_H, LIGHT_BLUE, radius=5, stroke_color=BLUE, stroke_w=1.2)
rect(col3_x, row1_y + COL_H - 20, COL_W, 20, BLUE, radius=5)
rect(col3_x, row1_y + COL_H - 20, COL_W, 10, BLUE)
text("💧 HYDRATION RULES", col3_x + 6, row1_y + COL_H - 14, size=9.5, color=WHITE, bold=True)
water_items = [
"Drink 2.5 – 3 Litres per day",
"2 glasses on waking (before tea!)",
"1 glass before every meal",
"1 glass before going to bed",
"Urine must be pale yellow",
"Never hold urine for long",
"Extra water in summer / exercise",
"Lemon juice in water is great",
"Avoid soda & energy drinks",
]
bullet_list(water_items, col3_x + 6, row1_y + COL_H - 28, COL_W - 10,
size=8, color=HexColor("#154360"), bullet_color=BLUE, line_h=11, bullet="💧")
# ═══════════════════════════════════════════════════════════════════════════════
# ROW 2 (2 panels): Sample Meal Plan | Golden Rules
# ═══════════════════════════════════════════════════════════════════════════════
ROW2_Y = row1_y - 8
ROW2_H = 210
row2_bottom = ROW2_Y - ROW2_H
MEAL_W = (W - 2*M - COL_GAP) * 0.53
RULE_W = (W - 2*M - COL_GAP) * 0.47
meal_x = M
rule_x = M + MEAL_W + COL_GAP
# ── Panel A: Meal Plan ────────────────────────────────────────────────────────
rect(meal_x, row2_bottom, MEAL_W, ROW2_H, HexColor("#F0FFF4"), radius=5, stroke_color=TEAL, stroke_w=1.2)
rect(meal_x, row2_bottom + ROW2_H - 20, MEAL_W, 20, TEAL, radius=5)
rect(meal_x, row2_bottom + ROW2_H - 20, MEAL_W, 10, TEAL)
text("🍽️ SAMPLE ONE-DAY MEAL PLAN", meal_x + 6, row2_bottom + ROW2_H - 14, size=9.5, color=WHITE, bold=True)
meals = [
("🌅 6–7 AM", "2 glasses warm water (before anything)"),
("☕ 8–9 AM", "Poha / Upma / Oats + Milk + Apple or Banana"),
("🕙 11 AM", "Water or Coconut water (NO soda)"),
("🍚 1–2 PM", "Rice + Dal + Sabzi (cauliflower/cabbage) + Curd + Salad"),
("🍎 4–5 PM", "Seasonal fruit (apple/papaya) + Buttermilk"),
("🍗 7–8 PM", "Roti + Chicken/Fish or Dal + Lauki sabzi + Curd"),
("🌙 9–10 PM", "Warm milk or 1 glass water (dilutes overnight urine)"),
]
cy = row2_bottom + ROW2_H - 30
for (time_lbl, meal_desc) in meals:
# time chip
rect(meal_x + 5, cy - 9, 60, 14, TEAL, radius=3)
text(time_lbl, meal_x + 7, cy - 3, size=7.5, color=WHITE, bold=True)
# meal text
c.setFont("Helvetica", 8.5)
c.setFillColor(BLACK)
c.drawString(meal_x + 70, cy - 3, meal_desc)
cy -= 26
# ── Panel B: Golden Rules ─────────────────────────────────────────────────────
rect(rule_x, row2_bottom, RULE_W, ROW2_H, YELLOW, radius=5, stroke_color=ORANGE, stroke_w=1.2)
rect(rule_x, row2_bottom + ROW2_H - 20, RULE_W, 20, ORANGE, radius=5)
rect(rule_x, row2_bottom + ROW2_H - 20, RULE_W, 10, ORANGE)
text("🏆 GOLDEN RULES", rule_x + 6, row2_bottom + ROW2_H - 14, size=9.5, color=WHITE, bold=True)
rules = [
("1", "Drink 2.5–3 L water every single day", TEAL),
("2", "Do NOT avoid dairy or calcium foods", MID_GREEN),
("3", "Eat curd/milk WITH your meals (binds oxalate in gut)",DARK_GREEN),
("4", "Reduce salt — high salt = more calcium in urine", ORANGE),
("5", "Limit red meat & organ meat", ORANGE),
("6", "No Vitamin C supplements > 500 mg/day", RED),
("7", "Get a kidney ultrasound done", BLUE),
("8", "Repeat urine test in 4–6 weeks", BLUE),
("9", "Ask doctor about Potassium Citrate", DARK_GREEN),
]
ry = row2_bottom + ROW2_H - 28
for num, rule_text, chip_col in rules:
# number circle (simulated with small rounded rect)
rect(rule_x + 5, ry - 9, 14, 14, chip_col, radius=3)
text(num, rule_x + 7 if len(num)==1 else rule_x+5, ry - 2, size=8, color=WHITE, bold=True)
c.setFont("Helvetica", 8.5)
c.setFillColor(BLACK)
c.drawString(rule_x + 24, ry - 2, rule_text)
ry -= 20
# ═══════════════════════════════════════════════════════════════════════════════
# ROW 3: IMPORTANT REMINDERS STRIP
# ═══════════════════════════════════════════════════════════════════════════════
REM_Y = row2_bottom - 6
REM_H = 38
rect(M, REM_Y - REM_H, W - 2*M, REM_H, LIGHT_TEAL, radius=5, stroke_color=TEAL, stroke_w=1)
text("⚠️ IMPORTANT REMINDERS", M + 8, REM_Y - 12, size=9, color=TEAL, bold=True)
reminders = [
"Always eat dairy WITH meals — never restrict calcium",
"Urine should be pale yellow, not dark — dark = drink more",
"Starfruit is extremely high in oxalate — NEVER eat it",
"If pain returns, see a doctor immediately — don't wait",
]
rx_start = M + 8
ry_start = REM_Y - 24
for i, rem in enumerate(reminders):
rx = rx_start + i * (W - 2*M - 16) / 4
c.setFillColor(TEAL)
c.setFont("Helvetica-Bold", 8)
c.drawString(rx, ry_start, "• " + rem)
# ═══════════════════════════════════════════════════════════════════════════════
# FOOTER
# ═══════════════════════════════════════════════════════════════════════════════
FOOT_H = 22
rect(0, 0, W, FOOT_H, DARK_GREEN)
rect(0, FOOT_H - 3, W, 3, MID_GREEN)
text("For Calcium Oxalate Kidney Stone / Crystal Patients | Based on established nephrological dietary guidelines",
M, 8, size=7.5, color=HexColor("#A9DFBF"))
text("Consult your doctor or dietitian for personalised advice. This card is for general guidance only.",
W - M, 8, size=7, color=HexColor("#7DCEA0"), align="right", max_width=0)
# right-align disclaimer
c.setFillColor(HexColor("#7DCEA0"))
c.setFont("Helvetica", 7)
disclaimer = "Consult your doctor or dietitian for personalised advice."
c.drawRightString(W - M, 8, disclaimer)
# ── Save ──────────────────────────────────────────────────────────────────────
c.save()
print(f"PDF saved: {output}")
cd /home/daytona/workspace/diet-sheet && python quick_ref_card.py 2>&1
ls -lh /home/daytona/workspace/diet-sheet/Patient_QuickRef_Card.pdf
Patient QuickRef Card
PDF Document · PDF
| Zone | Content |
|---|---|
| Header | Title banner with patient name of condition |
| Top Row (3 columns) | 🚫 Foods to Avoid (red) · ✅ Safe Foods (green) · 💧 Hydration Rules (blue) |
| Middle Row (2 panels) | 🍽️ Sample One-Day Meal Plan with time chips · 🏆 9 Golden Rules with numbered badges |
| Reminder Strip | 4 critical alerts (dairy with meals, urine color, starfruit warning, when to see a doctor) |
| Footer | Disclaimer and guideline reference |
How to consume this
Cital disodium hydrogen citrate liquid dosage how to consume kidney stones
http://annapurnapharmacy.com/drug/3446-cital-syrup
| Detail | Instruction |
|---|---|
| Dose | 15 ml to 30 ml per dose (as directed by doctor) |
| Frequency | 3 times a day (after meals) |
| How to take | Dilute in a full glass of water (150-200 ml) before drinking - do NOT drink it neat |
| When | After breakfast, after lunch, after dinner |
| Duration | As prescribed - usually continued until symptoms resolve and urine test normalises |
The label on your bottle says "Dosage: As directed by the physician" - so follow exactly what your doctor prescribed. The typical standard dose is 15 ml three times a day mixed in water.
| Precaution | Details |
|---|---|
| Always dilute | Never take undiluted - can cause stomach irritation |
| Drink extra water | Minimum 2.5-3 litres of water per day alongside this medicine |
| With food | Take after meals to reduce nausea or stomach upset |
| Kidney disease | Use with caution if severe kidney disease - dose adjustment needed |
| Hypertension / Heart failure | Contains sodium - caution in patients on low-sodium diet |
| Diabetes | This version is sugar-free (with sucralose) - safe for diabetics |
| Alcohol | Avoid alcohol while on this medicine |
| Cital Does | Low-Oxalate Diet Does |
|---|---|
| Alkalinizes urine (prevents crystal formation) | Reduces oxalate load entering urine |
| Raises urine pH above 6.5 | Reduces the raw material for crystal formation |
| Acts like potassium citrate - inhibits crystal growth | Reduces dietary triggers |
| Relieves pain and burning | Prevents recurrence long-term |
⚠️ Important: This bottle says "Dosage as directed by the physician" - always follow your doctor's specific dose. Do not increase the dose on your own. If you were not given a specific dose instruction, contact your prescribing doctor before starting.