top > 色分け リファレンス
萌ディタの色分けは、複数の言語を同時に扱うことができます。また、言語の中の状態(コメントの中であるとか、ブロックの中であるとか)を認識して、それぞれの状態に応じた色分けをすることもできます。色分けのルールはスクリプト内で、正規表現を用いて指定します。
この例では、html の部分と javascript の部分を異なる言語として扱い、それぞれにふさわしい色分けをしています。javascript 内で html のタグを書いても、html 内で javascript のコードを書いても、誤認識せず色分けしています。
色分けの定義は、スクリプトに公開された Lex 字句解析器オブジェクトに対してルールを追加していくことで行います。Lex オブジェクトは App.Lexes 字句解析器コレクションの要素です。この字句解析器に対して追加(Add())したり、既存の解析器を参照(Item())することで字句解析器の機能を呼び出します。
字句解析器は段落(改行までの 1 行。折り返し行 1 行ではありません)ごとに文字列を走査し、定義されたパターンを見つけると、パターンにひもづくスタイルを割り当てます。どのパターンにも合致しない文字列は、デフォルトのスタイル(これも解析器にあからじめ設定しておきます)を割り当てます。
この解析器に 2 つのパターンが定義されているとき、このように動作します。
段 落 中 の こ こ を 強 調 し ま す 。
^
ここを強調 (マッチ失敗)
ここを強調だよ(マッチ失敗)
「段」を開始位置として、定義された 2 つのパターンが合致するか調べます。マッチの順番は、定義された順に従います。どちらも合致しないので、「段」はデフォルトの色で表示します。
段 落 中 の こ こ を 強 調 し ま す 。
^
ここを強調 (マッチ成功)
ここを強調だよ(マッチ失敗)
↓
段 落 中 の こ こ を 強 調 し ま す 。
^
ここを強調 (マッチ成功)
ここを強調だよ(マッチ失敗)
ここで、最初に定義したパターンが合致しました。パターンが 1 つでも合致したら、照合の開始位置は合致した文字数だけ大きく進みます。ここで、残りのパターンは照合されません。そのため、先頭に共通した部分を含むパターンは長いほうから定義するか、正規表現 '|' で並列に指定する必要があります(正規表現での照合はより長く合致したものを返すからです)。
このあと「します。」をデフォルトのスタイルと認識して、色分けが完了します。
App.Lexes はコレクションなので、複数の解析器を追加できます。そして色分けの処理は、テキストの解析中に特定の状態になったとき、用いる解析器を取り替える仕組みを持ちます。これにより、複数の言語を同時に解析することを実現しています。
たとえば html では、<script> 〜 </script> で挟まれた部分はスクリプトとして扱われます。このときのスクリプトは、html に対する字句解析器では正しく色分けをすることができません。正しく色分けするには、script 要素内だけは字句解析器をスクリプト用のそれに切り替える必要があります。
具体的には、字句解析器が '<'、'script'、'>' というトークンを連続的に入力したときに(実際は language や type の属性も見ます)解析器を変更するルールを追加することになります。解析器の変更は、合致した文字列に適用するスタイルに解析器を変更する指令を含めることで行います。
ある 1 つの字句解析器の中でも、複数の状態を取りえることがあります。たとえば、プログラム言語とそのコメント文は 1 つの言語の中に文法がまとめられていますが、字句解析の実際は異なるルールで行われることが多いです。このとき、1 つの字句解析器の内部においても、「通常の解析中」「コメントの解析中」と状態の区別をする必要があります。
また、html では 'abbr' というのは要素名にも属性名にも存在する識別子ですが、要素か属性名かを色分けで区別するには、'abbr' という識別子が '<' の直後かどうか、という状態を解析器が認識できなければなりません。
萌ディタの字句解析器は、1 から 30 までの状態を取ることができ、特定のルールにマッチしたタイミングで状態を遷移することができます。html のタグ内部の状態遷移図を考えた場合、

