## 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:


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.

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);


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”.

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).


-- 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
*/
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
-------------------------------------------------------------
--
-- 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
-------------------------------------------------------------
--
--
-------------------------------------------------------------
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