オープンノートの作り方

[トップページ]

このサイトの作り方のノウハウをここに書いて置く。

目次

現在の構成
なぜ、pukiwiki + pukiwiki-mode から muse に移行したか
ホスティングサービスの選択
muse で htmlオーサリングをする
ローカルウエブの land.to へのミラー
ローカルイメージのプット
land.to 側での namazu インデクスの更新
land.to 側での namazu を使うにあたっての補足事項
iSilo を使った Palm 用イメージの作成
今後の予定

基本的な考え方は、普段使っている、emacs の上で、絶えず作成しているメモ的なドキュメントを、なるべく手間をかけずに、同一のまま、他のマシンや、出先や、palm の上で閲覧したり検索したりしたいし、外部にも公開したい。というものであった。

箇条書きにすると↓のようになる。

現在の構成

現状の構成は下表の通りである。
オーサリング muse + emacs
ローカルな全文検索 muse の全文検索機能 && namazu2
ローカルイメージ museの wisywig性 && localhost上の apache2
公開イメージホスティング land.to
公開イメージの全文検索 muse の全文検索機能 && namazu2
palm 上への取り込み iSilo

ちなみに、これ以前に、次のような構成で 旧オープンノート を運用していた。
オーサリング pukiwiki-mode + pukiwikihelper-mode + emacs
ローカルイメージ local host上の apache2 + php5 + pukiwiki
ローカルな全文検索 pukiwiki の全文検索機能
公開イメージホスティング AAA! CAFE -> land.to
palm 上への取り込み plucker foo

以下順に、このような選択に至った理由を書いておく。

なぜ、pukiwiki + pukiwiki-mode から muse に移行したか

僕の場合は、三行以上の文を書く時は emacs から編集出来る、ということが絶対の前提になるので、pukiwiki を使う限りは pukiwiki-mode を使うことになる。 この pukiwiki-mode で厄介な問題は、編集中のバッファに対して、ファイル名が割当てられていないので、自動バックアックとかが出来ず、編集中に emacs がクラッシュしてしまうと、編集中のイメージが失なわれてしまう、というものである。

で、この問題を、解決するために、 pukiwiki-mode 相当のものを自前で作ってしまおうと考えて、muse を調べているウチに、僕が必要としていることは muse を使えば十分であることが判ったので、 muse に乗り換えることにした訳である。

なお余談だが、emacs には、muse 同様に、wiki的簡易記法から html を生成するモードとして、muse の前身である emacs-wiki と bhl-modeが別にある。

現時点で bhl-mode で出来ることは muse ですべて出来るが、その逆は真ではない。いまとなっては、殆どのヒトによっては、bhl-mode を調査する必要はない、muse を使うべきである。

一方 emacs-wiki には、まだ muse では実装されていない perl や python の埋め込みが可能である、という大きな違いがある。リストを入れ子にする必要がなくって、P 言語を埋め込みたいヒトには emacs-wiki の方が、よい選択である場合がある。

muse が pukiwiki + pukiwiki-mode より優れる点

muse が pukiwiki + pukiwiki-mode より劣る点

簡単にいうと、muse の方が拡張性柔軟性が圧倒的に優れるが、開発が始まったばかりのソフトなので未完の度合いが高く、自分で作ってやらなくっちゃいけない処がまだまだ多い、ということになる。

その機能拡張の手間だが、 elisp も php も同程度に習熟していることを前提にすると muse の方が圧倒的にラク。

また、高機能な分、少なくとも俺は、マニュアルを一通り読んだだけではよく判らない個所が沢山あったね。取っ付きは確実に悪いと思う。elisp と html がある程度自由にならないとツラいかも。

※後二者の問題については、変更提案済である。僕のカスタムコードも要望があれば公開する。

ホスティングサービスの選択

本稿執筆段階で、無料ホスティングサービスで、法人運営で、鯖がデータセンター設置で、広告やアフィリエイト等設置するのに規制がなく、mysql が使えて php が使えて、python が使えて perl が使えて ruby が使えて、いつでも新規にアカウントが作れるサービスというと、多分 land.to しかないんじゃないかな、と思う。

後述するが、ここは実は namazu も使える、という大きな特徴がある。

性能は、まあ無料で、CGI 可にしてはよくやっている、という程度、可用性、MTTR は僕としては満足している、自営宅鯖よりは絶対によい筈だ。

本人確認が結構厳格だったりするのも安心できるポイントといえよう。

