連続する改行を詰めるブックマークレット

某ブログやケータイサイトなんかで使われまくってる改行タグを詰めるだけです。もう1度実行すると戻ります。
<p>&nbsp;</p> なんかで行間取ってるのも詰まります。

↓のコードをダブルクリックでコピーしてブックマークに登録して下さい。

javascript:(function(){var uze=document.getElementById('uze-br');if(uze){uze.parentNode.removeChild(uze);}else{var uze=document.createElement('style');uze.id='uze-br';uze.type='text/css';uze.appendChild(document.createTextNode('br{display:block !important;content:"" !important;}p.uze,div.uze{display:none !important;}'));document.getElementsByTagName('head')[0].appendChild(uze);var p=document.evaluate('//p[text()="xA0"] | //div[text()="xA0"]',document,null,XPathResult.ORDERED_NODE_SNAPSHOT_TYPE,null);for(var i=0;i<p.snapshotLength;i++){p.snapshotItem(i).className='uze';}}})();

CSSで br { display: block; content: “”; } を適用してJavaScriptで&nbsp;を消してるだけ

PHP5のfgetcsvで文字化けするときの対応策 fgetcsv_reg を少し変えてみた

PHP5でfgetcsvを使用すると文字化けしたり正常に読み込めない場合の対応策として fgetcsv_reg というユーザー定義関数 ( PHP5でfgetcsvが正常に動作しない : ::yossy.blog:: )
がありますが、大量にcsvファイルを読み込んでると結構遅くなるので若干変えてみました。

殆ど同じですが$lengthの初期値1024にしてtrim(), empty()使わなかったりfeof()でファイル終端か判断してるぐらいで、気持ち早いかなって程度です。

※いい加減なので場合によっては遅くなるかもしれません。

<?php
function fgetcsv_reg( &$handle, $length = 1024, $delimiter = ',', $enclosure = '"' ) {

    $delimiter = preg_quote( $delimiter );
    $enclosure = preg_quote( $enclosure );

    $buffer = '';

    while ( !feof( $handle ) ) {
        $buffer .= fgets( $handle, $length );
        if ( preg_match_all( '/' . $enclosure . '/', $buffer, $m ) % 2 == 0 ) {
            break;
        }
    }

    $pattern = '/(' . $enclosure . '[^' . $enclosure . ']*(?:' . $enclosure . $enclosure . '[^' . $enclosure . ']*)*' . $enclosure . '|[^' . $delimiter . ']*)' . $delimiter . '/';

    $values = array();
    $len = preg_match_all( $pattern, preg_replace( '/[rn]+$/', '', $buffer ) . $delimiter, $matches );
    for ( $i = 0; $i < $len; $i++ ) {
        $values[] = str_replace( $enclosure . $enclosure, $enclosure, preg_replace( '/^' . $enclosure . '(.*)' . $enclosure . '$/s', "$1", $matches[1][$i] ) );
    }
    return $buffer ? $values : false;

}
?>

PHPのマルチバイト文字列関数で”ISO-2022-JP”, “JIS”, “ISO-2022-JP-MS”の違い

PHP5.2.1ぐらいから”ISO-2022-JP-MS”というのも使えるそうなので”ISO-2022-JP”,”JIS”とどう違うか試してみました。

<?php
/* UTF-8からISO-2022-JP, JIS, ISO-2022-JP-MSに変換してみる */
setlocale( LC_ALL, 'ja_JP.UTF-8' );

/* ダメ元で☎ ☃なども */
$str = 'アイウエオ ㈱ ㈲ ① ② Ⅰ Ⅱ ℡ ㎏ ㎎ 﨑 髙 神 ☎ ☃';

header( 'Content-Type: text/plain; charset=ISO-2022-JP' );

printf( "%sn", 'PHP' . PHP_VERSION );
$encodings = array( 'ISO-2022-JP', 'JIS', 'ISO-2022-JP-MS' );
foreach ( $encodings as $encoding ) {
    printf( "%sn", $encoding . ' : ' . mb_convert_encoding( $str, $encoding, 'UTF-8' ) );
}
?>

これを実行すると以下のようになります。