| トークン | トークンを受け付ける状態の番号 | 遷移先の状態の番号 | 導かれるパターン | 導かれるスタイル |
|---|---|---|---|---|
| < | 1 | 2 | 1/</ | state:2 |
| 要素名 | 2 | 3 | 2/要素名/ | state:3 |
| 属性名 | 3、4 | 4 | 3,4/属性名/ | state:4 |
| = | 4 | 5 | 4/=/ | state:5 |
| "〜" | 5 | 3 | 5/"〜"/ | state:3 |
| > | 2、3、4、5 | 6 | 2..5/>/ | state:6 または他の解析器に遷移 |
となります。あるトークンを受け付ける状態と、受け付けた後に遷移する遷移先の状態のセットが導かれるわけです。「遷移してくる状態」のそれぞれで「入力文字」が合致するか調べ、合致したら「遷移先の状態」へ移ることになります。字句解析器に追加するルールもこの、「トークンを受け付ける状態」「トークン」「受け付けたトークンに対するスタイル」「受け付けた後の遷移先状態」をセットにした形式をとります。
字句解析器への定義は、以下のとおりです。これらのスクリプトは、拡張子クラスの onInitProp イベントハンドラ内に記述します。
f.onInitProp = function (arg, classname, methodname) {
var lex = App.Lexes.Add('test');
App.Prop(this.name, 'lex') = lex.name;
lex.DefaultStyle(1) = 'color:gray';
lex.Add(
'test-rule1', // このルールの名前
'/ここを強調/', // パターン
'color:red' // スタイル
);
lex.Add(
'test-rule2', // このルールの名前
'/ここを強調だよ/', // パターン
'color:red' // スタイル
);
}
var lex = App.Lexes.Add('test');
これで、字句解析器のコレクションに新しい解析器を追加し、変数 lex に格納しています。このときつけた名前で、あとから App.Lexes.Item('test') として参照もできます(いまのところ、あとから参照したからといってどうなるものでもないけど)。
App.Prop(this.name, 'lex') = lex.Name;
拡張子クラスのトップレベルの解析器として指定します。テキスト先頭からの走査は、トップレベルの解析器を用いて行います。トップレベルとは、「スクリプトを含んだ html」の html など、テキストが依存する言語のなかで代表となるもののことをいいます。
字句解析器コレクション Lexes の Add() メソッドの引数は、以下の仕様です。
| 名称 | 字句解析器の名称は文字列で、[-a-z0-9_]+ でなければいけません。 |
|---|
lex.DefaultStyle(1) = 'color:gray';
デフォルトのスタイルを必要なら指定しておきます。定義したどのルールにも合致しない文字は、このスタイルで表示されます。引数はどちらも反映させる状態の番号です。
DefaultStyle() プロパティの引数は、以下の仕様です。
| 状態 | 1 から 30 の数値。
値の設定時に限り、文字列での指定が可能です。
|
|---|
lex.Add(
'test-rule1', // このルールの名前
'/ここを強調/', // パターン
'color:red' // スタイル
);
lex.Add(
'test-rule2', // このルールの名前
'/ここを強調だよ/', // パターン
'color:red' // スタイル
);
字句解析器にルールを追加します。ルールは、その名称、パターン、スタイルがセットになっています。パターンは必ず '/' で挟みます。
字句解析器 Lex の Add() メソッドの引数は、以下の仕様です。
| 名称 | ルールの名称は文字列で、[-a-z0-9_]+ でなければいけません。 | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| パターン | パターンは文字列で、状態のリストopt / パターン本体 / 照合フラグopt に分けられます。 状態のリストは、このパターンがどの状態のときに照合されるかを指定するもので、1 から 30 の数値で指定します。省略、または複数の指定が可能です。
パターン本体は、実際に照合を行う正規表現を記述します。ただし、'/' はパターンのデリミタなので、エスケープする必要があります。さらに、javascript が文字列を解析する分も含めて、エスケープは二重にしなければいけません(すごくまぎらわしいです)。
照合フラグは、いまのところ 1 つだけです。省略が可能です。
|
||||||||||||||||||||||||||||
| スタイル | スタイルは文字列で、スタイル指定子 ( ; スタイル指定子 )* です。以下のスタイル指定子を任意の数指定できます。指定子の間は ';' で区切ります。同じ指定子を複数書いた場合、あとに指定したものが有効です。
|
ルールの追加には、この他 AddKeywords メソッドを使用することもできます。このメソッドの場合、パターン本体の書式は正規表現ではなく、スペースで区切ったキーワード群(U+007f までの文字を使った文字列)になります。正規表現に比べて、照合が軽くなるというメリットがあります。
色の指定には、以下の方法があります。
| 基本 16 色 | 16 個の色名を直接指定します。
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| システムカラー | システムに定義済みの色を指定します。
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| 16 進での指定 | 16 進数で指定します。#rgb、#rrggbb の 2 とおりの指定が可能です。 |
萌ディタに表示する要素に対する色の定義、および字句解析器に対するスタイルの定義はそれぞれひとまとめにして扱うことができます。ひとまとめにしたものをカラーテーマといいます。
萌ディタに表示する以下の要素は、自由に色を割り当てることができます。
| 文字の色 |
| 背景の色 |
| 行番号の色 |
| 行番号領域の背景の色 |
| 行番号との区切り線の色 |
| 現在行のガイドの色 |
| 現在行のガイドの色(IME ON 時) |
| ビュー情報の区切り線の色 |
| ビュー情報のファイル名の色 |
| EOF マークの色 |
| EOF 行のガイドの色 |
| タブの色 |
| 改行マークの色 |
| 折り返し位置の区切り線の色 |
| マークの色 |
| 空白文字の色 |
| 特殊な空白文字の色 |
| 漢字の空白文字の色 |
| アクセス禁止領域の色 |
どの ini ファイルを参照するかは、プロパティ color-theme に設定します。カラーテーマは、萌ディタの実行中にメニューから変更できます。カラーテーマを変更すると、テーマカラーを指定している要素の色が置き換わります。
字句解析器に登録したルールのスタイルで 'exstyle' 句を使用した場合、ini ファイルに対して定義されたスタイルの実体を参照するようになります。

カラーテーマの定義は、専用の ini ファイルに対して行い、
に置いておきます。
theme ディレクトリの下に置いた ini ファイルは、メニューから選択して実行時に適用することができます。字句解析器に対するカラーテーマは、今のところ任意の選択をすることはできません(要望次第)。

クラス、字句解析器の両方とも、カラーテーマに裏、表の概念があります。
表は、白い背景を前提とした色の定義。裏は、黒い背景を前提とした色の定義です。この別は、プロパティ theme-side に保持され、拡張子クラスのテーマ、字句解析器のテーマの両方が影響を受けます。
プロパティ theme-side はメニューから切り替えることができます。
top > 色分け リファレンス