Twitterでの言及数を知る

Posted
on
in

公式にはAPIが用意されていない。プライベートだけど誰でも叩けるAPIがあるけど使わないでくれと言っている。のでTopsyAddThisのAPI経由とかしか今のところ方法は無さそう。などということを公式Tweet Buttonのサブセットなdata-*属性による設定を受け入れるTweet Buttonを作ってて知った。

View Demo: Tweet Button Powered by Topsy

TopsyのAPIはコマーシャル・ライセンスを取らないと専用の画像を使ってリンク必須と読めるのでとても使いづらい。というか使えない。AddThisの(api-public.addthis.comで動いてる奴)はドキュメント見つからない。Shared Countとか見つけたけどコレは普通にプライベートなAPIを使っててダメそう。

なんか良いの無いもんかな。

UglifyJSのHTTP APIを叩くPerlスクリプト

Posted
on
in

UglifyJSClosure Compilerから乗り換えようかなーとちょっと思っているのでとりあえずコンパイルするためのスクリプトを書くところから。UglifyJSのHTTP APIがそこそこClosure Compiler ServiceのREST APIと互換性があるようなので、まずはローカルのJavaScriptファイルをClosure Compiler ServiceのREST APIでコンパイルできるようにで書いたPerlスクリプトを修正して使ってみる。

Download: uglifyjs.pl

使い方は元になったClosure Compiler ServiceのREST APIを叩く奴と一緒。

UglifyJSのHTTP APIではjs_codeパラメーターが複数使えない。なので手元でまとめてから投げたりする必要があるので、ちゃんとまとめないと意図した順番でコードが実行されない可能性がある。素直にどこかにアップロードしてからcode_urlパラメーターでそれを指定したほうが安全そう。

Closure Compiler Serviceのような埋め込みコメントに対応したCUIラッパー書いた方が良さそう。ありそう。

追記

Closure Compilerに比べてローカル環境を構築するコストと実行するコストが低い気がするので連結するだけのスクリプトを書いてパイプでつなげることにした。Closure Compilerの@code_urlとそれに似た@code_pathだけ使えて、それらを連結するだけ。

Google Code Prettifyのローダースクリプトを書き直した

Posted
on
in

単にDOMContentLoadedGoogle Code PrettifyprettyPrint()を呼んでただけだったのをゴニョゴニョするようにした。将来性とマークアップのしやすさのためにpre要素にprettyprintというクラスを指定しないように方針変更したので、それに合わせてcode[class*=language-]な要素を探してその親がpreだったらprettyprintを追加し、その後でprettyPrint()を走らせるという感じ。一応サポートしている言語もチェックしたりとかもするようにした。Rainbow移行への布石。

同じブラウザーかつ同じバージョンならdocument.querySelectorAll()におけるセレクターとCSSにおけるセレクターは完全にサポート状況が同じとみなして良いのかわからない。頑張ってググりたい。

language-fooをクラスに持つcode要素を表現するセレクターはcode[class|=language]とかでいけるかと思ったけど、そういう使い方するものではなかったしダメだった。空白区切りで複数の値を取れるプロパティーではそれぞれの値の先頭にマッチするようなセレクターが欲しい。いやいらないです。

サポートしている言語かそうでないかはごく簡単にチェック。

var languages = ["bsh", "c", "cc", "cpp", "cs", "csh", "cyc", "cv", "htm",
  "html", "java", "js", "m", "mxml", "perl", "pl", "pm", "py", "rb", "sh",
  "xhtml", "xml", "xsl", "css", "scss", "vim"],
  reLanguage = new RegExp("\\blanguage-(" + languages.join("|") + ")\\b");

追加しづらそう……。Google Code PrettifyのlangHandlerRegistryを参照するかlangHandlerForExtension()パクった方が良さそう。むしろ頑張ってハイライトしようとするフォールバックの部分なくしちゃえばいいのかなー。


視認しつつマークアップの修正をしなければならなかったのでVimのキーボードマクロでだいたい誤魔化した。普段はqに誤爆するとうっとうしいけど、使う時はコマンドラインにでるrecordingというメッセージがすごく可愛く見える。多分結構な数のエントリーでおかしくなってそう。気づいたら直す。

