手動を自動にするって矛盾しないか?
「XHTML 1.1のtargetあり」にすることとする。 詳しくは前章を参照せよ。 他の方法も大きくは変わらないだろう。
ココにあるプログラムはかなり怪しいです。 自己責任で使ってください。 らっしーは一切の保証が出来ません。
ドキュメント宣言を書き換えることと、 広告をbodyの開始タグの直後に挿入すること。 この二つだけである。
ドキュメント宣言
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"[
<!ATTLIST a
target CDATA #IMPLIED
>
]>
通常広告(ブロック)
<div class="ad_block">
<a href="http://ad.xrea.com/ad_click.fcg?site=user.s*.xrea.com"
target="_blank" class="ad_anchor">
<img src="http://ad.xrea.com/ad_img.fcg?site=user.s*.xrea.com"
height="60" width="468" alt="ad image" class="ad_image" />
</a>
</div>
思いつくだけあげてみる。 他にも知っているなら教えてください。
自動広告も一緒に現れてしまうから、 無理なのでは?
タグを挿入するくらいなら、初めから広告を貼った方が早い?
これは、特定のファイルにアクセスすると、 CGIにアクセスするようになる機能を利用する。
まず、広告を適切に挿入するCGIを用意する。 addad.cgiとして、/public_html/x/addad.cgiに置くとしよう。
.heaccseeに次のように記述する。
AddType application/x-httpd-xhtml xhtml Action application/x-httpd-xhtml /x/addad.cgi
言語は何でもいいだろう。 なるべくなら、Cが一番いいと思われる。 fastcgiが使えるようであれば、それが一番いい。 mod_phpはポートが違うので無理だと思う。
なお、Python版、PHP版、Perl版を募集中…。
これらのプログラムは全て未保証です。 重大なバグが含まれている可能性があります。 自己責任で使用してください。
ライセンスについてはただいま少し考え中です。 Rubyと似たようなライセンスまたはGPLにしようと思っています。 もしかしたらLGPLにするかも知れません。 BSDと言うのもあり得ます。
少なくとも自由に使っていいです。 再配布するときはGPLであれば今のところ文句は言いません。
たぶんあまり問題はないと思います。 速度も気にするほど遅くはありません。
addad.cgiと言う名前で保存して、 $userと$serverには自分のユーザー名とサーバー名を入れてください。 あとは、自分のサイトに置くだけ。
#!/usr/local/bin/ruby
$user = "" # user id
$sever = "" # sever name
INTERNAL_DTD_SUBSET = "[<!ATTLIST a target CDATA #IMPLIED>]"
PUBID = "-//W3C//DTD XHTML 1.1//EN"
SYSTEM = "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"
DOC_DECLr = /(<!DOCTYPE\s+html\s+PUBLIC\s+"#{PUBID}"\s+"#{SYSTEM}"\s*)(>)/
def ad_tag(user, server)
site = "#{user}.#{server}.xrea.com"
%|<div class="ad_block">| +
%|<a href="http://ad.xrea.com/ad_click.fcg?site=#{site}"| +
%| target="_blank" class="ad_anchor">| +
%|<img src="http://ad.xrea.com/ad_img.fcg?site=#{site}"| +
%| height="60" width="468" alt="ad image" class="ad_image" />| +
%|</a>| +
%|</div>|
end
def add_ad(xhtml, user, server)
xhtml = xhtml.sub(DOC_DECLr){ $1 + INTERNAL_DTD_SUBSET + $2 }
xhtml = xhtml.sub(/<body(\s[^>]*)?>/){ $& + ad_tag(user, server) }
return xhtml
end
if $0 == __FILE__
xhtml = nil
if xhtml_file = ENV['PATH_TRANSLATED']
open(xhtml_file) do |file|
xhtml = file.read
end
else
xhtml = ARGF.read # commandline mode
end
xhtml = add_ad(xhtml, $user, $server)
print "Content-type: application/xhtml+xml\n\n"
print xhtml
end
テストは不十分です! このプログラムは参考程度にしてください。 使用して何かあっても私は一切責任を持てません。
出来上がったが、妖しさ100倍。 USERとSERVERに自分のユーザー名とサーバー名を入れてください。
下のソースをaddad.cとして保存して、 USERとSERVERには自分のユーザー名とサーバー名を入れてください。 次にXREAにアップし、 SSHでgcc -o addad addad.cと打ってください。 addadというファイルをaddad.cgiとリネームして後は適当に置くだけです。 コンパイルされたaddad(addad.cgi)はバイナリ転送してください。
コンパイルはgcc 3.2とgcc 2.95.3-10でそれぞれcygwinでは出来ました。 XREA上では未テストです。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define USER "" /* user id */
#define SERVER "" /* sever name */
#define INTERNAL_DTD_SUBSET "[<!ATTLIST a target CDATA #IMPLIED>]"
#define MAX_LINE 1024 /* buffer size */
static FILE *xhtml_file;
static char line_buff[MAX_LINE];
void print_line(char *xhtml_line, FILE *file);
void print_ad_tag(const char *user, const char *server)
{
printf("<div class=\"ad_block\">"
"<a href=\"http://ad.xrea.com/ad_click.fcg?site=%s.%s.xrea.com\""
" target=\"_blank\" class=\"ad_anchor\">"
"<img src=\"http://ad.xrea.com/ad_img.fcg?site=%s.%s.xrea.com\""
" height=\"60\" width=\"468\" alt=\"ad image\" class=\"ad_image\" />"
"</a>"
"</div>", user, server, user, server);
}
void print_doc_decl(char* xhtml_line, FILE *file)
{
char *p, s[MAX_LINE];
int i;
for (i = 0; i < MAX_LINE; i++) {
s[i] = '\0';
}
while (1) {
if ((p = strchr(xhtml_line, '>')) == NULL) {
printf("%s", xhtml_line);
xhtml_line = fgets(line_buff, MAX_LINE, file);
if (xhtml_line == NULL) {
break;
}
/* next */
} else {
printf("%s", strncpy(s, xhtml_line, (p - xhtml_line)));
printf("%s", INTERNAL_DTD_SUBSET);
print_line(p, file);
break;
}
}
}
void print_body_tag(char* xhtml_line, FILE *file)
{
char *p, s[MAX_LINE];
int i;
for (i = 0; i < MAX_LINE; i++) {
s[i] = '\0';
}
while (1) {
if ((p = strchr(xhtml_line, '>')) == NULL) {
printf("%s", xhtml_line);
xhtml_line = fgets(line_buff, MAX_LINE, file);
if (xhtml_line == NULL) {
break;
}
/* next */
} else {
printf("%s", strncpy(s, xhtml_line, (p - xhtml_line) + 1));
print_ad_tag(USER, SERVER);
print_line(p + 1, file);
break;
}
}
}
void print_tag(char* xhtml_line, FILE *file)
{
/* xhtml_line[0] must be '<' */
switch (xhtml_line[1]) {
case '!': /* doc_decl or comment or CDATA etc. */
if (xhtml_line[2] == 'D' && xhtml_line[3] == 'O' &&
xhtml_line[4] == 'C' && xhtml_line[5] == 'T' &&
xhtml_line[6] == 'Y' && xhtml_line[7] == 'P' &&
xhtml_line[8] == 'E') {
/* "<!DOCTYPE" */
print_doc_decl(xhtml_line, file);
break; /* switch */
}
/* not break... but it make no bug on valid xml! */
case 'b': /* body? */
if (xhtml_line[2] == 'o' && xhtml_line[3] == 'd' &&
xhtml_line[4] == 'y') {
/* "<body" */
switch (xhtml_line[5]) {
case '>':
printf("%s", "<body>");
print_ad_tag(USER, SERVER); /* ad! */
print_line(xhtml_line + 6, file);
break;
case ' ': case '\t': case '\r': case '\n': /* spaces */
/* body start tag */
print_body_tag(xhtml_line, file);
break;
default:
printf("%s", "<");
print_line(xhtml_line + 1, file);
break;
}
break; /* switch */
}
default:
printf("%s", "<");
print_line(xhtml_line + 1, file);
break;
}
}
void print_line(char *xhtml_line, FILE *file)
{
char *p, s[MAX_LINE];
int i;
for (i = 0; i < MAX_LINE; i++) {
s[i] = '\0';
}
if ((p = strchr(xhtml_line, '<')) == NULL) {
/* no tag... */
printf("%s", xhtml_line);
} else {
printf("%s", strncpy(s, xhtml_line, p - xhtml_line));
print_tag(p, file);
}
}
int main(int argc, char **argv)
{
int c;
char *file_name, *xhtml_line;
FILE *xhtml_file;
if ((file_name = getenv("PATH_TRANSLATED")) == NULL) {
if (argc > 1) {
file_name = argv[1]; /* commandline mode */
}
}
xhtml_file = fopen(file_name, "r");
printf("Content-type: application/xhtml+xml\n\n");
while ((xhtml_line = fgets(line_buff, MAX_LINE, xhtml_file)) != NULL) {
print_line(xhtml_line, xhtml_file);
}
fclose(xhtml_file);
return 0;
}
初めから手動広告を貼り付ければいいだけです。 しかし、ローカルの時点で広告を貼り付けるのはウザイという人も いるかも知れません。 そんなときは自動で張り付けるプログラムをローカルで実行して、 保存すればいいだけです。 上にあるプログラムを参考に作ってみてはどうでしょうか?
もっとも素晴らしいのは、FTPアップするときに変換するプログラムでしょう。 たぶん、自分で作るしかないですが…。
XREAで使える便利な広告のためのプログラム群をまとめる予定ですが、 どうなるかあまり決まっていない。
なお、Rubyで書く予定なので、他の言語は…。