# Create a concise 1-page PDF handout for the Soybean Production Guide
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.lib.units import cm
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.lib import colors
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer, Table, TableStyle
from reportlab.lib.enums import TA_LEFT
from reportlab.lib.styles import ParagraphStyle
pdf_path = "/mnt/data/soybean_guide_one_pager.pdf"
# Document setup
doc = SimpleDocTemplate(pdf_path, pagesize=A4, leftMargin=1.5*cm, rightMargin=1.5*cm, topMargin=1.5*cm, bottomMargin=1.5*cm)
styles = getSampleStyleSheet()
# Custom styles
title_style = ParagraphStyle(
'Title',
parent=styles['Heading1'],
fontSize=18,
spaceAfter=8,
)
h_style = ParagraphStyle(
'Heading',
parent=styles['Heading3'],
fontSize=12.5,
textColor=colors.black,
spaceBefore=6,
spaceAfter=4
)
body = ParagraphStyle(
'Body',
parent=styles['BodyText'],
fontSize=10.5,
leading=13.5
)
small = ParagraphStyle(
'Small',
parent=styles['BodyText'],
fontSize=9,
textColor=colors.black,
leading=11.5
)
story = []
# Title
story.append(Paragraph("Soybean Production Guide — One‑Pager (Eswatini & SADC)", title_style))
# Overview bullets
overview = """
Agro‑ecology fit: Warm season, frost‑free; rainfall 450–700 mm; well‑drained loams, pH 5.8–7.0.
Why soy: Strong feed/food demand; fixes N; ideal in maize–soy rotation. """ story.append(Paragraph(overview, body)) # Planting window table story.append(Paragraph("Planting Calendar (typical rain‑fed)", h_style)) cal_table = Table([ ["Zone", "Window"], ["Highveld/Middleveld", "Oct–Dec (after first effective rains)"], ["Lowveld", "Nov–Jan (avoid peak heat at flowering)"], ["Irrigated", "Schedule to water availability; avoid cold snaps"] ], colWidths=[5*cm, 10*cm]) cal_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), colors.lightgrey), ("TEXTCOLOR", (0,0), (-1,0), colors.black), ("GRID", (0,0), (-1,-1), 0.25, colors.grey), ("ALIGN", (0,0), (-1,-1), "LEFT"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("FONTSIZE", (0,0), (-1,-1), 9.5), ])) story.append(cal_table) # Key practices sections sections = [ ("Varieties & Seed", "Use certified, region‑adapted seed; germination ≥85%. Target 300–450k plants/ha; 60–80 kg/ha typical (adjust to seed size)."), ("Soil & Fertility", "Soil test; lime to pH ≥5.8. Starter P (10–20 kg P/ha) and K as per test. Avoid high N which suppresses nodulation."), ("Inoculation", "Treat seed each season with soy‑specific Rhizobium; keep inoculant cool, mix in shade, plant promptly."), ("Planting", "Row 45–75 cm; 4–6 cm in‑row. Depth 3–5 cm. Calibrate planter to avoid seed damage and skips."), ("Water", "Critical: flowering, pod set, grain fill. Maintain 60–80% FC; avoid waterlogging; conserve moisture with residues."), ("Weeds", "Control first 6 weeks: pre‑em/early post + hand/hoeing. Narrow rows aid canopy closure."), ("Pests & Diseases", "Scout weekly. Watch cutworms/armyworms, aphids, stink bugs; rust & foliar diseases. Use IPM and timely, selective sprays."), ("Harvest & Handling", "Harvest at 12–14% moisture; dry to ≤12% for storage. Clean grain; store cool, dry, insect‑free.") ] for head, text in sections: story.append(Paragraph(head, h_style)) story.append(Paragraph(text, body)) # Mini budget table (placeholders) story.append(Paragraph("Costing Snapshot (placeholders, per ha)", h_style)) budget = Table([ ["Item", "Rate/Unit", "Qty", "Cost (SZL)"], ["Certified seed", "—/kg", "—", "—"], ["Inoculant", "—/pack", "—", "—"], ["Fertiliser (P&K)", "—/kg", "—", "—"], ["Weed/Pest control", "—/ha", "1", "—"], ["Field prep & planting", "—/ha", "1", "—"], ["Harvest/Transport", "—", "—", "—"], ], colWidths=[5*cm, 3.5*cm, 2*cm, 3.5*cm]) budget.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), colors.lightgrey), ("GRID", (0,0), (-1,-1), 0.25, colors.grey), ("ALIGN", (0,0), (-1,-1), "LEFT"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("FONTSIZE", (0,0), (-1,-1), 9.5), ])) story.append(budget) # FAQs story.append(Paragraph("FAQs", h_style)) faqs = [ ("Do I inoculate every season?", "Yes—use soy‑specific Rhizobium each planting."), ("Should I apply a lot of N?", "No—excess N suppresses nodulation."), ("Best rotation partner?", "Maize/sorghum; avoid continuous soy."), ] for q, a in faqs: story.append(Paragraph(f"• {q} {a}", small)) # Resources story.append(Spacer(1, 6)) resources = "Resources: NAMBoard (add link) | Johannesburg Fresh Produce Market (add link). External sites may change without notice." story.append(Paragraph(resources, small)) doc.build(story) pdf_path
Why soy: Strong feed/food demand; fixes N; ideal in maize–soy rotation. """ story.append(Paragraph(overview, body)) # Planting window table story.append(Paragraph("Planting Calendar (typical rain‑fed)", h_style)) cal_table = Table([ ["Zone", "Window"], ["Highveld/Middleveld", "Oct–Dec (after first effective rains)"], ["Lowveld", "Nov–Jan (avoid peak heat at flowering)"], ["Irrigated", "Schedule to water availability; avoid cold snaps"] ], colWidths=[5*cm, 10*cm]) cal_table.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), colors.lightgrey), ("TEXTCOLOR", (0,0), (-1,0), colors.black), ("GRID", (0,0), (-1,-1), 0.25, colors.grey), ("ALIGN", (0,0), (-1,-1), "LEFT"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("FONTSIZE", (0,0), (-1,-1), 9.5), ])) story.append(cal_table) # Key practices sections sections = [ ("Varieties & Seed", "Use certified, region‑adapted seed; germination ≥85%. Target 300–450k plants/ha; 60–80 kg/ha typical (adjust to seed size)."), ("Soil & Fertility", "Soil test; lime to pH ≥5.8. Starter P (10–20 kg P/ha) and K as per test. Avoid high N which suppresses nodulation."), ("Inoculation", "Treat seed each season with soy‑specific Rhizobium; keep inoculant cool, mix in shade, plant promptly."), ("Planting", "Row 45–75 cm; 4–6 cm in‑row. Depth 3–5 cm. Calibrate planter to avoid seed damage and skips."), ("Water", "Critical: flowering, pod set, grain fill. Maintain 60–80% FC; avoid waterlogging; conserve moisture with residues."), ("Weeds", "Control first 6 weeks: pre‑em/early post + hand/hoeing. Narrow rows aid canopy closure."), ("Pests & Diseases", "Scout weekly. Watch cutworms/armyworms, aphids, stink bugs; rust & foliar diseases. Use IPM and timely, selective sprays."), ("Harvest & Handling", "Harvest at 12–14% moisture; dry to ≤12% for storage. Clean grain; store cool, dry, insect‑free.") ] for head, text in sections: story.append(Paragraph(head, h_style)) story.append(Paragraph(text, body)) # Mini budget table (placeholders) story.append(Paragraph("Costing Snapshot (placeholders, per ha)", h_style)) budget = Table([ ["Item", "Rate/Unit", "Qty", "Cost (SZL)"], ["Certified seed", "—/kg", "—", "—"], ["Inoculant", "—/pack", "—", "—"], ["Fertiliser (P&K)", "—/kg", "—", "—"], ["Weed/Pest control", "—/ha", "1", "—"], ["Field prep & planting", "—/ha", "1", "—"], ["Harvest/Transport", "—", "—", "—"], ], colWidths=[5*cm, 3.5*cm, 2*cm, 3.5*cm]) budget.setStyle(TableStyle([ ("BACKGROUND", (0,0), (-1,0), colors.lightgrey), ("GRID", (0,0), (-1,-1), 0.25, colors.grey), ("ALIGN", (0,0), (-1,-1), "LEFT"), ("VALIGN", (0,0), (-1,-1), "MIDDLE"), ("FONTSIZE", (0,0), (-1,-1), 9.5), ])) story.append(budget) # FAQs story.append(Paragraph("FAQs", h_style)) faqs = [ ("Do I inoculate every season?", "Yes—use soy‑specific Rhizobium each planting."), ("Should I apply a lot of N?", "No—excess N suppresses nodulation."), ("Best rotation partner?", "Maize/sorghum; avoid continuous soy."), ] for q, a in faqs: story.append(Paragraph(f"• {q} {a}", small)) # Resources story.append(Spacer(1, 6)) resources = "Resources: NAMBoard (add link) | Johannesburg Fresh Produce Market (add link). External sites may change without notice." story.append(Paragraph(resources, small)) doc.build(story) pdf_path