WordPressでソースコード色分け表示

参考:

「iG:Syntax Hiliter」の紹介。

http://jmblog.jp/archives/62

導入

http://blog.igeek.info/wp-plugins/igsyntax-hiliter/
 → iG_Syntax_Hiliter.zip をダウンロード。

・解凍すると以下のようなファイル階層ができる。

iG-Syntax Hiliter
├COPYING
├GNU GPL.txt
├MANUAL.html
├READ ME.txt
└ig_syntax hiliter plugin
 ├syntax_hilite.php
 └is_syntax_hilite
  ├…
  ├…
  ├…

・syntax_hilite.php と is_syntax_hilite を /wp-content/plugins にアップロード。
・[サイト管理] – [プラグイン] に [iG:Syntax Hiliter] が表示されるようになるので、これを有効化。

現在は「SyntaxHighlighter Evolved」を使用。

使用

[cpp]~[/cpp] を試す。

int a,b;
b=test(a);
if(b){
  printf("Hello\n");
}
while(a<10 && a>1){
	a++; //※←ここのインデントはTABを使ってみてる。
}

[perl]~[/perl] を試す。

#!/usr/bin/perl
print "Hello\n";
if($a){
  exit;
}elsif($b){
  exit;
}else{
  exit;
}

[code]~[/code] を試す。

abc;
> echo "abc"

Boost Regex++

C++ で正規表現が使いたい。Boost Regex++ がよさげ。

boost入手・導入

http://www.boost.org/

boost_1_35_0.zip を入手。D:\boost_1_35_0 として解凍。
VCのインクルードパスに D:\boost_1_35_0 を追加。

regexビルド

boostの多くのモジュールはビルドしなくても使えるが、regexはビルドが必要。

Visual Studio 2005 Professional にて。
スタートメニューの [Visual Studio 2005] – [Visual Studio Tools] – [Visual Studio 2005 コマンド プロンプト] を実行。

> cd D:\boost_1_35_0\libs\regex\build
> nmake -f vc8.mak              (lib作成)
> nmake -f vc8.mak install      (VCディレクトリにlibをコピー)

参考:

http://d.hatena.ne.jp/twhs/20080112

コーディング実験

#include <boost/regex.hpp>
#include <string>
using namespace std;

void test()
{
	//簡単な検索 ("abcdefg" から "abc" の有無を判定)
	printf("-- simple --\n");
	{
		const char* source = "abcdefg"; //検索対象
		boost::reg_expression<char, boost::regex_traits<char> > regex("abc"); //正規表現
		boost::match_results<const char*> results; //結果
		//実行
		bool found = boost::regex_search(source, results, regex);
		printf("found = %d\n", found?1:0);
	}

	//抜き出し ("abcdafc" から "a.c" にマッチするものを検索)
	printf("-- pick up --\n");
	{
		const char* source = "abcdafc"; //検索対象
		boost::reg_expression<char, boost::regex_traits<char> > regex("a.c"); //正規表現
		boost::match_results<const char*> results; //結果
		//実行
		bool found = boost::regex_search(source, results, regex);
		if(found){
			string p = results.str(0);
			printf("found = %s\n", p.c_str());
		}
	}

	//カッコ (カッコ付きの正規表現。複数の結果を取得できる)
	printf("-- brackets --\n");
	{
		const char* source = "abcdafc"; //検索対象
		boost::reg_expression<char, boost::regex_traits<char> > regex("(a.c).*(.f)"); //正規表現
		boost::match_results<const char*> results; //結果
		//実行
		bool found = boost::regex_search(source, results, regex);
		if(found){
			for(int i=0;i<(int)results.size();i++){
				printf("found[%d]: pos = %d, len = %d, str = %s\n",
					i, results.position(i), results.length(i), results.str(i).c_str());
			}
		}
	}
}

参考:

http://www.s34.co.jp/cpptechdoc/article/regexpp/

実用に向けたコーディング

