Developer Documentation

This section contains useful information for people interested in contributing code to Pencil.

If you’ll be testing & debugging using Firefox, you will probably want to start off by setting up an extension development environment.

Code Overview

The application code lives under app/content/pencil/.

Many of the files directly under app/content/pencil/ are pairs of UI definitions and their JavaScript files (e.g. exportWizard.xul and exportWizard.js)

mainWindow.xul & common/pencil.js are good places to start reading the code - they are responsible for initializing the application.

mainWindow.xul is responsible for specifying the application’s base UI, including keybindings, menus, toolbars, panes, and for including the application’s JavaScript-Files. mainWindow.js contains mostly helper functions used in the .xul file, along with post-boot code like parsing command-line arguments & building the Recent Documents menu.

common/pencil.js initializes a global Pencil object & sets up event listeners on boot-up. The Pencil object contains attributes linked to the application’s Controller, Rasterizer, etc.

common/controller.js is responsible for managing the Document & it’s Pages. The Controller object contains methods for creating new Documents/Pages, saving/loading Documents & moving/removing/duplicating Pages.

common/utils.js is a huge grab bag of randomness, from DOM & SVG manipulation to font sorting to creating temp files to grabbing images from the clipboard to getting a file’s extension from it’s path.

bindings/ contains components like the color picker & font editor. stencils/ contains the default Stencil Collections bundled with Pencil.

You should also reference the Developer API Documentation.

Code Style

Some things to keep in mind:

  • Wrap lines longer than ~80 characters
  • Indent using 4 spaces, never use tabs
  • Always use the strict equality operators === and !==.
  • Run jshint on the changed files(this might generate a lot of errors on some files).

Debugging

If you set the DEBUG environmental variable when building Pencil, the build.sh script will enable debugging features like printing calls to dump() to the console or debug() to the javascript console:

export DEBUG=true
cd build
./build.sh linux
# If you've got XULRunner:
xulrunner Outputs/Linux/application.ini -console -jsconsole -purgecaches
# If you only have Firefox installed:
firefox --app Outputs/Linux/application.ini -console -jsconsole -purgecaches

Setting DEBUG will cause also Pencil to start a remote debugging server on port 6000. This lets you use Firefox’s DOM Inspector to debug Pencil - but only when you run Pencil using xulrunner. You can connect Firefox to the debugging server by going to Firefox -> Tools -> Web Developer -> Connect.... You may need to enable Remote Debugging under Firefox’s Web Developer Tools Settings(Ctrl-Shift-I then click the gear icon in the upper-right).

Writing Documentation

This documentation is built using Sphinx, which adds some extra flavor on top of reStructuredText. If you’re unfamiliar with these tools a good starting point is the reStructuredText Primer, Sphinx Markup & JavaScript Domain pages in Sphinx’s documentation.

The API documentation is generated by the Sphinx plugin autoanysrc. This parses all the comments in javascript files from the /app/ directory. If a comment follows the form /*""" docs here */, autoanysrc will add the comment to the Developer API Documentation page. For example:

/*"""
Module/Section Name
===================

A description about the current file
*/
function SomeClass(arg) {
    /*"""
    .. class:: SomeClass(arg)

        A text description of the class

        :param string arg: The argument you must pass in when initializing

        .. attribute:: arg

            The argument passed to the constructor
    */
    this.arg = arg;
}
SomeClass.prototype.someFunction = function() {
    /*"""
     .. function:: someFunction(void) {

         :returns: something
    */
    return this.arg;
    }
}

Note that the dots for the function annotation should be indented by one space, so they line up with the * of the /*. This will create the proper nesting in the final documentation.

The Build System

The build.sh script is responsible for building everything. Each build is usually in two steps: copying & modifying files common to all builds then customizing those files for the specific build(by removing files, embedding xulrunner, creating the expected directory structure, etc.).

The build script uses the properties.sh file to hold variables such as the current version & the minimum/maximum firefox/xulrunner versions. The script uses replacer.sh to replace all instances of @VARIABLE@ with the value of VARIABLE in the file passed to it.

If you add a variable to properties.sh you must modify the replacer.sh script to replace the variable. If you add a variable to a file, you must make sure that file is processed by replacer.sh at some point(usually in the prep() function).

replacer.sh uses the sed-debug-script to remove all the text between //DEBUG_BEGIN and //DEBUG_END. This can be used to enable code only when building for development. If you add //DEBUG_BEGIN and //DEBUG_END to a file, make sure build.sh passes the file to replacer.sh``(again, this usually happens in the ``prep() function).

You can pass the clean argument to build.sh to remove all the outputs. You can use maintainer-clean to remove any XULRunner downloads as well.