Hii I am an MD Homoepathic student and want to achieve great knowledge of materia medica with proper applicatikn in my practice...Explai the phosphorous remedy, in detail , how the patient will describe their symtpoms in clinic...explain the medicine in a way so that i can understand it easily with som visual infographics, mnemonicss...also provide the content into printable pdf
Phosphorus homeopathic materia medica keynotes symptoms personality constitution
https://www.materiamedica.info/en/materia-medica/henry-c-all…
mkdir -p /home/daytona/workspace/phosphorus-pdf && ls /home/daytona/workspace/
~/phosphorus-pdf/generate_pdf.py
#!/usr/bin/env python3
"""
Phosphorus Homeopathic Materia Medica - Comprehensive Study Guide PDF
For MD Homoeopathy Students
"""
from reportlab.lib.pagesizes import A4
from reportlab.lib import colors
from reportlab.lib.units import cm, mm
from reportlab.lib.styles import getSampleStyleSheet, ParagraphStyle
from reportlab.lib.enums import TA_CENTER, TA_LEFT, TA_JUSTIFY
from reportlab.platypus import (
SimpleDocTemplate, Paragraph, Spacer, Table, TableStyle,
HRFlowable, PageBreak, KeepTogether
)
from reportlab.platypus.flowables import Flowable
from reportlab.graphics.shapes import Drawing, Rect, Circle, String, Line, Polygon, RoundRect
from reportlab.graphics import renderPDF
from reportlab.graphics.charts.piecharts import Pie
import math
# ─── COLOR PALETTE ─────────────────────────────────────────────────────────────
PHOS_GOLD = colors.HexColor('#F5A623') # warm amber (phosphorus glow)
PHOS_ORANGE = colors.HexColor('#E8751A') # deep orange
PHOS_DARK = colors.HexColor('#1A1A2E') # dark navy
PHOS_TEAL = colors.HexColor('#16213E')
PHOS_BLUE = colors.HexColor('#0F3460')
PHOS_LIGHT = colors.HexColor('#FFF8EE') # warm white background
PHOS_MINT = colors.HexColor('#E8F5E9')
PHOS_PINK = colors.HexColor('#FCE4EC')
PHOS_LAVENDER= colors.HexColor('#EDE7F6')
PHOS_YELLOW = colors.HexColor('#FFFDE7')
PHOS_CYAN = colors.HexColor('#E1F5FE')
BOX_GREEN = colors.HexColor('#2E7D32')
BOX_RED = colors.HexColor('#C62828')
BOX_BLUE = colors.HexColor('#1565C0')
BOX_PURPLE = colors.HexColor('#6A1B9A')
BOX_ORANGE = colors.HexColor('#E65100')
WHITE = colors.white
BLACK = colors.black
W, H = A4 # 595.27, 841.89
# ─── CUSTOM FLOWABLES ──────────────────────────────────────────────────────────
class GlowTitle(Flowable):
"""A glowing phosphorus-style title banner."""
def __init__(self, title, subtitle="", width=None):
Flowable.__init__(self)
self.title = title
self.subtitle = subtitle
self.width = width or (W - 4*cm)
self.height = 4.2*cm
def draw(self):
c = self.canv
w, h = self.width, self.height
# Gradient-like background using overlapping rectangles
for i in range(10):
alpha = 0.3 + i * 0.07
c.setFillColor(colors.HexColor('#F5A623'), alpha=alpha)
c.roundRect(i*2, i*1.5, w - i*4, h - i*3, 12, fill=1, stroke=0)
# Outer border
c.setStrokeColor(PHOS_ORANGE)
c.setLineWidth(2)
c.roundRect(0, 0, w, h, 12, fill=0, stroke=1)
# Title text
c.setFillColor(PHOS_DARK)
c.setFont("Helvetica-Bold", 26)
c.drawCentredString(w/2, h - 1.5*cm, self.title)
if self.subtitle:
c.setFont("Helvetica", 13)
c.setFillColor(PHOS_BLUE)
c.drawCentredString(w/2, h - 2.4*cm, self.subtitle)
# Decorative dots
c.setFillColor(PHOS_ORANGE)
for x in [0.5*cm, w-0.5*cm]:
c.circle(x, h/2, 5, fill=1, stroke=0)
class SectionHeader(Flowable):
"""Colored section header bar."""
def __init__(self, text, color=None, icon="", width=None):
Flowable.__init__(self)
self.text = text
self.color = color or PHOS_BLUE
self.icon = icon
self.width = width or (W - 4*cm)
self.height = 1.0*cm
def draw(self):
c = self.canv
w, h = self.width, self.height
c.setFillColor(self.color)
c.roundRect(0, 0, w, h, 6, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 13)
label = f"{self.icon} {self.text}" if self.icon else self.text
c.drawString(0.4*cm, 0.3*cm, label)
class InfoBox(Flowable):
"""A rounded info box with label and content lines."""
def __init__(self, title, items, bg_color, border_color, title_color=None, width=None):
Flowable.__init__(self)
self.title = title
self.items = items
self.bg_color = bg_color
self.border_color = border_color
self.title_color = title_color or border_color
self.width = width or (W - 4*cm)
self.height = (len(items) + 1.5) * 0.55 * cm + 0.8*cm
def draw(self):
c = self.canv
w, h = self.width, self.height
c.setFillColor(self.bg_color)
c.roundRect(0, 0, w, h, 8, fill=1, stroke=0)
c.setStrokeColor(self.border_color)
c.setLineWidth(1.5)
c.roundRect(0, 0, w, h, 8, fill=0, stroke=1)
# Title
c.setFillColor(self.title_color)
c.setFont("Helvetica-Bold", 11)
c.drawString(0.4*cm, h - 0.6*cm, self.title)
# Items
c.setFillColor(PHOS_DARK)
c.setFont("Helvetica", 9.5)
for i, item in enumerate(self.items):
y = h - 1.1*cm - i * 0.55*cm
# bullet
c.setFillColor(self.border_color)
c.circle(0.5*cm, y + 0.15*cm, 2.5, fill=1, stroke=0)
c.setFillColor(PHOS_DARK)
c.drawString(0.85*cm, y, item)
class PhosphorusBodyDiagram(Flowable):
"""Visual body diagram showing phosphorus symptoms on body systems."""
def __init__(self, width=None):
Flowable.__init__(self)
self.width = width or (W - 4*cm)
self.height = 7.5*cm
def draw(self):
c = self.canv
w, h = self.width, self.height
# Background
c.setFillColor(PHOS_LIGHT)
c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
c.setStrokeColor(PHOS_GOLD)
c.setLineWidth(1.5)
c.roundRect(0, 0, w, h, 10, fill=0, stroke=1)
# Title
c.setFont("Helvetica-Bold", 11)
c.setFillColor(PHOS_BLUE)
c.drawCentredString(w/2, h - 0.6*cm, "PHOSPHORUS — BODY SYSTEMS AT A GLANCE")
# Draw simplified body silhouette in center
cx = w / 2
# Head
c.setFillColor(colors.HexColor('#FFDDC1'))
c.setStrokeColor(PHOS_ORANGE)
c.setLineWidth(1)
c.circle(cx, h - 1.8*cm, 0.55*cm, fill=1, stroke=1)
# Neck
c.setFillColor(colors.HexColor('#FFDDC1'))
c.rect(cx-0.2*cm, h - 2.6*cm, 0.4*cm, 0.6*cm, fill=1, stroke=0)
# Torso
c.setFillColor(colors.HexColor('#FFDDC1'))
c.roundRect(cx-0.8*cm, h - 5.0*cm, 1.6*cm, 2.4*cm, 4, fill=1, stroke=1)
# Arms
c.setStrokeColor(colors.HexColor('#FFDDC1'))
c.setLineWidth(5)
c.line(cx - 0.8*cm, h - 3.0*cm, cx - 2.0*cm, h - 4.5*cm)
c.line(cx + 0.8*cm, h - 3.0*cm, cx + 2.0*cm, h - 4.5*cm)
# Legs
c.line(cx - 0.4*cm, h - 5.0*cm, cx - 0.5*cm, h - 6.8*cm)
c.line(cx + 0.4*cm, h - 5.0*cm, cx + 0.5*cm, h - 6.8*cm)
# SYMPTOM LABELS with arrows
labels = [
# (x, y, text, side) side: L or R
(cx - 5.5*cm, h - 1.6*cm, "Head: Burning, Empty\nSensation, Vertigo", "L", cx - 0.55*cm, h - 1.8*cm),
(cx + 3.2*cm, h - 1.6*cm, "Eyes: Hollow,\nBlue Rings", "R", cx + 0.55*cm, h - 1.8*cm),
(cx - 5.5*cm, h - 3.2*cm, "Chest: Burning,\nTight, <Left Side", "L", cx - 0.8*cm, h - 3.5*cm),
(cx + 3.2*cm, h - 2.8*cm, "Throat:\nHoarseness,\nLaryngitis", "R", cx + 0.8*cm, h - 3.0*cm),
(cx - 5.5*cm, h - 4.5*cm, "Abdomen:\nAll-gone Sensation,\nProfuse Diarrhoea", "L", cx - 0.8*cm, h - 4.2*cm),
(cx + 3.2*cm, h - 4.5*cm, "Spine: Burning\nBetween Scapulae", "R", cx + 0.8*cm, h - 3.8*cm),
(cx - 5.5*cm, h - 6.2*cm, "Limbs: Trembling\nWeakness, Burning\nPalms", "L", cx - 0.5*cm, h - 6.0*cm),
(cx + 3.2*cm, h - 6.0*cm, "Bleeding:\nSmall wounds,\nBright red", "R", cx + 0.5*cm, h - 5.5*cm),
]
c.setFont("Helvetica", 7.5)
for lx, ly, text, side, ax, ay in labels:
# Arrow line
c.setStrokeColor(PHOS_ORANGE)
c.setLineWidth(0.8)
if side == "L":
txt_end_x = lx + 2.8*cm
else:
txt_end_x = lx
c.line(txt_end_x, ly + 0.15*cm, ax, ay)
# Label box
c.setFillColor(PHOS_YELLOW)
bw = 2.7*cm
bh = 0.8*cm if "\n" not in text else (text.count("\n") + 1) * 0.4*cm + 0.3*cm
if side == "L":
bx = lx
else:
bx = lx
c.roundRect(bx, ly - bh + 0.3*cm, bw, bh, 3, fill=1, stroke=0)
c.setFillColor(PHOS_DARK)
lines = text.split("\n")
for li, line in enumerate(lines):
c.drawString(bx + 0.1*cm, ly - li * 0.35*cm, line)
class MnemonicBox(Flowable):
"""Visual mnemonic display box."""
def __init__(self, title, letters, width=None):
Flowable.__init__(self)
self.title = title
self.letters = letters # list of (letter, word, description)
self.width = width or (W - 4*cm)
self.height = (len(letters) + 1) * 0.75*cm + 0.7*cm
def draw(self):
c = self.canv
w, h = self.width, self.height
# Background
c.setFillColor(PHOS_LAVENDER)
c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
c.setStrokeColor(BOX_PURPLE)
c.setLineWidth(2)
c.roundRect(0, 0, w, h, 10, fill=0, stroke=1)
# Title
c.setFillColor(BOX_PURPLE)
c.setFont("Helvetica-Bold", 12)
c.drawCentredString(w/2, h - 0.6*cm, self.title)
# Letters
for i, (letter, word, desc) in enumerate(self.letters):
y = h - 1.3*cm - i * 0.75*cm
# Letter circle
c.setFillColor(BOX_PURPLE)
c.circle(0.6*cm, y + 0.1*cm, 0.28*cm, fill=1, stroke=0)
c.setFillColor(WHITE)
c.setFont("Helvetica-Bold", 10)
c.drawCentredString(0.6*cm, y, letter)
# Word
c.setFillColor(PHOS_ORANGE)
c.setFont("Helvetica-Bold", 10)
c.drawString(1.1*cm, y, f"{word}")
# Dash + description
c.setFillColor(PHOS_DARK)
c.setFont("Helvetica", 9.5)
c.drawString(1.1*cm + len(word)*0.18*cm + 0.4*cm, y, f"— {desc}")
class ModalityBox(Flowable):
"""Better/Worse modalities in a two-column box."""
def __init__(self, better, worse, width=None):
Flowable.__init__(self)
self.better = better
self.worse = worse
self.width = width or (W - 4*cm)
rows = max(len(better), len(worse))
self.height = (rows + 1.2) * 0.55*cm + 0.8*cm
def draw(self):
c = self.canv
w, h = self.width, self.height
half = w / 2 - 0.1*cm
# Better box
c.setFillColor(PHOS_MINT)
c.roundRect(0, 0, half, h, 8, fill=1, stroke=0)
c.setStrokeColor(BOX_GREEN)
c.setLineWidth(1.5)
c.roundRect(0, 0, half, h, 8, fill=0, stroke=1)
c.setFillColor(BOX_GREEN)
c.setFont("Helvetica-Bold", 11)
c.drawString(0.3*cm, h - 0.55*cm, "✓ BETTER (Amelioration)")
c.setFont("Helvetica", 9.5)
for i, item in enumerate(self.better):
y = h - 1.1*cm - i * 0.55*cm
c.setFillColor(BOX_GREEN)
c.circle(0.4*cm, y + 0.15*cm, 2.5, fill=1, stroke=0)
c.setFillColor(PHOS_DARK)
c.drawString(0.75*cm, y, item)
# Worse box
ox = w/2 + 0.1*cm
c.setFillColor(PHOS_PINK)
c.roundRect(ox, 0, half, h, 8, fill=1, stroke=0)
c.setStrokeColor(BOX_RED)
c.setLineWidth(1.5)
c.roundRect(ox, 0, half, h, 8, fill=0, stroke=1)
c.setFillColor(BOX_RED)
c.setFont("Helvetica-Bold", 11)
c.drawString(ox + 0.3*cm, h - 0.55*cm, "✗ WORSE (Aggravation)")
c.setFont("Helvetica", 9.5)
for i, item in enumerate(self.worse):
y = h - 1.1*cm - i * 0.55*cm
c.setFillColor(BOX_RED)
c.circle(ox + 0.4*cm, y + 0.15*cm, 2.5, fill=1, stroke=0)
c.setFillColor(PHOS_DARK)
c.drawString(ox + 0.75*cm, y, item)
class PatientQuoteBox(Flowable):
"""A speech-bubble style patient quote."""
def __init__(self, system, quotes, width=None):
Flowable.__init__(self)
self.system = system
self.quotes = quotes
self.width = width or (W - 4*cm)
self.height = (len(quotes) * 1.0 + 1.2) * cm
def draw(self):
c = self.canv
w, h = self.width, self.height
c.setFillColor(PHOS_CYAN)
c.roundRect(0, 0, w, h, 10, fill=1, stroke=0)
c.setStrokeColor(BOX_BLUE)
c.setLineWidth(1.5)
c.roundRect(0, 0, w, h, 10, fill=0, stroke=1)
# System name
c.setFillColor(BOX_BLUE)
c.setFont("Helvetica-Bold", 10)
c.drawString(0.4*cm, h - 0.55*cm, f"💬 {self.system}")
# Quotes
c.setFont("Helvetica-Oblique", 9)
c.setFillColor(PHOS_DARK)
for i, q in enumerate(self.quotes):
y = h - 1.1*cm - i * 0.9*cm
c.setFillColor(PHOS_GOLD)
c.roundRect(0.3*cm, y - 0.05*cm, 0.02*cm, 0.55*cm, 1, fill=1, stroke=0)
c.setFillColor(PHOS_DARK)
c.drawString(0.55*cm, y + 0.12*cm, f'"{q}"')
# ─── DOCUMENT SETUP ────────────────────────────────────────────────────────────
def create_styles():
styles = getSampleStyleSheet()
custom = {}
custom['title'] = ParagraphStyle('title', fontName='Helvetica-Bold', fontSize=22,
textColor=PHOS_DARK, alignment=TA_CENTER, spaceAfter=6)
custom['h2'] = ParagraphStyle('h2', fontName='Helvetica-Bold', fontSize=14,
textColor=PHOS_BLUE, spaceBefore=10, spaceAfter=4)
custom['h3'] = ParagraphStyle('h3', fontName='Helvetica-Bold', fontSize=11,
textColor=PHOS_ORANGE, spaceBefore=6, spaceAfter=3)
custom['body'] = ParagraphStyle('body', fontName='Helvetica', fontSize=9.5,
textColor=PHOS_DARK, leading=14, spaceAfter=4,
alignment=TA_JUSTIFY)
custom['bullet'] = ParagraphStyle('bullet', fontName='Helvetica', fontSize=9.5,
textColor=PHOS_DARK, leading=13, leftIndent=14,
bulletIndent=4)
custom['small'] = ParagraphStyle('small', fontName='Helvetica', fontSize=8.5,
textColor=colors.grey, alignment=TA_CENTER)
custom['key'] = ParagraphStyle('key', fontName='Helvetica-Bold', fontSize=10,
textColor=BOX_RED, leading=14)
custom['centred'] = ParagraphStyle('centred', fontName='Helvetica', fontSize=9.5,
textColor=PHOS_DARK, alignment=TA_CENTER)
return custom
def page_bg(canvas, doc):
"""Draw background on every page."""
canvas.saveState()
# Subtle page background
canvas.setFillColor(colors.HexColor('#FEFCF8'))
canvas.rect(0, 0, W, H, fill=1, stroke=0)
# Top accent bar
canvas.setFillColor(PHOS_ORANGE)
canvas.rect(0, H - 8, W, 8, fill=1, stroke=0)
# Bottom accent bar
canvas.setFillColor(PHOS_BLUE)
canvas.rect(0, 0, W, 5, fill=1, stroke=0)
# Footer text
canvas.setFillColor(colors.grey)
canvas.setFont("Helvetica", 8)
canvas.drawCentredString(W/2, 12, f"PHOSPHORUS — Homeopathic Materia Medica Study Guide | Page {doc.page}")
canvas.drawString(1.5*cm, 12, "For MD Homoeopathy Students")
canvas.restoreState()
# ─── MAIN CONTENT BUILDER ──────────────────────────────────────────────────────
def build_pdf():
path = "/home/daytona/workspace/phosphorus-pdf/Phosphorus_Materia_Medica.pdf"
doc = SimpleDocTemplate(
path, pagesize=A4,
leftMargin=2*cm, rightMargin=2*cm,
topMargin=2.2*cm, bottomMargin=1.8*cm,
title="Phosphorus Homeopathic Materia Medica",
author="MD Homoeopathy Study Guide"
)
S = create_styles()
story = []
sp = lambda n=0.3: Spacer(1, n*cm)
# ══════════════════════════════════════════════════════════════════════════
# PAGE 1 — COVER / INTRODUCTION
# ══════════════════════════════════════════════════════════════════════════
story.append(sp(0.5))
story.append(GlowTitle(
"PHOSPHORUS (Phos.)",
"Complete Materia Medica — MD Homoeopathy Study Guide"
))
story.append(sp(0.4))
# Drug classification table
drug_data = [
["CATEGORY", "DETAIL"],
["Source", "Yellow Phosphorus — Non-metallic element (P), Group VA"],
["Preparation", "Trituration → Succussion; available 6C to 1M+"],
["Constitution", "Phosphoric / Sanguine / Nervous temperament"],
["Miasm", "Primarily Psoric + Sycotic; Syphilitic in advanced stages"],
["Kingdom", "Mineral"],
["Hahnemann introduced", "19th Century — proven on healthy volunteers"],
]
drug_table = Table(drug_data, colWidths=[4.5*cm, 11.5*cm])
drug_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PHOS_BLUE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('BACKGROUND', (0,1), (0,-1), colors.HexColor('#E3F2FD')),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,1), (-1,-1), 9.5),
('ROWBACKGROUNDS', (1,1), (-1,-1), [PHOS_LIGHT, WHITE]),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#BBDEFB')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
story.append(drug_table)
story.append(sp(0.4))
# The Phosphorus Essence quote
story.append(Paragraph(
'<b><i>"Like Phosphorus itself — luminous in the dark, brilliant, burning, and easily exhausted — '
'so is the Phosphorus patient: radiant, giving, sensitive, yet quickly depleted."</i></b>',
ParagraphStyle('quote', fontName='Helvetica-Oblique', fontSize=10.5, textColor=PHOS_BLUE,
alignment=TA_CENTER, borderColor=PHOS_GOLD, borderWidth=1,
borderPadding=8, borderRadius=6, backColor=PHOS_YELLOW,
spaceBefore=4, spaceAfter=4)
))
story.append(sp(0.4))
# ── CONSTITUTION SECTION ──
story.append(SectionHeader("CONSTITUTION & PHYSICAL TYPE", PHOS_BLUE, "◈"))
story.append(sp(0.25))
const_data = [
[Paragraph("<b>Physical Build</b>", S['h3']),
Paragraph("<b>Temperament</b>", S['h3']),
Paragraph("<b>Skin & Hair</b>", S['h3'])],
[
Paragraph(
"• Tall, slender, narrow-chested<br/>"
"• Rapidly growing young people<br/>"
"• Inclined to stoop/slouch<br/>"
"• Delicate, fine-boned frame<br/>"
"• Emaciation tendency<br/>"
"• Chlorotic / anaemic", S['body']),
Paragraph(
"• Sanguine temperament<br/>"
"• Nervous, sensitive, excitable<br/>"
"• Quick perceptions<br/>"
"• Vivid imagination<br/>"
"• Easily impressed<br/>"
"• Extroverted, open, affectionate", S['body']),
Paragraph(
"• Fair, delicate skin<br/>"
"• Blonde, red, or soft hair<br/>"
"• Delicate long eyelashes<br/>"
"• Hair falls in handfuls<br/>"
"• Skin bleeds easily<br/>"
"• Hollow eyes, blue rings", S['body']),
]
]
const_table = Table(const_data, colWidths=[5.2*cm, 5.2*cm, 5.6*cm])
const_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), colors.HexColor('#E3F2FD')),
('BACKGROUND', (0,1), (0,1), PHOS_LIGHT),
('BACKGROUND', (1,1), (1,1), PHOS_YELLOW),
('BACKGROUND', (2,1), (2,1), PHOS_MINT),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#BBDEFB')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 6),
('ALIGN', (0,0), (-1,0), 'CENTER'),
]))
story.append(const_table)
story.append(sp(0.4))
# ── BODY DIAGRAM ──
story.append(SectionHeader("BODY SYSTEMS OVERVIEW", PHOS_ORANGE, "⚕"))
story.append(sp(0.2))
story.append(PhosphorusBodyDiagram())
story.append(sp(0.3))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# PAGE 2 — MIND & EMOTIONAL PICTURE + PATIENT LANGUAGE
# ══════════════════════════════════════════════════════════════════════════
story.append(SectionHeader("MIND & EMOTIONAL PICTURE", BOX_PURPLE, "🧠"))
story.append(sp(0.3))
mind_data = [
["POSITIVE STATE (When Healthy)", "NEGATIVE STATE (When Sick/Depleted)"],
[
Paragraph(
"• Warm, affectionate, loving, generous<br/>"
"• Brilliant, creative, imaginative<br/>"
"• Enthusiastic, vivacious, full of life<br/>"
"• Empathetic, psychic, clairvoyant<br/>"
"• Social butterfly, loves company<br/>"
"• Quick wit, charming personality<br/>"
"• Spiritual, deeply intuitive", S['body']),
Paragraph(
"• Restless, anxious, fidgety<br/>"
"• Fearful (alone, dark, thunderstorms)<br/>"
"• Apathetic, indifferent, sluggish<br/>"
"• Memory loss, confusion<br/>"
"• Gloomy forebodings, weary of life<br/>"
"• Hypersensitive to all impressions<br/>"
"• Desires magnetism / being rubbed", S['body'])
]
]
mind_table = Table(mind_data, colWidths=[8*cm, 8*cm])
mind_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (0,0), BOX_GREEN),
('BACKGROUND', (1,0), (1,0), BOX_RED),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('BACKGROUND', (0,1), (0,1), PHOS_MINT),
('BACKGROUND', (1,1), (1,1), PHOS_PINK),
('GRID', (0,0), (-1,-1), 0.5, colors.grey),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 6),
('BOTTOMPADDING', (0,0), (-1,-1), 6),
('LEFTPADDING', (0,0), (-1,-1), 6),
('ALIGN', (0,0), (-1,0), 'CENTER'),
]))
story.append(mind_table)
story.append(sp(0.4))
# FEARS
story.append(SectionHeader("CHARACTERISTIC FEARS OF PHOSPHORUS", BOX_PURPLE, "⚠"))
story.append(sp(0.2))
fears_data = [
["FEAR", "HOW PATIENT EXPRESSES IT"],
["Being alone", '"Doctor, I cannot be left alone — something bad will happen to me"'],
["Dark / twilight", '"I feel terrified as evening approaches, especially at dusk"'],
["Thunderstorms", '"Thunder makes me shake — I feel all my nerves vibrate"'],
["Death when alone", '"If nobody is with me, I fear I will die"'],
["Something creeping", '"It feels like something is creeping out from every corner"'],
["Future / ghosts", '"I have these gloomy thoughts... nothing good will happen"'],
]
fears_table = Table(fears_data, colWidths=[4.5*cm, 11.5*cm])
fears_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), BOX_PURPLE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [PHOS_LAVENDER, WHITE]),
('GRID', (0,0), (-1,-1), 0.5, colors.HexColor('#CE93D8')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
('FONTNAME', (1,1), (1,-1), 'Helvetica-Oblique'),
('TEXTCOLOR', (1,1), (1,-1), PHOS_BLUE),
]))
story.append(fears_table)
story.append(sp(0.4))
# PATIENT LANGUAGE — HOW THEY DESCRIBE SYMPTOMS
story.append(SectionHeader("HOW THE PATIENT DESCRIBES SYMPTOMS IN CLINIC", BOX_BLUE, "💬"))
story.append(sp(0.25))
story.append(Paragraph(
"When a Phosphorus patient walks into your clinic, they are typically expressive, warm, and talkative. "
"They describe their symptoms vividly with emotional language. Here is what you will typically hear:",
S['body']
))
story.append(sp(0.2))
patient_quotes = [
("RESPIRATORY / CHEST", [
"My chest burns like fire from inside",
"I have this tight feeling — worse when I lie on my left side",
"My cough is exhausting me — I cough till my head feels empty",
"My voice disappears in the evenings — I can barely speak by nightfall",
"Cold air hits me and immediately I start coughing",
]),
("DIGESTIVE SYSTEM", [
"I feel this horrible empty, hollow feeling in my stomach — like a pit",
"I crave cold things — ice cream, cold water, ice chips... they make me feel better",
"But the moment that cold water warms up in my stomach, I vomit it right back",
"My stools come out like water — just pours out like a tap being opened",
"I can eat and still feel famished — the hunger never seems to go away",
]),
("NERVOUS SYSTEM / GENERAL", [
"I feel this burning sensation running along my spine, especially between my shoulder blades",
"My hands burn — the palms feel hot, I have to keep them out of covers at night",
"I feel so weak... trembling all over for no reason",
"I'm very sensitive — light, noise, smells overwhelm me completely",
"Thunder makes me absolutely panic — I shake during storms",
]),
("HEAD / EYES / HAIR", [
"My head feels completely empty — like there is nothing inside",
"I get headaches that are better when I wash my face with cold water",
"My hair is falling out in handfuls — clumps on my pillow every morning",
"My eyes feel hollow — dark rings around them that never go away",
"I see green halos around lights sometimes",
]),
("BLEEDING / HAEMORRHAGE", [
"Even the smallest cut bleeds for a very long time — bright red blood",
"I get nosebleeds that are hard to stop — bright, fresh blood",
"My gums bleed when I just touch them",
"My periods are too long and the blood is bright red",
]),
]
for system, quotes in patient_quotes:
story.append(PatientQuoteBox(system, quotes))
story.append(sp(0.2))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# PAGE 3 — KEYNOTES, MODALITIES, PECULIAR SYMPTOMS
# ══════════════════════════════════════════════════════════════════════════
story.append(SectionHeader("KEYNOTE SYMPTOMS (Red Flag Signs for Prescribing)", BOX_RED, "🔑"))
story.append(sp(0.25))
keynotes = [
("1", "BURNING", "Burning in every organ — chest, spine, palms, stomach, skin. Most characteristic."),
("2", "HAEMORRHAGE", "Small wounds bleed profusely. Bright red, fresh blood from any orifice."),
("3", "EMPTY SENSATION", "All-gone hollow feeling in head, chest, stomach — 'nothing inside'"),
("4", "COLD WATER RELIEF", "Desires cold food/drinks — relieves gastric symptoms; vomited when warm"),
("5", "LEFT-SIDE AFFINITY", "Chest pain and breathing issues worse on left side; can't lie on left"),
("6", "TALL & SLENDER", "Constitutional type: tall, narrow-chested, rapidly growing adolescents"),
("7", "FEAR WHEN ALONE", "Dread of death/disease when alone; greatly comforted by company"),
("8", "EVENING AGGRAVATION", "Most symptoms worsen in the evening, before midnight"),
("9", "OVERSENSITIVITY", "All senses hyperacute — light, sound, odour, touch, electrical changes"),
("10", "HUNGER AT NIGHT", "Ravenous hunger especially at night; eating relieves mental symptoms"),
]
kn_data = [["#", "KEYNOTE", "CLINICAL NOTE"]] + keynotes
kn_table = Table(kn_data, colWidths=[0.8*cm, 3.8*cm, 11.4*cm])
kn_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), BOX_RED),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTNAME', (1,1), (1,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (1,1), (1,-1), BOX_RED),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [colors.HexColor('#FFF8F8'), WHITE]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#FFCDD2')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
('ALIGN', (0,0), (0,-1), 'CENTER'),
]))
story.append(kn_table)
story.append(sp(0.4))
# MODALITIES
story.append(SectionHeader("MODALITIES — BETTER & WORSE", BOX_GREEN, "⚖"))
story.append(sp(0.2))
better = [
"Cold food and cold drinks",
"Lying on the RIGHT side",
"Being rubbed / mesmerized",
"Sleep (short sleep refreshes)",
"Cold water (head & face)",
"In the dark",
"Eating (relieves faintness)",
"Open air (for head symptoms)",
]
worse = [
"Evening / before midnight",
"Lying on LEFT or painful side",
"Thunderstorms / weather change",
"Warm food or warm drinks",
"Warm room",
"Physical or mental exertion",
"Slight touch / pressure",
"Fasting / missing meals",
]
story.append(ModalityBox(better, worse))
story.append(sp(0.4))
# PECULIAR SYMPTOMS
story.append(SectionHeader("PECULIAR / STRANGE / RARE SYMPTOMS (Guiding Symptoms)", PHOS_ORANGE, "★"))
story.append(sp(0.2))
peculiar = [
["SYMPTOM", "SIGNIFICANCE"],
["Cold water vomited as soon as it warms in stomach", "Highly characteristic — rules out other remedies"],
["Nausea from putting hands in warm water", "Unique to Phosphorus; triggers nausea via reflex"],
["Sneezing from putting hands in water", "Strange reflex — unusual modality"],
["Burning between scapulae (shoulder blades)", "Like ice OR intense heat — both possible"],
["Desires to be magnetized / mesmerized", "Unusual mental symptom; better from therapeutic touch"],
["Haemorrhage: bright red, profuse from small wounds", "Haemorrhagic diathesis — very characteristic"],
["Craves ice cream — relieves stomach pain", "Ice cream specifically relieves gastric complaints"],
["Sensation: anus remains open after stool", "Weak, patulous anus sensation after profuse diarrhoea"],
["Clairvoyance / psychic states", "Heightened intuition in phosphorus temperament"],
["Stool: long, slender, dry like dog stool", "Hard constipation alternating with profuse diarrhoea"],
]
pec_table = Table(peculiar, colWidths=[6.5*cm, 9.5*cm])
pec_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PHOS_ORANGE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [PHOS_YELLOW, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#FFE0B2')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
story.append(pec_table)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# PAGE 4 — SYSTEM-WISE SYMPTOMS
# ══════════════════════════════════════════════════════════════════════════
story.append(SectionHeader("SYSTEM-WISE SYMPTOM PICTURE", PHOS_BLUE, "📋"))
story.append(sp(0.25))
systems = [
("RESPIRATORY SYSTEM", BOX_BLUE, PHOS_CYAN, [
"Violent, racking cough — exhausting, leaves patient prostrated",
"Expectoration: bloody, rust-coloured, brick-dust like; purulent",
"Bronchitis, pneumonia — hepatization of lungs (solid, liver-like)",
"Hoarseness: worse evenings; voice fails towards evening (laryngitis)",
"Chest pain: acute, burning, worse pressure, worse lying on left side",
"Cold air aggravates immediately — even slightest chill triggers cough",
"Pneumonia: right lower lobe commonly affected",
]),
("DIGESTIVE SYSTEM", BOX_GREEN, PHOS_MINT, [
"Hunger: intense, gnawing, ravenous — especially at night",
"Craves: cold food, ice cream, ice, juicy/refreshing things, salt",
"Aversion: warm food, warm drinks (immediately vomited when warmed)",
"Nausea: on putting hands in warm water (peculiar keynote)",
"Vomiting: as soon as water warms in stomach — projectile regurgitation",
"Diarrhoea: profuse, watery, pouring as from hydrant; involuntary; painless",
"Stools: sago-like particles; sensation of open anus after passing stool",
"Constipation: alternate — long, slender, hard stools voided with straining",
"Liver: fatty degeneration, hepatitis; jaundice with haemorrhagic tendency",
]),
("NERVOUS SYSTEM", BOX_PURPLE, PHOS_LAVENDER, [
"Burning along spine — in spots, between scapulae",
"Trembling of whole body — from weakness, nervous exhaustion",
"Oversensitivity: noise, light, odours, touch, electrical changes",
"Chorea, paralysis — ascending type (like Guillain-Barré picture)",
"Nervous debility after loss of fluids (haemorrhage, seminal emissions)",
"Neuropathy: burning, numbness in extremities",
"Tendency to faint — from odours, from warm rooms",
]),
("CARDIOVASCULAR / HAEMORRHAGIC", BOX_RED, PHOS_PINK, [
"Haemorrhagic diathesis — main characteristic feature",
"Small wounds bleed profusely — bright red, fresh blood",
"Bleeding from every mucous outlet: nose, gums, lungs, bowel, uterus",
"Epistaxis: profuse, bright red; recurrent nosebleeds",
"Petechiae, purpura — bleeding under the skin",
"Haemoptysis — blood-streaked or frank bleeding from lungs",
"Post-surgical haemorrhage, oozing from small capillaries",
]),
("MUSCULOSKELETAL", PHOS_ORANGE, PHOS_YELLOW, [
"Profound weakness and prostration — entire body",
"Burning in palms of hands — must put them outside covers",
"Bones: exostoses, caries of jaw (phosphorus necrosis historically)",
"Growing pains in rapidly growing adolescents",
"Weakness of ankles — children learning to walk stumble repeatedly",
"Trembling weakness in limbs after exertion or emotional excitement",
]),
("SKIN / HAIR / NAILS", colors.HexColor('#795548'), colors.HexColor('#EFEBE9'), [
"Hair falls in handfuls — patchy baldness (alopecia)",
"Dandruff falls in clouds (like Lycopodium)",
"Skin bleeds easily from minor trauma",
"Jaundice: yellow discolouration with bleeding tendency (liver involvement)",
"Delicate, thin, fair skin — susceptible to chapping, bruising",
"Nails: brittle, break easily",
]),
]
for sys_name, hdr_color, bg_color, items in systems:
story.append(InfoBox(sys_name, items, bg_color, hdr_color, hdr_color))
story.append(sp(0.25))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# PAGE 5 — MNEMONICS & QUICK REVISION
# ══════════════════════════════════════════════════════════════════════════
story.append(SectionHeader("MNEMONICS FOR QUICK REVISION", BOX_PURPLE, "🧩"))
story.append(sp(0.3))
# Mnemonic 1 — PHOSPHORUS
story.append(MnemonicBox(
"MNEMONIC 1 — P·H·O·S·P·H·O·R·U·S (Main Keynotes)",
[
("P", "Prostration", "Great weakness and trembling; weariness from loss of vital fluids"),
("H", "Haemorrhage", "Profuse bleeding from small wounds; bright red blood"),
("O", "Open Senses", "Oversensitive to light, noise, odour, touch, electricity"),
("S", "Slender & Tall", "Constitutional type: tall, narrow-chested, rapidly growing"),
("P", "Palms Burning", "Burning in palms; must put hands outside blankets"),
("H", "Hunger (nocturnal)","Ravenous hunger especially at night; eating relieves symptoms"),
("O", "Open Anus", "Sensation of patulous anus after profuse diarrhoea"),
("R", "Right Side Chest", "Pneumonia: right lower lobe; lies on right side for relief"),
("U", "Unquenchable", "Craves cold water/ice — vomited as soon as it warms"),
("S", "Spine Burning", "Burning in spots along spine, between scapulae"),
]
))
story.append(sp(0.35))
# Mnemonic 2 — FEARS
story.append(MnemonicBox(
"MNEMONIC 2 — DARTS (Characteristic Fears)",
[
("D", "Dark", "Fears the dark — especially twilight and dusk"),
("A", "Alone", "Terrified of being alone — fears death when alone"),
("R", "Rumination", "Gloomy forebodings, weary of life, dark thoughts"),
("T", "Thunder", "Thunderstorms cause violent anxiety and trembling"),
("S", "Sinister", "Feels something creeping from every corner"),
]
))
story.append(sp(0.35))
# Mnemonic 3 — BURNS
story.append(MnemonicBox(
"MNEMONIC 3 — BURNS (Burning Locations)",
[
("B", "Between Scapulae", "Burning spot between shoulder blades — or icy cold"),
("U", "Upper Stomach", "Burning in epigastrium; all-gone sensation in abdomen"),
("R", "Running up Back", "Intense heat or cold running up the entire spine"),
("N", "Nervous System", "Burning in nerves, extremities; neuropathy picture"),
("S", "Skin & Soles", "Burning in palms and soles; skin hot to touch"),
]
))
story.append(sp(0.35))
# Mnemonic 4 — COLD
story.append(MnemonicBox(
"MNEMONIC 4 — COLD (What RELIEVES Phosphorus)",
[
("C", "Cold drinks/food", "Craves and is relieved by cold food, ice cream, cold water"),
("O", "On right side", "Lying on RIGHT side relieves chest symptoms"),
("L", "Lying in dark", "Rest in a dark, quiet room relieves head symptoms"),
("D", "Dark + rubbing", "Being rubbed/mesmerized; dark room; short sleep"),
]
))
story.append(sp(0.4))
# QUICK COMPARISON TABLE
story.append(SectionHeader("DIFFERENTIAL DIAGNOSIS — KEY DIFFERENTIALS", BOX_BLUE, "⚖"))
story.append(sp(0.2))
diff_data = [
["SYMPTOM", "PHOSPHORUS", "ARSENICUM", "SULPHUR", "LYCOPODIUM"],
["Burning", "All organs, spine, palms", "Burning but < cold (wants warmth)", "Burning soles & vertex", "Burning in stomach/throat"],
["Haemorrhage", "Bright red, profuse", "Dark, offensive", "Less prominent", "Rare, moderate"],
["Cold desires", "Strong — ice, cold drinks", "Warm drinks only", "Cold but variable", "Warm food preferred"],
["Aggravation time", "Evening / midnight", "1-3 AM", "Morning / bathing", "4-8 PM"],
["Fear", "Alone, dark, thunderstorm", "Alone + death + disease", "Of poverty, criticism", "Of public, strangers"],
["Constitution", "Tall, slender, sanguine", "Thin, anxious, restless", "Hot, lean or fat", "Dried-up, wrinkled, intellectual"],
["Left side", "Affected (chest/heart)", "No predominance", "No predominance", "Right-sided primarily"],
]
diff_table = Table(diff_data, colWidths=[3.5*cm, 3.5*cm, 3.5*cm, 3.5*cm, 2*cm])
diff_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PHOS_BLUE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 9),
('BACKGROUND', (1,1), (1,-1), colors.HexColor('#FFF8EE')),
('FONTNAME', (1,1), (1,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (1,1), (1,-1), PHOS_ORANGE),
('FONTSIZE', (0,1), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [WHITE, colors.HexColor('#F5F5F5')]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#BBDEFB')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 4),
('BOTTOMPADDING', (0,0), (-1,-1), 4),
('LEFTPADDING', (0,0), (-1,-1), 4),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (0,1), (0,-1), PHOS_BLUE),
]))
story.append(diff_table)
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# PAGE 6 — CLINICAL APPLICATION + DOSAGE + RELATIONSHIP
# ══════════════════════════════════════════════════════════════════════════
story.append(SectionHeader("CLINICAL CONDITIONS WHERE PHOSPHORUS IS INDICATED", BOX_GREEN, "🏥"))
story.append(sp(0.25))
clinical_data = [
["CONDITION", "KEY INDICATIONS IN THAT DISEASE"],
["Pneumonia", "Right lower lobe; rust-coloured sputum; burning chest; hepatization stage"],
["Bronchitis/Laryngitis", "Violent cough; hoarse evenings; cough on entering cold air; haemoptysis"],
["Gastritis / GERD", "Burning, empty sensation; vomiting when water warms; craving cold"],
["Cholera / Diarrhoea", "Profuse, painless, watery stool; open anus sensation; great prostration"],
["Hepatitis / Liver disease", "Fatty degeneration; jaundice; hepatomegaly; haemorrhagic tendency"],
["Epistaxis / Bleeding disorders", "Recurrent bright red nosebleeds; haemophilia-like; post-surgical ooze"],
["Anaemia / Chlorosis", "In young girls, rapidly growing, slender, pale, fatigued"],
["Nervous exhaustion / Neurasthenia", "After overwork, excessive study, loss of fluids; trembling, weakness"],
["Alopecia", "Hair falls in handfuls; dandruff in clouds; patchy baldness"],
["Retinal diseases", "Retinitis from suppressed menses; visual disturbances (halos)"],
["Anxiety disorders", "Fear of being alone, dark, thunderstorms; needs company and reassurance"],
["Tuberculosis (constitutional)", "Tall, narrow-chested, chlorotic; evening cough; haemoptysis"],
["Glaucoma / Eye diseases", "Glaucoma; retinal haemorrhage; optic nerve atrophy"],
]
clin_table = Table(clinical_data, colWidths=[4.5*cm, 11.5*cm])
clin_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), BOX_GREEN),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [PHOS_MINT, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#C8E6C9')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
story.append(clin_table)
story.append(sp(0.4))
# RELATIONSHIP OF REMEDIES
story.append(SectionHeader("RELATIONSHIP OF REMEDIES", PHOS_ORANGE, "🔗"))
story.append(sp(0.2))
rel_data = [
["RELATIONSHIP", "REMEDIES", "NOTES"],
["Complementary", "Arsenicum, Lycopodium, Allium Cepa", "Complete each other's action; follow well"],
["Follows well after", "Calcarea, Belladonna, China", "Use in sequence for deeper action"],
["Followed well by", "Arsenicum, Nux Vomica, Sulphur", "Phosphorus prepares for these"],
["Antidotes", "Nux Vomica, Coffee, Camphor, Turpentine", "To neutralise Phosphorus action"],
["Inimical (never use together)", "Causticum", "Antagonistic — avoid combining"],
["Similar to", "Ferrum, Phosphoric Acid, Tuberculinum", "Similar action, differentiate carefully"],
]
rel_table = Table(rel_data, colWidths=[4*cm, 5.5*cm, 6.5*cm])
rel_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PHOS_ORANGE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [PHOS_YELLOW, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#FFE0B2')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
# Highlight the inimical row in pink
('BACKGROUND', (0,5), (-1,5), PHOS_PINK),
('TEXTCOLOR', (0,5), (-1,5), BOX_RED),
]))
story.append(rel_table)
story.append(sp(0.35))
# DOSAGE GUIDANCE
story.append(SectionHeader("DOSAGE & POTENCY SELECTION GUIDE", PHOS_BLUE, "💊"))
story.append(sp(0.2))
dose_data = [
["POTENCY", "WHEN TO USE", "FREQUENCY"],
["6C / 12C", "Acute conditions; local symptoms predominant; tissue affinity prescribing", "3-4 times daily"],
["30C", "Sub-acute; mental + physical combination; most commonly used", "Once or twice daily"],
["200C", "Constitutional; well-defined mental picture; sensitive patients", "Once weekly"],
["1M", "Chronic, deep constitutional cases; marked personality match", "Once monthly"],
["LM Potencies", "Sensitive patients; gradual, gentle action preferred; elderly / children", "Daily in water"],
]
dose_table = Table(dose_data, colWidths=[2.5*cm, 10*cm, 3.5*cm])
dose_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PHOS_BLUE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (0,1), (0,-1), PHOS_BLUE),
('FONTSIZE', (0,1), (-1,-1), 9),
('ROWBACKGROUNDS', (0,1), (-1,-1), [PHOS_CYAN, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#BBDEFB')),
('VALIGN', (0,0), (-1,-1), 'MIDDLE'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 7),
]))
story.append(dose_table)
story.append(sp(0.35))
# IMPORTANT CAUTION BOX
caution_data = [
[Paragraph("<b>⚠ IMPORTANT CLINICAL CAUTIONS</b>", ParagraphStyle('w', fontName='Helvetica-Bold',
fontSize=10, textColor=BOX_RED, alignment=TA_CENTER))],
[Paragraph(
"1. <b>Causticum is inimical</b> — never prescribe Phosphorus immediately before or after Causticum.<br/>"
"2. <b>Sensitive patients</b>: avoid high potencies (1M+) in nervous, highly strung constitutions — aggravation can be violent.<br/>"
"3. <b>Haemorrhagic tendency</b> — ensure no active life-threatening bleeding before constitutional treatment; manage emergencies allopathically.<br/>"
"4. <b>Hepatic disease</b>: monitor liver enzymes; Phosphorus has affinity for liver — fatty degeneration, not always curative alone in cirrhosis.<br/>"
"5. <b>Do not confuse</b> Phosphorus with Phosphoric Acid — Phos Acid has profound indifference, grief, debility; Phosphorus has vivacity and excitability.",
ParagraphStyle('cb', fontName='Helvetica', fontSize=9.5, textColor=PHOS_DARK, leading=14)
)],
]
caution_table = Table(caution_data, colWidths=[16*cm])
caution_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), PHOS_PINK),
('BACKGROUND', (0,1), (-1,-1), colors.HexColor('#FFF8F8')),
('BOX', (0,0), (-1,-1), 1.5, BOX_RED),
('GRID', (0,0), (-1,-1), 0.3, colors.HexColor('#FFCDD2')),
('TOPPADDING', (0,0), (-1,-1), 7),
('BOTTOMPADDING', (0,0), (-1,-1), 7),
('LEFTPADDING', (0,0), (-1,-1), 10),
]))
story.append(caution_table)
story.append(sp(0.4))
story.append(PageBreak())
# ══════════════════════════════════════════════════════════════════════════
# PAGE 7 — QUICK REVISION CARD + CASE TAKING CHECKLIST
# ══════════════════════════════════════════════════════════════════════════
story.append(SectionHeader("CASE-TAKING CHECKLIST FOR PHOSPHORUS", BOX_BLUE, "✅"))
story.append(sp(0.25))
story.append(Paragraph(
"Use these questions in clinic to confirm Phosphorus prescription:",
S['body']
))
story.append(sp(0.15))
checklist_data = [
["DOMAIN", "QUESTIONS TO ASK IN CLINIC", "PHOS ANSWER"],
["Build/Type", "What is patient's build, hair colour, complexion?",
"Tall, slender, fair, long lashes, soft hair"],
["Thermals", "Are you a hot or cold patient? Do you like open windows?",
"Hot patient; craves cold; open air for head"],
["Appetite", "Do you have unusual hunger? When? What do you crave/avoid?",
"Ravenous at night; craves cold, ice cream; avoids warm food"],
["Sleep", "Do you fear going to sleep alone? Any unusual fears?",
"Fears dark, alone, thunder; short sleep refreshes"],
["Bleeding", "Do small cuts take long to stop? Any frequent nosebleeds?",
"Yes — profuse bright red bleeding, slow to clot"],
["GI symptoms", "Describe your stool. Any vomiting pattern?",
"Profuse diarrhoea; vomiting when water warms"],
["Chest", "Do you cough? Which side? Any burning in chest?",
"Burning chest; worse left side; worse cold air"],
["Spine/Hands", "Any burning sensation in back or palms?",
"Yes — burning spine, burning palms at night"],
["Mind/Fears", "Do you need company? Fear being alone?",
"Strongly — dread death when alone; fears dark"],
["Sensitivity", "Are you sensitive to noise, light, or smells?",
"Extremely — all senses hyperacute"],
["Social", "How do you relate to people? Affectionate?",
"Warm, loving, open — kisses everyone; gives freely"],
]
cl_table = Table(checklist_data, colWidths=[3.5*cm, 7.5*cm, 5*cm])
cl_table.setStyle(TableStyle([
('BACKGROUND', (0,0), (-1,0), BOX_BLUE),
('TEXTCOLOR', (0,0), (-1,0), WHITE),
('FONTNAME', (0,0), (-1,0), 'Helvetica-Bold'),
('FONTSIZE', (0,0), (-1,0), 10),
('FONTNAME', (0,1), (0,-1), 'Helvetica-Bold'),
('TEXTCOLOR', (0,1), (0,-1), BOX_BLUE),
('FONTSIZE', (0,1), (-1,-1), 8.5),
('ROWBACKGROUNDS', (0,1), (-1,-1), [PHOS_CYAN, WHITE]),
('GRID', (0,0), (-1,-1), 0.4, colors.HexColor('#BBDEFB')),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 5),
('BOTTOMPADDING', (0,0), (-1,-1), 5),
('LEFTPADDING', (0,0), (-1,-1), 5),
('TEXTCOLOR', (2,1), (2,-1), BOX_GREEN),
('FONTNAME', (2,1), (2,-1), 'Helvetica-Oblique'),
]))
story.append(cl_table)
story.append(sp(0.4))
# MEMORY CARD / VISUAL SUMMARY
story.append(SectionHeader("ONE-PAGE VISUAL SUMMARY — PHOSPHORUS AT A GLANCE", PHOS_ORANGE, "📊"))
story.append(sp(0.2))
summary_data = [
[
Paragraph("<b>THE ESSENCE</b><br/>\"The Bright Flame — luminous,<br/>giving, burning, and easily spent\"",
ParagraphStyle('ess', fontName='Helvetica-Bold', fontSize=10, textColor=PHOS_DARK,
alignment=TA_CENTER, backColor=PHOS_YELLOW, borderPadding=6)),
Paragraph("<b>TOP 5 KEYNOTES</b><br/>1. Burning everywhere<br/>2. Haemorrhage<br/>3. Empty sensation<br/>4. Fear alone/dark<br/>5. Cold water cravings",
ParagraphStyle('t5', fontName='Helvetica', fontSize=9, textColor=PHOS_DARK,
backColor=PHOS_PINK, borderPadding=6)),
Paragraph("<b>PECULIARS</b><br/>• Vomits water when warm<br/>• Nausea from warm water<br/>• Clairvoyance<br/>• Craves ice cream<br/>• Desires magnetism",
ParagraphStyle('pe', fontName='Helvetica', fontSize=9, textColor=PHOS_DARK,
backColor=PHOS_LAVENDER, borderPadding=6)),
],
[
Paragraph("<b>BETTER</b><br/>Cold food/drinks<br/>Right side<br/>Dark room<br/>Sleep<br/>Being rubbed",
ParagraphStyle('bet', fontName='Helvetica', fontSize=9, textColor=BOX_GREEN,
backColor=PHOS_MINT, borderPadding=6)),
Paragraph("<b>WORSE</b><br/>Evening & night<br/>Left side<br/>Thunderstorms<br/>Warm food/room<br/>Fasting",
ParagraphStyle('wor', fontName='Helvetica', fontSize=9, textColor=BOX_RED,
backColor=PHOS_PINK, borderPadding=6)),
Paragraph("<b>NEVER FORGET</b><br/>• Inimical: Causticum<br/>• Antidotes: Nux/Coffee<br/>• Follows: Calc, Bell<br/>• Miasm: Psora+Sycosis<br/>• Potency: 30C to 1M",
ParagraphStyle('nf', fontName='Helvetica', fontSize=9, textColor=PHOS_DARK,
backColor=PHOS_CYAN, borderPadding=6)),
],
]
sum_table = Table(summary_data, colWidths=[5.3*cm, 5.3*cm, 5.4*cm])
sum_table.setStyle(TableStyle([
('BOX', (0,0), (-1,-1), 2, PHOS_ORANGE),
('GRID', (0,0), (-1,-1), 1, PHOS_ORANGE),
('VALIGN', (0,0), (-1,-1), 'TOP'),
('TOPPADDING', (0,0), (-1,-1), 8),
('BOTTOMPADDING', (0,0), (-1,-1), 8),
('LEFTPADDING', (0,0), (-1,-1), 8),
]))
story.append(sum_table)
story.append(sp(0.5))
# FOOTER REFERENCES
story.append(HRFlowable(width="100%", thickness=1, color=PHOS_GOLD))
story.append(sp(0.2))
story.append(Paragraph(
"<b>References:</b> Henry C. Allen — Materia Medica Keynotes | William Boericke — Pocket Manual of Homoeopathic Materia Medica | "
"J.T. Kent — Lectures on Homoeopathic Materia Medica | E.B. Nash — Leaders in Homoeopathic Therapeutics | "
"E.A. Farrington — Comparative Materia Medica | J.H. Clarke — Dictionary of Practical Materia Medica",
S['small']
))
story.append(sp(0.1))
story.append(Paragraph(
"Compiled for MD Homoeopathy Students | For Educational Purposes Only | Always practice under supervision",
S['small']
))
# BUILD
doc.build(story, onFirstPage=page_bg, onLaterPages=page_bg)
print(f"PDF created: {path}")
return path
if __name__ == "__main__":
build_pdf()
cd /home/daytona/workspace/phosphorus-pdf && python generate_pdf.py 2>&1
~/phosphorus-pdf/generate_pdf.py
Successfully replaced 1 instance(s) of the string in '/home/daytona/workspace/phosphorus-pdf/generate_pdf.py'