「Mery.iniのオプション値を取得」の版間の差分

提供:MeryWiki
ナビゲーションに移動 検索に移動
編集の要約なし
279行目: 279行目:
// ③ 戻り値で得た配列の内容をアウトプットバーに出力する
// ③ 戻り値で得た配列の内容をアウトプットバーに出力する


OutputBar.Writeln( "\n> GetIniOption2()" );;
OutputBar.Writeln( "\n> GetIniOption2()" );
var section, key, value;
var section, key, value;
for ( var i = 0; i < iniOption.length; i ++ ) {
for ( var i = 0; i < iniOption.length; i ++ ) {
292行目: 292行目:
}
}
</source>
</source>


== メモ ==
== メモ ==

2019年8月22日 (木) 22:46時点における版

GetIniOption() 関数

Mery.ini ファイル内の各行
 KeyName=value
の「項目名 Key」の文字列を指定して「値 value」を取得するための 組み込み用関数 です。
Mery.ini の任意の項目名(左辺)で検索をかけて、生の値(右辺)をそのまま取得します。


ペーストする位置は呼び出し元のコードから参照できるスコープ内であれば、ソースコードの末尾でも問題ありません。
使い方は 使用例 を参考にしてください。
  • INI 内に同名の「項目名」がある場合は、さいしょにヒットした項目の「値」のみを返します。これは、引数の配列の要素(項目名)と戻り値の配列の要素(値)を 1 対 1 で対照させるための仕様です。
    → 重複する「項目名」のある項目を参照する場合は GetIniOption2 関数 を使用してください(2019/05/21 追加)。
  • 引数の配列で「オプション項目名」の記述を間違えると var value = iniText.match(reg)[0] の行でエラーになります。これにより引数の記述のミスを指摘できるので、エラー回避の処理は入れてありません。
    → 警告ダイアログを表示し、誤った項目名を指摘するように変更しました(2019/05/21)。※ 呼び出し元のコードの処理は継続されます。
  • 「Mery.exe」自体のファイル名をリネームしている場合、 %AppData%\Mery\Mery.ini を参照できないことがあります。
    → Mery の実行ファイルのベース名を取得するように変更しました(2019/05/21)。


  • このマクロは Mery.ini の内容を編集(書き換え)するものではありません。
  • 基本的に Mery.ini は オプション などの設定ダイアログを [OK] ボタンで閉じたときと Mery を終了したときにしか更新されず、標準メニューバー、ツールバーアイコン、右クリックメニュー、ショートカットキー、マクロ等でエディタの設定状態を変更しているばあい、INI の内容が最新の状態とはなりません。
    よって、かならずしもエディタの表示状態(折り返しや色の反転、記号の表示設定など)どおりの値を取得できるわけではありません。
MeryInfo.js にはない項目として「行の表示方法」の取得ぐらいしか使い道がない…
  • Mery.ini の直接編集でオプションパネルから設定変更できない「隠し機能」項目をカスタマイズしている人なら、現在の設定値の確認などにも使えるかも?


ソースコード

// #title="Mery.ini のオプション値を取得"

/**
 * 組み込み関数 GetIniOption( keyArray )
 * 引数で指定した任意の INI オプション項目の「値」を返す
 *
 * ※ 引数は INI オプション項目名を列挙した配列
 *   記述形式は [ "KeyName1", "KeyName2", "KeyName3" ] 
 * → 戻り値 も INI オプション項目の値を並べた 配列。
 *   (各要素は 数値 または 文字列)
 */
// ---------- ▼ 組み込み関数 ココから ▼ ----------

function GetIniOption( keyArray ) {
  // Mery.ini を探す
  var iniPath = editor.FullName.replace( /\.exe$/i, ".ini" );
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  if ( ! Fso.FileExists( iniPath ) ) {
    var iniName = /\\([^\\]+)\.exe$/.exec( editor.FullName )[1];
    var WshShell = new ActiveXObject( "WScript.Shell" );
    iniPath = WshShell.SpecialFolders( "APPDATA" )
            + "\\Mery\\" + iniName + ".ini";
  }
  // Mery.ini を読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText, Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( iniPath );
  var iniText = Adodb.ReadText( adReadAll );	// .replace( /\r\n?/g, "\n" )
  Adodb.Close();

  // includeライブラリの IO.js と MeryInfo.js を #include しているマクロに組み込むなら
  //   var iniPath  から  Adodb.Close()  までは以下の一行だけでよい
  // var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" );

  // 引数の配列をループ処理して ini からオプションの値を取得する
  var value, iniOptionArray = [];
  for ( var i = 0, len = keyArray.length; i < len; i ++ ) {
    reg = new RegExp( "^" + keyArray[i] + "=[^\\r\\n]*$", "gm" );
    try {
      // 項目名の記述ミスがあるとこの行でエラーが発生する
      value = iniText.match( reg )[0]
                     .substr( keyArray[i].length + 1 );
      // 10進数なら Number 型で返す
      if ( /^-?[0-9]+$/.test( value ) ) {
        value = Number( value );
      }
    }
    catch ( e ) {
      Alert( keyArray[i] + " という項目はありません。" );
      value = undefined;
    }
    iniOptionArray.push( value );
  }
  return iniOptionArray;
}

