# BlocklyPy Library and Tool

[![npm version](https://badge.fury.io/js/blocklypy.svg)](https://badge.fury.io/js/blocklypy)

**LEGO SPIKE and EV3 Mindstorms Code to Pybricks - block-code analyzer and converter to Pybricks python code**

This tool and library will read, analyze and convert the LEGO standard graphical blockly files to Pybricks python files.

SPIKE Prime ([45678](https://www.lego.com/en-us/product/lego-education-spike-prime-set-45678)) and SPIKE Essentials ([45345](https://www.lego.com/en-us/product/lego-education-spike-essential-set-45345)) kit and Robot Inventor ([51515](https://www.lego.com/en-us/product/robot-inventor-51515)) kit for **word-blocks** and **icon-blocks** transformation and LEGO python for analysis only.

-   SPIKE v2 (.llsp) and SPIKE v3 (.llsp3) files.
-   Robot Inventor files (.lms).

EV3 Mindstorms kit ([31313](https://www.lego.com/en-us/product/lego-mindstorms-ev3-31313)) LabView EV3-G code transformation:

-   EV3Classroom files (.lmsp).
-   EV3 Lab (.ev3) files EV3 iPad (.ev3m) files.
-   EV3 Lab Compiled Binary (.rbf) files.

Analysis only:

-   Pybricks python (.py) file, multiple files or zipped (.zip) multiple files.

## Quick intro: Command Line Interface tool

Blocklypy CLI tool is a standalone tool that one can install and run on a node environment locally.

Generate and print python converted code of a SPIKE blockly source code file.

```sh
blocklypy python testfile.llsp3
```

Detailed documentation of the [command line interface tool](#command-line-interface-tool).

## Quick intro: Library for TypeScript

Blocklypy library is a TypeScript library packaged for both browser and node.js environment usage.

```javascript
const { convertProjectToPython } = require('blocklypy');
const fname = 'testfile.llsp';
const file = fs.readFileSync(fname);
const options = {};
const inputfiles = [{ name: fname, buffer: file }];
const result = convertProjectToPython(inputfiles, options).then((retval) => {
    console.log(retval.pycode);
});
```

Detailed documentation of the [blocklypy library](#blocklypy-library).

## Author

Attila Farago ([@afarago](https://github.com/afarago/))

---

# Command Line Interface tool

Blocklypy CLI tool is a standalone tool that one can install and run on a node environment locally.

## Usage

```
Usage: blocklypy [options] [command]

Command line interface for blocklypy to analyze and convert LEGO robotics code to Python.
Blocklypy converts LEGO robotics code to Pybricks python, converting and analyzing word-block, icon-block, ev3g and ev3 compiled code.

Options:
  -V, --version                              output the version number
  -o, --open                                 Open the output file in the default viewer
  -h, --help                                 display help for command

Commands:
  graph|g [options] <input>                  Generate dependency callgraph content
  preview [options] <input>                  Save preview content
  python|py [options] <input> [stackfilter]  Convert and save python content, with optional stack filtering
  plain [options] <input>                    Convert and save plain pseudocode content
  help [command]                             display help for command
```

## Installation

1. [Install node](https://nodejs.org/en/download) environment.
2. Install blocklypy globally.  
   `npm install -g blocklypy`
3. Run blocklypy locally.  
   `blocklypy -h`

## Examples

Convert and print a SPIKE blockly source code file to python.

```sh
blocklypy python testfile.llsp3
```

Convert and save an EV3Classroom source code file to python.

```sh
blocklypy python --python testfile.lmsp
```

Generate and save svg dependency call graph of a EV3-G source code file.

```sh
blocklypy graph --svg --open testfile.ev3
```

Generate and save png dependency call graph of a pybricks code module zip and open it locally.

```sh
blocklypy graph --png testfile.zip
```

Decompile an EV3-G compiled RBF source code file and save the pseudocode as a text file.

```sh
blocklypy plain --txt testfile.rbf
```

Extract and save blockly diagram code of an Robot Inventor source code file.

```sh
blocklypy preview --svg testfile.lms
```

---

# Blocklypy Library

Blocklypy library is a TypeScript library packaged for both browser and node.js environment usage.

## Usage

```javascript
const { convertProjectToPython } = require('blocklypy');

const file = fs.readFileSync(__FILE__);

const options = {};
const inputfiles = [{ name: __FILE__, buffer: file }];
convertProjectToPython(inputfiles, options).then((retval) => {
    console.log(retval.pycode);
});
```

## Result

**Type**: `IPyProjectResult`

### pycode

**Type**: `string | string[]`

Python representation of the blockly code in Pybricks flavour.

```python
"""
Project:    test1
Slot:       0
Created:    2024-09-02T09:08:14.079Z
Last saved: 2024-09-03T16:57:06.369Z
"""

#region ========================== SECTION: IMPORTS ========================== #
from pybricks.hubs import PrimeHub
from pybricks.tools import wait
#endregion
...
#region ======================= SECTION: PROGRAM CODE ======================== #
# ------------------------------- GROUP: START ------------------------------- #
# STACK #1: flipperevents_whenProgramStarts()
def stack1_whenprogramstarts_fn():
    hub.display.pixel(0, 0, 100)
    hub.display.icon(convert_icon_matrix("9909999099000009000909990", g_pixel_brightness))
    wait(convert_time(g_aa))
    hub.display.off()

#endregion

#region ====================== SECTION: MAIN CODE ============================ #
stack1_whenprogramstarts_fn()
#endregion
```

### plaincode

**Type**: `string`

Pseudo code of the blockly code.

```js
flipperevents_whenProgramStarts()
    flipperlight_lightDisplaySetPixel(x: "1", y: "1", brightness: 100)
    flipperlight_lightDisplayImageOnForTime(matrix: "9909999099000009000909990", value: g_aa)

flippermove_movementSpeed(speed: 50)
    flippermove_startMove(direction: "back")

data_setvariableto(value: "0", variable: "aa")

data_changevariableby(value: 13, variable: "aa")

flipperlight_lightDisplayImageOn(matrix: "9909999099000009000909990")
```

### extra

**Type**: `object`

Contains input format dependent extra information such as blockly slot and svg preview or rbf disassembly.

```json
{
    "blockly.slot": 0,
    "blockly.svg": "<svg xmlns='http://www.w3.org/2000/svg…fa6d44c8e6aa1eaca43d65'/><defs></g></svg>"
}
```

### dependencygraph

**Type**: `string`

Graphviz dot format representation of the python code call structure.

```
digraph ev3graph {
	rankdir = LR

    "demo_ev3treevis" -> "TestProgram1"
	"demo_ev3treevis" -> "UsingMyBlocks"
	"TestProgram1" -> "Limit"
	"UsingMyBlocks" -> "DriveCmDetectColor"
    ...
}
```
