FLV::Info で ustream の FLV ファイル情報をとろうとするとエラーになる件

Posted by Gosuke Miyashita Mon, 08 Oct 2007 05:07:00 GMT

ustream の FLV をダウンロードして音声変換する方法は、typesterさんのとこに詳しく書いてある わけですが、sox に渡すときにサンプルレートを指定する必要があったりします。

で、これを Plagger プラグインで実現するためには、何らかの方法で元ファイルのサンプルレートを取得しないといけないわけで、FLV::Info でできそうだな、と思ったところ

Failed to read FLV file: Tag size is too small (0) at byte 193 (0xc1) at /usr/local/lib/perl5/site_perl/5.8.7/FLV/Tag.pm line 81.

といったエラーが出ます。色々調べてみたところ、ustream の FLV ファイル中に、ボディが 0 のオーディオタグが存在するから、ということがわかったので、パッチを書いて RT に投げておきました。

パッチ自体は数行コメントアウトして1行追加しただけ、という簡単なものなのですが、このパッチを書くために、FLVのファイルフォーマット を調べて、音声フォーマットを取得する Perl スクリプトを自分で書いてみたりと、えらく回り道しました。せっかくなんでスクリプトを載せておきます。スクリプト作成にあたって、nelly2pcm のソースも参考にしています。

#!/usr/bin/perl

use strict;
use warnings;
use Readonly;

Readonly my $FLV_TAG_TYPE_AUDIO                => 0x08;
Readonly my $AUDIO_MASK_STEREO                 => 0x01;
Readonly my $AUDIO_MASK_16bit                  => 0x02;
Readonly my $AUDIO_MASK_RATE                   => 0x0c;
Readonly my $AUDIO_RATE_5point5KHZ             => 0x00;
Readonly my $AUDIO_RATE_11KHZ                  => 0x04;
Readonly my $AUDIO_RATE_22KHZ                  => 0x08;
Readonly my $AUDIO_RATE_44KHZ                  => 0x0c;
Readonly my $AUDIO_MASK_FORMAT                 => 0xf0;
Readonly my $AUDIO_FORMAT_UNCOMPRESSED         => 0x00;
Readonly my $AUDIO_FORMAT_ADPCM                => 0x10;
Readonly my $AUDIO_FORMAT_MP3                  => 0x20;
Readonly my $AUDIO_FORMAT_NELLYMOSER_8KHZ_MONO => 0x50;
Readonly my $AUDIO_FORMAT_NELLYMOSER           => 0x60;

Readonly my %AUDIO_RATE => (
    $AUDIO_RATE_5point5KHZ => 5.5,
    $AUDIO_RATE_11KHZ      => 11,
    $AUDIO_RATE_22KHZ      => 22,
    $AUDIO_RATE_44KHZ      => 44,
);

Readonly my %AUDIO_FORMAT => (
    $AUDIO_FORMAT_UNCOMPRESSED         => 'Uncompressed',
    $AUDIO_FORMAT_ADPCM                => 'ADPCM',
    $AUDIO_FORMAT_MP3                  => 'MP3',
    $AUDIO_FORMAT_NELLYMOSER_8KHZ_MONO => 'Nellymoser 8kHz mono',
    $AUDIO_FORMAT_NELLYMOSER           => 'Nellymoser',
);

my $file = shift;

open my $fh, '<', $file;

my $header = read_header($fh);

while ( ! eof $fh ) {
    my $tag = read_tag($fh);
    if ( $tag->{type} == $FLV_TAG_TYPE_AUDIO and $tag->{length} ) {
        my $first_byte = $tag->{first_byte};

    my $stereo       = $first_byte & $AUDIO_MASK_STEREO;
    my $audio_size  = $first_byte & $AUDIO_MASK_16bit ? 16 : 8;
        my $audio_rate   = $AUDIO_RATE{ $first_byte & $AUDIO_MASK_RATE } || 'unknown';
        my $audio_format = $AUDIO_FORMAT{ $first_byte & $AUDIO_MASK_FORMAT } || 'unknown';

        print 'audio type: ' . ( $stereo ? 'stereo' : 'mono' ) . "\n";
        print "audio size: $audio_size bit\n";
        print "audio rate: $audio_rate Hz\n";
        print "audio format: $audio_format\n";
        last;
    }
}

