Archive for June, 2010

Build and run current xcode project from command line

Friday, June 18th, 2010

I edit my source code via the command line using vim. Then I need to go into xcode and push build/run to debug the code I’m working on. I’d rather just issue a command from vim. Here’s a cheap way to build and run via and applescript which can then be called by vim.
Save the following applescript as xcode_build_and_launch.scpt


tell application "Xcode"
  activate
  set targetProject to project of active project document
	
  if (build targetProject) starts with "Build succeeded" then
    launch targetProject
  end if
end tell

Then from vim you can issue:


:!osascript path/to/xcode_build_and_launch.scpt

This will activate xcode and build the current project, and if that succeeds then it will launch the current executable target.

Note: I stripped the above out of code from a question on stackoverflow. Apparently this will not work for iPhone simulator projects.

Update: I like to call it from vim with the bash time command and then I have an idea of how long the compile took.


:!time osascript path/to/xcode_build_and_launch.scpt

Installing mplayer on Snow Leopard “with MacPorts”

Wednesday, June 16th, 2010

I didn’t quite get macports to install mplayer on my Snow Leopard machine. But it almost did and with a little help I got it installed, and it wasn’t too hard.
First issue:


sudo port install mplayer

This will grab all of the dependencies and then finally fail to install mplayer itself.

After that, follow these instructions. The svn command didn’t work for me so I just grabbed the Subversion snapshot from the mplayer site.

Compiling triangle’s showme with X11 on Snow Leopard

Wednesday, June 16th, 2010

I was trying to install Triangle on the Snow leopard computer I just started using and ran into some trouble compiling with x11. When I ran the command:


cc -O -o showme showme.c -lX11

I got this error:


ld: library not found for -lX11
collect2: ld returned 1 exit status

After some digging in my /usr directory I found X11 had its own directory. So when I issued this command:


cc -O -I/usr/X11 -o showme showme.c -L/usr/X11/lib -lX11

Everything worked fine.

triangle showme demo working in x11

Note: Seems like it is going to be annoying that -lX11 doesn’t work, so maybe I will make a link at some point.

Change screenshot file format in Snow Leopard to PNG

Wednesday, June 16th, 2010

Just started working on a snow leopard machine and have been annoyed that the screenshots are saved as PDFs. To switch back to png I opened Terminal.app and issued this command:


defaults write com.apple.screencapture type png

Then you must issue:


killall SystemUIServer

to make the change take effect.

Note: You can replace png in the above with any of these: png, pdf, tiff, pict, bmp, gif, psd, sci, or tga.

source

Piecewise functions in matlab

Tuesday, June 15th, 2010

Not the most difficult thing to do by any means. But here’s a handy conversion from a math formula to matlab. Say you have the piecewise polynomial, m, defined as:


        / 0              if x < 0,
m(x) = |  -2x²(x - 3/2)  if 0 ≤ x < 1,
       |  1 + (x - 1)    if 1 ≤ x < 3/2,
        \ x - 1/4        if x ≥ 3/2.

So in matlab if I have some variable x with some values, i.e.

x = -1:0.01:2;

then I can formulate the above as:


m = ...
  (0               ) .* (x < 0           ) + ...
  (-2*x.^2.*(x-3/2)) .* (0 <= x & x < 1  ) + ...
  (1+(x-1).^2      ) .* (1 <= x & x < 3/2) + ...
  (x-1/4           ) .* (x >= 3/2        );

Now, I can show a plot:


plot(x,m);

piecewise polynomial plot matlab

This works because the conditions in matlab are now logicals that return a vector the same size as x, with 1′s if the condition was true and 0′s otherwise. Multiplied against the value for the condition and added to the next gives the correct solution. I guess this method is somewhat risky in the sense that if you mess up your logicals or inequalities the addition could sum up erroneous values without recognizing the error. But I think the presentation is very nice and is easily broken up if need be.

Note: The polynomial above is from Higher Order Barycentric Coordinates by Torsten Langer and Hans-Peter Seidel.

Ad blocking one website at a time

Monday, June 7th, 2010

I wrote a small piece of Applescript code that allows me to zap ads from web pages that I browse using Safari. It uses javascript to remove the ads or containing objects from the page directly. It doesn’t use intelligent ad recognition in any way. Rather my idea was much simpler. Most people spend 90% of there time on the web looking at a small number of websites: facebook, new york times, twitter, google, wikipedia, gmail, youtube, etc. See Pareto principle. If I can block 100% of the ads on 90% of the pages I look at then my ad blocker is effectively 90% efficient.

The ads on these big sites are usually in the same place on the page making them very easy to remove from the html with javascript. I organized my applescript so that adding a new site on which to block ads is very simple (just a line or two) and blocking a certain type of ad on that site is just another line.

I use the magnifying glass tool, in the Safari Developer tool, Web Inspector, to select the ad object on the page. Inevitably the website has used a class or id which then I feed into my script. Often the containing object is as simple as “ad” or “bigAd”.

screenshot of web inspector, selecting ad

When I have my blocker running in the background, it usually takes up 2% of the CPU. If I crank down the delay in the script so that the ads disappear even faster then it can get as high as 10% or so, but it’s not really worth it.

There is no reason why you couldn’t easily port this style of ad blocker to grease monkey, opera, or anything that runs client-side javascript.

Here is the applescript, it creates a few useful javascript methods and sets up the blocker to run in the background (with a little error checking).


