Get code of particular block

1,269 views
Skip to first unread message

Pāvils Jurjāns

unread,
Dec 17, 2015, 1:16:19 PM12/17/15
to Blockly
How one gets the JavaScript code of a particular block?

I have this test code, and all I get is two empty strings:

    function getJavaScriptCode(workspace) {

      // Only blocks with top parent of type "procedures_defnoreturn" and "procedures_defreturn" must be included in the final code
      blocks = workspace.getTopBlocks(true);
      Blockly.JavaScript.init(workspace);

      console.log(blocks);
      for (var b = 0; b < blocks.length; b++) {
        var block = blocks[b];
        console.log(Blockly.JavaScript.blockToCode(block));
      }

My plan was to gather the code only from certain blocks, instead of doing the traditional

      var code = Blockly.JavaScript.workspaceToCode(workspace);

What am I missing?

Blake

unread,
Dec 17, 2015, 4:28:22 PM12/17/15
to Blockly
Pavils,

That code works fine on the generating javascript demo. (https://blockly-demo.appspot.com/static/demos/generator/index.html)

I copied your function to the console and ran it and it worked fine.

I just had to add the closing curly brace:

function getJavaScriptCode(workspace) {

    // Only blocks with top parent of type "procedures_defnoreturn" and "procedures_defreturn" must be included in the final code
    blocks = workspace.getTopBlocks(true);
    Blockly.JavaScript.init(workspace);

    console.log(blocks);
    for (var b = 0; b < blocks.length; b++) {
    var block = blocks[b];
    console.log(Blockly.JavaScript.blockToCode(block));
    }
}

getJavaScriptCode(Blockly.mainWorkspace) 


--
You received this message because you are subscribed to the Google Groups "Blockly" group.
To unsubscribe from this group and stop receiving emails from it, send an email to blockly+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Pāvils Jurjāns

unread,
Dec 18, 2015, 8:04:39 AM12/18/15
to Blockly
Well, I am not sure why it "works" for you. Perhaps you tried with some other type of blocks?

Here's the block setup I tried with (copy-paste the 3 lines of code in the console):

xml_text = '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="procedures_defnoreturn" x="90" y="64"><field name="NAME">foo</field><statement name="STACK"><block type="text_print"><value name="TEXT"><block type="text"><field name="TEXT">bar</field></block></value></block></statement></block></xml>'
var xml = Blockly.Xml.textToDom(xml_text);
Blockly.Xml.domToWorkspace(workspace, xml);

That function registers one top-level block, and the console.log(Blockly.JavaScript.blockToCode(block)) just prints out an empty string. Does it give you something else?

That can be tested in browser's console:

Blockly.JavaScript.init(workspace);
Blockly.JavaScript.blockToCode(workspace.getTopBlocks[0]);

This can be carried out also in the demo app you gave link to, just remove the "if" block before importing new xml. I get empty string on my "foo" function also there.

Do you get something else than empty string? 

Blake

unread,
Dec 18, 2015, 1:14:13 PM12/18/15
to Blockly
Okay so I see your point. 

If you look carefully at how the Javascript generator works, it saves the function definitions in the Blockly.JavaScript.definitions_ list then prepends them onto the code.

If you notice here is where the code is stored in the definitions:
If you change line 60 to return code that will make our previous code work.

So this is where the definitions are read and output:

Hopefully that makes sense.


How I figured this out... I wrote out the steps really clearly as to how to reproduce the bug. Then on the code playground(https://blockly-demo.appspot.com/static/demos/code/index.html) I stepped through the functions that are called when one clicks on the javascript tab.

Here are the steps. Not really relevant, I just don't have the heart to delete them.

1) Clear all blocks (from console)
> Blockly.mainWorkspace.clear()

2) Load two blocks (from console)

var xml_text = '<xml xmlns="http://www.w3.org/1999/xhtml"><block type="procedures_defnoreturn" x="90" y="64"><field name="NAME">foo</field><statement name="STACK"><block type="text_print"><value name="TEXT"><block type="text"><field name="TEXT">bar</field></block></value></block></statement></block><block type="controls_if" x="88" y="163"></block></xml>'
var xml = Blockly.Xml.textToDom(xml_text);
Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml);

2) In the console get the top blocks (from console)
> var tb = Blockly.mainWorkspace.getTopBlocks()

3) Init JavaScript Generator (from console)
> Blockly.JavaScript.init(Blockly.mainWorkspace);

3) Try to generate code (from console)

> Blockly.JavaScript.blockToCode(tb[0])
""
> Blockly.JavaScript.blockToCode(tb[1])
"if (false) {
}
"

Pāvils Jurjāns

unread,
Dec 18, 2015, 6:29:01 PM12/18/15
to Blockly
Ok, cool, thanks for the tip.

I don't feel it is good idea to meddle with the core code - unknown side effects, problems with maintenance when new version comes, etc. So I just borrowed the necessary code from there.

Here's an updated code:

    function getJavaScriptCode(workspace) {

      blocks = workspace.getTopBlocks(true);
      Blockly.JavaScript.init(workspace);

      var code = [];
      var comments = [];
      for (var b = 0; b < blocks.length; b++) {
        var block = blocks[b];
        //console.log(block.type);
        var blockCode = Blockly.JavaScript.blockToCode(block);
        if (["procedures_defnoreturn", "procedures_defreturn"].indexOf(block.type) > -1) {
          // For function blocks, the code is stored in Blockly.JavaScript.definitions_
        } else {
          comments.push(blockCode);
        }
      }
      for (var def in Blockly.JavaScript.definitions_) {
        code.push(Blockly.JavaScript.definitions_[def]);
      }

      var code = code.join("\n");
      code += "/*\n" + comments.join("\n") + "*/";
    }

Sure, pretty hacky, but hell, it seems like this does exactly what I need.

Blake

unread,
Dec 18, 2015, 6:32:16 PM12/18/15
to Blockly
Cool! Good work!

What are you building?

Pāvils Jurjāns

unread,
Dec 18, 2015, 6:45:42 PM12/18/15
to Blockly
Here's the essence of my project: https://community.onion.io/topic/193/controlling-ws2812-device-rgb-led-strip/10

And here's a screenshot of a simple Blockly code example:

Reply all
Reply to author
Forward
0 new messages