diff --git a/Alternatives.md b/Alternatives.md deleted file mode 100644 index 8ac6e9f..0000000 --- a/Alternatives.md +++ /dev/null @@ -1,18 +0,0 @@ -# A growing family - -Blockly is one of a growing number of visual programming environments. Many of these languages have roots at MIT, leading to a similar look and feel across different products. Blockly was influenced by [App Inventor](http://www.appinventor.mit.edu/), which in turn was influenced by [Scratch](http://scratch.mit.edu/), which in turn was influenced by [StarLogo](http://education.mit.edu/projects/starlogo-tng). - -# Blockly's distinguishing features - -Blockly was designed with the following requirements: - * Execute in a web-browser. No downloads or plugins needed. - * Exportable code. Users can extract their programs as JavaScript, Python, Dart or other language so that when they outgrow Blockly they can keep learning. - * Open source. Everything about Blockly is open: you can fork it, hack it, and use it in your own websites. - * Highly capable. With the ability to calculate standard deviation using a single block, Blockly is not a toy. - -Equally important is a negative characteristic: - * Blockly in itself is not an educational platform. Blockly is an editor that may be used as part of an educational platform, or as part of a business suite, or as part of a gaming system, etc. - -# Alternatives - -Wikipedia currently lists about a hundred [visual programming environments](https://en.wikipedia.org/wiki/Visual_programming_language). Please check them out before choosing one. Visual programming environments are still evolving quickly and as a community we are still learning what works and what doesn't. \ No newline at end of file diff --git a/BlocklyModes.md b/BlocklyModes.md deleted file mode 100644 index 43e5efc..0000000 --- a/BlocklyModes.md +++ /dev/null @@ -1,11 +0,0 @@ -Blockly has two modes: simple and advanced. - -Simple mode has a fixed toolbox with a small number of blocks, no scrollbars, and usually no trashcan: -https://blockly-demo.appspot.com/static/demos/fixed/index.html - -Advanced mode has flyout toolboxes organized by category, an infinite scrolling workspace, and usually a trashcan: -https://blockly-demo.appspot.com/static/demos/toolbox/index.html - -These two modes are mutually incompatible. Consider what happens when one drags a block to the toolbox. In one mode the block is deleted. In the other mode the workspace grows to the left. A scrolling workspace next to a fixed toolbox would be bad. - -The determining factor for the existence of a scrolling workspace is whether there are categories in the toolbox. See the second link, above. \ No newline at end of file diff --git a/CachingArguments.md b/CachingArguments.md deleted file mode 100644 index a4357c2..0000000 --- a/CachingArguments.md +++ /dev/null @@ -1,80 +0,0 @@ -**[Creating Custom Blocks](CustomBlocks): [Generating Code](GeneratingCode): Caching Arguments** - -# Caching Arguments - -When generating code from blocks one often finds the need to use the returned value of a sub-block more than once. Consider a value block that finds and returns the last element of a list. The block itself would have one input (a list), and would return a value (the last element). Here is the generator for JavaScript: -``` - var code = arg0 + '[' + arg0 + '.length - 1]'; -``` -If ` arg0 ` is a variable name, this generator returns perfectly acceptable JavaScript: -``` - aList[aList.length - 1] -``` -However, this generator may have unintended behaviour if ` arg0 ` were a function call. Consider the following code: -``` - randomList()[randomList().length - 1] -``` -The two returned values might be of different lengths, resulting in an out of range condition. Additionally, if the function call has side-effects, then calling it twice could be undesirable. - -There are two solutions to this problem. Statement blocks should use temporary variables. Value blocks should use utility functions. - -## Temporary Variables - -The simplest solution is to assign the offending input to a temporary variable. Care must be taken that this variable does not accidentally collide with an existing variable. The following code shows an example of a temporary variable in a statement block which alerts the last element of a list. -``` - var listVar = Blockly.JavaScript.variableDB_.getDistinctName( - 'temp_list', Blockly.Variables.NAME_TYPE); - var code = 'var ' + listVar + ' = ' + arg0 + ';\n'; - code += 'alert(' + listVar + '[' + listVar + '.length - 1]);\n'; -``` -The ` getDistinctName ` call takes an argument of the desired variable name ("temp\_list") and will return an non-colliding name to use (possibly "temp\_list2"). - -The downside of temporary variables is that if the offending input was already a variable, then one generates redundant code: -``` - var temp_list = foo; - alert(temp_list[temp_list.length - 1]); -``` -To produce cleaner code, check to see if the offending input is a simple literal, and generate code accordingly: -``` -if (argument0.match(/^\w+$/)) { - var code = 'alert(' + arg0 + '[' + arg0 + '.length - 1]);\n'; -} else { - var listVar = Blockly.JavaScript.variableDB_.getDistinctName( - 'temp_list', Blockly.Variables.NAME_TYPE); - var code = 'var ' + listVar + ' = ' + arg0 + ';\n'; - code += 'alert(' + listVar + '[' + listVar + '.length - 1]);\n'; -} -``` - -See ` Blockly.JavaScript.controls_forEach ` for a working example of temporary variables. - -Temporary variables work well in statement blocks (in this case an alert) where the generated code may span multiple lines. However they are unworkable in value blocks which must be on a single line. For value blocks one must use a utility function instead of temporary variables. - -## Utility Functions - -Defining a utility function is a powerful way to create blocks that operate at a higher level than the underlying language. Utility functions are not generated unless they are used, and they are only generated once regardless of the number of times they are used. The following example includes inline comments. - -``` - // Only define a utility function if it hasn't already been defined. - // The 'definitions_' property of the generator stores all the utility functions. - if (!Blockly.JavaScript.definitions_['list_lastElement']) { - // Obtain a non-colliding function name. - var functionName = Blockly.JavaScript.variableDB_.getDistinctName( - 'list_lastElement', Blockly.Generator.NAME_TYPE); - // Save this name in a place that can be accessed by all blocks of this type. - Blockly.JavaScript.list_lastElement.utilityFunction = functionName; - // Build the function line by line. Ensure that the name is dynamic. - var func = []; - func.push('function ' + functionName + '(aList) {'); - func.push(' // Return the last element of a list.'); - func.push(' return aList[aList.length - 1];'); - func.push('}'); - // Add the completed function to the code generator. - Blockly.JavaScript.definitions_['list_lastElement'] = func.join('\n'); - } - // Generate the function call for this block. - var code = Blockly.JavaScript.list_lastElement.utilityFunction + '(' + arg0 + ')'; - return [code, Blockly.JavaScript.ORDER_FUNCTION_CALL]; -``` - -See ` Blockly.JavaScript.text_endString ` for a working example of a utility function. \ No newline at end of file diff --git a/Closure.md b/Closure.md deleted file mode 100644 index 16c8877..0000000 --- a/Closure.md +++ /dev/null @@ -1,21 +0,0 @@ -# Introduction - -Did you just get this error message? - -![](closure_alert.png) - -If so, then you are probably attempting to run the uncompiled version of Blockly and you are missing the dependency on [Closure Library](https://developers.google.com/closure/library/). - -## Getting Closure - -Getting Closure is quick and easy. Use either Git or Subversion to checkout a copy from [Closure's repository](https://github.com/google/closure-library): - -``` -svn checkout https://github.com/google/closure-library/trunk closure-library-read-only -``` - -Once you have the Closure files, place them next to Blocky's root directory and ensure that the directory is named ` closure-library-read-only `. This is the directory structure you want: - -![](closure_directory.png) - -That's it. Blockly should now work in uncompiled mode. diff --git a/CloudStorageWithAppEngine.md b/CloudStorageWithAppEngine.md deleted file mode 100644 index a39100b..0000000 --- a/CloudStorageWithAppEngine.md +++ /dev/null @@ -1,79 +0,0 @@ -**[Installation](Installation): Cloud Storage** - -# Introduction - -If your application is hosted on App Engine, a cloud storage service is available that allows users to save, load, share, and publish their programs. - -_Note that the [RealtimeCollaboration](RealtimeCollaboration) feature provides an alternate way to save, load, share, and publish programs. It does, however, currently require users to have a Google Account._ - -## Setting up App Engine - -The first step is to get your own copy of Blockly running on App Engine. - - 1. Download and install the [Python SDK](https://developers.google.com/appengine/downloads). - 1. Log into [Google App Engine](https://appengine.google.com/) and create an application. - 1. Edit ` appengine/app.yaml ` and change the application ID from ` blockly-demo ` to the application name you created in the previous step. - 1. Copy (or soft-link) the following files and directories into ` appengine/static/ `: - * ` apps/ ` - * ` demos/ ` - * ` msg/ ` - * ` media/ ` - * ` tests/ ` - * ` *_compressed.js ` - 1. Optional: If you'd like to use ` blockly_uncompressed.js ` on the server, also copy that into ` appengine/static/ ` and copy ` closure-library-read-only/ ` into the parent directory, ` appengine/ `. - 1. Optional: If you'd like to run the Blockly Playground, you'll have to add links for the ` blocks `, ` core `, ` generators `, and ` tests ` directories, as well as the files in step 5. - 1. Run the Google App Engine Launcher from the GUI, add your ` appengine ` directory as an existing application, and press the "Deploy" button. If you prefer to use the command line, run: ` appcfg.py --oauth2 update appengine/ `. - -Once Blockly is uploaded you can point a browser to the URL you created in step 2. You should see a list of demos, including the cloud storage demo. - -## Talking to the Cloud - -Examine the [storage demo](https://blockly-demo.appspot.com/static/demos/storage/index.html)'s source at [demos/storage/index.html](https://github.com/google/blockly/tree/master/demos/storage/index.html) and note the following features. First, there is a script include that loads the cloud storage API: - -``` - -``` - -There are also these message definitions, which you should modify as desired: -``` - BlocklyStorage.HTTPREQUEST_ERROR = 'There was a problem with the request.\n'; - BlocklyStorage.LINK_ALERT = 'Share your blocks with this link:\n\n%1'; - BlocklyStorage.HASH_ERROR = 'Sorry, "%1" doesn\'t correspond with any saved Blockly file.'; - BlocklyStorage.XML_ERROR = 'Could not load your saved file.\n'+ - 'Perhaps it was created with a different version of Blockly?'; -``` -Translations into other languages can be found at [apps/json](https://github.com/google/blockly/tree/master/apps/json). - -Saving the current blocks is a single call to ` BlocklyStorage.link() `: - -``` - -``` - -To restore saved blocks on page load, just call ` BlocklyStorage.retrieveXml ` with the URL's hash after Blockly has been injected: - -``` - if ('BlocklyStorage' in window && window.location.hash.length > 1) { - BlocklyStorage.retrieveXml(window.location.hash.substring(1)); - } -``` - -## Local Storage - -The ` storage.js ` API also offers the ability to save a single set of blocks in the browser's local storage. This may be implemented instead of cloud storage, or in addition with cloud storage (though in the latter case one has to be careful of both types of storage attempting to restore at once). - -To restore blocks from local storage, call ` BlocklyStorage.restoreBlocks ` in a timeout right after Blockly has been injected. - -``` - window.setTimeout(BlocklyStorage.restoreBlocks, 0); -``` - -To automatically backup the blocks into local storage when the user leaves the page, call ` BlocklyStorage.backupOnUnload ` and it will register an event listener on the page's unload event. - -``` - BlocklyStorage.backupOnUnload(); -``` - -## Example - -Here is [a live demo](https://blockly-demo.appspot.com/static/demos/storage/index.html) of cloud storage. diff --git a/help/Colour.md b/Colour.md similarity index 95% rename from help/Colour.md rename to Colour.md index 465fb19..d12c3f6 100644 --- a/help/Colour.md +++ b/Colour.md @@ -8,13 +8,13 @@ Blockly users can choose, create, and blend colours. Colours are primarily used The simplest way to get a colour is with the **colour picker**. It appears as a red rounded rectangle. When the user clicks on it, a palette of colours pops open, from which the user can choose the desired colour by again clicking. -![](help/colour-select.png) +![](colour-select.png) ## Creating a colour from red, green, and blue components The **colour with** block allows the user to specify the desired percent of red, green, and blue. This block builds a colour with the maximum amounts of red and blue and no green (making purple): -![](help/colour-with.png) +![](colour-with.png) Note that we use [a range from 0 to 100 (inclusive) for each component](http://www.december.com/html/spec/colorper.html), not the less intuitive range of 0 to 255 generally used by programmers and graphic designers. @@ -24,7 +24,7 @@ The ability to specify colours with changing numbers allows some beautiful turtl The **random colour** block generates colours at random. -![](help/colour-random-colour.png) +![](colour-random-colour.png) Specifically, each of the red, green, and blue components is a number from 0 to 255 (inclusive), with equal likelihood. @@ -32,7 +32,7 @@ Specifically, each of the red, green, and blue components is a number from 0 to Unlike traditional turtle graphics systems, Blockly provides a means for blending two colours, as though one were blending two different colours of paint. The following block provides the colour that would be obtained by mixing equal amounts of red paint (actually, [red light](http://www.newton.dep.anl.gov/askasci/gen99/gen99557.htm)) and yellow paint: -![](help/colour-blend.png) +![](colour-blend.png) If the ratio were 0, the result would have no red and all yellow. If the ratio were 1, the result would be all red and no yellow. @@ -40,7 +40,7 @@ If the ratio were 0, the result would have no red and all yellow. If the ratio Blockly colours are represented as text of the form "#rrggbb" where "rr", "gg", and "bb" represent the red, green, and blue components, respectively, in the hexadecimal range 00 to ff. Since colours are usually passed to the "set colour" block in the turtle graphics application, most users are never aware of this, but it is exposed by the following program: -![](help/colour-print.png) +![](colour-print.png) which prints "#ff0000". diff --git a/ContributingCode.md b/ContributingCode.md deleted file mode 100644 index 2fe96b3..0000000 --- a/ContributingCode.md +++ /dev/null @@ -1,76 +0,0 @@ -# Introduction - -Blockly welcomes your contributions. Want to translate Blockly into a new language? Want to fix a bug that's annoying you? Want to write an application that uses Blockly? - -The only rule is that all code committed by anyone must be reviewed and approved by one other contributor. - -## First-time contributor - -Just use Subversion to pull down a copy of Blockly's source from the repository: -``` -svn checkout http://blockly.googlecode.com/svn/trunk/ blockly -``` -Windows users may wish to use [Tortise SVN](http://tortoisesvn.tigris.org/). - -Make your changes, then send us the resulting patch: -``` -svn diff -``` -Post the patch in a bug, or on the newsgroup, or email it to one of us. - -If it is good, and you want to do more, we will add you as a contributor. - -## As a contributor - -Once you are a Blockly contributor we encourage you to [install depot\_tools](http://dev.chromium.org/developers/how-tos/install-depot-tools) that streamline the process of getting reviews done. Then you can set up your working directory: - -``` -mkdir blockly -cd blockly -gclient config --name trunk https://blockly.googlecode.com/svn/trunk -gclient sync -``` - -First time before running 'gclient sync', you may need run the command: -``` -svn ls https://blockly.googlecode.com/svn/trunk -``` - -and type 'p' to accept Server certificate (p)ermanently to access the https resource. - -[Install Closure library](Closure). - -### Update the code - -``` -cd blockly -gclient sync -``` - -### Submitting a code review - - * Do some work. - * cd trunk - * ` gcl change ` - * [Run tests](UnitTesting). - * ` gcl upload xxxx ` - * Go to the url on codereview.appspot.com returned by ` gcl upload `. - * Click on "Publish+Mail Comments", fill in the reviewer field, and send. - * Get "LGTM" (Looks Good To Me) from reviewer. - * ` gclient sync ` - * [Run tests](UnitTesting). - * ` gcl commit xxxx ` - -### Branching - -To include branches in your client, create it with: - -``` -gclient config --name blockly https://blockly.googlecode.com/svn -``` - -To merge in changes from the main branch, run the following from the subdirectory for the branch (e.g., ` branches/i18n `): - -``` -svn merge https://blockly.googlecode.com/svn/trunk -``` diff --git a/CreatingMutators.md b/CreatingMutators.md deleted file mode 100644 index 6ffb3e4..0000000 --- a/CreatingMutators.md +++ /dev/null @@ -1,68 +0,0 @@ -**[Creating Custom Blocks](wiki/CustomBlocks): [Defining a Block](wiki/DefiningBlocks): Creating Mutators** - -# Creating Mutators - -Advanced blocks may use a mutator to be even more dynamic and configurable. Mutators allow blocks to change in custom ways, beyond dropdown and text input fields. The most common example is the pop-up dialog which allows ` if ` statements to acquire extra ` else if ` and ` else ` clauses. But not all mutators are so visible. - -## mutationToDom and domToMutation - -The XML format used to load, save, copy, and paste blocks automatically captures and restores all data stored in editable fields. However, if the block contains additional information, this information will be lost when the block is saved and reloaded. - -A simple example of this is the ` Blockly.Language.text_trim ` block. This block normally reads "` trim spaces from [both] sides `" where ` [both] ` is a dropdown with options ` both `, ` left `, and ` right `. The latter two options result in a grammatical error, requiring the word ` sides ` to become ` side `. This is easy to accomplish, one just adds a validation function on the dropdown which changes the text field. When the dropdown is changed, so is the field. However, since the field is not editable, it is not saved or restored when converted to and from XML. To store this extra information, a mutation is stored. - -Saving mutation data is accomplished by adding a ` mutationToDom ` function in the block's definition. Here is the example from the aforementioned ` text_trim ` block: -``` - mutationToDom: function() { - // Save whether the 'sides' field should be plural or singular. - var container = document.createElement('mutation'); - var plural = (this.getFieldValue('MODE') == 'BOTH'); - container.setAttribute('plural', plural); - return container; - } -``` -This function is called whenever a block is being written to XML. If the function does not exist or returns null, then no mutation is recorded. If the function exists and returns a 'mutation' XML element, then this element (and any properties or child elements) will be stored as part of the block's XML representation. In the above case the XML will include this tag: ` ` - -The inverse function is ` domToMutation ` which is called whenever a block is being restored from XML. Here is the example from the aforementioned ` text_trim ` block: -``` - domToMutation: function(xmlElement) { - // Restore the 'sides' field as plural or singular. - var plural = (xmlElement.getAttribute('plural') == 'true'); - this.setFieldText(plural ? 'sides' : 'side', 'SIDES'); - } -``` -If this function exists, it is passed the block's 'mutation' XML element. The function may parse the element and reconfigure the block based on the element's properties and child elements. In the above case, a field is changed from singular to plural. - -## compose and decompose - -Mutation dialogs allow a user to explode a block into smaller sub-blocks and reconfigure them, thereby changing the shape of the original block. The dialog button is added to a block in its [init function](wiki/DefiningBlocks#Init_Function). - -``` - this.setMutator(new Blockly.Mutator(['controls_if_elseif', 'controls_if_else'])); -``` - -![https://blockly.googlecode.com/svn/wiki/controls_if.png](https://blockly.googlecode.com/svn/wiki/controls_if.png) - -The ` setMutator ` function takes one argument, a new Mutator. The Mutator constructor takes one argument, a list of sub-blocks to show in the mutator's toolbox. Creating a mutator for a sub-block is not advised at this time. - -When a mutator dialog is opened, the block's ` decompose ` function is called to populate the mutator's workspace. -``` - decompose: function(workspace) { - var ifBlock = new Blockly.Block(workspace, 'controls_if_if'); - ifBlock.initSvg(); - ... - return ifBlock; - } -``` - -At a minimum this function must create and initialize a top-level block for the mutator dialog, and return it. This function should also populate this top-level block with any sub-blocks which are appropriate. - -When a mutator dialog saves its content, the block's ` compose ` function is called to modify the original block according to the new settings. -``` - compose: function(ifBlock) { - ... - } -``` - -This function is passed the top-level block from the mutator's workspace (the same block that was created and returned by the ` compose ` function). Typically this function would spider the sub-blocks attached to the top-level block, then update the original block accordingly. - -This function should take care to ensure that any blocks already connected to the original block should remain connected to the correct inputs, even if the inputs are reordered. \ No newline at end of file diff --git a/Credits.md b/Credits.md deleted file mode 100644 index ef31b1b..0000000 --- a/Credits.md +++ /dev/null @@ -1,22 +0,0 @@ -(TODO: Add table of contents.) -# Engineers - -## Core - * Neil Fraser - * Quynh Neutron - * Chris Pirich - * Ellen Spertus - * Phil Wagner - -## Bug fixes - * Spencer Gordon - -# Documentation - -In addition to documentation by the engineers, we are grateful to: - - * Janet Miller - -# Translators - -Siebrand Mazeland helped immensely by setting us up at http://translatewiki.net, which we have been using. Anatoly Techtonik helped with several Serbian languages. \ No newline at end of file diff --git a/CustomBlocks.md b/CustomBlocks.md deleted file mode 100644 index 10e0848..0000000 --- a/CustomBlocks.md +++ /dev/null @@ -1,31 +0,0 @@ -This document is aimed at developers who wish to create new blocks within Blockly. It is assumed that one has a local copy of Blockly which one can edit, one is generally familiar with Blockly's usage, and one has a basic understanding of JavaScript or some similar language. - -# Introduction - -Blockly comes with a large number of pre-defined blocks. Everything from mathematical functions to looping structures. However, in order to interface with an external application, one must create custom blocks to form an API. For example, when creating a drawing program, one might need to create a "_draw circle of radius R_" block. - -In most cases the easiest approach is to just find a really similar block which already exists, copy it, and modify it as needed. The following documentation is for those who need more help. If all else fails, post in the [support newsgroup](https://groups.google.com/group/blockly). - -## Define Block - -The first step is to create a block; specifying its shape, labels, and connection points. This is done in the ` language/ ` directory. - -→ More info on [Defining Blocks](DefiningBlocks)... - -Advanced blocks may dynamically change their shape in response to the user or other factors. - -→ More info on [Creating Mutators](CreatingMutators)... - -## Code Generation - -The second step is to create the generator code to export the new block to a programming language (such as JavaScript, Python, or Dart). This is done in the ` generators/ ` directory. - -→ More info on [Generating Code](GeneratingCode)... - -To generate code that is both clean and correct, one must be mindful of the order of operations list for the given language. - -→ More info on [Operator Precedence](OperatorPrecedence)... - -Creating more complicated blocks requires the use of temporary variables and/or utility functions. This is particularly true when an input is used twice and needs to be cached. - -→ More info on [Caching Arguments](CachingArguments)... \ No newline at end of file diff --git a/DefiningBlocks.md b/DefiningBlocks.md deleted file mode 100644 index a67c7cd..0000000 --- a/DefiningBlocks.md +++ /dev/null @@ -1,287 +0,0 @@ -**[Creating Custom Blocks](CustomBlocks): Defining Blocks** - -Note that much of block creation can be done through the Blockly GUI using [Block Factory](https://blockly-demo.appspot.com/static/apps/blockfactory/index.html) instead of manually creating the code given below. - -# Defining a Block - -Go to the ` blocks/ ` directory. Assuming your block(s) don't fit in the existing categories, create a new JavaScript file. This new JavaScript file needs to be included in the list of ` - -``` - -Then include the messages for the user's language (in this case English): - -``` - -``` - -Add an empty div to the page and set its size: - -``` -
-``` - -Add the structure of the toolbox (see [Defining the Toolbox](Toolbox) for more information): - -``` - -``` - -Finally, call the following to inject Blockly into an empty div. Set 'path' to be the relative path from your web page to Blockly's root directory. This is used by Blockly so that media such as the trash can and the sounds may be loaded. - -``` - -``` - -Test the page in a browser. You should see Blockly's editor filling the div, with four block categories in the toolbox. Here is [a live demo](https://blockly-demo.appspot.com/static/demos/fixed/index.html). \ No newline at end of file diff --git a/InjectingResizable.md b/InjectingResizable.md deleted file mode 100644 index 604c5e6..0000000 --- a/InjectingResizable.md +++ /dev/null @@ -1,76 +0,0 @@ -**[Installation](wiki/Installation): Injecting Resizable Blockly** - -# Introduction - -The most flexible way to put Blockly into a web page is to inject it into an 'iframe'. -This is slightly more complicated than [injecting Blockly into a div](wiki/InjectingFixedSize), but using an iframe allows -Blockly to resize to fill the page, and it allows more than one instance of Blockly to exist on the page. -The only limitation of using an iframe is that for security reasons Blockly will not execute in Chrome when served directly off the local file system with the ` file:// ` protocol. - -## Injection - -Include the following snippet in your web page: - -``` - - -``` - -The iframe is where Blockly will appear. It will be sized as needed using tables, CSS, or JavaScript. The next step is to create the frame for the editor. Here's a good starting snippet for ` frame.html `. - -``` - - - - - - - - - - - - - - -``` - -The script tags in the above snippet load the core Blockly script (` blockly_compressed.js `), the core blocks set (` blocks_compressed.js `), and selects the user's language to be English (` msg/js/en.js `). - -Adjust the paths as needed to enable inclusion of these script files. Likewise, the ` Blockly.inject ` line has a path that needs to point to Blockly's root directory so that media such as the trash can and the sounds may be loaded. - -Test the page in a browser. You should see Blockly's editor filling the iframe, with four block categories in the toolbox. - -Here is [a live demo](https://blockly-demo.appspot.com/static/demos/iframe/index.html) of an iframe nested in a table that fills the screen. \ No newline at end of file diff --git a/Installation.md b/Installation.md deleted file mode 100644 index cf56791..0000000 --- a/Installation.md +++ /dev/null @@ -1,77 +0,0 @@ -# Introduction - -Blockly is designed to easily install into your web application. Users drag blocks around, Blockly generates code, your application does something with that code. From your application's point of view Blockly is just a textarea in which the user types syntactically perfect JavaScript, Python, Dart, or other language. - -Blockly is 100% client-side, requiring no support from the server (unless one wants to use the cloud-storage or realtime collaboration features). There are no 3rd party dependencies (unless one wants to recompile the core). Everything is open source. - -If you do not need to modify the code, you can use our public server at https://blockly-demo.appspot.com. Installation is only recommended for developers who wish to modify or add source code. - -## Get the Code - -First, download the source code. Use [Subversion](http://subversion.apache.org/) to pull a copy of Blockly off of Google Code: - -``` -svn checkout http://blockly.googlecode.com/svn/trunk/ blockly -``` - -Once you have the code, point your browser at ` apps/maze/index.html ` and test out the maze app. Verify that clicking "Run Program" will make the man move forward. - -## Injecting Blockly - -With your installation of Blockly verified as working, inject Blockly into a web page using either a fixed-size ` div ` or a resizable ` iframe `. - -→ More info on [injecting fixed-sized Blockly](InjectingFixedSize)... - -→ More info on [injecting resizable Blockly](InjectingResizable)... - -## Configuration - -The ` Blockly.inject ` line contains as its second argument a dictionary of name-value pairs. These are used for configuration. The following options are supported: - -| Name | Type | Description | -|--------------|--------|---------------------------------------------------------------------------------------------------------------------| -| ` collapse: ` | boolean | Allows blocks to be collapsed or expanded. Defaults to ` true ` if the toolbox has categories, ` false ` otherwise. | -| ` comments: ` | boolean | Allows blocks to have comments. Defaults to ` true ` if the toolbox has categories, ` false ` otherwise. | -| ` disable: ` | boolean | Allows blocks to be disabled. Defaults to ` true ` if the toolbox has categories, ` false ` otherwise. | -| ` maxBlocks: ` | number | Maximum number of blocks that may be created. Useful for student exercises. Defaults to ` Infinity `. | -| ` path: ` | string | Path from page (or frame) to the Blockly root directory. Defaults to ` "./" `. | -| ` readOnly: ` | boolean | If ` true `, prevent the user from editing. Supresses the toolbox and trashcan. Defaults to ` false `. | -| ` rtl: ` | boolean | If ` true `, mirror the editor for Arabic or Hebrew locales. See [RTL demo](https://blockly-demo.appspot.com/static/demos/rtl/index.html). Defaults to ` false `. | -| ` scrollbars: ` | boolean | If ` false `, supress scrollbars that appear if the toolbox has categories. Defaults to ` true `. | -| ` sound: ` | boolean | If ` false `, don't play sounds (e.g. click and delete). Defaults to ` true `. | -| ` toolbox: ` | XML nodes or string | Tree structure of categories and blocks available to the user. See [Defining the Toolbox](Toolbox) for more information. | -| ` trashcan: ` | boolean | Displays or hides the trashcan. Defaults to ` true ` if the toolbox has categories, ` false ` otherwise. | - -Blockly's library of blocks is highly configurable. The blocks shown to the user can be customized so that users only see blocks that are relevant to the task. Browse the ` blocks/ ` directory for block categories that you want to include. The categories and blocks shown in the toolbox (the side menu) is specified using an [XML tree](Toolbox). - -Additionally, custom blocks need to be built to call your web application's API. An example is the [Maze application](https://blockly-demo.appspot.com/static/apps/maze/index.html) which has custom blocks for movement. More info on [Creating custom blocks](CustomBlocks)... - -## Language Generators - -Blockly is not a programming language, one cannot 'run' a Blockly program. Instead, Blockly can translate the user's program into JavaScript, Python, Dart, or some other language. - -→ More info on [Language Generators](LanguageGenerators)... - -## Importing and Exporting Blocks - -If your application needs to save and store the user's blocks and restore them at a later visit, use this call for export to XML: - -``` - var xml = Blockly.Xml.workspaceToDom(Blockly.mainWorkspace); - var xml_text = Blockly.Xml.domToText(xml); -``` - -This will produce a minimal (but ugly) string containing the XML for the user's blocks. If one wishes to obtain a more readable (but larger) string, use ` Blockly.Xml.domToPrettyText ` instead. - -Restoring from an XML string to blocks is just as simple: - -``` - var xml = Blockly.Xml.textToDom(xml_text); - Blockly.Xml.domToWorkspace(Blockly.mainWorkspace, xml); -``` - -## Cloud Storage - -Blockly comes with an optional cloud-storage feature. It enables users to save, load, share, and publish their programs. If your project is hosted on App Engine you can take advantage of this service. - -→ More info on [Cloud Storage](CloudStorageWithAppEngine)... diff --git a/JSInterpreter.md b/JSInterpreter.md deleted file mode 100644 index 06a2d8a..0000000 --- a/JSInterpreter.md +++ /dev/null @@ -1,104 +0,0 @@ -**[Installation](Installation): [Language Generators](LanguageGenerators): JavaScript Interpreter** - -## Eval is Evil - -The quickest way to run your user's blocks is to generate JavaScript, then push the resulting code through the browser's ` eval() ` function. This works very well for many simple applications. The [Language Generators](LanguageGenerators) page describes how to do this, along with a couple of hacks such as how to deal with infinite loops and how not to collide with existing variables. - -However, if you are serious about running the user's blocks properly, then the [JS Interpreter](https://github.com/NeilFraser/JS-Interpreter) is the way to go. This project is separate from Blockly, but was specifically written for Blockly. - - * Execute code at any speed. - * Pause/resume/step-through execution. - * Highlight blocks as they execute. - * Completely isolated from browser's JS. - -## Run the Interpreter - -First, download the JS Interpreter from GitHub and add it to your page: - -``` - -``` - -The simplest method of calling it is to generate the JavaScript, create the interpreter, and run the code: - -``` -var code = Blockly.JavaScript.workspaceToCode(); -var myInterpreter = new Interpreter(code); -myInterpreter.run(); -``` - -## Step the Interpreter - -In order to execute the code slower, or in a more controlled manner, replace the call to ` run ` with a loop that steps (in this case one step every 10ms): - -``` -function nextStep() { - if (myInterpreter.step()) { - window.setTimeout(nextStep, 10); - } -} -nextStep(); -``` - -Note that each step is not a line or a block, it is a semantic unit in JavaScript, which may be extremely fine-grained. - -## Add an API - -The JS Interpreter is a sandbox that is completely isolated from the browser. Any blocks that perform actions with the outside world require an API added to the interpreter. For a full description, see the documentation for the JS Interpreter. But to start with, here is the API needed to support the alert and prompt blocks: - -``` -function initApi(interpreter, scope) { - // Add an API function for the alert() block. - var wrapper = function(text) { - text = text ? text.toString() : ''; - return interpreter.createPrimitive(alert(text)); - }; - interpreter.setProperty(scope, 'alert', - interpreter.createNativeFunction(wrapper)); - - // Add an API function for the prompt() block. - wrapper = function(text) { - text = text ? text.toString() : ''; - return interpreter.createPrimitive(prompt(text)); - }; - interpreter.setProperty(scope, 'prompt', - interpreter.createNativeFunction(wrapper)); -} -``` - -Then modify your interpreter initialization to pass in the initApi function: - -``` -var myInterpreter = new Interpreter(code, initApi); -``` - -The alert and prompt blocks are the only two blocks in the default set of blocks that require a custom API for the interpreter. - -## Highlight Blocks - -Some applications that use Blockly will want to highlight the currently executing block as the code runs. This may be done on a statement-by-statement level by setting ` STATEMENT_PREFIX ` prior to generating the JavaScript code: - -``` -Blockly.JavaScript.STATEMENT_PREFIX = 'highlightBlock(%1);\n'; -Blockly.JavaScript.addReservedWords('highlightBlock'); -``` - -This results in the statement ` highlight('123'); ` being added to before every statement, where ` 123 ` is the serial number of the block to be highlighted. Then create the API for the highlighting function: - -``` -function initApi(interpreter, scope) { - // Add an API function for highlighting blocks. - var wrapper = function(id) { - id = id ? id.toString() : ''; - return interpreter.createPrimitive(Blockly.mainWorkspace.highlightBlock(id)); - }; - interpreter.setProperty(scope, 'highlightBlock', - interpreter.createNativeFunction(wrapper)); -} -``` - -More sophisticated applications might wish to repeatedly execute steps without pause until a highlight command is reached, then pause. This strategy simulates line-by-line execution. The example below uses this approach. - -## Example - -Here is [a live demo](https://blockly-demo.appspot.com/static/demos/interpreter/index.html) of interpreting JavaScript step by step. \ No newline at end of file diff --git a/Klingon.md b/Klingon.md deleted file mode 100644 index de9fd69..0000000 --- a/Klingon.md +++ /dev/null @@ -1,59 +0,0 @@ -On 1 April 2014 we released a -[Klingon translation of Blockly](https://blockly-demo.appspot.com/static/apps/code/index.html?lang=tlh#ortpyd). -Klingon is an unusual choice for a translation, and on this page we wanted to -give some context on the hows and whys, as well as how you can help. - -![](klingon.png) - -## Why? - -Blockly has been translated into over 40 languages, including RTL languages such -as Arabic and Hebrew. We feel that it is important that novice programmers are -able to learn the fundamentals of programming in their own language, before -making the transition to conventional English-based programming languages. - -Klingon is a real language in every sense of the word. It is not just a -collection of made-up words thrown together for a movie. Instead, it has been -crafted by linguists over the course of decades. The Klingon language has a -complicated grammar that is completely unique. - -Consider word order. English follows the Subject-Verb-Object order ("The cat -eats the food."). Hungarian follows the Object-Subject-Verb order ("The food -the cat eats."). Hebrew follows the Verb-Subject-Object order ("Eats the cat -the food."). Klingon is the most bizarre, with Object-Verb-Subject order ("The -food eats the cat."). Supporting Klingon is the ultimate test of Blockly's -flexibility. Block inputs need to be reordered, suffix groups need to be added, -rules for plurals need to be rethought. Infrastructure improvements made during -the course of translating to Klingon help us support all languages. - -## Who? - -The number of Google employees who are fluent in Klingon is larger than one -might expect (and we are hiring). Google's Klingon language group maintains -a style guide for terminology so that different applications use a consistent -vocabulary. - -We are always pleased when volunteers come forward to contribute new -translations or corrections -- whether for Klingon, or other languages. - -## How? - -Most of [Blockly's translations](Translation) are done by volunteers using -Translatewiki. Unfortunately, Klingon is not in their language matrix. -As a result, Klingon contributors need to edit two files manually: - -https://github.com/google/blockly/tree/master/msg/json/tlh.json - -and - -https://github.com/google/blockly/tree/master/apps/json/tlh.json - -See the ` en.json ` files in each directory for the English phrases (including -those not yet translated to Klingon), and the ` qqq.json ` files for descriptions. -We actively do not want tooltip messages or help URLs translated since they -offer useful context for those new to Klingon. - -All phrases _must_ be manually translated. Bing Translate produces such -translations as ` "Library" -> "be'nI''a'wI', Datu'" ` which actually means -` "discover my big sister" `. -Clearly this would be an inadvisable phrase to use in a Klingon environment. diff --git a/Language.md b/Language.md deleted file mode 100644 index 4a5c006..0000000 --- a/Language.md +++ /dev/null @@ -1,11 +0,0 @@ -# Language Design Philosophy - -The primary users of Blockly are novice programmers. However, in addition to wanting to enable these users to do useful work, we also want to actively support a smooth migration to JavaScript once they outgrow Blockly. This drives several design decisions. - -## One-based Lists - -Novice programmers freak out when they encounter zero-based lists for the first time. As a result, Blockly follows the lead of Lua and Lambda Moo by making list and string indexing one-based. - -## Variable Names - -Novice programmers do not expect that ` location_X ` and ` location_x ` are different variables. As a result, Blockly follows the lead of BASIC and HTML by making variables case-insensitive. Also, Blockly does not require that variables conform to the typical ` [_A-Za-z][_A-Za-z0-9]* ` scheme. If one wants to name a variable ` List of zip codes ` or \ No newline at end of file diff --git a/LanguageGenerators.md b/LanguageGenerators.md deleted file mode 100644 index 64a0575..0000000 --- a/LanguageGenerators.md +++ /dev/null @@ -1,74 +0,0 @@ -**[Installation](wiki/Installation): Language Generators** - -# Introduction - -Most applications of Blockly require the user's program to be translated into JavaScript, -Python, Dart, or some other language. This action is performed on the client-side by Blockly. - -## Generating Code - -The first step is to include the generator for the language in question. -Right after ` blockly_compressed.js ` is loaded, load the generator(s) needed. -Here is the JavaScript generator: - -``` - -``` - -The user's blocks may be exported to code at any time from your application with this call: - -``` - var code = Blockly.JavaScript.workspaceToCode(); -``` - -Replace ` JavaScript ` with ` Python ` or ` Dart ` in all preceding lines to switch the language generated. - -## Realtime Generation - -Generating code is an extremely fast operation, so there's no harm in calling this function frequently. A common strategy is to generate and display code in realtime by adding a listener to Blockly's change event: - -``` - function myUpdateFunction() { - var code = Blockly.JavaScript.workspaceToCode(); - document.getElementById('textarea').value = code; - } - Blockly.addChangeListener(myUpdateFunction); -``` - -## Running JavaScript Code - -If JavaScript code is generated, it may be executed right in the browser: - -``` - Blockly.JavaScript.addReservedWords('code'); - var code = Blockly.JavaScript.workspaceToCode(); - try { - eval(code); - } catch (e) { - alert(e); - } -``` - -Basically, the above snippet just generates the code and evals it. However, there are a couple of refinements. -One refinement is that the eval is wrapped in a ` try `/` catch ` so that any runtime errors are visible, instead of failing quietly. -Another refinement is that ` code ` is added to the list of reserved words so that if the user's code contains a variable of that name it will be automatically renamed instead of colliding. Any local variables should be reserved in this way. - -## Infinite Loops - -Although the resulting code is guaranteed to be syntactically correct at all times, it may contain infinite loops. -Since solving the [Halting problem](https://en.wikipedia.org/wiki/Halting_problem) is beyond Blockly's scope (!) the best approach for dealing with these cases is to maintain a counter and decrement it every time an iteration is performed. -To accomplish this, just set ` Blockly.JavaScript.INFINITE_LOOP_TRAP ` to a code snippet which will be inserted into every loop and every function. Here is an example: - -``` - window.LoopTrap = 1000; - Blockly.JavaScript.INFINITE_LOOP_TRAP = 'if(--window.LoopTrap == 0) throw "Infinite loop.";\n'; - var code = Blockly.JavaScript.workspaceToCode(); -``` - -## JS Interpreter - -Instead of using ` eval() `, a completely different way to run JavaScript code is to use a [JavaScript Interpreter](wiki/JSInterpreter). This allows for step-by-step execution at any speed. Blocks may be highlighted as they are executed. Infinite loops are no longer an issue. Security is guaranteed. The JS Interpreter is recommended for any non-trivial applications. - -## Example - -Here is [a live demo](https://blockly-demo.appspot.com/static/demos/generator/index.html) of generating and executing JavaScript. \ No newline at end of file diff --git a/help/Lists.md b/Lists.md similarity index 85% rename from help/Lists.md rename to Lists.md index 838906b..482d782 100644 --- a/help/Lists.md +++ b/Lists.md @@ -9,34 +9,34 @@ As in everyday speech, a Blockly list is an ordered collection of items, such as The simplest list is the empty list, which is created with the **create empty list** block: -![](help/list-create-empty-list.png) +![](list-create-empty-list.png) ## create list with ### basic usage The **create list with** block allows the user to specify the initial values in a new list. In this example, a list of words is being created and placed in a variable named **letters**: -![](help/list-create-list-with-text.png) +![](list-create-list-with-text.png) For this document, we'll denote this list as ["alpha", "beta", "gamma"], and we will refer below to the variables defined in this section. This shows the creation of a list of numbers: -![](help/list-create-list-with-numbers.png) +![](list-create-list-with-numbers.png) This creates a list of colours: -![](help/list-create-list-with-colours.png) +![](list-create-list-with-colours.png) It is less common, but possible, to create a list with values of different types: -![](help/list-create-list-with-mixture.png) +![](list-create-list-with-mixture.png) ### changing number of inputs To change the number of inputs, click on the plus ("+") icon. This opens a new window: -![](help/list-create-list-modify-tooltip.png) +![](list-create-list-modify-tooltip.png) You can then drag **item** sublocks from the left side of the window into the **if** block on the right side to add a new input, as shown: @@ -49,7 +49,7 @@ While the new item was added at the bottom in this example, it can be added anyw The **create list with item** block lets you create a list that has the specified number of copies of an item. For example, the following blocks set the variable **words** to the list containing ["very", "very", "very"]. -![](help/list-create-list-with-item.png) +![](list-create-list-with-item.png) # Checking a List's Length @@ -57,7 +57,7 @@ The **create list with item** block lets you create a list that has the specifie The value of an **is empty** block is **true** if its input is the empty list and **false** if it is anything else (including a non-list). IS THIS TRUE? The value of the following blocks would be **false** because the variable **colours** is not empty: it has three items. -![](help/list-empty.png) +![](list-empty.png) Note the similarity to the ["is empty" block for text](Text#Checking_for_empty_text). @@ -65,11 +65,11 @@ Note the similarity to the ["is empty" block for text](Text#Checking_for_empty_t The value of the **length of** block is the number of elements in the list used as an input. For example, the value of the following blocks would be 3 because colour has three items. -![](help/list-length.png) +![](list-length.png) Note that the **length of** block tells you how many items are in the list, not how many _different_ items are in it. For example, the following has the value 3, even though **words** consists of three copies of the same text (["very", "very", "very"]). -![](help/list-length2.png) +![](list-length2.png) Note the similarity to the ["length of" block for text](Text#Text_length). @@ -77,15 +77,15 @@ Note the similarity to the ["length of" block for text](Text#Text_length). These blocks find the position of an item in a list. For example, the following has a value of 1 because the first appearance of "very" is as the beginning of the **words** list (["very", "very", "very"]). -![](help/list-find-first1.png) +![](list-find-first1.png) The result of the following is 3 because the last appearance of "very" in **words** is in position 3. -![](help/list-find-last.png) +![](list-find-last.png) If the item is nowhere in the list, the result is in the value 0, as in this example: -![](help/list-find-first2.png) +![](list-find-first2.png) These blocks are analogous to [the ones for finding letters in text](Text#Finding_text). @@ -95,42 +95,42 @@ These blocks are analogous to [the ones for finding letters in text](Text#Findin Recall the definition of the list **colours**: -![](help/list-create-list-with-colours.png) +![](list-create-list-with-colours.png) The following block gets the color blue because it is the second element in the list (counting from the beginning on the left): -![](help/list-in-list-get1.png) +![](list-in-list-get1.png) This gets green because it is the second element counting from the right end: -![](help/list-in-list-get2.png) +![](list-in-list-get2.png) This gets the first element, red: -![](help/list-in-list-get3.png) +![](list-in-list-get3.png) This gets the last element, yellow: -![](help/list-in-list-get4.png) +![](list-in-list-get4.png) This randomly selects an item from the list, returning any of red, blue, green, or yellow with equal likelihood. -![](help/list-in-list-get5.png) +![](list-in-list-get5.png) ### Getting and removing an item A dropdown menu on the **in list ... get** block changes it to **in list ... get and remove**, which provides the same otuput but also modifies the original list: -![](help/list-in-list-get-options.png) +![](list-in-list-get-options.png) This example sets the variable **first letter** to "alpha" and leaves **letters** as: ["beta", "gamma"]. -![](help/list-in-list-get-and-remove.png) +![](list-in-list-get-and-remove.png) ### Removing an item Selecting "remove" on the dropdown causes the plug on the left of the block to disappear: -![](help/list-in-list-remove.png) +![](list-in-list-remove.png) This removes the first item from **letters**. @@ -138,15 +138,15 @@ This removes the first item from **letters**. The **in list ... get sublist** block is similar to the **in list ... get** block except that it extracts a sublist, rather than an individual item. There are several options for how the start and end of the sublist can be specified: -![](help/list-sub-list1.png) +![](list-sub-list1.png) -![](help/list-sub-list2.png) +![](list-sub-list2.png) A few languages (notably Hungarian) require text following the right socket (hole). This is referred to as a "tail" message. In this example, a new list **first letters** is created. This new list has two elements: ["alpha", "beta"]. -![](help/list-sub-list-example.png) +![](list-sub-list-example.png) Note that this block does not modify the original list. @@ -156,7 +156,7 @@ Note that this block does not modify the original list. The **in list ... set** block replaces the item at a specified location in a list with a different item. -![](help/list-set.png) +![](list-set.png) For the meaning of each of the dropdown options, see the [previous section](Lists#Getting_Items_from_a_List). @@ -164,13 +164,13 @@ The following example does two things: 1. The list **words** is created with 3 items: ["very", "very", "very"]. 1. The third item in the list is replaced by "good". The new value of **words** is ["very", "very", "good"]. -![](help/list-set-example.png) +![](list-set-example.png) ## in list ... insert at The **in list ... insert at** block is obtained by using the dropdown menu on the **in list ... set** block: -![](help/list-insert-at.png) +![](list-insert-at.png) It inserts a new item into the list at the specified location, before the item previously at that location. The following example (built on an earlier one) does three things: @@ -178,7 +178,7 @@ It inserts a new item into the list at the specified location, before the item p 1. The third item in the list is replaced by "good". The new value of **words** is ["very", "very", "good"]. 1. The word "you're" is inserted at the beginning of the list. The final value of **words** is ["You're", "very", "very", "good"]. -![](help/list-insert-at-example.png) +![](list-insert-at-example.png) # Related Blocks @@ -186,15 +186,15 @@ It inserts a new item into the list at the specified location, before the item p The [print block](Text#Printing_text) in the Text category can print lists. The result of the following program is the shown alert box: -![](help/list-print.png) +![](list-print.png) -![](help/list-print-popup.png) +![](list-print-popup.png) ## Doing something for each item in a list The [for-each block](Loops#for_each) in the Control category performs an operation on every item in a list. For example, these blocks individually print each item in the list: -![](help/control-for-each.png) +![](control-for-each.png) This does not remove the items from the original list. diff --git a/help/Logic.md b/Logic.md similarity index 92% rename from help/Logic.md rename to Logic.md index 663db62..5597196 100644 --- a/help/Logic.md +++ b/Logic.md @@ -11,7 +11,7 @@ Boolean values (also called _conditions_) are used in these control block, which One of the many examples from those pages is: -![](help/if-else.png) +![](if-else.png) If the value of the variable **x** is greater than 100, the condition is **true**, and the text "What a big number!" is printed. If the value of **x** is not greater than 100, the condition is **false**, and "That's not very big." is printed. @@ -25,13 +25,13 @@ If a block expects a Boolean value as an input, it usually interprets an absent A single block, with a dropdown specifying either **true** or **false**, can be used to get a boolean value: -![](help/logic-true-false.png) +![](logic-true-false.png) ## comparisons There are six comparison operators. Each takes two inputs (normally numbers) and returns true or false depending on how the inputs compare with each other. -![](help/logic-compare.png) +![](logic-compare.png) The six operators are: equals, not equals, less than, less than or equal, greater than, greater than or equal. @@ -39,22 +39,22 @@ The six operators are: equals, not equals, less than, less than or equal, greate The **and** block will return **true** only if both of its two inputs are also true. -![](help/logic-and.png) +![](logic-and.png) The **or** block will return **true** if either of its two inputs are true. -![](help/logic-or.png) +![](logic-or.png) ## not The **not** block converts its Boolean input into its opposite. For example, the result of: -![](help/logic-not-true.png) +![](logic-not-true.png) is false. As mentioned above, if no input is provided, a value of **true** is assumed, so the following block produces the value **false**: -![](help/logic-not.png) +![](logic-not.png) Leaving an input empty is not recommended, however. diff --git a/help/Loops.md b/Loops.md similarity index 94% rename from help/Loops.md rename to Loops.md index 93d08b9..820f4da 100644 --- a/help/Loops.md +++ b/Loops.md @@ -9,7 +9,7 @@ The **Control** category holds blocks that control whether other blocks placed i The simplest "repeat" block runs the code in its body the specified number of times. For example, the following block will print "Hello!" ten times. -![](help/control-repeat.png) +![](control-repeat.png) ### repeat while @@ -22,7 +22,7 @@ Imagine a game in which a player rolls a die and adds up all of the values rolle 1. The variable **total** gets increased by **roll**. 1. The end of the loop having been reached, control goes back to step 2. -![](help/control-repeat-while.png) +![](control-repeat-while.png) When the loop completes, any subsequent blocks (not shown) would be run. In our example, the loop would end after some number of random numbers in the range 1 to 6 had been printed, and the variable **total** would hold the sum of these numbers, which would be guaranteed to be at least 30. @@ -32,23 +32,23 @@ For more information, see https://en.wikipedia.org/wiki/While_loop. "Repeat while" loops repeat their bodies _while_ some condition is true. Repeat-until loops are similar except that they repeat their bodies _until_ some condition is true. The following blocks are equivalent to the previous example because the loop contains until **total** is greater than or equal to 30. -![](help/control-repeat-until.png) +![](control-repeat-until.png) ## count with The **count with** block (called a [for loop](https://en.wikipedia.org/wiki/For_loop) in most programming languages) advances a variable from the first value to the second value by the increment amount (third value), running the body once for each value. For example, the following program prints the numbers 1, 3, and 5. -![](help/control-count-with.png) +![](control-count-with.png) As shown by the two following loops, each of which prints the numbers 5, 3, and 1, the first input may be larger than the second. The behavior is the same whether the increment amount (third value) is positive or negative. -![](help/control-for-each-down.png) +![](control-for-each-down.png) ## for each The **for each** block (see https://en.wikipedia.org/wiki/Foreach) is similar, except instead of giving the loop variable values in a numeric sequence, it uses the values from a list in turn. The following program prints each element of the list: "alpha", "beta", "gamma". -![](help/control-for-each.png) +![](control-for-each.png) # Loop Termination Blocks @@ -60,10 +60,10 @@ The **continue with next iteration** (called [continue](https://en.wikipedia.org The following program prints "alpha" on the first iteration of the loop. On the second iteration, the **continue with next iteration** block is run, skipping the printing of "beta". On the final iteration, "gamma" is printed. -![](help/control-for-each-continue.png) +![](control-for-each-continue.png) ## break out of loop The **break out of loop** block provides [an early exit from a loop](https://en.wikipedia.org/wiki/Control_flow#Early_exit_from_loops). The following program prints "alpha" on the first iteration and "breaks out" of the loop on the second iteration when the loop variable is equal to "beta". The third item in the list is never reached. -![](help/control-for-each-break.png) +![](control-for-each-break.png) diff --git a/OperatorPrecedence.md b/OperatorPrecedence.md deleted file mode 100644 index 24938ab..0000000 --- a/OperatorPrecedence.md +++ /dev/null @@ -1,84 +0,0 @@ -**[Creating Custom Blocks](CustomBlocks): [Generating Code](GeneratingCode): Operator Precedence** - -Code generators are used to convert Blockly's programs into JavaScript, Python, Dart, etc. The most challenging issue when writing a code generator for a new block is handling the order of operations so that the resulting code executes as intended. - -# Bad Parentheses - -Consider the following assembly of blocks. - -![](operatorPrecedence.png) - -If the generators were not aware of operator precedence, the resulting JavaScript code would be: -``` - alert(2 * 3 + 4); -``` -This is obviously incorrect, since the multiplication operator rips apart the addition, grabbing the '3' for itself. One solution is to wrap the result of every value block in parentheses: -``` - alert(((2) * ((3) + (4))); -``` -This solution works perfectly, but it results in extremely messy code with large numbers of redundant parentheses. For some use cases this is not an issue. If human eyes are never going to see the generated code, then this is acceptable. However, Blockly is often used as an educational tool to introduce programming, a use case which relies on generating human-readable code. - -# Good Parentheses - -To generate correct code without an unreasonable number of parentheses, each language generator is provided with an ordered list of precedences. Here is the list for JavaScript: - -``` -Blockly.JavaScript.ORDER_ATOMIC = 0; // 0 "" ... -Blockly.JavaScript.ORDER_MEMBER = 1; // . [] -Blockly.JavaScript.ORDER_NEW = 1; // new -Blockly.JavaScript.ORDER_FUNCTION_CALL = 2; // () -Blockly.JavaScript.ORDER_INCREMENT = 3; // ++ -Blockly.JavaScript.ORDER_DECREMENT = 3; // -- -Blockly.JavaScript.ORDER_LOGICAL_NOT = 4; // ! -Blockly.JavaScript.ORDER_BITWISE_NOT = 4; // ~ -Blockly.JavaScript.ORDER_UNARY_PLUS = 4; // + -Blockly.JavaScript.ORDER_UNARY_NEGATION = 4; // - -Blockly.JavaScript.ORDER_TYPEOF = 4; // typeof -Blockly.JavaScript.ORDER_VOID = 4; // void -Blockly.JavaScript.ORDER_DELETE = 4; // delete -Blockly.JavaScript.ORDER_MULTIPLICATION = 5; // * -Blockly.JavaScript.ORDER_DIVISION = 5; // / -Blockly.JavaScript.ORDER_MODULUS = 5; // % -Blockly.JavaScript.ORDER_ADDITION = 6; // + -Blockly.JavaScript.ORDER_SUBTRACTION = 6; // - -Blockly.JavaScript.ORDER_BITWISE_SHIFT = 7; // << >> >>> -Blockly.JavaScript.ORDER_RELATIONAL = 8; // < <= > >= -Blockly.JavaScript.ORDER_IN = 8; // in -Blockly.JavaScript.ORDER_INSTANCEOF = 8; // instanceof -Blockly.JavaScript.ORDER_EQUALITY = 9; // == != === !== -Blockly.JavaScript.ORDER_BITWISE_AND = 10; // & -Blockly.JavaScript.ORDER_BITWISE_XOR = 11; // ^ -Blockly.JavaScript.ORDER_BITWISE_OR = 12; // | -Blockly.JavaScript.ORDER_LOGICAL_AND = 13; // && -Blockly.JavaScript.ORDER_LOGICAL_OR = 14; // || -Blockly.JavaScript.ORDER_CONDITIONAL = 15; // ?: -Blockly.JavaScript.ORDER_ASSIGNMENT = 16; // = += -= *= /= %= <<= >>= ... -Blockly.JavaScript.ORDER_COMMA = 17; // , -Blockly.JavaScript.ORDER_NONE = 99; // (...) -``` - -The bulk of this list is taken directly from JavaScript's [language spec](https://developer.mozilla.org/en/JavaScript/Reference/Operators/Operator_Precedence), with ` ORDER_ATOMIC ` added to the start and ` ORDER_NONE ` added to the end. - -Applying these orders occurs in two places within each block's generator. The first place is when fetching generated code from a connected value block. In this case we pass the constant which represents the maximum binding strength of any operators adjacent to the sub-block's generated code. For example: -``` - var arg0 = Blockly.JavaScript.valueToCode(this, 'NUM1', Blockly.JavaScript.ORDER_DIVISION); -``` -The second place is when returning generated code from a value block. In this case we pass the constant which represents the minimum binding strength of any operators in the block's generated code. For example: -``` - return [arg0 + ' / ' + arg1, Blockly.JavaScript.ORDER_DIVISION]; -``` - -If the order value returned by the sub-block is weaker than or equal to the order value for the order argument of the parent block, then the ` valueToCode ` function will automatically wrap the contents of the sub-block's code in parentheses to prevent it from being ripped apart by the parent block's code. - -Below are some more examples. In each case the block has one connected sub-block which is represented as 'X' (the contents of 'X' is unknown and doesn't matter). The second column lists the strongest operator which might split 'X'. The third column lists the weakest operator in the final code for the block. - -| **Generated Code** | **Max strength against X** | **Min strength of block** | -|:-------------------|:---------------------------|:--------------------------| -| ` X + 1 ` | ` ORDER_ADDITION ` | ` ORDER_ADDITION ` | -| ` Math.sqrt(X) ` | ` ORDER_NONE ` | ` ORDER_MEMBER ` | -| ` !X && false ` | ` ORDER_LOGICAL_NOT ` | ` ORDER_LOGICAL_AND ` | -| ` foo[X % 60] ` | ` ORDER_MODULUS ` | ` ORDER_MEMBER ` | - -# Math is hard - -Still don't understand? No problem. Just use ` ORDER_ATOMIC ` as the order on every call to ` valueToCode `, and use ` ORDER_NONE ` as the order for the final return statement on every value block. The resulting code will be infested with needless parentheses, but is guaranteed to be correct. \ No newline at end of file diff --git a/RealtimeCollaboration.md b/RealtimeCollaboration.md deleted file mode 100644 index c234ed1..0000000 --- a/RealtimeCollaboration.md +++ /dev/null @@ -1,44 +0,0 @@ -### Introduction -The Blockly library supports realtime collaboration of Blockly programs similar to realtime collaboration of documents in Google Drive, i.e. multiple users can edit the same program at the same time, with all the users seeing each others changes in real time. - -Using Blockly's realtime collaboration feature will provide your users with a sharable link which they can send to a friend or colleague. That link contain the ID of a 'document' which is saved in Google Drive and stores the Blockly program that is being edited. Note that this implies that using Blockly's realtime collaboration feature also provides for persistent storage of a Blockly program (as an alternative to the mechanism described in [CloudStorageWithAppEngine](CloudStorageWithAppEngine)) and therefore is useful even if you don't necessarily care about realtime collaboration. Also note that another benefit of using the realtime collaboration feature will be the ability to 'undo' and 'redo' editing operations. 'Undo' and 'redo' are not currently supported due to a bug (in Blockly code) but hopefully that will soon be fixed. - -Blockly's realtime collaboration is built using [Google Drive's Realtime API](https://developers.google.com/drive/realtime/): a service provided by Google that enables 3rd party developers to incorporate realtime collaboration into their own web applications. - -> _Note that Google Drive's Realtime API currently requires users to have (or create) Google Accounts, so please consider that when deciding to enable realtime collaboration into your app._ - -By default realtime collaboration is currently disabled in Blockly. This wiki page tells you how to enable it. Note that these instructions are for the developer using Blockly for their web application, not for the end user. - -There are two major steps to take in order to enable realtime collaboration in Blockly. One is to [put the appropriate code in your application](#Code_to_enable_realtime_collaboration). The other is to use the [Google Developer Console](https://cloud.google.com/console/project) to [register your application](Registering_with_the_Google_Developer_Console) to use Google Drive's Realtime API. - -### Code to enable realtime collaboration -To enable realtime collaboration in your application's code add a 'realtime: true' option to your Blockly.inject() method call. There are also a set of 'realtimeOptions: ...' that you can add, as well. Here, for example, is the code in for this in [playground.html](https://github.com/google/blockly/tree/master/tests/playground.html) in the Blockly Playground application (which is part of the standard Blockly test codebase): - -``` -function start() { - var toolbox = document.getElementById('toolbox'); - Blockly.inject(document.getElementById('blocklyDiv'), - {rtl: rtl, path: '../', toolbox: toolbox, realtime: true, - realtimeOptions: - {clientId: 'YOUR CLIENT ID GOES HERE', - chatbox: {elementId: 'chatbox'}, - collabElementId: 'collaborators'}}); - if (Blockly.Realtime.isEnabled()) { - enableRealtimeSpecificUi(); - } -} -``` - -The clientId string (i.e 'YOUR CLIENT ID GOES HERE') needs to be replaced by the Client ID that you will obtain when registering your application in the Google Developers Console. That ID should look something like ` '12345678901.apps.googlecontent.com' ` - -The 'chatbox' option is used if you want to have a collaborative chat in you app. Within that option you must specify an 'elementId' suboption which tells the realtime code the id of a textarea that is defined in your app and which will be used for the chat. You can also specify the initial text to be placed in your chatbox by adding an 'initText' suboption. If you don't specify an 'initText' it will default to the value of Blockly.Msg.CHAT, which has the value _'Chat with your collaborator by typing in this box!'_ for english users but can be localized. - -The 'collabElementId' option is used if you want to view thumbnail images (with alt/hover text containing the users' name) of all the users (with available profiles that are accessible to the user) currently collaborating on a particular Blockly-based program. The value of the 'collabElementId' option should be the id of a div in your application where the thumbnails will be placed. See the [playground.html](https://github.com/google/blockly/tree/master/tests/playground.html) for an example of this. - -### Registering with the Google Developer Console -To register your application with the Google Developers Console, please use the instructions that can be found in the [activation section of the Google Drive Realtime API Quickstart documentation](https://developers.google.com/drive/realtime/realtime-quickstart#step_1_activate_the_drive_api). - -### Example -Here's [a simple live demo](https://blockly-realtime-collab.appspot.com/static/demos/realtime/index.html) of Blockly realtime collaboration in action. For something more extensive, here's [a live demo of the Blockly Playground](https://blockly-realtime-collab.appspot.com/static/tests/playground.html) enabled for realtime collaboration. - -The first time you view them you may need to click the 'You must authorize' button. \ No newline at end of file diff --git a/help/Text.md b/Text.md similarity index 85% rename from help/Text.md rename to Text.md index 58badb5..fb8e684 100644 --- a/help/Text.md +++ b/Text.md @@ -12,15 +12,15 @@ Text can contain letters (which may be lower-case or upper-case), numbers, punct ## Text creation The following block creates the piece of text "hello" and stores it in the variable named ` greeting `. -![](help/text-text.png) +![](text-text.png) The **create text with** block combines (concatenates) the value of the ` greeting ` variable and the new text "world" to create the text "helloworld". Note that there is no space between them, since none was in either original text. -![](help/text-create.png) +![](text-create.png) To increase the number of text inputs, click on the plus sign, which changes the view to: -![](help/text-append-modify.png) +![](text-append-modify.png) Additional inputs are added by dragging an "item" block from the gray toolbox on the left into the "join" block. @@ -28,37 +28,37 @@ Additional inputs are added by dragging an "item" block from the gray toolbox on The **to...append text** block adds the given text to the specified variable. In this case, it changes the value of the variable ` greeting ` from "hello" to "hello, there!" -![](help/text-append.png) +![](text-append.png) ## Text length The **length of** blocks count the number of letters, numbers, etc., in each text. The length of "We're #1!" is 9, and the length of the empty text is 0. -![](help/text-length1.png) +![](text-length1.png) -![](help/text-length2.png) +![](text-length2.png) ## Checking for empty text The **is empty** block checks whether the given text is empty (has length 0). The result is **true** in the first case and **false** in the second. -![](help/text-empty2.png) +![](text-empty2.png) -![](help/text-empty1.png) +![](text-empty1.png) ## Finding text These blocks can be used to check whether a piece of text is in another piece of text and, if so, where it appears. For example, this asks for the first occurrence of "e" in "hello". The result is 2. -![](help/text-find-first.png) +![](text-find-first.png) This asks for the _last_ occurrence of "e" in "hello", which, is also 2. -![](help/text-find-last.png) +![](text-find-last.png) Whether **first** or **last** is selected, this block will give the result 0, since "hello" does not contain "z". -![](help/text-find-first-last.png) +![](text-find-first-last.png) ## Extracting text @@ -66,23 +66,23 @@ Whether **first** or **last** is selected, this block will give the result 0, si This gets "b", the second letter in "abcde": -![](help/text-in-text-get1.png) +![](text-in-text-get1.png) This gets "d", the second _to last_ letter in "abcde": -![](help/text-in-text-get2.png) +![](text-in-text-get2.png) This gets "a", the first letter in "abcde": -![](help/text-in-text-get3.png) +![](text-in-text-get3.png) This gets "e", the last letter in "abcde": -![](help/text-in-text-get4.png) +![](text-in-text-get4.png) This gets any of the 5 letters in "abcde" with equal probability: -![](help/text-in-text-get5.png) +![](text-in-text-get5.png) None of these modify the text on which the extraction is performed. @@ -99,7 +99,7 @@ and ending with: In the following example, "abc" is extracted. -![](help/text-get-substring.png) +![](text-get-substring.png) ## Adjusting text case @@ -110,7 +110,7 @@ This block creates a version of the input text that is either: The result of the following block is "HELLO". -![](help/text-case.png) +![](text-case.png) Non-alphabetic characters are not affected. Note that this block on text in languages without case, such as Chinese. @@ -123,13 +123,13 @@ The following block removes space characters from: The result of the following block is "hi there". (Spaces in the middle of the text are not affected.) -![](help/text-trim-spaces.png) +![](text-trim-spaces.png) ## Printing text The **print** block causes the input value to be displayed in a pop-up window, as shown: -![](help/text-print.png) +![](text-print.png) If the code is exported as JavaScript, Python, or Dart, it will be printed to the console (screen). In no case is it sent to the printer, as the name might suggest. @@ -137,12 +137,12 @@ If the code is exported as JavaScript, Python, or Dart, it will be printed to th The following block creates a pop-up window that prompts the user to enter a name. The result is stored in the variable **name**: -![](help/text-prompt.png) +![](text-prompt.png) This is what the current version of the pop-up window looks like: -![](help/text-prompt-popup.png) +![](text-prompt-popup.png) There is also a version of the block for getting a number from the user: -![](help/text-get-number.png) +![](text-get-number.png) diff --git a/Toolbox.md b/Toolbox.md deleted file mode 100644 index 6e7d7c1..0000000 --- a/Toolbox.md +++ /dev/null @@ -1,158 +0,0 @@ -**[Installation](Installation): Defining the Toolbox** - -# Introduction - -The toolbox is the side menu from whence the user may create new blocks. -The structure of the toolbox is specified with XML, which may be either a tree -of nodes, or a string representation. This XML is passed to Blockly when it is -injected into the page. - -Here is a minimal example, using a tree of nodes: - -``` - - -``` - -Here is the same example, using a string representation: - -``` - -``` - -## No Categories - -If there are a small number of blocks, then they may be displayed without any -categories. In this mode all the available blocks are shown in the toolbox, -there are no scrollbars on the main workspace, and the trashcan is not needed. - - -## Categories - -The blocks in the toolbox may be organized in categories. Here are two -categories ('Control' and 'Logic'), each of which contain three blocks: - -``` - -``` - -There are two categories that have special behaviours. Variable and procedure -categories are defined with no contents, but with a ` 'custom' ` property of -` 'VARIABLE' ` or ` 'PROCEDURE' ` respectively. These categories will be populated -automatically with the appropriate blocks. - -``` - - -``` - -## Tree of Categories - -Categories may be nested within other categories. Here are two top-level -categories ('Core' and 'Custom'), each of which contain two sub-categories, -each of which contain blocks: - -``` - -``` - -Note that it is possible for a category to contain both sub-categories and blocks. -In the above example, 'Custom' has two sub-categories ('Move' and 'Turn'), as well -as a block of its own ('start'). - -## Block Groups - -The XML may contain groups of blocks, or customized blocks. Here are three blocks: - 1. A simple ` logic_boolean ` block. - 1. A ` math_number ` block that has been modified to display the number 42 instead of the default of 0. - 1. A ` controls_for ` block that has two ` math_number ` blocks that appear connected to it. - -``` - -``` - -The XML for these groups or customized blocks is the same as Blockly's XML save format. -Thus, the easiest way to construct the XML for such blocks is to use the -[Code application](https://blockly-demo.appspot.com/static/apps/code/en.html) to -build the blocks, then switch to the XML tab and copy the result. - -## Changing the Toolbox - -The application may change the blocks available in the toolbox at any time with a single function call: -``` - Blockly.updateToolbox(newTree); -``` - -As was the case during initial configuration, ` newTree ` may either be a tree of nodes, or a string representation. The only restriction is that the mode cannot be changed; that is if there were categories in the initially-defined toolbox then the new toolbox must also have categories (though the categories may change). Likewise, if the initially-defined toolbox did not have any categories, then the new toolbox may not have any categories. - -Be aware that at this time updating the toolbar causes some minor UI resets: - * In a toolbox with categories, the flyout will close if it was open. - * In a toolbox without categories, any fields changed by the user (such as a dropdown) will revert to the default. - * Any toolbox so long that it extends beyond the page will have its scrollbar jump to the top. - -Here is [a live demo](https://blockly-demo.appspot.com/static/demos/toolbox/index.html) of a tree with categories and block groups. \ No newline at end of file diff --git a/Translation.md b/Translation.md deleted file mode 100644 index 9afb2f1..0000000 --- a/Translation.md +++ /dev/null @@ -1,33 +0,0 @@ -# Introduction - -Our goal is for Blockly to be available in as many languages as possible, so students don't have to struggle with English at the same time as they're learning computer science concepts. - - -# Using Blockly - -If you're not already a Blockly user, try it out. Some good starting places are: - * [Puzzle](https://blockly-games.appspot.com/puzzle) (to learn the Blockly user interface) - * [Maze](https://blockly-games.appspot.com/maze) - * [Code](https://blockly-demo.appspot.com/blockly/apps/code/index.html) (meant for experienced programmers) - -# Translatewiki - -All of Blockly's translations are handled by [translatewiki.net](http://translatewiki.net). - -## Creating an account at Translatewiki - -Use the [Getting started wizard](http://translatewiki.net/w/i.php?title=Special:UserLogin&returnto=Special%3AFirstSteps&type=signup). Steps are: - 1. Creating an account. - 1. Configuring your preferences. You may specify any languages at this step. - 1. Creating your user page. You must specify (at least) "I have a moderate command of" "English" to do translations for Blockly. You should also specify at least one other language that you are able to do translations into. - 1. Request translator permissions. Write a brief introduction, ideally information to give the reviewer reason to believe you're a genuine translator and not a vandal. Press "Send request". You then need to wait to be manually approved, which can take anywhere from a few minutes to a couple of hours (longest during nighttime in Central Europe). **You probably will not be notified that you were approved; just give it a try a little later.** - -Optionally, personalize your user page. You can do this by clicking on your user name, which is shown on the top of the page once you have logged in. Once on your user page, the easiest way to modify it is by clicking on the "Edit with form" tab near the top of the page. - -## Reading about Blockly translation - -Visit [Translating:Blockly](http://translatewiki.net/wiki/Translating:Blockly), which has detailed information for translators. Please contact us with any questions. You can leave a comment on this page or use the translatewiki interface to give feedback. - -## Start translating - -Start translating by clicking on the "Translate this project" link at the top of [Translating:Blockly](http://translatewiki.net/wiki/Translating:Blockly) or going directly to http://translatewiki.net/w/i.php?title=Special:Translate&group=out-blockly-0-all. You may have to click on "English" in the phrase "Translate to English" toward the upper right to change to your language. diff --git a/TranslationForDevelopers.md b/TranslationForDevelopers.md deleted file mode 100644 index bda291e..0000000 --- a/TranslationForDevelopers.md +++ /dev/null @@ -1,308 +0,0 @@ -This document provides what developers should know about Blockly translations. Translators should read [this document](Translation) instead. - -# Introduction - -Internationalization (i18n) is one of Blockly's top priorities. See, for example, [CS in VN](https://neil.fraser.name/news/2013/03/16/). Blockly supports right-to-left and left-to-right scripts, and the [Puzzle application](https://blockly-demo.appspot.com/static/apps/puzzle/index.html) has been translated into over 50 languages. We look forward to getting all of Blockly translated into that many languages. - -# TranslateWiki -We use [TranslateWiki](http://www.translatewiki.net) as our translation console and translator community. We provide them with the following files: - * **qqq.json**, mapping message names to _message documentation_ (information for translators). - * **en.json**, mapping message names to the English-language text. Note that we use Canadian English. - * **_LANG_.json**, mapping message names to the appropriate language text. Messages that have not been translated to the given language will not be present in this file. -_LANG_ is (loosely) an [IETF language tag](https://en.wikipedia.org/wiki/IETF_language_tag), such as "de" for German or "pt-br" for Brazilian Portuguese. See this [incomplete list of languages supported by translatewiki](https://translatewiki.net/wiki/Special:SupportedLanguages). - -TranslateWiki gives us _LANG_.json files and sometimes a modified ` qqq.json ` files with improved messages. All files are transferred through our repository, to which TranslateWiki has access. Our -contact is Siebrand Mazeland. - -# Applications and Tutorials - -The Blockly applications and tutorials (henceforth referred to as "apps") are built with "Soy", also known as [Google Closure templates](https://developers.google.com/closure/templates/), which has [translation tools](https://developers.google.com/closure/templates/docs/translation). Specifically, all messages appear in files whose name ends with the "soy" extension. Messages used by multiple apps are defined in [apps/common.soy](https://github.com/google/blockly/tree/master/apps/common.soy), and have the prefix "Apps." Messages used by only a single app are defined in that app's template.soy file, such as [apps/maze/template.soy](https://github.com/google/blockly/tree/master/apps/maze/template.soy) and prefixed with the name of the application, such as "Maze.". - -## The msg tag -Here is an example of a message definition: - -``` -{msg meaning="Maze.moveForward" - desc="block text - Imperative or infinitive of a verb for a person moving - (walking) in the direction he/she is facing."} - move forward -{/msg} -``` - -Notes: - * The key is defined through the "meaning" attribute: "Maze.moveForward". - * The message documentation for the translator is defined through the "desc" attribute. This appears as the value in the qqq.json file. - * The English language text appears between the "msg" start and end tags. This appears as the value in the en.json file. - -A left brace or right brace can be included in an attribute value by using double braces to introduce and close the "msg" tags and writing "{lb}" [brace](left) for "{" or "{rb}" for "}", as in this definition: - -``` -{{msg meaning="Puzzle.country1Language" - desc="The English language.{lb}{lb}Identical|English{rb}{rb}"}} - English -{{/msg}} -``` -(The TranslateWiki "Identical" tag is shrouded in mystery. It was added to a Blockly file by a TranslateWiki wizard, and I was told not to worry about why.) - -## Placement of the msg tag - -### Messages used only once within a template - -If a message is used only once and the use is within the template, it can be defined where it is used: - -``` - -``` - - -### Messages referenced from JavaScript files -If a message is used by a JavaScript file, such as maze.js or blocks.js, it must be declared within a span: - -``` - - {msg meaning="Maze.moveForward" - desc="block text - Imperative or infinitive of a verb for a person moving - (walking) in the direction he/she is facing."} - move forward - {/msg} - -``` -By convention, the id of the span is the same as the "meaning" key but replaces periods with underscores. The message is referenced from code through the method ` BlocklyApps.getMsg() `, as in the example below from [apps/maze/blocks.js](https://github.com/google/blockly/tree/master/apps/maze/blocks.js): - -``` -Blockly.Blocks['maze_moveForward'] = { - // Block for moving forward. [A portion of the following code is omitted.] - init: function() { - this.setColour(290); - this.appendDummyInput() - .appendField(BlocklyApps.getMsg('Maze_moveForward')); - } -}; -``` - -### Messages used multiple times -If a message is used multiple times within one or multiple template files, all "msg" tags should have the same "meaning" attribute and enclosed text, but only one should have the real description as the "desc" attribute. The others should have "IBID" (case-insensitive). - -If a message is used in more than one app, it should be defined within a span in [apps/common.soy](https://github.com/google/blockly/tree/master/apps/common.soy), and its meaning should be prefixed with "Apps.". For example, common.soy includes: - -``` - - {msg meaning="Apps.blocklyMessage" - desc="The project name. If readers of your language would know approximately how to pronounce 'Blockly', - leave unchanged. Otherwise, include a transliteration in parentheses, such as the Russian: - 'Blockly (\u0411\u043bo\u043a\u043b\u0438)'."} - Blockly - {/msg} - -``` - -Here is a sample use from [apps/turtle/template.soy](https://github.com/google/blockly/tree/master/apps/turtle/template.soy): -``` -{msg meaning="Apps.blocklyMessage" desc="IBID"}Blockly{/msg} -``` - -## Build process - -### Building a single app in English - -Every app's template.soy file contains a comment near the top describing how to rebuild its English-language message file (apps/` * `/generated/en.js). For example, this command appears at the top of [apps/turtle/template.soy](https://github.com/google/blockly/tree/master/apps/turtle/template.soy): - -``` -java -jar ../_soy/SoyToJsSrcCompiler.jar --outputPathFormat generated/en.js --srcs ../common.soy,template.soy -``` - -When run in the apps/turtle directory, this rebuilds [apps/turtle/generated/en.js](https://github.com/google/blockly/tree/master/apps/turtle/generated/en.js). - -Emacs users might want to add the following to their .emacs file to automatically regenerate the appropriate en.js file whenever a template.soy file is saved: -``` -(add-hook 'after-save-hook - (lambda () - (if (string-match "^template.soy\\(<.*>\\)?$" (buffer-name)) - (shell-command "java -jar ../_soy/SoyToJsSrcCompiler.jar --outputPathFormat generated/en.js --srcs ../common.soy,template.soy")))) -``` -Of course, if you have a different path to ` _soy ` or wish to generate "en\_us.js" instead of "en.js", you will need to change the command. - - -### Doing a full build - -Before checking in code, developers should do a full i18n build by following the instructions in comments at the top of [apps/common.soy](https://github.com/google/blockly/tree/master/apps/common.soy). The below diagram shows the build process. It is followed by a description of each step. - -![](i18n_block_diagram.png) - -#### SoyMsgExtractor.jar - -SoyMsgExtractor.jar extracts the messages from the template files into ` extracted_msgs.xlf `. For example, this message: - -``` -{msg meaning="Maze.moveForward" - desc="block text - Imperative or infinitive of a verb for a person moving - (walking) in the direction he/she is facing."} - move forward -{/msg} -``` - -becomes: - -``` - - move forward - block text - Imperative or infinitive of a verb for a person moving - (walking) in the direction he/she is facing. - Maze.moveForward - -``` - -The ` id ` is some sort of hash value that changes whenever the message description changes. - -#### xliff\_to\_json.py - -The script xliff_to_json.py takes ` extracted_msgs.xlf ` as input and generates three JSON files that use message "meanings" (such as `Maze.moveForward') as keys: - * [qqq.json](https://github.com/google/blockly/tree/master/apps/json/qqq.json), where the values are the message documentation (translator instructions). - * [en.json](https://github.com/google/blockly/tree/master/apps/json/en.json), where the values are the English-language messages (e.g., "move forward"). - * [keys.json](https://github.com/google/blockly/tree/master/apps/json/keys.json), where the values are ` id `s from ` extracted_msgs.xlf `, such as "4138774728570944645". - -Note that these do not change the other languages' json files, which were generated by translatewiki. These files are automatically picked up by Siebrand Mazeland at translatewiki, who periodically checks in updated qqq.json and other languages' JSON files as blockly@translatewiki.net. - -#### json\_to\_js.py - -Finally, the script json_to_js.py uses the JSON files and template files to generate JavaScript files for each app-language combination, such as [apps/maze/generated/es.js](https://github.com/google/blockly/tree/master/apps/maze/generated/es.js), the Spanish translation of the maze application. - -## Translation status - -The status of the translations can be found at "https://translatewiki.net/w/i.php?title=Special%3AMessageGroupStats&x=D&group=out-blockly-apps&suppressempty=1". - -To see how complete each application is, run the following from the ` apps/ ` directory: -``` -../i18n/status.py json/*.json --html > status.html -``` -View the resulting file in a browser. Additional options can be seen with: -``` -../i18n/status.py --help -``` - -# The Blockly Language - -"The Blockly language" or "core Blockly" refers to the blocks that are defined in [blocks/](http://code.google.com/p/blockly/source/browse/#svn%2Ftrunk%2Fblocks) and are independent of (although used by) the apps. These include blocks for: - * control flow (such as if and if-else) - * loops - * mathematical and logical functions and values - * functions on text and on lists - * creating and using functions and variables -In this context of "the core Blockly language", "core" does _not_ refer to the directory [core/](http://code.google.com/p/blockly/source/browse/#svn%2Ftrunk%2Fcore), which contains Blockly's low-level base, which is not directly visible to users. - -Because the core Blockly language may be used by developers who do not use Closure or Soy, and because the messages are only referenced from JavaScript, we use a different pipeline than described above for messages for applications and tutorials. - -## messages.js - -### definitions and descriptions - -Messages are defined in the file [msg/messages.js](https://github.com/google/blockly/tree/master/msg/messages.js) using the following format: -``` -/// -Blockly.Msg. = ''; -``` -Descriptions may be multiple lines, each of which is preceded by three slashes (` /// `). The key and English-language text must be on a single line, and the text must be delimited by single quotation marks immediately followed by a semicolon. - -Here is a sample definition: -``` -/// dropdown - This finds the most common numbers ([https://en.wikipedia.org/wiki/Mode_(statistics) modes]) -/// in a list. For example, the modes of the list {1, 3, 9, 3, 9} are {3, 9}. -Blockly.Msg.MATH_ONLIST_OPERATOR_MODE = 'modes of list'; -``` - -By convention, descriptions start with one of the terms listed in https://translatewiki.net/wiki/Translating:Blockly#Messages_associated_with_blocks. It is followed by a hyphen and a message description starting with a capital letter and ending with a period. - -The use of [MediaWiki markup](http://www.mediawiki.org/wiki/Help:Formatting) is encouraged, including external links to this Blockly wiki, Wikipedia, and saved programs illustrating the use of a block. Files may be [uploaded to translatewiki](https://translatewiki.net/wiki/Special:Upload) and referenced as shown in the following example: -``` -/// block text - Title of blocks allowing users to find text. See -/// [https://github.com/google/blockly/wiki/Text#Finding_text -/// https://github.com/google/blockly/wiki/Text#Finding_text]. -/// [[File:Blockly-find-text.png]] -Blockly.Msg.TEXT_INDEXOF_INPUT_INTEXT = 'in text'; -``` -This causes the picture to be displayed in-line for the translator. - -Developers are encouraged to read through [msg/messages.js](https://github.com/google/blockly/tree/master/msg/messages.js) and to use the [Translation](Translation) interface before creating their own messages. - -### synonyms - -In some cases, one message is defined to be equal to another, as in: - -``` -Blockly.Msg.TEXT_APPEND_VARIABLE = Blockly.Msg.VARIABLES_DEFAULT_NAME; -``` - -This says that the default name of the variable in the "text append" block is the same as the general default variable. The format must be exactly as shown. It is not possible to include any other code on the line, such as concatenating two messages. - -These synonyms exist either for historical reasons (they used to have different values) or to facilitate making them different in the future. - -Synonym definitions may appear anywhere in ` messages.js ` after the right-hand value has been defined. - -## Message interpolation - -Ideally, translators should be given sentences, rather than bits of pieces of text to be concatenated with data. This can sometimes be provided through message interpolation, as in this example: - -![](count-with.png) -``` -/// block title - Title of [https://github.com/google/blockly/wiki/Loops#count_with count with] blocks. -Blockly.Msg.CONTROLS_FOR_INPUT_WITH = 'count with'; - -/// block text - Starting with a (usually lower) number in a range (%1), -/// ending with a (usually higher) number in a range (%2), and counting the -/// iterations by a number of steps (%3). As in -/// [https://github.com/google/blockly/wiki/Loops#count_with -/// https://github.com/google/blockly/wiki/Loops#count_with]. -Blockly.Msg.CONTROLS_FOR_INPUT_FROM_TO_BY = 'from %1 to %2 by %3'; -``` -The relevant part of the definition of the 'controls\_for' block in blocks/loops.js is: -``` - this.appendDummyInput() - .appendField(Blockly.Msg.CONTROLS_FOR_INPUT_WITH) - .appendField(new Blockly.FieldVariable(null), 'VAR'); - this.interpolateMsg(Blockly.Msg.CONTROLS_FOR_INPUT_FROM_TO_BY, - ['FROM', 'Number', Blockly.ALIGN_RIGHT], - ['TO', 'Number', Blockly.ALIGN_RIGHT], - ['BY', 'Number', Blockly.ALIGN_RIGHT], - Blockly.ALIGN_RIGHT); -``` -The %1, %2, and %3 are placeholders respectively for the 'FROM', 'TO', and 'BY' numbers. - -Note that the two messages could not have been combined into a single one because interpolation only supports sockets, not dropdowns, text fields, number fields, etc. - -## Build process - -Building consists of two steps: (1) generating JSON files and (2) generating JS files. They are built automatically by the main [build.py script](https://github.com/google/blockly/tree/master/build.py) but can also be built by executing the following two scripts. - -### Generating JSON files - -Translatewiki requires [en.json](https://github.com/google/blockly/tree/master/msg/json/en.json) and [qqq.json](https://github.com/google/blockly/tree/master/msg/json/qqq.json). We also require a file [synonyms.json](https://github.com/google/blockly/tree/master/msg/json/synonyms.json), to keep track of synonymous messages. These three files are generated by running the following command from the ` msg/ ` directory: -``` -../i18n/js_to_json.py -``` -The script [js\_to\_json.py](https://github.com/google/blockly/tree/master/i18n/js_to_json.py) contains the regular expressions matching lines in ` messages.js `, in case any question arises about syntax. - -### Generating JavaScript files - -The JSON files produced in the previous step, as well as any obtained from translatewiki are used by the following script: -``` -../i18n/create_messages.py json/*.json -``` -This populates the directory [msg/js/](https://github.com/google/blockly/tree/master/msg/js). -Any messages not defined in a language's .json file will have the original English-language text, as shown by this excerpt from zh-tw.js: -``` -Blockly.Msg.CHANGE_VALUE_TITLE = "修改值:"; -Blockly.Msg.COLLAPSE_ALL = "Collapse Blocks"; // untranslated -``` -The comment "untranslated" is added automatically by [create\_messages.py](https://github.com/google/blockly/tree/master/i18n/create_messages.py). - -## Translation status - -The status of the translations can be found at "https://translatewiki.net/w/i.php?title=Special%3AMessageGroupStats&x=D&group=out-blockly-core&suppressempty=1". diff --git a/Tutorial_CreateYourFirstBlock.md b/Tutorial_CreateYourFirstBlock.md deleted file mode 100644 index 6d6955e..0000000 --- a/Tutorial_CreateYourFirstBlock.md +++ /dev/null @@ -1,260 +0,0 @@ -# Tutorial - Create and add your first block - Step-by-step guide - -![http://i289.photobucket.com/albums/ll234/syntax_photos/BlockFactory_MoveTo_Preview_zps16065a5d.png](http://i289.photobucket.com/albums/ll234/syntax_photos/BlockFactory_MoveTo_Preview_zps16065a5d.png) -
-

