Skip to content
 
 

Latest commit

 

History

1,513 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Make pictures of Scratch blocks from text.

Screenshot

Try it out!

Documentation


scratchblocks-plus is a fork of scratchblocks, and adds the following features:

Compatibility with scratchblocks

scratchblocks-plus follows the core text syntax and common browser APIs of scratchblocks 3.x, including parse, render, renderMatching, and loadLanguages. Most browser integrations can migrate by changing the package or script name.

It is not a complete package-level drop-in replacement:

  • scratchblocks-plus is ESM-first and does not support CommonJS require();
  • the root package entry is browser-only because it uses window and the DOM;
  • Node.js rendering and syntax-only parsing use dedicated package subpaths;
  • internal modules and exact generated SVG markup are not compatibility guarantees.

The classic script build still creates window.scratchblocks, so existing browser code that uses the documented scratchblocks API generally remains compatible.


scratchblocks-plus is used to write Scratch scripts:

It's MIT licensed, so you can use it in your projects.

For the full guide to the syntax, see the wiki.

Usage

ESM (recommended)

Install the package from npm:

npm install scratchblocks-plus

The root entry is intended for browser applications and bundlers. It default-exports the initialized scratchblocks API and automatically adds the required styles to the page:

import scratchblocks from "scratchblocks-plus"

scratchblocks.renderMatching("pre.blocks", {
  style: "scratch3",
  languages: ["en"],
  // catHats: true,
  // fontFamily: '"Noto Sans SC", sans-serif',
})

Set catHats to true to render all Scratch 3 hat and custom block definition hats as cat hats. It defaults to false and has no visual effect with the scratch2 style.

Use fontFamily to override the font family for all block labels, input values, and comments in that render. The value uses CSS font-family syntax; load the font before rendering, for example by waiting for document.fonts.ready. If the option is omitted or empty, each style keeps its default fonts.

The ESM entry does not create window.scratchblocks. Import the default export wherever it is needed.

To load every bundled locale in an ESM application:

import scratchblocks from "scratchblocks-plus"
import locales from "scratchblocks-plus/locales/all"

scratchblocks.loadLanguages(locales)

The all-locales entry is large. Import individual locale JSON files when your bundler supports JSON modules and you only need a few languages.

Node.js rendering

Use the dedicated SSR entry instead of the browser root. Install a DOM and canvas implementation alongside scratchblocks-plus:

npm install scratchblocks-plus @xmldom/xmldom @napi-rs/canvas
import { renderToSVGString } from "scratchblocks-plus/node-ssr"

const svg = renderToSVGString("move (10) steps", {
  style: "scratch3",
  fontFamily: '"Noto Sans SC", sans-serif',
})

For custom fonts in Node.js, register the font with the selected Canvas implementation before rendering so SVG layout measurement uses the same font.

Syntax-only parsing

Parsing and document analysis do not require a DOM or canvas implementation:

import { parse } from "scratchblocks-plus/syntax"

const document = parse("move (10) steps")
const block = document.scripts[0].blocks[0]

console.log(block.info.id) // "MOTION_MOVESTEPS"

TypeScript model names are available as type-only exports from the browser entry:

import scratchblocks, {
  type Block,
  type Document,
} from "scratchblocks-plus"

const document: Document = scratchblocks.parse("move (10) steps")
const block: Block = document.scripts[0].blocks[0]

block.info.id identifies the registered Scratch block definition. For an application-defined identity, assign id directly to a Script, Block, Input, or Comment before creating a view or rendering:

const document = scratchblocks.parse("move (10) steps")
const block = document.scripts[0].blocks[0]
block.id = "workspace-block-42"

const view = scratchblocks.newView(document, { style: "scratch3" })
view.render()
const element = view.getElementById("workspace-block-42")

The ID is rendered as data-sb-id; it is not part of scratchblocks text and is not included by stringify(). Duplicate IDs are allowed, and lookup returns the first matching element in document order.

To hide a block without removing its layout space, set its optional hidden property before creating the view:

