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

提供: MeryWiki
ナビゲーションに移動 検索に移動
Sukemaru (トーク | 投稿記録)
編集の要約なし
Sukemaru (トーク | 投稿記録)
GetIniOption3() 関数を追加
1行目: 1行目:
<div style="float:right">__toc__</div>
<div style="float:right">__toc__</div>
設定ファイル Mery.ini にアクセスして任意の項目の設定値を参照するための '''組み込み用コード''' です。<br>
テキストエディタ Mery の設定ファイル '''Mery.ini''' を参照して任意の項目の設定値を取得するための '''マクロ用組み込みコード''' です。<br><br>
複数の項目を配列にして関数に渡す仕様につき Mery.ini へのアクセス('''読みこみ''')を1回で済ませられるため、多様性に富んだ参照を高速に処理できます。
複数の項目を配列にして関数に渡す仕様につき Mery.ini へのアクセス('''読みこみ''')が1回で済むため、多様性に富んだ参照を高速に処理できます。
<br><br>
<br><br>
※ <b style="color:#c00;">Mery.ini の内容を編集(書き換え)するものではありません。</b>
※ <b style="color:#c00;">このページのマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。</b>
<br>
※ 標準ツールバーのメニューや右クリックメニューのコマンド、ツールバーアイコン、ショートカットキー、他のマクロなどから変更された設定内容(おもにエディタの表示設定)は直ちに Mery.ini に反映されるわけではないので、この組み込み用コードにより取得されたオプション値がエディタの状態どおりではない場合があります。
<br clear=all>
<br clear=all>


== GetIniOption() 関数 ==
== GetIniOption() 関数 ==


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




