Streamlining Anki with LaTeX

I recently started using Anki (open source spaced repetition flashcard tool) for reviewing, learning, and remembering technical material that I’ve learned over the years. Given the nature of optimization, machine learning, control theory, etc., it’s usually the case that I want to easily include expressions/equations in my flashcards. By default, any LaTeX code in an Anki flashcard needs to be wrapped in [latex] [/latex] tags, which is cumbersome and leads to stylistic inconsistencies. Additionally, in order to use your own custom commands and common packages, by default, they need to be added manually to an Anki note type header; that is, you cannot include them with an input{} command. This makes maintaining these commands cumbersome.

So, the solution is to
1. configure Anki to use LaTeX as its default typesetting system (the default Anki card editor is a light WYSIWYG editor), and
2. create and install a custom package that allows you to use and, importantly, maintain your custom commands with Anki.
Let’s go through how to setup both.


This tutorial assumes that you have installed
– LaTeX distribution (e.g. for OSX, Windows).

LaTeX as Anki’s default typesetting system [1]

Create a LaTeX note type

  1. Tools > Manage Note Types > Add
  2. Select “Add: Basic”
  3. Name: LaTeX

Modify the card format

Find “LaTeX” in the Note Types dialog list. Select “Cards…” button. Now surround the {{Front}} and {{Back}} tags in [latex] [/latex] tags, and add your preferred styling to the cards. (Sorry, you’ll have to remove the space in [ latex] in the instructions below because the same tag convert text to LaTeX in these posts too.)

Front Template:

[ latex]{{Front}}[/latex]


