from [Link].
pagesizes import A4
from [Link] import colors
from [Link] import mm
from [Link] import (SimpleDocTemplate, Paragraph, Spacer, Table,
TableStyle, HRFlowable, KeepTogether)
from [Link] import getSampleStyleSheet, ParagraphStyle
from [Link] import TA_LEFT, TA_CENTER
from [Link] import Flowable
import textwrap
W, H = A4
# ── COLOUR PALETTE
──────────────────────────────────────────────────────────
C_BG = [Link]("#F8F9FF")
C_HEADER = [Link]("#1A1A2E")
C_ACCENT = [Link]("#4F46E5")
C_ACCENT2 = [Link]("#7C3AED")
C_YOURS = [Link]("#0EA5E9")
C_HOT = [Link]("#10B981")
C_CARD_BG = [Link]("#FFFFFF")
C_CARD_BOR = [Link]("#E5E7EB")
C_TEXT = [Link]("#1F2937")
C_MUTED = [Link]("#6B7280")
C_BADGE = {
"AI Assistant": ("#EFF6FF","#1D4ED8"),
"Image & Design": ("#FDF2F8","#9D174D"),
"Video": ("#FFF7ED","#C2410C"),
"Audio & Voice": ("#ECFDF5","#065F46"),
"Coding": ("#F5F3FF","#4C1D95"),
"Content Writing": ("#FFFBEB","#92400E"),
"Productivity": ("#F0FDF4","#14532D"),
"Web & No-Code": ("#EFF6FF","#1E40AF"),
"Presentations": ("#FFF7ED","#9A3412"),
"SEO & Analytics": ("#ECFDF5","#064E3B"),
"Business Tools": ("#F0FDF4","#166534"),
"Client & Project Mgmt":("#F5F3FF","#3B0764"),
"Finance & Invoicing": ("#F0FDF4","#14532D"),
"Social Media": ("#FDF2F8","#831843"),
"Branding": ("#FFFBEB","#78350F"),
"Stock Media": ("#FFFBEB","#713F12"),
"Automation": ("#F5F3FF","#4C1D95"),
}
# ── ALL TOOLS
────────────────────────────────────────────────────────────────
TOOLS = [
# YOUR TOOLS
("🎨","Pixel AI","Image & Design","AI image generation & pixel art
creation","yours"),
("📷","QR Code Money","Business Tools","Generate QR codes for payments &
links","yours"),
("📊","Google Sheets AI","Productivity","AI formulas, data analysis &
automation in spreadsheets","yours"),
("🌐","[Link]","Web & No-Code","Generate full websites with AI in
seconds","yours"),
("","[Link]","Presentations","AI-powered slide design & deck
creation","yours"),
("🔠","Looka","Branding","AI logo & brand identity designer","yours"),
("📈","Social Blade","Social Media","Track YouTube, Instagram & social media
analytics","yours"),
("🔍","SimilarWeb","SEO & Analytics","Website traffic & competitor research
tool","yours"),
("","Pixabay","Stock Media","Free AI-tagged stock photos, videos &
music","yours"),
("📸","Shutterstock","Stock Media","Premium stock photos & AI image
generator","yours"),
("⬛","Blackbox AI","Coding","AI coding assistant — autocomplete, debug &
explain code","yours"),
("🏢","Odoo","Client & Project Mgmt","ERP: CRM, invoicing, HR & project
management","yours"),
# AI ASSISTANTS
("💬","ChatGPT","AI Assistant","Conversational AI for writing, research,
coding & more","hot"),
("🤖","Claude","AI Assistant","Deep writing, analysis, coding & long
documents","hot"),
("✨","Gemini","AI Assistant","Google AI integrated with Gmail & Docs","hot"),
("🔎","Perplexity AI","AI Assistant","AI search engine with cited real-time
answers","hot"),
("🪟","Microsoft Copilot","AI Assistant","AI assistant built into Windows &
Office 365",""),
("🐦","Poe","AI Assistant","Access ChatGPT, Claude, Gemini in one app",""),
# SOCIAL MEDIA
("📅","Buffer","Social Media","Schedule & publish posts across all
platforms","hot"),
("📣","Hootsuite AI","Social Media","AI social media scheduler & analytics
dashboard","hot"),
("📲","Later","Social Media","Visual Instagram & TikTok planner &
scheduler",""),
("📉","Metricool","Social Media","All-in-one social analytics & scheduling
tool","hot"),
("💼","Taplio","Social Media","AI LinkedIn content creator & scheduler",""),
("","Flick AI","Social Media","AI hashtag research & caption writer",""),
("🤳","[Link]","Social Media","Generate social media posts & reels with
AI","hot"),
("📮","Publer","Social Media","Social media scheduler with AI caption
writing",""),
# CONTENT WRITING & SEO
("","Jasper AI","Content Writing","AI blog writer for long-form content &
SEO","hot"),
("📋","[Link]","Content Writing","AI copywriting: ads, emails, landing
pages","hot"),
("📄","Writesonic","Content Writing","AI article & SEO content writer",""),
("✍️
","Grammarly","Content Writing","AI grammar, tone & clarity
checker","hot"),
("🔄","QuillBot","Content Writing","AI paraphraser, summarizer & grammar
fixer","hot"),
("📝","Rytr","Content Writing","Budget-friendly AI writing assistant",""),
("🏄","Surfer SEO","SEO & Analytics","AI SEO content optimizer & keyword
planner","hot"),
("📡","SEMrush","SEO & Analytics","Full SEO suite: keywords, backlinks &
audits","hot"),
("🔗","Ahrefs","SEO & Analytics","Backlink analysis, keyword & site audit
tool",""),
("💡","Ubersuggest","SEO & Analytics","Free keyword research & SEO audit
tool",""),
("","Google Search Console","SEO & Analytics","Monitor site performance in
Google Search","hot"),
("🏆","Rank Math","SEO & Analytics","AI SEO plugin for WordPress
websites",""),
# WEB DEV & CODING
("💻","GitHub Copilot","Coding","AI pair programmer inside VS Code &
IDEs","hot"),
("","Cursor","Coding","AI-first code editor with full project
context","hot"),
("⚡","Replit AI","Coding","Code, run & deploy apps in browser with AI",""),
("🧩","v0 by Vercel","Web & No-Code","Generate React UI from text prompts
instantly","hot"),
("","Framer AI","Web & No-Code","AI website builder with animations &
CMS","hot"),
("🫧","Bubble","Web & No-Code","Build full web apps without code",""),
("🌊","Webflow AI","Web & No-Code","Professional web design & CMS with
AI","hot"),
("","Durable AI","Web & No-Code","Build a business website with AI in 30
seconds",""),
("🖧","Hostinger AI","Web & No-Code","AI website builder + hosting +
domain",""),
# CLIENT & PROJECT MGMT
("📒","Notion AI","Client & Project Mgmt","AI docs, wikis, tasks & project
planning","hot"),
("","Trello","Client & Project Mgmt","Visual Kanban board for managing client
tasks",""),
("✅","ClickUp AI","Client & Project Mgmt","AI task manager, docs & time
tracker","hot"),
("🎯","Asana","Client & Project Mgmt","Project & deadline tracker for client
work",""),
("📆","[Link]","Client & Project Mgmt","Team & freelance project
management platform",""),
("📹","Loom AI","Client & Project Mgmt","Screen record & share video updates
to clients","hot"),
("🎤","[Link]","Client & Project Mgmt","AI meeting transcription & auto-
summary",""),
("📅","Calendly","Client & Project Mgmt","Automated meeting scheduler &
booking page","hot"),
("💬","Slack","Client & Project Mgmt","Team & client communication hub",""),
# FINANCE & INVOICING
("💚","Fiverr","Finance & Invoicing","Top freelance marketplace to find & sell
services","hot"),
("🔵","Upwork","Finance & Invoicing","Find high-paying freelance clients &
projects","hot"),
("💳","Payoneer","Finance & Invoicing","Receive international payments from
clients","hot"),
("🏦","Razorpay","Finance & Invoicing","Accept payments & invoicing for Indian
freelancers","hot"),
("🧾","Invoice Ninja","Finance & Invoicing","Free open-source invoicing &
client management",""),
("🌊","Wave","Finance & Invoicing","Free accounting, invoices & receipts for
freelancers","hot"),
("📑","Zoho Invoice","Finance & Invoicing","Free professional invoicing
tool",""),
("📗","FreshBooks","Finance & Invoicing","Freelance accounting, time tracking
& invoicing",""),
("","PayPal","Finance & Invoicing","Send invoices & receive global
payments","hot"),
# IMAGE & DESIGN
("🎨","Canva AI","Image & Design","AI design, Magic Edit & social media
graphics","hot"),
("","Midjourney","Image & Design","High-quality AI art & image
generation","hot"),
("🔥","Adobe Firefly","Image & Design","AI image & vector generation inside
Adobe",""),
("✂️","[Link]","Image & Design","Remove image backgrounds instantly with
AI","hot"),
("🔭","Upscayl","Image & Design","Free AI image upscaler — 4x resolution
boost",""),
("","Ideogram AI","Image & Design","AI image gen with accurate text
rendering","hot"),
("","Adobe Express","Image & Design","Quick social graphics, logos & video
clips",""),
# VIDEO
("✂️","CapCut AI","Video","AI video editor with captions, effects &
templates","hot"),
("","HeyGen","Video","AI avatar video creator for explainers & ads","hot"),
("🎬","Runway ML","Video","AI video generation, editing & VFX",""),
("📺","Synthesia","Video","Create AI presenter videos without a camera",""),
("","InVideo AI","Video","Create marketing videos from text prompts","hot"),
("","Descript","Video","Edit video by editing the text transcript",""),
# AUDIO
("","ElevenLabs","Audio & Voice","Ultra-realistic AI voice cloning & text-to-
speech","hot"),
("🔊","Murf AI","Audio & Voice","AI voiceover generator for videos &
podcasts",""),
("🎵","Suno AI","Audio & Voice","Generate full songs with vocals using
AI",""),
("🎧","Adobe Podcast","Audio & Voice","AI podcast enhancement & noise
removal",""),
# AUTOMATION & PRODUCTIVITY
("⚙️","Zapier AI","Automation","Automate workflows across 6000+ apps","hot"),
("🔗","[Link]","Automation","Visual automation builder for complex
workflows","hot"),
("📋","Typeform","Productivity","AI-generated forms, surveys & lead
capture",""),
("💡","[Link]","Presentations","Create AI decks, docs & webpages
instantly","hot"),
("📖","Tome","Presentations","AI-powered storytelling & presentation
builder",""),
("","Notion Calendar","Productivity","Smart calendar that connects to your
Notion tasks",""),
]
# Group by category
from collections import OrderedDict
CAT_ORDER = [
"AI Assistant","Social Media","Content Writing","SEO & Analytics",
"Coding","Web & No-Code","Client & Project Mgmt","Finance & Invoicing",
"Image & Design","Video","Audio & Voice","Automation","Presentations",
"Productivity","Branding","Stock Media","Business Tools"
]
grouped = OrderedDict()
for cat in CAT_ORDER:
grouped[cat] = []
for t in TOOLS:
cat = t[2]
if cat not in grouped:
grouped[cat] = []
grouped[cat].append(t)
# ── CUSTOM FLOWABLES
─────────────────────────────────────────────────────────
class ColorRect(Flowable):
def __init__(self, w, h, fill, radius=4):
super().__init__()
self.w, self.h, [Link], [Link] = w, h, fill, radius
def draw(self):
[Link]([Link])
[Link](0, 0, self.w, self.h, [Link], stroke=0, fill=1)
class ToolCard(Flowable):
"""One tool card: emoji circle + name + badge + description"""
def __init__(self, emoji, name, category, desc, tag, page_width):
super().__init__()
[Link] = emoji
[Link] = name
[Link] = category
[Link] = desc
[Link] = tag # 'yours', 'hot', ''
[Link] = page_width
self.card_h = 62
[Link] = page_width
[Link] = self.card_h + 4
def draw(self):
c = [Link]
cw = [Link]
ch = self.card_h
# Card background
[Link]([Link]("#FFFFFF"))
[Link]([Link]("#E5E7EB"))
[Link](0.5)
[Link](0, 0, cw, ch, 6, stroke=1, fill=1)
# Left accent stripe
if [Link] == "yours":
[Link]([Link]("#0EA5E9"))
elif [Link] == "hot":
[Link]([Link]("#10B981"))
else:
[Link]([Link]("#E5E7EB"))
[Link](0, 0, 4, ch, 3, stroke=0, fill=1)
# Emoji circle
cx, cy = 28, ch // 2
[Link]([Link]("#F3F4F6"))
[Link](cx, cy, 18, stroke=0, fill=1)
[Link]("Helvetica", 18)
try:
[Link](cx, cy - 6, [Link])
except:
[Link]([Link]("#6B7280"))
[Link](cx, cy - 5, "AI")
# Tool name
[Link]("Helvetica-Bold", 11)
[Link]([Link]("#111827"))
[Link](54, ch - 18, [Link][:28])
# Category badge
bg_hex, txt_hex = C_BADGE.get([Link], ("#F3F4F6","#374151"))
badge_text = [Link]
[Link]("Helvetica", 7)
badge_w = [Link](badge_text, "Helvetica", 7) + 10
bx = 54
by = ch - 32
[Link]([Link](bg_hex))
[Link](bx, by, badge_w, 11, 3, stroke=0, fill=1)
[Link]([Link](txt_hex))
[Link](bx + 5, by + 2.5, badge_text)
# Tag label
if [Link] == "yours":
lbl, lbg, ltx = "YOUR TOOL", "#DBEAFE", "#1D4ED8"
elif [Link] == "hot":
lbl, lbg, ltx = "MUST HAVE", "#D1FAE5", "#065F46"
else:
lbl, lbg, ltx = None, None, None
if lbl:
[Link]("Helvetica-Bold", 6.5)
lw = [Link](lbl, "Helvetica-Bold", 6.5) + 10
lx = cw - lw - 8
[Link]([Link](lbg))
[Link](lx, ch - 20, lw, 12, 3, stroke=0, fill=1)
[Link]([Link](ltx))
[Link](lx + 5, ch - 14, lbl)
# Description
[Link]("Helvetica", 8.5)
[Link]([Link]("#4B5563"))
# wrap text
max_w = cw - 60
words = [Link]()
lines = []
cur = ""
for w in words:
test = (cur + " " + w).strip()
if [Link](test, "Helvetica", 8.5) < max_w:
cur = test
else:
if cur: [Link](cur)
cur = w
if cur: [Link](cur)
for i, line in enumerate(lines[:2]):
[Link](54, ch - 46 - i * 11, line)
# ── BUILD PDF
────────────────────────────────────────────────────────────────
def build():
path = "/mnt/user-data/outputs/AI_Tools_Freelance_Guide.pdf"
margin = 14*mm
doc = SimpleDocTemplate(
path, pagesize=A4,
leftMargin=margin, rightMargin=margin,
topMargin=14*mm, bottomMargin=14*mm
)
usable_w = A4[0] - 2*margin
styles = getSampleStyleSheet()
story = []
# ── COVER PAGE ───────────────────────────────────────────────────────────
[Link](Spacer(1, 20*mm))
# Big header block
cover_data = [[
Paragraph(
'<font color="#FFFFFF" size="26"><b>Ultimate AI Tools Guide</b></font><br/>'
'<font color="#C7D2FE" size="13">for Freelancers — Digital Marketing,
Content, SEO & Web Dev</font>',
ParagraphStyle("ch", fontName="Helvetica", leading=28, alignment=TA_CENTER)
)
]]
cover_tbl = Table(cover_data, colWidths=[usable_w])
cover_tbl.setStyle(TableStyle([
("BACKGROUND", (0,0),(0,0), [Link]("#4F46E5")),
("ROUNDEDCORNERS", [10]),
("TOPPADDING", (0,0),(-1,-1), 22),
("BOTTOMPADDING",(0,0),(-1,-1), 22),
("LEFTPADDING", (0,0),(-1,-1), 20),
("RIGHTPADDING",(0,0),(-1,-1), 20),
]))
[Link](cover_tbl)
[Link](Spacer(1, 6*mm))
# Stats row
total = len(TOOLS)
yours_c = sum(1 for t in TOOLS if t[4]=="yours")
hot_c = sum(1 for t in TOOLS if t[4]=="hot")
cats_c = len([c for c in grouped if grouped[c]])
stat_style = ParagraphStyle("stat", fontName="Helvetica-Bold", fontSize=20,
textColor=[Link]("#4F46E5"), alignment=TA_CENTER)
lbl_style = ParagraphStyle("lbl", fontName="Helvetica", fontSize=9,
textColor=[Link]("#6B7280"), alignment=TA_CENTER)
stats = [
[Paragraph(str(total), stat_style), Paragraph(str(yours_c), stat_style),
Paragraph(str(hot_c), stat_style), Paragraph(str(cats_c), stat_style)],
[Paragraph("Total Tools", lbl_style), Paragraph("Your Tools", lbl_style),
Paragraph("Must-Have", lbl_style), Paragraph("Categories", lbl_style)],
]
stat_tbl = Table(stats, colWidths=[usable_w/4]*4, rowHeights=[28,16])
stat_tbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(-1,-1), [Link]("#F9FAFB")),
("BOX",(0,0),(-1,-1),0.5, [Link]("#E5E7EB")),
("ROUNDEDCORNERS",[8]),
("TOPPADDING",(0,0),(-1,-1),10),
("BOTTOMPADDING",(0,0),(-1,-1),6),
]))
[Link](stat_tbl)
[Link](Spacer(1, 5*mm))
# Legend
leg_style = ParagraphStyle("leg", fontName="Helvetica", fontSize=9,
textColor=[Link]("#374151"), alignment=TA_CENTER)
leg_data = [[
Paragraph('<font color="#0EA5E9">■</font> Blue stripe = Your current tool',
leg_style),
Paragraph('<font color="#10B981">■</font> Green stripe = Must-have addition',
leg_style),
Paragraph('No stripe = Bonus tool', leg_style),
]]
leg_tbl = Table(leg_data, colWidths=[usable_w/3]*3)
leg_tbl.setStyle(TableStyle([("TOPPADDING",(0,0),(-1,-1),4),("BOTTOMPADDING",
(0,0),(-1,-1),4)]))
[Link](leg_tbl)
[Link](Spacer(1, 8*mm))
# ── CATEGORY SECTIONS ────────────────────────────────────────────────────
cat_title_style = ParagraphStyle(
"cattitle", fontName="Helvetica-Bold", fontSize=13,
textColor=[Link]("#FFFFFF"), spaceAfter=4
)
for cat in CAT_ORDER:
tools = [Link](cat, [])
if not tools:
continue
section = []
# Category header
bg_hex, txt_hex = C_BADGE.get(cat, ("#4F46E5","#FFFFFF"))
# darken bg for header
hdr_data = [[Paragraph(
f'<font color="{txt_hex}" size="12"><b>{cat}</b></font>'
f'<font color="{txt_hex}" size="9"> · {len(tools)} tools</font>',
ParagraphStyle("hh", fontName="Helvetica-Bold", fontSize=12, leading=16)
)]]
hdr_tbl = Table(hdr_data, colWidths=[usable_w])
hdr_tbl.setStyle(TableStyle([
("BACKGROUND",(0,0),(0,0), [Link](bg_hex)),
("ROUNDEDCORNERS",[6]),
("TOPPADDING",(0,0),(-1,-1),8),
("BOTTOMPADDING",(0,0),(-1,-1),8),
("LEFTPADDING",(0,0),(-1,-1),12),
]))
[Link](hdr_tbl)
[Link](Spacer(1, 3))
# 2-column grid of tool cards
card_w = (usable_w - 6) / 2
pairs = [tools[i:i+2] for i in range(0, len(tools), 2)]
for pair in pairs:
row_cells = []
for t in pair:
card = ToolCard(t[0], t[1], t[2], t[3], t[4], card_w)
row_cells.append(card)
if len(row_cells) == 1:
row_cells.append(Spacer(card_w, 1))
pair_tbl = Table([row_cells], colWidths=[card_w, card_w], rowHeights=[66])
pair_tbl.setStyle(TableStyle([
("TOPPADDING",(0,0),(-1,-1),0),
("BOTTOMPADDING",(0,0),(-1,-1),0),
("LEFTPADDING",(0,0),(-1,-1),0),
("RIGHTPADDING",(0,0),(-1,-1),3),
("VALIGN",(0,0),(-1,-1),"TOP"),
]))
[Link](pair_tbl)
[Link](Spacer(1, 4))
[Link](Spacer(1, 5*mm))
[Link](KeepTogether(section[:6])) # keep header + first few cards
[Link](section[6:])
# ── FOOTER PAGE ──────────────────────────────────────────────────────────
[Link](HRFlowable(width=usable_w, color=[Link]("#E5E7EB")))
[Link](Spacer(1,4*mm))
footer_style = ParagraphStyle("foot", fontName="Helvetica", fontSize=9,
textColor=[Link]("#9CA3AF"), alignment=TA_CENTER)
[Link](Paragraph("Ultimate AI Tools Guide for Freelancers · Digital
Marketing · Content Writing · SEO · Web Dev", footer_style))
[Link](Paragraph("90+ tools curated for modern freelancing workflows",
footer_style))
# Page number callback
def add_page_number(canvas, doc):
[Link]()
[Link]("Helvetica", 8)
[Link]([Link]("#9CA3AF"))
[Link](A4[0]-14*mm, 8*mm, f"Page {[Link]}")
# Header line on non-first pages
if [Link] > 1:
[Link]([Link]("#E5E7EB"))
[Link](0.5)
[Link](14*mm, A4[1]-10*mm, A4[0]-14*mm, A4[1]-10*mm)
[Link]("Helvetica-Bold", 8)
[Link]([Link]("#4F46E5"))
[Link](14*mm, A4[1]-8*mm, "AI Tools Guide for Freelancers")
[Link]()
[Link](story, onFirstPage=add_page_number, onLaterPages=add_page_number)
print(f"✅ PDF created: {path}")
return path
build()
1. You’ve hit your limit for Claude messages. Limits will reset at
3:40 AM. For higher limits, explore our Pro plan.