Niro*

#6 Control Android browser focus high-lighting

The browser of Android has weird focus high-lighting. I want disabling it sometimes.

As using the following CSS for elements that aren't high-lighted but focusing.

-webkit-tap-highlight-color: rgba(0, 0, 0, 0);  

Premise

  • Android browser assign focus to "a" elements.
  • Android browser assign focus to the elements that are bound "onclick" event.

#5 Show branches that are changed only recently

Often, some projects using git have too many branches, but most branches are not updated in days. The old branches are very bother.

I wrote a script which shows only recent branches named 'git-branch-recent'.

#!/usr/bin/env ruby

branches = `git branch -a`.gsub!(/^\*?\s+|\(no branch\)\s*/, "").split(/\n/)

details = []
Ref = Struct.new(:hash, :name, :time, :rtime, :author, :subject)

IO.popen("-", "r+") do |io|
	if io.nil?
		args = [ "show", "--pretty=format:%H\t%d\t%ct\t%cr\t%an\t%s", *branches ]
		args << "--"
		exec "git", *args
	else
		while l = io.gets
			next unless l =~ /^[a-z0-9]{40}/
			hash, refs, time, rtime, author, subject = * l.chomp.split(/\t/)
			refs.gsub!(/^\s*\(|\)\s*$/, '')

			refs.split(/\s*,\s*/).each do |ref|
				ref.gsub!(%r{refs/(remotes|heads)/}, '')
				details.push Ref.new(hash, ref, time.to_i, rtime, author, subject)
			end
		end
	end
end

details = details.sort_by {|ref| ref.time }.last(10)
remote_master = nil
rtime_width = name_width = author_width = 0
details.each do |ref|
	name_width    = ref.name.size   if ref.name.size   > name_width
	author_width  = ref.author.size if ref.author.size > author_width
	rtime_width   = ref.rtime.size  if ref.rtime.size  > rtime_width
	remote_master = ref.hash        if ref.name == 'origin/master'
end

puts "There are %d branches. (remote:%d, local:%d)" % [
	branches.size,
	branches.grep(/\//).size,
	branches.size - branches.grep(/\//).size
]
details.each {|ref|
	ref.instance_eval {
		out = "\e[32m% -#{name_width}s\e[39m % #{rtime_width}s %s \e[31m% -#{author_width}s\e[39m %s" % [
			name,
			rtime,
			hash[/^.{7}/],
			author,
			subject
		]
		puts (hash == remote_master) ? "\e[7m#{out}\e[m" : out
	}
}

[[git]]

#4 Levenshtein distance implemented in Ruby and RubyInline

module Levenshtein
	def levenshtein(a, b)
		if Inline::USABLE
			Inline.levenshtein(a, b)
		else
			PureRuby.levenshtein(a, b)
		end
	end

	module PureRuby
		def levenshtein(a, b)
			case
			when a.empty?
				b.length
			when b.empty?
				a.length
			else
				d = Array.new(a.length + 1) { |s|
					Array.new(b.length + 1, 0)
				}

				(0..a.length).each do |i|
					d[i][0] = i
				end

				(0..b.length).each do |j|
					d[0][j] = j
				end

				(1..a.length).each do |i|
					(1..b.length).each do |j|
						cost = (a[i - 1] == b[j - 1]) ? 0 : 1
						d[i][j] = [
							d[i-1][j  ] + 1,
							d[i  ][j-1] + 1,
							d[i-1][j-1] + cost
						].min
					end
				end

				d[a.length][b.length]
			end
		end

		module_function :levenshtein
	end

	module Inline
		begin
			require "rubygems"
			require "inline" # sudo gem install RubyInline

			inline do |builder|
				builder.c <<-'EOS'
					VALUE levenshtein (VALUE array1, VALUE array2) {
						VALUE ret;
						long len1 = RARRAY(array1)->len;
						long len2 = RARRAY(array2)->len;
						long i, j;

						long** d = ALLOC_N(long*, len1 + 1);
						for (i = 0; i <= len1; i++) {
							d[i] = ALLOC_N(long, len2 + 1);
							memset(d[i], 0, sizeof(d[i]));
						}

						for (i = 1; i <= len1; i++) d[i][0] = i;
						for (j = 1; j <= len2; j++) d[0][j] = j;
						for (i = 1; i <= len1; ++i) {
							for (j = 1; j <= len2; ++j) {
								int del = d[i-1][j  ] + 1;
								int ins = d[i  ][j-1] + 1;
								int sub = d[i-1][j-1] + (
									rb_equal(
										RARRAY(array1)->ptr[i-1],
										RARRAY(array2)->ptr[j-1]
									) ? 0 : 1
								);

								d[i][j] =
									(del <= ins && del <= sub) ? del:
									(ins <= del && ins <= sub) ? ins:
									sub;
							}
						}

						ret = LONG2FIX(d[len1][len2]);

						for (i = 0; i < len1; i++) free(d[i]);
						free(d);

						return ret;
					}
				EOS
			end

			module_function :levenshtein

			USABLE = true
		rescue LoadError
			USABLE = false
		end
	end
end


require 'rubygems'
require 'spec'

[Levenshtein::Inline, Levenshtein::PureRuby].each do |m|
	describe m do
		it "should return correct levenshtein distance" do
			[
				["kitten", "sitting", 3],
				["foo", "foo", 0],
				["", "", 0],
				["foO", "foo", 1],
				["", "foo", 3],
			].each do |a, b, expected|
				m.levenshtein(a.split(//), b.split(//)).should == expected
				m.levenshtein(b.split(//), a.split(//)).should == expected
			end
		end
	end
end

Spec::Runner.run

require "benchmark"

Benchmark.bm(10) do |x|
	n = 10000

	x.report("inline") do
		n.times {
			Levenshtein::Inline.levenshtein("kitten".split(//), "sitting".split(//))
		}
	end if Levenshtein::Inline::USABLE

	x.report("pureruby") do
		n.times {
			Levenshtein::PureRuby.levenshtein("kitten".split(//), "sitting".split(//))
		}
	end
end

[[ruby]] [[algorithm]

#3 HTML::Trim for trimming HTML text to specify size

HTML::Trim is a Perl module for trimming HTML text to specified bytes or text length.

Sometimes, we want to set in formatted HTML texts which is input by user. HTML::Trim is useful for the purpose.

use HTML::Trim qw(htrim hvtrim);

my $trimmed = hvtrim('foo bar <a href="/">baz</a> fumino', 10, '…');
#=> 'foo bar <a href="hoge">b</a>…'

HTML::Trim provide two functions, one of it is trimming by byte length named "htrim" or "HTML::Trim::trim" and another by character (considering multibyte east-asian characters) length named "hvtrim" or "HTML::Trim::vtrim". You should use vtrim for universal use.

[[perl]] [[cpan]]

#2 Benchmark JavaScript code casually

Sometimes, want benchmark to compare some codes and show it people. I made a tiny benchmark script in a .html and a .js.

Features

  • Run each code in random for fairness
  • Color after running
  • Only html and javascript code
  • bit.ly link

Example

[[javascript]]

login