Pages

07 November, 2011

Freemind to Mediawiki via CoffeeScript

Check out my new project at Github. I wrote a little Freemind to Mediawiki converter using CoffeeScript.

https://github.com/ubunatic/mm2wiki

CoffeeScript does really a good job for writing such software. Parsers, writers, and other data processing stuff can be easily done, thanks to CoffeeScript comprehensions and other smart language features.
Together with running all code running smoothly via node.js... Really nice!

-- written on an iPad, typing long text, and copying links is horrible ;)

11 October, 2011

Whitening SumatraPDF

I am using SumatraPDF as OSS alternative for the heavyweight Adobe Reader.
Sumatra is lightning fast and I like it more than Evince, which I used before.

One thing that bugged me was the ugly yellow background. It makes the tool and unfortunately also it's website look unprofessional. Here is how you can change that - at least the tool, not the web site ;)

  1. Start SumatraPDF.exe at least once. You may have to "open with..." it with a pdf file first.
  2. Fire up regedit and find (Strg+F) "SumatraPDF.exe". You need to find a key named: HKEY_USERS\...\Software\Classes\Applications\SumatraPDF.exe\shell\open\command
  3. There you should find a value named: (Default) that points to your Sumatra executable (see my screenshot)
  4. Double-click the (Default) value and add:  -bg-color 0xffffff between the "...SumatraPDF.exe" and the "%1" (as in my screenshot)
  5. Done! 
More Sumatra command line parameters can be found here: http://blog.kowalczyk.info/software/sumatrapdf/manual.html


17 July, 2011

Making command line JavaScript ready for node.js AND rhino


I have several command line scripts for doing repetitive chores. As seen in a previous post, I used rhino to run the scripts. But since node.js has been arising, I guess many developer will use that one as JavaScript interpreter. It also starts a bit faster that rhino.

The problem is that the two are not very compatible since the hooks to the operating system are named differently. This will lead to errors when one engine executes scripts designed for the other.

Here is a workaround that can make basic scripts, not using too many internals, compatible with each other. It works well for my string conversion scripts.
var args = arguments;

//initalize for node.js/rhino compatibility
if(typeof print === 'undefined') print = console.log;
if(typeof console === 'undefined') console = { log: print };
if(typeof process !== 'undefined') args = process.argv.splice(2); 
This script does two things:
  1. It maps the command line arguments to args. Node.js stores them in process.argv and rhino in the default arguments array.
  2. It will merge the basic logging functionality of rhino and node.js, mapping node.js' console.log to rhino's print function and vice versa.
That's it! I hope you can make use of this little hint.

Ciao,
Juve

26 June, 2011

Using gedit's External Tools Plugin to Search in Files

IDEs for strongly typed languages allow you to press a hotkey (e.g., F3 in Eclipse) to look up a type or use features like "where used" to find all references of class, property, or method.

When hacking Javascript in gedit I also very often need to find all references of variables, object properties, and functions. But when coding with a weakly typed language like Javascript in gedit you do not have any shortcut to success. At least not by default.

Searching manually is not an option as soon as your projects grow larger. Firing up the gnome-search-tool is also not an option, since it would require further clicking in the dialog and cannot open gedit at the correct line.

Super Simple Search Script
Currently, the best option for me is to use this little script:
#!/bin/sh
args=$(xargs)
echo "searching for '$args'"
grep -nr $args * | sed 's/\(^[^\:]*:[0-9]*:\)/\1 /g' 
It simply looks up the current word in all files of the current document's directory and outputs "filename:line-number: matching line's text" in gedit's bottom pane. Output text using the "file:line:text" pattern is clickable in gedit and lets you jump to the line in the file immediately.


Installation
To use this script in gedit you need to enable the External Tools Plugin. Add a new entry in the plugin's configuration screen, name it, assign your hotkey, and select "Current word" as "Input". Finally copy the script code into the text area and check if everything is correct. Look at the first screenshot to check if everything is set up correctly.

Now you can finally test your new tool. Open a file and select a word. You can also set the cursor before any of the characters of the word. Now press your hotkey (F3 in my case) and the script should check your current file's directory for other files containing the word. Look at the second screenshot to see a sample result.

I hope you liked this article and that the script is useful for you.
Best wishes, Juve


20 June, 2011

Motorola Update Hell

Last week I tried to update my Motorola Defy mobile phone. It is an Android 2.1 device and the people in the US could simply update via WiFi or 3G to Android 2.2. Unfortunately Motorola decided to do a more complex scenario here in Europe.

