トップ «前の日記(2007-10-24) 最新 次の日記(2007-11-03)» 編集

Route 477



2007-11-01

[junk] 風邪

最近更新がなかったのは風邪気味だったからで、風邪を引くと判断力が低下するので つい夜更かししてしまい、更に風邪が悪化するという悪循環。

しかし副作用として、DTD HARDでハイスコアが出た(9700)。

[javascript] mootoolsのダウンロード版ドキュメントを作った

ネット繋がってないとリファレンス引けないのは不便だよねー、ということで。

[ruby] 大量のhtmlのリンクを一瞬で張り直すRubyスクリプト

ごめん一瞬は嘘かも。8瞬くらいで。

上のmootoolsのリファレンスを作るためにとりあえずhtmlを全部ダウンロードしたんだけど *1、拡張子が全部jsになってたり、cssが絶対パスになってたりで このままでは使えない。

というわけで、フィルタを適用しながらディレクトリを複製するRubyスクリプトを書いてみた。

#
# filter_mirror.rb
#
class FilterMirror
  def self.run(src, dst, filter = lambda{|f, d| [f, d]})
    new(src, dst, filter).run
  end

  def initialize(src, dst, filter)
    @src_path, @dst_path, @filter = src, dst, filter
  end

  def run
    Dir.glob("#{@src_path}/**/*").each do |from|
      to = from.dup
      to[/\A#{Regexp.quote(@src_path.to_s)}/] = @dst_path.to_s

      if File.directory?(from)
        to, data = @filter.call(to, "")
        Dir.mkdir(to)
      else
        data = File.open(from, "rb"){|f| f.read}
        to, data = @filter.call(to, data)
        File.open(to, "wb"){|f| f.write data}
        puts "wrote #{to}"
      end
    end
  end
end

呼び出し元はこちら。

#
# mootools_relink.rb
#
require 'rubygems'
require 'hpricot'
require 'pathname'
require 'filter_mirror.rb'

# フィルタ

filter = proc{|path, data|
  # ファイル名の修正
  unless path =~ /scripts/
    path.sub!(/\.js\z/, "\.html")  # *.jsを*.htmlにリネーム
  end
  path.sub!(/css\....\.css/, "css") # *.css.xzc.css → *.css

  # ファイル内容の修正
  if path =~ /\.html\z/
    is_index = (path =~ /index\.html\z/)

    doc = Hpricot(data)
    # 全てのaタグに対し
    (doc/:a).each do |a|
      if a["href"]
        a["href"] = a["href"].sub(/\.js/, "\.html")           # *.jsへのリンクを*.htmlに
        a["href"] = a["href"].sub(%r{\A../}, "") if is_index  # index.htmlなら ../ を除去
      end
    end
    # 全てのlinkタグに対し(css)
    (doc/:link).each do |link|
      link["href"] = link["href"].sub(%r{\A/styles/}, is_index ? "styles/" : "../styles/")
    end
    # 全てのscriptタグに対し(javascript)
    (doc/:script).each do |script|
      script["src"] = script["src"].sub(%r{\A/scripts/}, is_index ? "scripts/" : "../scripts/")
    end
    data = doc.to_html
  end

  return [path, data]
}

# メイン

if ARGV.size < 2
  puts "usage: #{$0} from to"
  exit
end
src_path = Pathname.new(ARGV[0])
dst_path = Pathname.new(ARGV[1])
if dst_path.exist?
  puts "error: #{dst_path} already exists"
  exit
end
dst_path.mkdir

FilterMirror.run(src_path, dst_path, filter)

フィルタはファイルのパス名とファイルの中身を引数に取り、それらの配列を返す。 変更しない場合はそのまま返せばいい。ここではHpricotを使ってリンクの張り直しをしています

Hpricotについてはこちらをどうぞ。

*1 wgetなりgethtmlwなりで

[ruby] procとProc.new

前者はreturnできるが後者はreturnできないらしい?

(11/2追記:http://d.hatena.ne.jp/ha-tan/20071031/1193883317 で書かれてました。return先が違うのね。)

[Plagger] Publish::HTMLというプラグインを書いてみた

みんなEFTのテストとかどうやってるんですかね?いちいちGMailに送って確かめる、ってのも面倒すぎるよなぁ。

というわけで、Perlの練習がてらにエントリをHTMLに出力するプラグインを書いてみたよ。

package Plagger::Plugin::Publish::HTML;
use strict;
use warnings;
use base qw( Plagger::Plugin );

our $VERSION = '0.01';

use File::Spec;
use IO::File;

sub register {
    my($self, $context) = @_;
    $context->register_hook(
        $self,
        'publish.feed' => \&feed,
    );
}

sub feed {
    my ($self, $context, $args) = @_;

    # open file
    my $dir = $self->conf->{dir};
    unless (-e $dir && -d _) {
        mkdir $dir, 0755 or $context->error("mkdir $dir: $!");
    }
    my $file = Plagger::Util::filename_for($args->{feed}, $self->conf->{filename} || "%i.html");
    my $path = File::Spec->catfile($dir, $file);
    my $io = IO::File->new("> $path");

    # output feeds
    my $feed = $args->{feed};
    my $encoding = $self->conf->{encoding} || 'utf-8';
    my $body = $self->templatize('html.tt', { feed => $feed, encoding => $encoding });

    $io->printf("%s\n", $body);

    # log
    $context->log(
        info => sprintf(
            "Write to %s: %d entries",
            $path,
            $args->{feed}->count
        )
    );
}

1;
__END__

=head1 NAME

Plagger::Plugin::Publish::HTML - Output to HTML

=head1 SYNOPSIS

  - module: Publish::HTML
    config:
      dir: /var/www/hoge
      encoding: euc-jp
      filename: my_%t.html

=head1 DESCRIPTION

This plugin creates HTML.

Template is loaded from assets/plugins/Publish-HTML/html.tt .

=head1 CONFIG

=head2 dir

Directory to save html files in.

=head2 filename

Filename to be used to create html files. It defaults to C<%i.html>. It
supports the following format like printf():

=over 4

=item * %u url

=item * %l link

=item * %t title

=item * %i id

=back

=head1 AUTHOR

yhara

=head1 SEE ALSO

L<Plagger>

=cut

Publish::GmailとPublish::CVSの実装を大いに参考にしました(ていうかほとんど繋ぎ合わせただけ)。

assetsはこんな感じ。assets/plugins/Publish-HTML/html.tt に置いてください。

[% USE util = Plagger.Util -%]
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=[% encoding %]" />
</head>
<body>
<h1>feed "[% feed.title %]"</h1>
url: [% feed.link %] <br/>

[% FOREACH entry = feed.entries -%]
<div style="border:1px dotted black; margin:0.5em; padding:0.5em">
<div>
<h2>entry "[% entry.title %]"</h2>
[% IF entry.icon %]
<a href="[% entry.permalink | html %]">
        <img [% util.dumbnail(entry.icon, width=150, height=60) %] style="border:0" align="right"
        src="[% entry.icon.url | html %]" alt="[% (entry.icon.title || entry.title) | html %]" />
</a>
[% ELSIF feed.image %]
<a href="[% feed.link | html %]">
        <img [% util.dumbnail(feed.image, width=150, height=60) %] style="border:0" align="right"
        src="[% feed.image.url | html %]" alt="[% feed.title | html %]" />
</a>
[% END -%]

[% IF entry.author %]by [% entry.author | html %][% END %][% IF entry.tags.size %] on [% entry.tags.join(',') %][% END %]</div>
[% IF entry.body -%]
[% IF entry.body.match('(?i)^<p[ >]') %][% entry.body %][% ELSE %]<div style="padding: 1em 0">[% entry.body %]</div>[% END %]
[% ELSE %]<br />[% END %]
<div style="font-size:0.8em">
        Posted on [% entry.date ? entry.date.format('Mail') : "?"%] |
        <a href="[% entry.permalink | html %]">permalink</a> [% FOREACH widget = entry.widgets %] |
        [% widget.html(entry) %][% END %]
        <br clear="all" />
</div>
</div>
<!--[% UNLESS loop.last %]<hr />[% END %]-->
[%- END %]
</body>
</html>

[ruby] Hpricotの:nth-childの実装が間違ってる件

1 originにしようとして -1 originになってるっぽいw

パッチ:

*** elements.rb 2007-10-08 17:52:23.000000000 +0900
--- elements.rb.new     2007-11-02 02:41:32.000000000 +0900
***************
*** 422,428 ****
        case arg
        when 'even'; (parent.containers.index(self) + 1) % 2 == 0
        when 'odd';  (parent.containers.index(self) + 1) % 2 == 1
!       else         self == (parent.containers[arg.to_i + 1])
        end
      end

--- 422,428 ----
        case arg
        when 'even'; (parent.containers.index(self) + 1) % 2 == 0
        when 'odd';  (parent.containers.index(self) + 1) % 2 == 1
!       else         self == (parent.containers[arg.to_i - 1])
        end
      end

[hiki] パッチを <<< で貼り付けられない

こっちはパッチなし(ごめんなさい)

[ruby] 変数に代入した値を簡単に確認する方法

例えば

n = calc(a,b,c)

というコードでcalcの返り値を見たいときは、

p n = calc(a,b,c)

とすると簡単に確認できる。

[misc] 知識と技術と発想

http://d.hatena.ne.jp/higepon/20071101/1193915666

知識と技術はともかく、発想ってどうやって鍛えるんだろう。

[vim] vimの楽しみ

当時はこのキーを押すと画面に文字が出るってのが楽しくてしかたがなかったので、どんなしょうもないプログラムを入力するのも楽しくてしかたがなかった

[2007-10-31 - ABAの日誌より引用]

vim使ってると「いくつかキーを押すだけで複雑な編集処理ができる」ってのが楽しくてしかたがないので、 どんなしょうもないプログラムを入力するのも楽しくてしかたがない (というとさすがに過言かw)。