« 2007年6月 | トップページ | 2007年8月 »

2007年7月21日 (土)

はてなスター設置その後

前回の記事にてはてなスターの設置についてのエントリーを書きました。
なにやらブックマークしてくれる人がいたりはてなスター日記のほうにもほんのちょっと取り上げていただいている様子

そのコメントの中に、「ただし、このブログでは、Main Index(トップページ)にのみ設置している模様。」というものがありました。気づいてなかった・・・

というわけでいじってみました。不格好な方法かもしれないけれど解決しました。
まず、なんで一記事単位表示だとうまくいかないかについて書きます。

はてなスターが必要とする情報は、タイトルとpermalinkURLだけです。はてなスターでは、以下のように、h3要素の中にリンクが含まれている場合に、それをタイトルとpermalinkである、と判断します。
はてなスターをブログに貼り付けるより

とあるようにh3要素の中にリンクが必要になっているのですが、一記事単位はタイトルがリンクになっていないのです。

それで解決法ですが、

記事の検出をしているのは「Hatena.Star.EntryLoader」というオブジェクトの「loadEntries」メソッドです。このコードを上書きすることで、はてなスターに正しく記事のタイトルとpermalinkを認識させることができます。
はてなスターをブログに貼り付けるより

とのことですので、同ページにのっているものを参考に

<script type="text/javascript" src="http://s.hatena.ne.jp/js/HatenaStar.js"/>
<script type="text/javascript">
  Hatena.Star.Token = 'd1b02052474b7e28330ad1fbba7513eb57a1ebfe';
</script>
<script type="text/javascript">
  Hatena.Star.EntryLoader.loadEntries = function () {
        var entries = [];
        //var headers = document.getElementsByTagName('h3');
        var c = Hatena.Star.EntryLoader;
        var headers = c.getHeaders();
        for (var i = 0; i < headers.length; i++) {
            var header = headers[i];
            var a = header.getElementsByTagName('a')[0];
            var uri;
            if (a) {
              uri = a.href;
            }
            else {
              uri = Ten.DOM.getElementsByTagAndClassName("a","permalink",document)[0].href
            }
            var title = '';
            var cns = header.childNodes;
            title = c.scrapeTitle(header);
            var cc = c.createCommentContainer();
            header.appendChild(cc);
            var sc = c.createStarContainer();
            header.appendChild(sc);
            entries.push({
                uri: uri,
                title: title,
                star_container: sc,
                comment_container: cc
            });
        }
        return entries;
  }
</script>

というスクリプトをメモのところに置きました。無理やりなので、ココログかはてなスターの仕様が変わったらすぐダメになりそうで怖いです。
ちなみに

<script type="text/javascript">
  Hatena.Star.Token = 'd1b02052474b7e28330ad1fbba7513eb57a1ebfe';
