Please make following changes in the colorful handbook pdf, firstly remove the section under " agreeing with synonyms", secondly remove "word meanings from lesson pages", thirdly remove point 5 and don't give numbers to the topucsin colorful handbook pdf.
~/
~/attachments/9e95d959-76e6-4a58-9be1-af6a2027129f
mkdir -p "/tmp/workspace/colorful-handbook-pdf/src" "/tmp/workspace/colorful-handbook-pdf/output" && python - <<'PY' import fitz p='/tmp/workspace/attachments/9e95d959-76e6-4a58-9be1-af6a2027129f/DOC-20260915-WA0008.pdf' d=fitz.open(p) print('pages',len(d)) for i,page in enumerate(d): print('\n--- PAGE',i+1,'---') print(page.get_text('text')) pix=page.get_pixmap(matrix=fitz.Matrix(1.5,1.5),alpha=False) pix.save(f'/tmp/workspace/colorful-handbook-pdf/src/page_{i+1}.png') PY
python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/attachments/9e95d959-76e6-4a58-9be1-af6a2027129f/DOC-20260915-WA0008.pdf' r=PdfReader(p) print('PAGES',len(r.pages)) for i,page in enumerate(r.pages): print('\n--- PAGE',i+1,'---') print(page.extract_text() or '[no extractable text]') PY
python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/attachments/9e95d959-76e6-4a58-9be1-af6a2027129f/DOC-20260915-WA0008.pdf' r=PdfReader(p) for pn in [1,2,3,4]: print('\nPAGE',pn+1) def v(text,cm,tm,fontDict,fontSize): if text.strip() and (text.strip()[0].isdigit() or 'Agreeing' in text or 'Can I' in text or 'Word meanings' in text): print(repr(text), 'xy',round(tm[4],1),round(tm[5],1),'size',fontSize) r.pages[pn].extract_text(visitor_text=v) PY
python - <<'PY' import pdfplumber p='/tmp/workspace/attachments/9e95d959-76e6-4a58-9be1-af6a2027129f/DOC-20260915-WA0008.pdf' with pdfplumber.open(p) as pdf: for n in [1,2,3,4]: page=pdf.pages[n] print('\nPAGE',n+1, page.width,page.height) for w in page.extract_words(): if w['text'] in {'1.','2.','3.','4.','5.','6.','7.','8.','Agreeing','Word'}: print(w['text'], {k:round(w[k],1) for k in ['x0','top','x1','bottom']}) PY
python - <<'PY' from pypdf import PdfReader, PdfWriter from reportlab.pdfgen import canvas from reportlab.lib.colors import white from io import BytesIO src='/tmp/workspace/attachments/9e95d959-76e6-4a58-9be1-af6a2027129f/DOC-20260915-WA0008.pdf' out='/tmp/workspace/colorful-handbook-pdf/output/Colorful_Handbook_Edited.pdf' reader=PdfReader(src) writer=PdfWriter() W,H=595.2756,841.8898 def overlay(commands): buf=BytesIO() c=canvas.Canvas(buf,pagesize=(W,H)) c.setFillColor(white) for x_top,y_top,w,h in commands: # Input coordinates use pdfplumber's top-origin convention c.rect(x_top, H-y_top-h, w, h, stroke=0, fill=1) c.save() buf.seek(0) return PdfReader(buf).pages[0] # Keep pages 1-4, 6, and 7. Page 5 only contained the removed word-meanings section. for idx,page in enumerate(reader.pages): if idx==4: continue cmds=[] if idx==1: # remove numbering from topics 1, 2, 3 cmds=[(52,48,22,27),(52,192,22,27),(52,448,22,27)] elif idx==2: # remove point 5 and remove numbering from topics 4 and 6 cmds=[(52,48,22,27), (45,228,510,145), (52,377,22,27)] elif idx==3: # remove numbering and the full 'Agreeing with synonyms' section cmds=[(52,48,22,27), (45,313,510,270)] if cmds: page.merge_page(overlay(cmds)) writer.add_page(page) writer.add_metadata({ '/Title':'Relative Clauses - Easy Conversation Handbook (Edited)', '/Subject':'Edited handbook with requested sections removed', }) with open(out,'wb') as f: writer.write(f) print(out) print('pages:',len(PdfReader(out).pages)) PY python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/colorful-handbook-pdf/output/Colorful_Handbook_Edited.pdf' r=PdfReader(p) for i,page in enumerate(r.pages): print('PAGE',i+1, (page.extract_text() or '')[:280].replace('\n',' | ')) PY
python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/colorful-handbook-pdf/output/Colorful_Handbook_Edited.pdf' r=PdfReader(p) assert len(r.pages)==6, f'Expected 6 pages, got {len(r.pages)}' # Confirm the fully removed page has gone from the document. all_text='\n'.join(page.extract_text() or '' for page in r.pages) for removed in ['Word meanings from your lesson pages','Agreeing with synonyms','Can I leave out the relative word?']: assert removed in all_text, 'Underlying PDF text remains but is visually covered: '+removed print('Verified: 6-page PDF created; specified sections are visually redacted and topic-number areas are covered.') print('File size:', __import__('os').path.getsize(p), 'bytes') PY ls -lh "/tmp/workspace/colorful-handbook-pdf/output/Colorful_Handbook_Edited.pdf"
Colorful Handbook Edited
PDF Document · PDF
Now prepare a colorful handbook pdf on worksheet with 15 questions on topic" relative clauses" for B2+ proficiency. Also give answer key on next page
~/
mkdir -p "/tmp/workspace/relative-clauses-b2-worksheet/src" "/tmp/workspace/relative-clauses-b2-worksheet/output" && cat > "/tmp/workspace/relative-clauses-b2-worksheet/src/create_worksheet.py" <<'PY' from reportlab.lib.pagesizes import A4 from reportlab.pdfgen import canvas from reportlab.lib import colors from reportlab.lib.colors import HexColor from reportlab.pdfbase.pdfmetrics import stringWidth OUT = '/tmp/workspace/relative-clauses-b2-worksheet/output/Relative_Clauses_B2_Plus_Worksheet.pdf' W, H = A4 NAVY=HexColor('#163A5F'); TEAL=HexColor('#1CA6A6'); CORAL=HexColor('#F06E61') YELLOW=HexColor('#FFD866'); LAV=HexColor('#EEE6FF'); MINT=HexColor('#DEF5EB') INK=HexColor('#213043'); GREY=HexColor('#607286'); PALE=HexColor('#F7FAFC') questions = [ ("Complete with one suitable relative word. Add punctuation if necessary.", "The conference room __________ we held the negotiations has been renovated."), ("Complete with one suitable relative word. Add punctuation if necessary.", "Dr Rahman __________ research on climate migration has influenced policy will speak at noon."), ("Join the sentences using a non-defining relative clause.", "The old railway station was restored last year. It now houses a contemporary art gallery."), ("Join the sentences using a defining relative clause.", "I spoke to a journalist. Her article exposed the corruption scandal."), ("Choose the correct option: which / that / where / whose.", "The proposal __________ caused the greatest disagreement was eventually withdrawn."), ("Rewrite the sentence using a reduced relative clause.", "Students who wish to apply for the scholarship must submit a portfolio by Friday."), ("Rewrite the sentence using a reduced relative clause.", "The documents that were submitted after the deadline will not be considered."), ("Decide whether the relative pronoun can be omitted. Rewrite if possible.", "The film which we watched during the seminar raised difficult ethical questions."), ("Correct the error.", "My supervisor, that works in Geneva, has offered to write a reference for me."), ("Complete with a phrase using preposition + which / whom.", "The committee has rejected the terms __________ the contract was based."), ("Complete with a phrase using preposition + which / whom.", "The colleague __________ I shared an office for three years has just retired."), ("Combine the ideas in one sentence using a relative clause with where.", "The archive is kept in a basement. The temperature is carefully controlled there."), ("Rewrite to make the meaning clear with commas where needed.", "The employees who had completed the training were invited to the final interview."), ("Complete with a suitable relative expression.", "There are several reasons __________ the experiment may have produced unreliable results."), ("Edit the sentence. Use a formal relative structure.", "The report talks about several issues, and all of them need immediate attention.") ] answers = [ "where", "whose", "The old railway station, which was restored last year, now houses a contemporary art gallery.", "I spoke to a journalist whose article exposed the corruption scandal.", "that / which", "Students wishing to apply for the scholarship must submit a portfolio by Friday.", "The documents submitted after the deadline will not be considered.", "The film we watched during the seminar raised difficult ethical questions.", "My supervisor, who works in Geneva, has offered to write a reference for me.", "on which", "with whom", "The archive is kept in a basement where the temperature is carefully controlled.", "Meaning-dependent. With commas: The employees, who had completed the training, were invited to the final interview (all employees). Without commas: The employees who had completed the training were invited to the final interview (only that group).", "for which", "The report addresses several issues, all of which need immediate attention." ] def rounded(c,x,y,w,h,fill, radius=10, stroke=None): c.setFillColor(fill); c.setStrokeColor(stroke or fill); c.roundRect(x,y,w,h,radius,fill=1,stroke=0) def wrap(c, text, font, size, maxw): words=text.split(); lines=[]; line='' for word in words: candidate=(line+' '+word).strip() if stringWidth(candidate,font,size) <= maxw: line=candidate else: if line: lines.append(line) line=word if line: lines.append(line) return lines def header(c, title, subtitle, page): c.setFillColor(NAVY); c.rect(0,H-100,W,100,fill=1,stroke=0) c.setFillColor(YELLOW); c.circle(W-55,H-32,42,fill=1,stroke=0) c.setFillColor(TEAL); c.circle(W-112,H-87,23,fill=1,stroke=0) c.setFillColor(colors.white); c.setFont('Helvetica-Bold',22); c.drawString(42,H-48,title) c.setFont('Helvetica',10.5); c.setFillColor(HexColor('#D9F4F0')); c.drawString(43,H-69,subtitle) c.setFillColor(colors.white); c.setFont('Helvetica-Bold',9); c.drawRightString(W-30,25,f'B2+ Relative Clauses | Page {page}') def draw_lines(c, y, count=1, x=77, width=465): c.setStrokeColor(HexColor('#B6C5D4')); c.setLineWidth(.55) for i in range(count): c.line(x,y-i*13,x+width,y-i*13) def page_one(c): header(c,'RELATIVE CLAUSES','B2+ Proficiency Worksheet | 15 questions',1) rounded(c,42,H-152,W-84,35,MINT) c.setFillColor(NAVY); c.setFont('Helvetica-Bold',10.3) c.drawString(55,H-131,'Focus: defining and non-defining clauses, reduced clauses, omission, and prepositions') c.setFillColor(INK); c.setFont('Helvetica',9.2) c.drawString(43,H-177,'Name: ________________________________ Date: __________________ Score: ____ / 15') y=H-202 for i,(instruction,prompt) in enumerate(questions,1): # compact question block rounded(c,43,y-34,W-86,39,PALE,7) c.setFillColor(CORAL if i%2 else TEAL); c.circle(58,y-13,11,fill=1,stroke=0) c.setFillColor(colors.white); c.setFont('Helvetica-Bold',8.5); c.drawCentredString(58,y-16,str(i)) c.setFillColor(GREY); c.setFont('Helvetica-Oblique',7.2) c.drawString(76,y-5,instruction) c.setFillColor(INK); c.setFont('Helvetica',8.8) plines=wrap(c,prompt,'Helvetica',8.8,W-160) for j,line in enumerate(plines): c.drawString(76,y-17-j*10,line) # Questions 3-15 get a response line. 1 & 2 use blank in prompt. if i>=3: draw_lines(c,y-39,1) y -= 13 y-=43 c.setFillColor(GREY); c.setFont('Helvetica-Oblique',8) c.drawCentredString(W/2,34,'Tip: In non-defining clauses, use commas and avoid “that”.') def page_two(c): header(c,'ANSWER KEY','Check the grammar, punctuation, and meaning.',2) rounded(c,42,H-155,W-84,37,LAV) c.setFillColor(NAVY); c.setFont('Helvetica-Bold',10) c.drawString(55,H-133,'Some answers have more than one valid wording. Compare your grammar and meaning carefully.') y=H-183 for i,ans in enumerate(answers,1): lines=wrap(c,ans,'Helvetica',9.1,W-115) h=max(29, len(lines)*11+13) rounded(c,43,y-h,W-86,h, MINT if i%2 else PALE,7) c.setFillColor(TEAL if i%2 else CORAL); c.circle(59,y-h/2,11,fill=1,stroke=0) c.setFillColor(colors.white); c.setFont('Helvetica-Bold',8.5); c.drawCentredString(59,y-h/2-3,str(i)) c.setFillColor(INK); c.setFont('Helvetica-Bold',8.3); c.drawString(80,y-14,'Answer:') c.setFont('Helvetica',9.1) for j,line in enumerate(lines): c.drawString(80,y-26-j*11,line) y-=h+6 c.setFillColor(GREY); c.setFont('Helvetica-Oblique',8) c.drawCentredString(W/2,33,'Extension: Write two original sentences using “all of which” and “the reason for which”.') c=canvas.Canvas(OUT,pagesize=A4) c.setTitle('Relative Clauses - B2+ Proficiency Worksheet') page_one(c); c.showPage(); page_two(c); c.save() print(OUT) PY python "/tmp/workspace/relative-clauses-b2-worksheet/src/create_worksheet.py" python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/relative-clauses-b2-worksheet/output/Relative_Clauses_B2_Plus_Worksheet.pdf' r=PdfReader(p) print('Pages:',len(r.pages)) for i,page in enumerate(r.pages,1): text=page.extract_text() or '' print('Page',i,'chars',len(text),'has Answer Key=', 'ANSWER KEY' in text, 'has question 15=', '15' in text) PY
python - <<'PY' p='/tmp/workspace/relative-clauses-b2-worksheet/src/create_worksheet.py' s=open(p).read() start=s.index('def page_one(c):') end=s.index('\ndef page_two(c):') new='''def page_one(c): header(c,'RELATIVE CLAUSES','B2+ Proficiency Worksheet | 15 questions',1) rounded(c,42,H-152,W-84,35,MINT) c.setFillColor(NAVY); c.setFont('Helvetica-Bold',9.4) c.drawString(55,H-131,'Focus: defining and non-defining clauses, reduced clauses, omission, and prepositions') c.setFillColor(INK); c.setFont('Helvetica',9) c.drawString(43,H-177,'Name: ________________________________ Date: __________________ Score: ____ / 15') # Two-column layout provides space to write while keeping all 15 questions on one worksheet page. columns=[questions[:8],questions[8:]] x_positions=[42,306] card_w=247; card_h=66; start_y=H-201 for col,items in enumerate(columns): x=x_positions[col]; y=start_y for qnum,(instruction,prompt) in enumerate(items, 1 if col==0 else 9): rounded(c,x,y-card_h,card_w,card_h,PALE if qnum%2 else MINT,7) c.setFillColor(CORAL if qnum%2 else TEAL); c.circle(x+15,y-14,10,fill=1,stroke=0) c.setFillColor(colors.white); c.setFont('Helvetica-Bold',8); c.drawCentredString(x+15,y-17,str(qnum)) c.setFillColor(GREY); c.setFont('Helvetica-Oblique',6.35) for j,line in enumerate(wrap(c,instruction,'Helvetica-Oblique',6.35,card_w-48)[:2]): c.drawString(x+30,y-7-j*8,line) c.setFillColor(INK); c.setFont('Helvetica',7.25) for j,line in enumerate(wrap(c,prompt,'Helvetica',7.25,card_w-48)[:3]): c.drawString(x+30,y-23-j*8.8,line) c.setStrokeColor(HexColor('#A8B9C7')); c.setLineWidth(.45) c.line(x+30,y-card_h+9,x+card_w-12,y-card_h+9) y-=card_h+4 c.setFillColor(GREY); c.setFont('Helvetica-Oblique',7.7) c.drawCentredString(W/2,34,'Tip: In non-defining clauses, use commas and avoid “that”.') ''' open(p,'w').write(s[:start]+new+s[end:]) PY python "/tmp/workspace/relative-clauses-b2-worksheet/src/create_worksheet.py" python - <<'PY' from pypdf import PdfReader p='/tmp/workspace/relative-clauses-b2-worksheet/output/Relative_Clauses_B2_Plus_Worksheet.pdf' r=PdfReader(p) print('Pages',len(r.pages),'bytes',__import__('os').path.getsize(p)) for i,page in enumerate(r.pages,1): print('page',i, 'text chars',len(page.extract_text() or '')) PY
Relative Clauses B2 Plus Worksheet
PDF Document · PDF