const doc = scratchblocks.parse(`repeat (10)
  move (10) steps
end`)
doc.getBlockByPath("1.1").hidden = true

const view = scratchblocks.newView(doc, { style: "scratch3" })
view.render()

When hidden is true, the block, its nested blocks, and attached visual annotations are invisible, while their original dimensions and positions are preserved. Hidden blocks remain available through element lookup APIs. The property is application-only: scratchblocks text cannot set it, and stringify() does not include it. Create a new view after changing hidden on an existing document.

React

Use the scratchblocks-plus-react package to render scratchblocks in React.

Classic HTML script

ESM is recommended for new projects. The classic IIFE build remains available for pages that use a global window.scratchblocks object.

You'll need to include a copy of the scratchblocks-plus JS file on your webpage. There are a few ways of getting one:

  • You could clone this repository and build it yourself using Node 16.14.0+ (npm run build).
<script src="scratchblocks-plus.min.js"></script>

The convention is to write scratchblocks inside pre tags with the class blocks:

<pre class="blocks">
when flag clicked
move (10) steps
</pre>

You then need to call scratchblocks.renderMatching after the page has loaded. Make sure this appears at the end of the page (just before the closing </body> tag):

<script>
  scratchblocks.renderMatching("pre.blocks", {
    style: "scratch3", // Optional, defaults to "scratch2".
    languages: ["en", "de"], // Optional, defaults to ["en"].
    scale: 1, // Optional, defaults to 1.
  })
</script>

The renderMatching() function takes a CSS-style selector for the elements that contain scratchblocks code: we use pre.blocks to target pre tags with the class blocks.

The style option controls how the blocks appear. Supported built-in styles are scratch2, scratch3, scratch3-high-contrast, and scratch3-outline.

Inline blocks

You might also want to use blocks "inline", inside a paragraph:

I'm rather fond of the <code class="b">stamp</code> block in Scratch.

To allow this, make a second call to renderMatching using the inline argument.

<script>
  scratchblocks.renderMatching("pre.blocks", ...)

  scratchblocks.renderMatching("code.b", {
    inline: true,
    // Repeat `style` and `languages` options here.
  })
</script>

This time we use code.b to target code blocks with the class b.

Translations

If you want to use languages other than English, you'll need to include a second JS file that contains translations. The releases page includes two options; you can pick one:

  • translations.js includes a limited set of languages, as seen on the Scratch Forums
  • translations-all.js includes every language that Scratch supports.

The translations files are hundreds of kilobytes in size, so to keep your page bundle size down you might like to build your own file with just the languages you need.

For example, a translations file that just loads the German language (ISO code de) would look something like this:

scratchblocks.loadLanguages({
    de: <contents of locales/de.json>
})

With ESM, import the locale JSON file when your bundler supports JSON modules:

import de from "scratchblocks-plus/locales/de.json"

scratchblocks.loadLanguages({
  de,
})

Languages

To update the translations:

npm upgrade scratch-l10n
npm run locales

Adding a language

Each language requires some additional words which aren't in Scratch itself (mainly the words used for the flag and arrow images). I'd be happy to accept pull requests for those! You'll need to rebuild the translations with npm run locales after editing the aliases.

Development

This should set you up and start a http-server for development:

npm install
npm start

Then open http://localhost:8000/ :-)

For more details, see CONTRIBUTING.md.

Credits

Many, many thanks to the contributors!

  • Maintained by LuYifei2011
  • This is a fork of scratchblocks, so all the credit there still applies here.
  • Original scratchblocks library by tjvr
  • Original scratchblocks library maintained by tjvr and apple502j
  • Icons derived from Scratch Blocks (Apache License 2.0)
  • Scratch 2 SVG proof-of-concept, shapes & filters by as-com
  • Anna helped with a formula, and pointed out that tjvr can't read graphs
  • JSO designed the syntax and wrote the original Block Plugin
  • Help with translation code from joooni
  • Block translations from the scratch-l10n repository
  • Ported to node by arve0

About

Make pictures of Scratch blocks from text.

Resources

Contributing

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages