利用者:Triglav/Triwiki/Trireplace.js
表示
< 利用者:Triglav | Triwiki
お知らせ: 保存した後、ブラウザのキャッシュをクリアしてページを再読み込みする必要があります。
多くの Windows や Linux のブラウザ
- Ctrl を押しながら F5 を押す。
Mac における Safari
Mac における Chrome や Firefox
- ⌘ Cmd と ⇧ Shift を押しながら R を押す。
詳細についてはWikipedia:キャッシュを消すをご覧ください。
//-------------------------------------------------
// Triwiki 文字置換 Trireplace.js
//-------------------------------------------------
//コマンドラインパラメータ(ドラッグアンドドロップ用)設定
var rpDataFile = "";
var rpOutputFile = "Trireplace.htm";
var rpPath = "";
if ( WScript.Arguments.Length != 0 ) {
//ファイルパスをセット
rpDataFile = WScript.Arguments.Item(0);
//このパスは「クリック」「ドラッグアンドドロップ、コマンド入力」で値が違う
//パスをセット(ほんとは、これ以外にjsファイルの所在パスを取得したい)
rpPath = rpDataFile.replace(/^([\s\S]*)\\([\s\S]*?)$/,"$1\\");
rpDataFile = rpDataFile.replace(/^([\s\S]*)\\([\s\S]*?)\.([\s\S]*?)$/,"$2.$3");
rpOutputFile = rpDataFile.replace(/^([\s\S]*?)\.([\s\S]*?)$/,"$1.htm");
}
//include
eval( new ActiveXObject("Scripting.FileSystemObject").OpenTextFile(rpPath + "Triwiki.js", 1).ReadAll() );
//タイムスタンプと件数管理
var rpNow = new Date();
var rpStarttime = new EditTool().timestamp(rpNow, 1);
var rpTimestamp1 = new EditTool().timestamp(rpNow, 0);
var rpTimestamp2 = "";
var rpCountS = 0;
var rpCountP = 0;
var rpCountE = 0;
var rpNote = "";
var rpWrite = "";
var rpAccount = "";
//編集、API、ファイル処理初期化
var pagetbl = new Array();
var ER0 = new EditReplace();
var WA0 = new WikipediaAPI();
WA0.sendflg = 0;
var FL0 = new ConfigAccess();
FL0.initialize();
//出力ファイル初期化(unicodeファイル生成)
if (WA0.rtn == 0) {
FS0 = WScript.CreateObject("Scripting.FileSystemObject").CreateTextFile(rpPath + rpOutputFile,1,1);
FS0.Write("<html>\n" + rpNow.toUTCString() + "<br />\n");
}
//入力ファイル読み込みと展開
if (WA0.rtn == 0) {
var FS9 = WScript.CreateObject("Scripting.FileSystemObject");
var FS9Flg = FS9.FileExists(rpPath + rpDataFile);
if (FS9Flg == false) {
WA0.rtn = 31;
WA0.error = "入力ファイルがありません";
}
else {
var stream = FS9.OpenTextFile(rpPath + rpDataFile, 1, false, -2);
//冒頭の読み飛ばし
var intext = "";
while(!stream.AtEndOfStream && intext.substr(0,8) != "#setings") {
intext = stream.ReadLine();
if (intext.substr(0,3) == "//+") {
rpWrite = rpWrite + intext + "<br />\n";
}
//コメント行を飛ばす
if (!intext.match(/^\s*\/\//)) {
//設定値の格納
if (m = intext.match(/^\s*(.*?)=(.*)$/)) {
var v = m[1].replace(/^\s*(.*?)\s*$/, "$1");
var w = m[2].replace(/^(["'])(.*)\1$/, "$2").replace(/^\s*(.*?)\s*$/, "$1");
FL0.cfg[v] = w;
}
}
}
FL0.makelist();
}
}
//設定ファイル入力
if (WA0.rtn == 0) {
FL0.cfg.configfile = rpPath + FL0.cfg.configfile;
FL0.getcfg();
rpWrite = rpWrite + FL0.list.join("<br />\n").replace(/\nmode=[\S\s]*/, "\n") + "------------------<br /><br />\n";
if (FL0.rtn != 0) {
WA0.rtn = FL0.rtn;
WA0.error = FL0.error;
}
}
//IEの設定
if (FL0.cfg.monitor != "0") {
var IE9 = new IEaccess();
IE9.navi("about:blank");
}
FS0.Write(iewrite(rpWrite, 1));
//ログイン
if (WA0.rtn == 0) {
//wikipedia以外
if (FL0.cfg.wikiurl != "") {
WA0.url = FL0.cfg.wikiurl;
}
rpAccount = FL0.cfg.account.replace(/@.*?$/, "");
WA0.id = FL0.cfg.account;
WA0.pass = FL0.cfg.password;
iewrite(WA0.login(), 0);
}
//ログページ開始出力
if (WA0.rtn == 0 && FL0.cfg.submit == 1 && FL0.cfg.logpage != "") {
FL0.cfg.mode = "A";
FL0.cfg.summary = ".";
FL0.cfg.botflg = "1";
FL0.cfg.minor = "1";
ER0.exctbl.length = 0;
ER0.exctbl[0] = "a:!--Bot 作業履歴-->,!--Bot 作業履歴-->\\n* " + rpStarttime + " [[利用者:" + rpAccount + "|" + rpAccount + "]] ([[利用者‐会話:" + rpAccount + "|会話]] | [[特別:投稿記録/" + rpAccount + "|実行中]])<!--" + rpTimestamp1 + "-->";
pagetbl.length = 0;
pagetbl[0] = FL0.cfg.logpage;
execute();
if (WA0.rtn == 0) {
rpCountS--;
}
else {
rpCountE--;
}
}
//処理セットのループ
if (WA0.rtn == 0) {
while(!stream.AtEndOfStream && WA0.rtn == 0) {
FL0.cfg.mode = "C";
FL0.cfg.summary = "bot";
FL0.cfg.botflg = "1";
FL0.cfg.minor = "1";
ER0.exctbl.length = 0;
pagetbl.length = 0;
//設定部(置換条件文含む)の取り込み
while(!stream.AtEndOfStream && intext.substr(0,6) != "#pages") {
intext = stream.ReadLine();
if (intext.substr(0,3) == "//+") {
FS0.Write(iewrite(intext + "<br />\n", 1));
}
//コメント行を飛ばす
if (!intext.match(/^\s*\/\//)) {
//置換条件文ではない
if (intext.substr(1,1) != "," &&
intext.substr(1,1) != ";" &&
intext.substr(1,1) != ":") {
//設定値の格納
if (m = intext.match(/^\s*(.*?)=(.*)$/)) {
var v = m[1].replace(/^\s*(.*?)\s*$/, "$1");
var w = m[2].replace(/^(["'])(.*)\1$/, "$2").replace(/^\s*(.*?)\s*$/, "$1");
FL0.cfg[v] = w;
}
} else {
//置換条件文の格納
ER0.exctbl.push(intext);
}
}
}
//各設定値表示
FL0.makelist();
FS0.Write(iewrite(FL0.list.join("<br />\n") + "<br />\n", 1));
for (x in ER0.exctbl) {
FS0.Write(iewrite(x + ":" + ER0.tagrep(ER0.exctbl[x]) + "<br />\n", 1));
}
FS0.Write(iewrite("<br />\n", 1));
//ページ部(記事名一覧)の取り込み
while(!stream.AtEndOfStream && intext.substr(0,8) != "#setings") {
intext = stream.ReadLine();
if (intext.substr(0,3) == "//+") {
FS0.Write(iewrite(intext + "<br />\n", 1));
}
if (intext.substr(0,2) != "//" &&
intext.substr(0,1) != "#" &&
intext.substr(0,1) != "") {
pagetbl.push(intext);
}
}
//実処理
execute();
}
stream.Close();
}
//エラーデータの退避
var BKrtn = 0;
var BKerror = "";
if (WA0.rtn != 0) {
BKrtn = WA0.rtn;
BKerror = WA0.error;
WA0.rtn = 0;
WA0.error = "";
}
//ログページ終了出力
if (WA0.rtn == 0 && FL0.cfg.submit == 1 && FL0.cfg.logpage != "") {
rpCountP = rpCountS;
if (rpCountS == 0) {
rpCountP = 1;
}
rpNote = "";
if (rpCountE != 0) {
rpNote = rpCountE + "?";
}
//再ログイン
iewrite(WA0.login(), 0);
//最終履歴のタイムスタンプを取得
WA0.path ="action=query&list=usercontribs&uclimit=1&ucuser=" + rpAccount;
iewrite(WA0.access(), 0);
if (WA0.rtn == 0) {
rpTimestamp2 = WA0.pickup(WA0.log, "timestamp=").replace(/(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)Z/,"$1$2$3$4$5$6999");
}
else {
rpNote = rpNote + "#";
}
FL0.cfg.mode = "A";
FL0.cfg.botflg = "1";
FL0.cfg.minor = "1";
ER0.exctbl.length = 0;
ER0.exctbl[0] = "a:[[特別:投稿記録/" + rpAccount + "|実行中]])<!--" + rpTimestamp1 + "-->,[{{利用者の投稿記録|" + rpAccount + "|" + rpCountP + "|" + rpTimestamp2 + "}} 投稿記録]) (" + rpCountS + " 件) ''(" + FL0.cfg.summary + ")'' " + rpNote;
FL0.cfg.cntlimit = 0;
pagetbl.length = 0;
pagetbl[0] = FL0.cfg.logpage;
execute();
if (WA0.rtn == 0) {
rpCountS--;
}
else {
rpCountE--;
}
}
//結果の出力とクローズ関連
WA0.rtn = BKrtn;
WA0.error = BKerror;
if (FL0.cfg.submit != 0) {
FS0.Write(iewrite("<br />\nend : rtn=" + WA0.rtn + ",S=" + rpCountS + ",E=" + rpCountE + " " + WA0.error + "<br />\n", 1));
FS0.Write(iewrite(WA0.logout(), 0));
FS0.Close();
if (FL0.cfg.monitor != "0") {
IE9.quit();
}
}
else {
FS0.Write(iewrite("<br />\nend : rtn=" + WA0.rtn + "," + WA0.error + "<br />\n", 1));
FS0.Write(iewrite(WA0.logout(), 0));
FS0.Write("</html>\n");
FS0.Close();
WScript.Echo( "作業完了" );
}
WScript.Quit();
function execute() {
//実処理(ページ毎)のループ
for (var pagecnt in pagetbl) {
if (WA0.rtn != 0) { break; }
//読み込み
if (WA0.rtn == 0) {
WA0.title = pagetbl[pagecnt];
WA0.section = "";
FS0.Write(iewrite("# <b><font color=blue>" + WA0.title + "</font></b>", 1));
FS0.Write("<br />\n");
aaa = WA0.title.indexOf("#");
if (WA0.title.indexOf("#") != -1) {
WA0.section = WA0.title.substring(WA0.title.indexOf("#") + 1);
WA0.title = WA0.title.substring(0, WA0.title.indexOf("#"));
}
iewrite(WA0.read(), 0);
//読み込み判定
if (WA0.rtn != 0 && WA0.error == "WS send timeout" &&
FL0.cfg.timeskip == "1") {
WA0.rtn = 103;
WA0.error = "※※エラー:読み込み";
FS0.Write(WA0.error + "<br />\n<br />\n");
}
//Botsテンプレート簡易判定
if (WA0.rtn == 0 && WA0.text.match(/\{\{bots|\{\{nobots/i) &&
FL0.cfg.nobots != "1") {
WA0.rtn = 102;
WA0.error = "※※Bots簡易判定陽性";
}
}
//置換
if (WA0.rtn == 0 && FL0.cfg.submit != 2) {
ER0.submit = FL0.cfg.submit;
WA0.text2 = ER0.replace(WA0.text);
FS0.Write(ER0.logtext);
iewrite(WA0.text2, 0, 2);
if (ER0.rtn != 0) {
WA0.rtn = 200 + ER0.rtn;
WA0.error = ER0.error;
}
}
//変更の無い更新用nochange
if (WA0.rtn == 0 && FL0.cfg.submit == 2) {
WA0.text2 = WA0.text;
}
//書き出し
if (WA0.rtn == 0 && FL0.cfg.mode == "A" && FL0.cfg.submit >= 1) {
WA0.summary = FL0.cfg.summary;
WA0.botflg = FL0.cfg.botflg;
WA0.minor = FL0.cfg.minor;
iewrite("\n", 0);
iewrite(WA0.edit(), 0);
if (WA0.rtn == 0) {
rpTimestamp2 = WA0.pickup(WA0.log, "newtimestamp=").replace(/(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)Z/,"$1$2$3$4$5$6999");
}
if (WA0.rtn != 0 && WA0.error == "protectedpage") {
WA0.rtn = 181;
WA0.error = "※※保護ページのため更新できません";
FS0.Write(WA0.error + "<br />\n<br />\n");
}
if (WA0.rtn != 0 && WA0.error == "nochange") {
WA0.rtn = 182;
WA0.error = "※※変換箇所がありません";
FS0.Write(WA0.error + "<br />\n<br />\n");
}
if (WA0.rtn != 0 && WA0.error == "readonly") {
WA0.rtn = 183;
WA0.error = "※※書き込み抑制中です(暫定)";
FS0.Write(WA0.error + "<br />\n<br />\n");
}
if (WA0.rtn != 0 && WA0.error == "WS send timeout" &&
FL0.cfg.timeskip == "1") {
WA0.rtn = 104;
WA0.error = "※※エラー:書き込み";
FS0.Write(WA0.error + "<br />\n<br />\n");
}
}
//結果表示および更新時にカウントとインターバル
iewrite(" rtn=" + WA0.rtn + "," + WA0.error + "<br />\n", 1);
if (FL0.cfg.mode == "A" && FL0.cfg.submit == 1) {
if (WA0.rtn == 0) {
rpCountS++;
//入力値intimeで指定された秒間隔まで待つ
//まず強制的に1秒待つ
WScript.Sleep(1000);
if (FL0.cfg.interval <= 60) {
//1分以下の場合
while (new Date().getSeconds() % FL0.cfg.interval != 0) {
}
} else {
//1分を超える場合はインターバル時間
WScript.Sleep(FL0.cfg.interval * 1000);
}
}
else {
rpCountE++;
}
}
//ページ単位のエラーはリセットする
if (WA0.rtn >= 100) {
WA0.rtn = 0;
WA0.error = "";
}
//処理制限数に到達時は処理セットを終了させる
if (FL0.cfg.cntlimit != 0) {
if (rpCountS >= FL0.cfg.cntlimit) {
WA0.rtn = 301;
WA0.error = "更新ページが設定制限数に到達しました。";
break;
}
}
}
FS0.Write(iewrite("<br />\n", 1));
}
//IE出力
function iewrite(intext, inmode, inmode2) {
if (FL0.cfg.monitor != "0") {
return(IE9.write(intext, inmode, inmode2));
}
else {
if (inmode == 1) {
return(intext);
}
}
}
/*
* 汎用文字置換
*
*/
function EditReplace() {
this.rtn = 0;
this.error = "";
this.submit = 0;
this.exctbl = new Array(); //this.replaceを呼び出すたびに(呼び出す直前に)オリジナルからここに複写して、時刻・記事名などを埋め込むように使う
this.regmode = "";
this.repmode = "";
this.newtext = "";
this.rgflg = "";
this.oldtext = "";
this.logtext = "";
this.matchtbl = new Array();
//文章編集 intext:対象文章
this.replace = function(intext) {
var outtext = intext;
var pointA = 0;
var rgexp = new RegExp();
var aflg = 0;
var bcnt = 0;
var ccolor = "";
this.rtn = 0;
this.logtext = "";
this.matchtbl[0] = "";
//置換セットのループ
var kei = 0;
var kej = 0;
var kek = 0;
var testflg = 0;
while (kei in this.exctbl) {
//仕切り位置を確認・分解
pointA = this.exctbl[kei].length + 1;
kek = 2;
while (kek < this.exctbl[kei].length) {
if (this.exctbl[kei].substr(kek, 1) == "," &&
this.exctbl[kei].substr(kek - 1, 1) != "\\") {
pointA = kek;
break;
}
kek++;
}
this.regmode = this.exctbl[kei].substring(0, 1);
this.repmode = this.exctbl[kei].substring(1, 2);
this.oldtext = this.exctbl[kei].substring(2, pointA);
this.newtext = this.coderep(this.exctbl[kei].substring(pointA + 1)); //通常検索を正規表現に強制変換
if (this.repmode == ":" ||
this.repmode == ";") {
this.oldtext = this.oldtext.replace(/([\[\(\^\$\.\*\+\?\|\{\}\]\)])/g,"\\$1");
//;大小文字を区別しない。空白を_にも対応。\nのみ機能。
if (this.repmode == ";") {
this.oldtext += "/i";
this.oldtext = this.oldtext.replace(/ /g,"[ _ \t]");
this.oldtext = this.oldtext.replace(/\\\n/g,"\\n");
this.oldtext = this.oldtext.replace(/\\\[\\\[(.)/g,"\\[\\[[ _ \t]*?$1");
this.oldtext = this.oldtext.replace(/(.)\\\]\\\]/g,"$1[ _ \t]*?\\]\\]");
this.oldtext = this.oldtext.replace(/\\\{\\\{(.)/g,"\\{\\{[ _ \t]*?$1");
this.oldtext = this.oldtext.replace(/(.)\\\}\\\}/g,"$1[ _ \t]*?\\}\\}");
this.oldtext = this.oldtext.replace(/(.)\\\|(.)/g,"$1[ _ \t]*?\\|[ _ \t]*?$2");
}
}
//大小文字を区別しない場合
this.rgflg = this.oldtext.substring(this.oldtext.length - 3);
if (this.rgflg.substring(0,1) != "\\" &&
this.rgflg.substring(1,3) == "/i") {
this.oldtext = this.oldtext.substring(0, this.oldtext.length - 2);
this.rgflg = "i";
}
else {
this.rgflg = "";
}
if (this.regmode >= "a" && this.regmode <= "z") {
rgexp = new RegExp(this.oldtext, this.rgflg);
testflg = rgexp.test(outtext);
}
switch (this.regmode) {
case "e":
//存在時にエラー
if (testflg == true) {
this.logedit2(outtext, 40, 1, "");
this.error = "※※除外条件検出のため更新できません";
this.logtext += this.error + "<br />\n";
this.rtn = 1;
}
else {
this.logedit2(outtext, 40, 0, "");
this.logtext += "○除外条件には該当しません<br />\n";
}
break;
case "f":
//未存在時にエラー
if (testflg == false) {
this.logedit2(outtext, 40, 0, "");
this.error = "※※必須条件未検出のため更新できません";
this.logtext += this.error + "<br />\n";
this.rtn = 2;
}
else {
this.logedit2(outtext, 40, 1, "");
this.logtext += "○必須条件に合致します<br />\n";
}
break;
case "c":
//退避記憶を複写
if (isNaN(this.oldtext) || isNaN(this.newtext)) {
this.oldtext = "0";
this.newtext = "0";
}
if (bcnt == 0) {
this.matchtbl[this.oldtext - 0] = "";
}
this.matchtbl[this.newtext - 0] = this.matchtbl[this.oldtext - 0];
this.logedit2(outtext, 40, 0, "");
this.logtext += "☆退避" + this.oldtext + "を退避" +
this.newtext + "に複写しました:" +
this.tagrep(this.matchtbl[this.newtext - 0]) + "<br />\n";
break;
case "a":
case "s":
case "t":
//[t](テスト)のログ出力はオレンジ
ccolor = "";
if ( this.regmode == "t" ) {
ccolor = "orange";
}
//更新時には[t](テスト)を処理しない
if ( this.regmode != "t" || this.submit == 0 ) {
bcnt = 0;
if ( this.oldtext.substr(0,1) == "^" ||
this.oldtext.substr(this.oldtext.length - 1,1) == "$" ) {
//先頭または末尾に追加
if (testflg == true) {
this.logedit2(outtext, 80, 1, ccolor);
outtext = outtext.replace(rgexp, this.newtext);
this.matchtbl[0] = RegExp.lastMatch;
if (this.regmode == "a") {
aflg = 1;
}
bcnt++;
}
}
else {
var outtext2 = "";
var matchtext = "";
var centertext = "";
var lefttext = "";
var righttext = "";
//同じ置換を繰り返す
while (rgexp.test(outtext)) {
outtext = outtext.replace(rgexp, this.newtext);
matchtext = RegExp.lastMatch;
lefttext = RegExp.leftContext;
righttext = RegExp.rightContext;
centertext = outtext.replace(lefttext, "").replace(righttext, "");
this.logedit(centertext, matchtext, outtext2 + lefttext, righttext, 40, 1, ccolor);
this.matchtbl[0] = matchtext;
if (this.regmode == "a") {
aflg = 1;
}
outtext2 += lefttext + centertext;
outtext = righttext;
bcnt++;
if (bcnt > 1000) {
this.error = "※※置換回数が規定値を超え更新できません";
this.logtext += "<br />\n" + this.error + "<br />\n";
this.rtn = 3;
break;
}
}
outtext = outtext2 + outtext;
}
}
break;
default:
this.error = "※※入力モードに誤りがあります:" + this.regmode;
this.logtext += this.error + "<br />\n";
this.rtn = 9;
}
if (this.rtn != 0) {
break;
}
kei++;
}
if (this.rtn == 0 && aflg == 0) {
this.error = "※※必須置換[a]対象がひとつもないため更新できません";
this.logtext += "<br />\n" + this.error + "<br />\n";
this.rtn = 4;
}
if (this.rtn == 0) {
//末尾の改行等を強制除去
outtext = outtext.replace(/\s$/g,"");
if (intext == outtext) {
this.error = "※※置換結果が置換前と同じため更新できません";
this.logtext += "<br />\n" + this.error + "<br />\n";
this.rtn = 5;
}
}
this.logtext += "<br />\n";
return(outtext);
}
//改行・タブ文字変換
this.coderep = function(intext) {
var outtext = intext;
outtext = outtext.replace(/\\n/g,"\n");
outtext = outtext.replace(/\\t/g,"\t");
outtext = outtext.replace(/\\,/g,",");
outtext = outtext.replace(/\\0/g,this.matchtbl[0]);
outtext = outtext.replace(/\\1/g,this.matchtbl[1]);
outtext = outtext.replace(/\\2/g,this.matchtbl[2]);
outtext = outtext.replace(/\\3/g,this.matchtbl[3]);
outtext = outtext.replace(/\\4/g,this.matchtbl[4]);
outtext = outtext.replace(/\\5/g,this.matchtbl[5]);
outtext = outtext.replace(/\\6/g,this.matchtbl[6]);
outtext = outtext.replace(/\\7/g,this.matchtbl[7]);
outtext = outtext.replace(/\\8/g,this.matchtbl[8]);
outtext = outtext.replace(/\\9/g,this.matchtbl[9]);
return (outtext);
}
//ログ生成
this.logedit = function(ctext, mtext, ltext, rtext, length, outflg, incolor) {
var outtext = "";
//カラー標準設定
if ( incolor == "" ) {
incolor = "red";
}
//置換指示文
outtext = "["+ this.regmode + "] " + this.tagrep(this.oldtext);
if (this.rgflg != "") {
outtext += "/" + this.rgflg;
}
outtext += ":→:" + this.tagrep(this.newtext);
outtext = "<br />\n" + outtext + "<br />\n";
//置換文前後
if (outflg == 1) {
var toptext = "";
var bottomtext = "";
if (this.oldtext.substr(0,1) == "^") {
toptext = "<b><font color=" + incolor + ">^</font></b>";
}
if (this.oldtext.substr(this.oldtext.length - 1,1) == "$") {
bottomtext = "<b><font color=" + incolor + ">$</font></b>";
}
outtext += this.tagrep(ltext.substr(ltext.length - length)) + toptext + "<b><font color=" + incolor + ">" + this.tagrep(mtext) + "</font></b>" + this.tagrep(rtext.substr(0, length)) + bottomtext + "<br />\n";
}
this.logtext += outtext;
}
//ログ生成補助
this.logedit2 = function(intext, length, outflg, incolor) {
this.logedit("", RegExp.lastMatch, RegExp.leftContext, RegExp.rightContext, length, outflg, incolor);
}
//タグの無効化、改行などの視覚化
this.tagrep = function(intext) {
var outtext = intext;
outtext = outtext.replace(/</g,"<");
outtext = outtext.replace(/>/g,">");
outtext = outtext.replace(/\n/g,"\\n");
outtext = outtext.replace(/\t/g,"\\t");
outtext = outtext.replace(/ /g," \\b");
outtext = outtext.replace(/ /g,"\\_");
return(outtext);
}
}