Luaレッスン22「(3.2)独自の数式ボックスを作成する」和訳

出典:http://compasstech.com.au/TNS_Authoring/Scripting/script_tut22.html

レッスン22「(3.2)独自の数式ボックスを作成する」

 2D Editorは、テキスト・ベースの面白い処理もいろいろできますが、その本領を発揮するのは、数式、化学式の入力と表示が簡単にできることであると思います。 

  1. MathBox、ChemBoxを設定する

まず、前回とまったく同じスクリプトから開始します。アクティブなテキスト・ボックスを作成し、"input"という名前のTI-Nspire変数に何らかのテキストを代入するスクリプトでした。

しかし今回は、TextBox1:createMathBox(またはTextBox1:createChemBox())というコマンドを1つだけ追加ししてください。これでマジックの完成です。

カーソルの点滅した状態で、数式ボックスまたは化学式ボックスがユーザーからの入力を待っています。

f:id:ti-nspire:20141210105708j:plain

f:id:ti-nspire:20141210105730j:plain

化学式ボックスは基本的には表示機能しかありません(もちろんそれも素晴らしい機能です)。しかし数式ボックスはライブ・ボックスであり、十分な機能性を備えてい、有効なコマンドを入力してenterを押せば、Notesとまったく同じように計算してくれます。

platform.apilevel = "2.0"

function on.construction()

     timer.start(0.4)

     TextBox1 = D2Editor.newRichText()

end

function on.resize()

     W = platform.window:width()

     H = platform.window:height()

     TextBox1:move(W*0.05, H*0.5)

     TextBox1:resize(W*0.9,H*0.4)

     TextBox1:createMathBox()

     fontSize = math.floor(W/32)

     fontSize = fontSize > 6 and fontSize or 7

     TextBox1:setFontSize(fontSize)

     TextBox1:setBorderColor(500)

     TextBox1:setBorder(1)

     TextBox1:setTextColor(200*200*200)

     TextBox1:setFocus(true)

end

function on.getFocus()

     TextBox1:setFocus()

end

function on.timer()

     cursor.show()

     Input = TextBox1:getExpression()

     if Input then

          var.store("input", Input)

     end

     platform.window:invalidate()

end

function on.escapeKey()

     TextBox1:setExpression(" ")

     platform.window:invalidate()

end

 

  1. 数式ボックスで遊ぶ

それぞれの出力をよく見てください。結果は、単純なコード・レイヤーの中にラップされています。MathBoxの場合は"\\0el {"と自分で入力した内容と"}"とが出力されます。ChemBoxの場合は、もっと単純に、"\\chem {"と自分で入力した内容と"}"とが出力されます。

ちょっと待った。スクリーン・ショットには"\"が1つしか表示されていませんよ、"\"は、Luaの予約文字であるため、"\"を認識させるためには、"\"をもう1つ余計に追加してエスケープする必要があるのです(以前お話ししましたよね?)

さて、課題です。もう一度、前回のレッスンと同じようにテキスト・ボックスを2つ作ってください。今回は、TextBox 1に入力された内容を計算し、その結果を2つ目のテキスト・ボックスに表示させます(もちろん正しい答を表示させます)

そのためにどのような処理が必要なのかを考えてから、次のセクションに移動してください。TextBox1から式を取得する必要があります。その方法はわかりますね。

f:id:ti-nspire:20141210105804j:plain

この式は、計算する必要がありますので、レッスン17およびmath.evalコマンドのことを思い出してください。しかし今回の出力は、単なる文字列ではなく、分数または代数形式になりそうです。そのため、バージョン3.2の新コマンドであるmath.evalStrが必要です。

しかしちょっと待った。入力は、例の奇妙なレイヤーにラップされています。TI-Nspireは、そのようにラップされたものが計算できません。そこで、ラップをはぎ取る必要があります。その手段として、unprettyという名前のちょっと巧みな函数を定義します。

ラップをはぎ取り、Nspireで計算し、Outputという名前の変数を生成してください。

結果は、TextBox2に表示するとします。TextBox2:setExpressionコマンドが使えます。簡単ですね。

結果をMathBoxに表示し、かつその結果をMathBox内で正しく書式設定したい場合は、その前後を前述のレイヤーでラップすれば良いだけです。巧みな方法ですね。

 今回の例もやはり、多くのさまざまな用途が考えられます。

たとえば、上段のテキスト・ボックスに問題を表示し、その答を正しい書式設定で生徒に下段に入力させるということが可能です。

TI-Nspireベースの電卓をLuaで作成し、生徒の学習の手段として自分なりの発想をプロトタイピングしながら、計算結果をさまざまに処理してみることができます。

function unpretty(input)

     input = input:gsub("\\0el {", "")

     input = input:gsub("}", "")

     input = input:gsub(" ", "") or ""

     return input

end

function on.timer()

     cursor.show()

     Input = TextBox1:getExpression()

     if Input then

          Output = math.evalStr(unpretty(Input))

               if Output then

                    TextBox2:setExpression("\\0el {"..Output.."}")

               end

     end

     platform.window:invalidate()

end

何を行う場合でも、paintコマンドと文字列とを使って分数や代数のレイアウトを独自に設定する大変な手間に比べたら、ずいぶん簡単な方法に思えます。存分に楽しんでください。

次回から始まる最後の一連のレッスンでは、Nspire Lua物理エンジンについて紹介します。