How to write mathematics on Medium

Tyler Neylon
6 min readMar 17, 2016

--

Medium doesn’t have strong support for mathematical writing. However, it does work well with most unicode characters and offers enough control over images to allow a hard-working author to produce decent-looking mathematical expressions. I’ve written two mathy posts so far on Medium. I’ll tell you what I’ve learned in the process.

Since I use a mac, I’ll offer some mac-specific tips, but I hope most of this information will be useful no matter which platform you use.

Inline expressions

Variables like x and y can simply be italicized. Although they’re not as beautiful as a LaTeX-typeset expression, basic arithmetic operators can also work as simple text: i+j=n/4, keeping only the variables italicized.

A plethora of unicode characters can help expand your inline repertoire:

  • The triangle △abc with angle ∠abc
  • The distance ‖xy
  • The integer ⎣x/y
  • The sum ∑ 1/n² = π²/6
  • The set A∩(B∪C)
  • The vector operations ⟨u,v⟩ and u×v
  • The set ℝ³
  • The cardinality ℵ₀

If you use Chrome and know TeX’s math syntax, then you can use a browser extension called TeX to Unicode. You type an expression like \alpha\to\beta in your browser, and this extension converts it directly to α→β when you activate it. Thanks to Matthias Langer for telling me about this!

If you’re on a mac, many of these Unicode characters are available from your browser’s Edit > Emoji & Symbols menu, especially under the Math Symbols category:

Symbols can also be copy and pasted from other pages like this one. I occasionally copy Greek characters from here, and feebly attempt to memorize some of the mac keyboard shortcuts listed here.

Displayed expressions

In many cases, an inline expression can’t do what you’d like. If you want to say that

then it’s time to turn to images.

Unfortunately, Medium treats all images as resizable by default. This is probably reasonable behavior for most posts, but results in difficulty when it comes to an image that contains text. Many people read Medium posts from their phones, and many read from their laptops. The end result is a non-ignorable variety of screen widths which translates to images being resized disproportionately with text.

In short, equations in full-width images will be scaled in vastly different ways depending on how someone is reading your post:

The same post as seen on two different devices. The text in the image doesn’t scale with the main text.

A solution was suggested to me by Mike Sall: keep the images small enough that they have to be displayed at full resolution across devices. A file whose name ends in “@2x” will be treated as a retina image regardless of its width — thanks to Marcin Wichary for pointing that out. To be clear, an example of a full filename would be image@2x.png. Combining these two tricks — constrained image widths, and explicitly marking retina images if you want retina support — can help force in-image text to scale with regular text.

I found by experimentation that setting the width to around 300px will keep a single, centered image scaled well with the text of the post. The height doesn’t matter. Within images, I explicitly sized text based on the x-height of characters, which is the distance from the baseline to the top of the x character.

Here is a summary of relevant details for correctly sizing your images:

  • Single image width: 300px
  • Font: Charter
  • Font x-height: 10px
  • Width for 2-column grid: 505px
  • Width for 3-column grid: 333px

Since 300px is narrow, image grids can be useful to make better use of your space while avoiding wide images that scale poorly. If you use an image grid, keep in mind that the images will be arranged differently on different devices: typically in a row on a laptop browser, and in a column on a phone.

I’ve noticed that the default font used by LaTeX is close enough to italic Charter that the two can work reasonably well together.

Software to help generate math images

I generated many of my math expressions using LaTeXiT, which allows you to save an arbitrary LaTeX expression as an image file. With this tool, I typically use File > Export image to generate a PNG file at 200% scale, and then touch up that file in Photoshop to either add it to a composite image, or scale the text.

If you don’t have access to LaTeXiT, I imagine you could use standard LaTeX with screen captures of the resulting typeset math.

I recommend choosing a short English phrase to tag each image so you can easily match images with file names. Use that tag to save a primary psd file for a particular image. Different snapshots of an image can be saved as tag1.png, tag2.png, etc. There are more sophisticated ways to do this, but this approach is easy to learn and implement. I highly recommend keeping your psd file around because it’s much easier to edit a composite image with many small tweakable pieces than a monolithic png file.

Geometric diagrams

Occasionally, you may want to set up a diagram like this:

I’m far from an expert on software like Illustrator or Sketch, so please take my advice with a grain of salt. However, I found that working directly with SVG and JavaScript was a reasonable option. My workflow was to create an SVG file, take a screenshot from a browser, and then work with the resulting image — such as by adding more text to it—within Photoshop.

I liked working with the SVG format because it allowed me to specify mathematically precise coordinates and geometric relationships. It also allowed me to write functions that I could use across related diagrams, as well as with animations, which I’ll discuss below.

Here is some sample code I used to produce an SVG-based animated shown below. I found two functions to particularly simplify my code:

var svg = document.getElementById('svg')
var svgNS = svg.namespaceURI
function addAttributes(elt, attr) {
for (var key in attr) {
elt.setAttribute(key, attr[key])
}
return elt
}

function add(eltName, attr) {
var elt = document.createElementNS(svgNS, eltName)
svg.appendChild(elt)
if (attr) addAttributes(elt, attr)
return elt
}

These functions allowed me to easily add SVG elements from code:

var myStyle = {stroke: '#666', fill: 'transparent'}
var circle = add('circle', myStyle)
addAttributes(circle, {cx: 50, cy: 50, r: 10})

Mozilla’s SVG reference was indispensable.

Animations

Occasionally, you may want to set up an animation like this:

That’s a nice animation.

I produced my animations in three steps:

  • Set up an SVG animated via JavaScript,
  • screen capture the animation using QuickTime Player, and
  • gif-ify the resulting .mov file using GIFBrewery.

I also used ImageOptim to help reduce gif file sizes.

I recommend making animations appear smooth by having a short delay between frames.

I hope these tips have been useful. If I missed anything, please let me know. Better yet, I’d love to see the mathy stuff you’re posting!

--

--

Tyler Neylon

Founder of Unbox Research. Machine learning engineer. Previously at Primer, Medium, Google.