あとRainbowに僕の書いた<code class="language-php">とかに対応するコードが取り込まれたのでdata-languageへ書きなおさなくても使えるようになった。作者のさじ加減で消えかねないのでマークアップにこだわりがないなら素直に併記した方が良さそう。

Rainbow

Posted
on
in

Rainbowはコードのシンタックス・ハイライトをやってくれるJavaScriptライブラリ。拡張の仕組みが凄く書きやすそうで良さそう。名前は悪い。しかもリダイレクト先のURLはrainbowsだし……。まぁとにかく乗り換えようかなとちょっと思った理由をちょっと書いておく。「ちょっと」なのでまだあんまり乗り換える気ない。

書きやすいといっても所詮は正規表現なので、定義フォーマットがGoogle Code Prettifyの黒魔術的なアレよりもちょっとシンプルだとかそういう意味にすぎない。なのでこの点だけでは既存の様々なシンタックス・ハイライトしてくれるライブラリから乗り換えるという程のパワーがあるわけではないと思う。他にもpre要素の子ではないそこらのcode要素のハイライトにも対応している所とかすごいと思うんだけど、おまけ機能的な感じでこれも乗り換えの動機にはならなそう。

僕が乗り換えようかなと思ったのは、Rainbowがシンタックス・ハイライトできる言語であるかどうかHTML側からは気にする必要がないように使うことができる点。Rainbow.color()に要素を渡すとその子をシンタックス・ハイライトしてくれるので、これをうまく使えば良い。そうすると何が良いかというと、例えばRainbowでサポートされていない言語パターンのコードを書く時にも以下のように書くだけ。

<pre><code class="language-vim">
...
</code></pre>

あとはクラスを見て対応しているかいないかを確認し、対応しているものだけRainbow.color()に通せば良い。実際にはかなり追加でJavaScriptを書かないとならなかった(data-language属性を追加したりとか色々)のでイマイチだったんだけど、Google Code Prettifyで「あとで言語ハンドラー追加した!」とかそういう時に昔のエントリーのHTMLを修正する必要があるのとくらべるとマシな気はする。

Google Code Prettifyのシンタックス・ハイライトを実行する前にゴニョゴニョする方が簡単そうに思えてきたところ。

2012年度版・ASIN抜き出す方法

Posted
on
in

Amazon.co.jpでアソシエイトツールバーが表示されている場合、window.Associates.SocialShareAttributes.asinにASINがあることに気づいたのでしばらくこっちを使ってみる。GoogleでのSocialShareAttributes検索結果が0だったのでメモしておく。

他だと以下の二つが抜き出す方法としては優秀な気がする。

canonicalはURL自体に色々パラメーター付いてても関係なさそうなので良さそう。id="ASIN"を参照は結構長いこと動いてるような気がするけどなんか不安……。

Data URIに変換するPerlスクリプト

Posted
on
in

Data URIはまだそれほど使いまくっているわけでもないので、ブラウザーでやったりVimからWSHでやったりいろいろしてたけど、必要な時はだいたい複数ファイルを何回も変換する必要があったりしていろいろ大変なのでPerlで書き直して右クリックから使う方法も考えた。@cho45が書いたのを見て重い腰が上がった。

#!/usr/bin/env perl

use strict;
use warnings;

use MIME::Base64;
use MIME::Types;
use Path::Extended qw(file);

my $mt = MIME::Types->new();
my @r;

foreach (@ARGV) {
  my $f = file($_);
  my $t = $mt->mimeTypeOf($file->stringify);
  push(@r, 'data:' . ($t ? $t : 'text/plain') . ';base64,' . encode_base64(scalar($f->slurp(binmode => 1)), ''));
}

print join("\n", @r);

exit;

