#!/usr/bin/env python3
"""
Monday Generator - Learn It (4 pages)
Usage:
from monday import generate_monday
generate_monday(week_dir=..., week_num=..., phonics_label=..., words=..., ...)
"""
import os, sys, random
sys.path.insert(0, os.path.dirname(__file__))
from helpers import (CSS, header, sectitle, secnote, write_line, word_bank,
fill_blank_with_line, page_break, word_names, word_definitions,
context_clue_cards)
from weasyprint import HTML
def generate_monday(**kw):
week_dir = kw["week_dir"]
week_num = kw["week_num"]
day_name = kw.get("day_name", "Monday")
phonics_label = kw["phonics_label"]
words = kw["words"]
learning_text = kw["learning_text"]
vowel_examples = kw.get("vowel_examples", [])
grammar_note = kw["grammar_note"]
grammar_deep = kw["grammar_deep"]
grammar_practice = kw["grammar_practice"]
story_text = kw["story_text"]
sort_labels = kw.get("sort_labels", [])
sort_instruction = kw.get("sort_instruction", "Sort each word into the correct pattern column.")
sort_title = kw.get("sort_title", "Pattern Sort")
fill_data = kw.get("fill_data", [])
opposite_words = kw.get("opposite_words", [])
sentence_words = kw.get("sentence_words", [])
sentence_instruction = kw.get("sentence_instruction",
"Write a complete sentence using each word. Remember: capital letter and period!")
# NEW: Vocabulary / context clue support
context_clue_sentences = kw.get("context_clue_sentences", []) # [(sentence, word), ...]
context_clue_sort = kw.get("context_clue_sort", {}) # {clue_type: [words], ...}
day_dir = os.path.join(week_dir, "Monday")
os.makedirs(day_dir, exist_ok=True)
WORD_NAMES = word_names(words)
# Word cards — compact 3-column grid (supports 3-tuple and 4-tuple)
defn_idx = 3 if len(words[0]) >= 4 else 2
cards = '<table class="word-grid" style="border-spacing:3px;">'
for i in range(0, len(words), 3):
cards += '<tr>'
for j in range(i, min(i+3, len(words))):
word = words[j][0]
defn = words[j][defn_idx]
cards += f'<td><div class="word-card" style="padding:3px 5px;"><div class="word" style="font-size:11px;">{word}</div><div class="def" style="font-size:8.5px;line-height:1.1;">{defn}</div>{write_line()}</div></td>'
cards += '</tr>'
cards += '</table>'
# Pattern sort
sort_words = list(WORD_NAMES)
random.Random(42).shuffle(sort_words)
wbank = word_bank(sort_words, seed=42)
n_cols = len(sort_labels)
cols = ""
for lab in sort_labels:
lines = "".join(write_line() for _ in range(3))
cols += f'<td style="width:{100//n_cols}%;text-align:center;vertical-align:top;border:1.5px solid #B2DFDB;border-radius:6px;padding:6px;background:#FAFAFA;"><div style="font-weight:bold;font-size:11px;color:#26A69A;margin-bottom:6px;">{lab}</div>{lines}</td>'
sort_html = f'<div class="activity">{wbank}<table style="width:100%;border-collapse:separate;border-spacing:3px;"><tr>{cols}</tr></table></div>'
# Copy practice (supports 3-tuple and 4-tuple)
copy_items = ""
for w in words:
word = w[0]
copy_items += f'<div style="display:flex;align-items:center;gap:12px;margin:10px 0;"><span style="font-weight:bold;font-size:24px;min-width:100px;color:#26A69A;line-height:34px;">{word}</span><div style="flex:1;position:relative;height:34px;margin:2px 0;width:100%"><div style="position:absolute;left:0;right:0;top:0;border-top:0.6pt solid rgb(0,0,255)"></div><div style="position:absolute;left:0;right:0;bottom:18px;border-bottom:0.4pt dashed rgb(255,0,0)"></div><div style="position:absolute;left:0;right:0;bottom:0;border-bottom:0.6pt solid rgb(0,0,255)"></div></div></div>'
# Grammar practice — 2-column table
gp_mid = (len(grammar_practice) + 1) // 2
gp_left = ""
for item in grammar_practice[:gp_mid]:
text = item[0] if isinstance(item, tuple) else item
gp_left += f'<div style="margin:4px 0;font-size:12px;">{text}{write_line()}</div>'
gp_right = ""
for item in grammar_practice[gp_mid:]:
text = item[0] if isinstance(item, tuple) else item
gp_right += f'<div style="margin:4px 0;font-size:12px;">{text}{write_line()}</div>'
gp_html = f'<table style="width:100%;border-collapse:separate;border-spacing:4px;"><tr>' \
f'<td style="vertical-align;top;width:50%">{gp_left}</td>' \
f'<td style="vertical-align;top;width:50%">{gp_right}</td>' \
f'</tr></table>'
# Fill blank — skip if no fill data
fill_section = ""
if fill_data:
fill_answers = [a for _, a in fill_data]
fb_bank = word_bank(fill_answers, seed=210)
fb_items = "".join(fill_blank_with_line(s) for s, _ in fill_data)
fill_section = f"""{sectitle("Fill in the Blank")}
{secnote("Choose a word from the word bank to complete each sentence.")}
{fb_bank}
{fb_items}"""
# Opposites — 2-column table — skip if no opposites
opp_section = ""
if opposite_words:
opp_mid = (len(opposite_words) + 1) // 2
opp_left = "".join(f'<div style="margin:4px 0;font-size:12px;"><strong style="color:#673ab7;font-size:12px;">{w}</strong><br>{write_line()}</div>' for w in opposite_words[:opp_mid])
opp_right = "".join(f'<div style="margin:4px 0;font-size:12px;"><strong style="color:#673ab7;font-size:12px;">{w}</strong><br>{write_line()}</div>' for w in opposite_words[opp_mid:])
opp_section = f"""{sectitle("Opposite Match-Up")}
{secnote("Write the opposite of each word.")}
<table style="width:100%;border-collapse:separate;border-spacing:4px;"><tr>
<td style="vertical-align;top;width:50%">{opp_left}</td>
<td style="vertical-align;top;width:50%">{opp_right}</td>
</tr></table>"""
# Sentence writing — 2-column table — skip if no sentence words
sent_section = ""
if sentence_words:
sent_mid = (len(sentence_words) + 1) // 2
sent_left = "".join(f'<div style="margin:6px 0;"><span style="font-size:11px;font-weight:bold;color:#26A69A;">{w}:</span>{write_line()}</div>' for w in sentence_words[:sent_mid])
sent_right = "".join(f'<div style="margin:6px 0;"><span style="font-size:11px;font-weight:bold;color:#26A69A;">{w}:</span>{write_line()}</div>' for w in sentence_words[sent_mid:])
sent_section = f"""{sectitle("Sentence Writing")}
{secnote(sentence_instruction)}
<table style="width:100%;border-collapse:separate;border-spacing:4px;"><tr>
<td style="vertical-align;top;width:50%">{sent_left}</td>
<td style="vertical-align;top;width:50%">{sent_right}</td>
</tr></table>"""
# Context clue sentences — NEW for vocab weeks
ctx_clue_section = ""
if context_clue_sentences:
ctx_clue_html = context_clue_cards(context_clue_sentences)
ctx_clue_section = f"""{sectitle("Context Clue Sentences")}
{secnote("Read each sentence. Look at the highlighted word. Use the surrounding words as clues to figure out its meaning.")}
{ctx_clue_html}"""
# Vowel examples — conditional
vu_section = ""
if vowel_examples:
mid = (len(vowel_examples) + 1) // 2
left = vowel_examples[:mid]
right = vowel_examples[mid:]
vu = '<table style="width:100%;border-collapse:separate;border-spacing:4px;font-size:12px;margin:4px 0 8px 0;"><tr>'
vu += f'<td style="vertical-align:top;padding:4px;"><ul style="margin:0;padding-left:16px;">'
for item in left:
vu += f'<li>{item}</li>'
vu += '</ul></td>'
vu += f'<td style="vertical-align:top;padding:4px;"><ul style="margin:0;padding-left:16px;">'
for item in right:
vu += f'<li>{item}</li>'
vu += '</ul></td></tr></table>'
vu_section = vu
pdf_name = f"Week0{week_num}_{day_name}_{phonics_label.replace(' ', '_')}.pdf"
html = f"""<!DOCTYPE html>
<html><head><meta charset="utf-8"><style>{CSS}</style></head><body>
<div>
{header("English Language Arts", f"Week {week_num}, {day_name} -- {phonics_label}")}
{sectitle("Here's What We're Learning")}
{secnote(learning_text)}
{vu_section}
{secnote(grammar_note)}
{sectitle("Word Cards")}
{secnote("Read each word. Notice the pattern that makes the vowel sound.")}
<div class="word-grid">{cards}</div>
{ctx_clue_section}
</div>
{page_break()}
<div>
{sectitle("Spelling Story")}
{secnote("Read the story. Circle each spelling word as you find it.")}
<div class="story-box">{story_text}</div>
{sectitle("Grammar: What Is a Sentence?")}
{secnote(grammar_deep)}
{sectitle("Practice: Capital Letters & Periods")}
{secnote("Add capital letters and periods to these sentences.")}
<div style="font-size:12px;margin:6px 0;">
{gp_html}
</div>
</div>
<div>
{sectitle(sort_title)}
{secnote(sort_instruction)}
{sort_html}
</div>
{page_break()}
<div>
{sectitle("Copy Practice")}
{secnote("Read each word carefully, then copy it neatly on the line.")}
{copy_items}
</div>
{page_break()}
<div>
{fill_section}
{opp_section}
{sent_section}
</div>
</body></html>"""
HTML(string=html).write_pdf(os.path.join(day_dir, pdf_name))
print(f"[ok] Week {week_num} Monday generated")