And whoever decided this strategy is hopefully not longer working for that company. The process requires an external PC and is a big mess.

After many hours trying to update on several machines I finally got my Android 2.2. Here is what I went through.

The Painful Path
  1. I checked the Motorola site and several sources on the web how to update.
  2. According to some sources, I should have been notified of the update directly on the devices, which did not happen.
  3. Then I tried to update via the Android system settings: "No updates for you, sorry guy".
  4. Obviously European mobile network providers require a more complex update approach, even if I have a retail version of the phone, not tied to any provider.
  5. Checking the web again. OK, I need an update software from Motorola.
  6. I found it on their site and downloaded it. OMG, it is an exe-file! It was of course not working on WINE and there was no update software for Linux.
  7. I assumed that this exe-file neither runs on my friends Mac nor my collagues iPads.
  8. Dammit, I had to find a Windows PC, but who owns such old-fashioned devices anymore?
  9. Then I remembered my old Windows XP image, on one of my hard drives. Fortunately it was still there and also tied to the GRUB as last entry to be chainloaded. I fired it up and it still worked.
  10. Yeah! Let's start the funny exe-file: "Motorola requires Internet Explorer 5.5 or above." What the heck? Why does an mobile device update software require and antiquated web browser? For security reasons, I disabled this leaky browser before this Windows image was installed and I will not install it now. Nobody dictates me what to install and what not. That's why I use Ubuntu, my current(!) Linux of choice.
  11. OK, I had to find another Windows device. But where to search? I wont tell you where I finally found my Windows device - the owner was a bit ashamed of still owning it - but we got the update running. He still had the leaky Internet Explorer installed even if he never used it. The update also requires the .NET framework, which was luckly already installed.
  12. Then the update software went a bit amok forcing the notification icons going wild. The notifications told us vigorously about "new devices", "failed driver installations", and "ready devices". I don't know how many times the notification flashed but that I had to start the software a second time and again let it try to dig all its system-related components into the Windows machine. OMG! Fortunately that was not my machine. :)
  13. After all this fiddling it would finally recognize the device, download the update, and install it. Done!
"Luckily" the Defy will not get an Update to 2.3. ;)

Btw., did I tell you that I did not have to install anything when I plugged my phone into my Ubuntu Linux PC and I could start development for Android immediately?

I really don't know why Motorola has built such a complicated update for its European phones. But I hope that next time they will consider the growing number of users of Macs, iPads, Android-based Pads, and even Desktop Linux PCs. The Wintel era is coming to an end.

Update: A few days ago, I send a mail to Motorola's CEO again telling them about me not being happy with their update strategy. It was obviously read by their IT support. Thereafter, they replied on my former support ticket, telling me that they read this blog entry and congratulating me on my update success.
They promised to forward my valuable feedback to the responsible departments. Very nice!

Ciao,
Juve


19 June, 2011

Connect gedit to Firebug


Did you ever jump back and forth between Firebug and gedit or other text editors, searching for the line you were just debugging/editing? 
Stop doing this manually! Firebug provides you with an "external editors" feature and allows you to jump to the right line in your code in the editor.

Here are some screenshots to show you how it looks like. First, I right click a line (e.g., line 7) in Firebug and select "gedit". Firebug/Firefox then calls "gedit myfile.js +7" making gedit get focus and jump to line 7.

Setup
Setting up gedit or other tools as external editors is really easy. I wonder why I did not try this earlier. Open Firebug and the Firebug option menu. Select "Open with Editor > Configure Editors".
Now click "Add", give the editor a name, select an executable and edit the command line arguments. Firebug can forward the current %url, the local path to the %file, and the %line number via the command line.
In my case, man gedit revealed that both file and line can be forwarded to gedit with the simple pattern gedit filename +linenumber, and therefore, gedit's arguments string in Firebug would be %file +%line.


That's it, I hope you could learn something new.
Ciao,
Juve


02 April, 2011

Make JSLint working nicely with gedit