sub read_header {
    my $fh = shift;
    read $fh, my $sig,       3;
    read $fh, my $version,   1;
    read $fh, my $flag,      1;
    read $fh, my $offset,    4;
    read $fh, my $prev_tag,  4;

    return {
        sig => $sig,
        version => unpack('H*', $version),
        flag    => unpack('H*', $flag),
        offset  => unpack('H*', $offset),
    };
}

sub read_tag {
    my $fh = shift;
    read $fh, my $type,               1;
    read $fh, my $length,             3;
    read $fh, my $timestamp,          3;
    read $fh, my $timestamp_extended, 1;
    read $fh, my $stream_id,          3;
    read $fh, my $first_byte,         1;

    my $pos = hex unpack 'H*', $length;
    seek $fh, $pos - 1, 1;

    read $fh, my $prev_tag,  4;

    return {
        type       => unpack('C', $type),
        length     => $pos,
        first_byte => unpack('C', $first_byte),
    };
}

こんな感じで FLV ファイルの音声情報を表示します。

$ ./get_flv_info.pl broadcast_35957_1191232400660.flv
audio type: mono
audio size: 16 bit
audio rate: 11 Hz
audio format: Nellymoser  

あとは Plagger プラグインを書くだけ、という感じなのですが、リビドーが沸いてこないのでちょっと保留。FFmpeg で Nellymoser に対応する予定がある(既に SVN HEAD には Nellymoser という文字列がコード中にある)ようなので、それまで待ってもいいかなー、と。

音声変換するプラグイン Filter::Audio は coderepos にあげてありますので、俺が対応してやるぜ、という方はお好きなようにいじってください。

Shibuya.pm テクニカルトーク #8 でしゃべってきました

Posted by Gosuke Miyashita Mon, 01 Oct 2007 14:18:00 GMT

プレゼン途中にバッテリーが切れるという失態をやらかしたため、yusukebeさん言うところの「お口で」のみのプレゼンとなってしまいました。ごめんなさい。会場でお見せできなかった幻の資料はこちらにアップしておきます

Thinkpad X60sはバッテリー残量表示が1時間になっていても、プレゼンやると2,3分でバッテリー切れますので、みなさんご注意下さい。

Trac の SearchHyperEstraierPlugin を Trac 0.10.x で動かすパッチ

Posted by Gosuke Miyashita Wed, 08 Aug 2007 18:03:00 GMT

SearchHyperEstraierPlugin が、Trac 0.10.x というか、うちの環境で動かないので、パッチ書いた。初 Python プログラミング。(というほどのものじゃないけど。)


=== searchhyperestraier/searchhyperestraier.py
==================================================================
--- searchhyperestraier/searchhyperestraier.py    (revision 892)
+++ searchhyperestraier/searchhyperestraier.py    (local)
@@ -2,8 +2,9 @@
 # SearchRepositoryWithNamazu plugin

 from trac.core import *
-from trac.Search import ISearchSource, query_to_sql, shorten_result
+from trac.Search import ISearchSource, shorten_result
 from trac.util import NaivePopen
+from trac.util.text import to_unicode
 from StringIO import StringIO
 import urllib
 import time
@@ -44,9 +45,9 @@
         browse_trac = self.env.config.get('searchhyperestraier', 'browse_trac','enabled')

-        cmdline = "%s %s %s %s" % (estcmd_path,estcmd_arg,index_path,unicode(query,'utf-8').encode(estcmd_encode))
+        cmdline = "%s %s %s %s" % (estcmd_path,estcmd_arg,index_path,' '.join(query))
         self.log.debug('SearchHyperEstraier:%s' % cmdline)
-        np = NaivePopen(cmdline)
+        np = NaivePopen( cmdline.encode(estcmd_encode) )
         #self.log.debug('Result:%s' % unicode(np.out,'utf-8').encode('mbcs'))
         #self.log.debug('Result:%s' % np.out)
         if np.errorlevel or np.err:
@@ -74,7 +75,7 @@
             attrelem_array = element.getElementsByTagName("attribute")
             for attrelem in attrelem_array:
                 attr_name = attrelem.getAttribute("name")
-                attr_value = unicode(attrelem.getAttribute("value")).encode('utf-8')
+                attr_value = to_unicode(attrelem.getAttribute("value"))
                 #URLとタイトルを生成
                 if attr_name == "_lreal":
                     attr_value=attr_value[len(replace_left):].replace("\\","/")

エラーが出るたびに、適当にいじってたら動いた、という感じ。なので、こんなんでいいのかはよく分からない。

Pushmi つかってます & 技術者募集中 at 福岡 3

Posted by Gosuke Miyashita Thu, 02 Aug 2007 16:52:00 GMT

