First install the prerequisites: git, nodejs, and grunt. Next, be sure you're in your home directory. Then:
git clone https://github.com/PencilCode/pencilcode.git cd pencilcode npm install grunt grunt devserver
On Windows Subsystem for Linux (WSL) only:
git clone https://github.com/cacticouncil/pencilcode.git cd pencilcode npm install --no-shrinkwrap grunt grunt devserver
Development can be done on Linux, Mac, or Windows.
The prerequisites are a standard node.js development environment
which is very widely used, plus grunt (you'll need to
npm install -g grunt-cli
).
First, you need git, which is easy. On Linux,
just sudo apt-get install git
or sudo yum install git-core
if you don't have it.
Second, you need node.js (which is the node
and npm
binaries)
and grunt
(which is the build tool popular in the node.js community).
The Ubuntu and Debian packages for node.js are pretty old, so don't
just apt-get install the packages. Get and build the latest node
and
npm
and grunt
binaries as follows:
(For Linux:)
mkdir -p /tmp/nodejs && cd /tmp/nodejs wget -N http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz # http://nodejs.org/dist/node-latest.tar.gz tar xzvf node-*.tar.gz && cd `ls -d node-v*` ./configure --prefix=$HOME/local make install echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.bashrc source ~/.bashrc npm install -g grunt-cli
Zsh users should change bashrc
to zshrc
in the above code.
(For Windows Subsystem for Linux:)
sudo apt-get install npm git sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10 sudo npm install -g grunt-cli
(For Mac:)
mkdir -p /tmp/nodejs && cd /tmp/nodejs curl http://nodejs.org/dist/v0.12.7/node-v0.12.7.tar.gz > node-latest.tar.gz tar xzvf node-*.tar.gz && cd `ls -d node-v*` ./configure --prefix=$HOME/local make install echo 'export PATH=$HOME/local/bin:$PATH' >> ~/.profile source ~/.profile npm install -g grunt-cli
The above drops all the built binaries into ~/local/bin
so you
don't need root.
On the Mac, git comes from Apple (you can get it as part of the
Command line tools for XCode),
and if you'd rather not build it, node.js can be installed from
http://nodejs.org/download/.
You will still need to sudo npm install -g grunt-cli
.
On Windows, git can be installed from here: http://git-scm.com/download/win and node.js can be installed from here: http://nodejs.org/download/. Windows development is untested, but if you try it, let me know.
Because node.js does not work on cygwin, when I work with node.js on a Windows box, I just run it with debian under a vbox instance https://www.virtualbox.org/.
To experiment with PencilCode, you will want to run a local copy of the site's frontend. Your webpage may appear in plain (rather ugly) text unless you run devchrome with your grunt devserver.
To build and start the dev server (by default it runs on localhost:8008):
devchrome bg %1 grunt grunt devserver
(Use grunt sdevserver to run https instead of http.)
To use the devserver, modify DNS resolution so *.pencilcode.net.dev points to localhost. For example, with chrome on OSX, add a couple aliases to your .profile by running the following:
cat >> ~/.profile <<EOF alias chrome="/Applications/Google\\ \\Chrome.app/Contents/MacOS/Google\\ \\Chrome" alias devchrome='chrome --host-resolver-rules="MAP *pencilcode.net.dev localhost:8008" --user-data-dir=$HOME/devchrome --ignore-certificate-errors http://pencilcode.net.dev/' EOF source ~/.profile
And then "devchrome" will launch an instance of Chrome with the right proxy.
On Linux, add something like this to your .bashrc:
alias devchrome='google-chrome --host-resolver-rules="MAP *pencilcode.net.dev localhost:8008" --user-data-dir=$HOME/devchrome http://pencilcode.net.dev/'
On Windows:
You can set up command line options for the Canary Chrome shortcut, with the following options.
--host-resolver-rules="MAP *pencilcode.net.dev localhost:8008" --ignore-certificate-errors https://pencilcode.net.dev/"
When running devchrome, any URL with a hostname that ends with ".dev" will be routed to the development server. Visit https://pencilcode.net.dev/ to browse your local copy of the website.
The structure of pencilcode is really simple.
content/src/editor.html
that does all the work.
All pencilcode.net/edit/...
URLs resolve to this static file.src/
directory (symlink
to content/src
). These javascript files are combined and minified
into content/src/editor.js by the build.pencilcode.net/load/...
and pencilcode.net/save/...
to read and write actual data.content
.To get a sense for the protocol used by /load/
and /save/
, just
try hitting the URLs directly in your browser. For example, visit
http://guide.pencilcode.net/load/ to see the JSON response for
a directory listing. To see the details of how /load/ and /save/
work, see the code in site/wsgi.
The production site is an nginx server, configured in nginx/nginx_site.conf
.
The devserver is simpler: it is a node.js proxy server. When using
the devserver, the proxy.pac will direct the requests to your local
dev server, and the dev server will produce editor.html (and its
related javascript) for /edit/
urls. The devserver does not do any
storage - it forwards /load/
and /save/
to the live website on
pencilcode.net.
The PencilCode editor is broken into three main pieces:
editor-storage.js
is the storage layer. It deals with the
protocol for talking to /load/
and /save/
URLs, and it also
does local caching, offline storage, and backup. Someday
when we build a fully offline version of PencilCode, or when
we adapt it to use Google Drive for storage, the major work
will be in this file.editor-view.js
is the UI for the development environement.
It knows how to show directory listings, source code editors,
and framed run sandboxes. Other UI affordances: login dialog
box UI, a butter bar notification, and whizzy horizontal
animated transitions. The idea is that the view doesn't
do any thinking for itself: it just does rendering and
surfaces events.editor-main.js
is the controller logic. This is the main
"business logic" for the editor and sets out what happens
whenever something happens. It loads and saves things
from the storage and pours the data into the view; and
it responds to events that come from the view.The view and the main logic are a bit large and probably should be refactored into further smaller pieces.
Improvements we'd like to make in PencilCode are in several basic directions:
We are always looking for more ideas too.
david.bau@gmail.com