Macro/投稿/38

http://sakura.qp.land.to/?Macro%2F%C5%EA%B9%C6%2F38


Top > Macro > 投稿 > 38

直前の閉じていない HTML/XML タグを閉じる

  • ページ: Macro/投稿
  • 作者: gis_dur?
  • カテゴリー: js
  • 投稿日: 2005-07-17 (日) 02:12:51

メッセージ

  0
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
/************************************************
**  Close Last Tag 2.1                         **
*************************************************
**  A "Sakura-Editor Macro" using WSH 5.6      **
**  For sakura.exe ver.1.4.7.0 and over        **
**            Copyright (C) 2004-2005 gis_dur  **
*************************************************
**【動作】                                     **
**  カーソル位置より前にある HTML/XML タグを   **
**  ファイル先頭に向かって検索し、             **
**  1. 閉じていないコメント                    **
**  2. 終了タグのない開始タグ                  **
**  がある場合、対応する終了タグを挿入します。 **
**  コメントタグ内は無視します。               **
************************************************/
 
// ======== 設定開始 ========
 
// true  : 構文エラーメッセージ非表示
// false : 構文エラーメッセージ表示
var QUIET_MODE  = false;
// 文字列 NO_CLOSE_TAG で指定された終了タグについて、
// true  : タグの省略を許さない (XML  モード)
// false : 常に省略する         (HTML モード)
var XML_MODE    = false;
// 省略可能な終了タグ
var NO_CLOSETAG = "|area|base|basefont|bgsound|br|col|embed|frame" +
                  "|hr|img|input|isindex|keygen|link|meta|nextid" +
                  "|param|spacer|wbr|!doctype|"; // 小文字で記述
// 省略可能な終了タグを増やすには、以下のように追加します
// var NO_CLOSETAG += "|colgroup|dd|dt|li|option|p|rp|rt|";
 
// ======== 設定終了 ========
 
/***********************************************************
**  変数定義                                              **
***********************************************************/
// 正規表現オブジェクト
var regExpObj_tags     =
    new RegExp("<[/!]?[A-Za-z][\\w\\-:]*([^>]*/>)?|<!--|-->", "g");
var regExpObj_newLines =
    new RegExp("\x0d\x0a|\x0d|\x0a", "g");
// 終了タグスタック
var stack_tags = new Array();
// 全タグ
var TagsArray  = new Array();
// タグ総数
var ntags = 0;
// 全行
var LinesArray = new Array();
// 行総数
var nlines = 0;
// カーソル位置
var cursorX, cursorY;
// カーソル位置より前にある全テキスト
var all_text = "";
// 現在判定中のテキスト
var now_text = "";
// カーソル位置に挿入するテキスト
var ins_text = "";
// テンポラリ文字列
var tmp_str  = "";
 
// コメントブロック処理中であれば true
var b_comment = false;
 
/***********************************************************
**  主処理                                                **
***********************************************************/
// 選択状態を解除
Editor.CancelMode(0);
// カーソル位置取得
cursorX = Number(Editor.ExpandParameter('$x'))-1;
cursorY = Number(Editor.ExpandParameter('$y'))-1;
// 全て選択
Editor.SelectAll(0);
// 読み込み
all_text = Editor.GetSelectedString(0);
// 選択状態を解除
Editor.CancelMode(0);
 
// 改行コード統一
all_text = all_text.replace(regExpObj_newLines, "\x0d\x0a");
// 行に分解
LinesArray  = all_text.split(/\n/);
nlines  = LinesArray.length;
// カーソル行の文字列を取得
tmp_str = LinesArray[cursorY];
// カーソルが最終行にあって、かつ最終行に一文字も無い場合、
// 現在行は空文字列とする。
if (tmp_str == null) tmp_str = "";
// カーソル以前の文字列のみ残す
if (nlines-(cursorY+1) > 0)
    LinesArray.splice(cursorY+1, nlines-(cursorY+1));
