Friday, September 06, 2013

Regex in Haskell patterns

Have you ever wanted to do case expr of regexhere -> ... ?
You can do almost that with view patterns!

{-# LANGUAGE ViewPatterns #-}

import Text.Regex.Posix

-- Helper
pat :: String -> String -> [[String]]
pat p s = s =~ p

-- Function with matching
foo :: String -> String
foo (pat "foo(bar|baz)" -> [[_,x]]) = x
foo _ = "no!"

main :: IO ()
main = do
  print $ foo "foobar"
  print $ foo "foobaz"
  print $ foo "yes?"

The above code will print bar baz no! . Have fun!

Wednesday, July 03, 2013

Found my google reader alternative: the old reader

So I'd like to share with you my google reader alternative: theoldreader.
I've tried so far yoleo, feedly, goread and diggreader. Each of them is missing the following must have things for me:
  • The "next" button. I don't like using keyboard bindings when reading feeds.
  • Search through all feeds
  • Social by sharing/liking news
  • Exporting OPML
Additionally, theoldreader has a great (disabled by default) feature: clicking on a news will scroll to it. That is very handy if you don't want to stick your mouse clicking on the next button.

The only bad point of theoldreader is that there's an import queue, I'm currently in position 1566 (1481 after about 15 minutes). Other than that, it's perfect for my needs and resembles most of google reader.

Update: the search only looks for terms into post titles, not post contents :-(

Friday, June 28, 2013

Inline commenting system for blog sites

One side of the idea:
Lately I've seen some comment systems that inline comments in the text itself, see an example here.

Other side of the idea:
I've implemented a couple of unsupervised algorithms for news text extraction from web pages in Javascript, and they work generally well. They're also capable of splitting the news text into paragraphs and avoid image captions or other unrelated text.

The idea:
Merge the two ideas, as a new commenting service (like Disqus) for blogs, in a modern and interesting way.
  1. The algorithms are capable of extracting the news text from your blog and splitting it into paragraphs.
  2. For each paragraph, add a seamless event so that when the user overs a paragraph with the mouse, a comment action button appears.
  3. When clicking the comment button a popup will appear showing a text box at the top where you can write the comment, and the list of comments at the bottom that are related to that paragraph only. (I please you, let the user order comments by date.)
  4. Optional killer feature: together with the text box, you can also choose to add two buttons: "This is true", "This is false", so that there's a kind of voting system about the truth value of that paragraph from the readers perspective.
  5. Once you send the comment, that comment is tied to that paragraph.
  6. Give the possibility to create comments the old way, in case the user does not want to strictly relate the comment to a paragraph.
  7. Give the possibility to show all the comments at the bottom of the page (button "Show all comments"). If a comment is related to a paragraph, insert an anchor to the paragraph.
Given that the blogger shouldn't add any additional HTML code for the paragraphs because of the unsupervised news extraction algorithms, the comment service API will not differ in any way than the current ones being used.

Problems of this approach:
  • There's no clear chronology for the user between comments of two different paragraphs. In my opinion, this shouldn't be a big deal, as long as comments between two paragraphs are unrelated.
  • If a paragraph is edited/deleted, what happens to the comments? One solution is to not show them in the text, but add a button "Show obsolete comments" at the buttom of the page, or rather show them unconditionally.
  • The unsupervised algorithm may fail to identify the post. In that case, the blogger may fall back to manually define the DOM element containing the article.

Wednesday, June 05, 2013

Accessing simple private fields in PHP

A way of accessing private fields in PHP is by changing the accessibility of the fields themselves with http://php.net/manual/en/reflectionproperty.setaccessible.php.
However this approach requires PHP 5.3.

For PHP < 5.3 there's another subtle way of accessing private properties:

function getPrivateProperty($fixture, $propname) {
    try {
        $arr = (array)$fixture;
    } catch (Exception $e) {
    }
    $class = get_class($fixture);
    $privname = "\0$class\0$propname";
    return $arr[$privname];
}

Usage is pretty straightforward, pass in the object and the property name as string. The property must be private and must be convertible to array.

Saturday, April 06, 2013

Build Vala applications with Shake build system

I'm going to introduce you a very nice alternative to make: the Shake build system, by setting up a builder for your Vala application project.

First of all, you need to know that Shake is a library written in Haskell, and it's meant to be a better replacement for make. Let's start by installing cabal and then shake:
apt-get install cabal-install
cabal update
cabal install shake

TL;DR; this is the final Build.hs file:
#!/usr/bin/env runhaskell
import Development.Shake
import Development.Shake.FilePath
import Development.Shake.Sys
import Control.Applicative hiding ((*>))

app = "bestValaApp"
sources = words "file1.vala file2.vala file3.vala"
packages = words "gtk+-3.0 glib-2.0 gobject-2.0"

cc = "cc"
valac = "valac"
pkgconfig = "pkg-config"

-- derived
csources = map (flip replaceExtension ".c") sources
cobjects = map (flip replaceExtension ".o") csources

main = shakeArgs shakeOptions $ do
  want [app]
  app *> \out -> do
    need cobjects
    pkgconfigflags <- pkgConfig $ ["--libs"] ++ packages
    sys cc "-fPIC -o" [out] pkgconfigflags cobjects
  cobjects **> \out -> do
    let cfile = replaceExtension out ".c"
    need [cfile]
    pkgconfigflags <- pkgConfig $ ["--cflags"] ++ packages
    sys cc "-ggdb -fPIC -c -o" [out, cfile] pkgconfigflags
  csources *>> \_ -> do
    let valapkgflags = prependEach "--pkg" packages
    need sources
    sys valac "-C -g" valapkgflags sources
    
-- utilities
prependEach x = foldr (\y a -> x:y:a) []
pkgConfig args = (words . fst) <$> (systemOutput pkgconfig args)

Just tweak app, sources and packages to match your needs, chmod +x Build.hs then run ./Build.hs .

Explanation.
The words function splits a string by spaces to get a list of strings, e.g. ["file1.vala", "file2.vala", "file3.vala"].

The csources variable maps .vala file names to .c file names. Same goes for cobjects. It's the equivalent of $(subst .vala,.c,$(SOURCES)) you'd do with make.

There it comes the main. The shakeArgs shakeOptions part will run shake with default options. Shake provides handy command line options similar to make, run ./Build.hs -h for help.

The want [app] tells shake we want to build the app object by default. That's equivalent to the usual first make rule all: $(APP).

Then we define how to build the executable app with app *> \out -> do. We tell shake the dependencies with need cobjects. This is similar to $(APP): $(COBJECTS) in make but not equivalent. In shake dependencies are not static like in many other build systems. This is one of the most interesting shake features.
The rest is quite straightforward to understand.

Then we define how to build each .o object with cobjects **> \out -> do. Here the out variable contains the actual .o required to be built, equivalent to $@ in make. Then we need [cfile], in order to simulate %.o: %.c like in make.

One more feature shake has out-of-the-box that make doesn't is how to generate more files from a single command. With make you'd use a .stamp file due to valac generating several .c files out of .vala files. Then use the .stamp as dependency.
With shake instead we consistently define how to build .c files with csources *>> \_ -> do, then shake will do the rest.

The shake project is very active. You can read this tutorial to learn Haskell basics, and the reference docs of shake. The author homepage has links to cool presentations of the shake build system.

Thursday, March 28, 2013

Switch window by name on Linux - alternative to Alt+Tab

Today I want to share a very simple script that works with most Linux window managers: switch window by name.
It works like this: you press Ctrl+Alt+M, then a dialog appears where you write part of the name of the window, and you'll get switched to the window that matches the provided name.The string your provide will match part of window names in case-insensitive mode.
That means if you have "Foo - Mozilla Firefox" and type in "fire" you'll switch to firefox.

Note: it probably doesn't work with your configuration of awesome wm due to weird focus management.

The first step is to install the necessary packages:
apt-get install xbindkeys wmctrl zenity

With wmctrl we're able to switch to a window by specifying the name, while with xbindkeys we can bind Ctrl+Alt+M to open a zenity dialog then call wmctrl with the provided window name.

The only thing you need is the following file somewhere, let's call it keys.rc:
"WINDOWID='' app=$(zenity --text "App" --title "App" --entry) && wmctrl -R $app"
  control+alt + m

Now run xbindkeys -f keys.rc and we're done! Press Ctrl+Alt+M then type in the name of the window you want to switch to.

We can also add simpler bindings like this:
"wmctrl -R Firefox"
  control+alt + f

Now pressing Ctrl+Alt+F will switch to a firefox window.

Note that if it matches more window, only one of the window will be chosen obviously. The choice depends on xbindkeys.

I'm not using Alt+Tab anymore.

Sunday, March 24, 2013

Controlling audio volume in Awesome WM

I use awesome on my eeepc because it's much space and resource saving.
There are several possibilities for controlling volume in the Awesome window manager.
Today I'd like to share my way of doing it: using amixer for controlling the volume, and naughty for notifying the user.

Start by defining the following in your rc.lua (source discussion here):
volnotify = {}
volnotify.id = nil
function volnotify:notify (msg)
    self.id = naughty.notify({ text = msg, timeout = 1, replaces_id = self.id}).id
end

We use naughty for notifying the user instead of notify-send because of the "replaces_id" feature. It's used to replace an old notification with a new one. This is useful when you keep increasing the volume so that you only get one notification instead of stacking them up.
So the purpose of this code is to keep track of the id returned by naughty on each invocation, so that we can pass it to the next invocation.

function volume(incdec)
    awful.util.spawn_with_shell ("vol=$(amixer set Master 5%" .. incdec .. "|tail -1|cut -d % -f 1|cut -d '[' -f 2) && echo \\\"volnotify:notify('Volume $vol%')\\\"|awesome-client -", false)
end

function togglemute()
    awful.util.spawn_with_shell("vol=$(amixer set Master toggle|tail -n 1|cut -d '[' -f 3|cut -d ']' -f 1) && echo \\\"volnotify:notify('Volume $vol')\\\"|awesome-client -", false)
end

The first function is used to increase or decrease the volume. It accepts an argument of value either "+" or "-", then changes the master volume accordingly and finally displays a notification with the new volume.
The second function will toggle the mute state of the volume in a similar manner.

We are going to call these two functions whenever the user hits the media keys by binding new global keys as follows:

globalkeys = awful.util.table.join (globalkeys,
    awful.key({}, "XF86AudioMute", togglemute),
    awful.key({}, "XF86AudioLowerVolume", function() volume("-") end),
    awful.key({}, "XF86AudioRaiseVolume", function() volume("+") end)
)

Restart with Mod+Ctrl+R and that's it!