以下のJSとHTAと+1のファイルの圧縮(LZH) 15KB
.js は単独でも使用できる。
.hta は、.js が必要。もう一つ、.hta が使う 0〜0xff迄の文字を書いたファイルあり。
[ .js ]
// .js 、文字コード(セット)を変換した、別ファイルを作成。
// 目的のファイルかフォルダを、これに落して使う。
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 設定、
var 設_元コード = ""
// 元のファイルの文字コードセット。 例、"shift_jis" "iso-2022-jp" "euc-jp" "utf-8"
// [HKEY_CLASSES_ROOT\MIME\Database\Charset] のサブキー参照
// "_autodetect" というのもあるが、"shift_jis" と "iso-2022-jp" を判断してくれる程らしい。
if(!設_元コード) 設_元コード = "%自判定%"
// 「設_元コード」が空なら、文字セットを判定してみる。但し使い物にはならず。
// "%自判定%" は、関数「文字セット判定」を使うキーワード。
// ここを消して「設_元コード」を空のままにしておけば、入力ダイアログ出す
var 設_変換後コード = ""
// 変換後のコードセット指定。 "_autodetect" だと、"shift_jis" に?
// 空のままにしておけば、入力ダイアログ出す
var 設_変換後改行コード // = "\r\n"
// ついでに改行コードも変えるとしたら。"\n" "\r\n" などを指定。
var 設_変換後フォルダ = "tmp"
// 変換後のファイルを作る場所。(ファイル名は元名を使う)
// パスでない(ファイル名)なら此処のフォルダ中に。(空なら此処のフォルダ)。".." は使えない。
var 設_バイナリファイル確認パターン = /^[^\xfe\xff]{2}(.|\n)*?[\1-\x06\x0e-\x19\x1c-\x1f]/
// バイナリファイルと判断して、文字セットの変換を実行しない為のパターン。
// よく判らないのだが、\0-\x1f の内、テキストにありそうな文字
// \0\a\b\t\n\v\f\r eof esc を除いたどれかがあれば、としておく。
// しかし、これでは、ユニコードをバイナリとしてしまうので、最初の2文字の条件。
// バイナリでそれに一致してしまうと困ることになる。
// また、最初の2文字(ユニコードのバイト順序指示)がないユニコードも。
//------------------------------------------------
// フォルダを引数に与えた場合の動作
var 設_ファイル名パターン = /\.txt$|\.html?$/i
// フォルダ中で、作業の対象にするファイルの名前のパターン。
// 例、拡張子が、xxx → /\.xxx$/i
var 設_フォルダ下降 = false // 真偽 (true|false 、0|1 など)
// フォルダの中のフォルダの中のファイルにも作業するか?
//------------------------------------------------
// 結果報告を書き出すファイルの設定、(WScriptで実行時のみ、短い場合はダイアログで済ませる事に)
var 設_報告ファイル = "結果報告.tmp.txt"; // パス
// 報告用ファイルのパス。( \ は、\\ に。/ でもいい)
// パスでない(ファイル名)ならこれと同じフォルダに作る。
// 空なら、クリップボードへ。
var 設_報告ファイル文字セット = "_autodetect"
var 設_エディタ = "" // パス、コマンド
// 報告ファイルを開くエディタを指定するなら。
// 設定、ここ迄。
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
var FS = new ActiveXObject("Scripting.FileSystemObject")
var WS = new ActiveXObject("WScript.Shell")
var IE // "InternetExplorer.Application" 、場合により使う。
var src_STM = new ActiveXObject("ADODB.Stream")
var dest_STM = new ActiveXObject("ADODB.Stream")
var 設_変換後一時フォルダ; // htaで一時的変更の時に使う変数
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 文字コードセットの判断
// バイナリストリームで開くべきだろうけど、JS のみでは値を得られない為、"iso-8859-1"で開く。
// 但し、0x80-0x9fの間は、元のバイトコードのままではなく、
// 2バイトのユニコードになる(全部ではないが)、(例えば、…†‡‰‘’“”)、(これを書込むと1バイトに戻る)。
// 0xff 以上なら、0x80-0x9f と。
function 文字セット判定(filePath, bchkOnly){
//「bchkOnly」は、バイナリファイルでないかどうかの確認のみ行う。
// そうでなく文字セット判定で、バイナリファイルと判定したらエラーで返すので、呼出しは try-catch 内で。
src_STM.Charset = "iso-8859-1" // ascii(Latin-1)のストリームで開く
src_STM.Open(); src_STM.LoadFromFile(filePath)
var str = src_STM.ReadText(); src_STM.Close()
if(設_バイナリファイル確認パターン && 設_バイナリファイル確認パターン.test(str)){
if(bchkOnly)return 'バイナリファイル?、中止';
throw {description:'バイナリファイル?、中止'} // エラー投げる
}if(bchkOnly) return // バイナリファイル確認のみの場合、ここ迄。
return 判定試行2(str) // ← ここで↓の関数を変更。
}///
function 判定試行2(str){
if(/^[\xfe\xff]{2}/.test(str)) return "unicode"
//if(/\x1b.+\x1b/.test(str)) return "iso-2022-jp"
if(/\x1b\$.+\x1b\(/.test(str)) return "iso-2022-jp" // /\x1b\$B.+\x1b\(B/
if(/[\x81-\xfe]|[^\0-\xff]/.test(str)){
//if(/[\xE0-\xEF][\x80-\xBF\u0100-\u3000][\x80-\xBF\u0100-\u3000][\xE0-\xEF]/.test(str)) return "utf-8"
// 0x80-0x9f を、大雑把だが、[\u0100-\u3000]
// これでは、"shift_jis" "euc-jp" を、"utf-8" としてしまうか。
if(/[\x81-\x9f]|[^\0-\xff]/.test(str) && !/[\xfd\xfe]/.test(str) )
return "shift_jis" // "shift_jis" で使わない[\xfd\xfe]が無い事。
// [\x8e\x8f] は "euc-jp"にも使われるらしいが。
return "euc-jp" //
}///
return "iso-8859-1" // "shift_jis"
}///
function 判定試行1(str){
if(/^[\xfe\xff]{2,}/.test(str)) return "unicode"
var high = false // 0x80 以上のバイトの有無
for(var i=0, ch; i<str.length; i++){ ch = str.charCodeAt(i)
if(ch > 0x7f){ if((ch !=0x80 && ch<= 0x9f) || ch>0xff) return "shift_jis" // [\x81-\x9f] がある
high = 1; i++ }
else if(ch==0x1b) return "iso-2022-jp" // 0x1b(Esc)の有無
}if(high)return "euc-jp"; return "iso-8859-1" //
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 直接の作業部分。文字コードを変換したファイルを作成。
function 文字セットの変換(src_filePath, src_charset, dest_filePath, dest_charset){
// src_filePath 元のファイルパス、src_charset その文字コードセット
// dest_filePath 変換後の保存先ファイルパス、dest_charset 変換後の文字コードセット指定
src_STM.Open(); if(src_charset) src_STM.Charset = src_charset // 設定なしは "unicode" で読む
src_STM.LoadFromFile(src_filePath)
if(!src_STM.Size){ src_STM.Close(); return '空ファイル?' }
dest_STM.Open(); if(dest_charset) dest_STM.Charset = dest_charset // 設定なしは "unicode" に変換
if(設_変換後改行コード) dest_STM.WriteText( 改行の変更( src_STM.ReadText() ) ); // 改行コード変更もする場合。
else src_STM.CopyTo(dest_STM);
src_STM.Close(); var err;
try{ dest_STM.SaveToFile(dest_filePath, 2); }catch(e){ err = e.description }// 2 新規作成上書き
dest_STM.Close(); return err;
}///
function 改行の変更(str){
return str.replace(/\r\n|\n?\r|\n/g, 設_変換後改行コード) // パターンがこれでいいか?
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 存在しないフォルダを遡って作る
function フォルダ作成(foldPath){
var 合, 名配 = []; foldPath = foldPath.replace(/\\$/,'');
while( ! FS.FolderExists(foldPath) )
if(合= foldPath.match(/\\[^\\]+$/)){
名配.push(合[0]); foldPath = foldPath.replace(/\\[^\\]+$/,''); }//
else return( 'フォルダ作成失敗、'+ foldPath +' ?');
if(名配.length)try{ 名配.reverse(); // 名配[n] は "\\名前"
for(var i=0; i<名配.length; i++) FS.CreateFolder( foldPath += 名配[i] );
}catch(e){ return 'フォルダ作成失敗、'+ e.description; }
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 中心。
function 文字コード変換の実行(argA){
// フォルダが引数の場合
function フォルダから作業へ(topFolderPath){
function reflexive_folder(folderPath){
pick_file(folderPath)
var folderA =[], folders = new Enumerator( FS.GetFolder(folderPath).SubFolders )
for (; ! folders.atEnd(); folders.moveNext()) folderA.push( folders.item()+'' )
folderA.sort();
for(var i=0; i<folderA.length; i++) reflexive_folder( folderA[i] )
}///
function pick_file(folderPath){
var fileA =[], files = new Enumerator( FS.GetFolder(folderPath).Files )
for (; ! files.atEnd(); files.moveNext()){
if(設_ファイル名パターン && ! 設_ファイル名パターン.test(files.item()+'') )continue;
fileA.push(files.item()+'')
}///
if(fileA.length){ fileA.sort(); //for(var i=0; i< fileA.length; i++){ }
var relPath = folderPath.replace(topFolderParentPath, '')
var newFold = 置場所 + relPath // 「置場所」の末尾には \ あり
var str = ファイル配列から作業へ(fileA, newFold)
if(str)文 += '['+ relPath +']\n'+ str
}///
}///
var 文 = '';
var topFolderParentPath = topFolderPath.replace(/\\[^\\]+\\?$/,'\\')
// 各フォルダのパスから、この部分を消す(トップフォルダの名は残した相対パスを出す)為。
if(設_フォルダ下降) reflexive_folder( topFolderPath )
else pick_file( topFolderPath )
return 文;
}///
// ファイル配列からファイルを取り出して作業(実行)へ送る
function ファイル配列から作業へ(fileA, 場所){
var str ='', dest_filePath, src_charset = 設_元コード
for(var i=0, res, flag, errS; i<fileA.length; i++, res=''){
dest_filePath = 場所.replace(/\\?$/,'\\') + fileA[i].replace(/.+\\/,'')
if(判定)try{ src_charset = 文字セット判定(fileA[i])
}catch(e){ res = e.description }
else res = 文字セット判定(fileA[i], 1)// バイナリファイルでないか、のみ判断
if( !変換実行せず && !res && src_charset){
if( !flag && (errS= フォルダ作成(場所)) )return errS +' 、 '+ 場所 +'\n';
res = 文字セットの変換(fileA[i], src_charset, dest_filePath, 設_変換後コード)
}//
str += fileA[i].replace(/.+\\/,'') + (res ? ' '+res: (判定 ? ' 元、'+src_charset: '')) +'\n'
}/// src_charset と 設_変換後コード が同じになる場合、を考えていない。
return str
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
if(設_元コード==設_変換後コード){ alert('変換後のコードも同じなので、実行しない'); return; }
var res = 引数調べて分ける(argA); if(!res){ alert(''); return; }
var fileA = res[0], foldA = res[1]
var 判定 = 設_元コード=="%自判定%" ? true: false;
var 置場所 = (設_変換後一時フォルダ ? 設_変換後一時フォルダ: 設_変換後フォルダ);
置場所 += /\\$/.test(置場所) ? '': '\\';
var 変換実行せず;
// 実行確認、
var sConf = '元 、'+ 設_元コード +'\n変換後、'+ 設_変換後コード +'\n\n保存先、'+ 置場所 +'\n';
if(foldA.length){
sConf += '\n'+ (設_フォルダ下降 ? 'フォルダ内部を、降って実行' : '直下のファイルにのみ実行' ) +'\n'
+ (設_ファイル名パターン ? 'ファイル選択のパターン、 '+設_ファイル名パターン+'\n': '')
sConf += 'フォルダ、'+ (foldA.length >12 ? foldA.length+' 個' : '\n'+foldA.join('\n') );
}///
if(fileA.length) sConf += '\nファイル、'+
(fileA.length >12 ? fileA.length+' 個' : '\n'+fileA.join('\n') ) +'\n';
//if( 1 != WS.Popup(sConf, 60, '実行確認', 1) )return;
var res = WS.Popup( sConf+'\n\n[いいえ] で、テスト (変換は実行せず)', -1, '実行確認', 3 ); // 三択
if( !(res==6 || res==7))return; 変換実行せず = (res==7 ? true: false);
// 実行へ
var report = '';
if(fileA.length)report = ファイル配列から作業へ(fileA, 置場所)
for(var i=0, res; i<foldA.length; i++)
if( res= フォルダから作業へ(foldA[i]) ) report += res
// 報告
if( !report){ alert('該当なし'); return }
if( !WScript) return report
if( (res=report.match(/\n/g)) && res.length > 10 ) 報告の書込み(report);
else alert('完了\n\n'+ report)// 少ない場合、ダイアログに
}///
function 報告の書込み(文){
try{ if( ! 設_報告ファイル)throw 0;
dest_STM.Open(); dest_STM.Charset = 設_報告ファイル文字セット
dest_STM.WriteText(文); dest_STM.SaveToFile(設_報告ファイル, 2);
dest_STM.Close();
}catch(e){ // 書き込みできなかった時
if(WScript){
if(!IE){ IE = new ActiveXObject("InternetExplorer.Application"); IE.Navigate("about:blank") }
clipboardData = IE.Document.frames.clipboardData }///
clipboardData.setData('text', 文); if(WScript)IE.Quit()
if(設_報告ファイル || !WScript)alert( (e ? e.description: '') +'\n\n結果は、クリップボードに送った。');
return
}/// 結果報告ファイルを開く
WS.Run( (設_エディタ ? '"'+ 設_エディタ +'" ': '') +'"'+ 設_報告ファイル +'"' )//
}///
function 引数調べて分ける(argA){
var fileA =[], foldA =[], invalidA =[]
for(var i=0, arg, p; i<argA.length; i++){
arg = argA[i].replace(/^"(.+)"$/g,'$1');//" HTAの引数の場合
//if( ! /^\w+:\\|^\\/.test(arg) ) try{ eval(arg); continue }catch(e){ }
// ↑コマンドラインから設定、"変数名 = 値" などと。ただ値中の " や \ など厄介。
if( /\.lnk$/i.test(arg) )// ショートカットの場合。
try{ if(p = WS.CreateShortcut(arg).TargetPath)arg = p; else throw 1
}catch(e){ invalidA.push(arg) }///
if(FS.FolderExists(arg)) foldA.push(arg)
else if(FS.FileExists(arg)) fileA.push(arg)
else invalidA.push(arg)
}///
if(invalidA.length) alert('無効か不明な引数\n\n'+invalidA.join('\n'))
return [fileA, foldA]
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 設定の修正と、開始
try{ WScript }catch(e){ WScript =null }// WScript, alert, clipboardData, は宣言せず使用
var cd = WScript ? WScript.ScriptFullName.replace(/\\[^\\]+$/, '\\')
: location.pathname.replace(/^[\/]*(.+\\)[^\\]+$/,'$1')
if(設_変換後フォルダ) 設_変換後フォルダ = 設_変換後フォルダ.replace(/[\/]/g,'\\')
if( ! 設_変換後フォルダ || ! /^\\|:/.test(設_変換後フォルダ) ){
if( ! 設_変換後フォルダ)設_変換後フォルダ = '';
設_変換後フォルダ = cd + 設_変換後フォルダ.replace(/^\.\\/,'')
}///
if(設_報告ファイル) 設_報告ファイル = 設_報告ファイル.replace(/[\/]/g,'\\')
if(設_報告ファイル && ! /^\\|:/.test(設_報告ファイル) ){
設_報告ファイル = cd + 設_報告ファイル.replace(/^\.\\/,'')
}///
function WScriptで実行(){
alert = function(s){ WScript.Echo(s) }
if( ! WScript.Arguments.length){ alert('ファイルかフォルダを落す'); return }
if( !設_元コード || !設_変換後コード){ //alert('設定を'); return
IE = new ActiveXObject("InternetExplorer.Application"); IE.Navigate("about:blank")
var w = IE.Document.frames, s = '例、 shift_jis iso-2022-jp euc-jp utf-8 ';
if(!設_元コード && (設_元コード = w.prompt('元(現在)の文字セットを\n '+s, '') ) )
設_元コード = 設_元コード.replace(/\0.*/,'')
if(!設_変換後コード && (設_変換後コード = w.prompt('変換後の文字セットを\n '+s, 'shift_jis') ) )
設_変換後コード = 設_変換後コード.replace(/\0.*/,'')
}//
var argA =[]
for(var i=0; i<WScript.Arguments.length; i++)
argA.push( WScript.Arguments(i) )
文字コード変換の実行(argA)
}if(WScript)WScriptで実行()
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// ここ迄。
[ .hta ]
<head>
<title>文字セット変換 - HTA</title>
<script type="text/javascript" src="文字コード変換.js" id="scr1"></script>
<script type="text/javascript">
// 設定、
var 設_保存後ファイル開く // 真偽、(false 0 "" 未定義 なら偽。以外は真)
// true でファイル一つを変換や書込みした後に、そのファイルを開く。
// 但し「設_エディタ」を指定しないとまずい(拡張子により何で開かれるか判らない)。
var 設_バイトファイル = 'bytes'
// バイナリストリームへの書込み方法判らない為に使う、0〜0xff迄の文字を書いたファイル
設_バイトファイル = location.pathname.replace(/^[\/]*(.+\\)[^\\]+$/,'$1')+設_バイトファイル
// 同じフォルダに
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
var 入力_ファイルパス
function 入力設定の収集(標){
// 標、 1 ファイル内容表示。2 ファイル一つ変換。4 textArea欄文の書込み
if(標 !=4)設_元コード = select1/**/[ select1/**/.selectedIndex ].value
if(標 !=1){ 設_変換後コード = select2/**/[ select2/**/.selectedIndex ].value
var n = select3/**/.selectedIndex
設_変換後改行コード = n ? (n==1 ? '\r\n': '\n'): null }// 0 は変更なし
if(標 < 3){ // 入力欄のファイル1つにのみ実行する場合。
入力_ファイルパス = txtFilePath/**/.value;
if(!入力_ファイルパス) return 'ファイルの入力なし' }//
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
function 指定コードで読込んで表示(){
var res; if( res= 入力設定の収集(1) ){ alert(res); return; }
if(設_元コード=="%バイト%"){ バイト表示(入力_ファイルパス); return }
if(設_元コード=="%自判定%")try{ 設_元コード = 文字セット判定(入力_ファイルパス)
}catch(e){ alert(e.description); return }
//else if(res= 文字セット判定(入力_ファイルパス, 1)){ alert(res); return; }
var str
try{ src_STM.Charset = 設_元コード; src_STM.Open();
src_STM.LoadFromFile(入力_ファイルパス)
str = src_STM.ReadText(); src_STM.Close();
}catch(e){ if(src_STM.State)src_STM.Close(); alert(e.description); return }//
ファイル内容の表示(str, 1);
}///
var byte_STM
function バイト表示(src_filePath){
if( !byte_STM){ byte_STM = new ActiveXObject("ADODB.Stream"); byte_STM.Type = 1; }
try{ byte_STM.Open(); byte_STM.LoadFromFile(src_filePath); var str ='';
while(!byte_STM.EOS)
str += ( '0'+ getByteHex(byte_STM.Read(1)) ).slice(-2)/**/ +' '; // VBS使用
byte_STM.Close();
}catch(e){ if(byte_STM.State)byte_STM.Close(); alert(e.description); return }//
str = str.replace(/0D 0A |(0A )?0D |0A /g,'$&\n'); ファイル内容の表示(str)
}///
function ファイル内容の表示(str, escRep){
if(!str){ alert('空?'); return }
if(escRep) str = str.replace(/[\0-\x1f\x7f-\x9f]/g, // 表示できない(制御)文字は、%hh に。
function(c){ if(c=='\n'||c=='\r'||c=='\t')return c;
return '%'+ ( '0'+ c.charCodeAt(0).toString(16) ).slice(-2)/**/ } );//
// ↑\x80〜は2バイト文字にされるので指定しても大概は無駄だった("unicode"でない場合)。
var sInfo = 設_元コード +' : '+ 入力_ファイルパス.replace(/.+\\/,'')
infoRes1/**/.innerHTML = sInfo
//textArea1/**/.value = str; // textArea にも表示してしまうとしたら。
dispPre.innerHTML = str.replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')
.replace(/\r\n|\n?\r|\n/g, '<br>$&').replace(/ /g, ' ').replace(/\t/g, ' ')
// PRE要素で表示しようと思ったが止め。IEで PRE要素.innerHTML=str とするには、
// 改行・空白類を通常の要素と同じく BR や に置換する必要ある。
// 要素.innerHTML='<pre>'+str+'</pre>' とすればそれは不用だが、PRE要素の表示はひどく遅い。
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
function ファイル一つを変換へ(){
// 条件・設定の収集、
var res; if( res= 入力設定の収集(2) ){ alert(res); return; }
var file = 設_変換後フォルダ + ( /\\$/.test(設_変換後フォルダ) ? '': '\\')
+ 入力_ファイルパス.replace(/.+\\/,'') // 保存先ファイルパス
if(設_元コード=="%自判定%")try{ 設_元コード = 文字セット判定(入力_ファイルパス)
}catch(e){ alert(e.description); return }
else if(res= 文字セット判定(入力_ファイルパス, 1)){ alert(res); return; }
if( /%/.test(設_元コード) || /%/.test(設_変換後コード) ){
alert("文字セットに、選択されているものは、無効"); return }
// 確認、
var s = '元、 '+ 設_元コード +' 、 '+ 入力_ファイルパス.replace(/.*\\/,'')
+'\n後、 '+ 設_変換後コード
+(設_変換後改行コード ? ' 、 改行 '+設_変換後改行コード.replace(/[\n\r]/g,
function(c){ return (c=='\n' ? 'LF':'CR') })+' に' :'')
+' 、 保存先ファイル名は ?'
if( ! ( file= prompt(s, file) ) )return; file = file.replace(/\0.*/,'')
if( !保存場所の確認と処置(file))return
// 実行へ
var res = 文字セットの変換(入力_ファイルパス, 設_元コード, file, 設_変換後コード)
if(res) alert(res);
else if(設_保存後ファイル開く)エディタで開く(file)
}///
function 保存場所の確認と処置(filePath){
if(FS.FileExists(filePath) &&
!confirm('保存先、'+filePath+'\nは、既に存在するが、上書きするか、中止か、')) return
var err, fold = filePath.replace(/\\[^\\]+$/,'')
if( ! FS.FolderExists(fold) && (err= フォルダ作成(fold)) ){ alert(err); return; }
return true;
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// textArea欄の文を、指定のコードでファイルに書込み。
function テキストをファイルに保存(){
var str = textArea1/**/.value; if( !str ){ alert('欄が空'); return; }
var res; if( res= 入力設定の収集(4) ){ alert(res); return; }
var file = 設_変換後フォルダ.replace(/\\$|$/,'\\') + 'tmp.txt'// 保存先ファイルのパス
if( ! ( file= prompt('保存先のファイルパス・名を入力', file) ) )return; file = file.replace(/\0.*/,'')
if(/\\$/.test(file)){ alert('ファイル名を指定のこと'); return; }
if(設_変換後コード=="%バイト%"){ バイトで書込み(str, file); return }
if( !保存場所の確認と処置(file))return
if(設_変換後改行コード) str = 改行の変更(str)
try{ dest_STM.Open(); dest_STM.Charset = 設_変換後コード
dest_STM.WriteText(str); dest_STM.SaveToFile(file, 2);
dest_STM.Close();
}catch(e){ if(dest_STM.State)dest_STM.Close(); alert(e.description); return }//
if(設_保存後ファイル開く)エディタで開く(file)
}///
function バイトで書込み(str, filePath){
if(!設_バイトファイル){ alert("できない、0〜0xff迄の文字を書いたファイルが必要。"); return }
// 以下、バイナリストリームへの書込み、方法判らず。
// テキストストリームだと、例えば、"iso-8859-1" なら、0x80-0x9f が化けるし
// "unicode" で書込んで "\0" を削除と考えても、そこでまた同じ問題に会う。
// 仕方ないので、0〜0xff迄の文字を書いたファイルを用意して
// バイナリストリームからバイナリストリームへ書込みことに。→ ※
if(/[^a-f\d\s]/i.test(str)){ alert('数字、A-F、空白類以外の文字が混ざっている'); return }
var hexA = str.match(/[a-f0-9]+/ig), codeA =[]
if( !hexA || !hexA.length){ alert('空'); return; }
if( !保存場所の確認と処置(filePath))return
for(var i=0, matchA; i<hexA.length; i++){
matchA = hexA[i].match(/..|./g)
for(var j=0, n; j<matchA.length; j++)
if( !isNaN(n= parseInt('0x'+ matchA[j])) ) codeA.push(n)//codeA.push(getByte(n))
}///
try{ if( !byte_STM){ byte_STM = new ActiveXObject("ADODB.Stream"); byte_STM.Type = 1; }
byte_STM.Open();
//for(var i=0; i< codeA.length; i++) byte_STM.Write( getByte(codeA[i]) )// だめ
// ↓ 仕方ないので、、※
var getbyte_STM = new ActiveXObject("ADODB.Stream"); getbyte_STM.Type = 1;
getbyte_STM.Open(); getbyte_STM.LoadFromFile(設_バイトファイル)
for(var i=0; i< codeA.length; i++){
getbyte_STM.Position = codeA[i]; byte_STM.Write( getbyte_STM.Read(1) )
}getbyte_STM.Close()
byte_STM.SaveToFile(filePath, 2); byte_STM.Close();
}catch(e){ if(byte_STM.State)byte_STM.Close(); if(getbyte_STM.State)getbyte_STM.Close();
alert(e.description); return }//
if(設_保存後ファイル開く)エディタで開く(filePath)
}///
function エディタで開く(filePath){
WS.Run( (設_エディタ ? '"'+ 設_エディタ +'" ': '') +'"'+ filePath +'"' )//
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
function 一括の変換へ(){
// 条件・設定の収集、
var res; if( res= 入力設定の収集(8) ){ alert(res); return; }
// 対象のファイル、フォルダ
var newfileA =[], newfoldA =[], 集 = divArgs/**/.getElementsByTagName('input')
for(var i=0, 当; i<集.length; i++)
if(集[i].checked && (当= 集[i].id.match(/([^\d]+)(\d+)/)) ){
if(当[1] =='fi') newfileA.push( 引_filePathA[ 当[2] ] )
else if(当[1] =='fo') newfoldA.push( 引_foldPathA[ 当[2] ] )
}///
var argA = newfileA.concat(newfoldA)
if( !argA.length){ alert('引数(ファイルかフォルダ)がない'); return }
if(newfoldA.length){ // フォルダが引数の場合の設定
var text = filePtn/**/.value, flag, ptn
if(text){ flag = filePtnflag/**/.value;
try{ ptn = new RegExp(text, flag); }catch(e){ throw e; } }///
設_ファイル名パターン = ptn;
設_フォルダ下降 = chkReflv/**/.checked
}///
// 保存場所の確認・入力、
var fold = (設_変換後一時フォルダ ? 設_変換後一時フォルダ: 設_変換後フォルダ)
if( ! (fold= prompt('変換後の保存先フォルダを、', fold) ) ) return
設_変換後一時フォルダ = fold.replace(/\0.*/,'')
// 実行と、結果の報告表示
var resStr = 文字コード変換の実行(argA)
if(resStr) dispRes.innerHTML = '<pre>'+ resStr.replace(/&/g, '&').replace(/</g,'<') +'</pre>'
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
</script><script type="text/vbscript">
Function getByteHex(b): getByteHex = Hex(AscB(b)): End Function
Function getByte(n): getByte = ChrB(n): End Function
</script><script type="text/javascript">
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 初期表示と引数
var 引_filePathA =[], 引_foldPathA =[] // 引数の配列
onload = function(){ 最初の表示() }///
function 最初の表示(){
引数の表示();
// セレクト欄のコピー、
var charset = select1/*.options ?*/[ select1/**/.selectedIndex ].value
var Ele = select1/**/.cloneNode(true); Ele.id = "select2"
var 集 = Ele.getElementsByTagName('option') // 変換後用欄には無効なものを削除(idを付けておいた)
for(var i=0; i<集.length; i++) if(集[i].id)Ele.removeChild(集[i])
select2P/**/.appendChild(Ele)
var 集 = Ele.getElementsByTagName('option')// 元の selected がコピーかremoveChildで無効になる為
for(var i=0; i<集.length; i++) if(集[i].value==charset)集[i].selected = true //(上のfor中では無効)
// 「お気に入りの整理」コントロールのフォルダ設定
nsc.setRoot("shell:DesktopFolder")//
左引数面の切換え( (引_filePathA.length||引_foldPathA.length ? 0: 1) )
// 引数にフォルダある場合の設定の表示、// 不用か?
if(設_ファイル名パターン){
filePtn/**/.value = ( 設_ファイル名パターン ? 設_ファイル名パターン.source : '')
合 = (設_ファイル名パターン+'').match(/\/([^\/]+)$/)
filePtnflag/**/.value = (合 && 合[1] ? 合[1]: '')
}///
chkReflv/**/.checked = (設_フォルダ下降 ? true: false)
}///
function 引数の表示(){
var argA, res, 文 ='';
if(window.htaTag && htaTag.commandLine)argA = htaTag.commandLine.match( /".*?"|[^ ]+/g );
if(argA && (argA.shift(), argA.length) && (res= 引数調べて分ける(argA)) ){
引_filePathA = res[0], 引_foldPathA = res[1]; }//
for(var i=0; i<引_foldPathA.length; i++) 文 += '<div><input type="checkbox" id="fo'
+i+'" checked> '+ FS.GetFileName(引_foldPathA[i]) +'\\</div>';
for(var i=0; i<引_filePathA.length; i++)文 += '<div><input type="checkbox" id="fi'
+i+'" checked> <span class="argf" onclick="ファイル欄へ('+i+')">'
+ FS.GetFileName(引_filePathA[i]) +'</span></div>';
if(文)divArgs/**/.innerHTML = 文;
if(引_filePathA.length) txtFilePath/**/.value = 引_filePathA[0]
if( !引_foldPathA.length)setfoldSpan/**/.style.display = 'none'
}///
function ファイル欄へ(番){ txtFilePath/**/.value = 引_filePathA[番] }
function 引数の追加(path){
if(!path)return; var id; // 重複を確かめてない問題あり。
if(FS.FolderExists(path)){ id = 'fo'+ 引_foldPathA.length; 引_foldPathA.push(path) }//
else if(FS.FileExists(path)){ id = 'fi'+ 引_filePathA.length; 引_filePathA.push(path) }//
else{ alert("存在しない"); return }//
var str = '<div><input type="checkbox" id="'+ id +'" checked> '
+ path + (/^fo/.test(id) ? '\\':'') +'</div>';
divArgs/**/.innerHTML += str;
左引数面の切換え(0)
if(引_foldPathA.length && setfoldSpan/**/.style.display=='none') setfoldSpan/**/.style.display = ''
}///
//・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
// 表示に関係のもの
function 操作表示部の切換え(Ele){
if(Ele.className=="switchOn")return
var idA = ["fileCtrl", "lumpCtrl", "editCtrl"]
for(var i=0; i<idA.length; i++)
if( Ele.id.match(idA[i]) ) Ele.className = 'switchOn',
window[ idA[i] ].style.display = '';
else window[ idA[i]+'Swt' ].className = 'switchOff',
window[ idA[i] ].style.display = 'none';
if(/editCtrl/.test(Ele.id)){ editP.style.display = ''
dispRes.style.display = dispPreP.style.display = 'none'; select1.style.color = 'gray' }//
//textArea1.value = dispPre.innerHTML;//.replace(/&/g, '&').replace(/</g,'<')
else{ editP.style.display = 'none'; select1.style.color = ''
if(/lumpCtrl/.test(Ele.id)){
dispRes.style.display = ''; dispPreP.style.display = 'none'; 左引数面の切換え(0); }//
else{ dispPreP.style.display = ''; dispRes.style.display = 'none'; }//
}///
}///
function 左引数面の切換え(番){
divArgs.style.display = 番 ? 'none': '';
divNsc.style.display = 番 ? '': 'none';
argAddBtn.style.display = 番 ? '': 'none';
argNscBtn.style.display = 番 ? '': 'none';
argTab.className = 番 ? '': 'ltab';
viewTab.className = 番 ? 'ltab': '';
}///
function テキスト方向の変更(番, 標){
if(標){ dispPre.style.writingMode = (番==1 ? 'tb-rl': '')
dispPre.style.direction = (番==2 ? 'rtl': '')
dispPre.style.unicodeBidi = (番==2 ? 'bidi-override': ''); }//
else{ textArea1.style.writingMode = (番==1 ? 'tb-rl': '')//'lr-tb' ('rl-tb' はエラー)
textArea1.style.direction = (番==2 ? 'rtl': '')
textArea1.style.unicodeBidi = (番==2 ? 'bidi-override': '');
}// dir や style.direction で、'rtl' を指定しても、右揃えになるだけ(矢印キーが不用に逆になったりも)
// bdo 要素を使うか、{ unicode-bidi: bidi-override } にすると、方向が変わる。('embed' にしてもだめ)
}///
var strNscSelection; // NameSpace(お気に入りの整理)コントロールの選択されているパスを入れる。
</script>
<hta:application id="htaTag"></hta>
<!--・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・-->
<style type="text/css">
body{ margin:0; overflow:hidden; /*line-height:1.8; */
background-color:window; color:windowtext; }
#dispL, #dispR{ position:absolute; top:0; height:100%; }/* 左面、右面 */
#dispL{ width:20%; overflow:auto; border-right-style:outset; }/* 左面、リスト */
#dispR{ left:20%; width:80%; overflow:auto; } /* 右面 */
// 各面、
#divArgs{ padding:0.5em; padding-top:1em; }/* 引数表示部分(左面) */
#divArgs div{ padding-left:1.5em; text-indent:-1.5em; word-break:break-all; }
#ctrl0{ white-space:nowrap; /* 操作用部分(右面上部) */
padding-left:0.5em; padding-top:8px; padding-bottom:4px; }
#dispPre{ /* ファイル内容 表示部分(右面) */
line-height:1.4; font-family:monospace; padding:0.5em; }
/* フォーム部品(入力欄) */
#select1, #select2{ font-weight:bolder; /*font-size:larger;*/ }/* select欄、文字セット指定 */
.lineText{ font-weight:bolder; font-family:monospace; /* 入力欄 */
font-size:small; height:1.6em; line-height:1.6;
padding:0; padding-left:4px; padding-right:4px; }
.lineTextSmall{ font-family:monospace; }/* 入力欄、細字 */
textArea{ line-height:1.2; padding:0.2em; word-break:keep-all;/* 折返して欲しくないのだが方法判らず */
font-family:monospace; font-size:small; width:100%; } /* width:expression(dispR.clientWidth)と
タグで指定してる(縦書きにした時100%が効かなくなる為)が、何故かここで100%と書いて置かないと少し変に? */
/* ボタン類、など */
.label{ font-size:smaller; }
.btn{ font-weight:bolder; white-space:nowrap; /* ボタン */
border-style:outset; border-color:threedlightshadow; cursor:pointer;
padding-left:2px; padding-top:2px; vertical-align:20%; }
.argf{ cursor:pointer; }/* 引数表示部分(左面)中のファイル名 */
.switchOn{ background-color:windowtext; color:window; }
.switchOff{ cursor:pointer; background-color:window; color:windowtext; }
.ltab{ background-color:windowtext; color:window; }
</style>
<!--・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・-->
</head><body>
<div id="dispL">
<div id="" style="text-align:right; margin-top:8px; margin-bottom:0.5em;">
<span id="argAddBtn" onclick="引数の追加(strNscSelection)" class="btn" style="font-size:smaller;"
title=" 選択されているものを、引数へ追加 ">追加</span>
<span id="argNscBtn" onclick="var path =strNscSelection;
if(FS.FileExists(path))path=path.replace(/\\[^\\]+$/,'');
path=prompt('ルートの変更 、 空ならデスクトップへ',(path ? path:''));
if(path) nsc.setRoot(path); else if(path=='')nsc.setRoot('shell:DesktopFolder')"
class="btn" style="font-size:smaller;" title=" ルートの変更 ">R</span>
<span onclick="左引数面の切換え(0)" id="argTab" class="" style=""
title=" 引数一覧 ">引数</span>
<span onclick="左引数面の切換え(1)" id="viewTab" class="" style=""
title=" フォルダ・ファイル ツリー ">ビュー</span>
</div>
<div id="divArgs" style=""></div>
<div id="divNsc" style=""><!-- NameSpace(お気に入りの整理)コントロール -->
<OBJECT id=nsc classid=clsid:55136805-B2DE-11D1-B9F2-00A0C98BC547
style="BACKGROUND: window; WIDTH: 100%; HEIGHT: expression(document.body.clientHeight-nsc.offsetTop);">
<!--<PARAM NAME="Root" VALUE="shell:DesktopFolder"> ここではだめ? -->
</OBJECT>
<SCRIPT for=nsc event="FavoritesSelectionChange(cItems, hItem, strName, strUrl, cVisits, strDate, fAvailableOffline)" defer>
// NameSpaceコントロールの選択項目が変わった時。
strNscSelection = strUrl // (ショートカットなら、その行先になる)
if(fileCtrl.style.display !='none' && FS.FileExists(strNscSelection) )
txtFilePath/**/.value = strNscSelection // ファイルパスを入力する欄へ。
</SCRIPT>
</div>
</div>
<div id="dispR">
<div id="ctrl0" style="">
<div style="margin-bottom:1em">
<span class="label" title=" 文字セット(Charset)の指定 ">元</span
><select id="select1" style='margin-left:0.3em'><!--<option value="">-->
<option value="%自判定%" id="befOnly1">%自判定%
<option value="%バイト%">%バイト%
<option value="_autodetect">_autodetect
<!--<option value="_autodetect_all">_autodetect_all // エラーに? -->
<option value="x-user-defined">x-user-defined<!-- -->
<option value="shift_jis" selected>shift_jis<option value="iso-2022-jp">iso-2022-jp
<option value="euc-jp">euc-jp<option value="unicode">unicode
<option value="utf-8">utf-8<option value="utf-7">utf-7
<option value="Big5">Big5<!-- 繁体 -->
<option value="gb2312">gb2312<!-- "chinese" 簡体 -->
<option value="_autodetect_kr">_autodetect_kr<!-- 韓 -->
<option value="korean">korean<!-- "ks_c_5601-1987" 韓 -->
<option value="iso-8859-1">iso-8859-1<!-- "latin1" 西欧 -->
<option value="iso-8859-2">iso-8859-2<!-- "latin2" 中(東)欧 -->
<option value="iso-8859-3">iso-8859-3<!-- ラテン 3、エスペラント? -->
<option value="iso-8859-4">iso-8859-4<!-- "latin4" バルト(北欧) -->
<option value="iso-8859-5">iso-8859-5<!-- "cyrillic" キリル(露) -->
<option value="iso-8859-6">iso-8859-6<!-- "arabic" アラビア -->
<option value="iso-8859-7">iso-8859-7<!-- "greek" ギリシャ -->
<option value="iso-8859-8">iso-8859-8<!-- "hebrew" ヘブライ -->
<option value="iso-8859-9">iso-8859-9<!-- "latin5" トルコ -->
</select><!-- ↑ 適当に追加などを。[HKEY_CLASSES_ROOT\MIME\Database\Charset] のサブキー参照 -->
<!-- 上のselectをコピーして挿入 -->
<span class="label" title=" 変換後の Charset の指定 ">→変換後</span
><span id="select2P"></span
><select id="select3" title=" 変換後の改行コード ">
<option value=""> -<option value="">CRLF<option value="">LF
</select> <!>
<span onclick="操作表示部の切換え(this)" id="fileCtrlSwt" class="switchOn" style=""
title="">ファイル</span>
<span onclick="操作表示部の切換え(this)" id="lumpCtrlSwt" class="switchOff" style=""
title=" 引数の一括処理 ">一括</span>
<span onclick="操作表示部の切換え(this)" id="editCtrlSwt" class="switchOff" style=""
title="">編集</span>
<span class="btn" style="font-size:xx-small; " title=" スクリプトファイルの編集 "
onclick="location='view-source:'+location.href.replace(/\/[^\/]+$/,'/')+scr1.src">S</span>
</div>
<div id="fileCtrl" style="">
<span class="label">ファイル</span>
<input type="text" id="txtFilePath" class="lineTextSmall" size="60" title="">
<span onclick="指定コードで読込んで表示();" class="btn" style=""
title=" ファイル内容を、ここに表示 ">表示</span>
<span onclick="ファイル一つを変換へ()" class="btn" style=""
title=" 指定のコードで、別ファイルに保存 ">変換</span>
<span class="btn" style="font-size:xx-small; "
onclick="document.getElementById('fileBox').click();" title=" ファイル参照 ">f..</span>
<span style=""> </span><!-- ←これは上の[file..]が位置によって反応しなくなる事、防ぐ為 -->
<input type="file" id="fileBox" style="display:none;"
onchange="txtFilePath.value = this.value ? this.value: ''">
</div>
<div id="lumpCtrl" style="display:none;">
<span id="setfoldSpan">
<span title=" フォルダ中のファイルを 名前で選ぶパターン(正規表現) 例、拡張子 \.txt$ 全て .* ">
<span class="label">ファイル名パターン
</span>/<input type="text" id="filePtn" class="lineText" size="30"
>/<input type="text" id="filePtnflag" class="lineTextSmall" size="3"
title="フラグ、i m g " style="text-align:center; font-weight:bolder;">
</span>
<input type="checkbox" id="chkReflv" title=" フォルダの中のフォルダも降りて、ファイルに実行 "
><span class="label">フォルダ下降</span>
</span>
<span onclick="一括の変換へ()" class="btn" style=""
title=" 引数ファイル群を一括して変換保存 ">変換</span>
</div>
<div id="editCtrl" style="display:none; text-align:right; padding-right:1em;">
<span class="label">表示</span><select id="" style='margin-left:0.3em'
onchange="テキスト方向の変更(this.selectedIndex)">
<option value="">横<option value="">縦<option value="">右
</select>
<span onclick="テキストをファイルに保存()" class="btn" style=""
title=" テキスト欄の内容をファイルに保存 ">保存</span>
</div>
</div>
<div id="dispPreP" style="">
<div style="padding-left:0.5em; border-bottom-style:outset; border-width:1px;">
<span id="infoRes1"></span>
<span class="label">表示</span><select id="" style='margin-left:0.3em'
onchange="テキスト方向の変更(this.selectedIndex, 1)">
<option value="">横<option value="">縦<option value="">右
</select>
<input type="checkbox" onclick="dispPre.style.whiteSpace=(this.checked ? '':'nowrap')"
><span class="label">折返し</span>
</div>
<div id="dispPre" style="white-space:nowrap;"><bdo id="dispStr"></bdo></div>
</div>
<div id="editP" style="display:none;">
<div id="infoRes2" style=""></div>
<div><textarea id="textArea1" style="width:expression(dispR.clientWidth);
height:expression(document.body.clientHeight-textArea1.offsetTop-2);"></textarea></div>
</div> <!-- width:100%; では縦にした時、無効になってしまう。↑ -->
<div id="dispRes" style="display:none; border-top-style:outset; border-width;1px; padding:0.5em"></div>
</div>
<!--・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・-->
<!--
表示の不具合で、窓サイズを動かすと、直る場合あり。
左、フォルダ・ファイルビュー(お気に入りの整理のもの)、横スクロールバー出す方法判らない。
仕方ないので、表示のルートを変える方法で。[R] のボタンを。
unicode でないものを、unicode として読込んで表示するなど、異なる文字セットで、
ややサイズのあるファイルを [表示] すると、ひどく遅くなるかフリーズすることあり。
-->