</script>
<script type="text/javascript">
  Hatena.Star.EntryLoader.loadEntries = function () {

の</script><script type="text/javascript">のところを無駄かと思って消したらうまくいきませんでした。これは

外部ブログの認証にはブログトップページにトークンの記述が必要です

はてなスターをブログに貼り付けるより

とうことなのだと思います。

| | コメント (0) | トラックバック (0)

2007年7月15日 (日)

はてなスター設置

[観] はてなスターを設置してみました を参考に設置してみました。
私はベーシックなので、マイリストの方で。手順としては、

  1. リンクタイプのリストを作成。
  2. 適当な項目を作る。
  3. その項目のメモのところに
  4. <script type="text/javascript" src="http://s.hatena.ne.jp/js/HatenaStar.js"/>
    <script type="text/javascript">
      Hatena.Star.Token = 'd1b02052474b7e28330ad1fbba7513eb57a1ebfe';
      Hatena.Star.EntryLoader.headerTagAndClassName = ['h3', null];
    </script>

    こんな感じで張り付ける。

  5. 設定のメモの表示を「テキスト表示」に変更する。

追記
この方法だけだと個別ページにはてなスターが出ません。
こちらの参照もお願いします。

| | コメント (0) | トラックバック (0)

2007年7月14日 (土)

C言語でAdapter

Adapterパターンは、あるものとあるものを繋ぐために間に何かをはさむパターン。

Adapterに関して言えば、オブジェクト指向言語より手続き型言語の方が一個関数を定義するだけなので、作りやすいと思う。

例えばmallocというメモリ領域を動的にとる関数が標準ライブラリで提供されているが、引数が確保したいバイト数になっている。そのため、int型を10個分確保したいときは、

int *array = malloc(sizeof(int) * 10);

の様に書かないといけないのでちょっと面倒だ。そこで、型と数の二つを引数で与えるとその分のメモリ領域を取れるようにしたいと思ったとする。

そのとき新たに関数を作ると、

  1. 一から関数を作るのは作るための労力がかかる
  2. もしもmallocが変わったときに対応する必要がでてくるかもしれない

Adapterパターンを使えば以上の問題に対応することができる。具体的には、

#define malloc2(type, number) (malloc(sizeof(type) * (number)))

という内部でmallocを使う新しい関数(マクロ)を作る。そうすると、

int *array = malloc2(int, 10);

のように望んでいた使い方ができる関数ができる。

| | コメント (0) | トラックバック (0)

2007年7月 1日 (日)

C言語でIterator

C言語でSingleton
C言語でSingleton 2
に続いてIteratorをC言語で実装してみます。

とりあえず、これをみてください。

#include <stdio.h>
#include "book_shelf.h"
#include "iterator.h"
#include "book.h"

int main()
{
    BookShelf bookShelf;
    Iterator  it;

    bookShelf = new_BookShelf(4);
    bookShelf->appendBook("Around the World in 80 Days");
    bookShelf->appendBook("Bible");
    bookShelf->appendBook("Cinderella");
    bookShelf->appendBook("Daddy-Long-Legs");

    it = bookShelf->iterator();
    while (it->hasNext()) {
        Book book = (Book)it->next();
        printf("%s\n", book);
    }

    return 0;
}

実行結果が

Around the World in 80 Days
Bible
Cinderella
Daddy-Long-Legs

ループを回すのに配列の大きさを意識しなくていいことと、裏の仕組みを後で書きかえれる事が利点。
今回はファイルが多いので、zipファイルでまとめて公開。
「Iterator.zip」をダウンロード
展開すると下のリストのように展開されます。とりあえず、まとめてコンパイルすれば実行形式ファイルはつくれます。

  • main.c : 上のやつ
  • iterator.h : Iterator構造体の定義
  • aggregate.h : Aggregate構造体の定義
  • book.h : Book変数の定義
  • book_shelf.h : BookShelf構造体の定義
  • book_shelf.c : BookShelfの実装
  • book_shelf_iterator.h : BookShelfIterator構造体の定義
  • book_shelf_iterator.c : BookShelfIteratorの実装

この書き方はJavaでの実装をそのままC言語に落としただけだから、C言語っぽくはないのだと思う。

gccだと、

tree_stmt_iterator si;

for (si = tsi_start (node); !tsi_end_p (si); tsi_next (&si))
  {
    if (!first)
 newline_and_indent (buffer, spc);
    else
      first = false;
  dump_generic_node (buffer, tsi_stmt (si), spc, flags, true);
  }
}
http://gcc.yokinihakarae.com/S/824.html#L862

のように使用するIteratorを使っている。内部的には連結リストになっていて、リストの先頭をtsi_startで取得して、それをtsi_nextでたどっていく。NULLをさすようになったらtsi_end_pが真を返すようになる。みたいな感じ。

詳しくは、
http://wikiwiki.jp/aloha/?cmd=read&page=ssa_op_iter
なりを参考にソースを読んでください。(とGCC 解読室 Wiki*の宣伝)

| | コメント (0) | トラックバック (1)

« 2007年6月 | トップページ | 2007年8月 »