TidyText

Clean ChatGPT Text for Google Docs and Microsoft Word

Visit Website
September 30, 2024 TidyText.cc, copy paste to Google Docs, now with support for fractions

I’ve been crowdsourcing feedback on my new app, TidyText, via Reddit. Since I don’t have Microsoft Word, I decided to share it there to get feedback on how well it works (or doesn’t work). The first comment I received pointed out that fractions weren’t supported. I hadn’t really needed to render fractions in HTML before, aside from using basic tags like <sup>, but since ChatGPT outputs fractions using LaTeX syntax, it seemed doable.

Attempt 1: Marked.js with KaTeX

I use Marked.js for converting Markdown to HTML, I figured there was an extension that might meet my needs. I found marked-katex-extension, but soon after, I realized LaTeX does not render properly in Google Docs without using add-ons. That’s when I thought, “Maybe I should generate an image, like an SVG, so it would be lossless.” But then realized that KaTeX doesn’t support SVG.

This led me to use MathJax, which felt like overkill at first, but since it supports SVG, it turned out to be the necessary choice.

Attempt 2: MathJax

After the markdown attempt failed, I pivoted to MathJax to convert LaTeX into SVGs. The idea was that I could render the fractions as vector graphics and paste them into Google Docs. At least, that was the theory.

The integration with MathJax was relatively smooth, and I was able to generate SVG images for the fractions, which looked great on TidyText. But there was another problem: SVGs didn’t render in Google Docs.

The solution worked well visually within the app but fell short in Google Docs.

Attempt 3: Using Canvas API to convert the SVG to PNG

Since SVGs wouldn’t render in Google Docs, I ended up thinking about using the Canvas API to convert the SVG to a format that could be pasted in Google Docs. I wanted something that wouldn’t look compressed, so I ended up deciding on PNG (as opposed to JPEG). I ended up creating it at first and testing it out only to notice the resulting PNG images were blurry.

An image of the uncrispy fraction in TidyText

This fraction is not crispy!

I realized that I could scale up the image and then scale it back down in order to generate something that would appear extra crispy.

const img = new Image(); img.src = "data:image/svg+xml;base64," + btoa(svg); img.onload = () => { const scaleFactor = 3; const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); if (!ctx) return; canvas.width = img.width * scaleFactor; canvas.height = img.height * scaleFactor; ctx.scale(scaleFactor, scaleFactor); ctx.drawImage(img, 0, 0, img.width, img.height); // Convert canvas to PNG data URL const pngDataUrl = canvas.toDataURL("image/png"); const imageTag = <img src="${pngDataUrl}" alt="LaTeX formula" style="width:${img.width}px; height:${img.height}px;" />; };

Before and after, showing the uncrispy version in the before, and the crispy version in the after

Much better!

I then tested it using dark mode and noticed given these are images, the text needed to appear to be white, even though when copying to Google Docs, we’d want them to be black, so I decided to use the TailwindCSS dark mode variant to use a CSS filter to invert the text, that would then not carry over in the copied version.

An image showing the fraction with black text in dark mode

On the next episode of “Did you test it using dark mode?” 😅

TailwindCSS offers the filter invert and we can prepend it with dark: like so:

const imageTag = <img class=“dark:invert” id=”${uniqueId}” src=”${pngDataUrl}” alt=“LaTeX formula” style=“width:${img.width}px; height:${img.height}px;” />;

An animated gif showing TidyText in dark mode, successfully copying correctly to Google Docs

TailwindCSS dark:invert tada!

I did notice fractions don’t work in tables yet. Something for another day.

TLDR; Lessons learned

  • Markdown and LaTeX: not supported by Google Docs

  • MathJax: good for rendering formulas in SVGs

  • SVGs don’t render in Google Docs

  • Canvas API for SVG -> PNG conversion with scaling to keep text extra crispy.

  • CSS dark mode: being able to dynamically invert the image without affecting what the fraction would look like in Google Docs.

Next on the roadmap

Next on the roadmap (I think) is one-click Google Docs integration, but waiting on people to use the app and give feedback on features they actually want vs features I think they want, but really, I want. 🤓 🤪

Comment

September 24, 2024 I built a copy paste tool for ChatGPT and Google Docs called TidyText.cc

After working with ChatGPT and other AI tools, I realized that copying and pasting responses into Google Docs often messed up the formatting. Markdown is great for structured content, but dealing with the formatting cleanup? Not so much. 😅

Introducing TidyText

Features

  1. You can paste any text from ChatGPT (or elsewhere).

  2. It instantly converts the content into HTML that’s compatible with Google Docs.

  3. It provides a clean preview and lets you copy the result directly to your clipboard with one click.

Try it now

I built it using React, Vite, Web Workers (to handle processing of the markdown in the background), and DOMPurify for sanitizing input. I used TailwindCSS for the styling and everything is using TypeScript. It’s hosted using Cloudflare Pages.

🔧 Why build this?

  • I saw a simple problem I could solve for myself and make it simple and delightful.

  • I love a good mini app as a way of trying out something new (like Vite) and brushing up on my Web Workers skills.

  • Also I want to get more contracting clients.

💡 What’s next?

There’s Google Docs integration coming soon, so you’ll be able to generate and open documents directly in Google Docs without the extra step of copying.

If you’re using ChatGPT or any AI tool and need to quickly format content for Google Docs, TidyText is the tool for you! 🤖 🎉

Comment

About

TidyText was born out of the need to take the hassle out of copying ChatGPT outputs into Google Docs, ensuring that the text is well-formatted and ready to go, without having to manually clean it up.