When Threads Silences Your Temple Bell
How a century-old daily ritual met a modern platform algorithm — and a Node.js script won.
The Daily Ritual
Every morning, before sunrise, a panchangam — the sacred Hindu almanac — is compiled and shared across WhatsApp groups, Instagram pages, and social media feeds. It lists the tithi (lunar day), nakshatra (star), auspicious times, and the daily sankalpam that devout families recite before prayers. For thousands of families, this small block of text is as essential as morning coffee.
Nagai Narasimhan, who has been compiling and sharing this daily almanac for years, encountered a strange wall: Threads kept silently suppressing his posts. Every other platform — Instagram, WhatsApp, Facebook — accepted the content without complaint. But Threads? Crickets.
"The panchangam reaches people who depend on it daily. An algorithm shouldn't decide whether someone knows Rahu Kalam today."
Why Threads Blocks It
Threads (and many other platforms) run text through natural language classifiers at upload time. These systems look for patterns: density of non-Latin Unicode characters, repetition, structured formatting, or blocks of religious text that may trigger overzealous spam filters. The panchangam, written in a Tamil-English mix with diacritical characters, structured time tables, and repeated formatting marks like ===== — ticks many of those boxes.
The irony is sharp: this is not spam. It is a curated cultural document, hand-compiled daily. But the algorithm sees patterns, not intent.
Text classifiers on social platforms operate on Unicode character distributions and formatting heuristics. Dense Tamil script mixed with structured repeated symbols closely resembles patterns associated with bulk/spam posting — regardless of the actual content.
The Fix: Render Text as an Image
The solution is elegantly simple. If the platform can't read your text, don't give it text. Render your content onto a canvas as pixels — to a human it is perfectly legible; to a text classifier, it is just a JPEG.
The Code
The implementation uses the canvas npm package, which provides a Node.js binding to the Cairo graphics library — the same engine behind most Linux desktop rendering. Here's the full script:
// install with: npm install canvas const { createCanvas } = require('canvas'); const fs = require('fs'); const path = require('path'); // Read the panchangam text file const text = fs.readFileSync( path.join(__dirname, 'panchangam.txt'), 'utf8' ); const lines = text.split('\n'); const width = 800; const lineHeight = 30; // Dynamic height — grows with content const height = (lines.length * lineHeight) + 40; const canvas = createCanvas(width, height); const ctx = canvas.getContext('2d'); // White background ctx.fillStyle = '#fff'; ctx.fillRect(0, 0, width, height); // Text styling — use a Unicode-capable font ctx.fillStyle = '#000'; ctx.font = '20px "Nirmala UI", "Latha", Arial, sans-serif'; ctx.textBaseline = 'top'; // Draw each line let y = 20; for (const line of lines) { ctx.fillText(line, 20, y); y += lineHeight; } // Save as PNG const buffer = canvas.toBuffer('image/png'); fs.writeFileSync('panchangam.png', buffer); console.log('Image saved as panchangam.png');
How It Works — Line by Line
1. Reading the Source File
The script reads panchangam.txt synchronously and splits it by newline. Each line becomes one row on the canvas. This approach handles both Tamil and English text in the same document, because the rendering is purely graphical — no encoding translation needed.
2. Dynamic Canvas Height
Rather than hardcoding an image size, the height is calculated as (number of lines × 30px) + 40px padding. This means the script adapts automatically — a short day with few auspicious timings and a long day with a detailed sankalpam both produce correctly-sized images.
3. Font Selection Matters
The font stack "Nirmala UI", "Latha", Arial is deliberate. Nirmala UI and Latha are system fonts on Windows that have full coverage of Tamil Unicode. On Linux/Mac servers, you may need to install a Tamil font and register it explicitly with the canvas library:
const { registerFont } = require('canvas'); registerFont('./fonts/Latha.ttf', { family: 'Latha' }); // Call BEFORE createCanvas()
4. The PNG Output
canvas.toBuffer('image/png') produces a lossless PNG. This is important for text — JPEG compression creates artefacts around sharp character edges (ringing), making Tamil letterforms harder to read. PNG keeps every pixel crisp.
Broader Applications
This pattern — text → canvas → image — has a long history and many legitimate uses:
- Daily almanacs & religious content in minority-script languages that trip spam filters
- Watermarked quotations — render text with a logo overlay that plain text cannot carry
- Code screenshots in the style of Carbon.sh, for sharing syntax-highlighted snippets visually
- Infographic text cards with custom backgrounds and branding, generated server-side at scale
- OG images (Open Graph) — auto-generated preview cards for blog posts using the same canvas approach
Accessibility Note
One tradeoff of this approach is that the text is no longer machine-readable inside the image. Screen readers cannot parse it, and search engines won't index the content. Best practice when using this technique: always include the full text in the post caption or as alt text on the image. Threads and Instagram both support alt text on images — fill it in. The algorithm won't block it; the content lives as pixels. But your audience who needs accessibility support, and search crawlers, can still find the text.
- Image rendered with a Unicode-capable font
- Saved as PNG (not JPEG) for sharp text
- Alt text filled with the full original text
- Caption includes key timings for quick scanning
Running It Daily — Automation
The final step is making this effortless. On any Linux/Mac system, a single cron job handles it:
30 5 * * * cd /home/user/panchangam && node texttoimage.js
Pair this with a social media scheduling tool (Buffer, Meta Business Suite, or a custom Threads API integration) and the image posts itself — every day, without manual intervention, without tripping any classifier.
Closing Thought
There is something quietly poetic about this solution. Sanskrit and Tamil have been encoded in stone, palm leaf, and paper for thousands of years. Today, a few lines of JavaScript encode them as pixels to slip past a neural network. The medium changes; the message endures.
If you maintain a community page that shares culturally specific content in non-Latin scripts and you've hit similar walls — this technique works. It's three npm installs and fifty lines of code. The daily panchangam will reach its readers.
![[Lavanya Deepak]](http://img.photobucket.com/albums/v31/vdeepakkumar/lvdp.gif)

![[Microsoft Certified Professional]](http://img12.photobucket.com/albums/v31/vdeepakkumar/mcp.gif)