.card {
font-family: arial;
font-size: 10px;
text-align: center;
color: black;
background-color: white;
img {
width: auto;
height: auto;

Back Template:

<hr id=answer>
[ latex]{{Back}}[/latex]

Custom commands in LaTeX note type

The next thing you’ll want to do is modify your LaTeX note type’s Header and Footer with the commands you commonly use. To edit the Header/Footer, return to the Note Types dialog and select “Options…”. The default looks like this:


\usepackage[paperwidth=5in, paperheight=100in]{geometry}



Creating your own LaTeX package [2]

While adding your commonly used packages and commands is useful, I like to maintain a common set of commands/packages that I can simply include in my new documents (without needing to update the Header/Footer in Anki every time I add something new). However, by default, Anki does not allow for input or def in its preamble, so including your (self-updating) custom and usual commands is not so straightforward. Fortunately, you can include your commands in a custom LaTeX package and invoke that package instead. For example, a LaTeX package called giraffemath.sty is defined by including the line \ProvidesPackage{giraffemath}. Here is a barebones example:


Installing and including the package [3]

Now, let’s add your custom package(s) to your local latex packages directory. We’ll first create a directory to house all your custom packages, and then we’ll symlink it to your local distribution installation directory’s texmf-dist subdirectory. On my machine (OSX), my path is /usr/local/texlive/2013/texmf-dist.

mkdir ~/Dropbox/custom-tex-packages
cp giraffemath.sty ~/Dropbox/custom-tex-packages
ln -s ~/Dropbox/custom-tex-packages/ `kpsewhich -var-value TEXMFHOME`/tex/latex/custom-tex-packages

Refreshing the LaTeX tree [4]

Next, we will need to refresh the tex packages to pick up the changes you have made to the packages. NOTE: You will need to run this command each time you make a change to your custom packages.

sudo texhash
sudo mktexlsr

Adding your package to the Anki note type header

Last but not least, add your package to the LaTex preamble. Your new header may look like this:


\usepackage[paperwidth=5in, paperheight=100in]{geometry}



Adding a new note

That’s it! Now when you create a new Anki card, you can choose LaTeX as your note type. LaTeX away! (Wrap inline math in $$.) Here’s an example:

Screen Shot 2015-11-06 at 10.52.04 PM - anki example

And the card looks like this:
Screen Shot 2015-11-06 at 10.54.03 PM - anki preview

Adventures in Hydroponics (Weeks 23-26)

Automation edition

Well, another semester has gone by (time flies!). Let’s see what happened to the garden!

Day 163 (Nov 28, 2014)
Things got busy and winter came! Wind and temperature weren’t being super kind to my plants, so they took refuge in our living room. Which might turn into a permanent home — we’ll see. Anyway, the semester rolls along and the plants continue to get bigger.

But the question is: where is the promised automation? Wasn’t that the point all along? So, here’s the start of the water automation. First step: water drainage from the trays. Look, a first water test!

Day 178 (Dec 13, 2014)
First things first: prepping the system.

Fixing the drainage tubes to the trays resembles good soldering practice: a solid mechanical connection, along with good electrical connection (with solder). Here, that means, respectively: physically putting the 0.25″ tube through a hole in the tray and splitting the top end, and then attaching the tube from both top and bottom to the tray (with glue).

My system consists of one feeder tube per plant. With so many feeder tubes, it’s important to maintain sufficient pressure inside each tube. These fittings restrict the outflow, which did the trick. The long pieces are stakes, which position the feeder tubes.

Day 179 (Dec 14, 2014)
The water automation system itself is an open loop closed system. That is, water pumps out of this 20 gallon reservoir into a main 0.5″ tube, which runs out to 0.25″ feeder tubes to each plant. The extra water sinks to the bottom of the tray, which drains back into the reservoir. Remember: safety first!

Day 181 (Dec 16, 2014)
With 7 hours before I take off for Seattle, there are two outstanding issues: the system needs a timer and sometimes the trays don’t drain. Eep!

Good thing duct tape fixes many things. When the drainage tubes are submerged in the reservoir and there is air sitting in the tube, there is simultaneous atmospheric pressure from both the reservoir and the plant tray. The pressure from the plant tray is insufficient for forcing the water out of the drainage tube, so the water does not drain (thanks Joey, for the explanation!). Solution? Don’t submerge the drainage tubes in water in the first place.

The timer was easy enough too to set up. 1 minute watering, twice per day is what we decided.

And last but not least, I filled up the reservoir, dumped in some nutrients, and it’s ready to go!

Until next year, plants! I’m leaving you in good hands with Philipp, in case the system decides to take over the house! (Thanks Philipp!)

Adventures in Hydroponics (Weeks 6-13)

Wildlife edition

In which my plants meet wildlife or just naturally fail to grow.

Day 44 (July 29, 2014)
When I go away on vacation, some opportunistic caterpillars visit and eat all of the watercress. Like, all of it. Ma’ayan snaps up some evidence! (Also super special thanks to Ma’ayan for babysitting while I am away!!) I expect that the watercress is mostly done for, but I keep watering it anyway.
Yes, I’m approximating the day count at this point.

Day 48 (Aug 03, 2014)
I’ve return to Berkeley to living and well plants, except for the poor watercress. (Yayyy basil and parsley growing up.)

Day 60 (Aug 15, 2014)
Dear cilantro, I really insist you stand up straight. (Spoiler alert: they die. Turns out cilantro is notoriously difficult to grow.)

Day 75 (Sep 01, 2014)
I’m learning all about Berkeley wildlife, which is pretty exciting. My basil plant is attacked by what I suspect to be a squirrel. It dug up the rockwool, leaving a mess and the roots of the plant exposed. I promptly stick the rockwool back into the cube as best I can and proceed to wait and see what happens.


Day 89 (Sep 14, 2014)
Oh dang, it’s the return of the watercress, 1.5 months after the ravaging. No special treatment, just water and nutrients at normal intervals (and the Bay Area climate).

Parsley and basil are doing well too.


Cilantro still struggling though. They realllllly want to reach the sun. I believe these are attempt 35 or so to grow cilantro (which also fail).

Adventures in Hydroponics (Weeks 2-5)

Day 24 (July 8, 2014)
The watercress children got big, time to transplant! [In the meantime, I screwed up and lost a bunch of baby plants. Let’s call it survival of the fittest.]

There we go, transplanted! So much room for roots to grow.

I transplanted a few more babies and prototyped a tiny irrigation system. Ah yes, a series of tubes. And I’ve got my own terrace farm. 🙂

The baby basil, California poppies, and wildflowers (new!), with their own water tubes!

Day 27 (July 11, 2014)
Just chillin’. The previous shots were a prototype system, so I removed everything except the stakes (black water tube holders). I planted some wildflowers and chives in soil too, and the first soiling sprouted!

Day 34 (July 18, 2014)
Oh man, the watercress is so delicious that the insects want some too!

Basil’s starting to look like basil.

And we’ve got some new babies (parsley)!

[Special thanks to Jacob for the prototyping bucket and to Kevin/Irena for the wildflower seeds!]

Adventures in hydroponics (Week 1)

Day 1 (June 15, 2014)
Berkeley has an awesome hydroponics store! Turns out, getting started with hydroponics is really easy. Buying and planting everything took Eric and me just a few hours. See the end for a build of materials and a comparison with soil!

Day1-SeedsOn the menu are: arugula, basil, California poppy (I guess I won’t eat these..), (chinese) garlic chives, parsley, soy bean, and watercress!

Day1-My own little farm45 little plots for my own little farm. 🙂 These modular “grow blocks” are a synthetic material from molten rock in which the plants take root.

Day1-Chive seedlingI had pre-germinated the garlic chives, so they get a head start of a week or two (hard to see, but you can see one sprout if you zoom in!).

Day 5 – June 19, 2014
Day5-ChivesGrow, chives, grow!

Day 7 – June 21, 2014
Day7-ArugulaBaby arugula.

Day7-SoyBaby soy!

Day7-So many seedlingsSooo many babies.

Appendix I: Cost analysis
(Rough) build of materials
$2 – “Nursery” tray for the plants
$8 – Concentrated plant nutrients (Botanicare CNS17, 1qt)
$7 – pH test kit
$10 – Growing media (45 stonewool blocks, Grodan mini Gro Blocks, $0.21ea)
$14 – Misc seeds
$?? – A lemon
$41 – Total

As compared with growing with soil, from a quick home depot search:
$8 – Potting mix (soil + fertilizer)
$21 – Plaster planter boxes (24in, 3x)
$14 – Misc seeds
$43 – Total

Both are spec’ed for about 6 months of growing for 7 types of plants (45 individual plants via hydroponics, probably fewer than that for soil due to space) and with no consideration for permanent planters or automation. So the material costs can be comparable at the early stages at least. However, hydroponics should save significantly on the water bill.

Appendix II: Possible next steps
Water automation (irrigation) with Grodan Gro Blocks via timer pump + reservoir [src]


My blog has been getting a lot of spam on one particular post that I wrote earlier this year. Here’s some sample spam on my blog. It looks like someone forgot to fill in the words from their spam template and instead posted the entire template by accident, but this makes writing spam look like a fun pastime for a bored teenager.

This template is particularly interested in what blogging service I use and also notes that my blog posts are awesome. Woohoo, external validation via spam!

Uh, although it was pretty fun seeing this, I’ve enabled Akismet’s anti-spam WordPress plugin, but let me know if you have any other anti-spam suggestions (aside from using this template to filter out spam generated from this template).

{I have|I’ve} been {surfing|browsing} online more than {three|3|2|4} hours today, yet I never found any interesting article like yours. {It’s|It is} pretty worth enough for me. {In my opinion|Personally|In my view}, if all {webmasters|site owners|website owners|web owners} and bloggers made good content as you did, the {internet|net|web} will be {much more|a lot more} useful than ever before.|
I {couldn’t|could not} {resist|refrain from} commenting. {Very well|Perfectly|Well|Exceptionally well} written!| {I will|I’ll} {right away|immediately} {take hold of|grab|clutch|grasp|seize|snatch} your {rss|rss feed} as I {can not|can’t} {in finding|find|to find} your {email|e-mail} subscription {link|hyperlink} or {newsletter|e-newsletter} service.

More spam…

Blog migration from Posterous to WordPress

Posterous was recently acquired by Twitter, so I have been twiddling my thumbs for the past few weeks thinking about how/where to transition my blog and give it a more permanent home. I finally decided to give WordPress a try. Initially, the customizability of WordPress scared me, but it is truly wonderful how modular and flexible the system is.

If you were watching my old blog, please note that this is the new home!

This post documents the migration of my Posterous blog here, both in terms of content and functionality, in rough order in which I made the changes. I looked around for tools to do most of the heavy lifting, but I also made manual changes where I did not see a clear alternative. The process was spread out over about 3 days and was relatively painless.

Importing posts, comments, images, tags from Posterous into WordPress

I used Posterous Importer, which is well done and takes care of most of the heavy lifting.

Install at the Plugins > Add New menu, or alternatively:

Upload the posterous-importer folder to the /wp-content/plugins/ directory
Activate the plugin through the 'Plugins' menu in WordPress
Go to the Tools -> Import screen, Click on Posterous


Importer Status
Posts: 28
Comments: 10
Attachments: 167


Linking to previous posts

By default, links within posts to previous blog posts on Posterous will still point to the links on Posterous. I used a very manual process for switching these links, but I was not migrating many posts, and WordPress at least has a very nice interface for searching through previous content.

Editing the main template

I disliked the fact that my name would show up along every post on the main page of the blog (with my selected theme Typografia). This was not the case on my old blog, and it just seemed redundant. Instead of having to select a new theme that conveniently did not have this extra field, all I needed to do was go to Appearance > Editor in the menu to edit the theme and remove the following code:

<div class="post_author"><?php _e(' Posted by '); ?><?php the_author(); ?>

Editing the styles

There were some minor color contrast issues with the font color of the sidebar that spanned not only the main theme style (Typografia) but also the skin I selected (style4). Editing the styles of the main theme is done through the same interface as editing the main template. However, the theme editor doesn’t contain stylesheets for style skins, so I needed to ssh into my hosting server and manually edit the file at wp-content/themes/typografia/skins/skin4.css.

Tag to category conversion

Posterous uses tags and for whatever reason, WordPress has a sense of both categories and tags. This article details the distinction between tags vs categories. In short, the distinction is arbitrary, but categories can be viewed as a general bucket for a post, whereas tags can be viewed as attributes of a post. Categories are older than tags in WordPress history.

A plugin called Categories and Tags Converter (found at the Tools menu) allows for easy conversion between categories and tags in either direction.

Photo galleries

Posterous has a very nice built-in photo gallery display that takes the photos you want and displays them in gallery form with an easy way to switch between photos and download the entire set. Though the migration properly transferred most of the images, it missed some (that I needed to manually upload to WordPress) — on average 2 images per image-heavy post.

Additionally, it displayed all images without any special formatting and sort of just dumped them all our to the reader, so the images made the post a lot longer lengthier than necessary. WordPress also has a built-in gallery tool that tiles images to take up less space. My main use cases were (without the *):

Including all images associated with the post: [*gallery]

Tiling images in 2 columns (default is 3): [*gallery columns="2"]

Excluding images from gallery, to be displayed elsewhere in the post: [*gallery exclude="56,57,58"] (where 56,57,58 are image IDs)

Having multiple galleries in Posterous was trivial, but in WordPress meant creating multiple galleries that excluded all image IDs that belonged to other galleries. It was sort of a pain, but not that difficult. I did not try this, but there seems to be a better way via the Multiple Galleries plugin.

Other manual changes

Spacing between headings and text body was off in a number of posts, so that meant giving each post a quick scan for ugliness.

Publishing to Facebook and Twitter

Network Publisher uses LinksAlpha API to connect to up to 25 other social networking services. LinksAlpha allows 2 networks before trying to charge you, so that was perfect. The config documentation was very well done.

LinkAlpha’s privacy policy sounds, but regardless, from Facebook’s Account Settings > Apps, you can revoke all the authorizations except for “Post on your behalf.” The LinksAlpha web interface will give you an unhappy error about loading your news feed, but WordPress will still be able to successfully publish to your wall.

Google analytics

Google Analytics for WordPress gets this set up swiftly.


Posterous encouraged me to use Feedburner to publish my rss feed, which was great foresight. Instead of asking all my subscribers to update their link to the new one, I simply had to go to Edit Feed Details... and update the Original Feed URL.

Facebook Like button and Twitter Tweet button

I decided this feature on Posterous was not very meaningful and thus unnecessary to migrate over functionality.

And that’s it! The dread of migrating all this content and functionality has actually inhibited me from writing more, so I’m glad that that is over with.

This article on writing code in posts was not a part of the migration process, but it was useful for writing this post and describes the use of code and pre tags.

2011: The Year in Projects (Part 2)

This is Part 2 of my projects from 2011. For January thru June, see the previous post.

July: Dropbox mobile redesign
My summer project at Dropbox was a redesign of their mobile web app. Having not touched web development for the last 7 years, it was great to work with newer technologies. It was a summer of everything from designing the product and performing basic market research to developing and testing the product to doing everything possible to polish it up. Dropbox put up a nice blog post about it, and there were some other mentions too!

August: DEECS
Discover Electrical Engineering and Computer Science (DEECS) is a annual preorientation program for incoming freshman to explore EECS. In 5 days, 40 students build, code, and test LEGO line-following robots (assuming no prior LEGO theory and hardware or software skills), in addition to exploring MIT, checking out Boston, touring labs, and making friends with one another. I’ve been involved for the last 4 years, but last year I ran the robot project, with Nick. We bumped up the bar a bit by introducing training for lab assistants, and it was my first time lecturing.

September: Selling HKN resume books
Another sales-related project was figuring out how to best market the MIT EECS resume book to the large number of companies that want MIT EECS students. Alongside Alex, we fixed up the website, coordinated helpers to personally pitch the resume book to company representatives at the Fall 2011 career fair, and organized sales campaigns.

October: TimeTracker
I wanted to know how much time I was spending on email each day; it seemed like hours, and that was 1) terrifying, and 2) unacceptable. Pranjal wanted to quantify everything. Together, we wrote a few scripts that tracks computer usage down to the second and then gives you stats on where and how you spend your time. At the time of writing, I was averaging 1.8 hours for email, 3.5 hours in the terminal, and 8.9 hours of computer usage over the past week (per day). More daily averages: 4 minutes on Facebook, 20 minutes on Feedly, 8 minutes on Google Calendar, 1 minute on Wikipedia. The TimeTracker source can be found on Github.