弊社 は東京と福岡にオフィスがあり、それぞれの拠点に Subversion + Trac 環境を構築し、OpenVPN により VPN 接続してお互いの開発状況を公開しています。サービス絡みの開発は基本的に、東京は東京、福岡は福岡で完結しているので、この方式で問題はないのですが、サーバ管理関連のスクリプトなんかは、東京と福岡で共通するものが多いため、別々の SVN リポジトリで管理されてると不便なんですよね。かといって、どちらかの拠点だけしかリポジトリがないと、VPN の障害発生時に、リポジトリのない拠点からはまったくアクセスができない、という困ったことになってしまいます。

そこで、SVN リポジトリレプリケーションツール Pushmi を導入してみました。詳細は YAPC::Asia での 作者 Cl Kao によるスピーチ動画 を見て頂くとして、ここでは行った設定についてメモを残しておきます。ほとんど perldoc Pushmi の内容と同じですが。

まず当然 Pushmi のインストールが必要です。これの手順は省略。また、より良いアトミックロック実現のために memcached を利用している、ということなのでインストールしておきます。これも手順は省略。

memcached を起動します。

$ sudo /usr/bin/memcached -p 8123 -dP /var/run/memcached.pid -u nobody

/etc/pushmi.conf を設定します。弊社の環境では memcached のポートのみ指定してます。

authproxy_port: 8123

ミラーリポジトリを作成します。

$ pushmi mirror /var/db/my-local-mirror http://master.repository/svn
Mirror initialized.

ミラーリポジトリとマスターリポジトリを同期します。

$ pushmi sync /var/db/my-local-mirror
Retrieving log information from 1 to 62

ミラーリポジトリは、svnadmin create で作成するのと同様なディレクトリ、ファイル構造になってますが、Pushmi 用の pre-commit スクリプトと post-commit スクリプトが置かれている、というところが異なります。

pre-commit では以下の様なコマンドが実行され、ミラーリポジトリにコミットされた内容を、マスターリポジトリにコミットしに行きます。

/usr/bin/pushmi runhook $1 --txnname $2

post-commit では以下の様なコマンドが実行され、ミラーとマスターの整合性を確認しています。

/usr/bin/pushmi verify $1 --revision $2

Apache + WebDAV で SVN リポジトリにアクセスするために、以下の様な設定を Apache で行います。

<Location /svn/server>
  PerlSetVar SVNPath /var/db/my-local-mirror
  PerlSetVar Pushmi /usr/bin/pushmi
  PerlSetVar PushmiConfig /etc/pushmi.conf
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    AuthName "mirrored private area" 
    AuthType Basic
    Require valid-user
    AuthLDAPURL ldap://localhost:389/ou=people,o=paperboy?uid?sub?(objectclass=*)
    PerlAuthenHandler Pushmi::Apache::AuthCommit
  </LimitExcept>
</Location>

設定見て分かると思いますが、mod_perl を利用していて、Apche2 + mod_perl の環境が必要です。Apache は 2.0 系でも 2.2 系でも大丈夫なようです。弊社では 2.0 系を利用しています。

特にポイントとなるのは、

PerlAuthenHandler Pushmi::Apache::AuthCommit

の部分で、認証で渡されたユーザ名、パスワードをこのモジュールで memcached にキャッシュしておき、マスタリポジトリへのコミット時の認証に利用します。Apache 2.2 系の場合には、以下の様に設定します。

AuthBasicProvider Pushmi::Apache::RelayProvider

この状態では、ミラーへのコミットは即マスターに反映されますが、マスターへのコミットはミラーに反映されませんので、以下の様な cron 設定を行い、5分おきにマスターとミラーを同期するようにします。

*/5 * * * * /usr/bin/pushmi sync --nowait /var/db/my-local-mirror

今のところこれで問題なく動いています。

話変わりまして、弊社福岡支社では、プログラマサーバエンジニア を募集しています。Pushmi を実戦で使ってみたい!という方はぜひ。メガネ女子プログラマもいますよ。(東京本社にもいます。人妻ですが。)

FizzBuzz アセンブラ版 for x86/Linux

Posted by Gosuke Miyashita Sun, 13 May 2007 12:01:00 GMT

竹迫さんYappo さん に触発されて、FizzBuzz アセンブラ版 for x86/Linux をつくってみた。

20年ほど前に Z80 でアセンブラをちょっとかじった程度の知識しかないので、ベストには程遠いコードだと思います。だれかもっといいコードを教えてください。