// ---------- ▲ 組み込み関数 ココまで ▲ ----------


使い方

/**
 * 【使い方】
 *
 * GetIniOptions() 関数の使用は1回で済ませないと
 * その都度 INI ファイルの読み込みが発生してマクロの処理速度が落ちるので
 * 取得したい項目すべてをひとつの配列にまとめること
 * 
 * ※ 取得したいオプション項目がひとつだけの場合でも引数は ["配列"] のかたちで記述すること
 *  GetIniOption( [ "KeyName" ] )
 *
 * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
 */
// ① 取得したい INI オプション項目を ["配列"] に列挙する
var iniItem = [ "LineColumnView", "WrapMode", "QuoteCharacter", "TabColumns", "AutoIndent" ];

// または
var iniItem = new Array( "LineColumnView", "WrapMode", "QuoteCharacter", "TabColumns", "AutoIndent" );


// ② GetIniOption() の引数に配列を指定して変数に代入 (※返り値も配列)
var iniValue = GetIniOption( iniItem );


// ③-1.(例1)取得したオプションをダイアログで順々に表示する
for ( var i = 0, type; i < iniItem.length; i ++ ) {
  type = Object.prototype.toString.call( iniValue[i] ).slice( 8, -1 );
  Alert( iniItem[i] + " = " + iniValue[i] + "\nobject type: " + type );
}


// ③-2.(例2)個々の値の参照には、戻り値の配列の [インデックス] で要素を指定する
var settings = {
  lineColumnView: iniValue[0],	// 「行の表示方法」
  wrapMode: iniValue[1],		// 「折り返し方法」
  quoteCharacter: iniValue[2],	// 「引用マーク」
  tabColumns: iniValue[3],		// 「タブの桁数」
  autoIndent: iniValue[4]		// 「自動インデントを有効にする」
};

Alert( "行の表示方法: "
     + ( settings.lineColumnView == 1 ? "表示行" : "論理行" )
);


// ③-3.(注)取得したいオプション項目がひとつの場合も、["配列"] のかたちで記述すること
Alert( GetIniOption( ["LineColumnView"] ) );


GetIniOption2() 関数

Mery.ini ファイル内の各項目
 [SectionName]
 KeyName1=value1
 KeyName2=value2
の「段落名・セクション [Section]」と「項目名・キー Key」の文字列を指定して「値 value」を取得するための 組み込み用関数 です。
ことなるセクションに同じキー名の項目が重複して存在することを考慮してありますので、Mery.ini のすべての項目の参照が可能になります。


使い方は 使用例 を参考にしてください。


  • このマクロは Mery.ini の内容を編集(書き換え)するものではありません。


ソースコード

// #title="Mery.ini のオプション値を取得"

/**
 * 組み込み関数 GetIniOption2( keyArray )
 * 引数で指定した任意の INI オプション項目の配列に
 * 「値」をくわえた配列 で返す
 *
 * ※ 引数: INI オプション項目(セクション名とキー名)を指定する配列
 *   記述形式は [ [section1, key1], [section2, key2] ... ] (※入れ子にする)
 *
 * → 戻り値: INI オプション項目の「値」を追加した配列
 *   配列の形式は [ [section1, key1, value1], [section2, key2, value2] ... ]
 * ※ value はすべて文字列値(String)で返す(数字の場合も "1" として返す  "1" !== 1  )
 */
// ---------- ▼ 組み込み関数 ココから ▼ ----------

function GetIniOption2( keyArray ) {
  // Mery.ini を探す
  var iniPath = editor.FullName.replace( /\.exe$/i, ".ini" );
  var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
  if ( ! Fso.FileExists( iniPath ) ) {
    var iniName = /\\([^\\]+)\.exe$/.exec( editor.FullName )[1];
    var WshShell = new ActiveXObject( "WScript.Shell" );
    iniPath = WshShell.SpecialFolders( "APPDATA" )
            + "\\Mery\\" + iniName + ".ini";
  }
  // Mery.ini を読みこむ
  var Adodb = new ActiveXObject( "ADODB.Stream" );
  var adTypeText = 2,  adReadAll = -1;
  Adodb.Type = adTypeText, Adodb.Charset = "UTF-8";
  Adodb.Open();
  Adodb.LoadFromFile( iniPath );
  var iniText = Adodb.ReadText( adReadAll );	// .replace( /\r\n?/g, "\n" )
  Adodb.Close();

  // includeライブラリの IO.js と MeryInfo.js を #include しているマクロに組み込むなら
  //   var iniPath  から  Adodb.Close()  までは以下の一行だけでよい
  // var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" );

  // 引数の配列をループ処理して ini からオプションの値を取得する
  var section, key, value, iniOptionArray = [];
  var id1, id2, id3, id4;
  var iniLength = iniText.length;
  var Quote = function( str ) { return str.replace( /\W/g, "\\$&" ) };
  for ( var i = 0, len = keyArray.length; i < len; i ++ ) {
    section = keyArray[i][0];
    key     = keyArray[i][1];
    reg1 = new RegExp( "^\\[" + Quote( section ) + "\\]$", "m" );
    id1 = iniText.search( reg1 );				// セクションの開始位置
    if ( id1 != -1 ) {							// セクション名が正しいか?
      id2 = iniText.indexOf( "[", id1 + 1 );	// 次のセクションの開始位置
      id2 = ( id2 > id1 ) ? id2 : iniLength;
      id3 = iniText.indexOf( "\n" + key, id1 );	// キーの開始位置
      if ( id3 != -1 && id2 > id3 ) {			// セクション内にキーがあるか?
        id4 = iniText.indexOf( "\r\n", id3 );	// 検索項目の行末位置
        value = iniText.slice( id3 + key.length + 2, id4 );
        iniOptionArray.push( [ section, key, value ] );
      }
      else {	// キーの指定ミスがあった場合
        Alert( "\"" + key + "\" key is NOT found in [" + section + "] section." );
        iniOptionArray.push( [ section, undefined, null ] );
      }
    }
    else {	// セクションの指定ミスがあった場合
      Alert( "[" + section + "] section is NOT found in \"Mery.ini\" file." );
      iniOptionArray.push( [ undefined, key, null ] );
    }
    id1 = 0;
  }
  return iniOptionArray;
}

