文章目录
初始化自己的语言生成器
本示例中,在.\my_generators\text_generator.js
中构造了一个用于生成文本的生成器Text
js
Blockly.Text = new Blockly.Generator('Text');
Blockly.Text.scrub_ = function(block, code) {
var nextBlock = block.nextConnection && block.nextConnection.targetBlock();
var nextCode = Blockly.Text.blockToCode(nextBlock);
return code + nextCode;
};
添加积木
语法与其他语言一致
js
Blockly.Text['hello_world'] = function(block) {
var code = '你好,世界!';
return '1. ' + code + '\n';
};
使用
语法与其他语言一致
js
<script src="./my_generators/text_generator.js"></script>
html
Blockly.Text.INFINITE_LOOP_TRAP = null;
let code = Blockly.Text.workspaceToCode(workspace); // 代码生成
示例
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="./blockly/blockly_compressed.js"></script>
<script src="./blockly/blocks_compressed.js"></script>
<script src="./blockly/python_compressed.js"></script>
<script src="./my_generators/text_generator.js"></script>
<script src="./blockly/msg/js/zh-hans.js"></script>
<script src="./blockly/demos/code/msg/zh-hans.js"></script>
<script src="./my_blocks/my_blocks_b.js"></script>
<script src="./my_blocks/my_blocks_g.js"></script>
<!--代码高亮-->
<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 src="https://cdnjs.cloudflare.com/ajax/libs/highlightjs-line-numbers.js/2.8.0/highlightjs-line-numbers.min.js"></script>
<!--Markdown 解析和编译器-->
<script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
<script>
// category 栏翻译
for (var messageKey in MSG)
{
if (messageKey.indexOf('cat') == 0)
{
Blockly.Msg[messageKey.toUpperCase()] = MSG[messageKey];
}
}
</script>
<style>
html, body
{
height: 100%;
}
.content
{
visibility: hidden;
margin: 0;
padding: 1ex;
position: absolute;
direction: ltr;
}
</style>
</head>
<body>
<div id="blocklyDiv" style="height: 100%; width: 33%; display: inline-block; float: left;"></div>
<xml id="toolbox" style="display: none">
<category name="%{BKY_CATLOGIC}" colour="%{BKY_LOGIC_HUE}">
<block type="controls_if"></block>
<block type="logic_compare"></block>
<block type="logic_operation"></block>
<block type="logic_negate"></block>
<block type="logic_boolean"></block>
<block type="logic_null"></block>
<block type="logic_ternary"></block>
</category>
<category name="%{BKY_CATLOOPS}" colour="%{BKY_LOOPS_HUE}">
<block type="controls_repeat_ext">
<value name="TIMES">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
</block>
<block type="controls_whileUntil"></block>
<block type="controls_for">
<value name="FROM">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="TO">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
<value name="BY">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
<block type="controls_forEach"></block>
<block type="controls_flow_statements"></block>
</category>
<category name="%{BKY_CATMATH}" colour="%{BKY_MATH_HUE}">
<block type="math_number"></block>
<block type="math_arithmetic">
<value name="A">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="B">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
</block>
<block type="math_single">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">9</field>
</shadow>
</value>
</block>
<block type="math_trig">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">45</field>
</shadow>
</value>
</block>
<block type="math_constant"></block>
<block type="math_number_property">
<value name="NUMBER_TO_CHECK">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="math_round">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">3.1</field>
</shadow>
</value>
</block>
<block type="math_on_list"></block>
<block type="math_modulo">
<value name="DIVIDEND">
<shadow type="math_number">
<field name="NUM">64</field>
</shadow>
</value>
<value name="DIVISOR">
<shadow type="math_number">
<field name="NUM">10</field>
</shadow>
</value>
</block>
<block type="math_constrain">
<value name="VALUE">
<shadow type="math_number">
<field name="NUM">50</field>
</shadow>
</value>
<value name="LOW">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="HIGH">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>
<block type="math_random_int">
<value name="FROM">
<shadow type="math_number">
<field name="NUM">1</field>
</shadow>
</value>
<value name="TO">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
</block>
<block type="math_random_float"></block>
</category>
<category name="%{BKY_CATTEXT}" colour="%{BKY_TEXTS_HUE}">
<block type="text"></block>
<block type="text_join"></block>
<block type="text_append">
<value name="TEXT">
<shadow type="text"></shadow>
</value>
</block>
<block type="text_length">
<value name="VALUE">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_isEmpty">
<value name="VALUE">
<shadow type="text">
<field name="TEXT"></field>
</shadow>
</value>
</block>
<block type="text_indexOf">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{textVariable}</field>
</block>
</value>
<value name="FIND">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_charAt">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{textVariable}</field>
</block>
</value>
</block>
<block type="text_getSubstring">
<value name="STRING">
<block type="variables_get">
<field name="VAR">{textVariable}</field>
</block>
</value>
</block>
<block type="text_changeCase">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_trim">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_print">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
<block type="text_prompt_ext">
<value name="TEXT">
<shadow type="text">
<field name="TEXT">abc</field>
</shadow>
</value>
</block>
</category>
<category name="%{BKY_CATLISTS}" colour="%{BKY_LISTS_HUE}">
<block type="lists_create_with">
<mutation items="0"></mutation>
</block>
<block type="lists_create_with"></block>
<block type="lists_repeat">
<value name="NUM">
<shadow type="math_number">
<field name="NUM">5</field>
</shadow>
</value>
</block>
<block type="lists_length"></block>
<block type="lists_isEmpty"></block>
<block type="lists_indexOf">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_getIndex">
<value name="VALUE">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_setIndex">
<value name="LIST">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_getSublist">
<value name="LIST">
<block type="variables_get">
<field name="VAR">{listVariable}</field>
</block>
</value>
</block>
<block type="lists_split">
<value name="DELIM">
<shadow type="text">
<field name="TEXT">,</field>
</shadow>
</value>
</block>
<block type="lists_sort"></block>
</category>
<category name="%{BKY_CATCOLOUR}" colour="%{BKY_COLOUR_HUE}">
<block type="colour_picker"></block>
<block type="colour_random"></block>
<block type="colour_rgb">
<value name="RED">
<shadow type="math_number">
<field name="NUM">100</field>
</shadow>
</value>
<value name="GREEN">
<shadow type="math_number">
<field name="NUM">50</field>
</shadow>
</value>
<value name="BLUE">
<shadow type="math_number">
<field name="NUM">0</field>
</shadow>
</value>
</block>
<block type="colour_blend">
<value name="COLOUR1">
<shadow type="colour_picker">
<field name="COLOUR">#ff0000</field>
</shadow>
</value>
<value name="COLOUR2">
<shadow type="colour_picker">
<field name="COLOUR">#3333ff</field>
</shadow>
</value>
<value name="RATIO">
<shadow type="math_number">
<field name="NUM">0.5</field>
</shadow>
</value>
</block>
</category>
<sep></sep>
<category name="%{BKY_CATVARIABLES}" colour="%{BKY_VARIABLES_HUE}" custom="VARIABLE"></category>
<category name="%{BKY_CATFUNCTIONS}" colour="%{BKY_PROCEDURES_HUE}" custom="PROCEDURE"></category>
<sep></sep>
<category name="My blocks" colour="230">
<block type="hello_world"></block>
<block type="my_print"></block>
</category>
</xml>
</body>
<script>
// Construct the toolbox XML, replacing translated variable names.
// 构建 toolbox XML,替换翻译后的变量名。
var toolboxText = document.getElementById('toolbox').outerHTML;
toolboxText = toolboxText.replace(/(^|[^%]){(\w+)}/g,
function(m, p1, p2) {return p1 + MSG[p2];});
var toolboxXml = Blockly.Xml.textToDom(toolboxText);
var workspace = Blockly.inject(
'blocklyDiv',
{
toolbox: toolboxXml,
grid: // 栅格
{
spacing: 20,
length: 3,
colour: '#ccc',
snap: true
},
move: // 移动
{
scrollbars:
{
horizontal: true,
vertical: true
},
drag: true,
wheel: false
},
zoom: // 缩放
{
controls: true,
wheel: true,
startScale: 1.0,
maxScale: 3,
minScale: 0.3,
scaleSpeed: 1.2
},
media: './blockly/media/', // 图标及音效
trashcan: true
}
);
</script>
<script>
function show_code()
{
// Generate Python code and display it.
Blockly.Python.INFINITE_LOOP_TRAP = null;
let code = Blockly.Python.workspaceToCode(workspace); // 代码生成
// console.log(code);
let display_code_obj = document.getElementById("display_code"); // 获取代码展示区对象
display_code_obj.textContent = code; // 更新代码展示区的内容
// 开启代码高亮
hljs.initHighlightingOnLoad();
// 开启行号显示
// hljs.initLineNumbersOnLoad ();
}
function show_text()
{
Blockly.Text.INFINITE_LOOP_TRAP = null;
let code = Blockly.Text.workspaceToCode(workspace); // 代码生成
$m1.innerHTML = marked.parse(code); // 内容通过Markdown格式显示
}
</script>
<div style="height: 100%; width: 33%; display: inline-block; float: left;">
<button id="btn_code" style="float: left;">一键复制</button>
<!--代码展示区-->
<pre>
<code class="python" id="display_code">
</code>
</pre>
</div>
<div style="height: 100%; width: 33%; display: inline-block; float: left;">
<button id="btn_text">一键复制</button>
<!--文本展示区-->
<div id="$m1" class="markdown-body"></div>
</div>
<script>
// 开启代码高亮
hljs.initHighlightingOnLoad();
workspace.addChangeListener(show_code); // 绑定 show_code 函数到 Blockly 的 change 事件来实时生成和显示代码
workspace.addChangeListener(show_text);
</script>
<script type="module">
import { convert } from 'https://cdn.jsdelivr.net/npm/html-to-text@9.0.5/+esm' // html 转 纯文本 模块
const options = {
wordwrap: 130,
// ...
};
const btn_code = document.getElementById('btn_code'), // 获取 一键复制 按钮
btn_text = document.getElementById('btn_text'), // 获取 一键复制 按钮
alert = document.getElementById('msg');
let clipboard = navigator.clipboard;
btn_code.addEventListener
(
'click', async () =>
{
let display_code_obj = document.getElementById("display_code"); // 获取代码展示区对象
await clipboard.writeText(display_code_obj.textContent); // 代码展示区内容赋值给剪切板
}
)
btn_text.addEventListener
(
'click', async () =>
{
let text = convert($m1.innerHTML, options); // 内容转化为纯文本
await clipboard.writeText(text); // 文本赋值给剪切板
}
)
</script>
</html>