November: Sentiment Analysis
Sentiment analysis is the detection of emotional content in writing. For 6.867, Pranjal and I applied a bunch of machine learning techniques to IMDb reviews and Yelp reviews to see how easy (or hard) it was to detect sentiment. We essentially replicated and then extended a bit Pang’s 2002 work. Although I set out by assigning projects to months, I actually end up assigning months to projects. This is prime example of how projects span more than a single month because we are still working on it (nearly done!). The Sentiment-Analysis source can be found on Github.

December: Asiatrip
I wrote extensively on my recent Asiatrip with Nancy, Julian, and Josh to see manufacturing, makerspaces, relatives, and general touristy things, but there’s still so much left untold and unwritten! Regardless, it was an amazing way to spend Winter Break, it doubled the number of countries I’ve stayed in, and it widened my world by even more than that.

So, that’s all for 2011 and it was a fantastic amount of learning. w00t for the new year!

2011: The Year in Projects (Part 1)

Last year, I decided to try to do a project every month. Projects are the little journeys in life, the real learning experiences, the realization of an idea. They result in gained skills, friends, inspiration, and sometimes, an improved world. They are technical and they are non-technical.

I quickly realized that projects don’t take a month. They either take a few days or much longer, but the idea is still valid. I did my best to focus my efforts on a particular project each month. Here are the results.