// ---------- ▲ 組み込み関数 ココまで ▲ ----------


使い方

/**
 * 【使い方】
 *
 * GetIniOptions2() 関数の使用は1回で済ませないと
 * その都度 INI ファイルの読み込みが発生してマクロの処理速度が落ちるので
 * 取得したい項目すべてをひとつの配列にまとめること
 * 
 * ※ 取得したいオプション項目がひとつだけの場合でも引数の配列は入れ子にすること
 *  GetIniOption2( [ [ "SectionName", "KeyName" ] ] )
 *
 * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
 *  記述ミスをした項目は  undefined  に置き換え、要求された値は  null  で返す
 * ※ オプションの値が空  KeyName=  の場合は空文字列  ""  を返す
 *
 * ※ 値はすべて "文字列" 型で返されるので、必要に応じて  Number( value )  などのかたちで利用する
 */
// ① セクション名とキー名をセットにした配列 [ [section1, key1], [section2, key2] ... ]
//    セクション名に「\」がある場合は、ふたつ重ね「\\」で記述すること

var keyArray = new Array(
  [ "General", "LineColumnView" ],
  [ "General", "FileFilter" ], 
  [ "General", "Untitled" ], 
  [ "Display", "FallbackFonts" ], 
  [ "View", "FontName0" ], 
  [ "Macros\\Macro1", "FileName" ],
  [ "Themes\\Theme29", "Caption" ]
);


// ② 関数の引数に配列をあたえて、変数 iniOption に代入する
//    関数の戻り値も配列 [ [section1, key1, value1], [section2, key2, value2] ... ]
// ※ value は文字列値(String)で返される(数字の場合も "1"、※ "1" !== 1 )

var iniOption = GetIniOption2( keyArray );


// ③ 戻り値で得た配列の内容をアウトプットバーに出力する

OutputBar.Writeln( "\n> GetIniOption2()" );
var section, key, value;
for ( var i = 0; i < iniOption.length; i ++ ) {
  section = iniOption[i][0];	// セクション名に記述ミスがあると undefined
  key     = iniOption[i][1];	// キー名に記述ミスがあると undefined

  // 上の二つのいずれかにミスがあると値は null、値が空のときは ""
  value   = iniOption[i][2];

  OutputBar.Writeln( "\n[" + section + "]\n"
                   + key + "  =  " + value );
}

メモ

  • 2019/03/10 sukemaru
将来的に、INI を最新の状態に強制更新したり INI の設定項目を取得できる専用メソッドが実装されるかもしれませんし、現状でも includeライブラリMeryInfo.js)でもある程度 INI へのアクセスはできますが…。
あるいは、includeライブラリ(IO.js)の使用のみでエディタの表示状態を変更するマクロの例として「折り返しトグル切り替え」などもあります。
INI アクセスのための専用メソッド についてはフォーラム内の「マクロコマンドから「表示」の「色の反転」を取得したい」のトピック内で検討・議論されていますので、ご参考まで(セキュリティ上の懸念により実装は見送りとなっています)。
  • 2019/04/28 sukemaru
「文字列値」が2 バイト文字を含むときに正常に読みこめなかったので、"ADODB.Stream" / UTF-8 での読みこみに変更した。
  • 2019/04/29 sukemaru
値が「-」1文字のときに NaN になっていたのを文字列 "-" で返すように修正(値が空のときは長さ 0 の文字列 "" のまま)。
  • 2019/05/21 sukemaru
セクション指定可能な GetIniOption2() 関数を追加し、Mery.ini の完全な参照ができるようにした。
一応、従来の GetIniOption() 関数も残しておく。
  • 2019/06/02 sukemaru
GetIniOption2() 関数の変数 id2 のコードミスで引数のキー名にエラーがあった場合の処理が正しく行われなかったのを修正。


スポンサーリンク