#!/usr/bin/env python3
"""
Thursday Generator - Write It (4 pages)
Usage:
from thursday import generate_thursday
generate_thursday(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, page_break, remember_box
from weasyprint import HTML
def generate_thursday(**kw):
week_dir = kw["week_dir"]
week_num = kw["week_num"]
day_name = kw.get("day_name", "Thursday")
phonics_label = kw["phonics_label"]
words = kw["words"]
learning_text = kw["learning_text"]
remember_text = kw["remember_text"]
story_text = kw["story_text"]
comp_questions = kw["comp_questions"]
sentence_sort_data = kw.get("sentence_sort_data", [])
detective_words = kw.get("detective_words", []) # [misspelled_word, ...]
swap_data = kw.get("swap_data", [])
map_word = kw.get("map_word", "")
para_prompts = kw.get("para_prompts", [])
story_prompt = kw.get("story_prompt", "Write a story using at least 5 of your spelling words.")
# NEW: Vocabulary / context clue support
context_clue_writing = kw.get("context_clue_writing", []) # [word, ...] write context clue sentences
fix_paragraph = kw.get("fix_paragraph", "") # paragraph body missing topic/conclusion
day_dir = os.path.join(week_dir, "Thursday")
os.makedirs(day_dir, exist_ok=True)
WORD_NAMES = [w[0] for w in words]
# Comprehension questions with writing lines
comp_html = "".join(f'<div style="margin-bottom:8px;"><strong style="font-size:12px;">{q}</strong><br>{write_line()}</div>' for q in comp_questions)
# Sentence Sort
sort_html = ""
for idx, sentence in enumerate(sentence_sort_data, 1):
word_list = sentence.split()
shuffled = list(word_list)
random.Random(50 + idx).shuffle(shuffled)
tags = "".join(f'<span style="display:inline-block;background:#FFF3E0;border:1px solid #FFB74D;padding:2px 8px;margin:2px;border-radius:3px;font-size:11px;">{w}</span>' for w in shuffled)
sort_html += f'<div style="margin:8px 0;padding:6px 8px;background:#FAFAFA;border:1.5px solid #B2DFDB;border-radius:6px;"><div style="font-size:11px;font-weight:bold;color:#FF7043;margin-bottom:4px;">Sentence {idx}:</div><div style="margin-bottom:4px;">{tags}</div>{write_line()}</div>'
sort_section = ""
if sentence_sort_data:
sort_section = f"""{sectitle("Sentence Sort")}
{secnote("Unscramble the words to form correct sentences.")}
{sort_html}"""
# Spelling Detective - 8 words
det_html = ""
for wrong in detective_words:
det_html += f'<div style="display:inline-block;width:30%;margin:4px;padding:4px 8px;background:#FFF8E1;border-radius:4px;border:1px solid #FFD54F;font-size:12px;"><span style="text-decoration:line-through;color:#E53935;">{wrong}</span> <span style="color:#888;">→</span> <div style="position:relative;height:18px;margin:2px 0;display:inline-block;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:12px;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>'
det_section = ""
if detective_words:
det_section = f"""{sectitle("Spelling Detective")}
{secnote("Each word has a mistake. Write the correct spelling.")}
{det_html}"""
# Word Swap
swap_html = ""
for orig, (w1o, w1s), (w2o, w2s) in swap_data:
highlighted = orig.replace(w1o, f"<strong>{w1o}</strong>").replace(w2o, f"<strong>{w2o}</strong>")
swap_html += f'<div style="margin-bottom:10px;padding:6px 8px;background:#FFF3E0;border-radius:5px;border:1px solid #FFB74D;"><div style="font-size:10.5px;font-weight:bold;color:#FF7043;margin-bottom:3px;">Original:</div><div style="font-size:12px;font-style:italic;margin-bottom:4px;">{highlighted}</div><div style="font-size:10.5px;font-weight:bold;color:#FF7043;margin-bottom:3px;">Now write using <strong>{w1s}</strong> and <strong>{w2s}</strong>:</div>{write_line()}</div>'
swap_section = ""
if swap_data:
swap_section = f"""{sectitle("Word Swap")}
{secnote("Read the original, then write your own using the new words.")}
{swap_html}"""
# Spelling Map
map_section = ""
if map_word:
def map_line():
return '<div style="position:relative;height:22px;margin:2px 0;"><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:12px;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>'
map_html = (f'<div style="text-align:center;margin:12px 0;padding:12px;background:#E8F5E9;border-radius:8px;border:2px solid #A5D6A7;">'
f'<div style="font-weight:bold;font-size:14px;color:#2E7D32;margin-bottom:8px;">{map_word}</div>'
f'<table style="margin:0 auto;border-collapse:separate;border-spacing:4px;width:auto;">'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">Meaning:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">Long vowel:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'<tr><td style="padding:4px 8px;background:#FFF3E0;border:1px solid #FFB74D;border-radius:4px;font-size:11px;">Sentence:</td>'
f'<td style="padding:4px 8px;border:1px solid #ccc;border-radius:4px;font-size:11px;min-width:200px;">{map_line()}</td></tr>'
f'</table></div>')
map_section = f"""{sectitle("Spelling Map")}
{secnote("Fill in the details for this week's featured word.")}
{map_html}"""
# Paragraph Builder
para_html = ""
for p in para_prompts:
para_html += f'<div style="margin:8px 0;padding:6px 8px;background:#E0F2F1;border:1.5px solid #80CBC4;border-radius:6px;"><div style="font-size:11px;font-weight:bold;color:#FF7043;margin-bottom:4px;">{p}</div>{write_line()}{write_line()}{write_line()}</div>'
para_section = ""
if para_prompts:
para_section = f"""{sectitle("Paragraph Builder")}
{secnote("Write a short paragraph for each prompt. Use at least 2 spelling words in each.")}
{para_html}"""
# Context Clue Writing — write sentences that give clues (NEW)
ctx_write_html = ""
if context_clue_writing:
for word in context_clue_writing:
ctx_write_html += f'<div style="margin:6px 0;padding:6px 8px;background:#E8F5E9;border:1.5px solid #A5D6A7;border-radius:6px;"><div style="font-size:11px;font-weight:bold;color:#2E7D32;margin-bottom:4px;">Write a sentence that gives context clues for <strong>{word}</strong>:</div>{write_line()}</div>'
ctx_write_section = ""
if context_clue_writing:
ctx_write_section = f"""{sectitle("Context Clue Writing", "coral")}
{secnote("Write a sentence for each word that helps the reader figure out its meaning from context.")}
{ctx_write_html}"""
# Fix the Paragraph — add missing topic sentence and conclusion (NEW)
fix_para_section = ""
if fix_paragraph:
fix_para_section = f"""{sectitle("Fix This Paragraph", "coral")}
{secnote("This paragraph is missing a topic sentence and a conclusion. Write them!")}\n""" + \
f'<div style="background:#F3E5F5;border:1.5px solid #CE93D8;border-radius:6px;padding:10px;margin:8px 0;">\n' + \
f'<div style="font-size:11px;font-weight:bold;color:#AB47BC;margin-bottom:6px;">Write a topic sentence:</div>\n' + \
f'{write_line()}\n' + \
f'<div style="font-size:12px;margin:8px 0;padding:6px;background:#FAFAFA;border-radius:4px;line-height:1.5;">{fix_paragraph}</div>\n' + \
f'<div style="font-size:11px;font-weight:bold;color:#AB47BC;margin:8px 0 4px;">Write a conclusion sentence:</div>\n' + \
f'{write_line()}\n' + \
f'</div>'
# Story writing lines
story_lines = "\n ".join(write_line() for _ in range(8))
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} -- Write It")}
{sectitle("Here's What We're Learning")}
{secnote(learning_text)}
{remember_box("Remember This!", remember_text)}
{sectitle("Spelling Story")}
{secnote("Read the story. Circle each spelling word.")}
<div class="story-box">{story_text}</div>
{sectitle("Comprehension Questions")}
{secnote("Answer each question in a complete sentence.")}
{comp_html}
</div>
{page_break()}
<div>
{sort_section}
{det_section}
{swap_section}
</div>
<div>
{map_section}
{para_section}
{ctx_write_section}
{fix_para_section}
{sectitle("Write Your Own Story")}
{secnote("Write a story using at least 5 of your spelling words. Use capital letters and periods!")}
<div style="font-size:11px;font-weight:bold;color:#FF7043;margin-bottom:8px;">{story_prompt}</div>
{story_lines}
</div>
</body></html>"""
HTML(string=html).write_pdf(os.path.join(day_dir, pdf_name))
print(f"[ok] Week {week_num} Thursday generated")