* [[#関数1|組み込み関数本体]] を任意のマクロのソースコード内にペーストして使用します。
* [[#関数1|組み込み関数本体]] を任意のマクロのソースコード内にペーストして使用します。
: ペーストする位置は呼び出し元のコードから参照できるスコープ内であれば、ソースコードの末尾でも問題ありません。
: ペーストする位置は呼び出し元のコードから参照できるスコープ内であれば、ソースコードの末尾でも問題ありません。
: 使い方は [[#使い方_1|使用例]] を参考にしてください。
: 使い方は [[#使い方|使用例]] を参考にしてください。


* INI 内に同名の「項目名」がある場合は、さいしょにヒットした項目の「値」のみを返します。これは、引数の配列の要素(項目名)と戻り値の配列の要素(値)を 1 対 1 で対照させるための仕様です。<br> → 重複する「項目名」のある項目を参照する場合は [[#GetIniOption2() 関数|GetIniOption2 関数]] を使用してください(2019/05/21 追加)。
* INI 内に '''同名の「項目名」''' がある場合は、さいしょにヒットした項目の「値」のみを返します。これは、引数の配列の要素(項目名)と戻り値の配列の要素(値)を 1 対 1 で対照させるための仕様です。<br> → 重複する「項目名」のある項目を参照する場合は [[#GetIniOption2() 関数|GetIniOption2() 関数]] か [[#GetIniOption3() 関数|GetIniOption3() 関数]] を使用してください(2019/05/21, 2020/05/14 追加)。


* 引数の配列で「オプション項目名」の記述を間違えると、 警告ダイアログを表示し、誤った項目名を指摘します。<br> ※ 呼び出し元のコードの処理は継続されます。
* 引数の配列で「オプション項目名 <code>KeyName</code>」の記述を間違えると、 警告ダイアログを表示し、誤った項目名を指摘します。<br> ※ 呼び出し元のコードの処理は継続されます。


* 「Mery.exe」自体のファイル名をリネームしている場合も、Mery の実行ファイルのベース名を取得して、適切な INI ファイルを読みこみます。
* 「Mery.exe」自体のファイル名をリネームしている場合も、Mery の実行ファイルのベース名を取得して、適切な INI ファイルを読みこみます。
26行目: 30行目:
* <b style="color:#c00;">このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。 </b>
* <b style="color:#c00;">このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。 </b>
<br>
<br>
* 基本的に Mery.ini は [[ヘルプ:ツール#オプション|オプション]] などの設定ダイアログを [OK] ボタンで閉じたときと Mery を終了したときにしか更新されず、標準メニューバー、ツールバーアイコン、右クリックメニュー、ショートカットキー、マクロ等でエディタの設定状態を変更しているばあい、INI の内容が最新の状態とはなりません。 <br> よって、かならずしもエディタの表示状態(折り返しや色の反転、記号の表示設定など)どおりの値を取得できるわけではありません。
* 基本的に Mery.ini は [[ヘルプ:ツール#オプション|オプション]] などの設定ダイアログを閉じたときと Mery を終了したときにしか更新されず、標準メニューバー、ツールバーアイコン、右クリックメニュー、ショートカットキー、マクロ等でエディタの設定状態を変更しているばあい、INI の内容が最新の状態とはなりません。 <br> よって、かならずしもエディタの表示状態(折り返しや色の反転、記号の表示設定など)どおりの値を取得できるわけではありません。<br> ・・・ MeryInfo.js にはない項目として「行の表示方法」の取得ぐらいしか使い道がない?
<br>
: ・・・ MeryInfo.js にはない項目として「行の表示方法」の取得ぐらいしか使い道がない?
:* Mery.ini の直接編集でオプションパネルから設定変更できない「'''隠し機能'''」項目をカスタマイズしている人なら、現在の設定値の確認などにも使えるかも?
:* Mery.ini の直接編集でオプションパネルから設定変更できない「'''隠し機能'''」項目をカスタマイズしている人なら、現在の設定値の確認などにも使えるかも?
:* [[#メモ|メモ]] に挙げた導入事例のマクロのように、関数コードを改造することで Mery.ini のマクロへの活用法の幅がひろがります。
:* [[#メモ|メモ]] に挙げた導入事例のマクロのように、関数コードを改造することで Mery.ini のマクロへの活用法の幅がひろがりますが…。




38行目: 40行目:
  /**
  /**
   * 組み込み関数 '''GetIniOption( keyArray )'''
   * 組み込み関数 '''GetIniOption( keyArray )'''
  * 引数で指定した'''任意の''' INI オプション項目の「値」を返す
   *
   *
   * 引数で指定した'''任意の''' INI オプション項目の「値」を返す
   * '''引数:''' INI オプション項目名を列挙した配列
  * ※ 引数は INI オプション項目名を列挙した配列
   *  記述形式は ''[ "KeyName1", "KeyName2", "KeyName3" ] ''
   *  記述形式は ''[ "KeyName1", "KeyName2", "KeyName3" ] ''
   * → '''戻り値''' INI オプション項目の値を並べた '''配列'''。
   *  
   *  (各要素は 数値 または 文字列)
  * ''戻り値':'' INI オプション項目の「値」を並べた '''配列'''。
   *  各要素は 数値(Number) または 文字列(String)
   */
   */
<div id="関数1"> </div>
<div id="関数1"> </div>
65行目: 68行目:
   Adodb.Open();
   Adodb.Open();
   Adodb.LoadFromFile( iniPath );
   Adodb.LoadFromFile( iniPath );
   var iniText = Adodb.ReadText( adReadAll ); // .replace( /\r\n?/g, "\n" )
   var iniText = Adodb.ReadText( adReadAll );
   Adodb.Close();
   Adodb.Close();


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


84行目: 87行目:
         value = Number( value );
         value = Number( value );
       }
       }
     }
     } catch( e ) {
    catch( e ) {
       Alert( keyArray[i] + " という項目はありません。" );
       Alert( keyArray[i] + " という項目はありません。" );
       value = undefined;
       value = undefined;
103行目: 105行目:
   * 【使い方】
   * 【使い方】
   *
   *
   * GetIniOptions() 関数の使用は1回で済ませないと
   * GetIniOptions() 関数の使用を1回で済ませないと
   * その都度 INI ファイルの読み込みが発生してマクロの処理速度が落ちるので
   * その都度 '''INI ファイルの読み込み''' が発生してマクロの処理速度が落ちるので
   * 取得したい項目すべてをひとつの配列にまとめること
   * 取得したい項目すべてをひとつの配列にまとめること
   *  
   *  
   * ※ 取得したいオプション項目がひとつだけの場合でも引数は ["配列"] のかたちで記述すること
   * ※ 取得したいオプション項目がひとつだけの場合でも引数は
   *  ''GetIniOption( [ "KeyName" ] )''
  *    配列 ''["KeyName"]'' のかたちで記述すること
  *
   *  ''<code>GetIniOption( [ "KeyName" ] )</code>''
   *
   *
   * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
   * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して
   *  → 誤ったキーの戻り値は undefined
  *    組み込み関数および呼び出し元のコードを続行する
   *  → 誤ったキーの戻り値は ''undefined''
   */
   */
<source lang="javascript">
<source lang="javascript">
// ➀ 取得したい INI オプション項目を ["配列"] に列挙する
// ➀ 取得したい INI オプション項目を配列 ["KeyName1", "KeyName2" ...] に列挙する
 
var iniItem = [ "LineColumnView", "WrapMode", "QuoteCharacter", "TabColumns", "AutoIndent" ];
var iniItem = [ "LineColumnView", "WrapMode", "QuoteCharacter", "TabColumns", "AutoIndent" ];


121行目: 127行目:




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




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


// ➂-2.(例2)個々の「値」の参照には、戻り値の配列の [index] で要素を指定する


// ➂-2.(例2)個々の値の参照には、戻り値の配列の [インデックス] で要素を指定する
var settings = {
var settings = {
   lineColumnView: iniValue[0], // 「行の表示方法」
   lineColumnView: iniValue[0], // 「行の表示方法」
146行目: 155行目:




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


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




177行目: 188行目:
   * '''「値」をくわえた配列''' で返す
   * '''「値」をくわえた配列''' で返す
   *
   *
   * ※ '''引数''': INI オプション項目(セクション名とキー名)を指定する配列
   * ※ '''引数:''' INI オプション項目(セクション名とキー名)を指定する配列
   *  記述形式は ''[ [section1, key1], [section2, key2] ... ] ''(※入れ子にする)
   *  記述形式は ''[ [section1, key1], [section2, key2] ... ] ''(※入れ子にする)
   *
   *
   * → '''戻り値''': INI オプション項目の「値」を追加した配列
   * → '''戻り値:''' INI オプション項目の「値」を追加した配列
   *  配列の形式は ''[ [section1, key1, value1], [section2, key2, value2] ... ]''
   *  配列の形式は ''[ [section1, key1, value1], [section2, key2, value2] ... ]''
   * ※ value はすべて'''文字列値'''(String)で返す
   * ※ value はすべて '''文字列型''' (String)で返す
   *  (数字の場合も "1" として返す <span style="color:#c00;"> "1" !== 1 </span> )
   *  (数字の場合も '''"1"''' として返す <span style="color:#c00;"> "1" !== 1 </span> )
   */
   */
<div id="関数2"></div>
<div id="関数2"></div>
205行目: 216行目:
   Adodb.Open();
   Adodb.Open();
   Adodb.LoadFromFile( iniPath );
   Adodb.LoadFromFile( iniPath );
   var iniText = Adodb.ReadText( adReadAll ); // .replace( /\r\n?/g, "\n" )
   var iniText = Adodb.ReadText( adReadAll );
   Adodb.Close();
   Adodb.Close();


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


225行目: 236行目:
       id2 = iniText.indexOf( "\r\n[", id1 + 1 );// 次のセクションの開始位置
       id2 = iniText.indexOf( "\r\n[", id1 + 1 );// 次のセクションの開始位置
       id2 = ( id2 > id1 ) ? id2 : iniLength;
       id2 = ( id2 > id1 ) ? id2 : iniLength;
       id3 = iniText.indexOf( "\n" + key, id1 ); // キーの開始位置
       id3 = iniText.indexOf( "\n" + key + "=", id1 ); // キーの開始位置
       if ( id3 != -1 && id2 > id3 ) { // セクション内にキーがあるか?
       if ( id3 != -1 && id2 > id3 ) { // セクション内にキーがあるか?
         id4 = iniText.indexOf( "\r\n", id3 ); // 検索項目の行末位置
         id4 = iniText.indexOf( "\r\n", id3 ); // 検索項目の行末位置
         value = iniText.slice( id3 + key.length + 2, id4 ); // ("\n"+"=").length=2
         value = iniText.slice( id3 + key.length + 2, id4 );
         iniOptionArray.push( [ section, key, value ] );
         iniOptionArray.push( [ section, key, value ] );
       }
       }
254行目: 265行目:
   * 【使い方】
   * 【使い方】
   *
   *
   * GetIniOptions2() 関数の使用は1回で済ませないと
   * GetIniOptions2() 関数の使用を1回で済ませないと
   * その都度 INI ファイルの読み込みが発生してマクロの処理速度が落ちるので
   * その都度 '''INI ファイルの読み込み''' が発生してマクロの処理速度が落ちるので
   * 取得したい項目すべてをひとつの配列にまとめること
   * 取得したい項目すべてをひとつの配列にまとめること
   *  
   *  
   * ※ 取得したいオプション項目がひとつだけの場合でも引数の配列は入れ子にすること
   * ※ 取得したいオプション項目がひとつだけの場合でも引数の配列は '''入れ子''' にすること
   *  ''GetIniOption2( [ [ "SectionName", "KeyName" ] ] )''
  *
   *  ''<code>GetIniOption2( [ [ "SectionName", "KeyName" ] ] )</code>''
   *
   *
   * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
   * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
   *   記述ミスをした項目は  ''undefined''  に置き換え、要求された値は  ''null''  で返す
   *   記述ミスをした項目は  ''undefined''  に置き換え、要求された値は  ''null''  で返す
   * ※ オプションの値が空  ''KeyName=''  の場合は空文字列  '''''""'''''  を返す
   * ※ オプションの値が空  ''KeyName=''  の場合は空文字列  '''''""'''''  を返す
   *
   *
   * ※ 値はすべて '''"文字列"''' 型で返されるので、
   * ※ 値はすべて '''"文字列"''' (String)型で返されるので、
   *   必要に応じて  ''Number( value )''  などのかたちで利用する
   *   必要に応じて  ''Number( value )''  などのかたちで利用すること
   */
   */
<source lang="javascript">
<source lang="javascript">
// ➀ セクション名とキー名をセットにした配列 [ [section1, key1], [section2, key2] ... ]
// ➀ セクション名とキー名をセットにした配列を用意する
// [ [section1, key1], [section2, key2] ... ]
// セクション名にバックスラッシュ・¥ 記号「\」がある場合は、ふたつ重ね「\\」で記述すること
// セクション名にバックスラッシュ・¥ 記号「\」がある場合は、ふたつ重ね「\\」で記述すること


281行目: 294行目:
   [ "Themes\\Theme29", "Caption" ], // テーマ名 or ""
   [ "Themes\\Theme29", "Caption" ], // テーマ名 or ""
   [ "Display", "FallbackFonts" ], // フォント名 or ""
   [ "Display", "FallbackFonts" ], // フォント名 or ""
  // ※ ~ver 2.7.4 では FallbackFonts キーがないので [Display] undefined = null
// ※ ~ ver 2.7.4 では FallbackFonts キーがないので [Display] undefined = null


   // ※ 無効な セクション名 や キー名 を指定した場合
   // ※ 無効な セクション名 や キー名 を指定した場合
290行目: 303行目:


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


var iniOption = GetIniOption2( keyArray );
var iniOption = GetIniOption2( keyArray );




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


OutputBar.Writeln( "\n> GetIniOption2()" );
OutputBar.Writeln( "\nRun > " + ScriptName + " : function 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 ++ ) {
312行目: 326行目:
}
}
</source>
</source>
== GetIniOption3() 関数 ==
[[#GetIniOption2() 関数|GetIniOption2() 関数]] とおなじく、Mery.ini ファイル内の各項目 <br>
'''[SectionName]'''
'''KeyName1'''='''value1'''
'''KeyName2'''='''value2'''
の「段落名・セクション <code>[SectionName]</code>」と「項目名・キー <code>KeyName</code>」の文字列を指定して「値 <code>value</code>」を取得するための '''組み込み用関数''' です。<br> ことなるセクションに同じキー名の項目が重複して存在することを考慮してありますので、<u>Mery.ini のすべての項目の参照が可能になります</u>。
* GetIniOption2() 関数では戻り値も '''入れ子状の配列''' だったため、任意のキーの「値」を参照するには <source lang="javascript">
var iniOption = GetIniOption2([[section1, key1], [section2, key2]]);
var value1 = iniOption[0][2];
var value2 = iniOption[1][2];
</source> のように記述しなければならず、可読性にやや難ありでしたが、GetIniOption3() 関数では戻り値を ''' 連想配列(オブジェクト型)''' <code>{section1 : {key1 : value1}, section2 : {key2 : value2} ... }</code> ''<code>objOptions[section][key] = value</code>'' にしてあります。<br>
: INI から取得する「値」が複数のとき、任意の「値」の参照がしやすくなるかとおもいます。<source lang="javascript">
var keyArray = [["General", "LineColumnView"], ["View", "FontName0"]];
var iniOption = GetIniOption3(keyArray);
var value1 = iniOption.General.LineColumnView; // ドット記法
var value2 = iniOption["View"]["FontName0"]; // ブラケット記法
</source>
* 戻り値の「値」の部分 <code>value</code> は文字列型(String)です。<br> ※ GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったときに記述ミスした項目名を <span style="color:#c00;"><code>undefined</code></span> にして「値」を <span style="color:#c00;"><code>null</code></span> で返しましたが、<span style="color:#c00;">GetIniOption3() 関数では間違えたままの項目名の「プロパティ」に <code>undefined</code> を「値」としてあたえて返します。</span><br> ''e.g.'' <code>obj.General.HOGE = undefined</code>
* GetIniOption() 関数と GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったとき、つねに警告ダイアログを表示させる仕様にしてありましたが、GetIniOption3() 関数では第2引数(Bool)に <code>true</code> をあたえなかった場合は警告なしで処理を続行します。
* [[#関数3|組み込み関数本体]] を任意のマクロのソースコード内にペーストして使用します。
: 使い方は [[#使い方_3|使用例]] を参考にしてください。
* <b style="color:#c00;">このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。 </b>
=== ソースコード ===
// #title="Mery.ini のオプション値を取得"
/**
  * 組み込み関数 '''GetIniOption3( keyArray, boolAlertEnable )'''
  *
  * 引数で指定した INI オプション項目名と「値」をプロパティ値として持つ
  * 入れ子型のオブジェクトを返す
  *
  * '''引数:''' INI オプション項目(セクション名とキー名)を指定する入れ子型の配列
  * ※ 配列の記述形式は ''[ [ section1, key2 ], [ section2, key2 ] ... ]''
  *
  * '''戻り値:''' INI オプション項目の「値」を String 型のプロパティ値として持つオブジェクト
  *    ''{ section1 : { key1 : value1 }, section2 : { key2 : value2 } ... }''
  *    ''objOptions[ section ][ key ] = value''
  *
  * ※ 有効な value はすべて '''文字列型''' (String)で返す
  *  (数字の場合も '''"1"''' として返す <span style="color:#c00;"> "1" !== 1 </span> )
  * ※ 無効な section, key が指定されたものにたいしては ''value = undefined'' で返す
  *
  * ※ 各「値」への参照方法は
  *  ''var iniOptions = GetIniOption3( keyArray );''
  *  ''var value1 = iniOptions[ "section1" ][ "key1" ];'' // ブラケット記法
  *  ''var value2 = iniOptions.section2.key2;'' // ドット記法
  */
<div id="関数3"></div>
<source lang="javascript">
// ---------- ▼ 組み込み関数 ココから ▼ ----------
function GetIniOption3( keyArray, alertEnable ) {
  // 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 );
  Adodb.Close();
  // 引数の配列をループ処理して ini からオプションの値を取得する
  var section, key, value, options = {};
  var reg, 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];
    options[ section ] = options[ section ] || {};
    reg = new RegExp( "^\\[" + Quote( section ) + "\\]$", "m" );
    id1 = iniText.search( reg ); // セクションの開始位置
    if ( id1 != -1 ) { // セクション名が正しいか?
      id2 = iniText.indexOf( "\r\n[", 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 );
        options[ section ][ key ] = value;
      }
      // キーの指定ミス
      else {
        options[ section ][ key ] = undefined;
        if ( alertEnable ) {
          Alert( "\"" + key + "\" key is NOT found in [" + section + "] section.\n\n"
              + "The function will return ... \n"
              + "{ \"" + section + "\" : { \"" + key + "\" : undefined } }" );
        }
      }
    }
    // セクションの指定ミス
    else {
      options[ section ][ key ] = undefined;
      if ( alertEnable ) {
        Alert( "[" + section + "] section is NOT found in \"Mery.ini\" file.\n\n"
            + "The function will return ... \n"
            + "{ \"" + section + "\" : { \"" + key + "\" : undefined } }" );
      }
    }
    id1 = 0;
  }
  return options;
}
// ---------- ▲ 組み込み関数 ココまで ▲ ----------
</source>
=== 使い方 ===
/**
  * 【使い方】
  *
  * GetIniOption3() 関数の使用は1回で済ませないと
  * その都度 '''INI ファイルの読み込み''' が発生してマクロの処理速度が落ちるので
  * 取得したい項目すべてをひとつの配列にまとめること
  *
  * ※ 要求する項目が1セットの場合も配列を '''入れ子''' にすること
  *  ''GetIniOption3( [ [ "SectionName", "KeyName" ] ] );''
  *
  * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
  *    記述ミスをした項目の値 ''value ''は ''undefined'' で返される
  * ※ INI 内でオプションの値が空  ''KeyName=''  の場合は空文字列  '''""'''  を返す
  *
  * ※ 値はすべて '''"文字列"''' (String)型で返されるので、
  *    必要に応じて  ''Number( value )''  などのかたちで利用すること
  */
<source lang="javascript">
// ➀ セクション名とキー名をセットにした配列 [ [section1, key2], [section2, key2] ... ]
//    セクション名に「\」がある場合は、ふたつ重ね「\\」で記述すること
var keyArray = new Array(
  [ "General", "LineColumnView" ], // 0 or 1
  [ "General", "FileFilter" ], // "*.txt;*ini;*.htm; …"
  [ "General", "Untitled" ], // 「無題」の代替値 or ""
  [ "Display", "FallbackFonts" ], // フォント名 or "" (~ver2.7.4 では undefined)
  [ "View", "FontName0" ], // フォント名(履歴) or ""
  [ "Macros\\Macro1", "FileName" ], // Macros\マクロ名.js or ""
  [ "Outline\\JavaScript", "Match1" ], // 文字列値 or 正規表現 or "..."
  [ "Themes\\Theme29", "Caption" ], // テーマ名 or ""
  [ "Themes", "HOGE" ], // [Themes] HOGE  =  null
  [ "FUGA", "PIYO" ] // [FUGA] PIYO = null
);
// ➁ 関数の引数に配列をあたえて、変数 iniOption に代入する
//    関数の戻り値は入れ子状のオブジェクト
//    { section1 : { key1 : value1 }, section2 : { key2 : value2 } ... }
// ※ value は文字列値(String)で返される(数字の場合も "1"  ※ "1" !== 1 )
var iniOptions = GetIniOption3( keyArray, true ); // 戻り値は Object 型
// ➂-1.(例1)戻り値で取得した内容をアウトプットバーに出力する
OutputBar.Writeln( "\nRun > " + ScriptName + " : function GetIniOption3()" );
var section, key;
for ( var i = 0; i < keyArray.length; i ++ ) {
  section = keyArray[i][0],  key = keyArray[i][1];
  OutputBar.Writeln( "[" + section + "]\t" + key
                  + "=" + iniOptions[ section ][ key ] );
}
// ➂-2.(例2)特定の key の値を参照して変数に格納する場合
var ff = iniOptions.General.FileFilter; // ドット記法
var fn = iniOptions[ "View" ][ "FontName0" ]; // ブラケット記法
Alert( "[General]\nFileFilter=" + ff + "\n"
    + "[View]\nFontName0=" + fn );
</source>


== 更新履歴 ==
== 更新履歴 ==


* 2019/03/10 (sukemaru)
* 2019/03/10 (sukemaru)
: '''GetIniOption 関数''' の初版
: [[#GetIniOption() 関数|GetIniOption() 関数]] の初版
* 2019/04/28 (sukemaru)
* 2019/04/28 (sukemaru)
: 「文字列値」が2バイト文字を含むときに正常に読みこめなかったので、'''"ADODB.Stream" / UTF-8''' での読みこみに変更した。
: 「文字列値」が2バイト文字を含むときに正常に読みこめなかったので、'''"ADODB.Stream" / UTF-8''' での読みこみに変更した。
322行目: 532行目:
: 値がハイフン-マイナス「'''-'''」1文字のときに戻り値が '''NaN''' になっていたのを文字列 '''"-"''' で返すように修正(値が空のときは長さ 0 の文字列 '''""''' のまま)。
: 値がハイフン-マイナス「'''-'''」1文字のときに戻り値が '''NaN''' になっていたのを文字列 '''"-"''' で返すように修正(値が空のときは長さ 0 の文字列 '''""''' のまま)。
* 2019/05/21 (sukemaru)
* 2019/05/21 (sukemaru)
: セクション指定可能な '''GetIniOption2() 関数''' を追加し、Mery.ini の完全な参照ができるようにした。
: セクション指定可能な [[#GetIniOption2() 関数|GetIniOption2() 関数]] を追加し、Mery.ini の完全な参照ができるようにした。
: 一応、従来の GetIniOption() 関数も簡易版として残しておく(誤った参照キー名に対するエラー処理を変更)。
: 従来の GetIniOption() 関数も簡易版として残し、誤った参照キー名に対するエラー処理を変更しておいた。
* 2019/06/02 (sukemaru)
* 2019/06/02 (sukemaru)
: GetIniOption2() 関数の変数 '''''id2''''' 周りのコードで、引数のキー名にエラーがあった場合の処理が正しく行われなかった不具合を修正。
: GetIniOption2() 関数の変数 '''''id2''''' 周りのコードで、引数のキー名にエラーがあった場合の処理が正しく行われなかった不具合を修正。
331行目: 541行目:
: 関数コードの軽微な修正。
: 関数コードの軽微な修正。
: 説明などの文面を変更。
: 説明などの文面を変更。
* 2020/05/14 (sukemaru)
: セクション指定可能で、戻り値をオブジェクト型にした [[#GetIniOption3() 関数|GetIniOption3() 関数]] を追加。
<br>
<br>


342行目: 554行目:
<br>
<br>
* '''導入事例'''
* '''導入事例'''
:*「[[ポップアップメニューで検索先にジャンプ#sukemaru 版|検索ジャンプ]]」「[[ブックマーク一覧ジャンプ#sukemaru 版|ブックマークジャンプ]]」マクロでは「行の表示方法」(論理座標/表示座標) の取得に GetIniOption 関数を利用しています。
:*「[[ポップアップメニューで検索先にジャンプ#sukemaru 版|検索ジャンプ]]」「[[ブックマーク一覧ジャンプ#sukemaru 版|ブックマークジャンプ]]」マクロでは「行の表示方法」(論理座標/表示座標) の取得に GetIniOption() 関数を利用しています。
:*「[[ファイルを読み直す・開きなおす|読みなおし]]」マクロでは「自動保存」「バックアップ」関連の設定内容とすべての「編集モード名」を取得しています (※「読みなおし」マクロでは、GetIniOption 関数を大幅に魔改造して使用しています)。
:*「[[ファイルを読み直す・開きなおす|読みなおし]]」マクロでは、GetIniOption() 関数を大幅に魔改造して「自動保存」「バックアップ」関連の設定内容とすべての「編集モード名」を取得しています。
:*「[[コンパクトメニュー]]」マクロでは GetIniOption 関数をさらに魔改造して、「最近のファイルの表示数」 「無題タブ用のラベル」 などの値や、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 の一覧などを取得しています。
:*「[[コンパクトメニュー]]」マクロでは GetIniOption() 関数をさらに魔改造して、「最近のファイルの表示数」 「無題タブ用のラベル」 などの値や、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 の一覧などを取得しています。
<br>
<br>
* 読みこみたい値が「数値」や「Ascii だけの文字列」であれば、記述が煩雑になる ADODB.Stream や拙作の関数を使わずに、FileSystemObject の OpenTextFile と ReadAll メソッドでも問題ありません(値が2バイト文字の場合、文字化けするので FileSystemObject は不適)。
* 参照したい値が「数値」や「Ascii文字だけの文字列」であれば、記述が煩雑になる ADODB.Stream や拙作の関数を使わずに、FileSystemObject の <code>OpenTextFile()</code> <code>ReadAll()</code> メソッドでも問題ありません(値が2バイト文字の場合、文字化けするので FileSystemObject は不適)。
: なお、Mery.ini の改行コードは CR+LF なので、検索で改行位置を利用する場合は "\r\n" を用います。
: なお、Mery.ini の改行コードは CR+LF なので、検索で改行位置を利用する場合は "\r\n" を用います。
<br>
<br>
* 基本的に、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 のショートカットキーは取得できません (キー名が32桁の16進数になっていて「マクロ名」などで検索できないため)。
* 基本的に、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 のショートカットキーは取得できません (キー名が32桁の16進数になっていて「マクロ名」などで検索できないため)。

2020年5月14日 (木) 22:39時点における版

テキストエディタ Mery の設定ファイル Mery.ini を参照して任意の項目の設定値を取得するための マクロ用組み込みコード です。

複数の項目を配列にして関数に渡す仕様につき Mery.ini へのアクセス(読みこみ)が1回で済むため、多様性に富んだ参照を高速に処理できます。

このページのマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。
※ 標準ツールバーのメニューや右クリックメニューのコマンド、ツールバーアイコン、ショートカットキー、他のマクロなどから変更された設定内容(おもにエディタの表示設定)は直ちに Mery.ini に反映されるわけではないので、この組み込み用コードにより取得されたオプション値がエディタの状態どおりではない場合があります。


GetIniOption() 関数

Mery.ini ファイル内の各行

KeyName=value

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


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


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


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


ソースコード

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

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

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 );
  Adodb.Close();

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

  // 引数の配列をループ処理して ini からオプションの値を取得する
  var reg, 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 ( /^-?[1-9][0-9]*$/.test( value ) ) {
        value = Number( value );
      }
    } catch( e ) {
      Alert( keyArray[i] + " という項目はありません。" );
      value = undefined;
    }
    iniOptionArray.push( value );
  }
  return iniOptionArray;
}

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


使い方

/**
 * 【使い方】
 *
 * GetIniOptions() 関数の使用を1回で済ませないと
 * その都度 INI ファイルの読み込み が発生してマクロの処理速度が落ちるので
 * 取得したい項目すべてをひとつの配列にまとめること
 * 
 * ※ 取得したいオプション項目がひとつだけの場合でも引数は
 *    配列 ["KeyName"] のかたちで記述すること
 * 
 *   GetIniOption( [ "KeyName" ] )
 *
 * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して
 *    組み込み関数および呼び出し元のコードを続行する
 *   → 誤ったキーの戻り値は undefined
 */
// ➀ 取得したい INI オプション項目を配列 ["KeyName1", "KeyName2" ...] に列挙する

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 );
}	// "LineColumnView = 1 ↲ object type: number" ...


// ➂-2.(例2)個々の「値」の参照には、戻り値の配列の [index] で要素を指定する

var settings = {
  lineColumnView:	iniValue[0],	// 「行の表示方法」
  wrapMode:			iniValue[1],	// 「折り返し方法」
  quoteCharacter:	iniValue[2],	// 「引用マーク」
  tabColumns:		iniValue[3],	// 「タブの桁数」
  autoIndent:		iniValue[4]		// 「自動インデントを有効にする」
};

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


// ➂-3.(注)取得したいオプション項目がひとつの場合も、配列型 ["keyName"] で記述すること

Alert( GetIniOption( ["LineColumnView"] ) );


GetIniOption2() 関数

Mery.ini ファイル内の各項目

[SectionName]
KeyName1=value1
KeyName2=value2

の「段落名・セクション [SectionName]」と「項目名・キー KeyName」の文字列を指定して「値 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 );
  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 reg, 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];
    reg = new RegExp( "^\\[" + Quote( section ) + "\\]$", "m" );
    id1 = iniText.search( reg );				// セクションの開始位置
    if ( id1 != -1 ) {							// セクション名が正しいか?
      id2 = iniText.indexOf( "\r\n[", 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=  の場合は空文字列  ""  を返す
 *
 * ※ 値はすべて "文字列" (String)型で返されるので、
 *    必要に応じて  Number( value )  などのかたちで利用すること
 */
// ➀ セクション名とキー名をセットにした配列を用意する
// [ [section1, key1], [section2, key2] ... ]
// セクション名にバックスラッシュ・¥ 記号「\」がある場合は、ふたつ重ね「\\」で記述すること

var keyArray = new Array(
  [ "General", "LineColumnView" ], 		// 0 or 1
  [ "General", "FileFilter" ], 			// "*.txt;*ini;*.htm; …"
  [ "General", "Untitled" ], 			// 「無題」の代替文字列 or ""
  [ "View", "FontName0" ], 				// フォント名(履歴) or ""
  [ "Macros\\Macro1", "FileName" ], 	// Macros\マクロ名.js or ""
  [ "Outline\\JavaScript", "Match1" ],	// 文字列値 or 正規表現 or "..."
  [ "Themes\\Theme29", "Caption" ], 	// テーマ名 or ""
  [ "Display", "FallbackFonts" ], 		// フォント名 or ""
// ※ ~ ver 2.7.4 では FallbackFonts キーがないので [Display] undefined = null

  // ※ 無効な セクション名 や キー名 を指定した場合
  [ "HOGE", "FUGA" ],  				// [undefined]	FUGA  =  null
  [ "Themes", "PIYO" ]				// [Themes]		undefined  =  null
);


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

var iniOption = GetIniOption2( keyArray );


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

OutputBar.Writeln( "\nRun > " + ScriptName + " : function 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 );
}


GetIniOption3() 関数

GetIniOption2() 関数 とおなじく、Mery.ini ファイル内の各項目

[SectionName]
KeyName1=value1
KeyName2=value2

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


  • GetIniOption2() 関数では戻り値も 入れ子状の配列 だったため、任意のキーの「値」を参照するには
    var iniOption = GetIniOption2([[section1, key1], [section2, key2]]);
    var value1 = iniOption[0][2];
    var value2 = iniOption[1][2];
    
    のように記述しなければならず、可読性にやや難ありでしたが、GetIniOption3() 関数では戻り値を 連想配列(オブジェクト型) {section1 : {key1 : value1}, section2 : {key2 : value2} ... } objOptions[section][key] = value にしてあります。
INI から取得する「値」が複数のとき、任意の「値」の参照がしやすくなるかとおもいます。
var keyArray = [["General", "LineColumnView"], ["View", "FontName0"]];
var iniOption = GetIniOption3(keyArray);

var value1 = iniOption.General.LineColumnView;	// ドット記法
var value2 = iniOption["View"]["FontName0"];	// ブラケット記法


  • 戻り値の「値」の部分 value は文字列型(String)です。
    ※ GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったときに記述ミスした項目名を undefined にして「値」を null で返しましたが、GetIniOption3() 関数では間違えたままの項目名の「プロパティ」に undefined を「値」としてあたえて返します。
    e.g. obj.General.HOGE = undefined
  • GetIniOption() 関数と GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったとき、つねに警告ダイアログを表示させる仕様にしてありましたが、GetIniOption3() 関数では第2引数(Bool)に true をあたえなかった場合は警告なしで処理を続行します。


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


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


ソースコード

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

/**
 * 組み込み関数 GetIniOption3( keyArray, boolAlertEnable )
 * 
 * 引数で指定した INI オプション項目名と「値」をプロパティ値として持つ
 * 入れ子型のオブジェクトを返す
 * 
 * 引数: INI オプション項目(セクション名とキー名)を指定する入れ子型の配列
 * ※ 配列の記述形式は [ [ section1, key2 ], [ section2, key2 ] ... ]
 * 
 * 戻り値: INI オプション項目の「値」を String 型のプロパティ値として持つオブジェクト
 *     { section1 : { key1 : value1 }, section2 : { key2 : value2 } ... }
 *     objOptions[ section ][ key ] = value
 * 
 * ※ 有効な value はすべて 文字列型 (String)で返す
 *  (数字の場合も "1" として返す  "1" !== 1  )
 * ※ 無効な section, key が指定されたものにたいしては value = undefined で返す
 * 
 * ※ 各「値」への参照方法は
 *   var iniOptions = GetIniOption3( keyArray );
 *   var value1 = iniOptions[ "section1" ][ "key1" ];	// ブラケット記法
 *   var value2 = iniOptions.section2.key2;		// ドット記法
 */
// ---------- ▼ 組み込み関数 ココから ▼ ----------

function GetIniOption3( keyArray, alertEnable ) {
  // 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 );
  Adodb.Close();

  // 引数の配列をループ処理して ini からオプションの値を取得する
  var section, key, value, options = {};
  var reg, 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];
    options[ section ] = options[ section ] || {};
    reg = new RegExp( "^\\[" + Quote( section ) + "\\]$", "m" );
    id1 = iniText.search( reg );					// セクションの開始位置
    if ( id1 != -1 ) {								// セクション名が正しいか?
      id2 = iniText.indexOf( "\r\n[", 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 );
        options[ section ][ key ] = value;
      }
      // キーの指定ミス
      else {
        options[ section ][ key ] = undefined;
        if ( alertEnable ) {
          Alert( "\"" + key + "\" key is NOT found in [" + section + "] section.\n\n"
               + "The function will return ... \n"
               + "{ \"" + section + "\" : { \"" + key + "\" : undefined } }" );
        }
      }
    }
    // セクションの指定ミス
    else {
      options[ section ][ key ] = undefined;
      if ( alertEnable ) {
        Alert( "[" + section + "] section is NOT found in \"Mery.ini\" file.\n\n"
             + "The function will return ... \n"
             + "{ \"" + section + "\" : { \"" + key + "\" : undefined } }" );
      }
    }
    id1 = 0;
  }
  return options;
}

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


使い方

/**
 * 【使い方】
 *
 * GetIniOption3() 関数の使用は1回で済ませないと
 * その都度 INI ファイルの読み込み が発生してマクロの処理速度が落ちるので
 * 取得したい項目すべてをひとつの配列にまとめること
 *
 * ※ 要求する項目が1セットの場合も配列を 入れ子 にすること
 *   GetIniOption3( [ [ "SectionName", "KeyName" ] ] );
 *
 * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する
 *    記述ミスをした項目の値 value undefined で返される
 * ※ INI 内でオプションの値が空  KeyName=  の場合は空文字列  ""  を返す
 *
 * ※ 値はすべて "文字列" (String)型で返されるので、
 *    必要に応じて  Number( value )  などのかたちで利用すること
 */
// ➀ セクション名とキー名をセットにした配列 [ [section1, key2], [section2, key2] ... ]
//    セクション名に「\」がある場合は、ふたつ重ね「\\」で記述すること
var keyArray = new Array(
  [ "General", "LineColumnView" ], 		// 0 or 1
  [ "General", "FileFilter" ], 			// "*.txt;*ini;*.htm; …"
  [ "General", "Untitled" ], 			// 「無題」の代替値 or ""
  [ "Display", "FallbackFonts" ], 		// フォント名 or "" (~ver2.7.4 では undefined)
  [ "View", "FontName0" ], 				// フォント名(履歴) or ""
  [ "Macros\\Macro1", "FileName" ], 	// Macros\マクロ名.js or ""
  [ "Outline\\JavaScript", "Match1" ],	// 文字列値 or 正規表現 or "..."
  [ "Themes\\Theme29", "Caption" ], 	// テーマ名 or ""
  [ "Themes", "HOGE" ],				 	// [Themes] HOGE  =  null
  [ "FUGA", "PIYO" ] 					// [FUGA] PIYO = null
);

// ➁ 関数の引数に配列をあたえて、変数 iniOption に代入する
//    関数の戻り値は入れ子状のオブジェクト
//    { section1 : { key1 : value1 }, section2 : { key2 : value2 } ... }
// ※ value は文字列値(String)で返される(数字の場合も "1"  ※ "1" !== 1 )

var iniOptions = GetIniOption3( keyArray, true );	// 戻り値は Object 型


// ➂-1.(例1)戻り値で取得した内容をアウトプットバーに出力する

OutputBar.Writeln( "\nRun > " + ScriptName + " : function GetIniOption3()" );
var section, key;
for ( var i = 0; i < keyArray.length; i ++ ) {
  section = keyArray[i][0],  key = keyArray[i][1];
  OutputBar.Writeln( "[" + section + "]\t" + key
                   + "=" + iniOptions[ section ][ key ] );
}


// ➂-2.(例2)特定の key の値を参照して変数に格納する場合

var ff = iniOptions.General.FileFilter;			// ドット記法
var fn = iniOptions[ "View" ][ "FontName0" ];	// ブラケット記法
Alert( "[General]\nFileFilter=" + ff + "\n"
     + "[View]\nFontName0=" + fn );


更新履歴

  • 2019/03/10 (sukemaru)
GetIniOption() 関数 の初版
  • 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 周りのコードで、引数のキー名にエラーがあった場合の処理が正しく行われなかった不具合を修正。
  • 2019/08/27 (sukemaru)
GetIniOption2() 関数の変数 id2 周りのコードで、同一セクション内で に角カッコ「[」を含む キー が上にあると次の セクション の開始位置を正しく取得できなかった不具合を修正。
  • 2019/11/15 (sukemaru)
関数コードの軽微な修正。
説明などの文面を変更。
  • 2020/05/14 (sukemaru)
セクション指定可能で、戻り値をオブジェクト型にした GetIniOption3() 関数 を追加。


メモ

  • 2019/03/10 (sukemaru)
将来的に INI を最新の状態に強制更新したり INI の設定項目を取得できる専用メソッドが実装されるかもしれませんし、現状でも includeライブラリMeryInfo.js)によりある程度 INI へのアクセスはできますが…。
一応、includeライブラリ(IO.js)の使用のみでエディタの表示状態を変更するマクロの例として「折り返しトグル切り替え」などもあります。


INI アクセスのための専用メソッド については フォーラム 内のトピック『マクロコマンドから「表示」の「色の反転」を取得したい』で検討・議論されていますので、ご参考までに(セキュリティ上の 懸念 により実装は見送りとなっています)。


  • 導入事例
  • 検索ジャンプ」「ブックマークジャンプ」マクロでは「行の表示方法」(論理座標/表示座標) の取得に GetIniOption() 関数を利用しています。
  • 読みなおし」マクロでは、GetIniOption() 関数を大幅に魔改造して「自動保存」「バックアップ」関連の設定内容とすべての「編集モード名」を取得しています。
  • コンパクトメニュー」マクロでは GetIniOption() 関数をさらに魔改造して、「最近のファイルの表示数」 「無題タブ用のラベル」 などの値や、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 の一覧などを取得しています。


  • 参照したい値が「数値」や「Ascii文字だけの文字列」であれば、記述が煩雑になる ADODB.Stream や拙作の関数を使わずに、FileSystemObject の OpenTextFile()ReadAll() メソッドでも問題ありません(値が2バイト文字の場合、文字化けするので FileSystemObject は不適)。
なお、Mery.ini の改行コードは CR+LF なので、検索で改行位置を利用する場合は "\r\n" を用います。


  • 基本的に、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 のショートカットキーは取得できません (キー名が32桁の16進数になっていて「マクロ名」などで検索できないため)。
スポンサーリンク