#include <boost/regex.hpp>
#include <string>
#include <vector>
using namespace std;
vector<string> get_match_strings(const char* _source, const char* _regex)
{
	const char* source = _source; //検索対象
	boost::reg_expression<char, boost::regex_traits<char> > regex(_regex); //正規表現
	boost::match_results<const char*> results; //結果
	//実行
	bool found = boost::regex_search(source, results, regex);
	//解釈
	vector<string> ret;
	if(found){
		for(int i=0;i<(int)results.size();i++){
			ret.push_back(results.str(i));
		}
	}
	return ret;
}

上のような関数を用意しておくと便利。ちょっと負荷はかかるけど。
で、下のように使う。

void test2()
{
	//文字列内から「URL全体」と「サーバ名」を抜き出し。 (正規表現は適当)
	vector<string> ret = get_match_strings(
		"abc http://www.google.co.jp/gonyo/ponyo/ def",
		"http://([A-Za-z\\.]+)/[A-Za-z\\./]+"
	);
	for(int i=0;i<(int)ret.size();i++){
		printf("match[%d] = %s\n", i, ret[i].c_str());
	}
}

落とし穴メモ

「#include <boost/regex.hpp>」と書くところを
「#include <boost/regex.h>」と書き間違えてしまった場合↓

error C2039: 'reg_expression' : 'boost' のメンバではありません。
error C2065: 'reg_expression' : 定義されていない識別子です。

ややこしやー。

2ちゃんねるビューア考

数ある2ちゃんねるビューアの情報を開発者視点でちょこちょこまとめ。

参考

http://2ch.tora3.net/viewer.html

http://www.monazilla.org/

http://pc11.2ch.net/test/read.cgi/software/1223087735/

ローカルHTTPプロクシ

□禁断の壷

http://tubo.80.kg/

