top > 色分け リファレンス

色分け リファレンス

contents

萌ディタでの色分け

萌ディタの色分けは、複数の言語を同時に扱うことができます。また、言語の中の状態(コメントの中であるとか、ブロックの中であるとか)を認識して、それぞれの状態に応じた色分けをすることもできます。色分けのルールはスクリプト内で、正規表現を用いて指定します。

色分けの例この例では、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'、'>' というトークンを連続的に入力したときに(実際は languagetype の属性も見ます)解析器を変更するルールを追加することになります。解析器の変更は、合致した文字列に適用するスタイルに解析器を変更する指令を含めることで行います。

字句解析器内の状態の遷移

ある 1 つの字句解析器の中でも、複数の状態を取りえることがあります。たとえば、プログラム言語とそのコメント文は 1 つの言語の中に文法がまとめられていますが、字句解析の実際は異なるルールで行われることが多いです。このとき、1 つの字句解析器の内部においても、「通常の解析中」「コメントの解析中」と状態の区別をする必要があります。

また、html では 'abbr' というのは要素名にも属性名にも存在する識別子ですが、要素か属性名かを色分けで区別するには、'abbr' という識別子が '<' の直後かどうか、という状態を解析器が認識できなければなりません。

萌ディタの字句解析器は、1 から 30 までの状態を取ることができ、特定のルールにマッチしたタイミングで状態を遷移することができます。html のタグ内部の状態遷移図を考えた場合、

タグの状態遷移図

トークントークンを受け付ける状態の番号遷移先の状態の番号導かれるパターン導かれるスタイル
<121/</state:2
要素名232/要素名/state:3
属性名3、443,4/属性名/state:4
=454/=/state:5
"〜"535/"〜"/state:3
>2、3、4、562..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 の数値。

値の設定時に限り、文字列での指定が可能です。

"1"状態 1 に対して設定
"2,3"状態 2、3 に対して設定
"4..8"状態 4 から 8 に対して設定
"9..10,19..30"状態 9 から 10、および 19 から 30 に対して設定

字句解析器へのルールの追加

    lex.Add(
        'test-rule1',       // このルールの名前
        '/ここを強調/',     // パターン
        'color:red'         // スタイル
    );
    lex.Add(
        'test-rule2',       // このルールの名前
        '/ここを強調だよ/', // パターン
        'color:red'         // スタイル
    );

字句解析器にルールを追加します。ルールは、その名称、パターン、スタイルがセットになっています。パターンは必ず '/' で挟みます。

字句解析器 Lex の Add() メソッドの引数は、以下の仕様です。

名称ルールの名称は文字列で、[-a-z0-9_]+ でなければいけません。
パターン

パターンは文字列で、状態のリストopt / パターン本体 / 照合フラグopt に分けられます。

状態のリストは、このパターンがどの状態のときに照合されるかを指定するもので、1 から 30 の数値で指定します。省略、または複数の指定が可能です。

/pattern/どの状態のときも照合
1/pattern/状態 1 のとき照合
2,3/pattern/状態 2、3 のとき照合
4..8/pattern/状態 4 から 8 のとき照合
9..10,19..30/pattern/状態 9 から 10、および 19 から 30 のとき照合

パターン本体は、実際に照合を行う正規表現を記述します。ただし、'/' はパターンのデリミタなので、エスケープする必要があります。さらに、javascript が文字列を解析する分も含めて、エスケープは二重にしなければいけません(すごくまぎらわしいです)。

正規表現エンジンに渡したい文字列javascript 上の表記
/\\/
\\"\\\\"(文字列をシングルクォートで囲った場合)
/*\\/\\*
*/\\*\\//

照合フラグは、いまのところ 1 つだけです。省略が可能です。

i照合の際、大文字・小文字の区別をしません
スタイル

スタイルは文字列で、スタイル指定子 ( ; スタイル指定子 )* です。以下のスタイル指定子を任意の数指定できます。指定子の間は ';' で区切ります。同じ指定子を複数書いた場合、あとに指定したものが有効です。

color

前景色を指定します。

color:red のように ':' に続けて色名を指定します。指定しない場合は、デフォルトの前景色が用いられます。

background-color

背景色を指定します。

background-color:white のように ':' に続けて色名を指定します。指定しない場合は、デフォルトの背景色が用いられます。

decoration

装飾を指定します。

decoration:underline のように ':' に続けて識別子を指定します。指定しない場合は、装飾なしです。識別子は以下のとおり。

underline前景色で下線をひきます。
upperline前景色で上線をひきます。
strikethrough前景色で中線をひきます。
none装飾なし。
font

文字の形体を指定します。

font:italic のように ':' に続けて識別子を指定します。',' で繋げて複数指定することができます。指定しない場合は、いずれの形体も指定されません。識別子は以下のとおり。

bold太字にします。
italic斜体にします。
transit

解析器の遷移を指定します。

transit:html-lex のように ':' に続けて字句解析器名を指定します。

字句解析器名に続けて ':' および数値を指定することができます。これは、遷移先解析器の初期状態を指定します。