-- Safari AdBlocker Applescript
-- Author: Alec Jacobson http://alecjacobson.com
--


-- this might not be necessary... 
-- because safari already has getelementbyclassname... 
-- but perhaps without localization?
-- and perhaps not older safari?
set getElementsByClass to "
/*
  Developed by Robert Nyman, http://www.robertnyman.com
  Code/licensing: http://code.google.com/p/getelementsbyclassname/
*/  
var getElementsByClassName = function (className, tag, elm){
  if (document.getElementsByClassName) {
    getElementsByClassName = function (className, tag, elm) {
      elm = elm || document;
      var elements = elm.getElementsByClassName(className),
        nodeName = (tag)? new RegExp(\"\\b\" + tag + \"\\b\", \"i\") : null,
        returnElements = [],
        current;
      for(var i=0, il=elements.length; i<il; i+=1){
        current = elements[i];
        if(!nodeName || nodeName.test(current.nodeName)) {
          returnElements.push(current);
        }
      }
      return returnElements;
    };
  }
  else if (document.evaluate) {
    getElementsByClassName = function (className, tag, elm) {
      tag = tag || \"*\";
      elm = elm || document;
      var classes = className.split(\" \"),
        classesToCheck = \"\",
        xhtmlNamespace = \"http://www.w3.org/1999/xhtml\",
        namespaceResolver = (document.documentElement.namespaceURI === xhtmlNamespace)? xhtmlNamespace : null,
        returnElements = [],
        elements,
        node;
      for(var j=0, jl=classes.length; j<jl; j+=1){
        classesToCheck += \"[contains(concat(' ', @class, ' '), ' \" + classes[j] + \" ')]\";
      }
      try  {
        elements = document.evaluate(\".//\" + tag + classesToCheck, elm, namespaceResolver, 0, null);
      }
      catch (e) {
        elements = document.evaluate(\".//\" + tag + classesToCheck, elm, null, 0, null);
      }
      while ((node = elements.iterateNext())) {
        returnElements.push(node);
      }
      return returnElements;
    };
  }
  else {
    getElementsByClassName = function (className, tag, elm) {
      tag = tag || \"*\";
      elm = elm || document;
      var classes = className.split(\" \"),
        classesToCheck = [],
        elements = (tag === \"*\" && elm.all)? elm.all : elm.getElementsByTagName(tag),
        current,
        returnElements = [],
        match;
      for(var k=0, kl=classes.length; k<kl; k+=1){
        classesToCheck.push(new RegExp(\"(^|\\s)\" + classes[k] + \"(\\s|$)\"));
      }
      for(var l=0, ll=elements.length; l<ll; l+=1){
        current = elements[l];
        match = false;
        for(var m=0, ml=classesToCheck.length; m<ml; m+=1){
          match = classesToCheck[m].test(current.className);
          if (!match) {
            break;
          }
        }
        if (match) {
          returnElements.push(current);
        }
      }
      return returnElements;
    };
  }
  return getElementsByClassName(className, tag, elm);
};"
set setElementsToEmpty to "function setElementsToEmpty(a){
  for ( var i=0, len=a.length; i<len; ++i ){
    a[i].innerHTML = '';
  }
};
"

set this_url to ""
repeat
  try
    repeat while appIsRunning("Safari")
      tell application "Safari"
        
        try
          set doc to front document
          set this_url to URL of doc
          do JavaScript getElementsByClass in doc
          do JavaScript setElementsToEmpty in doc
          if this_url starts with "http://www.google.com/search?" then
            -- Regular google search
            -------------------------------------------------------------
            --
            -- ZAP CONTAINING DIV BY ITS ID
            --
            -------------------------------------------------------------
            do JavaScript "document.getElementById('rhsline').innerHTML = ''" in doc
            do JavaScript "document.getElementById('tads').innerHTML = ''" in doc
          else if this_url starts with "http://search.yahoo.com/search" then
            -- Regular yahoo search
            do JavaScript "document.getElementById('east').innerHTML = ''" in doc
            -------------------------------------------------------------
            --
            -- ZAP DIVS OF CERTAIN CLASS WITHIN  CERTAIN CONTAINING DIV (COULD BE NULL)
            --
            -------------------------------------------------------------
            do JavaScript "setElementsToEmpty(getElementsByClassName('ads horiz',null,document.getElementById('main')))" in doc
          -------------------------------------------------------------
          --
          -- ADD OTHER SITES HERE
          --
          -------------------------------------------------------------
          end if
          -- set delay amount accordingly to manage how much CPU to devote to blocking ads
          -- recommended between 1.0 and 0.001 seconds
          delay 0.1
        on error errText number errNum
          -- if anything but doc changing before ads removed or safari open but no windows
          -- pause so that CPU isn't stolen
          delay 2
        end try
      end tell
    end repeat
  on error errText number errNum
    if errNum is equal to -128 or errNum is equal to -609 then
      -- safari no longer open
    else
      display dialog errText & " " & errNum
    end if
    
  end try
  delay 5
end repeat

-- from http://codesnippets.joyent.com/posts/show/1124
on appIsRunning(appName)
  tell application "System Events" to (name of processes) contains appName
end appIsRunning

Download the ad blocker with all the sites I’ve blocked ads on

Imagine how strong this ad blocker could be if an army of users were updating the site specific zaps. Imagine the cold war it would start.

Note: Some sites inject their ads deeper into the content of the site like youtube does with its flash videos. I haven’t come up with a way to single this one out yet…