Blockly 的自定义语言生成器

Custom language generator to Blockly

我知道我可以使用

Blockly.JavaScript['my_code'] = function() {  ... }

但是如何添加其他语言支持,例如 JSON? 我试过了..

Blockly.Json['my_code'] = function() {  ... }

当我尝试恢复时它失败了

Blockly.Json.workspaceToCode(this.workspace)

workspaceToCode 不是函数。

我需要向 Blockly 添加新语言

I will not display this new language (JSON), it will just be used to send instructions to the robots.


我尝试

Blockly.Json = new Blockly.Generator('Json');
Blockly.Json['my_code'] = function() {  ... }

但是

出现错误
Blockly.Json.workspaceToCode(this.workspace)

错误..

Uncaught TypeError: this.init is not a function
    at js.ou3v.module.exports.Blockly.Generator.workspaceToCode

为 Blockly 创建一个新的语言生成器是一项相当大的工程,考虑到这一点,文档似乎并没有提供太多创建语言生成器的帮助。

根据我的经验,构建生成器的最佳方法是查看 generators/, I have used the JavaScript 生成器中的现有生成器,作为我想要生成 C++ 代码的项目的模板。

还值得注意的是 Block Factory generates JSON for use in other Blockly applications, however when I took a look at the code 因为没有为其定义实际的生成器。

我认为你得到的错误是因为 Blockly.Json 没有 init 函数引起的。这是在现有生成器文件中定义的内容,例如,来自 JavaScript 生成器:

/**
* Initialise the database of variable names.
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
*/
Blockly.JavaScript.init = function(workspace) {
  ....
};

考虑到这一点,您的函数将如下所示:

/**
* Initialise the database of variable names.
* @param {!Blockly.Workspace} workspace Workspace to generate code from.
*/
Blockly.Json.init = function(workspace) {
 .....
};

生成器文件还包含其他函数,但查看现有代码并根据您的需要对其进行调整应该会对您有所帮助。

这是我提出的最小可行示例:

我定义了一个小自定义块print:

Blockly.defineBlocksWithJsonArray([
  {
    type: 'print',
    message0: 'print %1',
    args0: [
      { type: 'field_input', name: 'EMOJI_CODE' }
    ]
  }
]);

然后我用这个新块初始化 Blockly 编辑器:

const ws = Blockly.inject('ide', {
  toolbox: {
    kind: 'flyoutToolbox',
    contents: [
      { kind: 'block', type: 'print' }
    ]
  }
});

然后我需要定义块将生成什么。

在此示例中,我们将字符串转换为表情符号,例如:-) 变为 </code>。我定义了一种新语言以及 <code>print 块应该做什么:

const emojiLang = new Blockly.Generator('EmojiLang');

emojiLang['print'] = function (block) {
  const code = block.getFieldValue('EMOJI_CODE');
  if (!code) return 'waiting…';
  if (code == ':-)') return '';
  if (code == ':-(') return '';
  if (code == ':-/') return '';
  return '(unknown)';
};

最后我听取了编辑器中的变化以将块转换为表情符号:

ws.addChangeListener(function () {
  document.getElementById('out').innerHTML =
    emojiLang.workspaceToCode(ws);
});

完整的工作示例

const emojiLang = new Blockly.Generator('EmojiLang');

emojiLang['print'] = function (block) {
  const code = block.getFieldValue('EMOJI_CODE');
  if (!code) return 'waiting…';
  if (code == ':-)') return '';
  if (code == ':-(') return '';
  if (code == ':-/') return '';
  return '(unknown)';
};

Blockly.defineBlocksWithJsonArray([
  {
    type: 'print',
    message0: 'print %1',
    args0: [
      { type: 'field_input', name: 'EMOJI_CODE' }
    ]
  }
]);

const ws = Blockly.inject('ide', {
  toolbox: {
    kind: 'flyoutToolbox',
    contents: [
      { kind: 'block', type: 'print' }
    ]
  }
});

ws.addChangeListener(function () {
  document.getElementById('out').innerHTML =
    emojiLang.workspaceToCode(ws);
});
<script src="https://unpkg.com/blockly/blockly.min.js"></script>

Emoji: <span id="out"></span>
<div id="ide" style="height:200px;width:400px;"></div>