Please create a colorful pdf chart using the chart from both the attached photo for my ESL student.
ls -la /tmp/workspace/; fc-list | grep -i -E "dejavu|liberation|noto" | head
mkdir -p /tmp/workspace/clause-chart && cat > /tmp/workspace/clause-chart/make.py <<'EOF' from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A4, landscape from reportlab.lib.colors import HexColor, white from reportlab.pdfbase.pdfmetrics import stringWidth from reportlab.lib.utils import simpleSplit W, H = landscape(A4) OUT = "/tmp/workspace/clause-chart/English_Clause_Chart.pdf" c = canvas.Canvas(OUT, pagesize=landscape(A4)) c.setTitle("The English Clause Chart"); c.setAuthor("ESL Class") NAVY=HexColor("#1F3A93"); GREEN=HexColor("#2E9E5B"); LGREEN=HexColor("#E3F6EA") ORANGE=HexColor("#E8741E"); LORANGE=HexColor("#FFEBDA"); PURPLE=HexColor("#7B3FBF") YELLOW=HexColor("#FFF6C9"); RED=HexColor("#D62F4B"); BLUE=HexColor("#1E88E5") TEAL=HexColor("#00897B"); PINK=HexColor("#D81B8A"); DARK=HexColor("#222222"); BG=HexColor("#F4F8FF") LBLUE=HexColor("#E3F0FF"); LPINK=HexColor("#FDE4F2"); LTEAL=HexColor("#DDF4F1"); LPURP=HexColor("#EEE2FA"); LRED=HexColor("#FDE3E8") def bg(): c.setFillColor(BG); c.rect(0,0,W,H,stroke=0,fill=1) # decorative dots for i,col in enumerate([RED,ORANGE,GREEN,BLUE,PURPLE]*3): c.setFillColor(col); c.circle(20+i*55, 12, 4, stroke=0, fill=1) def rbox(x,y,w,h,fill,stroke=None,r=12,lw=2): c.setFillColor(fill) if stroke: c.setStrokeColor(stroke); c.setLineWidth(lw) c.roundRect(x,y,w,h,r,stroke=1 if stroke else 0,fill=1) def ctext(txt,x,y,font="Helvetica-Bold",size=14,color=DARK): c.setFillColor(color); c.setFont(font,size); c.drawCentredString(x,y,txt) def segs(x,y,parts,size=14,center=False,font="Helvetica-Bold"): """parts: list of (text,color,font or None)""" tot=sum(stringWidth(t,f or font,size) for t,_,f in parts) if center: x=x-tot/2 for t,col,f in parts: c.setFillColor(col); c.setFont(f or font,size); c.drawString(x,y,t); x+=stringWidth(t,f or font,size) def arrow(x1,y1,x2,y2,col,lw=4): import math c.setStrokeColor(col); c.setFillColor(col); c.setLineWidth(lw) ang=math.atan2(y2-y1,x2-x1); L=14 bx,by=x2-L*0.8*math.cos(ang),y2-L*0.8*math.sin(ang) c.line(x1,y1,bx,by) p=c.beginPath(); p.moveTo(x2,y2) p.lineTo(x2-L*math.cos(ang-0.4),y2-L*math.sin(ang-0.4)) p.lineTo(x2-L*math.cos(ang+0.4),y2-L*math.sin(ang+0.4)); p.close() c.drawPath(p,stroke=0,fill=1) def wrapped(txt,x,y,w,font,size,color,lead=None): lead=lead or size*1.3 c.setFillColor(color); c.setFont(font,size) for ln in simpleSplit(txt,font,size,w): c.drawString(x,y,ln); y-=lead return y def chip(x,y,txt,col,size=11): w=stringWidth(txt,"Helvetica-Bold",size)+18 rbox(x,y,w,19,white,col,r=9,lw=1.8) c.setFillColor(col); c.setFont("Helvetica-Bold",size); c.drawString(x+9,y+5.5,txt) return x+w+8 # ================= PAGE 1 ================= bg() rbox(30,520,W-60,58,NAVY,r=16) ctext("THE ENGLISH CLAUSE CHART",W/2,540,size=30,color=white) for i,col in enumerate([RED,ORANGE,YELLOW,GREEN,BLUE]): c.setFillColor(col); c.circle(W/2-200+i*0,0,0) rbox(30,452,W-60,52,YELLOW,ORANGE) segs(W/2,472,[("Definition: ",NAVY,None),("A clause is a group of words with a ",DARK,"Helvetica"), ("SUBJECT",RED,None),(" and a ",DARK,"Helvetica"),("VERB",BLUE,None),(".",DARK,"Helvetica")],size=19,center=True) # question qw,qh=420,42; qx=W/2-qw/2; qy=382 rbox(qx,qy,qw,qh,PURPLE,r=21) ctext("CAN IT STAND ALONE AS A SENTENCE?",W/2,qy+14,size=16,color=white) arrow(W/2,452,W/2,qy+qh+2,PURPLE,3) # branches bx1=30+185; bx2=W-30-185 c.setStrokeColor(PURPLE); c.setLineWidth(3) c.line(W/2-60,qy+qh/2-0,0+0,0) if False else None arrow(qx+30,qy+2,bx1,332,GREEN,4) arrow(qx+qw-30,qy+2,bx2,332,ORANGE,4) rbox(bx1-120,352,60,24,GREEN,r=12); ctext("YES",bx1-90,359,size=13,color=white) rbox(bx2+60,352,60,24,ORANGE,r=12); ctext("NO",bx2+90,359,size=13,color=white) def bigbox(x,col,lcol,num,title,sub,defs,ex_parts,ex_note,tags,tagtitle): w=370; top=332; bottom=34 rbox(x,bottom,w,top-bottom,lcol,col,lw=3) rbox(x,top-62,w,62,col,r=14) c.rect(x,top-62,w,20,stroke=0,fill=1) if False else None ctext(f"{num}. {title}",x+w/2,top-30,size=21,color=white) ctext(sub,x+w/2,top-50,font="Helvetica-Oblique",size=13,color=white) y=top-92 c.setFillColor(col); c.setFont("Helvetica-Bold",12); c.drawString(x+18,y,"DEFINITION") y-=24 for d,bold in defs: c.setFillColor(col); c.circle(x+26,y+5,4,stroke=0,fill=1) c.setFillColor(DARK); c.setFont("Helvetica-Bold" if bold else "Helvetica",17); c.drawString(x+40,y,d); y-=27 # example box ey=y-12 rbox(x+16,ey-52,w-32,60,white,col,r=10,lw=1.8) c.setFillColor(col); c.setFont("Helvetica-Bold",11); c.drawString(x+28,ey-4,"EXAMPLE") segs(x+28,ey-28,ex_parts,size=17) c.setFillColor(HexColor("#555555")); c.setFont("Helvetica-Oblique",10.5); c.drawString(x+28,ey-45,ex_note) # tags ty=ey-80 c.setFillColor(col); c.setFont("Helvetica-Bold",12); c.drawString(x+18,ty,tagtitle) tx=x+18; ty2=ty-30 for t in tags: wt=stringWidth(t,"Helvetica-Bold",12)+18 if tx+wt>x+w-14: tx=x+18; ty2-=26 tx=chip(tx,ty2,t,col,12) bigbox(30,GREEN,LGREEN,1,"INDEPENDENT CLAUSE","(Main Clause)", [("A complete thought.",True),("Can stand alone.",False)], [("The dog barks.",GREEN,None)],"It has a subject + verb and makes sense by itself.", ["Declarative","Interrogative","Imperative","Exclamatory"],"BROKEN DOWN BY SENTENCE TYPE (next page):") bigbox(W-30-370,ORANGE,LORANGE,2,"DEPENDENT CLAUSE","(Subordinate Clause)", [("An incomplete thought.",True),("Cannot stand alone.",False),("Needs an Independent clause.",False)], [("because it is bored",ORANGE,None),(" (not a sentence!)",HexColor("#777777"),"Helvetica-Oblique")], "It needs a main clause to finish the idea.", ["Adjective","Adverb","Noun"],"BROKEN DOWN BY THEIR JOB (next page):") c.showPage() # ================= PAGE 2 ================= bg() rbox(30,530,W-60,48,NAVY,r=14) ctext("CLAUSE TYPES AND EXAMPLES",W/2,545,size=24,color=white) # left header LX=30; LW=370; RX=W-30-LW rbox(LX,490,LW,34,GREEN,r=10) ctext("INDEPENDENT CLAUSE: by sentence type",LX+LW/2,501,size=14,color=white) rbox(RX,490,LW,34,ORANGE,r=10) ctext("DEPENDENT CLAUSE: by their job",RX+LW/2,501,size=14,color=white) left=[("1","Declarative","(Statement)",[("The dog barks.",None)],BLUE,LBLUE), ("2","Interrogative","(Question)",[("Does the dog bark?",None)],PINK,LPINK), ("3","Imperative","(Command)",[("Bark, dog!",None)],TEAL,LTEAL), ("4","Exclamatory","(Excitement)",[("The dog is barking!",None)],RED,LRED)] ch=84; gap=9; y0=482 for i,(n,name,mean,ex,col,lcol) in enumerate(left): top=y0-i*(ch+gap); by=top-ch rbox(LX,by,LW,ch,lcol,col,lw=2.2) c.setFillColor(col); c.circle(LX+30,by+ch/2,17,stroke=0,fill=1) ctext(n,LX+30,by+ch/2-6,size=18,color=white) segs(LX+58,top-28,[(name+" ",col,None),(mean,DARK,"Helvetica-Oblique")],size=16) c.setFillColor(DARK); c.setFont("Helvetica-Bold",11); c.drawString(LX+58,top-47,"Example:") c.setFillColor(DARK); c.setFont("Helvetica-Bold",19); c.drawString(LX+58,top-71,ex[0][0]) right=[("1","Adjective Clause","Describes a noun",["who","which","that"], [("The dog ",DARK,None),("[that is loud]",RED,None),(" barks.",DARK,None)],BLUE,LBLUE), ("2","Adverb Clause","Tells when, why, how",["because","when","if"], [("The dog barks ",DARK,None),("[because it is bored]",RED,None),(".",DARK,None)],PINK,LPINK), ("3","Noun Clause","Acts as a subject / object",["what","whoever","that"], [("[What the dog wants]",RED,None),(" is a bone.",DARK,None)],TEAL,LTEAL)] rh=116; rgap=9 for i,(n,name,job,clues,ex,col,lcol) in enumerate(right): top=y0-i*(rh+rgap); by=top-rh rbox(RX,by,LW,rh,lcol,col,lw=2.2) c.setFillColor(col); c.circle(RX+30,top-26,16,stroke=0,fill=1) ctext(n,RX+30,top-32,size=17,color=white) segs(RX+56,top-31,[(name,col,None)],size=17) segs(RX+18,top-52,[("Job: ",col,None),(job,DARK,"Helvetica-Bold")],size=12.5) c.setFillColor(col); c.setFont("Helvetica-Bold",12.5); c.drawString(RX+18,top-75,"Clue words:") x=RX+18+stringWidth("Clue words:","Helvetica-Bold",12.5)+10 for cl in clues: x=chip(x,top-81,cl,col,12.5) segs(RX+18,top-102,[("Ex: ",col,None)]+ex,size=14.5) # special banner rbox(30,34,W-60,100-9*0-0 if False else 66,LPURP,PURPLE,lw=2.5) rbox(30,34+66-22,W-60,22,PURPLE,r=10) ctext("SPECIAL DEPENDENT CLAUSE: PARTICIPLE CLAUSES",W/2,34+66-16,size=13,color=white) segs(46,34+30,[("Examples: ",PURPLE,None),("Walking to work, ...",DARK,None),(" Having been told, ...",DARK,None)],size=13.5) wrapped('A "shortcut" type of Adverb clause that drops words like "while" or "because" to make sentences shorter.',46,34+12,W-92,"Helvetica",11.5,DARK) c.showPage(); c.save() EOF cd /tmp/workspace/clause-chart && python make.py && python -c " import pdfplumber p=pdfplumber.open('English_Clause_Chart.pdf') print(len(p.pages)) for i,pg in enumerate(p.pages): pg.to_image(resolution=80).save(f'p{i+1}.png') "; ls
cd /tmp/workspace/clause-chart && python - <<'EOF' s=open('make.py').read() s=s.replace('rbox(bx1-120,352,60,24,GREEN,r=12); ctext("YES",bx1-90,359','rbox(bx1-60,350,60,24,GREEN,r=12); ctext("YES",bx1-30,357') s=s.replace('rbox(bx2+60,352,60,24,ORANGE,r=12); ctext("NO",bx2+90,359','rbox(bx2,350,60,24,ORANGE,r=12); ctext("NO",bx2+30,357') s=s.replace('w=370; top=332; bottom=34','w=370; top=332; bottom=28') s=s.replace('y=top-92\n','y=top-84\n').replace('y-=24\n for d,bold','y-=22\n for d,bold').replace('drawString(x+40,y,d); y-=27','drawString(x+40,y,d); y-=25') s=s.replace('ey=y-12','ey=y-6').replace('ty=ey-80','ty=ey-76').replace('tx=x+18; ty2=ty-30','tx=x+18; ty2=ty-26') s=s.replace('tx=chip(tx,ty2,t,col,12)','tx=chip(tx,ty2,t,col,11)').replace('wt=stringWidth(t,"Helvetica-Bold",12)+18','wt=stringWidth(t,"Helvetica-Bold",11)+18') s=s.replace('ty2-=26','ty2-=24') s=s.replace('c.circle(20+i*55, 12, 4','c.circle(20+i*55, 12, 3') open('make.py','w').write(s) EOF python make.py && python -c " import pdfplumber p=pdfplumber.open('English_Clause_Chart.pdf') p.pages[0].to_image(resolution=80).save('p1.png')"
cd /tmp/workspace/clause-chart && grep -n "top=332\|ty2=ty\|bx1-60" make.py; python -c " import pdfplumber p=pdfplumber.open('English_Clause_Chart.pdf') p.pages[0].to_image(resolution=80).save('p1_v2.png')"
English Clause Chart
PDF Document · PDF
Make a one-page poster version of this chart
cd /tmp/workspace/clause-chart && cat > poster.py <<'EOF' from reportlab.pdfgen import canvas from reportlab.lib.pagesizes import A3 from reportlab.lib.colors import HexColor, white from reportlab.pdfbase.pdfmetrics import stringWidth from reportlab.lib.utils import simpleSplit import math W,H = A3 OUT="/tmp/workspace/clause-chart/English_Clause_Poster.pdf" c=canvas.Canvas(OUT,pagesize=A3) c.setTitle("The English Clause Chart - Poster") NAVY=HexColor("#1F3A93"); GREEN=HexColor("#2E9E5B"); LGREEN=HexColor("#E3F6EA") ORANGE=HexColor("#E8741E"); LORANGE=HexColor("#FFEBDA"); PURPLE=HexColor("#7B3FBF") YELLOW=HexColor("#FFF6C9"); RED=HexColor("#D62F4B"); BLUE=HexColor("#1E88E5") TEAL=HexColor("#00897B"); PINK=HexColor("#D81B8A"); DARK=HexColor("#222222"); BG=HexColor("#F4F8FF") LBLUE=HexColor("#E3F0FF"); LPINK=HexColor("#FDE4F2"); LTEAL=HexColor("#DDF4F1"); LPURP=HexColor("#EEE2FA"); LRED=HexColor("#FDE3E8") GREY=HexColor("#777777") def rbox(x,y,w,h,fill,stroke=None,r=14,lw=2.5): c.setFillColor(fill) if stroke: c.setStrokeColor(stroke); c.setLineWidth(lw) c.roundRect(x,y,w,h,r,stroke=1 if stroke else 0,fill=1) def ctext(t,x,y,font="Helvetica-Bold",size=14,color=DARK): c.setFillColor(color); c.setFont(font,size); c.drawCentredString(x,y,t) def segs(x,y,parts,size=14,center=False,font="Helvetica-Bold",maxw=None): def tw(sz): return sum(stringWidth(t,f or font,sz) for t,_,f in parts) if maxw: while tw(size)>maxw: size-=0.5 tot=tw(size) if center: x-=tot/2 for t,col,f in parts: c.setFillColor(col); c.setFont(f or font,size); c.drawString(x,y,t); x+=stringWidth(t,f or font,size) def arrow(x1,y1,x2,y2,col,lw=5): c.setStrokeColor(col); c.setFillColor(col); c.setLineWidth(lw) a=math.atan2(y2-y1,x2-x1); L=20 bx,by=x2-L*0.8*math.cos(a),y2-L*0.8*math.sin(a) c.line(x1,y1,bx,by) p=c.beginPath(); p.moveTo(x2,y2) p.lineTo(x2-L*math.cos(a-0.4),y2-L*math.sin(a-0.4)); p.lineTo(x2-L*math.cos(a+0.4),y2-L*math.sin(a+0.4)); p.close() c.drawPath(p,stroke=0,fill=1) def chip(x,y,t,col,size=15): w=stringWidth(t,"Helvetica-Bold",size)+24 rbox(x,y,w,size+11,white,col,r=(size+11)/2,lw=2) c.setFillColor(col); c.setFont("Helvetica-Bold",size); c.drawString(x+12,y+6.5,t) return x+w+10 # background + border c.setFillColor(BG); c.rect(0,0,W,H,stroke=0,fill=1) cols=[RED,ORANGE,GREEN,BLUE,PURPLE] for i in range(int(W//30)+1): c.setFillColor(cols[i%5]); c.circle(10+i*30,14,5,stroke=0,fill=1) c.circle(10+i*30,H-8,5,stroke=0,fill=1) M=30; CW=385; GAP=W-2*M-2*CW; LX=M; RX=M+CW+GAP # Title rbox(M,1082,W-2*M,84,NAVY,r=22) ctext("THE ENGLISH CLAUSE CHART",W/2,1110,size=46,color=white) # Definition rbox(M,992,W-2*M,74,YELLOW,ORANGE,r=18,lw=3) segs(W/2,1019,[("Definition: ",NAVY,None),("A clause is a group of words with a ",DARK,"Helvetica"), ("SUBJECT",RED,None),(" and a ",DARK,"Helvetica"),("VERB",BLUE,None),(".",DARK,"Helvetica")],size=28,center=True) # Question qw,qh=520,52; qx=W/2-qw/2; qy=904 arrow(W/2,992,W/2,qy+qh+3,PURPLE,4) rbox(qx,qy,qw,qh,PURPLE,r=26) ctext("CAN IT STAND ALONE AS A SENTENCE?",W/2,qy+17,size=23,color=white) TOP=860 cxl=LX+CW/2; cxr=RX+CW/2 arrow(qx+40,qy+2,cxl,TOP+3,GREEN,5) arrow(qx+qw-40,qy+2,cxr,TOP+3,ORANGE,5) rbox(cxl-120,TOP+24,80,30,GREEN,r=15); ctext("YES",cxl-80,TOP+33,size=17,color=white) rbox(cxr+40,TOP+24,80,30,ORANGE,r=15); ctext("NO",cxr+80,TOP+33,size=17,color=white) def topbox(x,col,lcol,num,title,sub,defs,ex,note): bot=598; h=TOP-bot rbox(x,bot,CW,h,lcol,col,lw=3.5) rbox(x,TOP-72,CW,72,col,r=16) c.rect(x,TOP-72,CW,1,stroke=0,fill=0) ctext(f"{num}. {title}",x+CW/2,TOP-35,size=27,color=white) ctext(sub,x+CW/2,TOP-59,font="Helvetica-Oblique",size=16,color=white) c.setFillColor(col); c.setFont("Helvetica-Bold",15); c.drawString(x+22,TOP-98,"DEFINITION") y=TOP-126 for d,b in defs: c.setFillColor(col); c.circle(x+32,y+6,5,stroke=0,fill=1) c.setFillColor(DARK); c.setFont("Helvetica-Bold" if b else "Helvetica",21); c.drawString(x+48,y,d); y-=30 rbox(x+18,bot+14,CW-36,70,white,col,r=12,lw=2) c.setFillColor(col); c.setFont("Helvetica-Bold",13); c.drawString(x+32,bot+66,"EXAMPLE") segs(x+32,bot+42,ex,size=23,maxw=CW-64) c.setFillColor(HexColor("#555555")); c.setFont("Helvetica-Oblique",12.5); c.drawString(x+32,bot+24,note) topbox(LX,GREEN,LGREEN,1,"INDEPENDENT CLAUSE","(Main Clause)", [("A complete thought.",True),("Can stand alone.",False)], [("The dog barks.",GREEN,None)],"It has a subject + verb and makes sense by itself.") topbox(RX,ORANGE,LORANGE,2,"DEPENDENT CLAUSE","(Subordinate Clause)", [("An incomplete thought.",True),("Cannot stand alone.",False),("Needs an Independent clause.",False)], [("because it is bored",ORANGE,None),(" (not a sentence!)",GREY,"Helvetica-Oblique")], "It needs a main clause to finish the idea.") # sub headers SB=556 rbox(LX,SB,CW,36,GREEN,r=12); ctext("BROKEN DOWN BY SENTENCE TYPE",LX+CW/2,SB+11,size=17,color=white) rbox(RX,SB,CW,36,ORANGE,r=12); ctext("BROKEN DOWN BY THEIR JOB",RX+CW/2,SB+11,size=17,color=white) arrow(cxl,598,cxl,SB+37,GREEN,4); arrow(cxr,598,cxr,SB+37,ORANGE,4) left=[("1","Declarative","(Statement)","The dog barks.",BLUE,LBLUE), ("2","Interrogative","(Question)","Does the dog bark?",PINK,LPINK), ("3","Imperative","(Command)","Bark, dog!",TEAL,LTEAL), ("4","Exclamatory","(Excitement)","The dog is barking!",RED,LRED)] ch=100; gp=8; y0=SB-8 for i,(n,name,mean,ex,col,lcol) in enumerate(left): top=y0-i*(ch+gp); by=top-ch rbox(LX,by,CW,ch,lcol,col,lw=2.5) c.setFillColor(col); c.circle(LX+36,by+ch/2,22,stroke=0,fill=1) ctext(n,LX+36,by+ch/2-8,size=24,color=white) segs(LX+72,top-34,[(name+" ",col,None),(mean,DARK,"Helvetica-Oblique")],size=22,maxw=CW-90) c.setFillColor(GREY); c.setFont("Helvetica-Bold",12); c.drawString(LX+72,top-54,"EXAMPLE") c.setFillColor(DARK); c.setFont("Helvetica-Bold",26); c.drawString(LX+72,top-84,ex) right=[("1","Adjective Clause","Describes a noun",["who","which","that"], [("The dog ",DARK,None),("[that is loud]",RED,None),(" barks.",DARK,None)],BLUE,LBLUE), ("2","Adverb Clause","Tells when, why, how",["because","when","if"], [("The dog barks ",DARK,None),("[because it is bored]",RED,None),(".",DARK,None)],PINK,LPINK), ("3","Noun Clause","Acts as a subject / object",["what","whoever","that"], [("[What the dog wants]",RED,None),(" is a bone.",DARK,None)],TEAL,LTEAL)] rh=136; rg=8 for i,(n,name,job,clues,ex,col,lcol) in enumerate(right): top=y0-i*(rh+rg); by=top-rh rbox(RX,by,CW,rh,lcol,col,lw=2.5) c.setFillColor(col); c.circle(RX+36,top-34,21,stroke=0,fill=1) ctext(n,RX+36,top-42,size=23,color=white) segs(RX+70,top-42,[(name,col,None)],size=26) segs(RX+22,top-68,[("Job: ",col,None),(job,DARK,"Helvetica-Bold")],size=17) c.setFillColor(col); c.setFont("Helvetica-Bold",16); c.drawString(RX+22,top-96,"Clue words:") x=RX+22+stringWidth("Clue words:","Helvetica-Bold",16)+12 for cl in clues: x=chip(x,top-103,cl,col,15) segs(RX+22,top-125,[("Ex: ",col,None)]+ex,size=19,maxw=CW-40) # participle banner bt=y0-4*(ch+gp)+gp-8 # just under left cards bh=84; by=bt-bh-2 by=40 rbox(M,by,W-2*M,bh+4,LPURP,PURPLE,r=14,lw=3) rbox(M,by+bh+4-30,W-2*M,30,PURPLE,r=14) ctext("SPECIAL DEPENDENT CLAUSE: PARTICIPLE CLAUSES",W/2,by+bh+4-21,size=17,color=white) segs(M+22,by+32,[("Examples: ",PURPLE,None),("Walking to work, ...",DARK,None),(" Having been told, ...",DARK,None)],size=19) c.setFillColor(DARK); c.setFont("Helvetica",14) c.drawString(M+22,by+10,'A "shortcut" type of Adverb clause that drops words like "while" or "because" to make sentences shorter.') print("left cards bottom", y0-4*(ch+gp)+gp, "banner top", by+bh+4) c.showPage(); c.save() EOF python poster.py && python -c " import pdfplumber p=pdfplumber.open('English_Clause_Poster.pdf'); print(len(p.pages)) p.pages[0].to_image(resolution=70).save('poster_v1.png')"
cd /tmp/workspace/clause-chart && python - <<'EOF' s=open('poster.py').read() R=[('size=28,center=True)','size=28,center=True,maxw=W-2*M-50)'), ('bot=598; h=TOP-bot','bot=580; h=TOP-bot'), ('drawString(x+48,y,d); y-=30','drawString(x+48,y,d); y-=27'), ('SB=556','SB=538'), ('arrow(cxl,598,','arrow(cxl,580,'),('arrow(cxr,598,','arrow(cxr,580,'), ('ch=100; gp=8','ch=92; gp=8'), ('top-34,[(name+" "','top-32,[(name+" "'), ('drawString(LX+72,top-54,"EXAMPLE")','drawString(LX+72,top-50,"EXAMPLE")'), ('drawString(LX+72,top-84,ex)','drawString(LX+72,top-78,ex)'), ('rh=136; rg=8','rh=125; rg=8'), ('c.circle(RX+36,top-34,21','c.circle(RX+36,top-30,20'), ('ctext(n,RX+36,top-42,size=23','ctext(n,RX+36,top-38,size=22'), ('segs(RX+70,top-42,','segs(RX+70,top-38,'), ('segs(RX+22,top-68,','segs(RX+22,top-62,'), ('drawString(RX+22,top-96,"Clue words:")','drawString(RX+22,top-88,"Clue words:")'), ('chip(x,top-103,','chip(x,top-95,'), ('segs(RX+22,top-125,','segs(RX+22,top-114,'), ] for a,b in R: assert a in s,a s=s.replace(a,b) open('poster.py','w').write(s) EOF python poster.py && python -c " import pdfplumber p=pdfplumber.open('English_Clause_Poster.pdf'); print(len(p.pages)) p.pages[0].to_image(resolution=70).save('poster_v2.png')"
English Clause Poster
PDF Document · PDF
Instead make a pdf for direct download
cd /tmp/workspace/clause-chart && python - <<'EOF' from pypdf import PdfReader, PdfWriter, Transformation, PageObject from reportlab.lib.pagesizes import A4 r=PdfReader("English_Clause_Poster.pdf"); src=r.pages[0] sw,sh=float(src.mediabox.width),float(src.mediabox.height) s=A4[0]/sw page=PageObject.create_blank_page(width=A4[0],height=A4[1]) page.merge_transformed_page(src,Transformation().scale(s,s)) w=PdfWriter(); w.add_page(page); w.add_metadata({"/Title":"The English Clause Chart"}) w.write("English_Clause_Chart_OnePage_A4.pdf") EOF python -c " import pdfplumber p=pdfplumber.open('English_Clause_Chart_OnePage_A4.pdf'); print(len(p.pages), p.pages[0].width, p.pages[0].height, len(p.pages[0].extract_text())) p.pages[0].to_image(resolution=50).save('a4_check.png')"; ls -la
English Clause Chart OnePage A4
PDF Document · PDF
English Clause Poster
PDF Document · PDF
English Clause Chart
PDF Document · PDF