PHP5.2.17
ISO-2022-JP : ????? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
JIS : アイウエオ ? ? ? ? ? ? ? ? ? ? ? ? ? ?
ISO-2022-JP-MS : アイウエオ ㈱ ㈲ ① ② Ⅰ Ⅱ ℡ ㎏ ㎎ 﨑 髙 神 ? ?

ISO-2022-JPとJISの違いは半角カナが使えるかどうか。ISO-2022-JP-MSはそれに加えて機種依存文字や外字まで使えてしまう。ってことですかね。

メール送信で使えそうな気がしますが、”-MS”と付いてるだけあってWindows以外では化けると思います。
Macは試してませんが携帯宛だど髙などが絵文字か空白か「?」に化けてました。

ということで、半角カナを使われそうな携帯などで”JIS”、それ以外では”ISO-2022-JP”を使って”ISO-2022-JP-MS”は使わない方が無難。

instagramの画像見たときにアーカイブ(listagram)のリンク付けるだけのGreasemonkeyスクリプト

instagramでアップロードした画像を一覧表示してくれる「listagram」というサイトがめっちゃ便利なんでinstagram開いたら「アーカイブ」ってリンク追加しただけ。

ついでに説明っぽいのあったら付け足してる。

2011/02/07
プロフィール画像設定してない場合はユーザーID取得できないので「アーカイブ」のリンク追加しないように修正

ダウンロード: instagram_archive.user.js
(listagramよりI4PCの方が個人的に好きなので終了)


// ==UserScript==
// @name           instagram archives
// @description    add instagram photo info, listagram archive link
// @version        1.3
// @author         oflow
// @namespace      http://oflow.me/
// @include        http://instagr.am/p/*
// @exclude        https://*
// ==/UserScript==

(function() {
    var css = [
        '.profile-photo { float: none !important; position: absolute; }',
        '.profile-info { float: none !important; margin-left: 60px; }',
        '.profile-info h1 { margin-bottom: 0.3em; }',
        '.profile-info h1 span { font-weight: normal; margin-left: 0.5em; font-size: 90%; }'
    ].join('');

    function getMeta() {
        var meta = document.getElementsByTagName( 'meta' );
        for ( var i = 0, length = meta.length; i < length; i++ ) {
            if ( meta[i].getAttribute( 'property' ) == 'og:description' ) {
                addOgDescription( meta[i].getAttribute( 'content' ) );
                break;
            }
        }
    }

    function addOgDescription( content ) {
        if ( !content ) return;
        var span = document.createElement( 'span' );
        span.appendChild( document.createTextNode( content ) );
        var h1 = document.getElementsByTagName( 'h1' )[0];
        if ( h1 ) {
            h1.appendChild( span );
        }
    }

    function addListagram() {
        var profileImg = document.getElementsByClassName( 'photo-info' )[0].getElementsByTagName( 'img' )[0];
        if ( !profileImg ) return;
        if ( !//profile_([0-9]+)_/.test( profileImg.src ) ) {
            return;
        }
        var id = RegExp.$1;
        var profileInfo = document.getElementsByClassName( 'profile-info' )[0];
        profileInfo.appendChild( document.createTextNode( ' · ' ) );
        var a = document.createElement( 'a' );
        a.href = 'http://listagr.am/u/' + id;
        a.appendChild( document.createTextNode( 'アーカイブ' ) );
        profileInfo.appendChild( a );
    }
    GM_addStyle( css );
    getMeta();
    addListagram();

} )();

PHPでFizzBuzz問題を考えてみた

まず、FizzBuzz問題とは。

1~100までの数字で3で割り切れる時は「Fizz」、5で割り切れる時は「Buzz」、両者で割り切れる時は「FizzBuzz」と出力する。

たったこれだけです。
せんだ!みつお!なはなは!とか3の倍数と3が付くときのアレみたいな感じです。

「2分以内で書け」や「1行で書け」や「○○バイト以内で書け」や「%を使うな」などの条件を付ける場合もありますが、これをPHPで書いたらどうなるかと思いましてやってみました。

<?php
for ( $i = 1; $i <= 100; $i++ ) {
    if ( $i % 15 == 0 ) {
        print 'FizzBuzz';
    } else if ( $i % 3 == 0 ) {
        print 'Fizz';
    } else if ( $i % 5 == 0 ) {
        print 'Buzz';
    } else {
        print $i;
    }
    print "n";
}
// <プークスクス
?>

実行結果