最初竹迫さんのコードと同じように書けるかな、と思ったのですが、Windows とちがって、画面に表示するだけで EAX, EBX, ECX, EDX レジスタ使うので、竹迫さんのように BX レジスタを見張り役に、CX レジスタをカウンタに、ってことができませんでした。

また、とりあえず書いただけで疲れたので、コードゴルフにチャレンジする気力はありません。

global  _start

_start:
        mov     si, 0

mawasu: 
        call    space
        inc     si
        mov     ax, si

        mov     di, 3
        xor     edx, edx
        div     di
        cmp     dx, 0
        je      pfizz

        mov     ax, si
        mov     di, 5
        xor     edx, edx
        div     di
        cmp     dx, 0
        je      pbuzz

        call    num
        cmp     si, 100
        jb      mawasu

pfizz:
        call    fizz

        mov     ax, si
        mov     di, 5
        xor     edx, edx
        div     di
        cmp     dx, 0
        je      pbuzz

        jmp     mawasu

pbuzz:
        call    buzz
        jmp     mawasu

num:
        mov     ax, si

        mov     di, 100
        cmp     ax, di
        jnge    num2

        jmp     end

num2:
        mov     di, 10
        cmp     ax, di
        jnge    num3

        xor     edx, edx
        div     di
        add     ax, 48
        call    print

num3:   
        mov     ax, si
        mov     di, 10
        xor     edx, edx
        div     di
        mov     al, dl
        add     al, 48
        call    print
        ret

fizz:
        mov     al, 0x46
        call    print
        mov     al, 0x69
        call    print
        mov     al, 0x7a
        call    print
        call    print
        ret

buzz:
        mov     al, 0x42
        call    print
        mov     al, 0x75
        call    print
        mov     al, 0x7a
        call    print
        call    print
        ret

space:
        mov     al, 0x20
        call    print
        ret

print:
        push    eax
        mov     eax, 4
        mov     ebx, 1
        mov     ecx, esp
        mov     edx, 1
        int     0x80
        pop     eax
        ret

end:    
        mov     al, 0x0a
        call    print

        mov     al, 1
        mov     bl, 0
        int     0x80

nasm を使ってこんな感じで動かすことができます。

$ nasm -f elf fizzbuzz.asm
$ ld -s -o fizzbuzz fizzbuzz.o
$ ./fizzbuzz

fizzbuzz.asm

書いていてアセンブラの TMTOWTDI っぷりは Perl の比じゃないと思った。

Re: DBICとDBIx::Class::Schema::Loader 僕のいろいろな勘違い 2

Posted by Gosuke Miyashita Sun, 06 May 2007 10:11:00 GMT

ブログが続かないわけ | DBICとDBIx::Class::Schema::Loader 僕のいろいろな勘違い にて、

とはいえ、僕の稼働中のアプリはすでに手動型のSchema で動いている。スキーマを作り直したら、リレーションの設定を全てしなおさなければならないので、それは現実的じゃない。inflate, deflate の指定は、やっぱりすべてのSchema にかかなきゃだめそうだ。

とあったので、これに関して少し楽ができる方法をコメントしようと思ったけれど、コメント欄ではうまく伝えられる自信がないので、こちらで書いてみることにしました。

load_components で 読み込む方法

DBIx::Class::Schema::Loader ではなく DBIx::Class::Schema を継承したスキーマの場合には、各スキーマファイルに以下の様に書いてあげれば OK です。(既にご存知かもしれませんが。)

package My::Schema::Table;

__PACKAGE__->load_components(
  "InflateColumn::DateTime",
  "PK::Auto",
  "Core",
);

すべてのスキーマファイルに書かなきゃいけないことには変わりありませんが、各カラムに inflate/deflate を設定するよりははるかに楽だと思います。

make_schema_at を使う方法

make_schema_at でスキーマファイルを生成しているのであれば、こんな感じでリレーションだけ定義した ./tmp/lib/My/Schema/Table.pm をまず用意します。

package My::Schema::Table;

__PACKAGE__->belongs_to(
    realation => 'My::Schema::OtherTable
    { 'foreign.id' => 'self.other_table_id' },
);

1;

でもって、こんなスクリプトを実行します。

#!/usr/bin/perl

use strict;
use warnings;

use lib qw( ./tmp/lib );
use Carp;
use DBIx::Class::Schema::Loader qw( make_schema_at dump_to_dir:lib dump_overwrite );