Introduction

- -This tutorial a complete walk though for adding a block to the turtle app.
-By the end of the tutorial you will have a fully functional new block in the turtle tool box.
-This new block, called move to will move the turtle directly to a specified x/y location.
-
-
-

Before you begin

- -The basic tools you need for this tutorial are:
-
-
  • Subversion
- -
  • A simple text editor (also an IDE for Javascript code editor would be good)
- -
  • The Blockly source code
- -
  • A browser
- -
-

Installing Subversion

-
-For Linux its a simple matter of running this in a terminal window:
-
	> sudo apt-get install subversion
-
- -For Windows see http://tortoisesvn.net/ - - -

Install the Blockly source code

-
-To get the latest verison of Blockly run the following from a terminal window:
-
	> svn checkout http://blockly.googlecode.com/svn/trunk/ blockly
-
-Once everything is downloaded you will have a new Blockly folder containing the code and examples.
-Since this tutorial modifies the turtle app files you might want to copy the folder and contents for backup purposes.
-The folder in question is called "turtle" and exists in the "blockly/apps/" folder.
-
-
-

Pre-checks

- -Open the Blockly/apps/turtle folder. Test the turtle app by double-clicking the index.html file.
-Make sure it runs in the browser.
-
-The files which are going to be modified are turtle.js, blocks.js, and template.soy within the folder.
-
-
-
-