ハッ 嘲笑なんか気にしなければこれで良いんですよ!!

では「1行で書く」ってのを考えると、これを改行入れなければいいじゃん?ってなる訳で「どれだけ短く書けるか」ってのに挑戦しました。

まず、 if { } else if { } … この辺が長いので三項演算子を使うことに。
あまりひねらない書き方ですが、それぞれを三項演算子に置き換え、1行で書いた方が短いので for文の {} や余計なスペース、最後のセミコロンも省略します。

<?php for($i=1;$i<=100;$i++)print($i%15?($i%3?($i%5?$i:'Buzz'):'Fizz'):'FizzBuzz')."n"?>

何かそれっぽくなってきた!!
この時点で89バイト。

更に短くするにはと思いついたのが
for ( $i = 1; $i <= 100; $i++ ) の部分です。ここを for ( $i = 1; $i < 101; $i++ ) にしたら1文字減りますね。 何かで見た事あった次の書き方でも動きます。 for ( $i = 0; ++$i < 101; ) これでいい気もしますが101ってのがどうも気に入らないので1減らして for ( $i = 0; $i++ < 100; ) この書き方の方が見やすいかもです。文字数変わりませんし。 [php title="1行でFizzBuzz (87バイト)"]<?php for($i=0;$i++<100;)print($i%15?($i%5?($i%3?$i:"Fizz"):"Buzz"):"FizzBuzz")."n";?>[/php] これをTwitterに書いた直後に print を echo に変えるって気付きました。 echo は print と違って ,(コンマ) で区切って出力するって方法があります。ついでに最初の <?php を <? でもいいっての思い出して [php title="79bytes"]<?for($i=0;$i++<100;)echo$i%15?($i%3?($i%5?$i:'Buzz'):'Fizz'):'FizzBuzz',"n"?>[/php] ギリギリ80バイトの壁を越えました。 もうこの辺からparse error覚悟で動けばいいや!ってスペースどこ削って大丈夫か体当たり的になってます。 echo$i なんか続けて書いていいのかよ!とツッコミ入れたい。 ただ、この書き方 15の時がどうにか出来そうな気がします。 「3で割り切れる」=「FizzもしくはFizzBuzzなのでFizzだけ出力」、「5で割り切れない」=「数字だけ」ということを頭に入れて15という数字を消すと [php gutter="0" classname="inline"]( $i % 3 ( $ % 5 ? $i : '' ) : 'Fizz' ), ( !$i % 5 ? 'Buzz' : '' )[/php] こう書くこともできます。 いや ( !$i%5 ? 'Buzz' : '' ) は逆に出来るじゃないか… ということで ( $i%5 ? '' : 'Buzz' ) それでPHPの定数で思い出した事が1つ。 定義してない定数(主にtypo)はそのまま定数名が出力されたことありませんか? このPHPのいい加減な何でも文字列を利用して 「Fizz, Buzzという定数のつもりだけど実は定義してなかったからそのまま出力してね!」作戦。 [php title="FizzBuzz 67bytes "]<?for($i=0;$i++<100;)echo$i%3?($i%5?$i:''):Fizz,$i%5?'':Buzz,"n"?>[/php] ここで67バイトまで縮めることが出来ました。 ギブアップ。 翌日、forじゃなくても良いんじゃね?て思いwhileに変えると結構短く出来ました。 [php title="FizzBuzz 63bytes"]<?while($i++<100)echo$i%3?($i%5?$i:''):Fizz,$i%5?'':Buzz,"n"?>[/php] ここで、Twitterにpostしたところ救世主 @daira4000 さんに「三項演算子の()を外して、nを直接LFにする」と教えて頂きましてさらに短くなり、最後の ?> は ; に変えても大丈夫ということでついに60バイトの壁突破。

<?while($i++<100)echo$i%3?$i%5?$i:'':Fizz,$i%5?'':Buzz,"
";

実行結果

ΩΩΩ< ()は消しても大丈夫なのか-!!!
さらに考えたけど順番が変わった程度でした。

<?while($i++<100)echo$i%3?'':Fizz,$i%5?$i%3?$i:'':Buzz,"
";

PHPでは最短56バイトで書けるらしいんですがそんな脳みそは持ち合わせておりません。おわり。

へっぽこスクリプト・スタイルシート