Saturday, November 24, 2012

Adding syntax highlighting to code snippets in Blogger


As I am starting to write tech blogs, I will be adding lots of code snippets to my blogs. While it's trivial to add code-snippets via plugins in paid blogging platforms, unfortunately free versions of Blogger or WordPress doesn't allow any code-editing plugins.
After doing some research I found out that, even though Blogger doesn't come with plugins like gist embedder or syntax highlighter, thankfully we can add them by loading custom JavaScript files.

Below are couple of ways to add them and gotchas:


1. Adding Gist embedding plugin (gistLoader):

Follow instructions http://blog.moski.me/2012/01/gist-with-bloggers-dynamic-views.html
Gotcha #1: 
For whatever reason, it never worked while using one of the "dynamic views" templates. But when I switched to "Simple" template (this one), it worked like a charm.

Gotcha #2: 

Some of the templates don't have JQuery. So Make sure to add JQuery before gistLoader.
Loading ....

2. Adding Syntax Highlighter plugin:

 Follow this great blog post http://oneqonea.blogspot.com/2012/04/how-do-i-add-syntax-highlighting-to-my.html

 Gotcha #1: Again this never worked while using one of the "dynamic views" templates. But when I switched to "Simple" template (this one), it worked like a charm.

 



3. Adding Google Prettify plugin:

Follow this blog http://www.milesdennis.com/2010/02/adding-googles-code-prettify-in-blogger.html & there are many other blogs that shows how to add Google code prettify plugin.


This should be in color but something is wrong :)
... code ...

Dealing with AngularJS + JQuery Masonry + ImagesLoaded plugins for a Pinterest like app


Recently I was working on a project where I wanted to create Pinterest like cards with different heights. Each 'card' can have images, comments, likes etc. I wanted to use Angularjs, Jquery Masonry plugin to achieve this.  But the problem was that in Angularjs doesn't provide easy way to deal with jquery plugins.

After doing lot of reading (AngularJS docs are GREAT btw), research &  googling, the closest I came to was: http://jsfiddle.net/roychoo/XVzUW/3/   (or my version: http://jsfiddle.net/rajaraodv/GwP5Z/1/)

Those things are great if the cards don't have images, but if you do have images, you get into issues. Because if you have images, you won't necessarily know their width and heights before hand until they are completely loaded.

Steps / Problem:

  1. ng-repeat will create dom elements
  2. masonry starts calculating width & hight of cards and starts to rearrange them
  3. BUT, images are not loaded so the height/width are wrong! so step2 will be wrong and you'll endup with stacked cards(one on top of the other)


Loading ....



If you set image's height & width to some static number (say 200px X 300px), then you'll make Masonry plugin happy (i.e. cards will be properly arranged), but you'll end up stretching/squeezing the images (especially if the images are very small).

Steps / problem:

  1. ng-repeat will create dom elements
  2. masonry starts calculating width & hight of cards and starts to rearrange them
  3. Masonry is happy BUT images look squeezed or stretched.



To minimize stretching/squeezing images, I had set max-height and max-width for images. But since these values are not constant, you will still get into masonry issue.

Steps / problem:

  1. ng-repeat will create dom elements
  2. masonry starts calculating width & hight of cards and starts to rearrange them
  3. BUT, AGAIN images are not loaded! so step2 will be wrong & you'll endup with stacked cards(one on top of the other)


Then I found I can easily deal with images using Imagesloaded (github) JQuery plugin. I thought, great and went to work.
Loading ....

To my surprise, that didn't work either!

Steps / problem:

So, I started digging into ImagesLoaded plugin's code and then realized that by the time ImagesLoaded starts to collect img's src, AngularJS hasn't yet added it. i.e. the ng-src="path/to/img" hasn't been copied to src="path/to/img" yet! And src was "" when ImagesLoaded plugin ran!


Finally.. Solution:

After some trial and error I wrapped the whole thing with a $timeout of 0 and that was enough for it to finally work!
Loading ....


PS: There may be a better way of solving this problem, if there is, please let me know.