URIモジュールでのnew('data:')だとBase64でエンコードするかどうかよしなにしてくれちゃうので、普通にMIME::Base64を使った。メディアタイプ判別のモジュールはいくつか試したけど、未知の時に例外吐いて死ぬ奴とか常に配列で返す奴とか色々アレなのが多くて、未知の場合は空で返ってくるMIME::Typesが結局一番ましな感じだった。

右クリックから使う場合は、

@echo off

perl -S convert-to-data-uri.pl %* | clip

というようなバッチファイルを送るに置いておくとクリップボードに即コピーとかできる。

Sassでコンパイル時にData URIに変換する関数とか書いて使ってたことも少しあったけど、コンパイルが遅くなりがちで辛いので直ぐに止めた……。

追記

Windowsだとバイナリ・ファイルがうまくいかないのでPath::Extendedに変えて明示的にbinmodeを指定して読むようにした。自分で書いてて、id:charsbarに教えてもらったのをきれいさっぱり忘れてた……。

GitHubで今開いているコミットをmasterの最新と比較する

Posted
on
in

GitHubには任意の二点間のスナップショット差分を見るためのCompareというビューがある。各リポジトリのページからこの機能にアクセスするUIがないのでマイナーな気がするけど、アクティビティーとかでちょっと使われてたりするので見たことはあるはず。CompareビューにはリポジトリのURLの最後に/compareと付けるだけで入ることができ、開かれるダイアログで任意のタグやブランチ、SHA1ハッシュを入力すると差分がズラッと並んでくれる。特定のコミットのページからは特にUIはないのだけどURLをちょっと書き換えるだけでmasterの最新との差分を見ることができる。

具体的には

https://github.com/hail2u/normalize.scss/commit/58d8597e5b6df43e9ad6023ac68f10e7ec47e139

というような特定のコミットを参照しているページのURLを

https://github.com/hail2u/normalize.scss/compare/58d8597e5b6df43e9ad6023ac68f10e7ec47e139...master

と書き換えるとそのコミットからmasterの最新のコミットまでの差分が見れるということ。/commit//compare/に書き換えて...masterを最後につけるだけ。たまに使うんだけどこの機能に簡単にアクセスするためのUIがなくて良く忘れる……というのももう10回目くらいな気がするので、ブックマークレットを作った。

Bookmarklet: Github: Compare this commit with master

commitとかいうユーザー名の人のリポジトリではうまく動かない気がするけどまぁいいか。クローンとかは特にしてるわけではないけどウォッチしてるプロジェクトの変更を一望する時とかに使っている。

Sassのリスト

Posted
on
in

Sassではいわゆる「配列」のような複数のデータを格納するリストを作れる……というのだけど使ったことなかった。リファレンスでもさらっと流されてるし、リストを使う@eachの説明でもベタに並べてあるだけで、どうやって作ってどうやって使うのかイメージできなかった。変数の値を空白区切りにしたらリストな変数になるということはどう考えてもリファレンスからは読み取れないと思う。

基本

特に難しいこともなく空白(かカンマ)区切りで指定するとリストになる。

$lists: foo bar buz;

.test {
  property: $lists;
}

リストな変数であってもそのまま参照した場合は普通の変数と同じようにそのまま(空白区切りのまま)出力される。

.test {
  property: foo bar buz }

リストの特定のインデックスの値を参照するにはnth()関数を使う。

.test {
  property: nth($lists, 2);
}

これでリストの2番目の値を参照できる。多くのプログラミング言語と違って添え字は1始まりなことには注意が必要。

.test {
  property: bar }

書きづらいこと以外はまぁ普通な感じ。

応用

変数をそのままリストの値にすることもできる。

$foo: f o o;
$bar: b a r;
$buz: b u z;
$lists: $foo $bar $buz;

.test {
  property: nth($lists, 3);
}

勿論(?)このようにリストをリストにぶち込むとかも出来て、こうすると多次元配列っぽいものになる。この場合は基本の最初の例のように空白区切りでの出力となる。

.test {
  property: b u z }

nth()関数をネストすればどんどん辿れる。