無論、サポートは掲示板で助けあい、が原則だが、その分情報開示がされているので、判っている人間にはよいサポートだと思う。要望への対応は小回りが利く感じであり好感がある。

という訳で、僕としては、ある程度知識のある人間が web 上での実験をするんだったら land.to をイチオシしたい。

ただ、html 設置のみで、マルチメディアデータを沢山置いて、アフィリエイト広告を設置しないんだったら yahoo!ジオシティもよい選択だと思う。動作はこちらの方がはるかに軽快だし、サービスの存続性も高いだろう。

このケースでは、ブックレビューが中心となるので、アマゾンの書籍画像等を使うので、僕は選択しなかった。

muse で htmlオーサリングをする

emacs 使いで、かつ WEBページ作成の簡易言語として wiki を使ってきた人間なら、で、かつ、英語のドキュメントが苦にならないヒトならば、 muse を試すべきだろう。

muse では、次のような wiki ライクの簡単な表現から html を生成することができる。

その上、elisp を埋め込んだり、カスタムマークアップを新たに定義して使ったり、生の html を張り込んだりすることもできる。

基本的に静的なウエブページに出来ることは何でも出来る。それも、殆どテキストを普通に書下すスタイルで、それなりのウエブページにすることができる。

以下に muse のマークアップの例を示す。

# 生html の埋め込み
<literal>
<form method="get" action="namazu.cgi">
<input name="query" size="30" type="text">
<input name="submit" value="オープンノート内検索" type="submit">
</form>
</literal>
# コメント、↓の行は目次に展開される
<contents>
# ↓はパブリッシュ時に展開されるリスプコードの埋め込み
<lisp>(muse-index-as-string t t)</lisp>

* 章のタイトル

** セクションの標題

*** サブセクションの標題
 - リスト
  - 入れ子のリスト
 1. 数字つきのリスト

