「Mery.iniのオプション値を取得」の版間の差分
(→GetIniOption2() 関数: 「次のセクションの開始位置」を修正) |
(<source>タグを<syntaxhighlight>タグに置き換え) |
||
(他の1人の利用者による、間の8版が非表示) | |||
1行目: | 1行目: | ||
<div style="float:right">__toc__</div> | |||
テキストエディタ Mery の設定ファイル '''Mery.ini''' を参照して任意の項目の設定値を取得するための '''マクロ用組み込みコード''' です。<br><br> | |||
複数の項目を配列にして関数に渡す仕様につき Mery.ini へのアクセス('''読みこみ''')が1回で済むため、多様性に富んだ参照を高速に処理できます。 | |||
<br><br> | |||
※ <b style="color:#c00;">このページのマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。</b> | |||
<br><br> | |||
※ 標準ツールバーのメニューや右クリックメニューのコマンド、ツールバーアイコン、ショートカットキー、他のマクロなどから変更された設定内容(おもにエディタの表示設定)は直ちに Mery.ini に反映されるわけではないので、この組み込み用コードにより取得されたオプション値がエディタの状態どおりではない場合があります。<br> | |||
⇒ [[#QueryStatusByID|Mery ver 3.1.0 以降ではメニュー項目の '''✔'''チェックの ON/OFF 状態もマクロから取得できるようになったようです。]] | |||
<br clear=all> | |||
== GetIniOption() 関数 == | == GetIniOption() 関数 == | ||
Mery.ini ファイル内の各行 <br> | Mery.ini ファイル内の各行 <br> | ||
'''KeyName'''='''value''' | |||
の「項目名 <code>KeyName</code>」の文字列を指定して「値 <code>value</code>」を取得するための '''組み込み用関数''' です。<br> | |||
Mery.ini の任意の項目名(左辺) <code>KeyName</code> で検索をかけて、生の値(右辺)<code>value</code> をそのまま取得します。 | |||
* [[#関数1|組み込み関数本体]] を任意のマクロのソースコード内にペーストして使用します。 | * [[#関数1|組み込み関数本体]] を任意のマクロのソースコード内にペーストして使用します。 | ||
: ペーストする位置は呼び出し元のコードから参照できるスコープ内であれば、ソースコードの末尾でも問題ありません。 | : ペーストする位置は呼び出し元のコードから参照できるスコープ内であれば、ソースコードの末尾でも問題ありません。 | ||
: 使い方は [[# | : 使い方は [[#使い方|使用例]] を参考にしてください。 | ||
* | * INI 内に '''同名の「項目名」''' がある場合は、さいしょにヒットした項目の「値」のみを返します。これは、引数の配列の要素(項目名)と戻り値の配列の要素(値)を 1 対 1 で対照させるための仕様です。<br> → 重複する「項目名」のある項目を参照する場合は [[#GetIniOption2() 関数|GetIniOption2() 関数]] か [[#GetIniOption3() 関数|GetIniOption3() 関数]] を使用してください(2019/05/21, 2020/05/14 追加)。 | ||
* | * 引数の配列で「オプション項目名 <code>KeyName</code>」の記述を間違えると、 警告ダイアログを表示し、誤った項目名を指摘します。<br> ※ 呼び出し元のコードの処理は継続されます。 | ||
* 「Mery.exe」自体のファイル名をリネームしている場合も、Mery の実行ファイルのベース名を取得して、適切な INI ファイルを読みこみます。 | |||
* 基本的に Mery.ini は [[ヘルプ:ツール#オプション|オプション]] | * <b style="color:#c00;">このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。 </b> | ||
<br> | |||
* Mery.ini の直接編集でオプションパネルから設定変更できない「'''隠し機能'''」項目をカスタマイズしている人なら、現在の設定値の確認などにも使えるかも? | * 基本的に Mery.ini は [[ヘルプ:ツール#オプション|オプション]] などの設定ダイアログを閉じたときと Mery を終了したときにしか更新されず、標準メニューバー、ツールバーアイコン、右クリックメニュー、ショートカットキー、マクロ等でエディタの設定状態を変更しているばあい、INI の内容が最新の状態とはなりません。 <br> よって、かならずしもエディタの表示状態(折り返しや色の反転、記号の表示設定など)どおりの値を取得できるわけではありません。<br> ・・・ MeryInfo.js にはない項目として「行の表示方法」の取得ぐらいしか使い道がない? | ||
:* Mery.ini の直接編集でオプションパネルから設定変更できない「'''隠し機能'''」項目をカスタマイズしている人なら、現在の設定値の確認などにも使えるかも? | |||
:* [[#メモ|メモ]] に挙げた導入事例のマクロのように、関数コードを改造することで Mery.ini のマクロへの活用法の幅がひろがりますが…。 | |||
29行目: | 41行目: | ||
/** | /** | ||
* 組み込み関数 '''GetIniOption( keyArray )''' | * 組み込み関数 '''GetIniOption( keyArray )''' | ||
* 引数で指定した'''任意の''' INI オプション項目の「値」を返す | * 引数で指定した '''任意の''' INI オプション項目の「値」を返す | ||
* | * | ||
* | * '''引数:''' INI オプション項目名を列挙した配列 | ||
* | * ※ 記述形式は '''''[ "KeyName1", "KeyName2", "KeyName3" ]''''' | ||
* | * | ||
* | * '''戻り値:''' INI オプション項目の「値」を並べた '''配列'''。 | ||
* ※ 配列の形式は '''''[ "value1", "value2", "value3" ]''''' | |||
* 各要素 value は '''数値型'''(Number) または '''文字列型'''(String) | |||
*/ | */ | ||
<div id="関数1"> </div> | <div id="関数1"> </div> | ||
< | <syntaxhighlight lang="javascript"> | ||
// ---------- ▼ 組み込み関数 ココから ▼ ---------- | // ---------- ▼ 組み込み関数 ココから ▼ ---------- | ||
56行目: | 70行目: | ||
Adodb.Open(); | Adodb.Open(); | ||
Adodb.LoadFromFile( iniPath ); | Adodb.LoadFromFile( iniPath ); | ||
var iniText = Adodb.ReadText( adReadAll ); | var iniText = Adodb.ReadText( adReadAll ); | ||
Adodb.Close(); | Adodb.Close(); | ||
/ | /* includeライブラリの IO.js, MeryInfo.js を #include しているマクロに組み込むなら | ||
var iniPath から Adodb.Close() までは以下の一行だけでもよい */ | |||
// var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" ); | // var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" ); | ||
// 引数の配列をループ処理して ini からオプションの値を取得する | // 引数の配列をループ処理して ini からオプションの値を取得する | ||
var value, iniOptionArray = []; | var reg, value, iniOptionArray = []; | ||
for ( var i = 0, len = keyArray.length; i < len; i ++ ) { | for ( var i = 0, len = keyArray.length; i < len; i ++ ) { | ||
reg = new RegExp( "^" + keyArray[i] + "=[^\\r\\n]*$", "gm" ); | reg = new RegExp( "^" + keyArray[i] + "=[^\\r\\n]*$", "gm" ); | ||
72行目: | 86行目: | ||
.substr( keyArray[i].length + 1 ); | .substr( keyArray[i].length + 1 ); | ||
// 10進数なら Number 型で返す | // 10進数なら Number 型で返す | ||
if ( /^-?[0-9] | if ( /^-?[1-9][0-9]*$/.test( value ) ) { | ||
value = Number( value ); | value = Number( value ); | ||
} | } | ||
} | } catch( e ) { | ||
Alert( keyArray[i] + " という項目はありません。" ); | Alert( keyArray[i] + " という項目はありません。" ); | ||
value = undefined; | value = undefined; | ||
86行目: | 99行目: | ||
// ---------- ▲ 組み込み関数 ココまで ▲ ---------- | // ---------- ▲ 組み込み関数 ココまで ▲ ---------- | ||
</ | </syntaxhighlight> | ||
94行目: | 107行目: | ||
* 【使い方】 | * 【使い方】 | ||
* | * | ||
* GetIniOptions() | * GetIniOptions() 関数の使用を1回で済ませないと | ||
* その都度 INI | * その都度 '''INI ファイルの読み込み''' が発生してマクロの処理速度が落ちるので | ||
* 取得したい項目すべてをひとつの配列にまとめること | * 取得したい項目すべてをひとつの配列にまとめること | ||
* | * | ||
* ※ 取得したいオプション項目がひとつだけの場合でも引数は [" | * ※ 取得したいオプション項目がひとつだけの場合でも引数は | ||
* | * 配列 '''''["KeyName"]''''' のかたちで記述すること | ||
* | |||
* '''''<code>GetIniOption( [ "KeyName" ] )</code>''''' | |||
* | * | ||
* ※ INI | * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して | ||
* 組み込み関数および呼び出し元のコードを続行する | |||
* → 誤ったキーの戻り値は '''''<syntaxhighlight lang="javascript" inline>undefined</syntaxhighlight>''''' | |||
*/ | */ | ||
< | <syntaxhighlight lang="javascript"> | ||
// | // ➀ 取得したい INI オプション項目を配列 ["KeyName1", "KeyName2" ...] に列挙する | ||
var iniItem = [ "LineColumnView", "WrapMode", "QuoteCharacter", "TabColumns", "AutoIndent" ]; | var iniItem = [ "LineColumnView", "WrapMode", "QuoteCharacter", "TabColumns", "AutoIndent" ]; | ||
111行目: | 129行目: | ||
// | // ➁ GetIniOption() の引数に配列を指定して変数に代入する | ||
var iniValue = GetIniOption( iniItem ); // ※戻り値も配列 | |||
// ➂-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] で要素を指定する | |||
var settings = { | var settings = { | ||
lineColumnView: iniValue[0], // 「行の表示方法」 | lineColumnView: iniValue[0], // 「行の表示方法」 | ||
wrapMode: iniValue[1], | wrapMode: iniValue[1], // 「折り返し方法」 | ||
quoteCharacter: iniValue[2], // 「引用マーク」 | quoteCharacter: iniValue[2], // 「引用マーク」 | ||
tabColumns: iniValue[3], | tabColumns: iniValue[3], // 「タブの桁数」 | ||
autoIndent: iniValue[4] // 「自動インデントを有効にする」 | autoIndent: iniValue[4] // 「自動インデントを有効にする」 | ||
}; | }; | ||
136行目: | 157行目: | ||
// | // ➂-3.(注)取得したいオプション項目がひとつの場合も、配列型 ["keyName"] で記述すること | ||
Alert( GetIniOption( ["LineColumnView"] ) ); | Alert( GetIniOption( ["LineColumnView"] ) ); | ||
</ | |||
</syntaxhighlight> | |||
145行目: | 168行目: | ||
Mery.ini ファイル内の各項目 <br> | Mery.ini ファイル内の各項目 <br> | ||
'''[SectionName]''' | |||
'''KeyName1'''='''value1''' | |||
'''KeyName2'''='''value2''' | |||
の「段落名・セクション <code>[SectionName]</code>」と「項目名・キー <code>KeyName</code>」の文字列を指定して「値 <code>value</code>」を取得するための '''組み込み用関数''' です。<br> <span style="color:#0000c0;">ことなるセクションに同じキー名の項目が重複して存在することを考慮してありますので、<u>Mery.ini のすべての項目の参照が可能になります</u>。</span> | |||
155行目: | 178行目: | ||
* <b style="color:#c00;"> | * <b style="color:#c00;">このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。 </b> | ||
163行目: | 186行目: | ||
/** | /** | ||
* 組み込み関数 '''GetIniOption2( keyArray )''' | * 組み込み関数 '''GetIniOption2( keyArray )''' | ||
* 引数で指定した'''任意の''' INI オプション項目の配列に | * | ||
* 引数で指定した '''任意の''' INI オプション項目の配列に | |||
* '''「値」をくわえた配列''' で返す | * '''「値」をくわえた配列''' で返す | ||
* | * | ||
* | * '''引数:''' INI オプション項目(セクション名とキー名)を指定する配列 | ||
* | * ※ 記述形式は '''''[ [section1, key1], [section2, key2] ... ] '''''(※入れ子にする) | ||
* | * | ||
* | * '''戻り値:''' INI オプション項目の「値」を追加した '''配列''' | ||
* | * ※ 配列の形式は '''''[ [section1, key1, value1], [section2, key2, value2] ... ]''''' | ||
* ※ value はすべて''' | * | ||
* ※ value はすべて '''文字列型''' (String)で返す | |||
* (数字の場合も '''<syntaxhighlight lang="javascript" inline>"1"</syntaxhighlight>''' として返す <span style="color:#c00;">"1" !== 1</span> ) | |||
*/ | */ | ||
<div id="関数2"></div> | <div id="関数2"></div> | ||
< | <syntaxhighlight lang="javascript"> | ||
// ---------- ▼ 組み込み関数 ココから ▼ ---------- | // ---------- ▼ 組み込み関数 ココから ▼ ---------- | ||
193行目: | 219行目: | ||
Adodb.Open(); | Adodb.Open(); | ||
Adodb.LoadFromFile( iniPath ); | Adodb.LoadFromFile( iniPath ); | ||
var iniText = Adodb.ReadText( adReadAll ); | var iniText = Adodb.ReadText( adReadAll ); | ||
Adodb.Close(); | Adodb.Close(); | ||
/* includeライブラリの IO.js と MeryInfo.js を #include しているマクロに組み込むなら | |||
var iniPath から Adodb.Close() までは以下の一行だけでもよい */ | |||
// var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" ); | // var iniText = IO.LoadFromFile( MeryInfo.GetIniPath(), "utf-8" ); | ||
// 引数の配列をループ処理して ini からオプションの値を取得する | // 引数の配列をループ処理して ini からオプションの値を取得する | ||
var section, key, value, iniOptionArray = []; | var section, key, value, iniOptionArray = []; | ||
var id1, id2, id3, id4; | var reg, id1, id2, id3, id4; | ||
var iniLength = iniText.length; | var iniLength = iniText.length; | ||
var Quote = function( str ) { return str.replace( /\W/g, "\\$&" ) }; | var Quote = function( str ) { return str.replace( /\W/g, "\\$&" ) }; | ||
208行目: | 234行目: | ||
section = keyArray[i][0]; | section = keyArray[i][0]; | ||
key = keyArray[i][1]; | key = keyArray[i][1]; | ||
reg = new RegExp( "^\\[" + Quote( section ) + "\\]$", "m" ); | |||
id1 = iniText.search( | id1 = iniText.search( reg ); // セクションの開始位置 | ||
if ( id1 != -1 ) { // セクション名が正しいか? | if ( id1 != -1 ) { // セクション名が正しいか? | ||
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 ); | value = iniText.slice( id3 + key.length + 2, id4 ); | ||
iniOptionArray.push( [ section, key, value ] ); | iniOptionArray.push( [ section, key, value ] ); | ||
} | } | ||
234行目: | 260行目: | ||
// ---------- ▲ 組み込み関数 ココまで ▲ ---------- | // ---------- ▲ 組み込み関数 ココまで ▲ ---------- | ||
</ | </syntaxhighlight> | ||
242行目: | 268行目: | ||
* 【使い方】 | * 【使い方】 | ||
* | * | ||
* GetIniOptions2() | * GetIniOptions2() 関数の使用を1回で済ませないと | ||
* その都度 INI | * その都度 '''INI ファイルの読み込み''' が発生してマクロの処理速度が落ちるので | ||
* 取得したい項目すべてをひとつの配列にまとめること | * 取得したい項目すべてをひとつの配列にまとめること | ||
* | * | ||
* ※ | * ※ 取得したいオプション項目がひとつだけの場合でも引数の配列は '''入れ子''' にすること | ||
* | * | ||
* '''''<code>GetIniOption2( [ [ "SectionName", "KeyName" ] ] )</code>''''' | |||
* | * | ||
* ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する | * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する | ||
* | * 記述ミスをした項目は '''''<syntaxhighlight lang="javascript" inline>undefined</syntaxhighlight>''''' に置き換え、要求された値は '''''<syntaxhighlight lang="javascript" inline>null</syntaxhighlight>''''' で返す | ||
* ※ オプションの値が空 | * ※ オプションの値が空 ''<code>KeyName=</code>'' の場合は、空文字列 '''''<syntaxhighlight lang="javascript" inline>""</syntaxhighlight>''''' を返す | ||
* | * | ||
* ※ 値はすべて '''" | * ※ 値はすべて '''"文字列型"'''(String)で返されるので、 | ||
* 必要に応じて ''<code>Number( value )</code>'' などのかたちで利用すること | |||
*/ | */ | ||
< | <syntaxhighlight lang="javascript"> | ||
// | // ➀ セクション名とキー名をセットにした配列を用意する | ||
// | // [ [section1, key1], [section2, key2] ... ] | ||
// セクション名にバックスラッシュ・¥ 記号「\」がある場合は、ふたつ重ね「\\」で記述すること | |||
var keyArray = new Array( | var keyArray = new Array( // ▼ 戻り値 ▼ | ||
[ "General", "LineColumnView" ], // 0 or 1 | [ "General", "LineColumnView" ], // 0 or 1 | ||
[ "General", "FileFilter" ], // "*.txt;*ini;*.htm; …" | [ "General", "FileFilter" ], // "*.txt;*ini;*.htm; …" | ||
[ "General", "Untitled" ], // | [ "General", "Untitled" ], // 「無題」の代替文字列 or "" | ||
[ "View", "FontName0" ], // フォント名(履歴) or "" | [ "View", "FontName0" ], // フォント名(履歴) or "" | ||
[ "Macros\\Macro1", "FileName" ], // Macros\マクロ名.js or "" | [ "Macros\\Macro1", "FileName" ], // Macros\マクロ名.js or "" | ||
[ "Outline\\JavaScript", "Match1" ], // 文字列値 or 正規表現 or "..." | [ "Outline\\JavaScript", "Match1" ], // 文字列値 or 正規表現 or "..." | ||
[ "Themes\\Theme29", "Caption" ], // テーマ名 or "" | [ "Themes\\Theme29", "Caption" ], // テーマ名 or "" | ||
[ "Display", "FallbackFonts" ], | [ "Display", "FallbackFonts" ], // フォント名 or "" | ||
// 無効な セクション名 や キー名 を指定した場合 | // ※ ~ ver 2.7.4 では FallbackFonts キーがないので [Display] undefined = null | ||
// ※ 無効な セクション名 や キー名 を指定した場合 | |||
[ "HOGE", "FUGA" ], // [undefined] FUGA = null | [ "HOGE", "FUGA" ], // [undefined] FUGA = null | ||
[ "Themes", "PIYO" ] // [Themes] undefined = null | [ "Themes", "PIYO" ] // [Themes] undefined = null | ||
274行目: | 305行目: | ||
// | // ➁ 関数の引数に配列をあたえて、変数 iniOption に代入する | ||
// | // 関数の戻り値も入れ子状の配列 | ||
// ※ value は文字列値(String)で返される(数字の場合も "1" | // [ [section1, key1, value1], [section2, key2, value2] ... ] | ||
// ※ value は文字列値(String)で返される(数字の場合も "1" ※ "1" !== 1 ) | |||
var iniOption = GetIniOption2( keyArray ); | var iniOption = GetIniOption2( keyArray ); | ||
// | // ➂ 戻り値で取得した配列の内容をアウトプットバーに出力する | ||
OutputBar.Writeln( "\ | 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 ++ ) { | ||
section = iniOption[i][0]; // セクション名に記述ミスがあると undefined | section = iniOption[i][0]; // セクション名に記述ミスがあると undefined | ||
key = iniOption[i][1]; // キー名に記述ミスがあると undefined | key = iniOption[i][1]; // キー名に記述ミスがあると undefined | ||
295行目: | 328行目: | ||
+ key + " = " + value ); | + key + " = " + value ); | ||
} | } | ||
</ | </syntaxhighlight> | ||
== GetIniOption3() 関数 == | |||
[[#GetIniOption2() 関数|GetIniOption2() 関数]] とおなじく、Mery.ini ファイル内の各項目 <br> | |||
'''[SectionName]''' | |||
'''KeyName1'''='''value1''' | |||
'''KeyName2'''='''value2''' | |||
の「段落名・セクション <code>[SectionName]</code>」と「項目名・キー <code>KeyName</code>」の文字列を指定して「値 <code>value</code>」を取得するための '''組み込み用関数''' です。<br> <span style="color:#0000c0;">ことなるセクションに同じキー名の項目が重複して存在することを考慮してありますので、<u>Mery.ini のすべての項目の参照が可能です</u>。</span> | |||
* GetIniOption2() 関数では戻り値も '''入れ子状の配列''' だったため、任意のキーの「値」を参照するには <syntaxhighlight lang="javascript"> | |||
var iniOption = GetIniOption2([[section1, key1], [section2, key2]]); | |||
// 配列の index をふたつずつ指定して「値」を参照 | |||
var value1 = iniOption[0][2]; | |||
var value2 = iniOption[1][2]; | |||
</syntaxhighlight> のように記述しなければならず、コードの可読性にやや難ありでした。<br><br> GetIniOption3() 関数では戻り値を '''オブジェクト型(連想配列)''' にしてあります。 | |||
{section1 : {key1 : value1}, section2 : {key2 : value2} ... } | |||
⇒ ''value1 = objOptions[section1][key1]'' | |||
または ''value2 = objOptions.section2.key2'' | |||
: <span style="color:#0000c0;">セクション名とキー名がそのままプロパティ名になる</span>ので、INI から取得する「値」が複数のときに任意の「値」の参照がしやすくなるかとおもいます。<syntaxhighlight lang="javascript"> | |||
var keyArray = [["General", "LineColumnView"], ["View", "FontName0"]]; | |||
var iniOption = GetIniOption3(keyArray); | |||
// プロパティをセクション名とキー名の文字列で記述して「値」を参照 | |||
var value1 = iniOption.General.LineColumnView; // ドット記法 | |||
var value2 = iniOption["View"]["FontName0"]; // ブラケット記法 | |||
</syntaxhighlight> | |||
* 戻り値の「値」の部分 <code>value</code> は '''文字列型'''(String)です。 | |||
: ※ GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったときに記述ミスした項目名を <span style="color:#c00;"><syntaxhighlight lang="javascript" inline>undefined</syntaxhighlight></span> にして「値」を <span style="color:#c00;"><syntaxhighlight lang="javascript" inline>null</syntaxhighlight></span> で返しましたが、<span style="color:#c00;">GetIniOption3() 関数では間違えたままの項目名の「プロパティ」に '''<syntaxhighlight lang="javascript" inline>undefined</syntaxhighlight>''' を「値」としてあたえて返します。</span><br> ''e.g.'' <syntaxhighlight lang="javascript" inline>objOptions.General.HOGE = undefined</syntaxhighlight> | |||
* GetIniOption() 関数と GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったとき、つねに警告ダイアログを表示させる仕様にしてありましたが、GetIniOption3() 関数では第2引数(Bool)に <syntaxhighlight lang="javascript" inline>true</syntaxhighlight> をあたえなかった場合は警告なしで処理を続行します。 | |||
<div class="warningbox"> | |||
<span style="color:#c00;">※ セクション名に「'''<code>\</code>'''(バックスラッシュ、¥ マーク)」をふくむ項目を指定したときは、戻り値のプロパティ名は '''ブラケット記法''' で記述してください。</span><br> | |||
: ''e.g.'' <syntaxhighlight lang="javascript" inline>[ ["Macros\\Macro0", "FileName"], ["Mode\\Text", "Count"] ]</syntaxhighlight><br>⇒ <syntaxhighlight lang="javascript" inline>objOptions["Macros\\Macro0"]["FileName"]</syntaxhighlight><br> <syntaxhighlight lang="javascript" inline>objOptions["Mode\\Text"]["Count"]</syntaxhighlight> | |||
</div> | |||
* [[#関数3|組み込み関数本体]] を任意のマクロのソースコード内にペーストして使用します。 | |||
: 使い方は [[#使い方_3|使用例]] を参考にしてください。 | |||
* <b style="color:#c00;">このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。 </b> | |||
=== ソースコード === | |||
// #title="Mery.ini のオプション値を取得" | |||
/** | |||
* 組み込み関数 '''GetIniOption3( keyArray, boolAlertEnable )''' | |||
* | |||
* 引数で指定した '''任意の''' INI オプション項目名と「値」をプロパティ値として持つ | |||
* '''''入れ子型のオブジェクト''''' を返す | |||
* | |||
* '''第1引数:''' INI オプション項目(セクション名とキー名)を指定する入れ子型の配列 | |||
* ※ 配列の記述形式は '''''[ [ section1, key2 ], [ section2, key2 ] ... ]''''' (※入れ子にする) | |||
* | |||
* '''第2引数:''' INI オプション項目(セクション名とキー名)の指定ミスがあったときに | |||
* 警告ダイアログを表示する/しない を <syntaxhighlight lang="javascript" inline>true</syntaxhighlight> か <syntaxhighlight lang="javascript" inline>false</syntaxhighlight> で指定する(省略可) | |||
* | |||
* '''戻り値:''' INI オプション項目の「値」を String 型のプロパティ値として持つ '''''オブジェクト''''' | |||
* ※ 戻り値の形式は '''''{ section1: { key1: value1 }, section2: { key2: value2 } ... }''''' | |||
* ⇒ '''''<syntaxhighlight lang="javascript" inline>objOptions[ section ][ key ] = value</syntaxhighlight>''''' | |||
* | |||
* ※ 有効な value はすべて '''文字列型''' (String)で返す | |||
* (数字の場合も '''<syntaxhighlight lang="javascript" inline>"1"</syntaxhighlight>''' として返す <span style="color:#c00;">"1" !== 1</span> ) | |||
* ※ 無効な section, key が指定されたものにたいしては ''<syntaxhighlight lang="javascript" inline>value = undefined</syntaxhighlight>'' で返す | |||
* | |||
* ※ 各「値」への参照方法は | |||
* <syntaxhighlight lang="javascript" inline>var iniOptions = GetIniOption3( keyArray );</syntaxhighlight> | |||
* <syntaxhighlight lang="javascript" inline>var value1 = iniOptions[ "section1" ][ "key1" ]; // ブラケット記法</syntaxhighlight> | |||
* <syntaxhighlight lang="javascript" inline>var value2 = iniOptions.section2.key2; // ドット記法</syntaxhighlight> | |||
*/ | |||
<div id="関数3"></div> | |||
<syntaxhighlight lang="javascript"> | |||
// ---------- ▼ 組み込み関数 ココから ▼ ---------- | |||
function GetIniOption3( keyArray, alertEnable ) { | |||
var Fso = new ActiveXObject( "Scripting.FileSystemObject" ); | |||
// Mery.ini を探す | |||
var iniPath = editor.FullName.replace( /\.exe$/i, ".ini" ); | |||
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 options = {}; | |||
var section, key, value, reg, id1, id2, id3, id4; | |||
var iniLength = iniText.length; | |||
for ( var i = 0, len = keyArray.length; i < len; id1 = 0, i ++ ) { | |||
section = keyArray[i][0]; | |||
key = keyArray[i][1]; | |||
options[ section ] = options[ section ] || {}; | |||
// セクション名を検索 | |||
reg = new RegExp( "^\\[" + section.replace( /\W/g, "\\$&" ) + "\\]$", "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 ); // ("\n"+"=").length = 2 | |||
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 } }" ); | |||
} | |||
} | |||
} | |||
return options; | |||
} | |||
// ---------- ▲ 組み込み関数 ココまで ▲ ---------- | |||
</syntaxhighlight> | |||
=== 使い方 === | |||
/** | |||
* 【使い方】 | |||
* | |||
* GetIniOption3() 関数の使用は1回で済ませないと | |||
* その都度 '''INI ファイルの読み込み''' が発生してマクロの処理速度が落ちるので | |||
* 取得したい項目すべてをひとつの配列にまとめること | |||
* | |||
* ※ 要求する項目が1セットの場合も配列を '''入れ子''' にすること | |||
* '''''<code>GetIniOption3( [ [ "SectionName", "KeyName" ] ] );</code>''''' | |||
* | |||
* ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する | |||
* 記述ミスをした項目の値 ''value ''は '''''<syntaxhighlight lang="javascript" inline>undefined</syntaxhighlight>''''' で返される | |||
* ※ INI 内でオプションの値が空 ''<code>KeyName=</code>'' の場合は、空文字列 '''<syntaxhighlight lang="javascript" inline>""</syntaxhighlight>''' を返す | |||
* | |||
* ※ 値はすべて '''"文字列型"'''(String)で返されるので、 | |||
* 必要に応じて ''<code>Number( value )</code>'' などのかたちで利用すること | |||
* | |||
* <b style="color:#c00;">【注意】</b> | |||
* <span style="color:#c00;">※ セクション名にバックスラッシュ「'''<code>\</code>'''」が含まれる場合、</span> | |||
* <span style="color:#c00;">戻り値のプロパティ名を指定するさいには '''ブラケット記法''' で記述すること</span> | |||
* | |||
* e.g. ''<syntaxhighlight lang="javascript" inline>[ "Themes\\Theme0", "Caption" ]</syntaxhighlight>'' | |||
* ⇒ ''<syntaxhighlight lang="javascript" inline>objOptions["Themes\\Theme0"]["Caption"]</syntaxhighlight>'' | |||
* (ドット記法で ''<syntaxhighlight lang="javascript" inline>objOptions.Themes\\Theme0.Caption</syntaxhighlight>'' とすると <b style="color:#c00;">エラー</b> になる) | |||
*/ | |||
<syntaxhighlight 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 "" | |||
// → (~ ver 2.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 ); | |||
</syntaxhighlight> | |||
== 更新履歴 == | |||
* 2019/03/10 sukemaru | * 2019/03/10 (sukemaru) | ||
: | : [[#GetIniOption() 関数|GetIniOption() 関数]] の初版 | ||
* 2019/04/28 sukemaru | * 2019/04/28 (sukemaru) | ||
: | : 「文字列値」が2バイト文字を含むときに正常に読みこめなかったので、'''"ADODB.Stream" / UTF-8''' での読みこみに変更した。 | ||
* 2019/04/29 sukemaru | * 2019/04/29 (sukemaru) | ||
: | : 値がハイフン-マイナス「'''<code>-</code>'''」1文字のときに戻り値が '''<syntaxhighlight lang="javascript" inline>NaN</syntaxhighlight>''' になっていたのを文字列 '''<syntaxhighlight lang="javascript" inline>"-"</syntaxhighlight>''' で返すように修正(値が空のときは長さ 0 の文字列 '''<syntaxhighlight lang="javascript" inline>""</syntaxhighlight>''' のまま)。 | ||
* 2019/05/21 sukemaru | * 2019/05/21 (sukemaru) | ||
: セクション指定可能な GetIniOption2() | : セクション指定可能な [[#GetIniOption2() 関数|GetIniOption2() 関数]] を追加し、Mery.ini の完全な参照ができるようにした。 | ||
: | : 従来の GetIniOption() 関数も簡易版として残し、誤った参照キー名に対するエラー処理を変更しておいた。 | ||
* 2019/06/02 sukemaru | * 2019/06/02 (sukemaru) | ||
: GetIniOption2() | : GetIniOption2() 関数内の変数 '''id2''' 周りのコードで、引数のキー名にエラーがあった場合の処理が正しく行われなかった不具合を修正。 | ||
* 2019/08/27 (sukemaru) | |||
: GetIniOption2() 関数内の変数 '''id2''' 周りのコードで、同一セクション内で '''値''' に角カッコ「'''<code>[</code>'''」を含む キー が上にあると次の セクション の開始位置を正しく取得できなかった不具合を修正。 | |||
* 2019/11/15 (sukemaru) | |||
: 関数コードの軽微な修正。 | |||
: 説明などの文面を変更。 | |||
* 2020/05/14 (sukemaru) | |||
: セクション指定可能で、戻り値をオブジェクト型にした [[#GetIniOption3() 関数|GetIniOption3() 関数]] を追加。 | |||
<br> | |||
== メモ == | |||
* | * 2019/03/10 ~ (sukemaru) | ||
:* 将来的に INI を最新の状態に強制更新したり INI の設定項目を取得できる専用メソッドが実装されるかもしれませんし、現状でも [[includeライブラリ]]([[includeライブラリ#MeryInfo.js|MeryInfo.js]])によりある程度 INI へのアクセスはできますが…。 | |||
:* 一応、includeライブラリ(IO.js)の使用のみでエディタの表示状態を変更するマクロの例として「[[折り返しトグル切り替え]]」などもあります。 | |||
<br> | |||
:* <div id="QueryStatusByID">[表示] メニュー内などの各項目の '''✔'''チェックの ON/OFF 状態は Mery.ini から正しく取得できないことがありますが、[https://www.haijin-boys.com/software/mery/mery-3-1-0#10|Mery ver 3.1.0] 以降では '''[[マクロリファレンス:3:Editor_オブジェクト#QueryStatusByID_メソッド|QueryStatusByID メソッド]] <code>editor.QueryStatusByID(id);</code>''' を利用することで取得できるようになりました。</div> | |||
<br> | |||
: ※ '''INI アクセスのための専用メソッド''' については [https://www.haijin-boys.com/discussions 公式フォーラム] 内のトピック『[https://www.haijin-boys.com/discussions/4081 マクロコマンドから「表示」の「色の反転」を取得したい]』で検討・議論されていますので、ご参考までに(セキュリティ上の '''懸念''' により実装は見送りとなっています)。 | |||
<br> | |||
* '''導入事例''' | |||
:*「[[ポップアップメニューで検索先にジャンプ#sukemaru 版|検索ジャンプ]]」「[[ブックマーク一覧ジャンプ#sukemaru 版|ブックマークジャンプ]]」 マクロでは 「行の表示方法」(論理座標/表示座標) の取得に GetIniOption() 関数を利用しています。 | |||
:*「[[ファイルを読み直す・開きなおす|読みなおし]]」 マクロでは、GetIniOption() 関数を大幅に魔改造して 「自動保存」「バックアップ」 関連の設定内容とすべての 「編集モード名」 を取得しています。 | |||
:*「[[コンパクトメニュー]]」 マクロでは GetIniOption() 関数をさらに魔改造して、「最近のファイルの表示数」 「無題タブ用のラベル」 などの値や、「編集モード名」 「マクロ名」 「プラグイン名」 「外部ツール名」 の一覧などを取得しています。 | |||
<br> | |||
* 参照したい値が「数値」や「Ascii文字だけの文字列」であれば、記述が煩雑になる ADODB.Stream や拙作の関数を使わずに、FileSystemObject の <code>OpenTextFile()</code> と <code>ReadAll()</code> メソッドでも問題ありません(値が2バイト文字の場合、文字化けするので FileSystemObject は不適)。 | |||
: なお、Mery.ini の改行コードは CR+LF なので、検索で改行位置を利用する場合は <code>"\r\n"</code> を用います。 | |||
<br> | |||
* 基本的に、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 のショートカットキーは取得できません (キー名が32桁の16進数に符号化されていて「マクロ名」などで検索できないため)。 |
2023年5月17日 (水) 04:41時点における最新版
テキストエディタ Mery の設定ファイル Mery.ini を参照して任意の項目の設定値を取得するための マクロ用組み込みコード です。
複数の項目を配列にして関数に渡す仕様につき Mery.ini へのアクセス(読みこみ)が1回で済むため、多様性に富んだ参照を高速に処理できます。
※ このページのマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。
※ 標準ツールバーのメニューや右クリックメニューのコマンド、ツールバーアイコン、ショートカットキー、他のマクロなどから変更された設定内容(おもにエディタの表示設定)は直ちに Mery.ini に反映されるわけではないので、この組み込み用コードにより取得されたオプション値がエディタの状態どおりではない場合があります。
⇒ Mery ver 3.1.0 以降ではメニュー項目の ✔チェックの ON/OFF 状態もマクロから取得できるようになったようです。
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 オプション項目の「値」を並べた 配列。 * ※ 配列の形式は [ "value1", "value2", "value3" ] * 各要素 value は 数値型(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]]); // 配列の index をふたつずつ指定して「値」を参照 var value1 = iniOption[0][2]; var value2 = iniOption[1][2];
GetIniOption3() 関数では戻り値を オブジェクト型(連想配列) にしてあります。
{section1 : {key1 : value1}, section2 : {key2 : value2} ... } ⇒ value1 = objOptions[section1][key1] または value2 = objOptions.section2.key2
- セクション名とキー名がそのままプロパティ名になるので、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.objOptions.General.HOGE = undefined
- GetIniOption() 関数と GetIniOption2() 関数ではセクション名やキー名の指定が正しくなかったとき、つねに警告ダイアログを表示させる仕様にしてありましたが、GetIniOption3() 関数では第2引数(Bool)に
true
をあたえなかった場合は警告なしで処理を続行します。
※ セクション名に「\
(バックスラッシュ、¥ マーク)」をふくむ項目を指定したときは、戻り値のプロパティ名は ブラケット記法 で記述してください。
- e.g.
[ ["Macros\\Macro0", "FileName"], ["Mode\\Text", "Count"] ]
⇒objOptions["Macros\\Macro0"]["FileName"]
objOptions["Mode\\Text"]["Count"]
- 組み込み関数本体 を任意のマクロのソースコード内にペーストして使用します。
- 使い方は 使用例 を参考にしてください。
- このマクロ関数は Mery.ini の内容を編集(書き換え)するものではありません。
ソースコード[編集]
// #title="Mery.ini のオプション値を取得" /** * 組み込み関数 GetIniOption3( keyArray, boolAlertEnable ) * * 引数で指定した 任意の INI オプション項目名と「値」をプロパティ値として持つ * 入れ子型のオブジェクト を返す * * 第1引数: INI オプション項目(セクション名とキー名)を指定する入れ子型の配列 * ※ 配列の記述形式は [ [ section1, key2 ], [ section2, key2 ] ... ] (※入れ子にする) * * 第2引数: INI オプション項目(セクション名とキー名)の指定ミスがあったときに * 警告ダイアログを表示する/しない をtrue
かfalse
で指定する(省略可) * * 戻り値: 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 ) {
var Fso = new ActiveXObject( "Scripting.FileSystemObject" );
// Mery.ini を探す
var iniPath = editor.FullName.replace( /\.exe$/i, ".ini" );
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 options = {};
var section, key, value, reg, id1, id2, id3, id4;
var iniLength = iniText.length;
for ( var i = 0, len = keyArray.length; i < len; id1 = 0, i ++ ) {
section = keyArray[i][0];
key = keyArray[i][1];
options[ section ] = options[ section ] || {};
// セクション名を検索
reg = new RegExp( "^\\[" + section.replace( /\W/g, "\\$&" ) + "\\]$", "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 ); // ("\n"+"=").length = 2
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 } }" );
}
}
}
return options;
}
// ---------- ▲ 組み込み関数 ココまで ▲ ----------
使い方[編集]
/** * 【使い方】 * * GetIniOption3() 関数の使用は1回で済ませないと * その都度 INI ファイルの読み込み が発生してマクロの処理速度が落ちるので * 取得したい項目すべてをひとつの配列にまとめること * * ※ 要求する項目が1セットの場合も配列を 入れ子 にすること *GetIniOption3( [ [ "SectionName", "KeyName" ] ] );
* * ※ INI のオプション項目名の記述を間違えても警告ダイアログを表示して続行する * 記述ミスをした項目の値 value はundefined
で返される * ※ INI 内でオプションの値が空KeyName=
の場合は、空文字列""
を返す * * ※ 値はすべて "文字列型"(String)で返されるので、 * 必要に応じてNumber( value )
などのかたちで利用すること * * 【注意】 * ※ セクション名にバックスラッシュ「\
」が含まれる場合、 * 戻り値のプロパティ名を指定するさいには ブラケット記法 で記述すること * * e.g.[ "Themes\\Theme0", "Caption" ]
* ⇒objOptions["Themes\\Theme0"]["Caption"]
* (ドット記法でobjOptions.Themes\\Theme0.Caption
とすると エラー になる) */
// ➀ セクション名とキー名をセットにした配列 [ [section1, key2], [section2, key2] ... ]
// セクション名に「\」がある場合は、ふたつ重ね「\\」で記述すること
var keyArray = new Array( // ▼ 戻り値 ▼
[ "General", "LineColumnView" ], // 0 or 1
[ "General", "FileFilter" ], // "*.txt;*ini;*.htm; …"
[ "General", "Untitled" ], // 「無題」の代替値 or ""
[ "Display", "FallbackFonts" ], // フォント名 or ""
// → (~ ver 2.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)
- 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)の使用のみでエディタの表示状態を変更するマクロの例として「折り返しトグル切り替え」などもあります。
- [表示] メニュー内などの各項目の ✔チェックの ON/OFF 状態は Mery.ini から正しく取得できないことがありますが、ver 3.1.0 以降では QueryStatusByID メソッド
editor.QueryStatusByID(id);
を利用することで取得できるようになりました。
- ※ INI アクセスのための専用メソッド については 公式フォーラム 内のトピック『マクロコマンドから「表示」の「色の反転」を取得したい』で検討・議論されていますので、ご参考までに(セキュリティ上の 懸念 により実装は見送りとなっています)。
- 導入事例
- 「検索ジャンプ」「ブックマークジャンプ」 マクロでは 「行の表示方法」(論理座標/表示座標) の取得に GetIniOption() 関数を利用しています。
- 「読みなおし」 マクロでは、GetIniOption() 関数を大幅に魔改造して 「自動保存」「バックアップ」 関連の設定内容とすべての 「編集モード名」 を取得しています。
- 「コンパクトメニュー」 マクロでは GetIniOption() 関数をさらに魔改造して、「最近のファイルの表示数」 「無題タブ用のラベル」 などの値や、「編集モード名」 「マクロ名」 「プラグイン名」 「外部ツール名」 の一覧などを取得しています。
- 参照したい値が「数値」や「Ascii文字だけの文字列」であれば、記述が煩雑になる ADODB.Stream や拙作の関数を使わずに、FileSystemObject の
OpenTextFile()
とReadAll()
メソッドでも問題ありません(値が2バイト文字の場合、文字化けするので FileSystemObject は不適)。
- なお、Mery.ini の改行コードは CR+LF なので、検索で改行位置を利用する場合は
"\r\n"
を用います。
- 基本的に、「編集モード」 「マクロ」 「プラグイン」 「外部ツール」 のショートカットキーは取得できません (キー名が32桁の16進数に符号化されていて「マクロ名」などで検索できないため)。