Blocklyによるビジュアルプログラミング環境でのPython出力
Googleが提供するオープンソースのビジュアルプログラミングライブラリであるBlocklyは、ドラッグアンドドロップ型のブロックを使ってプログラムを構築できるだけでなく、そのブロック構造を複数のテキスト言語に変換することが可能です。本記事では、特にPythonへのリアルタイムコード変換機能の実装について解説します。
必要なスクリプトの読み込み
Pythonコードの生成を行うには、まず対応するコンパイラモジュールをHTML内に追加する必要があります。以下の順序でJavaScriptファイルを読み込みます。
<script src="./blockly/blockly_compressed.js"></script>
<script src="./blockly/blocks_compressed.js"></script>
<script src="./blockly/python_compressed.js"></script>
重要なのは、python_compressed.jsがblockly_compressed.jsの後に読み込まれることです。この依存関係が正しくないと、コード生成機能が動作しません。
コード生成処理の実行
ワークスペース内のブロック構成からPythonコードを生成するには、以下の一行を使用します。
const generatedCode = Blockly.Python.workspaceToCode(workspaceInstance);
ここでworkspaceInstanceはBlockly.inject()によって作成されたワークスペースオブジェクトです。無限ループ防止用のトラップコードを無効化したい場合は、事前に以下を設定します。
Blockly.Python.INFINITE_LOOP_TRAP = null;
リアルタイムプレビューの実装
ユーザー操作に応じて即座にコードを更新するためには、イベントリスナーを利用します。
function updatePreview() {
const pythonCode = Blockly.Python.workspaceToCode(workspaceInstance);
document.getElementById('code-output').textContent = pythonCode;
}
workspaceInstance.addChangeListener(updatePreview);
これにより、ブロックの追加・削除・接続の変更が発生するたびにupdatePreview関数が呼び出され、生成されたPythonコードが表示エリアに反映されます。
シンタックスハイライトの統合
出力されたコードを視覚的に見やすくするために、Highlight.jsを組み込む例を示します。
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/styles/default.min.css">
<script src="https://cdn.jsdelivr.net/gh/highlightjs/cdn-release@11.7.0/build/highlight.js"></script>
<script>
document.addEventListener('DOMContentLoaded', () => {
hljs.highlightAll();
});
</script>
コード表示後、hljs.highlightElement()を呼び出すことで、構文に応じた色分けが適用されます。
多言語対応の準備
日本語などの非英語UIに対応させるには、メッセージファイルを読み込み、カテゴリ名を動的に置換する処理が必要です。
let toolboxXml = document.getElementById('toolbox');
let localizedXml = toolboxXml.outerHTML.replace(/{(\w+)}/g, (match, key) => MSG[key] || match);
let domTree = Blockly.Xml.textToDom(localizedXml);
この処理により、%{BKY_CATLOGIC}のようなキーが翻訳済み文字列に置き換わり、日本語メニューが表示されます。
基本的なワークスペースの初期化
最後に、全体の初期化コードの骨格を示します。
const workspaceOptions = {
toolbox: domTree,
grid: {
spacing: 25,
length: 3,
colour: '#ddd',
snap: true
},
zoom: {
controls: true,
wheel: true,
maxScale: 3,
minScale: 0.5
},
trashcan: true,
media: './blockly/media/'
};
const workspaceInstance = Blockly.inject('blocklyDiv', workspaceOptions);
workspaceInstance.addChangeListener(updatePreview);
このようにして、ブロックエディタと同期してPythonコードをリアルタイムで生成・表示するWebアプリケーションを構築できます。