Niro* by cho45

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

require 'pathname'
require "optparse"

class GitRecentCommand
	Ref = Struct.new(:hash, :name, :time, :rtime, :author, :subject)

	def dot_git
		@dot_git ||= Pathname.new(`git rev-parse --git-dir`.chomp)
	end

	def self.run(argv)
		self.new.option(argv).run
	end

	def initialize(opts={})
		@opts = {
			:strict  => false,
			:max_num => 20,
		}.update(opts)
	end

	def option(argv)
		opts = @opts
		argv = argv.dup
		OptionParser.new do |parser|
			parser.instance_eval do
				self.banner = <<-EOB.gsub(/^\t+/, "")
					Usage: #{$0} [opts]

				EOB

				separator ""

				separator "Options:"
				on("-s", "--strict", "Running on strict mode (very heavy)") do |foreground|
					opts[:strict] = true
				end

				on("-n", "--number NUMBER", "Number branch to show") do |num|
					opts[:max_num] = num.to_i
				end

				parse!(argv)
			end
		end
		self
	end

	def run
		details = @opts[:strict] ? recent_branches_strict : recent_branches_fast
		details = details.sort_by {|ref| ref.time }.last(@opts[:max_num])

		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

		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[0m" : out
			}
		}
	end

	# search recent branches by file mtimes
	def recent_branches_fast
		refs = []
		refs.concat Pathname.glob(dot_git + 'refs/heads/**/*')
		refs.concat Pathname.glob(dot_git + 'refs/remotes/**/*')

		branches = refs.reject {|r| r.directory? }.sort_by {|r| r.mtime }.last(@opts[:max_num]).map {|r|
			ref = r.read.chomp
			if name = ref[/ref: (.+)/, 1]
				(dot_git + name).read.chomp
			else
				ref
			end
		}
		retrieve_branch_details(branches)
	end

	# search recent branches by retrieving whole branch information
	def recent_branches_strict
		branches = `git branch -a`.gsub!(/^\*?\s+|\(no branch\)\s*/, "").split(/\n/).map {|i|
			i.split(/ -> /)[0]
		}
		retrieve_branch_details(branches)
	end

	# retrieve branch details information from branch names
	def retrieve_branch_details(branches)
		details = []
		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|
						is_remote = ref[%r{refs/remotes}]
						ref.gsub!(%r{refs/(remotes|heads)/}, '')
						details.push Ref.new(hash, ref, time.to_i, rtime, author, subject)
					end
				end
			end
		end
		details
	end
end

GitRecentCommand.run(ARGV)

[[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