For coding Javascript, I use gedit and several plugins/external tools. One of them is JSLint. Here is a short tutorial get a good integration of JSLint into gedit.

  1. Install the Rhino Javascript command line engine:
    sudo apt-get install rhino

  2. Download and install the rhino version of JSLint. Unfortunately, it is no longer available from the original developer. You can get a copy from the juicer project: https://github.com/cjohansen/juicer/raw/master/lib/jslint/jslint-rhino.js (save link as). Copy the file to: $HOME/.gnome2/gedit/plugins/jslint-rhino.js

  3. Open gedit to configure JSLint as external tool.
    Enable the External Tools plugin and restart gedit.Go to Tools > Manage External Tools and add a new entry.

  4. Copy&Paste the following script into the text area. Make sure that file name and path of the downloaded JSLint file is the same as in this script.
    #!/bin/sh
    echo "/*jslint onevar: true, undef: true, newcap: true, nomen: true, regexp: true, plusplus: true, bitwise: true, browser: true, maxerr: 50, indent: 4, white: false */" > /tmp/jslint-me.js
    cat $1 >> /tmp/jslint-me.js
    result=$(js $HOME/.gnome2/gedit/plugins/jslint-rhino.js /tmp/jslint-me.js)
    rm /tmp/jslint-me.js
    js $HOME/.gnome2/gedit/plugins/jslint-rhino-text-replace.js "$GEDIT_CURRENT_DOCUMENT_NAME" $result > /dev/stdout

  5. Select a shortcut (Ctrl+J) and set the other options to
    Save: Nothing
    Input: Current Selection (default to document)

  6. Finally you need to copy another command line script to reformat the JSLint output. It will allow you to click the error messages in gedit, jumping to the corresponding line in your code. Copy the following script to: $HOME/.gnome2/gedit/plugins/jslint-rhino-text-replace.js. Make sure that file name and path of the text-replace script file is the same as in the gedit External Tools script.
    var newArgs = [], errorPrefix, i = 1, lastErrorIndex = -1, fileName = "";
    var len = arguments.length, fileName = arguments[0];

    while (i < len) {
    if (arguments[i] === "Lint" && arguments[i+1] === "at"){ //new Lint starting
    errorPrefix = fileName + ":" + (arguments[i+3]-1) + ":";
    newArgs.push(errorPrefix);
    lastErrorIndex = newArgs.length-1;
    i += 6;
    }
    newArgs[lastErrorIndex] += " " + arguments[i];
    i += 1;
    }

    for(i = 0; i < newArgs.length; i += 1) {
    print(newArgs[i]);
    }

    if(newArgs.length === 0) {
    print(fileName + ": Excellent! Your JS code is clean and shiny.");
    }

    //
    // Copyright (C) 2011 by Uwe Jugel, uwe.jugel@gmail.com
    //
    // Permission is hereby granted, free of charge, to any person obtaining a copy
    // of this software and associated documentation files (the "Software"), to deal
    // in the Software without restriction, including without limitation the rights
    // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    // copies of the Software, and to permit persons to whom the Software is
    // furnished to do so, subject to the following conditions:
    //
    // The above copyright notice and this permission notice shall be included in
    // all copies or substantial portions of the Software.
    //
    // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    // THE SOFTWARE.
    //
    // Info:
    // gedit support referencing and navigating from shell output lines to source
    // code lines if the output follows the "filename:linenumber:message" pattern
    // This script removes some verbosity from the JSLint error messages and
    // reformats them to support this pattern.
    //
    // Use this script after calling JSLint from gedit External Tools.
    //
    // Usage:
    // js PATH_TO/jslint-rhino-text-replace.js FILENAME JSLINTOUTPUT...
    //
You can now run JSLint on your opened Javascript files by pressing CTRL+J. You can also click on the output, and gedit jumps to the corresponding line in the source code.

Juve

22 February, 2011

OSS for Schools and Public Authorities

I just read a nice article about the growing spread of open source in schools and authorities all over the world. (german article, english translation)

Quite impressing how rapidly the number of these projects is growing and how large they have become. Here are some numbers:

Brazil: Saves estimated 500 Mio USD by using OSS since 2003.

Norway:
All 19 county governments are now using OSS (Ubuntu, Open Office, Gimp, etc.).

France:
French National Police saves 50 Mio € by using Ubuntu, Open Office, and a security-enhanced Thunderbird. The enhancement was contributed back to Mozilla and the French Military is now also using this Thunderbird.

Spain:
300,000 desktops and 180,000 laptops are using an Ubuntu-derived Linux. 100,000 will follow in 2011. The use of OSS also strengthened the local IT-industry (rather than Microsoft ;)

And in 2011 more will follow, such as Russia, where 55,000 schools could switch to OSS.

I really like this development, since I am a strong advocate for GNU/Linux, Gimp, etc. One of the best tools for me is Inkscape. But that's another story.

Best wishes for all your OSS projects,
Juve

Solve your cross domain issues. Avoid "file://"!