字句解析器名の代わりに '*return*' を指定することができます。これは、直前の解析器に遷移します。

state

状態の遷移を指定します。

state:2 のように ':' に続けて遷移する状態の番号を指定します。また符号を明示することで、現在の状態から相対的に移動することができます(なにげに重要です)。

no-style

視覚的な指定がないことを指定します。追加の値はありません。

これは常に、transit か state の指定と組み合わせて使います。あるルールに合致した場合、段落中の文字の着目点は合致した文字列の長さ分だけ進みますが、スタイルに color/background-color/decoration を指定しない場合は進みません。これは、遷移が発生するパターンに対する色づけを遷移先のルールで行えるようにするためです。

no-style はそれを抑制し、

  • 合致したパターンにデフォルトのスタイルを適用する
  • 段落中の文字の着目点を、合致した文字列の長さ分進める

動作を行います。

exstyle

適用するスタイルをテーマから参照することを指定します。

exstyle:コメント文 のように ':' に続けて外部スタイル名を指定します。外部スタイル名は、';' を含まない任意の文字列です。この外部スタイルは GUI で編集することができます。

ルールの追加には、この他 AddKeywords メソッドを使用することもできます。このメソッドの場合、パターン本体の書式は正規表現ではなく、スペースで区切ったキーワード群(U+007f までの文字を使った文字列)になります。正規表現に比べて、照合が軽くなるというメリットがあります。

色の指定

色の指定には、以下の方法があります。

基本 16 色

16 個の色名を直接指定します。

white
#ffffff
silver
#c0c0c0
red
#ff0000
yellow
#ffff00
lime
#00ff00
aqua
#00ffff
blue
#0000ff
fuchsia
#ff00ff
black
#000000
gray
#808080
maroon
#800000
olive
#808000
green
#008000
teal
#008080
navy
#000080
purple
#800080
システムカラー

システムに定義済みの色を指定します。

activeborder
アクティブなウィンドウの枠

inactivecaptiontext
非アクティブウィンドウのタイトルバーテキスト

activecaption
アクティブなウィンドウのタイトルバー

infobackground
ツールチップの背景

appworkspace
アプリケーション内のウィンドウの背景

infotext
ツールチップのテキスト

background
デスクトップの背景

menu
メニューの背景

buttonface
立体的なボタンの表面

menutext
メニューのテキスト

buttonhighlight
立体的なボタンの光の当たっている面

scrollbar
スクロールバー

buttonshadow
立体的なボタンの影になってる面

threeddarkshadow
立体的に表示される部分の­暗い影

buttontext
立体的なボタンのテキスト

threedface
立体的に表示される部分の­表面

captiontext
タイトルバーのテキスト

threedhighlight
立体的に表示される部分の­光の当たっている面

graytext
選択できないテキスト

threedlightshadow
立体的に表示される部分の­明るい影

highlight
選択している状態

threedshadow
立体的に表示される部分の­影

highlighttext
選択しているテキスト

window
ウィンドウ

inactiveborder
非アクティブウィンドウの枠

windowframe
ウィンドウのフレーム

inactivecaption
非アクティブウィンドウのタイトルバー

windowtext
ウィンドウのテキスト

16 進での指定

16 進数で指定します。#rgb、#rrggbb の 2 とおりの指定が可能です。

カラーテーマ

萌ディタに表示する要素に対する色の定義、および字句解析器に対するスタイルの定義はそれぞれひとまとめにして扱うことができます。ひとまとめにしたものをカラーテーマといいます。

拡張子クラスのカラーテーマ

萌ディタに表示する以下の要素は、自由に色を割り当てることができます。

文字の色
背景の色
行番号の色
行番号領域の背景の色
行番号との区切り線の色
現在行のガイドの色
現在行のガイドの色(IME ON 時)
ビュー情報の区切り線の色
ビュー情報のファイル名の色
EOF マークの色
EOF 行のガイドの色
タブの色
改行マークの色
折り返し位置の区切り線の色
マークの色
空白文字の色
特殊な空白文字の色
漢字の空白文字の色
アクセス禁止領域の色

どの ini ファイルを参照するかは、プロパティ color-theme に設定します。カラーテーマは、萌ディタの実行中にメニューから変更できます。カラーテーマを変更すると、テーマカラーを指定している要素の色が置き換わります。

字句解析器のカラーテーマ

字句解析器に登録したルールのスタイルで 'exstyle' 句を使用した場合、ini ファイルに対して定義されたスタイルの実体を参照するようになります。

カラーテーマファイル

カラーテーマの定義は、専用の ini ファイルに対して行い、

に置いておきます。

カラーテーマを選択する

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

テーマの裏、表

クラス、字句解析器の両方とも、カラーテーマに裏、表の概念があります。

表は、白い背景を前提とした色の定義。裏は、黒い背景を前提とした色の定義です。この別は、プロパティ theme-side に保持され、拡張子クラスのテーマ、字句解析器のテーマの両方が影響を受けます。

プロパティ theme-side はメニューから切り替えることができます。


更新履歴


top > 色分け リファレンス