make_schema_at(
    'My::Schema::Table',
    {
        components     => [qw/ ResultSetManager UTF8Columns InflateColumn::DateTime /],
        dump_overwrite => 1,
    },
    ['dbi:mysql:dbname' ,'user', 'password'],
);

そうすると、lib/My/Schema/Table.pm に以下の内容を吐き出してくれます。

package My::Schema::Table;

# Created by DBIx::Class::Schema::Loader v0.03009 @ 2007-04-26 18:21:23

use strict;
use warnings;

use base 'DBIx::Class';

__PACKAGE__->load_components(
  "ResultSetManager",
  "UTF8Columns",
  "InflateColumn::DateTime",
  "PK::Auto",
  "Core",
);
__PACKAGE__->table("table");
__PACKAGE__->add_columns(
  "id",
  { data_type => "INT", default_value => undef, is_nullable => 0, size => 11 },
  "other_table_id",
  { data_type => "INT", default_value => 0, is_nullable => 0, size => 11 },
  "date",
  { data_type => "DATE", default_value => undef, is_nullable => 1, size => 10 },

__PACKAGE__->set_primary_key("id");
# These lines loaded from user-supplied external file:
package My::Schema::Table;

__PACKAGE__->belongs_to(
    employees => 'My::Schema::Table',
    { 'foreign.id' => 'self.other_table_id' },
);

1;
# End of lines loaded from user-supplied external file

この方法を使うと、スキーマを作り直しても、リレーションの再設定をしなくて済みます。

手動でやるのが楽なのか、上の方法のいずれかを使うのが楽なのかは、状況にもよると思いますが、こんな方法もありますよ、ということで、ご参考になれば幸いです。

SVN::TracWiki #2

Posted by Gosuke Miyashita Mon, 30 Apr 2007 15:30:12 GMT

SVN::TracWiki (svn repos) をアップデート。以下の機能を実現するパッチを、Assurer の開発にも参加してくれている franck が送ってくれました。

  • Plugin::Extract::Pod で Perl プログラムのコミット時に、pod を自動で抽出して Wiki にアップ。
  • xmlrpc プラグインがなくても Wiki ポストができる。

Trac はソースコード自体の検索ができないので、当然 pod の内容も検索することができないのですが、このプラグインにより、pod の検索ができるようになります。

また、検索だけではなく、こんな感じ で pod を Trac の Wiki フォーマットに変換してキレイに表示してくれます。

試しに手元にあった XML::Atom をつっこんでみると、こんな感じ になります。

あと、File::Extract 内部で利用している File::MMagic::XS が謎の Segmentation Fault で落ちるので、File::MMagic を使うように強引に書き換えたり。

SVN::TracWiki #1

Posted by Gosuke Miyashita Sun, 22 Apr 2007 06:07:01 GMT

SVN::TracWiki (svn repos) について、ブクマコメントで miyagawa さんから「File::Extract?」というアドバイス?を頂きましたので、テキスト抽出部分を File::Extract ベースに書き換えてみました。

おかげでプラグインまわりの処理が少しすっきりした上に、File::Extract で対応しているファイルフォーマットであれば、SVN::TracWiki 用のプラグインを書かなくてもテキスト抽出ができるようになりました。(Excel で試しましたが、ばっちり動作しました。)

SVN::TracWiki #0

Posted by Gosuke Miyashita Sat, 21 Apr 2007 19:55:57 GMT

SVN::TracWiki というツールをつくってみました。svn repos はこちら

何をするものかというと、Subversion の post-commit スクリプトとして動作して、コミットされたファイルからテキストを抽出、そのファイルの実体へのリンクを付加して、Trac の Wiki へ自動ポストするというもの。

具体的な例としては、PowerPoint ファイルをコミットしたら、そのファイルからテキストのみを抽出して Wiki へ自動ポスト。こんな感じで

これで何がうれしいかというと、Subversion で管理している PowerPoint ファイルを、Trac 上で検索ができるようになります。こんな感じですね。元ファイルへのリンクもあるので、検索して元ファイルを開いて読む、ってことが簡単にできます。

例によって YAMLで設定 and プラガブル。ファイルからテキストを抽出する部分がプラグインになっていて、簡単に拡張できるようにしています。

現在は PowerPoint 用フィルタプラグインしかないのですが、以下の様なコードになっていて、フィルタ対象ファイルの MIME タイプを register() で指定、テキスト抽出ルーチンを filter() に記述、という感じで書きます。

package SVN::TracWiki::Plugin::Filter::PowerPoint;

use strict;
use warnings;
use base qw( SVN::TracWiki::Plugin::Filter );
use Encode;

sub register {
    my $self = shift;
    $self->register_mime_types( qw! application/vnd.ms-powerpoint !);
}

sub filter {
    my ( $self, $file ) = @_;
    my $html = `/usr/local/bin/ppthtml $file`;
    my $text = $self->strip_html($html);

    $text = Encode::decode('utf8', $text);
    $text = Encode::encode('utf8', $text);

    return $text;
}

1;

とりあえず動くようになっただけで、いけてない部分盛りだくさんですが、こんなのつくってみました、ってことで。

html-tt-mode を sgml-mode のマイナーモードで動くようにしてみた

Posted by Gosuke Miyashita Mon, 09 Apr 2007 08:36:45 GMT

Clouder::Blogger: html-tt - emacsのTemplate Toolkit用のmode を html-helper-mode ではなく、sgml-mode のマイナーモードで動くようにしたパッチ。(置換しただけ。)

別に sgml-mode に思い入れはなく、Meadow でデフォルトで動いてるからそのまま使ってるだけなので、html-helper-mode にしてもいいんだけど、どうも Meadow でうまく色づけされないので、その原因追求するよりも、sgml-mode で動くようにした方がはやかったので。

本当はどっちでも動くようにするのがいいんだろうけど、それはまた今度。

=== html-tt.el
==================================================================
--- html-tt.el	(revision 193)
+++ html-tt.el	(local)
@@ -66,7 +66,7 @@
 ;; Code:
 
 (provide 'html-tt)
-(require 'html-helper-mode)
+(require 'sgml-mode)
 (require 'tempo)
 (require 'font-lock)
 
@@ -217,38 +217,38 @@
 (defun html-tt-load-hook ()
   (interactive)
   ;; define key bind
-  ;(define-key html-helper-mode-map "\C-cs"
+  ;(define-key sgml-mode-map "\C-cs"
   ;  'html-tt-insert-sequence)
-  (define-key html-helper-mode-map "\C-cs"
+  (define-key sgml-mode-map "\C-cs"
     'tempo-template-html-tt-insert-sequence)
-  (define-key html-helper-mode-map "\C-cd"
+  (define-key sgml-mode-map "\C-cd"
     'html-tt-insert-directive)
-  (define-key html-helper-mode-map "\C-cn"
+  (define-key sgml-mode-map "\C-cn"
     'tempo-template-html-tt-insert-directive)
-  (define-key html-helper-mode-map "\C-ci"
+  (define-key sgml-mode-map "\C-ci"
     'tempo-template-html-tt-insert-if)
-  (define-key html-helper-mode-map "\C-cl"
+  (define-key sgml-mode-map "\C-cl"
     'tempo-template-html-tt-insert-elsif)
-  (define-key html-helper-mode-map "\C-ce"
+  (define-key sgml-mode-map "\C-ce"
     'tempo-template-html-tt-insert-else)
-  (define-key html-helper-mode-map "\C-cf"
+  (define-key sgml-mode-map "\C-cf"
     'tempo-template-html-tt-insert-foreach)
-  (define-key html-helper-mode-map "\C-cw"
+  (define-key sgml-mode-map "\C-cw"
     'tempo-template-html-tt-insert-while)
-  (define-key html-helper-mode-map "\C-cm"
+  (define-key sgml-mode-map "\C-cm"
     'tempo-template-html-tt-insert-switch)
-  (define-key html-helper-mode-map "\C-cn"
+  (define-key sgml-mode-map "\C-cn"
     'tempo-template-html-tt-insert-include)

   ;; add hilit-set-mode-pattern, if use hilit19.
   (if (featurep 'hilit19)
-      (hilit-add-pattern "\\[%" "%\\]" 'midnightblue 'html-helper-mode)
+      (hilit-add-pattern "\\[%" "%\\]" 'midnightblue 'sgml-mode)
     )
 
   ;; set font-lock
   (make-local-variable 'font-lock-defaults)
   (setq html-tt-font-lock-keywords
-	(append html-helper-font-lock-keywords html-tt-font-lock-keywords))
+	(append sgml-font-lock-keywords html-tt-font-lock-keywords))
   (setq font-lock-defaults '(html-tt-font-lock-keywords t t))
   ) 

.emacs での設定はこんな感じで。

(require 'html-tt)
(add-hook 'sgml-mode-hook 'html-tt-load-hook)

Older posts: 1 2 3 ... 18