I regularly trip over cross domain security problems [1]. These are even harder to solve if you are developing your HTML-based apps locally and try to run them by simply opening them in the browser via "file://local-path-to-my/app1". When such an app request data from a server, e.g., via xhr [2], the requests Origin header value is set to null.

You can avoid this by using a web server and starting your app from the server via "http://localhost:8080/app1". My projects usually reside in an easy to reach path, e.g., /home/juve/projects/app1 or E:/projects/app1, and I do not want to copy them redundantly to the server, into an awkwardly long sub path. Therefore, I often need to create an additional path mapping to the servers config, pointing to my project's absolute paths.

This is possible for many kinds of web servers. Here's how I did in in my Tomcat 6.0 server.xml. Simply find the <Host> tag and add a <Context> tag:
<Host>
<Context path="/app1" docbase="E:/projects/app1/">
</Context>
</Host>
Restart the server. Your ready to go! Don't waste time exploring "file://"-related cross domain problems. Use "http://localhost" instead!

[1] MDC, HTTP access control
[2] Using XMLHttpRequest

14 February, 2011

Simplify SVG for HTML5 App Debugging

In this article I will show you a nice little shell script that will
  • Crunch your big Inkscape SVG,
  • Round all numbers to one digit,
  • Remove all unnecessary styles, namespaces, nodes, and attributes that have no effect in the browser
The script is a rough start, and I expect it to get better when I will further develop my little HTML5 scenario.

Why do I need the script?

I've been experimenting with HTML5, SVG, JavaScript, Firebug, and Chrome Developer Tools since last Christmas. Currently, I am developing a little proof of concept game. The idea is to:
  1. Use vanilla Inkscape as main world editor.
  2. Render the game world using SVG in the browser.
  3. Use some JavaScript/JSON DSL to model the game logic.
If you are debugging things in the browser, you want a small DOM tree and as few code lines as possible. The basic Inkscape SVGs are quite redundant and you often have a lot of decimals with lots of post-comma digits. For better debugging I will round them down/up. I also wanted to replace many inline styles with a real <style> tag, and remove all unnecessary nodes, attributes, etc.

Full SVG simplification script
# This file is provided as is, with no warranties
#
# Author: Uwe Jugel
# WWW:    http://open-juve.blogspot.com
#
# License: Creative Commons Attribution-ShareAlike 3.0 Unported License.
#
#!/bin/sh

echo cleaning up $1
#namespaces
svgns=http://www.w3.org/2000/svg
svgns_escaped="http:\/\/www.w3.org\/2000\/svg"
sodins=http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd
inkns=http://www.inkscape.org/namespaces/inkscape

#replace svg root
svgreplace='s/\(^<svg\)\(\s\).*>$/\1\2xmlns=\"'$svgns_escaped'\"\2xmlns:svg=\"'$svgns_escaped'\">/g'

defaultstyles=''

for i in \
's/color:#000000;*//g' \
's/stroke:#000000;*//g' \
's/stroke-width:1[a-Z]*;*//g' \
's/stroke-linecap:butt;*//g' \
's/stroke-linejoin:miter;*//g' \
's/stroke-opacity:1[a-Z]*;*//g' \
's/fill:none;*//g' \
's/fill-opacity:1[a-Z]*;*//g' \
's/fill-rule:nonzero;*//g' \
's/stroke-miterlimit:4[a-Z]*;*//g' \
's/stroke-dasharray:none;*//g' \
's/stroke-dashoffset:0[a-Z]*;*//g' \
's/marker:none;*//g' \
's/visibility:visible;*//g' \
's/display:inline;*//g' \
's/overflow:visible;*//g' \
's/enable-background:accumulate;*//g'
do
defaultstyles="$defaultstyles -e $i"
done

emptystyle='s/style=""//'

cat $1 > /tmp/svg-cleanup.tmp1
touch /tmp/svg-cleanup.tmp2
touch /tmp/svg-cleanup.tmp3
touch ./tiles-export.svg

out=./tiles-export.svg
tmp=/tmp/svg-cleanup.tmp1
tmpround=/tmp/svg-cleanup.tmp2
tmploop=/tmp/svg-cleanup.tmp3

recursiontest=1
loops=1