形式    :ローカルHTTPプロクシ
ソース   :非公開
開発言語  :不明
作者    :マァヴ ◆jxAYUMI09sさん (http://d.hatena.ne.jp/keyword/%A5%DE%A5%A1%A5%F4) (Copyright: 株式会社ゼロ)
最終リリース:2007/07/05

サーバ上アクセサ

□p2

http://akid.s17.xrea.com/

形式    :HTTPサーバ上に配置する2chアクセサ (HTTPプロクシではない)
ソース   :公開 (CVS)
開発言語  :PHP
作者    :Sourceforge.jpメンバー 3人 (主開発: akiさん)
最終リリース:2008/10/08

専用ブラウザ (プラットフォーム非依存)

□Ya2b

http://www.geocities.co.jp/SiliconValley-Sunnyvale/1375/

形式    :ブラウザ
ソース   :公開
開発言語  :C++ (Visual C++ 6.0) / MFC
作者    :?
最終リリース:2004/03/31

□V2C

http://v2c.s50.xrea.com/

形式    :ブラウザ
ソース   :非公開
開発言語  :Java+Swing
作者    :n|aさん
最終リリース:2008/10/01

専用ブラウザ (オープンソース)

□ギコナビ

http://gikonavi.sourceforge.jp/

形式    :ブラウザ
ソース   :公開 (CVS)
開発言語  :Delphi/Kylix
作者    :Sourceforge.jpメンバー 5人 (原作:(ヒ)さん)
最終リリース:2008/09/16

□ホットゾヌ2

http://hp.vector.co.jp/authors/VA036533/

形式    :ブラウザ
ソース   :公開
開発言語  :Delphi 6 (PRO) (+ ギコBASIC)
作者    :Dax ◆6rZonuDqnさん
FAQ 担当  :Zonutanさん
掲示板運営 :(ホットゾヌ板)コッパさん
最終リリース:2008/09/21

□ぎこはにゃ~ん

http://ghanyan.monazilla.org/

形式    :ブラウザ
ソース   :公開 (mona.tar.bz2)
開発言語  :C++
作者    :◆hHhAnYaNVAさん
最終リリース:2007/03/17

□OpenJane

http://sourceforge.jp/projects/jane/

形式    :ブラウザ
ソース   :公開 (CVS)
開発言語  :Delphi/Kylix
作者    :Sourceforge.jpメンバー 10人 (元祖Jane作者=Twiddleさん)
最終リリース:2006/06/17 (CVS最終コミットは 2008/09/22)

□xyzzy 2ch-mode

http://www7a.biglobe.ne.jp/~hat/xyzzy/2ch-mode.html

形式    :ブラウザ
ソース   :公開
開発言語  :LISP (*.l がソース, *.lc がバイトコンパイル済みファイル)
作者    :Masashi Hattoriさん
最終リリース:2006/06/01

※ *.l と *.lc の意味、オープンソースであること、最終リリースの間違いを 1z009aさんからご指摘いただき、記事を修正しました。1z009aさん、ありがとうございます!

専用ブラウザ (ソース非公開)

□A BONE

http://www.a-bone.net/

形式    :ブラウザ
ソース   :見つからない
開発言語  :不明
作者    :委員長さん
最終リリース:2008/10/01

□えまのん

http://www.emanong.net/

形式    :ブラウザ
ソース   :見つからない
開発言語  :不明
作者    :おりびさん
最終リリース:2008/07/28

□Live2ch

http://www8.plala.or.jp/uro/live2ch/

形式    :ブラウザ
ソース   :見つからない
開発言語  :Visual Basic 6.0
作者    :geroimo ◆IbyRa9v5IEさん
最終リリース:2007/07/02

□かちゅ~しゃ

http://members.jcom.home.ne.jp/katjusha/

形式    :ブラウザ
ソース   :公開予定だったが紛失?
開発言語  :不明
作者    :かちゅ~しゃ作者さん
最終リリース:2001/07/14

サービス

□べっかんこ

http://2ch.tora3.net/mobile.html

携帯用2chアクセス提供HTTPサーバ。

Google Analytics で自分アクセスを除外(独自クッキー編)

Ultimate Google Analytics を使ってる時点で、管理者ログインしてれば自分アクセスは集計から除外される。でも自宅以外(管理者ログインしてない環境)からも自分サイトを閲覧することがあるので、管理者ログイン以外の集計除外方法を用意しておくと何かと助かる。

自宅以外から管理者ログインするのは抵抗があるし、そもそも管理者ログインをするためのPOSTリクエストが禁止されている環境もあるので。

参考:

http://rewish.org/tools/ga_cookie

Google Analytics側の設定

■ フィルタ作成画面へ進む
[Google Analytics] – [Analytics にアクセス] – [フィルタマネージャ] – [フィルタを追加]

■「新しいフィルタを作成」画面

フィルタ名 … 自分アクセス
フィルタの種類 … カスタム フィルタ
         └ 除外
         └ フィルタフィールド   … ユーザー定義
         └ フィルタパターン     … no_report
         └ 大文字と小文字の区別 … いいえ
選択したプロファイル … <対象プロファイル>

→ [変更を保存]

クッキー設定ページの作成

ただ「pageTracker._setVar(‘no_report’)」を含むページを作ればいいってわけじゃない。これだけじゃあ、「pageTracker」オブジェクトが不在なので、動作しない。ちゃんと「_gat._getTracker」でオブジェクトを取得すること。

<html>
<body>

<h4>Google Analytics クッキー設定ページ</h4>
<script type="text/javascript">
	//Googleスクリプトのインクルード
	var gaJsHost =
		(("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
	document.write(unescape("%3Cscript src='"
		+ gaJsHost
		+ "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
</script>
<script type="text/javascript">
	//トラッカーオブジェクト取得
	var pageTracker = _gat._getTracker("UA-XXXXXXX-X");

	//クッキー設定
	pageTracker._setVar('no_report');

	//クッキー確認
	document.write("[cookie] " + document.cookie + "<br>\n");
</script>

<p>
<a href="./">トップへ</a>
</p>

</body>
</html>

Sleipnirの検索ボックスのホイール動作を無効化

Sleipnir (2.8.2限定) で、検索ボックスでのホイール動作を無効化するアプリを作ってみました(ホントはプラグインとかで実現できればよかったんですけど、Sleipnirのプラグイン仕様を調べるよりも、Win32で直接アプリ組むほうが楽だったので、ただのEXE式となっています)。

http://clock-up.jp/archives/SleipnirWheel.zip

メカニズム

まず、フック開始部分。ここは定番。

HANDLE hHook=SetWindowsHookEx(WH_GETMESSAGE, GetMsgProc, g_hDll, 0);

フックした場所でやること。WM_MOUSEWHEEL メッセージを書き換える。MSG構造体を直接書き換えちゃうのは、ややトリッキーかもしれない。私はフックの定石を知りません。

LRESULT CALLBACK GetMsgProc(int nCode,WPARAM wparam,LPARAM lparam)
{
	if(nCode>=0 && wparam==PM_REMOVE){
		MSG* msg=(MSG*)lparam;
		if(msg->message==WM_MOUSEWHEEL){
			//検索ボックスでのホイールイベントを…
			if(IsSleipnirSearchBox(msg->hwnd)){
				HWND hwndFrame = ::GetAncestor(msg->hwnd, GA_ROOT);
				HWND hwndTab = ::FindWindowEx(hwndFrame, NULL, L"Afx:00400000:0", NULL);
				HWND hwndPage = ::FindWindowEx(hwndTab, NULL, L"IEBrowserFrame", NULL);
				//ページウィンドウでのホイールイベントとして差し替える
				msg->hwnd = hwndPage;
			}
		}
	}
	return CallNextHookEx(hHook,nCode,wparam,lparam);
}

ホイールの発生したウィンドウが検索ボックスであるかどうかの判定。

bool IsSleipnirSearchBox(HWND hwnd)
{
	wchar_t szName[256];

	//Sleipnirであることを確認 -> 異なる場合はfalseを返す
	HWND hwndFrame = ::GetAncestor(hwnd,GA_ROOT);
	if(!::GetWindowText(hwndFrame, szName, _countof(szName)))return false;
	if(wcsstr(szName, L"Sleipnir")==NULL)return false;

	//検索ボックスであることを確認 -> 異なる場合はfalseを返す
	while(1){
		if(!::GetClassName(hwnd, szName, _countof(szName)))break;

		if(wcsicmp(szName, L"Edit")==0)goto next;
		else if(wcsicmp(szName, L"FenrirComboBoxCtrl")==0)return true;
		else if(wcsicmp(szName, L"FenrirSearchWindow")==0)return true;
		else return false;

next:
		hwnd = ::GetParent(hwnd);
	}
	return false;
}

メカニズムの前提条件

Sleipnir 2.8.2 のウィンドウ構造が以下のようになっていることを利用しています(これはSpy++で調べました)。

SleipnirMainWindow
├MDIClient
│└Afx:00400000:0
│ └IEBrowserFrame (ページ表示部分)
└Afx:~
 └FenrirSearchWindow
  └FenrirComboBoxCtrl
   └Edit (検索ボックス)

展望

ホイールイベントが発生する度に文字列判定その他の処理が発生するので、負荷を考えると、あんまりよろしくない気分。Sleipnirプロセスのみに限定してフックを行えるなら、ちょっとは気が晴れるんですが。

理想としては、こんなフックアプリケーション作らなくてもいいように、Sleipnir自身に、検索ボックスでのホイール無効にできる機能が付いてほしい。

参考:

ここのフックの解説は、なんというか、妥協無く検証している感があって、なんか好き。

http://park15.wakwak.com/~opapa/cpp/Hook.htm

街情報

24時間営業のガソリンスタンド

http://5go.biz/ro/p42.htm

こういう情報ってすごい助かる。まさに人間様の集めた情報ってのは人間にとって使いやすいんだよなぁ。

Google Map で「(住所) ガソリンスタンド 24時間」で検索して、こういう情報が得られれば良いのに。
…と思って試しに検索してみたら、ちょうど目的の検索結果が引っかかった!たまたまかな?