[詳説]BricsCAD®のDIESEL式
BricsCAD には、初歩的なマクロ拡張機能として、DIESEL というものがあります。Direct Interactively Evaluated String Expression Language の頭文字をとったもので、日本語に直訳すると「直接対話型評価文字列式言語」と言った感じで、四文字熟語ならぬ十三文字熟語のようになってしまいます。
DIESEL は、主にメニューマクロやツールバーマクロで使用されますが、ステータスバーやメニュー表示をカスタマイズするケースでも利用されます。
DIESEL の基本的な考え方はとてもシンプルで "全部文字" ということです。BricsCAD の DIESELインタプリタは、文字列を受け取りそれを処理して文字列を返します。文字列の中で、DIESEL関数として解釈されるように記述された文字列を評価して、それにより返された結果が使用されます。
DIESELの関数とフォーマット
DIESELの関数は27個あり、関数の基本書式は次の通りです。
すべての関数は、次のようにドル記号と括弧、関数名で始まります。
$(fn1
その後に、1つ以上のパラメータが続き、閉じ括弧で閉じられます。
,param1 [ ,param2 .. paramN])
開閉括弧は DIESEL関数の開始と終了を意味します。
DIESEL関数は入れ子にすることができ、内側の関数の結果は、外側の関数のパラメータとして渡されます:$(fOuter$,$(fInner,param2,param3),param1)
注意事項
DIESEL 関数は常に$( で始まります。
Lispと同様に、冒頭の "$(" タグの後の最初の記号は関数として解釈され、次の(およびオプションの)記号は関数のパラメータとなります。
LISPと異なり DIESEL はパラメータはスペースではなく、 ,(コロン)で区切ります。(DIESEL はほとんどの場合、空白を許しません。)
DIESEL で使用できる関数は27個のみです。用意されている関数以外の関数を増やすくとは出来ません。(増やしたくなったらLISPを使い始めるときです。)
メニューとツールバーでDIESELを使う
カスタマイズ(CUI)ファイルのDIESEL式を使ってメニューをカスタマイズすることができます。
メニューで扱うとき、DIESELコードは常に$M=が付きます。
例. 実行中のコマンド名が格納された cmdnames のシステム変数値を取得します。
$M=$(getvar,cmdnames)
ステータスバーでDIESELを使う
MODEMACRO システム変数を使用すると、ステータスバーの左端に情報を表示することができます。MODEMACROシステム変数は、コマンドラインから直接使用するか、設定ダイアログからアクセスします。
例えば、次のテキストをコマンドラインで入力すると、ステータスバーに Hello world と表示されます
:modemacro
:新しい MODEMACRO値, or . =なし<"">: Hello world
DIESEL を使用して、ステータスバーのユーザー領域に表示されるテキストをカスタマイズすることができます。
:modemacro;Dwg=$(getvar,dwgname)
ステータスバーを空白に戻すには、次のように入力します:
:modemacro;""
なお、システム変数MODEMACROの値はセッション間で保存されないので、新しいセッションを開始するとクリアされます。
DIESEL 文字列関数リファレンス
DIESEL関数のリファレンスと記述サンプルです。
$(+,val1,val2, ... valn)
数値 val1、val2、...valn の合計を返します。
コード 戻り値
$(+,1,2,3) => 6
$(+,2,3.4,10,5) => 20.4
$(+,$(getvar,thickness),10) => 15, THICKNESS=5 の時
$(−,val1,val2, ... valn)
val1 から val2 ~ valn を減算した結果を返します。
コード 戻り値
$(-,30,20,4) => 6
$(-,2,3.4,10,5) => -16.4
$(-,$(getvar,thickness),4) => 1、THICKNESS=5 の時
$(*,val1,val2, ... valn)
数値 val1, val2, ...valn を掛け合わせた結果を返します。
コード 戻り値
$(*,30,20,4) => 6
$(*,2,3.4,10,5) => 340
$(*,$(getvar,luprec),10) => 40、LUPREC=4 の時
$(/,val1,val2, ... valn)
数値 val1 を val2、...valn で割った結果を返します。
コード 戻り値
$(/,30,2) => 15
$(/,30,2,3) => 5
$(/,30,2,3,2) => 2.5
$(=,val1,val2)
数値 val1、val2 が等しい場合は 1 を、そうでない場合は 0 を返します。
コード 戻り値
$(=,30,30.0) => 1
$(=,10,9.9999999) => 0
$(=,$(getvar,thickness),5) => 1、THICKNESS=5 のとき
$(<,val1,val2)
数値 val1 が val2 より小さい場合は 1 が、そうでない場合は 0 が返されます。
コード 戻り値
$(<,2,30) => 1
$(<,2,30,3) => $(>,??) error: 2つの引数のみ使用可能
$(<,30,a) => $(>,??) error: 両引数は数値であるべき
$(>,val1,val2)
数値 val1 が val2 より大きい場合は 1、そうでない場合は 0 が返されます。
コード 戻り値
$(>,30,2) => 1
$(>,30,2,3) => $(>,??) error: 2つの引数のみ使用可能
$(>,30,a) => $(>,??) error: 両引数は数値であるべき
$(!=,val1,val2)
数値 val1 と val2 が等しくない場合は 1 が、そうでない場合は 0 が返されます。
コード 戻り値
$(!=,30,30.0) => 0
$(!=,10,9.9999999) => 1
$(!=,$(getvar,thickness),5) => 0 、THICKNESS=5 の時
$(<=,val1,val2)
数値 val1 が val2 以下の場合は 1 、それ以外の場合は 0 が返されます。
コード 戻り値
$(<=,2,30) => 1
$(>=,val1,val2)
数値 val1 が val2 以上の場合は1を、それ以外の場合は 0 を返します。
コード 戻り値
$(>=,2,30) => 0
$(AND,val1,val2, ... valn)
整数 val1 ~ valn のビット単位の論理積を返します。
システム変数 OPMSTATE の理論積の例
$M=$(and,$(>,$(getvar,OPMSTATE),0))
$(EDTIME, time, format-phrase)
指定された書式に基づいてフォーマットされた日付と時刻を返します。time: ユリウス暦の日付を表す実数です。(0を指定すると現在の日時が返されます)
format-phrase:日付と時刻の表示形式を指定します。日付の形式は次の通り
形式 戻り値
D 4
DD 04
DDD Wed
DDDD Wednesday
M 3
MM 03
MON Mar
YY 09
YYYY 2009
H 9
HH 09
MM 37
SS 06
AM/PM AM
a/p a
コード例
コード 戻り値
$(edtime,$(getvar,date),H:MMam/pm) => 09:37am
$(edtime,$(getvar,date),DDD"," DD-MO-YY) => Wed 04-03-09
$(edtime,$(getvar,date),YYYY/MM/DD) => 2023/06/15
$(EQ,val1,val2)
文字列 val1 と val2 が一致する場合は 1 が、そうでない場合は 0 が返されます。
コード例
コード 戻り値
$(eq,30,30.0) => 0 注: $(=,30,30.0) では 1 に評価されます。
$(eq,10,a) => 0
$(eq,ABC,abc) => 0
$(eq,ABC,$(upper,abc)) => 1
$(EVAL,str)
文字列str を DIESEL評価器に渡し、その評価結果を返します。
コード例 : システム変数 users1 に "$(getvar,lastpoint)" がセットされているとします
コード 戻り値
$(eval,users1) => users1
$(eval,$(getvar,users1)) => 420.5,594.4,0.0
$(eval,$(+,1,5)) => 6
$(FIX,value)
実数値の端数を切り捨てて整数にします。
コード例
コード 戻り値
$M=$(FIX,"123.5432") => "123"
$(GETENV, varname)
(OS)環境変数 varname の値を返します。
コード例
コード 戻り値
$(getenv,OS) => Windows_NT
$(getenv,TEMP) => C:\Users\username\AppData\Local\Temp
$(getenv,WINDIR) => C:\Windows
$(getenv,FOO) => 無いものは空文字
$(GETVAR, varname)
システム変数 varname の値を返します。
コード例
コード 戻り値
$(getvar,OSMODE) => 517
$(getvar,PICKSTYLE) => 0
$(getvar,USERS1) => ""
システム変数については、システム変数リファレンスをご確認ください。
$(IF,expr,dotrue,dofalse)
expr が 0 でない場合、dotrue が評価され、そうでない場合は、dofalseが評価されて返されます。Exprで選ばれなかった分岐は評価されないことに注意してください。
コード例
コード 戻り値
$(if,1,TRUE,FALSE) => TRUE
$(if,0,TRUE,FALSE) => FALSE
システム変数 OPMSTATE の値によってプロパティパネルの表示をON/OFF切り替えするマクロ
$M=$(if,$(and,$(>,$(getvar,OPMSTATE),0)),^c^c_propertiesclose,^c^c_properties)
$(INDEX,which,string)
文字列は、マクロ引数の区切り文字であるカンマで区切られた1つ以上の値を含むと仮定します。 これは、これらの値のうち1つを選択して抽出し、最初の項目は0番とします。
コード例
システム変数 lastpoint の値が 420.5,594.4,0.0 だった時
コード 戻り値
$(index,0,$(getvar,lastpoint)) => 420.5
$(index,1,$(getvar,lastpoint)) => 594.4
$(index,2,$(getvar,lastpoint)) => 0.0
$(NTH,which,arg0,arg1,argN)
whichで選択された引数を評価し、返します。whichが 0 の場合、arg0 が返され、以下同様です。$(NTH) と $(INDEX) の違いに注意してください。$(NTH) は関数に渡された一連の引数のうちの一つを返すのに対し、$(INDEX) は一つの引数として渡されたカンマ区切りの文字列から値を抽出します。
コード例
コード 戻り値
$(nth,0,eni,meni,mini,mo) => eni
$(nth,1,eni,meni,mini,mo) => meni
$(nth,3,eni,meni,mini,mo) => mo
$(nth,3,$(+,100,0),$(+,100,1),$(+,100,2),$(+,100,3)) => 103
$(OR,val1,val2, ... valn)
整数 val1 から valn のビットごとの論理和を返します。
コード例
コード 戻り値
$(or,101,110) => 111
$(or,100,101,110) => 111
$(or,100,010,001) => 111
$(or,10111011,00000100) => 10111111
$(or,000,100,101,110) => 111
$(STRFILL,string,ncopies)
n コピーした文字列を連結した結果を返します。
コード例
コード 戻り値
$(strfill,TA,2) => TATA
$(strfill,#,3) => ###
$(strfill,|xx,3)| => |xx|xx|xx|
$(STRLEN,string)
文字列の長さを文字数で返します。
コード例
コード 戻り値
$(strlen,Mary had a little lamb) => 22
$(strlen,Mary had a little lamb.) => 23
$(strlen,ベルギーワッフル) => 8
$(SUBSTR,string,start,length)
文字列の先頭の文字から長さ分の文字列を返します。lengthが省略された場合は、文字列の残りの長さ全体が返されます。
コード例
コード 戻り値
$(substr,Mary had a little lamb.,1,8) => Mary had
$(substr,Mary had a little lamb.,19,23) => lamb.
$(substr,ベルギーワッフル,1,4) => ベルギー
$(substr,ベルギーワッフル,5) => ワッフル
$(TIME)
1970年1月1日からの経過秒数で、現在の時刻をUnix方式で返します。
コード例
コード 戻り値
$(TIME) => 1686707432
$(UPPER,string)
文字列は、現在のロケール規則に従って大文字に変換されて返されます。
コード例
コード 戻り値
$(upper,Mary had a little lamb) => MARY HAD A LITTLE LAMB
$(upper,fOo BaR) => FOO BAR
$(upper,おはょう。-Good morning) => おはょう。-GOOD MORNING
$(XOR,val1,val2, ... valn)
整数 val1 から valn のビットごとの論理 XOR を返します。
コード例
コード 戻り値
$(xor,101,110) => 11
$(xor,100,101) => 1
$(xor,100,010,001) => 111
$(xor,000,100,101,110) => 111
SETENV コマンドについて
AutoCAD LTでメニューカスタマイズをされている場合、「$(GETENV) の関数と対で使われる SETENV コマンドはあるの?」という点が気になるかと思いますが、BricsCAD は 標準で SETENV コマンドを搭載していません。
しかしこれについては、BricsCAD の拡張性を活用して SETENVコマンドを追加してしまうことで解決出来ます。コマンドは LISP のプログラムを作成してロードすることで簡単に追加できますが、既に作成・公開されているものがありますので紹介いたします。
使い方はリンク先のサイトに記載されていますのでご覧ください。
DIESEL関数の遅延評価について
ほぼ日本のみでしか使われていない Hack的なテクニックとして、AutoCAD LT において値の反映が行われずに処理が進んでしまう事を回避するためにDIESEL式を文字評価させることで遅延評価の効果を期待する(下記のような記述)というものがありますが、このテクニックは BricsCAD では利用できません。
$M="$(getenv,幅)"
$M="""(getenv,幅)"""
$M="""""""(getenv,幅)"""""""
このような形で記述されたものは、まず、文字渡しを除去して通常のDIESEL関数として動作するか確認してください。(上記の例でいうと、$M=$(getenv,幅) に変更するということです)
変更後でもうまく動かないようであれば、LISP に移植することを検討してください。
BricsCADは、Lite のレベルから性能のいい LISP言語を使うことが出来ます。DIESEL式を駆使した長いマクロによるカスタマイズは、エラー処理がない、値のチェックが出来ない、高度な分岐処理が出来ない、PCの性能・環境によって動きが変わってしまうなど、図面作成の生産性を高めるにはネックになる点がありますので、他のCADから移行される場合は、タイミングを見て比較的簡単に使えるLISP言語への移植をおすすめします。
LISPの中でDIESELを使う
通常のインターフェスのコマンドでDIESEL式を使用するのとは別に、LISP にてDIESELと連携した利用をすることができます:
modemacroを使用する
LISP の SetVar 関数で MODEMACROシステム変数にDIESELで取得した値を表示する例
(setvar "modemacro" "Tilemode= $(getvar,tilemode)")MenuCmdを使う
LISP の MenuCmd関数とM=メニューマクロを併用することで、メニューをカスタマイズすることができます。
(menucmd "M=Tilemode= $(getvar,tilemode)")コマンドラインDIESEL評価器を作成する。
通常 DIESEL をコマンドラインで直接評価することはできませんが、以下の Lispルーチンを使用することでコマンドラインでの評価をエミュレートします。
この関数では上記と同様に (menucmd m=) を使って評価を行います
;command line DIESEL evaluator
;found @ http://www.crlf.de/Dokumente/Diesel/Diesel.html
(defun c:DIESEL (/ s)
(while (/= "" (setq s (getstring T "\nDIESEL: ")))
(princ (menucmd (strcat "m=" s)))
)
(princ)
)
使用例:
DIESEL[enter]
DIESEL: $(>,100,100.0)
0
開発向けのドキュメント
本記事の内容は、メニューや開発言語を使用したカスタマイズに必要なドキュメントとして用意されている、「デベロッパーリファレンス」の内容を日本向けにアレンジ訳したものです。システム変数リファレンスやこの記事と合わせてご利用ください。
以上、BricsCAD のメニューカスタマイズで使用できる DIESEL式について一通りまとめてみました。なにか気になることがあればコメント欄からの質問もしていただけます。
では、良いCADライフを!👍
#CAD #BricsCAD #AutoCAD #メニューカスタマイズ #DIESEL #MNU #MNS #CUI #CUIX