echo "starting recursive rounding"
while [ $recursiontest = 1 ]; do
for i in 's/\(\.[0-9]\)[0-4][0-9]*/\1/g' 's/\(\.[0-9]\)[5-9][0-9]*/\1_CEIL_/g' \
's/0_CEIL_/1/g' 's/1_CEIL_/2/g' 's/2_CEIL_/3/g' 's/3_CEIL_/4/g' 's/4_CEIL_/5/g' \
's/5_CEIL_/6/g' 's/6_CEIL_/7/g' 's/7_CEIL_/8/g' 's/8_CEIL_/9/g' \
's/\([0-9]\)9_CEIL_/\1_CEIL_0/' 's/\([0-9]\)\.9_CEIL_/\1_CEIL_\.0/'
do
cat $tmp | sed -e $i > $tmpround
cat $tmpround > $tmp
done
diff=$(diff -qn $tmp $tmploop)
recursiontest=$?
if [ $recursiontest = 1 ]; then echo "loop: $loops"; fi
loops=$(($loops+1));
cat $tmp > $tmploop
done
echo "recursive rounding done."

cat $tmp | xmlstarlet ed -N svg=$svgns -N sodi=$sodins -N ink=$inkns -d "//svg:metadata" -d "//sodi:*" \
-d "//@sodi:nodetypes" -d "//@ink:connector-curvature" -d "//@sodi:docname" | sed $defaultstyles -e $emptystyle \
-e $svgreplace > $out

The Script in Detail

First I define some namespaces that will be used by xmlstartlet to modify the xml tree:
#namespaces
svgns=http://www.w3.org/2000/svg
svgns_escaped="http:\/\/www.w3.org\/2000\/svg"
sodins=http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd
inkns=http://www.inkscape.org/namespaces/inkscape
Then I have a little replacement expression that will kill all namespaces from from the svg root tag (will be called last).
#replace svg root
svgreplace='s/\(^<svg\)\(\s\).*>$/\1\2xmlns=\"'$svgns_escaped'\"\2xmlns:svg=\"'$svgns_escaped'\">/g'
Inkscape writes many inline styles into each node in the SVG tree. Most of them are default values that are supported by the browser. Therefore, we can remove them (and manually replace them with a CSS file someday).
defaultstyles=''
for i in 's/color:#000000;*//g' 's/stroke:#000000;*//g' 's/stroke-width:1[a-Z]*;*//g' #and so on
do
defaultstyles="$defaultstyles -e $i"
done
If not style is left, I also have to remove the empty style attribute
emptystyle='s/style=""//'
Now comes a funny part (after some file initialization). I am using a while loop and a for loop to accomplish some basic rounding of all numbers in the file. Post-digits .X1 to .X4 are cut down to .X, while all numbers .X5 and above are rounded up including a distribution of the rounding to the previous digits. The solution using only sed and some loops looks awkward but it works.
while [ $recursiontest = 1 ]; do
for i in 's/\(\.[0-9]\)[0-4][0-9]*/\1/g' 's/\(\.[0-9]\)[5-9][0-9]*/\1_CEIL_/g' \
's/0_CEIL_/1/g' 's/1_CEIL_/2/g' 's/2_CEIL_/3/g' 's/3_CEIL_/4/g' 's/4_CEIL_/5/g' \
's/5_CEIL_/6/g' 's/6_CEIL_/7/g' 's/7_CEIL_/8/g' 's/8_CEIL_/9/g' \
's/\([0-9]\)9_CEIL_/\1_CEIL_0/' 's/\([0-9]\)\.9_CEIL_/\1_CEIL_\.0/'
do
cat $tmp | sed -e $i > $tmpround
cat $tmpround > $tmp
done
diff=$(diff -qn $tmp $tmploop)
recursiontest=$?
if [ $recursiontest = 1 ]; then echo "loop: $loops"; fi
loops=$(($loops+1));
cat $tmp > $tmploop
done
This script marks all places to be rounded up with _CEIL_ and then replaces these marks with new marks or the correct numbers until no marks are left.

Finally, I aggregate all sed expressions, use xmlstartlet to remove the bad nodes and attributes, and write out the result.
cat $tmp | xmlstarlet ed -N svg=$svgns -N sodi=$sodins -N ink=$inkns -d "//svg:metadata" -d "//sodi:*" \
-d "//@sodi:nodetypes" -d "//@ink:connector-curvature" -d "//@sodi:docname" | sed $defaultstyles -e $emptystyle \
-e $svgreplace > $out

Conclusion

I am not 100% sure if the tools (bash/sed/xmlstartlet) are the perfect fit for my task but they get the job done without being overly complex. If I imagine of how unreadable an XSLT script would be, compared to this little bash script, I believe that my choice was not unwise.

I hope you find this article helpful for you SVG-related project.

Best wishes,
Juve


Creative Commons License
SVG simplificaion shell script by Uwe Jugel is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.