.test {
  property: nth(nth($lists, 3), 2);

これでリストに格納したリストの特定のインデックスを参照できる。

.test {
  property: u }

素晴らしい。

具体的な利用

幅とそれを利用したクラスが必要なカラム定義なんかに利用できる。

$column: 60px;
$gutter: 20px;
$gap:    10px;

$colspan1:  (($column + $gutter) *  1 - $gutter);
$colspan2:  (($column + $gutter) *  2 - $gutter);
...
$colspan11: (($column + $gutter) * 11 - $gutter);
$colspan12: (($column + $gutter) * 12 - $gutter);
$colspan: $colspan1 $colspan2 ... $colspan11 $colspan12;

@for $i from 1 through 12 {
  .colspan#{$i} {
    margin-left: $gap;
    margin-right: $gap;
    float: left;
    width: nth($colspan, $i);
  }
}

このように変数を使って変数を参照することができる。append()関数も使えばもっとうまく短く書けそう。


なんてことをカラム定義を生成するSCSSパーシャルを作ってて理解した。でもけっこうな魔窟っぽい予感がするので気をつけて使った方が良さそう。

追記

append()を使うと短くはなる。空のリスト(というか変数?)も作ることができるようなので以下のような感じで書ける。

$column: 60px;
$gutter: 20px;
$gap:    10px;

$colspan: ();

@for $i from 1 through 16 {
  $colspan: append($colspan, (($column + $gutter) * $i - $gutter));
}

スッキリ!

3.2のprerelease版では複数のリストを明示的に多次元リストにまとめるzip()とリストから検索するindex()という関数も追加されている。駆使すると今はできない同じルールセット内の別プロパティーの値とかを参照するみたいな機能作れそう。多分誰も読めなくなるけど。

CSS LintのPhantomJS向けCLIをちょっと変えた

Posted
on
in

PhantomJSからCSS Lintを使うで書いたCSS LintPhantomJS向けCLIを1ファイルで完結するようにClosure Compilerで連結した。オプションに対応とかじゃない。対応しようかと思ってたんだけど、ルールのオン・オフとかすごい面倒な感じだったのでやめた。外部ファイルに設定書けるようになったりするまではデフォルトで使ってようと思ってる。

Download: csslint-phantomjs.min.js

使い方は以前と同じ。僕はラッパーのシェル・スクリプトを書いてそれを使っている。

$ phantomjs csslint-phantomjs.min.js test.css

ついでにこのスクリプトを置いてあるGistリポジトリへ使っているJSHintJSLintのCLIも置いておいた。PhantomJS使ったスクリプトは他にもいくつかあるので気が向いたらここに追加するつもり。

a要素でのitemprop属性

Posted
on
in

Microdataではitemprop属性を指定された要素からどうやって値を選択するか厳密に決められていて、それに外れた書き方はできない。metatimeimg要素の場合はまぁそうなるよねみたいな感じなんだけど、a要素だけがちょっと。

仕様では、a要素でitemprop属性を使った場合その値はhref属性の値を絶対URLに変換したものとなっている。そのため以下のようには書けない。

<address itemscope
  itemtype="http://schema.org/Person">
  Copyright &copy; 2012
  <a href="http://example.com/about/"
    itemprop="name url">
    John Doe
  </a>
</address>

MicroformatshCardのような感覚では書けないということで、以下のようにspan要素(など)を使って別にしないといけない。

<address itemscope
  itemtype="http://schema.org/Person">
  Copyright &copy; 2012
  <a href="http://example.com/about/"
    itemprop="url">
    <span itemprop="name">
      John Doe
    </span>
  </a>
</address>

ボキャブラリーごとに対応しなくても良いようにHTMLの要素側で値の選択法を決定させているのだと思う。ボキャブラリー側でデータ型を決めてそれによって値の選択法を変えるというのだと、処理系でボキャブラリーをちゃんと処理しなければ正確なデータの抽出が行えない。HTML要素で値の選択法が決定されるMicrodataの実装ではデータの抽出自体はボキャブラリーを処理せずに行えることになる。HTMLがマークアップ言語なこともあって理にかなっている実装なんじゃないか(と今は思う)。


このWebサイトはまだ直してない……けど今から直す。