January: Maslab
Mobile Autonomous Systems Laboratory (Maslab) is MIT’s most intense IAP robotics competition. There are 4 weeks to build a robot from scratch to compete in a game requiring computer vision, navigation, and ball launching. Last year, Dan, Stan, Leighton, and I built, coded, debugged, tested, and didn’t sleep too much, but then we won! Check out our paper and the competition highlights.

February: Machine Learning Pilot
Alongside Chenxia, Diyang, and Stan, I ran a couple undergraduate machine learning reading groups (sponsored by IEEE/ACM), with the intent of gauging interest and appropriateness for a larger program with more technical topics. The idea was to experiement with this way of making friends while better learning technical material. We had a more applied group, as well as a more general group. Having never started an organization of my own, it was an incredible experience running the pilot program, and the results were very encouraging.

March: Kinect Symphony Conductor
I hacked up a symphony conductor demo using the Microsoft Kinect, with thanks to Brian for choice of music. The tempo of the music changes depending on how fast your arms move. I demoed this at the MIT 150th Open House, alongside other IEEE and EECS department booths.

April: Everything in the Kitchen Sink
My solution to the problem of dirty dishes piling up in communal kitchen sinks is to use cameras to detect the addition of dishes to a sink and who is using the sink at the time, and then to yell at them or blast out shaming emails. For 6.869 (Advances in Computer Vision), I worked on the dish detection portion of this solution.

The Undergraduate Reading Group Experience (URGE) is the program that grew out the Machine Learning Pilot of Spring 2011. With an amazing staff and support from IEEE/ACM and UMA, I directed this larger technical reading group program in Fall 2011. We had 8 groups this time, spanning EECS, math, and physics. The idea is to help create a cohesive technical undergraduate community at MIT, so that even more awesome productive things can happen. We recently got recognition from the The Institute, the IEEE newspaper!

June: Selling Maslab
I am Maslab‘s Sponsor Coordinator, so I had a lot of fun working with sponsors new and old to make Maslab 2012 possible. Having never done any kind of sales before, it was grand adventure of making brochures, designing sponsorship packages, writing emails, pitching Maslab, handling finances, and organizing events. Thanks to the sponsors of 2012, Maslab is going great!

Next up: July thru December!