npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

codemirror-blocks

v0.8.6

Published

CodeMirror extension for using draggable blocks to write programming languages

Downloads

47

Readme

dependencies Status devDependencies Status Build Status Coverage Status Code Climate

codemirror-blocks

A library for making functional languages editable using visual blocks inside of codemirror

Usage

CodeMirror-Blocks ("CMB") is not a block editor. It's a toolkit for building block editors. In other words, it is NOT intended to be used in your IDE. ;-)

CMB should instead be included in language-specific modules, so your Python editor would include a CMB-enabled Python module. CMB provides the blockification and a11y features, and the language module provides the parser and (optionally) the vocalization and appearance for each construct in the language. The language module is what you use in your IDE.

The following language modules are available now:

  • https://github.com/bootstrapworld/wescheme-blocks
  • https://github.com/bootstrapworld/pyret-blocks

If you happen to use one of those languages, you're good to go! Export the language module using the normal npm run build mechanism, then include it in your favorite CodeMirror-enabled project. You can now use the CodeMirrorBlocks constructor to replace an existing CodeMirror instance with blocks. In other words, you'd replace code that looks like this:

    // make a new CM instance inside the container elt, passing in CM ops
    this.editor = CodeMirror(container, {/* CodeMirror options  */}});

With code that looks like this:

    // make a new CMB instance inside the container elt, passing in CMB ops
    this.editor = CodeMirrorBlocks(container, {/* CodeMirrorBlocks options  */});

But if you're here, our guess is that you have a language in mind (Python, Rust, YourFavLang, etc.) and you want to allow people to hack in that language even if they need blocks, or rely on screenreaders. So how does one make a language module?

Making your own language module

NOTE: your IDE will need to load CodeMirror as an external dependency. We assume it already does (otherwise, why would you be here?), so you'll need to provide it yourself.

Create a new repository

Make a repo (e.g. - YourFavLang-blocks), and include CMB as a dependency:

    npm install --save codemirror-blocks
    

Then add folders for your parser (src/languages/YourFavLang) and test cases (spec/languages/YourFavLang).

Provide a Parser

Write a parser for your language that produces an Abstract Syntax Tree composed of CMB's node types.

CMB's AST nodes all have constructors that take arguments specifying (1) the from and to position of the node (in CodeMirror's {line, ch} format), (2) the fields that define the node, and (3) an options object.

The options object is used for a number of CMB-internal purposes, but there are two (language-dependant) fields that your parser will need to set. First, you'll want to set options[aria-label] to a short, descriptive string for how that node should be vocalized by a screenreader (e.g. - "v: a value definition"). Your parser will also be responsible for associating block- and line-comments with the node they describe. For example:

    if (node instanceof structures.defVar) {
       var name = parseNode(node.name);
       var expr = parseNode(node.expr);
       var cmnt = new Comment(cmntFrom, cmtTo, cmtText);
       return new VariableDefinition(
          from,
          to,
          name,
          expr,
          {'aria-label': node.name.val+': a value definition', 'comment' : comment}
       );
    }

Defining your own AST Nodes

You can also provide your own AST nodes, by extending the built-in AST.ASTNode class. Here is one example of a language defining custom AST nodes.

Your subclassed Node must contain:

  1. constructor - consumes the from and to locations, all required child fields, and an options object initialized to {}.
  2. spec - a static field, which defines specifications for all fields of the node. These specifications are documented here
  3. longDescription() - a method that dynamically computes a detailed description of the node (optionally referring to its children, for example), and produces a string that will be read aloud to the user.
  4. pretty() - a method that describes how the node should be pretty-printed. Pretty-printing options are documented here.
  5. render() - a method that produces the node (usually in JSX) to be rendered.

Tell CMB about the Language

Create an index.js see this example file that hooks up your language to the CMB library.

Style Your Blocks

CMB provides default CSS styling for all node types, but you can always add your own! Add a style.less file that overrides the built-in styles, providing your own "look and feel" using standard CSS.

Obviously, if you've added new AST node types, you'll have to provide the styling for those yourself!

Write Your Tests

In spec/languages/YourFavLang, add some unit tests for your parser! Make sure you test all the fields, but especially the aria-label and longDescription() return values.

You may find it useful to check out this example.

Hacking on CMB Itself

But maybe you're not here to make an accessible block editor for a new language. Maybe you want to hack on the CMB library itself, and help close some of our open issues!

To get your dev environment up and running, follow these steps. Note that to run tests, you will need either Chrome or Chromium and point the variable CHROME_BIN to the binary like this:

export CHROME_BIN=/usr/bin/chromium

You must enter the following command in every session before you run the test. Alternatively, you can put it in your .{bash,zsh}rc, which will run them automatically.

  1. Checkout the repository in your favorite manner

  2. install dependencies with npm

     npm install
  3. start the webpack development server:

     npm start
  4. browse to http://localhost:8080/ and fire away!

  5. while you work, be sure to continuously run the unit tests with:

     npm run test-watch

Library code is in the src/ directory. An example of how it should be used is in the example/ directory.

  1. you can generate local coverage reports in the .coverage/ folder by running:

     COVERAGE=true npm test
  2. you can generate a static, minified ball of JS and CSS in the dist/ folder by running:

     npm run build