Step 1 - Designing the block

- -Let's start by designing the block itself. Open the online block designer. This designer helps to define how the new block will look and function.
-
-Open this link: https://blockly-demo.appspot.com/static/apps/blockfactory/index.html - -Design the block as per this layout:
-
- - -The preview block should look like this:
-
- - -Once complete you can see two sets of generated code in the tables to the right.
-
-

Blockly Language Code

-
Blockly.Blocks['move_to'] = {
- init: function() {
- this.setHelpUrl('http://www.example.com/');
- this.setColour(160);
- this.appendDummyInput()
- .appendField("move to");
- this.appendValueInput("XPOS")
- .setCheck("Number")
- .appendField("x");
- this.appendValueInput("YPOS")
- .setCheck("Number")
- .appendField("y");
- this.setInputsInline(true);
- this.setPreviousStatement(true);
- this.setNextStatement(true);
- this.setTooltip('');
-}
-
- -

Blockly JavaScript stub code

-
Blockly.JavaScript['move_to'] = function(block) {
- var value_xpos = Blockly.JavaScript.valueToCode(block, 'XPOS', Blockly.JavaScript.ORDER_ATOMIC);
- var value_ypos = Blockly.JavaScript.valueToCode(block, 'YPOS', Blockly.JavaScript.ORDER_ATOMIC);
- // TODO: Assemble JavaScript into code variable.
- var code = '...';
- return code;
-};
-
- -For more details on block design see:
-https://code.google.com/p/blockly/wiki/DefiningBlocks - -For more details on the code generation see:
-https://code.google.com/p/blockly/wiki/GeneratingCode - -
-

Step 2 - Editing the blocks.js file

- - -Open blocks.js via a standard text editor or IDE.
-
-Taking the above two blocks of code, paste both parts in after this section of code.
-
-
Blockly.JavaScript['draw_move'] = function(block) {
- ...
-};
-
- -The code will now need some modification. Replace the source code above with:
-
-
Blockly.Blocks['draw_moveto'] = {
- // move turtle to absolute x,y location
- // for reference 0,0 is top/let and 200,200 is centre
- init: function() {
- this.setHelpUrl('');
- this.setColour(160);
- this.appendDummyInput()
- .appendField(BlocklyApps.getMsg('Turtle_moveTo'));
- this.appendValueInput("XPOS")
- .setCheck("Number")
- .appendField("x");
- this.appendValueInput("YPOS")
- .setCheck("Number")
- .appendField("y");
- this.setInputsInline(true);
- this.setPreviousStatement(true);
- this.setNextStatement(true);
- this.setTooltip(BlocklyApps.getMsg('Turtle_moveToTooltip'));
- }
-};
-
-Blockly.JavaScript['draw_moveto'] = function(block) {
- // Generate JavaScript for moving to absolute position
- var xpos = Blockly.JavaScript.valueToCode(block, 'XPOS', Blockly.JavaScript.ORDER_NONE) || '0';
- var ypos = Blockly.JavaScript.valueToCode(block, 'YPOS', Blockly.JavaScript.ORDER_NONE) || '0';
- return 'Turtle.moveTo(' + xpos + ',' + ypos + ', \'block_id_' + block.id + '\');\n';
-};
-
- -Now save the file changes.
-
-
-
-

Step 3 - Editing the turtle.js file

- -Open turtle.js via a standard text editor or IDE.
-
-Look for the Turtle API section. It comes under the // Turtle API comment.
-
-Add the following API block of code after the Turtle.moveBackward{} API block.
-
	Turtle.moveTo = function(xpos, ypos, id) {
- BlocklyApps.log.push(['MT', xpos, ypos, id]);
- };
-
-To cater for this API call another piece of code needs adding into the Turtle.step{} block.
-Drop this piece of code inside the switch (command) {...} block of the Turtle.step function.
-A sensible place is between the 'FD' (Forward) and 'RT' (Right Turn) sections:
-
    case 'MT': // Move To
- Turtle.x=values[0];
- Turtle.y=values[1];
- break;
-
- -Now save the file changes.
-
-
-
-

Step 4 - Editing the template.soy file

- -Open the template.soy file for editing.
-
-Within the {template .messages} block open up some space and paste in the following.
-This is helper/documentation for the move_to block.
-A recommended location is after the <span id="Turtle_moveBackward"> ... ></span> part in the document.
-
    <span id="Turtle_moveToTooltip">{msg meaning="Turtle.moveToTooltip" desc="Moves the turtle to an absolute x and y location via 2 numbers. Top left is 0,0 whilst centre is 200,200 (default)."}Moves turtle to the absolute x/y location without drawing a mark{/msg}</span>
- <span id="Turtle_moveTo">{msg meaning="Turtle.moveTo" desc="block text - Infinitive or imperative of a verb to move the turtle to an absolute x and y location via 2 numbers. Top left is 0,0 whilst centre is 200,200 (default)."}move to{/msg}</span>
-
-In order to make the new block appear in the tool box scroll down to the {template .toolbox} section and insert the following. A logical place for the "move to" block to appear in the tool box is after existing the "draw move" block. Therefore, paste this section after
 ... 
-
-Unknown end tag for

-
-
- -
	<block type="draw_moveto">
- <value name="XPOS">
- <block type="math_number">
- <field name="NUM">200</field>
- </block>
- </value>
- <value name="YPOS">
- <block type="math_number">
- <field name="NUM">200</field>
- </block>
- </value>
- </block>
-
- -Now save the file changes.
-
-
-
-

Step 5 - Compling the code changes

- -Before continuing ensure all changes to the turtle.js, blocks.js, and template.soy files have been saved.
-
-Now that the code has been entered it's time to compile the changes.
-Open up a terminal window and navigate into the turtle folder. For example:
-
> cd <myfolder>/blockly/apps/turtle
-
-Look at the top of the template.soy document. You should find an entry like this:
-
	java -jar ../_soy/SoyToJsSrcCompiler.jar --outputPathFormat generated/en.js --srcs ../common.soy,template.soy
-
-Copy this line then paste it into the terminal window. After a few seconds the compiling process should complete. If all went well (no reported errors) you can now test the new block.
-
-
-
-

Step 6 - Testing the new block

- -From the turtles folder double-click index.html. This should launch the turtle blockly program in your browser.
-Open the toolbox and check to see if the new ''move to'' block is present.
-Hovering over the new block should reveal the help text popup balloon.
-
-Constuct a simple test block and run the code. Example:
-
- - -You can check that the code is being correctly to generated by pressing the code button:
-
- - -The generated code should look like this:
-
var x_position;
-
-Turtle.turnRight(30);
-for (x_position = 100; x_position <= 300; x_position += 15) {
- Turtle.moveTo(x_position,220);
- Turtle.moveForward(50);
-}
-
- -

- -

END OF TUTORIAL

- -That's your first block under way. If you want to modify the blocks functionality/appearance then its just a matter of changing the code and re-compiling (as per Step 5).
-
-Note that you can leave the browser open but you will need to refresh the page in order to see new changes take place.
-
-(TODO: Link to Google+ page.)
-
-Please send any questions you have to the support group, not as a comment to this page. \ No newline at end of file diff --git a/UnitTesting.md b/UnitTesting.md deleted file mode 100644 index 9dead82..0000000 --- a/UnitTesting.md +++ /dev/null @@ -1,18 +0,0 @@ -After changing or adding code, you should run existing unit tests and consider writing more. - -# Running unit tests - 1. Load ` tests/generators/index.html ` in a browser. - 1. Choose the relevant part of the system to test from the drop-down menu, and click "Load". Blocks should appear in the workspace. - 1. Click on "JavaScript". - 1. Copy and run the generated code in a JavaScript console. If the output ends with "OK", the test has passed. - 1. Click on "Python". - 1. Copy and run the generated code in a Python interpreter. If the output ends with "OK", the test has passed. - 1. Click on "Dart". - 1. Copy and run the generated code in a Dart interpreter. If the output ends with "OK", the test has passed. - -# Modifying or creating unit tests - 1. Load ` tests/generators/index.html ` in a browser. - 1. Choose the relevant part of the system from the drop-down menu, and click "Load". Blocks should appear in the workspace. - 1. Make any changes or additions to the blocks. - 1. Click on "XML". - 1. Copy the generated XML into the appropriate file in ` tests/generators/ `. \ No newline at end of file diff --git a/help/Variables.md b/Variables.md similarity index 95% rename from help/Variables.md rename to Variables.md index 549d758..266d74e 100644 --- a/help/Variables.md +++ b/Variables.md @@ -16,7 +16,7 @@ While users can choose any name for a variable, core Blockly provides a default Clicking on a variable's dropdown symbol (triangle) gives the following menu: -![](help/variables-dropdown.png) +![](variables-dropdown.png) The menu provides the following options. * the names of all variables defined in the program. @@ -29,13 +29,13 @@ The menu provides the following options. The **set** block assigns a value to a variable, creating the variable if it doesn't already exist. For example, this sets the value of the variable named "age" to 12. -![](help/variables-set-variable.png) +![](variables-set-variable.png) ## Get The **get** block provides the value stored in a variable, without changing it. -![](help/variables-get-variable.png) +![](variables-get-variable.png) It is possible, but a bad idea, to write a program in which a **get** appears without a corresponding **set**. @@ -43,6 +43,6 @@ It is possible, but a bad idea, to write a program in which a **get** appears wi Consider the following example code: -![](help/variables-example.png) +![](variables-example.png) The first row of blocks creates a variable named "age" and sets its initial value to the number 12. The second row of blocks gets the value 12, adds 1 to it, and stores the sum (13) into the variable. The final row displays the message: "Happy birthday! You are now 13" diff --git a/appendField.png b/appendField.png deleted file mode 100644 index 37f20ae..0000000 Binary files a/appendField.png and /dev/null differ diff --git a/appendFieldCheckbox.png b/appendFieldCheckbox.png deleted file mode 100644 index a7331a8..0000000 Binary files a/appendFieldCheckbox.png and /dev/null differ diff --git a/appendFieldColour.png b/appendFieldColour.png deleted file mode 100644 index 2ffd66d..0000000 Binary files a/appendFieldColour.png and /dev/null differ diff --git a/appendFieldDropdown.png b/appendFieldDropdown.png deleted file mode 100644 index f41fb02..0000000 Binary files a/appendFieldDropdown.png and /dev/null differ diff --git a/appendFieldImage.png b/appendFieldImage.png deleted file mode 100644 index cf92dc8..0000000 Binary files a/appendFieldImage.png and /dev/null differ diff --git a/appendFieldTextInput.png b/appendFieldTextInput.png deleted file mode 100644 index 8dd001d..0000000 Binary files a/appendFieldTextInput.png and /dev/null differ diff --git a/appendFieldVariable.png b/appendFieldVariable.png deleted file mode 100644 index 1de0fd8..0000000 Binary files a/appendFieldVariable.png and /dev/null differ diff --git a/appendInput.png b/appendInput.png deleted file mode 100644 index 0efb853..0000000 Binary files a/appendInput.png and /dev/null differ diff --git a/closure_alert.png b/closure_alert.png deleted file mode 100644 index 93e8396..0000000 Binary files a/closure_alert.png and /dev/null differ diff --git a/closure_directory.png b/closure_directory.png deleted file mode 100644 index 5db997a..0000000 Binary files a/closure_directory.png and /dev/null differ diff --git a/help/colour-blend.png b/colour-blend.png similarity index 100% rename from help/colour-blend.png rename to colour-blend.png diff --git a/help/colour-print.png b/colour-print.png similarity index 100% rename from help/colour-print.png rename to colour-print.png diff --git a/help/colour-random-colour.png b/colour-random-colour.png similarity index 100% rename from help/colour-random-colour.png rename to colour-random-colour.png diff --git a/help/colour-select.png b/colour-select.png similarity index 100% rename from help/colour-select.png rename to colour-select.png diff --git a/help/colour-with.png b/colour-with.png similarity index 100% rename from help/colour-with.png rename to colour-with.png diff --git a/help/control-break.png b/control-break.png similarity index 100% rename from help/control-break.png rename to control-break.png diff --git a/help/control-count-with.png b/control-count-with.png similarity index 100% rename from help/control-count-with.png rename to control-count-with.png diff --git a/help/control-for-each-break.png b/control-for-each-break.png similarity index 100% rename from help/control-for-each-break.png rename to control-for-each-break.png diff --git a/help/control-for-each-continue.png b/control-for-each-continue.png similarity index 100% rename from help/control-for-each-continue.png rename to control-for-each-continue.png diff --git a/help/control-for-each-down.png b/control-for-each-down.png similarity index 100% rename from help/control-for-each-down.png rename to control-for-each-down.png diff --git a/help/control-for-each.png b/control-for-each.png similarity index 100% rename from help/control-for-each.png rename to control-for-each.png diff --git a/help/control-repeat-continue.png b/control-repeat-continue.png similarity index 100% rename from help/control-repeat-continue.png rename to control-repeat-continue.png diff --git a/help/control-repeat-until.png b/control-repeat-until.png similarity index 100% rename from help/control-repeat-until.png rename to control-repeat-until.png diff --git a/help/control-repeat-while.png b/control-repeat-while.png similarity index 100% rename from help/control-repeat-while.png rename to control-repeat-while.png diff --git a/help/control-repeat.png b/control-repeat.png similarity index 100% rename from help/control-repeat.png rename to control-repeat.png diff --git a/controls_if.png b/controls_if.png deleted file mode 100644 index 01ba8af..0000000 Binary files a/controls_if.png and /dev/null differ diff --git a/count-with.png b/count-with.png deleted file mode 100644 index ce80c9b..0000000 Binary files a/count-with.png and /dev/null differ diff --git a/help/create-list-with-colours.png b/create-list-with-colours.png similarity index 100% rename from help/create-list-with-colours.png rename to create-list-with-colours.png diff --git a/help/create-list-with-mixture.png b/create-list-with-mixture.png similarity index 100% rename from help/create-list-with-mixture.png rename to create-list-with-mixture.png diff --git a/i18n_block_diagram.png b/i18n_block_diagram.png deleted file mode 100644 index 27a3717..0000000 Binary files a/i18n_block_diagram.png and /dev/null differ diff --git a/help/if-else-if-else.png b/if-else-if-else.png similarity index 100% rename from help/if-else-if-else.png rename to if-else-if-else.png diff --git a/help/if-else-if.png b/if-else-if.png similarity index 100% rename from help/if-else-if.png rename to if-else-if.png diff --git a/help/if-else.png b/if-else.png similarity index 100% rename from help/if-else.png rename to if-else.png diff --git a/help/if-if.png b/if-if.png similarity index 100% rename from help/if-if.png rename to if-if.png diff --git a/help/if-modify.gif b/if-modify.gif similarity index 100% rename from help/if-modify.gif rename to if-modify.gif diff --git a/help/if-open.png b/if-open.png similarity index 100% rename from help/if-open.png rename to if-open.png diff --git a/help/if.png b/if.png similarity index 100% rename from help/if.png rename to if.png diff --git a/klingon.png b/klingon.png deleted file mode 100644 index 09f30ab..0000000 Binary files a/klingon.png and /dev/null differ diff --git a/help/list-create-empty-list.png b/list-create-empty-list.png similarity index 100% rename from help/list-create-empty-list.png rename to list-create-empty-list.png diff --git a/help/list-create-list-modify-tooltip.png b/list-create-list-modify-tooltip.png similarity index 100% rename from help/list-create-list-modify-tooltip.png rename to list-create-list-modify-tooltip.png diff --git a/help/list-create-list-modify.gif b/list-create-list-modify.gif similarity index 100% rename from help/list-create-list-modify.gif rename to list-create-list-modify.gif diff --git a/help/list-create-list-with-colours.png b/list-create-list-with-colours.png similarity index 100% rename from help/list-create-list-with-colours.png rename to list-create-list-with-colours.png diff --git a/help/list-create-list-with-item.png b/list-create-list-with-item.png similarity index 100% rename from help/list-create-list-with-item.png rename to list-create-list-with-item.png diff --git a/help/list-create-list-with-mixture.png b/list-create-list-with-mixture.png similarity index 100% rename from help/list-create-list-with-mixture.png rename to list-create-list-with-mixture.png diff --git a/help/list-create-list-with-numbers.png b/list-create-list-with-numbers.png similarity index 100% rename from help/list-create-list-with-numbers.png rename to list-create-list-with-numbers.png diff --git a/help/list-create-list-with-text.png b/list-create-list-with-text.png similarity index 100% rename from help/list-create-list-with-text.png rename to list-create-list-with-text.png diff --git a/help/list-empty.png b/list-empty.png similarity index 100% rename from help/list-empty.png rename to list-empty.png diff --git a/help/list-find-first1.png b/list-find-first1.png similarity index 100% rename from help/list-find-first1.png rename to list-find-first1.png diff --git a/help/list-find-first2.png b/list-find-first2.png similarity index 100% rename from help/list-find-first2.png rename to list-find-first2.png diff --git a/help/list-find-last.png b/list-find-last.png similarity index 100% rename from help/list-find-last.png rename to list-find-last.png diff --git a/help/list-in-list-get-and-remove.png b/list-in-list-get-and-remove.png similarity index 100% rename from help/list-in-list-get-and-remove.png rename to list-in-list-get-and-remove.png diff --git a/help/list-in-list-get-options.png b/list-in-list-get-options.png similarity index 100% rename from help/list-in-list-get-options.png rename to list-in-list-get-options.png diff --git a/help/list-in-list-get1.png b/list-in-list-get1.png similarity index 100% rename from help/list-in-list-get1.png rename to list-in-list-get1.png diff --git a/help/list-in-list-get2.png b/list-in-list-get2.png similarity index 100% rename from help/list-in-list-get2.png rename to list-in-list-get2.png diff --git a/help/list-in-list-get3.png b/list-in-list-get3.png similarity index 100% rename from help/list-in-list-get3.png rename to list-in-list-get3.png diff --git a/help/list-in-list-get4.png b/list-in-list-get4.png similarity index 100% rename from help/list-in-list-get4.png rename to list-in-list-get4.png diff --git a/help/list-in-list-get5.png b/list-in-list-get5.png similarity index 100% rename from help/list-in-list-get5.png rename to list-in-list-get5.png diff --git a/help/list-in-list-remove.png b/list-in-list-remove.png similarity index 100% rename from help/list-in-list-remove.png rename to list-in-list-remove.png diff --git a/help/list-insert-at-example.png b/list-insert-at-example.png similarity index 100% rename from help/list-insert-at-example.png rename to list-insert-at-example.png diff --git a/help/list-insert-at.png b/list-insert-at.png similarity index 100% rename from help/list-insert-at.png rename to list-insert-at.png diff --git a/help/list-length.png b/list-length.png similarity index 100% rename from help/list-length.png rename to list-length.png diff --git a/help/list-length2.png b/list-length2.png similarity index 100% rename from help/list-length2.png rename to list-length2.png diff --git a/help/list-print-popup.png b/list-print-popup.png similarity index 100% rename from help/list-print-popup.png rename to list-print-popup.png diff --git a/help/list-print.png b/list-print.png similarity index 100% rename from help/list-print.png rename to list-print.png diff --git a/help/list-set-example.png b/list-set-example.png similarity index 100% rename from help/list-set-example.png rename to list-set-example.png diff --git a/help/list-set.png b/list-set.png similarity index 100% rename from help/list-set.png rename to list-set.png diff --git a/help/list-sub-list-example.png b/list-sub-list-example.png similarity index 100% rename from help/list-sub-list-example.png rename to list-sub-list-example.png diff --git a/help/list-sub-list1.png b/list-sub-list1.png similarity index 100% rename from help/list-sub-list1.png rename to list-sub-list1.png diff --git a/help/list-sub-list2.png b/list-sub-list2.png similarity index 100% rename from help/list-sub-list2.png rename to list-sub-list2.png diff --git a/help/logic-and.png b/logic-and.png similarity index 100% rename from help/logic-and.png rename to logic-and.png diff --git a/help/logic-compare.png b/logic-compare.png similarity index 100% rename from help/logic-compare.png rename to logic-compare.png diff --git a/help/logic-not-true.png b/logic-not-true.png similarity index 100% rename from help/logic-not-true.png rename to logic-not-true.png diff --git a/help/logic-not.png b/logic-not.png similarity index 100% rename from help/logic-not.png rename to logic-not.png diff --git a/help/logic-or.png b/logic-or.png similarity index 100% rename from help/logic-or.png rename to logic-or.png diff --git a/help/logic-true-false.png b/logic-true-false.png similarity index 100% rename from help/logic-true-false.png rename to logic-true-false.png diff --git a/operatorPrecedence.png b/operatorPrecedence.png deleted file mode 100644 index 6984da1..0000000 Binary files a/operatorPrecedence.png and /dev/null differ diff --git a/sample.png b/sample.png deleted file mode 100644 index ec6547c..0000000 Binary files a/sample.png and /dev/null differ diff --git a/setInputsInline.png b/setInputsInline.png deleted file mode 100644 index 7b9b4a8..0000000 Binary files a/setInputsInline.png and /dev/null differ diff --git a/setNextStatement.png b/setNextStatement.png deleted file mode 100644 index 7fd38ed..0000000 Binary files a/setNextStatement.png and /dev/null differ diff --git a/setOutput.png b/setOutput.png deleted file mode 100644 index 054a73a..0000000 Binary files a/setOutput.png and /dev/null differ diff --git a/setPreviousStatement.png b/setPreviousStatement.png deleted file mode 100644 index 8ae2f59..0000000 Binary files a/setPreviousStatement.png and /dev/null differ diff --git a/help/text-append-modify.png b/text-append-modify.png similarity index 100% rename from help/text-append-modify.png rename to text-append-modify.png diff --git a/help/text-append.png b/text-append.png similarity index 100% rename from help/text-append.png rename to text-append.png diff --git a/help/text-case.png b/text-case.png similarity index 100% rename from help/text-case.png rename to text-case.png diff --git a/help/text-create.png b/text-create.png similarity index 100% rename from help/text-create.png rename to text-create.png diff --git a/help/text-empty1.png b/text-empty1.png similarity index 100% rename from help/text-empty1.png rename to text-empty1.png diff --git a/help/text-empty2.png b/text-empty2.png similarity index 100% rename from help/text-empty2.png rename to text-empty2.png diff --git a/help/text-find-first-last.png b/text-find-first-last.png similarity index 100% rename from help/text-find-first-last.png rename to text-find-first-last.png diff --git a/help/text-find-first.png b/text-find-first.png similarity index 100% rename from help/text-find-first.png rename to text-find-first.png diff --git a/help/text-find-last.png b/text-find-last.png similarity index 100% rename from help/text-find-last.png rename to text-find-last.png diff --git a/help/text-get-number.png b/text-get-number.png similarity index 100% rename from help/text-get-number.png rename to text-get-number.png diff --git a/help/text-get-substring.png b/text-get-substring.png similarity index 100% rename from help/text-get-substring.png rename to text-get-substring.png diff --git a/help/text-in-text-get1.png b/text-in-text-get1.png similarity index 100% rename from help/text-in-text-get1.png rename to text-in-text-get1.png diff --git a/help/text-in-text-get2.png b/text-in-text-get2.png similarity index 100% rename from help/text-in-text-get2.png rename to text-in-text-get2.png diff --git a/help/text-in-text-get3.png b/text-in-text-get3.png similarity index 100% rename from help/text-in-text-get3.png rename to text-in-text-get3.png diff --git a/help/text-in-text-get4.png b/text-in-text-get4.png similarity index 100% rename from help/text-in-text-get4.png rename to text-in-text-get4.png diff --git a/help/text-in-text-get5.png b/text-in-text-get5.png similarity index 100% rename from help/text-in-text-get5.png rename to text-in-text-get5.png diff --git a/help/text-length1.png b/text-length1.png similarity index 100% rename from help/text-length1.png rename to text-length1.png diff --git a/help/text-length2.png b/text-length2.png similarity index 100% rename from help/text-length2.png rename to text-length2.png diff --git a/help/text-print.png b/text-print.png similarity index 100% rename from help/text-print.png rename to text-print.png diff --git a/help/text-prompt-popup.png b/text-prompt-popup.png similarity index 100% rename from help/text-prompt-popup.png rename to text-prompt-popup.png diff --git a/help/text-prompt.png b/text-prompt.png similarity index 100% rename from help/text-prompt.png rename to text-prompt.png diff --git a/help/text-text.png b/text-text.png similarity index 100% rename from help/text-text.png rename to text-text.png diff --git a/help/text-trim-spaces.png b/text-trim-spaces.png similarity index 100% rename from help/text-trim-spaces.png rename to text-trim-spaces.png diff --git a/text_length.png b/text_length.png deleted file mode 100644 index 7ef8a56..0000000 Binary files a/text_length.png and /dev/null differ diff --git a/help/variable-dropdown.png b/variable-dropdown.png similarity index 100% rename from help/variable-dropdown.png rename to variable-dropdown.png diff --git a/help/variables-dropdown.png b/variables-dropdown.png similarity index 100% rename from help/variables-dropdown.png rename to variables-dropdown.png diff --git a/help/variables-example.png b/variables-example.png similarity index 100% rename from help/variables-example.png rename to variables-example.png diff --git a/help/variables-get-variable.png b/variables-get-variable.png similarity index 100% rename from help/variables-get-variable.png rename to variables-get-variable.png diff --git a/help/variables-set-variable.png b/variables-set-variable.png similarity index 100% rename from help/variables-set-variable.png rename to variables-set-variable.png