for (var i=0; i<cursorX; i++)
    if (isKanji(tmp_str.charAt(i)))
        cursorX--;
LinesArray[cursorY] = tmp_str.substring(0, cursorX);
// タグのリストを取得
TagsArray = LinesArray.join("\n").match(regExpObj_tags);
// タグ総数を取得
if (TagsArray == null) {
    ntags = 0;
} else {
    ntags = TagsArray.length;
}
 
// 直前の開始タグを検索する
for (var i=ntags-1;i>=0;i--) {
    // 注目しているタグまたはコメント
    if (!XML_MODE) {
        now_text = TagsArray[i].toLowerCase();
    } else {
        now_text = TagsArray[i];
    }
    // コメントブロック内での処理
    if ( b_comment ) {
        // コメント開始タグ
        if ( now_text=="<!--" ) {
            // コメントブロック処理を抜け出す
            b_comment = false;
        }
    // 通常処理
    } else {
    // -->
        if ( now_text=="-->" ) {
            // 検索位置より前はコメントブロック
            b_comment = true;
    // <!--
        } else if ( now_text=="<!--" ) {
            // コメント終了タグを挿入して終了
            ins_text = "-->";
            break;
    // <.../>
        } else if ( now_text.indexOf("/>")!=-1 ) {
            // 終了タグが必要ないので無視
    // </...>
        } else if ( now_text.indexOf("</")==0 ) {
            now_text = now_text.substring(2);
            // 終了タグスタックに追加
            stack_tags.push(now_text);
        } else {
            now_text = now_text.substring(1);
            // 終了タグをとらないタグは無視
            if (!XML_MODE && NO_CLOSETAG.indexOf("|"+now_text+"|")!=-1)
                continue;
            // 終了タグスタックの要素が無い場合
            // 対応する終了タグを挿入して終了
            if ( stack_tags.length==0 ) {
                ins_text = "</"+ TagsArray[i].substring(1) +">";
                break;
            // 終了タグスタックの最終要素と比較
            // 一致すれば無視して次のタグを検索
            // 一致しなければタグの包含関係に誤り
            // 例:<a> <b> </a> </b> ... |←検索開始位置
            } else {
                tmp_str = stack_tags.pop();
                if ( now_text!=tmp_str ) {
                    tmp_str = "タグの包含関係が不正です\n" +
                              "<" + now_text + "> ... ... " +
                              "</" + tmp_str + ">";
                    popup_error( tmp_str );
                    stack_tags=new Array();
                    break;
                }
            }
        }
    }
}
 
if (ins_text != "") {
    // 終了タグを挿入
    Editor.InsText(ins_text);
} else {
    // 不正なコメントブロック
    if ( b_comment )
        popup_error("コメントの開閉関係が不正です");
    // 終了タグスタックに余り要素
    if ( stack_tags.length ) {
        tmp_str = stack_tags.pop();
        tmp_str = "開始タグの無い終了タグが見つかりました\n" +
                  "</" + tmp_str + ">";
        popup_error( tmp_str );
    }
}
 
/***********************************************************
**  2バイト文字判定                                      **
***********************************************************/
function isKanji(c) {
    var tmp = escape(c);
    if (tmp.charAt(0) != "%") return false;
    if (tmp.charAt(1) == "u") return true;
    else return false;
}
 
/***********************************************************
**  エラー出力処理                                        **
***********************************************************/
function popup_error(err_string) {
    if (!QUIET_MODE) {
        Editor.SearchClearMark(0);
        var shell = new ActiveXObject("WScript.Shell");
        shell.Popup(err_string, 0, "HTML 文法エラー", 0);
    }
}


URL B I U SIZE Black Maroon Green Olive Navy Purple Teal Gray Silver Red Lime Yellow Blue Fuchsia Aqua White

リロード   新規 編集 凍結 差分 添付 複製 名前変更   ホーム 一覧 単語検索 最終更新 バックアップ リンク元   ヘルプ   最終更新のRSS
Last-modified: 2006-07-30 (日) 00:15:00 (4521d)