2005年12月16日(金)
■[news] 荷造りひもで耐震補強、震度5強まで実証
http://www.asahi.com/national/update/1215/TKY200512150433.html
荷造りひもで耐震補強--世界の約6割の人々が住むれんがや石積みの建物を、各国で手に入るポリプロピレン製の安いひもで補強できることを、目黒公郎・東京大学生産技術研究所教授らが15日、実物大の建物模型を使った実験で証明した。補強にかかる材料費は1棟数千円で、途上国の地震被害軽減に役立てたいとしている。
れんがや日干しれんがに粘土などをはさんで積み上げた建物は、地震でばらばらになって倒壊しやすく、10月のパキスタン北部の地震でも大きな被害を出した。
目黒さんらは、荷造りひもを網状にしてれんがを覆い、壁を一体化する補強法を提案している。
補強なしと補強ありの実物大建物模型を造り、神奈川県相模原市にある東急建設技術研究所の振動台で実験した。補強なしだと震度5弱で倒壊したが、補強した建物は震度5強で多数のひびが入っても倒れなかった。続けて震度6弱の揺れにすると倒れた。
「どこから崩れるか分かったので、補強法の工夫によって、さらに強くできる。来年、パキスタンの被災地で実演し、普及を図る予定だ」と目黒さんは言っている。
問題は、ポリプロピレン製のヒモが耐候性がないことだよな。
そりゃー立ててすぐは大丈夫だが、表面に張って三ヶ月に1回ふきかえる、とかそーいう感じにならざるを得ないんだが、そーすると、その度に建物をイチから作るのと変らないコストが掛る。(日乾し煉瓦の家って、地域によっては 5000円くらいで建つんだぜ。だって、只の粘土と只同然のマンパワで作るんだからな)そいでもって、何十年に一度かの地震の為にそんなことやってられるか、って話になる訳だ。
貧困があるかぎり、どうにもならない。それを解決するのは残念ながら技術ではなくって政治なんだな。
■[elisp][hatena-mode] ファイル名から曜日を求める
●サブ問題 hatena-mode のファイル名から、当該する曜日を求める。
曜日は7の剰余類だから、適当な日を原点にとって、そこからの日数を7 で割った余りを見れば、曜日が分る。
けど、面倒だから date コマンドを使うことにする。
↓のようにすれば、hatena-modeのファイル名の書式から、当該する曜日の数値表現(0..6)を得ることが出来る。(日曜はゼロ)
$ date --date=20051224 +%w
●サブ問題 カレントバッファの名前
フルパスが必要な時は、buffer-file-name パスを省いたファイル名だけは buffer-name ちょっと分りにくいな。
だから、曜日の数値表現を返すコマンド文字列を作るには次のようにすればいい。
現在バッファと同名なバッファがあると他にあると問題が発生することが予測されるが、仕様とする (w
(concat "date --date=" (buffer-name) " +%w")
●サブ問題 elisp から外部プログラムを呼ぶ
出来ることは知っていたが、どうするのか完全に忘れたので info を見るも、どこを見ればよいのかすら仲々分らなかった。
答えは process ->Synchronous Processes こいつもちょっと分りにくいな。
入力を文字列で与え、出力を文字列で返すには shell-commandt-string を使えばよい。(でもこれって、最後に余分な改行をつけてくれるのがイヤーン)
という訳で、曜日を(0..6)な表現の数値で返すプログラムは↓のようになる
(defun hatena-mode-dow-from-buffer-name() "Return Day of Week(0..6) from current buffer name of hatena-mode." (string-to-number (shell-command-to-string (concat "date --date=" (buffer-name) " +%w"))))
date にパスが通っていることが必要だが、意図的にそういう環境にしない限り通ってないことなんてないよな。えっ、Meadow な人はどうするのかって、簡単簡単 windoze ヤメればいいんだよ。
● 番組のタイトルの取得
で、何がしたかったのか、というと、毎日冒頭につけている録画記録の入力の省力化
ここまでやったら、表題からズレてくるが番組のタイトルも自動取得したくなってくる。
例えば、20051216 の視点・論点のタイトルは次のようにすれば取得できる。
$ curl -s http://www3.nhk.or.jp/hensei/ch3/20051216/main_18-24.html | kcc -e | grep 視点・論点 -A 2 | tail -n 2 | perl -pe "s/.*「(.*)」.*/\1/"
ところが、elisp から、shell-command-to-string 経由でこいつを読んでやると、↑のように正規表現が日本語文字列を含む場合うなくいかないことがある。(↑の例だと()は正常に動作するが「」は駄目。perl 部分を↓のように独立したファイルにしてやるとうまくいくが、全く同一の内容を、elisp 経由のコマンドラインで動かそうとすると駄目。(shell では動くんだな、これが)
#!/usr/bin/perl
# -*- coding:euc-japan-unix; mode:cperl -*-
# tv_prgram_title_filter
# filer for tv program title
use Encode;
use encoding 'euc-jp';
while (<>) {
s/.*(「.*」).*/\1/;
print ;
}
※20051218 追記
一行perl コードの先頭に ↓のBEGIN ブロックを追加してやるとうまく動いた。
BEGIN{use Encode; use encoding 'euc-jp'}
ただしウチの環境では、perl コードを "(ダブルクオート)で囲ってやらないと(つまりシングルクオートをエスケープしてシングルクオートで囲んでも)駄目だった。
タコなので深くは追求していない
(defun myhatena-insert-tv-title(ch title)
"Insert tv program title string"
(insert
(shell-command-to-string
(concat "curl -s http://www3.nhk.or.jp/hensei/"
ch "/" (buffer-name) "/main_18-24.html "
"| kcc -e | grep " title " -A 2 | tail -n 1 | "
;"perl -pe 's/.*(「.*」).*/\1/'" # これは動かない;
;"perl /home/amt/bin/tv_program_title_filter" # これはダサい
"perl -ple \"BEGIN{use Encode; use encoding 'euc-jp'}; "
"s/.*(「.*」).*/\1/\"" # こうやると動く
))))
(defun myhatena-insert-TokukhoSyutoken()
"金曜1930-1958 放映の 「特報首都圏」のタイトルを取得し録画記録に挿入"
(insert "+1930-1958 NHK 特報首都圏 ")
(myhatena-insert-tv-title "ch1" "特報首都圏"))
●結論
最初は、手入力の省力化という感じで作り始めたのだが、もう少し踏み込んで、関心のありそうな番組を網羅的に表示して、パーソナライズしたテレビ欄のように使えるようにしてみた。
↓みたいな感じにすると M-x myhatena-rokuga-head で、0500-翌0500に放映される主要な教養番組に関する要約が、「はてなダイアリー」のタグと伴に挿入される。
(defun hatena-mode-dow-from-buffer-name()
"return Day of Week(0..6) from current buffer name."
(string-to-number (shell-command-to-string
(concat "date --date=" (buffer-name) " +%w"))))
(defun myhatena-tvrecord-adjust-subtitle(title)
"タイトルが全角かつ10文字以下であることを仮定して,サブタイトル頭を揃える"
(let ((d (- 11 (length title))))
(while (< 0 d)
(insert " ") ;SPC2ヶ挿入
(setq d (1- d)))))
(defun myhatena-insert-tv-title(title &optional ch pattern timezone)
"Insert tv program title string"
(myhatena-tvrecord-adjust-subtitle title)
(unless ch (setq ch "ch1"))
(unless pattern (setq pattern "s/^.*?(「.*?」).*$/\\1/\""))
(unless timezone (setq timezone "05-29"))
(let
((subtitle
(shell-command-to-string
(concat "curl -s -m 270 http://www3.nhk.or.jp/hensei/"
ch "/" (buffer-name) "/main_" timezone ".html "
"| kcc -e | grep " title " -A 2 | tail -n 1 | "
"perl -pe \"BEGIN{use Encode; use encoding 'euc-jp'}; "
pattern))))
(if (string= "" subtitle) (setq subtitle "取得失敗、お休みかもね?\n"))
(insert subtitle))
)
;shell でパターンをテストするときのテンプレート
; curl -s http://www3.nhk.or.jp/hensei/ch3/20051216/main_18-24.html | kcc -e | grep 視点・論点 -A 2 | tail -n 1|perl -ple "BEGIN{use Encode; use encoding 'euc-jp'};s/^[\\s]*?(「.*?」)<BR>[\\s]*?([\\S].*?)<BR><BR>.*$/\\1\\2/"
(defun myhatena-entry-recording(title &optional DayOfWeek)
(cond
;;
((string= title "特報首都圏")
(insert (concat "+1930-1958 NHK " title " "))
(myhatena-insert-tv-title title))
((string= title "ビジネス未来人")
(insert (concat "+2225-2250 ETV " title " "))
(myhatena-insert-tv-title title "ch3"))
((string= title "あすを読む")
(insert (concat "+2345-2355 NHK " title " "))
(myhatena-insert-tv-title title))
((string= title "にんげんドキュメント")
(insert (concat "+2300-2345 NHK " title " "))
(myhatena-insert-tv-title title))
;;日曜 NHK
((string= title "たべもの新世紀")
(insert (concat "+0615-0653 NHK " title " "))
(myhatena-insert-tv-title
title nil "s/^.*?([\\S]+)<BR>(.*)$/\\1/\""))
((string= title "さわやか自然百景")
(insert (concat "+0745-0800 NHK " title " "))
(myhatena-insert-tv-title title))
((string= title "小さな旅")
(insert (concat "+0800-0825 NHK " title " "))
(myhatena-insert-tv-title title))
((string= title "経済羅針盤" )
(insert (concat "+0825-0857 NHK " title " "))
(myhatena-insert-tv-title
title "ch1" "s/^.*?▽(.*?)<BR>[\\s]*(.*?)<BR>.*$/「\\1」\\2/\""))
((string= title "NHKスペシャル")
(insert (concat "+2100-2153 NHK " title " "))
(myhatena-insert-tv-title title))
((string= title "NHKアーカイブス")
(insert (concat "+2100-2153 NHK " title " "))
(myhatena-insert-tv-title
title nil "s/^.*?▽([\\S]+)(「.*?」)[\\s]*((.*?)).*$/\\1\\2\\3/\""))
;;日曜 ETV
((string= title "トップランナー")
(insert (concat "+1900-1945 ETV " title " "))
(myhatena-insert-tv-title title "ch3"))
((string= title "あの人に会いたい")
(insert (concat "+1945-1955 ETV " title " "))
(myhatena-insert-tv-title title "ch3"))
;;日曜 BS1
((string= title "地球街角アングル")
(cond
((= DayOfWeek 0) ; 日曜は 1720からも放送がある
(insert (concat "+1720-1740 BS1 " title " "))
(myhatena-insert-tv-title title "bs1" nil "12-18"))
(t t))
(insert (concat "+2140-2200 BS1 " title " "))
(myhatena-insert-tv-title title "bs1" nil "18-24"))
((string= title "BS世界のドキュメンタリー")
(cond
((= DayOfWeek 0) ; 日曜のみ 2210-2300 2310-2400 の二本建
(insert (concat "+2210-2400 BS1 " title " "))
(myhatena-insert-tv-title title "bs1"))
(t
(insert (concat "+2110-2200 BS1 " title " ")) ;放映のない日もある
(myhatena-insert-tv-title title "bs1" に "18-24"))))
;;月曜 NHK
((string= title "クローズアップ現代")
(insert (concat "+1930-1958 NHK " title " "))
(myhatena-insert-tv-title title))
((string= title "地球・ふしぎ大自然")
(insert (concat "+2000-2045 NHK " title " "))
(myhatena-insert-tv-title title nil nil "18-24"))
((string= title "あすを読む")
(insert (concat "+2345-2355 NHK " title " "))
(myhatena-insert-tv-title title))
;;月曜 ETV
((string= title "きょうの健康")
(insert (concat "+2030-2045 ETV " title " "))
(myhatena-insert-tv-title title "ch3" nil "18-24"))
((string= title "平成若者仕事図鑑")
(insert (concat "+1930-1955 ETV " title " "))
(myhatena-insert-tv-title
title "ch3" "s/^.[^〜]*〜([^」]*」).*$/「\\1/\""))
((string= title "視点・論点")
(insert (concat "+2250-2300 ETV " title " "))
(myhatena-insert-tv-title
title "ch3" "s/^[\\s]*?(「.*?」)<BR>[\\s]*?([\\S].*?)<BR><BR>.*$/\\1\\2/\""))
;;月曜 BS1
((string= title "生命の大地・地球")
(insert (concat "+0615-0640 BS1 " title " "))
(myhatena-insert-tv-title
title "bs1" "s/^[\\s]*?(「.*?」)<BR>[\\s−]+([^\\s−]+).*$/\\1\\2/\""))
((string= title "地球街角アングル")
(insert (concat "+1235-1255 BS1 " title " "))
(myhatena-insert-tv-title title "bs1" nil "12-18")
(insert (concat "+1815-1835 BS1 " title " "))
(myhatena-insert-tv-title title "bs1" nil "18-24"))
((string= title "経済最前線")
(insert (concat "+2215-2300 BS1 " title " "))
(myhatena-insert-tv-title
title "bs1" "s/^[\\s]*?▽(.+?)<BR>.*$/\\1/\""))
;;水曜
((string= title "ハイビジョン特集")
(insert (concat "+0005-0107 NHK " title " "))
(myhatena-insert-tv-title
title nil "s/^[\\s]*?(「.*?」)<BR>[\\s−]+([^\\s−]+).*$/\\1\\2/\""))
;;土曜
((string= title "サイエンスZERO")
(insert (concat "+1900-1944 ETV " title " "))
(myhatena-insert-tv-title title "3ch"))
((string= title "ETV特集")
(insert (concat "+2200-2330 ETV " title " "))
(myhatena-insert-tv-title title "3ch"))
((string= title "新日本紀行ふたたび")
(insert (concat "+2020-2059 NHK " title " "))
(myhatena-insert-tv-title title ))
((string= title "BSドキュメンタリー")
(insert (concat "+2210-2300 BS1 " title " "))
(myhatena-insert-tv-title title "bs1"))
t
(insert (concat "+ NHK " title " "))
(myhatena-insert-tv-title title))
)
(defun myhatena-rokuga-head (arg)
(interactive "P")
(insert "*TVReservation*[tv] TV録画予定\n")
(insert ">|\n")
(if arg ; 前置数引数が指定されていれば終了
(return))
(let ((DayOfWeek (hatena-mode-dow-from-buffer-name))
)
(cond
((eq DayOfWeek 0) ;日曜
(myhatena-entry-recording "たべもの新世紀")
(myhatena-entry-recording "さわやか自然百景")
(myhatena-entry-recording "小さな旅")
(myhatena-entry-recording "経済羅針盤")
(myhatena-entry-recording "NHKスペシャル")
(myhatena-entry-recording "地球街角アングル" 0)
(myhatena-entry-recording "NHKアーカイブス")
(myhatena-entry-recording "トップランナー")
(myhatena-entry-recording "あの人に会いたい")
)
((eq DayOfWeek 1) ;月曜
(myhatena-entry-recording "生命の大地・地球")
(myhatena-entry-recording "クローズアップ現代")
(myhatena-entry-recording "平成若者仕事図鑑")
(myhatena-entry-recording "地球・ふしぎ大自然")
(myhatena-entry-recording "きょうの健康")
(myhatena-entry-recording "経済最前線")
(myhatena-entry-recording "視点・論点")
(myhatena-entry-recording "あすを読む")
)
((eq DayOfWeek 3) ;水曜
(myhatena-entry-recording "クローズアップ現代")
(myhatena-entry-recording "きょうの健康")
(myhatena-entry-recording "視点・論点")
(myhatena-entry-recording "あすを読む")
(myhatena-entry-recording "ハイビジョン特集")
)
((eq DayOfWeek 5) ;金曜
(myhatena-entry-recording "特報首都圏")
(myhatena-entry-recording "きょうの健康")
(myhatena-entry-recording "視点・論点")
(myhatena-entry-recording "ビジネス未来人")
(myhatena-entry-recording "にんげんドキュメント")
(myhatena-entry-recording "あすを読む")
)
((eq DayOfWeek 6) ;土曜
(myhatena-entry-recording "地球街角アングル" 6)
(myhatena-entry-recording "サイエンスZERO")
(myhatena-entry-recording "NHKスペシャル")
(myhatena-entry-recording "新日本紀行ふたたび")
(myhatena-entry-recording "BSドキュメンタリー")
(insert "+2230-2300 CNBC 世界は今 \n")
(myhatena-entry-recording "ETV特集")
)
(t ;その他平日
(myhatena-entry-recording "クローズアップ現代")
(myhatena-entry-recording "きょうの健康")
(myhatena-entry-recording "視点・論点")
(myhatena-entry-recording "あすを読む")
)
))
(insert "|<\n")
)
●雑談
- date って debian では /bin/date にあるんだ。知らなかった。
- 今 ruby の勉強してるんだけれど、lisp って 45年前の言語だから流石に古さを感じるな。
- elisp の正規表現なんて忍耐の限度外だよ。
- 日本語の正規表現がうまく動かん件、sedでもperl でも駄目だった。
※20051218追記
本問題は一行野郎用のオプション覚え書きに書いたように、スクリプト先頭に以下の BEGINブロックを追加して解決
なお、この場合スクリプトをダブルクオートで囲ってやらないとウマく動かない
BEGIN{use Encode; use encoding 'euc-jp'};
■[debian] 日本語で grep
GNU grep は一応 EUC と sjis に対応している筈んだけど、デフォが euc-jp な僕の環境だと、EUC以外ではうまく動いてくれない。
lv に同梱されている lgrep は EUC SJIS 以外に UTF-8 や、JISにも対応してくれ、自動判別してくれる。(その代り遅くって低機能)
iconv で変換する場合は、↓のようにするんだが、自動認識があまりアテにならず、入力の文字コードを調べてやらないといけない。
iconv -f shift-jis -t euc-jp main_18-24.html | grep 視点 -C 3 iconv -f utf-8 -t euc-jp main_18-24.html | grep 視点 -C 3
ちょっと試した範囲では kcc(debianでは kcc パッケージ) の方がうまく動く感じ。
$ kcc -c main_18-24.html #コードの判別 main_18-24.html: shift-JIS $ kcc -e main_18-24.html | grep 視点 -C 3 # 入力を自動判別しeucに変換して標準出力へ