定義 :: 説明
# URLのラベル付きリンク
[[http://www.microsoft.com][ゴミ製造業者]]
# ローカルのイメージファイルをインライン展開
[[秘密.jpg]]

# 表
氏名 || メールアドレス
宮本武蔵 | musashi@badmail.com
猿飛佐助 | saru@sanada.com

museモードバッファ上から 2 ストロークのコマンド C-c C-p(muse-project-publish) で、プロジェク単位で(例えば ~/public_html/muse/OpenNote) 上の ウエブイメージに変換してくれる。

ローカルウエブの land.to へのミラー

ローカルイメージのプット

僕は、↓のようなシェル関数を定義して、ローカルWEBを land.to にプットしている。

シェル関数の主要な動作を以下に箇条書きにしておく。

UploadOpenNote () {
Appli=OpenNote
CurrentDir=`pwd`
WorkDir=/tmp/${PPID}_${LINENO}_${SECONDS}
WorkImg=$WorkDir/img
mkdir -p $WorkDir $WorkImg
SrcDir=~/public_html/muse/$Appli
#SrcDir=/home/amt/public_html/muse/OpenNote
SrcImg=$SrcDir/img
TimeStamp=$SrcDir/lastime.stamp

# ローカル側のnamazu インデクスの更新
mknmz -q -O ~/public_html/muse/OpenNote/index --media-type='text/html' ~/public_html/muse/OpenNote/

# タイムスタンプより若いファイルを、作業ディレクトリにコピー
if [ -e ${TimeStamp} ]
    then
    find $SrcDir -newer ${TimeStamp} -iname '*.html' \
	-exec cp {}  $WorkDir \;
else
    find $SrcDir  -name '*.html' -exec cp {}  $WorkDir \;
fi
# 画像ファイルについても同様にする
if [ -e ${TimeStamp} ]
    then
    # find の -or が動かないんで↓のようにしている
    for i in $SrcImg/*.{gif,GIF,jp*g,JP*G}
      do
      if [ -e $i ] && [ $i -nt $TimeStamp ]
	  then cp $i $WorkImg
      fi
    done
    #find $SrcImg -newer ${TimeStamp} -iname *'.gif' -or -iname "*.j*pg" \
    #    -exec cp {}  $WorkImg \;
else
#    find $SrcImg  -iname '*.gif'  -o -iname '*.jp*g' -exec cp {} $WorkImg \;
# この個所だが、find の -o が、↑では動かないんで、↓のようにしている
    for i in $SrcImg/*.{gif,GIF,jp*g,JP*G}
#    do if [ -e $i ] ; then echo $i; cp $i $WorkImg ; fi ; done
    do if [ -e $i ] ; then cp $i $WorkImg ; fi ; done
fi

# 作業ディレクトリ上のファイルに対して以下の操作を実行
# ● charset UTF-8 -> EUC-JP
# ● 本文上下に広告タグを挿入
# ● EUC-jp として上書き出力

script=`cat <<'EOF-SCRIPT'
use strict;
use HTML::TreeBuilder;
use Encode;
use utf8;

# 広告タグ
my $google_ad = <<'EOF' ;

<!-- GoogleTag ひとつのページに3つまで -->
<script type="text/javascript"><!--
google_ad_client = "pub-0785007915280146";
google_alternate_color = "DCFFDC";
google_ad_width = 728;
google_ad_height = 90;
google_ad_format = "728x90_as";
google_ad_type = "text";
google_ad_channel ="3049761081";
google_color_border = "FFFFFF";
google_color_bg = "DCFFDC";
google_color_link = "0000FF";
google_color_text = "000000";
google_color_url = "008000";
//--></script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<BR>
EOF

my $google_adlink = <<'EOF' ;

<!-- GoogleLinkTag ひとつのページにひとつまで -->
<script type="text/javascript"><!--
google_ad_client = "pub-0785007915280146";
google_alternate_color = "DCFFDC";
google_ad_width = 728;
google_ad_height = 15;
google_ad_format = "728x15_0ads_al";
google_ad_channel ="3049761081";
google_color_border = "FFFFFF";
google_color_bg = "DCFFDC";
google_color_link = "0000FF";
google_color_text = "000000";
google_color_url = "008000";
//--></script>
<script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
<br>
EOF

my $amazon_ad = <<'EOF' ;

<!-- AmazonTag -->
<script type="text/javascript"><!--
  amazon_ad_tag = "itsumisblog-22";
  amazon_ad_width = "728";
  amazon_ad_height = "90";
  amazon_color_border = "DCFFDC";
  amazon_color_background = "EFFFEF";
  amazon_color_logo = "000000";
  amazon_ad_logo = "hide";
  amazon_ad_border = "hide";//-->
</script>
<script type="text/javascript" src="http://www.assoc-amazon.jp/s/ads.js"></script>
<br>
EOF

my $landto_ad = <<'EOF' ;

<!-- LandToTag -->
<iframe src="http://ty.land.to/ad/adpc_if.p" name="AD" id="AD" title="ad" width="468" height="70" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"><a href="http://land.to/index.php">Land.to</a></iframe>
<br>
EOF

my $root = HTML::TreeBuilder->new();
$root->ignore_unknown(1);
$root->ignore_ignorable_whitespace(0);
$root->store_comments(1);
$root->no_space_compacting(1);

# ファイルの読み込みとパーズ
open(F, $_) ||
    die "Can't open $_ file: $!";
$root->parse(decode('utf-8',join("", <F>)));


close($_);

#バッックアップ
#rename("$_", "$_~'")
# || die "Can't rename $_: $!";


# ヘッダのコンテンツタグを UTF-8 から EUC-JP に変更
my $meta_ctype_new = HTML::Element->new( '~literal',
  'text', '<meta content="text/html; charset=EUC-JP" http-equiv="Content-Type">'
);
my $meta_ctype_old = $root->look_down(
			    '_tag', 'meta',
			   'content', 'text/html; charset=utf-8');

$meta_ctype_old->replace_with($meta_ctype_new);

# 本文の上に挿入するタグ
my $above = HTML::Element->new( '~literal',
				'text',
				"\n<CENTER>\n" .
				$google_adlink . $google_ad .
				"\n</CENTER>\n<hr>\n<hr>\n"
);

#
# 本文の下に挿入するタグ
my $below = HTML::Element->new( '~literal',
				'text',
				"\n<hr>\n<hr>\n<CENTER>\n" .
				$google_ad . $google_ad . $amazon_ad . $landto_ad .
				"\n</CENTER>\n"
);



# 上下に広告を挿入
my $body = $root->find_by_tag_name('body');
$body->unshift_content($above);		# contents-list 先頭に unshift
$body->push_content($below);		# contents-list 末尾に push

# ファイルの書き戻しと後始末
open(OUT, ">$_") || die "Can't write $_: $!";
print OUT encode('euc-jp',$root->as_HTML('<>&')) ;
close(OUT);
$root->delete();

EOF-SCRIPT
`

# cd
cd $WorkDir
# script 実行
# ls にはサイレントモードがないので、エラー出力を /dev/null に切り替える
ls *.html 2>/dev/null | perl -nle "$script"

#if [ -e *.html ] || [ -e img/*.[jJgG]* ] ; then
if [ `ls *.html img/*.[jJgG]* 2>/dev/null | wc -l` -gt 0 ]
    then
    # 更新対象ファイルが存在すればアプロードしてタイプスタンプを更新
    lftp -c "open amt.ty.land.to &&user amt PassWD  && cd /public_html/OpenNote && mirror -R " && touch ${TimeStamp}
    # リモートで、namazu インデクス更新、その前後に cgi を一時的にアプしてすぐ消す
    lftp -c "open amt.ty.land.to &&user amt PassWD  && cd /public_html/OpenNote && lcd /home/amt/public_html/muse/OpenNote && put LandTo.mknmz.cgi && chmod 700 LandTo.mknmz.cgi"
    lynx -dump http://amt.ty.land.to/OpenNote/LandTo.mknmz.cgi > /dev/null
    lftp -c "open amt.ty.land.to &&user amt PassWD  && cd /public_html/OpenNote && rm LandTo.mknmz.cgi"
else echo "更新されたファイルはありません"
fi

# 作業領域の後始末
rm -r $WorkDir
# もとのディレクトリへの復帰
cd $CurrentDir
}

land.to 側での namazu インデクスの更新

上述のように、land.to では、namazu を使うことができる。

一応 Land.toサポート専用スペース::namazu に、こっそり手順が掲載されているが、これでは、自動的に自分のスペース全体が検索対象となってしまうので、そんな事なら、google のドメイン検索でも出来るので、あんまりうれしくない。

という訳で、上述のシェル関数の中で LandTo.mknmz.cgi という名前にして↓の cgi を使っている。

#!/bin/sh

echo "Content-type: text/html

<html>
<title>namazu index作成</title>

<body>
index作成ログ

<textarea cols=70 rows=30>
"
cd /home/httpd/amt/pupblic_html/OpenNote/index

/usr/local/bin/mknmz -f /home/httpd/amt/public_html/OpenNote/LandTo.mknmzrc -T /home/httpd/amt/public_html/OpenNote/LandTo.tmplt -O /home/httpd/amt/public_html/OpenNote/index  --media-type='text/html' /home/httpd/amt/public_html/OpenNote/
cat "foo"
echo "</textarea>

終了
</body>
</html>"

exit

land.to 側での namazu を使うにあたっての補足事項

namazu 検索窓

muse なら、下のコードを埋め込んでやったら、とりあえず namazu検索窓が出来る。

<literal>
<form method="get" action="namazu.cgi">
<input name="query" size="30" type="text">
<input name="submit" value="オープンノート内検索" type="submit">
</form>
</literal>

実際問題として、今後ヘッダに埋め込むか、<search> マークアップを定義するかを考え中。

namazu 検索画面の文字化け対策

land.to の namazu で、適切にインデクスが作られ、検索画面が文字化けせずに表示される為には、1) 検索対象が EUC-JP で、かつ、2) <a href="http://land.to/supportbb/viewtopic.php?t=66&highlight=namazu">ここ</a> にあるように、NMZ.head.ja のヘッダパートに <meta http-equiv=content-type content="text/html; charset=EUC-JP"> とか、書いておく必要がある。

そこで、僕はこのように細工したnamazu テンプレートを /home/httpd/amt/public_html/OpenNote/LandTo.tmplt に設置し、上の cgi でやっているように -T オプションで、これを見るようにしている。

広告自動挿入の停止

land.to は、デフォでは本文の上に広告を自動挿入するが、これを下に移動することを認めているので、上述のシェル関数では、本文上への広告の自動挿入を停止することを前提にして、本文下へ、land.to の広告タグを挿入している。

これに対応して、.htaccess にて、下のようにして、広告の自動挿入を停止している。

# 広告の自動挿入を停止
LayoutIgnoreURI *.html

mknmz 実行 cgi の実行制御

恐らくは負荷のために mknmz をみだりに実行されては困るという為だろうが、land.to は↓のようにいっている、が、その実現方法については何もいっていない。

cgiを他人よりアクセス出来ない様にして下さい

そこで僕は、実行直前にアプロードして、実行後に削除する、という具合にしているが、あんまり利口な方法とは思えない。もっと賢い方法があれば教えていただきたい。

iSilo を使った Palm 用イメージの作成

工事中

今後の予定


連絡先:webadmin.itsumi@gmail.com このページは muse.el で作成しています。