ccampbell-rainbow-9570daa/000077500000000000000000000000001173647220700155205ustar00rootroot00000000000000ccampbell-rainbow-9570daa/.gitignore000066400000000000000000000000051173647220700175030ustar00rootroot00000000000000*.pycccampbell-rainbow-9570daa/README.md000066400000000000000000000030161173647220700167770ustar00rootroot00000000000000# Rainbow Rainbow is a code syntax highlighting library written in Javascript. It was designed to be lightweight (1.4kb), easy to use, and extendable. It is completely themable via CSS. ## Quick Start 1. Include some markup for code you want to be highlighted: ```html
def openFile(path):
        file = open(path, "r")
        content = file.read()
        file.close()
        return content
``` 2. Include a CSS theme file in the ````: ```html ``` 3. Include rainbow.js and whatever languages you want before the closing ````: ```html ``` ## Extending Rainbow If you have a language specific pattern that you want highlighted, but it does not exist in the language syntax rules you can add a rule on your page. Let's say for example you want to reference PHP's apc functions. You can include the php language then in the markup on your page add: ```html ``` ## More Info You can check out additional documentation and build custom packages at [rainbowco.de](http://rainbowco.de).ccampbell-rainbow-9570daa/demos/000077500000000000000000000000001173647220700166275ustar00rootroot00000000000000ccampbell-rainbow-9570daa/demos/c.html000066400000000000000000000051711173647220700177430ustar00rootroot00000000000000 Syntax Highlighting

#ifndef type_h
#define type_h

typedef int type_id;

#define typeid(TYPE) type_find(#TYPE)
#define type_name(TYPE) #TYPE

type_id type_find(const char* type);
const char* type_id_name(int id);

#endif



#include <string.h>
#include <stdio.h>
#include <stdlib.h>

#include "error.h"

#include "type.h"

#define MAX_TYPE_LEN 512
#define MAX_NUM_TYPES 1024

/* Store Table of type names */
typedef char type_string[MAX_TYPE_LEN];
type_string type_table[MAX_NUM_TYPES];
int type_index = 0;

/* Dynamically enter types into table */
int type_find(const char* type) {
  
  if (strlen(type) >= MAX_TYPE_LEN) {
    error("Type name %s is too long to index into type table.", type);
  }
  if (type_index >= MAX_NUM_TYPES) {
    error("Too many types in type table already. Cannot add %s.", type);
  }
  
  for (int i = 0; i < type_index; i++) {
    // Return type index if found
    if (strcmp(type, type_table[i]) == 0) {
      return i;
    }
  }
  
  // If not found add to table and return
  strcpy(type_table[type_index], type);
  type_index++;
  
  return type_index-1;
}

const char* type_id_name(int id) {
  return type_table[id];
}


#ifndef sound_h
#define sound_h

#include "SDL/SDL.h"

typedef struct {
  char* data;
  int length;
} sound;

sound* wav_load_file(char* filename);
void sound_delete(sound* s);

#endif


#include "error.h"

#include "assets/sound.h"

static void flip_endian(char* data, int length) {
  for(int i = 0; i < length; i += 2) {
    int x = data[i];
    data[i] = data[i + 1];
    data[i + 1] = x;
  }
}

sound* wav_load_file(char* filename) {
  
  sound* s = malloc(sizeof(sound));
  
  SDL_AudioSpec spec;
  
  if( SDL_LoadWAV(filename, &spec, (Uint8**)&s->data, (Uint32*)&s->length) == NULL) {
    error("Unable to load sound file %s", filename);
  }
  
  if ((spec.format != AUDIO_S16LSB) &&
      (spec.format != AUDIO_S16MSB)) {
    error("Unsupported sound format for file %s, id %i.", filename, spec.format);
  }
  
  if (spec.format != AUDIO_S16SYS) {
    flip_endian(s->data, s->length);
  }
  
  return s;
}

void sound_delete(sound* s) {
  SDL_FreeWAV((Uint8*)s->data);
  free(s);
}

ccampbell-rainbow-9570daa/demos/css.html000066400000000000000000000020241173647220700203030ustar00rootroot00000000000000 Syntax Highlighting
/**
 * styles for blackboard theme
 */
pre {
    background: #0B1022;
    white-space: pre-wrap;
    white-space: -moz-pre-wrap;
    white-space: -pre-wrap;
    white-space: -o-pre-wrap;
    word-wrap: break-word;
    margin: 0px;
    padding: 0px;
    padding: 10px;
    color: #fff;
    font-size: 14px;
    margin-bottom: 20px;
}

pre, code {
    font-family: 'Monaco', courier, monospace;
}

pre .comment {
    color: #727272;
}

pre .constant {
    color: #D8FA3C;
}

pre .storage {
    color: #FBDE2D;
}

pre .string {
    color: #61CE3C;
}

pre .keyword, pre .selector {
    color: #FBDE2D;
}

pre .parent {
    font-style: italic;
}

pre .entity, pre .meta {
    color: #FF6400;
}

pre .support {
    color: #8DA6CE;
}
ccampbell-rainbow-9570daa/demos/html.html000066400000000000000000000022571173647220700204670ustar00rootroot00000000000000 Syntax Highlighting
<!-- inline styles! -->
<style type="text/css">
    body span.blah {
        background: #000;
        color: #fff;
    }
</style>

<body>
    <span class="blah" width="200" height="200">test code goes here</span>
</body>

<!-- inline php! -->
<?php
    $test = true;

    /**
     * test
     */
    function what($test) {
        return $test;
    }
?>

<!-- inline javascript! -->
<script type="text/javascript">
    function prettyCool() {
        doSomeJQueryOrWhatever();
    }
</script>

<article title="<?= $user->name ?>">test</article>
ccampbell-rainbow-9570daa/demos/index.html000066400000000000000000000011051173647220700206210ustar00rootroot00000000000000 Syntax Highlighting ccampbell-rainbow-9570daa/demos/js.html000066400000000000000000000034751173647220700201420ustar00rootroot00000000000000 Syntax Highlighting
/**
 * test function
 *
 * @param string
 * @return string
 */
function blah(foo, blah) {
    var test = 25;

    console.log(test.length);

    // if foo is true then return this string
    if (foo === true) {
        return 'foo is true';
    }
    return 'foo is false';
}

$(document).ready(function() {
    $("table").on("click", "td", function() {
        console.log('td click');
    });
});

window.Rainbow = {
    whatever: function(param) {

    },

    another: function(param) {

    }
};
window.Rainbow = window.Rainbow || {};

Rainbow.extend('javascript', [
    {
        'name': 'selector',
        'pattern': /\$(?=\.|\()/g
    }
]);
/**
 * cross browser get attribute for an element
 *
 * @see http://stackoverflow.com/questions/3755227/cross-browser-javascript-getattribute-method
 *
 * @param {Element} el
 * @param {string} attr     attribute you are trying to get
 * @returns {string}
 */
function _attr(el, attr) {
    var result = (el.getAttribute && el.getAttribute(attr)) || null;

    if (!result) {
        var attrs = el.attributes,
            length = attrs.length,
            i;

        for (i = 0; i < length; ++i) {
            if (attr[i].nodeName === attr) {
                result = attr[i].nodeValue;
            }
        }
    }

    return result;
}
ccampbell-rainbow-9570daa/demos/php-long.html000066400000000000000000000603001173647220700212400ustar00rootroot00000000000000 Syntax Highlighting
<?php
namespace Sonic;

/**
 * App singleton
 *
 * @category Sonic
 * @package App
 * @author Craig Campbell
 */
final class App
{
    /**
     * @var string
     */
    const WEB = 'www';

    /**
     * @var string
     */
    const COMMAND_LINE = 'cli';

    /**
     * @var float
     */
    const VERSION = '1.1.2';

    /**
     * @var App
     */
    protected static $_instance;

    /**
     * @var Request
     */
    protected $_request;

    /**
     * @var Delegate
     */
    protected $_delegate;

    /**
     * @var array
     */
    protected $_paths = array();

    /**
     * @var array
     */
    protected $_controllers = array();

    /**
     * @var array
     */
    protected $_queued = array();

    /**
     * @var bool
     */
    protected $_layout_processed = false;

    /**
     * @var array
     */
    protected $_configs = array();

    /**
     * @var array
     */
    protected $_included = array();

    /**
     * @var string
     */
    protected $_base_path;

    /**
     * constants for settings
     */
    const MODE = 0;
    const ENVIRONMENT = 1;
    const AUTOLOAD = 2;
    const CONFIG_FILE = 3;
    const DEVS = 4;
    const DISABLE_APC = 5;
    const TURBO = 6;
    const TURBO_PLACEHOLDER = 7;
    const DEFAULT_SCHEMA = 8;
    const EXTENSION_DATA = 9;
    const EXTENSIONS_LOADED = 10;
    const URI_PREFIX = 11;

    /**
     * @var array
     */
    protected $_settings = array(
        self::MODE => self::WEB,
        self::AUTOLOAD => false,
        self::CONFIG_FILE => 'ini',
        self::DEVS => array('dev', 'development'),
        self::DISABLE_APC => false,
        self::TURBO => false,
        self::EXTENSIONS_LOADED => array()
    );

    /**
     * constructor
     *
     * @return void
     */
    private function __construct() {}

    /**
     * magic call for methods added at runtime
     *
     * @param string $name
     * @param array $args
     */
    public function __call($name, $args)
    {
        return $this->callIfExists($name, $args, __CLASS__, get_class($this));
    }

    /**
     * magic static call for methods added at run time
     *
     * @param string $name
     * @param array $args
     */
    public static function __callStatic($name, $args)
    {
        return self::getInstance()->callIfExists($name, $args, __CLASS__, get_called_class(), true);
    }

    /**
     * calls method if it exists
     *
     * @param string $name
     * @param array $args
     * @param string $class
     * @param instance $class_name
     */
    public function callIfExists($name, $args, $class, $class_name, $static = false)
    {
        if (count($this->getSetting(self::EXTENSIONS_LOADED)) == 0) {
            return trigger_error('Call to undefined method ' . $class_name . '::' . $name . '()', E_USER_ERROR);
        }
        $this->includeFile('Sonic/Extension/Transformation.php');
        $method = $static ? 'callStatic' : 'call';
        return Extension\Transformation::$method($name, $args, $class, $class_name);
    }

    /**
     * gets instance of App class
     *
     * @return App
     */
    public static function getInstance()
    {
        if (self::$_instance === null) {
            self::$_instance = new App();
        }
        return self::$_instance;
    }

    /**
     * handles autoloading
     *
     * @param string $class_name
     * @return void
     */
    public function autoloader($class_name)
    {
        $path = str_replace('\\', '/', $class_name) . '.php';
        return $this->includeFile($path);
    }

    /**
     * includes a file at the given path
     *
     * @param string
     * @return bool
     */
    public function includeFile($path)
    {
        // replace / with directory separator for windows
        $path = str_replace('/', DIRECTORY_SEPARATOR, $path);

        if (isset($this->_included[$path])) {
            return false;
        }

        // if the path starts with / or C: then it is an absolute path
        // otherwise pull it from the libs directory
        include $path[0] == '/' || $path[1] == ':' ? $path : $this->getPath('libs') . DIRECTORY_SEPARATOR . $path;
        $this->_included[$path] = true;

        return true;
    }

    /**
     * initializes autoloader
     *
     * @return void
     */
    public function autoload()
    {
        spl_autoload_register(array($this, 'autoloader'));
    }

    /**
     * sets a setting
     *
     * @param string $key
     * @param mixed $value
     */
    public function addSetting($key, $value)
    {
        $this->_settings[$key] = $value;
    }

    /**
     * gets a setting
     *
     * @param string $name
     * @return mixed
     */
    public function getSetting($name)
    {
        if (!isset($this->_settings[$name])) {
            return null;
        }

        return $this->_settings[$name];
    }

    /**
     * returns the config
     *
     * first tries to grab it from APC then tries to grab it from instance cache
     * if neither of those succeed then it will instantiate the config object
     * and add it to instance cache and/or APC
     *
     * @param string $path path to config path
     * @param string $type (php || ini)
     * @return Config
     */
    public static function getConfig($path = null)
    {
        $app = self::getInstance();
        $environment = $app->getEnvironment();

        $type = $app->getSetting(self::CONFIG_FILE);

        // get the config path
        if ($path === null) {
            $path = $app->getPath('configs') . '/app.' . $type;
        }

        // cache key
        $cache_key =  'config_' . $path . '_' . $environment;

        // if the config is in instance cache return it
        if (isset($app->_configs[$cache_key])) {
            return $app->_configs[$cache_key];
        }

        // we need to load the util and config object before it fetches it from APC
        $app->includeFile('Sonic/Util.php');
        $app->includeFile('Sonic/Config.php');

        // if we are not dev let's try to grab it from APC
        if (!self::isDev() && !$app->getSetting(self::DISABLE_APC) && ($config = apc_fetch($cache_key))) {
            $app->_configs[$cache_key] = $config;
            return $config;
        }

        // if we have gotten here then that means the config exists so we
        // now need to get the environment name and load the config
        $config = new Config($path, $environment, $type);
        $app->_configs[$cache_key] = $config;

        if (!self::isDev() && !$app->getSetting(self::DISABLE_APC)) {
            apc_store($cache_key, $config, Util::toSeconds('24 hours'));
        }

        return $config;
    }

    /**
     * is this dev mode?
     *
     * @return bool
     */
    public static function isDev()
    {
        $app = self::getInstance();
        return in_array($app->getEnvironment(), $app->getSetting(self::DEVS));
    }

    /**
     * gets apache/unix environment name
     *
     * @return string
     */
    public function getEnvironment()
    {
        if ($env = $this->getSetting(self::ENVIRONMENT)) {
            return $env;
        }

        if ($env = getenv('ENVIRONMENT')) {
            $this->addSetting(self::ENVIRONMENT, $env);
            return $env;
        }

        throw new Exception('ENVIRONMENT variable is not set! check your apache config');
    }

    /**
     * gets the request object
     *
     * @return Request
     */
    public function getRequest()
    {
        if (!$this->_request) {
            $this->_request = new Request();
        }
        return $this->_request;
    }

    /**
     * overrides base path
     *
     * @param string $dir
     * @return void
     */
    public function setBasePath($path)
    {
        $this->_base_path = $path;
    }

    /**
     * gets base path of the app
     *
     * @return string
     */
    public function getBasePath()
    {
        if ($this->_base_path) {
            return $this->_base_path;
        }

        throw new \Exception('base path must be set before App::start() is called');
    }

    /**
     * overrides a default path
     *
     * @param string $dir
     * @param string $path
     * @return void
     */
    public function setPath($dir, $path)
    {
        $this->_paths['path_' . $dir] = $path;
    }

    /**
     * gets the absolute path to a directory
     *
     * @param string $dir (views || controllers || lib) etc
     * @return string
     */
    public function getPath($dir = null)
    {
        $cache_key =  'path_' . $dir;

        if (isset($this->_paths[$cache_key])) {
            return $this->_paths[$cache_key];
        }

        $base_path = $this->getBasePath();

        if ($dir !== null) {
            $base_path .= DIRECTORY_SEPARATOR . $dir;
        }

        $this->_paths[$cache_key] = $base_path;
        return $this->_paths[$cache_key];
    }

    /**
     * globally disables layout
     *
     * @return void
     */
    public function disableLayout()
    {
        $this->_layout_processed = true;
    }

    /**
     * gets a controller by name
     *
     * @param string $name
     * @return Controller
     */
    public function getController($name)
    {
        $name = strtolower($name);

        // controller has not been instantiated yet
        if (!isset($this->_controllers[$name])) {
            $path = $this->getPath('controllers') . '/' . str_replace('\\', DIRECTORY_SEPARATOR, $name) . '.php';
            $success = include $path;
            if (!$success) {
                throw new Exception('controller does not exist at path: ' . $path);
            }
            $class_name = '\Controllers\\' . $name;
            $this->_controllers[$name] = new $class_name;
            $this->_controllers[$name]->name($name);
        }

        return $this->_controllers[$name];
    }

    /**
     * runs a controller and action combination
     *
     * @param string $controller_name controller to use
     * @param string $action method within controller to execute
     * @param array $args arguments to be added to the Request object and view
     * @param bool $json should we render json
     * @param string $id view id for if we are in turbo mode an exception is thrown
     * @return void
     */
    protected function _runController($controller_name, $action, $args = array(), $json = false, $id = null)
    {
        $this->getRequest()->addParams($args);

        $controller = $this->getController($controller_name);
        $controller->setView($action, false);

        // if we are requesting JSON that means this is being processed from the turbo queue
        // if we are not in turbo mode then we run the action normally
        $can_run = $json || !$this->getSetting(self::TURBO);

        if ($this->_delegate) {
            $this->_delegate->actionWasCalled($controller, $action, $args);
        }

        if ($can_run) {
            $this->_runAction($controller, $action, $args);
        }

        $view = null;
        if ($controller->hasView()) {
            $view = $controller->getView();
            $view->setAction($action);
            $view->addVars($args);
        }

        // process the layout if we can
        // this takes care of handling this view
        if ($this->_processLayout($controller, $view, $args)) {
            return;
        }

        if (!$view) {
            return;
        }

        if ($this->_delegate) {
            $this->_delegate->viewStartedRendering($view, $json);
        }

        // output the view contents
        $view->output($json, $id);

        if ($this->_delegate) {
            $this->_delegate->viewFinishedRendering($view, $json);
        }
    }

    /**
     * processes the layout if it needs to be processed
     *
     * @param Controller $controller
     * @param View $view
     * @param array $args
     * @return bool
     */
    protected function _processLayout(Controller $controller, View $view = null, $args)
    {
        // if the layout was already processed ignore this call
        if ($this->_layout_processed) {
            return false;
        }

        // if the controller doesn't have a layout ignore this call
        if (!$controller->hasLayout()) {
            return false;
        }

        // if this is not the first controller and not an exception, ignore
        if (count($this->_controllers) != 1 && !isset($args['exception'])) {
            return false;
        }

        // process the layout!
        $this->_layout_processed = true;
        $layout = $controller->getLayout();

        $layout->topView($view ?: new View);

        if ($this->_delegate) {
            $this->_delegate->layoutStartedRendering($layout);
        }

        $layout->output();

        if ($this->_delegate) {
            $this->_delegate->layoutFinishedRendering($layout);
        }

        return true;
    }

    /**
     * runs a specific action in a controller
     *
     * @param Controller $controller
     * @param string $action
     * @return void
     */
    protected function _runAction(Controller $controller, $action, array $args = array())
    {
        if ($this->_delegate) {
            $this->_delegate->actionStartedRunning($controller, $action, $args);
        }

        $controller->$action();
        $controller->actionComplete($action);

        if ($this->_delegate) {
            $this->_delegate->actionFinishedRunning($controller, $action, $args);
        }
    }

    /**
     * public access to run a controller (handles exceptions)
     *
     * @param string $controller_name controller to use
     * @param string $action method within controller to execute
     * @param array $args arguments to be added to the Request object and view
     * @param bool $json should we render json?
     * @param string $controller_name
     */
    public function runController($controller_name, $action, $args = array(), $json = false)
    {
        try {
            $this->_runController($controller_name, $action, $args, $json);
        } catch (\Exception $e) {
            $this->handleException($e, $controller_name, $action);
            return;
        }
    }

    /**
     * queues up a view for later processing
     *
     * only happens in turbo mode
     *
     * @param string
     * @param string
     * @return void
     */
    public function queueView($controller, $name)
    {
        $this->_queued[] = array($controller, $name);
    }

    /**
     * processes queued up views for turbo mode
     *
     * @return void
     */
    public function processViewQueue()
    {
        if (!$this->getSetting(self::TURBO)) {
            return;
        }

        while (count($this->_queued)) {
            foreach ($this->_queued as $key => $queue) {
                $this->runController($queue[0], $queue[1], array(), true);
                unset($this->_queued[$key]);
            }
        }
    }

    /**
     * handles an exception when loading a page
     *
     * @param Exception $e
     * @param string $controller name of controller
     * @param string $action name of action
     * @return void
     */
    public function handleException(\Exception $e, $controller = null, $action = null)
    {
        if ($this->_delegate) {
            $this->_delegate->appCaughtException($e, $controller, $action);
        }

        // turn other exceptions into sonic exceptions
        if (!$e instanceof Exception) {
            $e = new Exception($e->getMessage(), Exception::INTERNAL_SERVER_ERROR, $e);
        }

        // only set the http code if output hasn't started
        if (!headers_sent()) {
            header($e->getHttpCode());
        }

        $json = false;
        $id = null;

        // in turbo mode we have to write the exception markup out to the
        // same div created before the exception was triggered.  this means
        // we have to get the id based on the controller and action that the
        // exception came from
        if ($this->getSetting(self::TURBO) && $this->_layout_processed) {
            $json = true;
            $id = View::generateId($controller, $action);
        }

        $completed = false;

        // controller and action are only null if this is a page not found
        // because we were not able to match any routes.  in all other cases
        // we can get the initial controller and action to determine if it has
        // completed
        if ($controller !== null && $action !== null) {
            $req = $this->getRequest();
            $first_controller = $req->getControllerName();
            $first_action = $req->getAction();
            $completed = $this->getController($first_controller)->hasCompleted($first_action);
        }

        $args = array(
            'exception' => $e,
            'top_level_exception' => !$completed,
            'from_controller' => $controller,
            'from_action' => $action
        );

        return $this->_runController('main', 'error', $args, $json, $id);
    }

    /**
     * determines if we should turn off turbo mode
     *
     * @return bool
     */
    protected function _robotnikWins()
    {
        if ($this->getRequest()->isAjax() || isset($_COOKIE['noturbo']) || isset($_COOKIE['bot'])) {
            return true;
        }

        if (isset($_GET['noturbo'])) {
            setcookie('noturbo', true, time() + 86400);
            return true;
        }

        if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'Googlebot') !== false) {
            setcookie('bot', true, time() + 86400);
            return true;
        }

        return false;
    }

    /**
     * sets a delegate class to receive events as the application runs
     *
     * @param string $delegate name of delegate class
     * @return \Sonic\App
     */
    public function setDelegate($delegate)
    {
        $this->includeFile('Sonic/App/Delegate.php');
        $this->autoloader($delegate);

        $delegate = new $delegate;

        if (!$delegate instanceof App\Delegate) {
            throw new \Exception('app delegate of class ' . get_class($delegate) . ' must be instance of \Sonic\App\Delegate');
        }

        $this->_delegate = $delegate;
        $this->_delegate->setApp($this);
        return $this;
    }

    /**
     * loads an extension by name
     *
     * @param string $name
     * @return App
     */
    public function loadExtension($name)
    {
        // if this is already loaded don't do anything
        if ($this->extensionLoaded($name)) {
            return $this;
        }

        $name = strtolower($name);

        // first grab the extension installation data
        $extensions = $this->getSetting(self::EXTENSION_DATA);
        if (!$extensions) {
            $path = $this->getPath('extensions/installed.json');

            if (file_exists($path)) {
                $extensions = json_decode(file_get_contents($path), true);
                $this->addSetting(self::EXTENSION_DATA, $extensions);
            }
        }

        if (!isset($extensions[$name])) {
            throw new Exception('trying to load extension "' . $name . '" which is not installed!');
        }

        // get the data related to this extension
        $data = $extensions[$name];

        // create a delegate object if this extension has one
        $delegate = null;
        if (isset($data['delegate_path']) && isset($data['delegate'])) {
            $this->includeFile('Sonic/Extension/Delegate.php');
            $this->includeFile($this->getPath($data['delegate_path']));
            $delegate = new $data['delegate'];
        }

        if ($delegate) {
            $delegate->extensionStartedLoading();
        }

        $base_path = $this->getPath();

        $core = 'extensions/' . $name . '/Core.php';
        $has_core = isset($data['has_core']) && $data['has_core'];
        $dev = isset($data['dev']) && $data['dev'];

        foreach ($data['files'] as $file) {

            // if the file is not in the extensions or libs directory then skip it
            // we don't want to load controllers/views/etc. here
            $lib_file = strpos($file, 'libs') === 0;

            // don't load libs files unless the extension says to explicitly
            if ($lib_file && !$data['load_libs']) {
                continue;
            }

            if (strpos($file, 'extensions') !== 0 && !$lib_file) {
                continue;
            }

            // if this is not a PHP file then skip it
            if (substr($file, -4) != '.php') {
                continue;
            }

            // skip core in dev mode
            if ($dev && $file == $core) {
                continue;
            }

            // if this is a file that is not in libs and not core then skip it
            if (!$dev && !$lib_file && $has_core && $file != $core) {
                continue;
            }

            $this->includeFile($base_path . '/' . $file);

            if ($delegate) {
                $delegate->extensionLoadedFile($file);
            }
        }

        $loaded = $this->getSetting(self::EXTENSIONS_LOADED);
        $loaded[] = $name;
        $this->addSetting(self::EXTENSIONS_LOADED, $loaded);

        if ($delegate) {
            $delegate->extensionFinishedLoading();
        }

        return $this;
    }

    /**
     * determines if an extension is loaded
     *
     * @param string $name
     * @return bool
     */
    public function extensionLoaded($name)
    {
        $loaded = $this->getSetting(self::EXTENSIONS_LOADED);
        return in_array(strtolower($name), $loaded);
    }

    /**
     * gets an extension helper for this extension
     *
     * @param string $name
     * @return \Sonic\Extension\Helper
     */
    public function extension($name)
    {
        $this->includeFile('Sonic/Extension/Helper.php');
        return Extension\Helper::forExtension($name);
    }

    /**
     * pushes over the first domino
     *
     * @param string $mode
     * @return void
     */
    public function start($mode = self::WEB)
    {
        $lib = $this->getPath('libs') . DIRECTORY_SEPARATOR . 'Sonic' . DIRECTORY_SEPARATOR;
        try {
            if ($this->_delegate) {
                $this->_delegate->appStartedLoading($mode);
            }

            $this->addSetting(self::MODE, $mode);

            require_once $lib . 'Exception.php';
            require_once $lib . 'Request.php';
            require_once $lib . 'Router.php';
            require_once $lib . 'Controller.php';
            require_once $lib . 'View.php';
            require_once $lib . 'Layout.php';

            if ($this->getSetting(self::AUTOLOAD)) {
                $this->autoload();
            }

            if ($this->_delegate) {
                $this->_delegate->appFinishedLoading();
            }

            // if we are calling this app from command line then all we want to do
            // is load the core application files
            if ($mode != self::WEB) {
                return;
            }

            if ($this->getSetting(self::TURBO) && $this->_robotnikWins()) {
                $this->addSetting(self::TURBO, false);
            }

            // try to get the controller and action
            // if an exception is thrown that means the page requested does not exist
            $controller = $this->getRequest()->getControllerName();
            $action = $this->getRequest()->getAction();

            if ($this->_delegate) {
                $this->_delegate->appStartedRunning();
            }

            $this->runController($controller, $action);

            if ($this->_delegate) {
                $this->_delegate->appFinishedRunning();
            }
        } catch (\Exception $e) {
            $this->handleException($e);
        }
    }
}

ccampbell-rainbow-9570daa/demos/php.html000066400000000000000000000034451173647220700203120ustar00rootroot00000000000000 Syntax Highlighting
// this is some sample php code
$i = 0;
for ($i = 0; $i < 25; ++$i) {
    echo $i;
}

# comment like this
function customFunction()
{
    return mt_rand(1, 100);
}

while ($test) {
    echo 'blah' . "\n";
};

$fruits = array('banana', 'strawberry', 'blueberry', 'apple', 'blackberry');

asort($fruits);

foreach ($fruits as $key => $value) {
    echo $value;
}
<?php
namespace Sonic;

/**
 * Util
 *
 * @category Sonic
 * @package Util
 * @author Craig Campbell
 */
class Util
{
    /**
     * deletes a directory recursively
     *
     * php's native rmdir() function only removes a directory if there is nothing in it
     *
     * @param string $path
     * @return void
     */
    public static function removeDir($path)
    {
        if (is_link($path)) {
            return unlink($path);
        }

        $files = new \RecursiveDirectoryIterator($path);
        foreach ($files as $file) {
            if (in_array($file->getFilename(), array('.', '..'))) {
                continue;
            }

            if ($file->isLink()) {
                unlink($file->getPathName());
                continue;
            }

            if ($file->isFile()) {
                unlink($file->getRealPath());
                continue;
            }

            if ($file->isDir()) {
                self::removeDir($file->getRealPath());
            }
        }
        return rmdir($path);
    }
}

ccampbell-rainbow-9570daa/demos/python.html000066400000000000000000000047211173647220700210420ustar00rootroot00000000000000 Syntax Highlighting
#!/usr/bin/env python
# Copyright 2012 Craig Campbell
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import re, os, math
from util import Util
from instrument import Instrument

class WarpWhistle(object):
    TEMPO = 'tempo'
    VOLUME = 'volume'
    TIMBRE = 'timbre'
    ARPEGGIO = 'arpeggio'
    INSTRUMENT = 'instrument'
    PITCH = 'pitch'
    OCTAVE = 'octave'
    SLIDE = 'slide'
    Q = 'q'

    ABSOLUTE_NOTES = 'X-ABSOLUTE-NOTES'
    TRANSPOSE = 'X-TRANSPOSE'
    COUNTER = 'X-COUNTER'
    X_TEMPO = 'X-TEMPO'
    SMOOTH = 'X-SMOOTH'
    N106 = 'EX-NAMCO106'
    FDS = 'EX-DISKFM'
    VRC6 = 'EX-VRC6'
    PITCH_CORRECTION = 'PITCH-CORRECTION'

    CHIP_N106 = 'N106'
    CHIP_FDS = 'FDS'
    CHIP_VRC6 = 'VRC6'

    def __init__(self, content, logger, options):
        self.first_run = True

        # current voice we are processing if we are processing voices separately
        self.process_voice = None

        # list of voices to process
        self.voices_to_process = None

        # list of voices
        self.voices = None

        self.content = content
        self.logger = logger
        self.options = options
        self.reset()

    def reset(self):
        """
        This method resets the properties of the instance.
        """
        self.current_voices = []
        self.global_vars = {}
        self.vars = {}
        self.instruments = {}
        self.data = {}
        self.global_lines = []

    def getDataForVoice(self, voice, key):
        if not voice in self.data:
            return None

        if not key in self.data[voice]:
            return None

        return self.data[voice][key]
ccampbell-rainbow-9570daa/demos/ruby-test.html000066400000000000000000000036641173647220700214640ustar00rootroot00000000000000 Ruby Test
# Comments
not_comment # comment

=begin
comment
=end

  =begin
  not_comment
  =end

# Strings
'string'
"string"
%q(string)
%q[string]
%q{string}
%q<string>
%q|string|
%Q(string)
%Q[string]
%Q{string}
%Q<string>
%Q|string|

foo('string', 'string')

"unsupported\"string"

# Heredocs
if true
  DOC = foo(<<-DOC)
heredoc
  xxx
    xxx
  DOC
  # ^heredoc ends here
DOC
end

if true
  DOC = foo(<<DOC)
heredoc
  xxx
    xxx
  DOC
DOC
# ^heredoc ends here
end

# Symbols
:symbol
:'long symbol'
:"long symbol"

# Regular Expressions
/regex/xxx
%r(regex)xxx
%r[regex]xxx
%r{regex}xxx
%r<regex>xxx
%r|regex|xxx

foo(/regex/xxx, /regex/xxx)
@path.sub(/^#{@root}/, '')

/unsupported\/regex/

# Classes
class Test < Object
  attr_accessor :z
end

x = Test.method(1, 2)
x = Test::method(1, 2)
x = Test::CONSTANT

# Methods
def method(x, y)
  z = 3
end

def self.method(x, y)
  z = 3
end

# Sigils
$stderr.puts 3
@@foo = 3
@foo = 3

# Data Structures
[:value]
['value']
{:key=>'value'}
{:key => 'value'}
{'key' => 'value'}
{key: 'value'}
foo(:key => 'value')
foo(key: 'value')

# Classes, modules, etc.
module Foo
  CONSTANT = 'An \'escaped\' string'
  class Bar
    def self.something
    begin
      1 + 1
    rescue StandardError => e
      puts "Whoa buddy!"
    end

    class << self
      def something
        1 + 1
      end
    end

    def something
    end
  end
end

class MyClass < ::Foo::Bar
end

foo(::Foo::Bar.something)


ccampbell-rainbow-9570daa/demos/ruby.html000066400000000000000000000143621173647220700205040ustar00rootroot00000000000000 rack/directory.rb
# Copyright (c) 2007, 2008, 2009, 2010 Christian Neukirchen <purl.org/net/chneukirchen>
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
# THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 
# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

require 'time'
require 'rack/utils'
require 'rack/mime'

module Rack
  # Rack::Directory serves entries below the +root+ given, according to the
  # path info of the Rack request. If a directory is found, the file's contents
  # will be presented in an html based index. If a file is found, the env will
  # be passed to the specified +app+.
  #
  # If +app+ is not specified, a Rack::File of the same +root+ will be used.

  class Directory
    DIR_FILE = "<tr><td class='name'><a href='%s'>%s</a></td><td class='size'>%s</td><td class='type'>%s</td><td class='mtime'>%s</td></tr>"
    DIR_PAGE = <<-PAGE
<html><head>
  <title>%s</title>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <style type='text/css'>
table { width:100%%; }
.name { text-align:left; }
.size, .mtime { text-align:right; }
.type { width:11em; }
.mtime { width:15em; }
  </style>
</head><body>
<h1>%s</h1>
<hr />
<table>
  <tr>
    <th class='name'>Name</th>
    <th class='size'>Size</th>
    <th class='type'>Type</th>
    <th class='mtime'>Last Modified</th>
  </tr>
%s
</table>
<hr />
</body></html>
    PAGE

    attr_reader :files
    attr_accessor :root, :path

    def initialize(root, app=nil)
      @root = F.expand_path(root)
      @app = app || Rack::File.new(@root)
    end

    def call(env)
      dup._call(env)
    end

    F = ::File

    def _call(env)
      @env = env
      @script_name = env['SCRIPT_NAME']
      @path_info = Utils.unescape(env['PATH_INFO'])

      if forbidden = check_forbidden
        forbidden
      else
        @path = F.join(@root, @path_info)
        list_path
      end
    end

    def check_forbidden
      return unless @path_info.include? ".."

      body = "Forbidden\n"
      size = Rack::Utils.bytesize(body)
      return [403, {"Content-Type" => "text/plain",
        "Content-Length" => size.to_s,
        "X-Cascade" => "pass"}, [body]]
    end

    def list_directory
      @files = [['../','Parent Directory','','','']]
      glob = F.join(@path, '*')

      url_head = ([@script_name] + @path_info.split('/')).map do |part|
        Rack::Utils.escape part
      end

      Dir[glob].sort.each do |node|
        stat = stat(node)
        next  unless stat
        basename = F.basename(node)
        ext = F.extname(node)

        url = F.join(*url_head + [Rack::Utils.escape(basename)])
        size = stat.size
        type = stat.directory? ? 'directory' : Mime.mime_type(ext)
        size = stat.directory? ? '-' : filesize_format(size)
        mtime = stat.mtime.httpdate
        url << '/'  if stat.directory?
        basename << '/'  if stat.directory?

        @files << [ url, basename, size, type, mtime ]
      end

      return [ 200, {'Content-Type'=>'text/html; charset=utf-8'}, self ]
    end

    def stat(node, max = 10)
      F.stat(node)
    rescue Errno::ENOENT, Errno::ELOOP
      return nil
    end

    # TODO: add correct response if not readable, not sure if 404 is the best
    #       option
    def list_path
      @stat = F.stat(@path)

      if @stat.readable?
        return @app.call(@env) if @stat.file?
        return list_directory if @stat.directory?
      else
        raise Errno::ENOENT, 'No such file or directory'
      end

    rescue Errno::ENOENT, Errno::ELOOP
      return entity_not_found
    end

    def entity_not_found
      body = "Entity not found: #{@path_info}\n"
      size = Rack::Utils.bytesize(body)
      return [404, {"Content-Type" => "text/plain",
        "Content-Length" => size.to_s,
        "X-Cascade" => "pass"}, [body]]
    end

    def each
      show_path = @path.sub(/^#{@root}/,'')
      files = @files.map{|f| DIR_FILE % f }*"\n"
      page  = DIR_PAGE % [ show_path, show_path , files ]
      page.each_line{|l| yield l }
    end

    # Stolen from Ramaze

    FILESIZE_FORMAT = [
      ['%.1fT', 1 << 40],
      ['%.1fG', 1 << 30],
      ['%.1fM', 1 << 20],
      ['%.1fK', 1 << 10],
    ]

    def filesize_format(int)
      FILESIZE_FORMAT.each do |format, size|
        return format % (int.to_f / size) if int >= size
      end

      int.to_s + 'B'
    end
  end
end
ccampbell-rainbow-9570daa/demos/shell.html000066400000000000000000000252641173647220700206350ustar00rootroot00000000000000 ruby-build
#!/usr/bin/env bash
# Copyright (c) 2011 Sam Stephenson
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

RUBY_BUILD_VERSION="20120216"

set -E
exec 3<&2 # preserve original stderr at fd 3

resolve_link() {
  $(type -p greadlink readlink | head -1) "$1"
}

abs_dirname() {
  local cwd="$(pwd)"
  local path="$1"

  while [ -n "$path" ]; do
    cd "${path%/*}"
    local name="${path##*/}"
    path="$(resolve_link "$name" || true)"
  done

  pwd
  cd "$cwd"
}

build_failed() {
  { echo
    echo "BUILD FAILED"
    echo

    if ! rmdir "${TEMP_PATH}" 2>/dev/null; then
      echo "Inspect or clean up the working tree at ${TEMP_PATH}"

      if file_is_not_empty "$LOG_PATH"; then
        echo "Results logged to ${LOG_PATH}"
        echo
        echo "Last 10 log lines:"
        tail -n 10 "$LOG_PATH"
      fi
    fi
  } >&3
  exit 1
}

file_is_not_empty() {
  local filename="$1"
  local line_count="$(wc -l "$filename" 2>/dev/null || true)"

  if [ -n "$line_count" ]; then
    words=( $line_count )
    [ "${words[0]}" -gt 0 ]
  else
    return 1
  fi
}

install_package() {
  install_package_using "tarball" 1 $*
}

install_git() {
  install_package_using "git" 2 $*
}

install_package_using() {
  local package_type="$1"
  local package_type_nargs="$2"
  local package_name="$3"
  shift 3

  pushd "$TEMP_PATH" >&4
  "fetch_${package_type}" "$package_name" $*
  shift $(($package_type_nargs))
  make_package "$package_name" $*
  popd >&4

  echo "Installed ${package_name} to ${PREFIX_PATH}" >&2
}

make_package() {
  local package_name="$1"
  shift

  pushd "$package_name" >&4
  before_install_package "$package_name"
  build_package "$package_name" $*
  after_install_package "$package_name"
  fix_directory_permissions
  popd >&4
}

fetch_tarball() {
  local package_name="$1"
  local package_url="$2"

  echo "Downloading ${package_url}..." >&2
  { curl "$package_url" > "${package_name}.tar.gz"
    tar xzvf "${package_name}.tar.gz"
  } >&4 2>&1
}

fetch_git() {
  local package_name="$1"
  local git_url="$2"
  local git_ref="$3"

  echo "Cloning ${git_url}..." >&2
  { git clone --depth 1 --branch "$git_ref" "$git_url" "${package_name}"
  } >&4 2>&1
}

build_package() {
  local package_name="$1"
  shift

  if [ "$#" -eq 0 ]; then
    local commands="standard"
  else
    local commands="$*"
  fi

  echo "Installing ${package_name}..." >&2

  for command in $commands; do
    "build_package_${command}"
  done
}

build_package_standard() {
  local package_name="$1"

  if [ -z "${MAKEOPTS+defined}" ]; then
    MAKE_OPTS="$MAKEOPTS"
  elif [ -z "${MAKE_OPTS+defined}" ]; then
    MAKE_OPTS="-j 2"
  fi

  { ./configure --prefix="$PREFIX_PATH" $CONFIGURE_OPTS
    make $MAKE_OPTS
    make install
  } >&4 2>&1
}

build_package_autoconf() {
  { autoconf
  } >&4 2>&1
}

build_package_ruby() {
  local package_name="$1"

  { "$RUBY_BIN" setup.rb
  } >&4 2>&1
}

build_package_ree_installer() {
  local options=""
  if [[ "Darwin" = "$(uname)" ]]; then
    options="--no-tcmalloc"
  fi

  # Work around install_useful_libraries crash with --dont-install-useful-gems
  mkdir -p "$PREFIX_PATH/lib/ruby/gems/1.8/gems"

  { ./installer --auto "$PREFIX_PATH" --dont-install-useful-gems $options $CONFIGURE_OPTS
  } >&4 2>&1
}

build_package_rbx() {
  local package_name="$1"

  { ./configure --prefix="$PREFIX_PATH" --gemsdir="$PREFIX_PATH"
    rake install
  } >&4 2>&1
}

build_package_maglev() {
  build_package_copy

  { cd "${PREFIX_PATH}"
    ./install.sh
    cd "${PREFIX_PATH}/bin"
    echo "Creating symlink for ruby*"
    ln -fs maglev-ruby ruby
    echo "Creating symlink for irb*"
    ln -fs maglev-irb irb
  } >&4 2>&1
  echo
  echo "Run 'maglev start' to start up the stone before using 'ruby' or 'irb'"
}

build_package_jruby() {
  build_package_copy
  cd "${PREFIX_PATH}/bin"
  ln -fs jruby ruby
  install_jruby_launcher
  remove_windows_files
}

install_jruby_launcher() {
  cd "${PREFIX_PATH}/bin"
  { ./ruby gem install jruby-launcher
  } >&4 2>&1
}

remove_windows_files() {
  cd "$PREFIX_PATH"
  rm -f bin/*.exe bin/*.dll bin/*.bat bin/jruby.sh
}

build_package_copy() {
  mkdir -p "$PREFIX_PATH"
  cp -R . "$PREFIX_PATH"
}

before_install_package() {
  local stub=1
}

after_install_package() {
  local stub=1
}

fix_directory_permissions() {
  # Ensure installed directories are not world-writable to avoid Bundler warnings
  find "$PREFIX_PATH" -type d -exec chmod go-w {} \;
}

require_gcc() {
  local gcc="$(locate_gcc || true)"
  if [ -z "$gcc" ]; then
    { echo
      echo "ERROR: This package must be compiled with GCC, and we"
      echo "couldn't find a suitable \`gcc' binary on your system."
      echo "Please install GCC and try again."
      echo

      if [ "$(uname -s)" = "Darwin" ]; then
        echo "As of version 4.2, Xcode is LLVM-only and no longer"
        echo "includes GCC. You can install GCC with these binary"
        echo "packages on Mac OS X:"
        echo
        echo "https://github.com/kennethreitz/osx-gcc-installer/downloads"
        echo
      fi
    } >&3
    return 1
  fi

  export CC="$gcc"
}

locate_gcc() {
  local gcc gccs
  IFS=: gccs=($(gccs_in_path))

  verify_gcc "$CC" ||
  verify_gcc "$(command -v gcc || true)" || {
    for gcc in "${gccs[@]}"; do
      verify_gcc "$gcc" && break || true
    done
  }

  return 1
}

gccs_in_path() {
  local gcc path paths
  local gccs=()
  IFS=: paths=($PATH)

  shopt -s nullglob
  for path in "${paths[@]}"; do
    for gcc in "$path"/gcc-*; do
      gccs["${#gccs[@]}"]="$gcc"
    done
  done
  shopt -u nullglob

  printf :%s "${gccs[@]}"
}

verify_gcc() {
  local gcc="$1"
  if [ -z "$gcc" ]; then
    return 1
  fi

  local version="$("$gcc" --version || true)"
  if [ -z "$version" ]; then
    return 1
  fi

  if echo "$version" | grep LLVM >/dev/null; then
    return 1
  fi

  echo "$gcc"
}

version() {
  echo "ruby-build ${RUBY_BUILD_VERSION}"
}

usage() {
  { version
    echo "usage: ruby-build [-v|--verbose] definition prefix"
    echo "       ruby-build --definitions"
  } >&2

  if [ -z "$1" ]; then
    exit 1
  fi
}

list_definitions() {
  { for definition in "${RUBY_BUILD_ROOT}/share/ruby-build/"*; do
      echo "${definition##*/}"
    done
  } | sort
}



unset VERBOSE
RUBY_BUILD_ROOT="$(abs_dirname "$0")/.."

case "$1" in
"-h" | "--help" )
  usage without_exiting
  { echo
    echo "  -v/--verbose     Verbose mode: print compilation status to stdout"
    echo "  --definitions    List all built-in definitions"
    echo
  } >&2
  exit 0
  ;;
"--definitions" )
  list_definitions
  exit 0
  ;;
"--version" )
  version
  exit 0
  ;;
"-v" | "--verbose" )
  VERBOSE=true
  shift
  ;;
esac


DEFINITION_PATH="$1"
if [ -z "$DEFINITION_PATH" ]; then
  usage
elif [ ! -e "$DEFINITION_PATH" ]; then
  BUILTIN_DEFINITION_PATH="${RUBY_BUILD_ROOT}/share/ruby-build/${DEFINITION_PATH}"
  if [ -e "$BUILTIN_DEFINITION_PATH" ]; then
    DEFINITION_PATH="$BUILTIN_DEFINITION_PATH"
  else
    echo "ruby-build: definition not found: ${DEFINITION_PATH}" >&2
    exit 1
  fi
fi

PREFIX_PATH="$2"
if [ -z "$PREFIX_PATH" ]; then
  usage
fi

if [ -z "$TMPDIR" ]; then
  TMP="/tmp"
else
  TMP="${TMPDIR%/}"
fi

SEED="$(date "+%Y%m%d%H%M%S").$$"
LOG_PATH="${TMP}/ruby-build.${SEED}.log"
TEMP_PATH="${TMP}/ruby-build.${SEED}"
RUBY_BIN="${PREFIX_PATH}/bin/ruby"
CWD="$(pwd)"

exec 4<> "$LOG_PATH" # open the log file at fd 4
if [ -n "$VERBOSE" ]; then
  tail -f "$LOG_PATH" &
  trap "kill 0" SIGINT SIGTERM EXIT
fi

export LDFLAGS="-L'${PREFIX_PATH}/lib' ${LDFLAGS}"
export CPPFLAGS="-I'${PREFIX_PATH}/include' ${CPPFLAGS}"

unset RUBYOPT
unset RUBYLIB

trap build_failed ERR
mkdir -p "$TEMP_PATH"
source "$DEFINITION_PATH"
rm -fr "$TEMP_PATH"
trap - ERR
ccampbell-rainbow-9570daa/js/000077500000000000000000000000001173647220700161345ustar00rootroot00000000000000ccampbell-rainbow-9570daa/js/language/000077500000000000000000000000001173647220700177175ustar00rootroot00000000000000ccampbell-rainbow-9570daa/js/language/c.js000066400000000000000000000037711173647220700205070ustar00rootroot00000000000000/** * C patterns * * @author Daniel Holden * @author Craig Campbell * @version 1.0.2 */ Rainbow.extend('c', [ { 'matches': { 2: [ { 'matches': { 1: 'keyword.define', 2: 'entity.name' }, 'pattern': /(\w+)\s(\w+)\b/g }, { 'name': 'keyword.define', 'pattern': /endif/g }, { 'matches': { 1: 'keyword.include', 2: 'string' }, 'pattern': /(include)\s(.*?)$/g } ] }, 'pattern': /(\#)([\S\s]*?)$/gm }, { 'name': 'keyword', 'pattern': /\b(do|goto|continue|break|switch|case|typedef)\b/g }, { 'name': 'entity.label', 'pattern': /\w+:/g }, { 'matches': { 1: 'storage.type', 3: 'storage.type', 4: 'entity.name.function' }, 'pattern': /\b((un)?signed|const)?\s?(void|char|short|int|long|float|double)\*?(\s(\w+)(?=\())?/g }, { 'matches': { 2: 'entity.name.function' }, 'pattern': /(\w|\*)(\s(\w+)(?=\())?/g }, { 'name': 'storage.modifier', 'pattern': /\b(static|extern|auto|register|volatile|inline)\b/g }, { 'name': 'support.type', 'pattern': /\b(struct|union|enum)\b/g }, /** * reset constants */ { 'name': 'variable', 'pattern': /\b[A-Z0-9_]{2,}\b/g }, /** * this rule is very iffy, but it seems like textmate * highlights anything like this * * using 4 or more characters to avoid keywords intersecting * such as if( and for( */ { 'matches': { 1: 'support.function.call' }, 'pattern': /(\w{4,})(?=\()/g } ]); ccampbell-rainbow-9570daa/js/language/css.js000066400000000000000000000043111173647220700210440ustar00rootroot00000000000000/** * CSS patterns * * @author Craig Campbell * @version 1.0.6 */ Rainbow.extend('css', [ { 'name': 'comment', 'pattern': /\/\*[\s\S]*?\*\//gm }, { 'name': 'constant.hex-color', 'pattern': /#([a-f0-9]{3}|[a-f0-9]{6})(?=;|\s)/gi }, { 'matches': { 1: 'constant.numeric', 2: 'keyword.unit' }, 'pattern': /(\d+)(px|cm|s|%)?/g }, { 'name': 'string', 'pattern': /('|")(.*?)\1/g }, { 'name': 'support.css-property', 'matches': { 1: 'support.vendor-prefix' }, 'pattern': /(-o-|-moz-|-webkit-|-ms-)?[\w-]+(?=\s?:)(?!.*\{)/g }, { 'matches': { 1: [ { 'name': 'entity.name.sass', 'pattern': /&/g }, { 'name': 'direct-descendant', 'pattern': />/g }, { 'name': 'entity.name.class', 'pattern': /\.[\w\-_]+/g }, { 'name': 'entity.name.id', 'pattern': /\#[\w\-_]+/g }, { 'name': 'entity.name.pseudo', 'pattern': /:[\w\-_]+/g }, { 'name': 'entity.name.tag', 'pattern': /\w+/g } ] }, 'pattern': /([\w\ ,:\.\#\&\;\-_]+)(?=.*\{)/g }, { 'matches': { 2: 'support.vendor-prefix', 3: 'support.css-value' }, 'pattern': /(:|,)\s?(-o-|-moz-|-webkit-|-ms-)?([a-zA-Z-]*)(?=\b)(?!.*\{)/g }, { 'matches': { 1: 'support.tag.style', 2: [ { 'name': 'string', 'pattern': /('|")(.*?)(\1)/g }, { 'name': 'entity.tag.style', 'pattern': /(\w+)/g } ], 3: 'support.tag.style' }, 'pattern': /(<\/?)(style.*?)(>)/g } ], true); ccampbell-rainbow-9570daa/js/language/generic.js000066400000000000000000000032501173647220700216710ustar00rootroot00000000000000/** * Generic language patterns * * @author Craig Campbell * @version 1.0.6 */ Rainbow.extend([ { 'matches': { 1: { 'name': 'keyword.operator', 'pattern': /\=/g }, 2: { 'name': 'string', 'matches': { 'name': 'constant.character.escape', 'pattern': /\\('|"){1}/g } } }, 'pattern': /(\(|\s|\[|\=)(('|")([^\\\1]|\\.)*?(\3))/gm }, { 'name': 'comment', 'pattern': /\/\*[\s\S]*?\*\/|(\/\/|\#)[\s\S]*?$/gm }, { 'name': 'constant.numeric', 'pattern': /\b(\d+(\.\d+)?(e(\+|\-)?\d+)?(f|d)?|0x[\da-f]+)\b/gi }, { 'name': 'constant', 'pattern': /\b[A-Z0-9_]{2,}\b/g }, { 'matches': { 1: 'keyword' }, 'pattern': /\b(and|array|as|bool(ean)?|c(atch|har|lass|onst)|d(ef|elete|ie|o(uble)?)|e(cho|lse(if)?|xit|xtends|xcept)|f(inally|loat|or(each)?|unction)|global|if|import|int(eger)?|long|new|object|or|pr(int|ivate|otected)|public|return|self|st(ring|ruct|atic)|switch|th(en|is|row)|try|(un)?signed|var|void|while)(?=\(|\b)/gi }, { 'name': 'constant.language', 'pattern': /true|false|null/g }, { 'name': 'keyword.operator', 'pattern': /\+|\!|\-|&(gt|lt|amp);|\||\*|\=/g }, { 'matches': { 1: 'function.call' }, 'pattern': /(\w+?)(?=\()/g }, { 'matches': { 1: 'storage.function', 2: 'entity.name.function' }, 'pattern': /(function)\s(.*?)(?=\()/g } ]); ccampbell-rainbow-9570daa/js/language/html.js000066400000000000000000000034621173647220700212260ustar00rootroot00000000000000/** * HTML patterns * * @author Craig Campbell * @version 1.0.4 */ Rainbow.extend('html', [ { 'name': 'source.php.embedded', 'matches': { 2: { 'language': 'php' } }, 'pattern': /<\?(php)?([\s\S]*?)(\?>)/gm }, { 'name': 'source.css.embedded', 'matches': { 0: { 'language': 'css' } }, 'pattern': /<style(.*?)>([\s\S]*?)<\/style>/gm }, { 'name': 'source.js.embedded', 'matches': { 0: { 'language': 'javascript' } }, 'pattern': /<script(?! src)(.*?)>([\s\S]*?)<\/script>/gm }, { 'name': 'comment.html', 'pattern': /<\!--[\S\s]*?-->/g }, { 'matches': { 1: 'support.tag.open', 2: 'support.tag.close' }, 'pattern': /(<)|(\/?>)/g }, { 'name': 'support.tag', 'matches': { 1: 'support.tag', 2: 'support.tag.special', 3: 'support.tag-name' }, 'pattern': /(<)(\/|\!?)(\w+)/g }, { 'matches': { 1: 'support.attribute' }, 'pattern': /([a-z-]+)(?=\=)/g }, { 'matches': { 1: 'support.operator', 2: 'string.quote', 3: 'string.value', 4: 'string.quote' }, 'pattern': /(=)('|")(.*?)(\2)/g }, { 'matches': { 1: 'support.operator', 2: 'support.value' }, 'pattern': /(=)([a-zA-Z\-0-9]*)\b/g }, { 'matches': { 1: 'support.attribute' }, 'pattern': /\s(\w+)(?=\s|>)(?![\s\S]*<)/g } ], true); ccampbell-rainbow-9570daa/js/language/javascript.js000066400000000000000000000044571173647220700224350ustar00rootroot00000000000000/** * Javascript patterns * * @author Craig Campbell * @version 1.0.6 */ Rainbow.extend('javascript', [ /** * matches $. or $( */ { 'name': 'selector', 'pattern': /(\s|^)\$(?=\.|\()/g }, { 'name': 'support', 'pattern': /\b(window|document)\b/g }, { 'matches': { 1: 'support.property' }, 'pattern': /\.(length|node(Name|Value))\b/g }, { 'matches': { 1: 'support.function' }, 'pattern': /(setTimeout|setInterval)(?=\()/g }, { 'matches': { 1: 'support.method' }, 'pattern': /\.(getAttribute|push|getElementById|getElementsByClassName|log|setTimeout|setInterval)(?=\()/g }, { 'matches': { 1: 'support.tag.script', 2: [ { 'name': 'string', 'pattern': /('|")(.*?)(\1)/g }, { 'name': 'entity.tag.script', 'pattern': /(\w+)/g } ], 3: 'support.tag.script' }, 'pattern': /(<\/?)(script.*?)(>)/g }, /** * matches any escaped characters inside of a js regex pattern * * @see https://github.com/ccampbell/rainbow/issues/22 * * this was causing single line comments to fail so it now makes sure * the opening / is not directly followed by a * * * @todo check that there is valid regex in match group 1 */ { 'name': 'string.regexp', 'matches': { 1: 'string.regexp.open', 2: { 'name': 'constant.regexp.escape', 'pattern': /\\(.){1}/g }, 3: 'string.regexp.close', 4: 'string.regexp.modifier' }, 'pattern': /(\/)(?!\*)(.+)(\/)([igm]{0,3})/g }, /** * matches runtime function declarations */ { 'matches': { 1: 'storage', 3: 'entity.function' }, 'pattern': /(var)?(\s|^)(.*)(?=\s?=\s?function\()/g }, /** * matches any function call in the style functionName: function() */ { 'name': 'entity.function', 'pattern': /(\w+)(?=:\s{0,}function)/g } ]); ccampbell-rainbow-9570daa/js/language/php.js000066400000000000000000000057371173647220700210600ustar00rootroot00000000000000/** * PHP patterns * * @author Craig Campbell * @version 1.0.3 */ Rainbow.extend('php', [ { 'name': 'support', 'pattern': /\becho\b/g }, { 'matches': { 1: 'variable.dollar-sign', 2: 'variable' }, 'pattern': /(\$)(\w+)\b/g }, { 'name': 'keyword.dot', 'pattern': /\./g }, { 'name': 'keyword', 'pattern': /\b(continue|break|end(for(each)?|switch|if)|case|require(_once)?|include(_once)?)(?=\(|\b)/g }, { 'matches': { 1: 'keyword', 2: { 'name': 'support.class', 'pattern': /\w+/g } }, 'pattern': /(instanceof)\s([^\$].*?)(\)|;)/g }, /** * these are the top 50 most used PHP functions * found from running a script and checking the frequency of each function * over a bunch of popular PHP frameworks then combining the results */ { 'matches': { 1: 'support.function' }, 'pattern': /\b(array(_key_exists|_merge|_keys|_shift)?|isset|count|empty|unset|printf|is_(array|string|numeric|object)|sprintf|each|date|time|substr|pos|str(len|pos|tolower|_replace|totime)?|ord|trim|in_array|implode|end|preg_match|explode|fmod|define|link|list|get_class|serialize|file|sort|mail|dir|idate|log|intval|header|chr|function_exists|dirname|preg_replace|file_exists)(?=\()/g }, { 'name': 'variable.language.php-tag', 'pattern': /(<\?(php)?|\?>)/g }, { 'matches': { 1: 'keyword.namespace', 2: { 'name': 'support.namespace', 'pattern': /\w+/g } }, 'pattern': /\b(namespace)\s(.*?);/g }, { 'matches': { 1: 'storage.modifier', 2: 'storage.class', 3: 'entity.name.class', 4: 'storage.modifier.extends', 5: 'entity.other.inherited-class' }, 'pattern': /\b(abstract|final)?\s?(class)\s(\w+)(\sextends\s)?([\w\\]*)?\s?\{?(\n|\})/g }, { 'name': 'keyword.static', 'pattern': /self::|static::/g }, { 'matches': { 1: 'storage.function', 2: 'support.magic' }, 'pattern': /(function)\s(__.*?)(?=\()/g }, { 'matches': { 1: 'keyword.new', 2: { 'name': 'support.class', 'pattern': /\w+/g } }, 'pattern': /\b(new)\s([^\$].*?)(?=\)|\(|;)/g }, { 'matches': { 1: { 'name': 'support.class', 'pattern': /\w+/g }, 2: 'keyword.static' }, 'pattern': /([\w\\]*?)(::)(?=\b|\$)/g }, { 'matches': { 2: { 'name': 'support.class', 'pattern': /\w+/g } }, 'pattern': /(\(|,\s?)([\w\\]*?)(?=\s\$)/g } ]); ccampbell-rainbow-9570daa/js/language/python.js000066400000000000000000000047421173647220700216050ustar00rootroot00000000000000/** * Python patterns * * @author Craig Campbell * @version 1.0.5 */ Rainbow.extend('python', [ /** * Python doesn't have constants so we should reset this pattern */ { 'name': 'variable', 'pattern': /\b[A-Z0-9_]{2,}\b/g }, /** * don't highlight self as a keyword */ { 'name': 'variable.self', 'pattern': /self/g }, { 'name': 'constant.language', 'pattern': /None|True|False/g }, { 'name': 'support.object', 'pattern': /object/g }, /** * built in python functions * * this entire list is 580 bytes minified / 379 bytes gzipped * * @see http://docs.python.org/library/functions.html * * @todo strip some out or consolidate the regexes with matching patterns? */ { 'name': 'support.function.python', 'pattern': /\b(bs|divmod|input|open|staticmethod|all|enumerate|int|ord|str|any|eval|isinstance|pow|sum|basestring|execfile|issubclass|print|super|bin|file|iter|property|tuple|bool|filter|len|range|type|bytearray|float|list|raw_input|unichr|callable|format|locals|reduce|unicode|chr|frozenset|long|reload|vars|classmethod|getattr|map|repr|xrange|cmp|globals|max|reversed|zip|compile|hasattr|memoryview|round|__import__|complex|hash|min|set|apply|delattr|help|next|setattr|buffer|dict|hex|object|slice|coerce|dir|id|oct|sorted|intern)(?=\()/g }, { 'matches': { 1: 'keyword' }, 'pattern': /\b(pass|lambda|with|is|not|in|from|elif)(?=\(|\b)/g }, { 'matches': { 1: 'storage.class', 2: 'entity.name.class', 3: 'entity.other.inherited-class' }, 'pattern': /(class)\s+(\w+)\((\w+?)\)/g }, { 'matches': { 1: 'storage.function', 2: 'support.magic' }, 'pattern': /(def)\s+(__\w+)(?=\()/g }, { 'name': 'support.magic', 'pattern': /__(name)__/g }, { 'matches': { 1: 'keyword.control', 2: 'support.exception.type' }, 'pattern': /(except) (\w+):/g }, { 'matches': { 1: 'storage.function', 2: 'entity.name.function' }, 'pattern': /(def)\s+(\w+)(?=\()/g }, { 'name': 'entity.name.function.decorator', 'pattern': /@(\w+)/g }, { 'name': 'comment.docstring', 'pattern': /('{3}|"{3})[\s\S]*\1/gm } ]); ccampbell-rainbow-9570daa/js/language/ruby.js000066400000000000000000000123021173647220700212340ustar00rootroot00000000000000/** * Ruby patterns * * @author Matthew King * @author Jesse Farmer * @author actsasflinn * @version 1.0.5 */ Rainbow.extend('ruby', [ /** * Strings * 1. No support for multi-line strings */ { 'name': 'string', 'matches': { 1: 'string.open', 2: { 'name': 'string.keyword', 'pattern': /(\#\{.*?\})/g }, 3: 'string.close' }, 'pattern': /("|`)(.*?[^\\\1])?(\1)/g }, { 'name': 'string', 'pattern': /('|"|`)([^\\\1\n]|\\.)*\1/g }, { 'name': 'string', 'pattern': /%[qQ](?=(\(|\[|\{|<|.)(.*?)(?:'|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)/g }, /** * Heredocs * Heredocs of the form `<<'HTML' ... HTML` are unsupported. */ { 'matches': { 1: 'string', 2: 'string', 3: 'string' }, 'pattern': /(<<)(\w+).*?$([\s\S]*?^\2)/gm }, { 'matches': { 1: 'string', 2: 'string', 3: 'string' }, 'pattern': /(<<\-)(\w+).*?$([\s\S]*?\2)/gm }, /** * Regular expressions * Escaped delimiter (`/\//`) is unsupported. */ { 'name': 'string.regexp', 'matches': { 1: 'string.regexp', 2: { 'name': 'string.regexp', 'pattern': /\\(.){1}/g }, 3: 'string.regexp', 4: 'string.regexp' }, 'pattern': /(\/)(.*?)(\/)([a-z]*)/g }, { 'name': 'string.regexp', 'matches': { 1: 'string.regexp', 2: { 'name': 'string.regexp', 'pattern': /\\(.){1}/g }, 3: 'string.regexp', 4: 'string.regexp' }, 'pattern': /%r(?=(\(|\[|\{|<|.)(.*?)('|\)|\]|\}|>|\1))(?:\(\2\)|\[\2\]|\{\2\}|\<\2>|\1\2\1)([a-z]*)/g }, /** * Comments */ { 'name': 'comment', 'pattern': /#.*$/gm }, { 'name': 'comment', 'pattern': /^\=begin[\s\S]*?\=end$/gm }, /** * Symbols */ { 'matches': { 1: 'constant' }, 'pattern': /(\w+:)[^:]/g }, { 'matches': { 1: 'constant.symbol' }, 'pattern': /[^:](:(?:\w+|(?=['"](.*?)['"])(?:"\2"|'\2')))/g }, { 'name': 'constant.numeric', 'pattern': /\b(0x[\da-f]+|\d+)\b/g }, { 'name': 'support.class', 'pattern': /\b[A-Z]\w*(?=((\.|::)[A-Za-z]|\[))/g }, { 'name': 'constant', 'pattern': /\b[A-Z]\w*\b/g }, /** * Keywords, variables, constants, and operators * In Ruby some keywords are valid method names, e.g., MyClass#yield * Don't mark those instances as "keywords" */ { 'matches': { 1: 'storage.class', 2: 'entity.name.class', 3: 'entity.other.inherited-class' }, 'pattern': /\s*(class)\s+((?:(?:::)?[A-Z]\w*)+)(?:\s+<\s+((?:(?:::)?[A-Z]\w*)+))?/g }, { 'matches': { 1: 'storage.module', 2: 'entity.name.class' }, 'pattern': /\s*(module)\s+((?:(?:::)?[A-Z]\w*)+)/g }, { 'name': 'variable.global', 'pattern': /\$([a-zA-Z_]\w*)\b/g }, { 'name': 'variable.class', 'pattern': /@@([a-zA-Z_]\w*)\b/g }, { 'name': 'variable.instance', 'pattern': /@([a-zA-Z_]\w*)\b/g }, { 'matches': { 1: 'keyword.control' }, 'pattern': /[^\.]\b(BEGIN|begin|case|class|do|else|elsif|END|end|ensure|for|if|in|module|rescue|then|unless|until|when|while)\b(?![?!])/g }, { 'matches': { 1: 'keyword.control.pseudo-method' }, 'pattern': /[^\.]\b(alias|alias_method|break|next|redo|retry|return|super|undef|yield)\b(?![?!])|\bdefined\?|\bblock_given\?/g }, { 'matches': { 1: 'constant.language' }, 'pattern': /\b(nil|true|false)\b(?![?!])/g }, { 'matches': { 1: 'variable.language' }, 'pattern': /\b(__(FILE|LINE)__|self)\b(?![?!])/g }, { 'matches': { 1: 'keyword.special-method' }, 'pattern': /\b(require|gem|initialize|new|loop|include|extend|raise|attr_reader|attr_writer|attr_accessor|attr|catch|throw|private|module_function|public|protected)\b(?![?!])/g }, { 'name': 'keyword.operator', 'pattern': /\s\?\s|=|<<|<<=|%=|&=|\*=|\*\*=|\+=|\-=|\^=|\|{1,2}=|<<|<=>|<(?!<|=)|>(?!<|=|>)|<=|>=|===|==|=~|!=|!~|%|&|\*\*|\*|\+|\-|\/|\||~|>>/g }, { 'matches': { 1: 'keyword.operator.logical' }, 'pattern': /[^\.]\b(and|not|or)\b/g }, /** * Functions * 1. No support for marking function parameters */ { 'matches': { 1: 'storage.function', 2: 'entity.name.function' }, 'pattern': /(def)\s(.*?)(?=(\s|\())/g } ], true); ccampbell-rainbow-9570daa/js/language/shell.js000066400000000000000000000026231173647220700213670ustar00rootroot00000000000000/** * Shell patterns * * @author Matthew King * @author Craig Campbell * @version 1.0.3 */ Rainbow.extend('shell', [ /** * This handles the case where subshells contain quotes. * For example: `"$(resolve_link "$name" || true)"`. * * Caveat: This really should match balanced parentheses, but cannot. * @see http://stackoverflow.com/questions/133601/can-regular-expressions-be-used-to-match-nested-patterns */ { 'name': 'shell', 'matches': { 1: { 'language': 'shell' } }, 'pattern': /\$\(([\s\S]*?)\)/gm }, { 'matches': { 2: 'string' }, 'pattern': /(\(|\s|\[|\=)(('|")[\s\S]*?(\3))/gm }, { 'name': 'keyword.operator', 'pattern': /<|>|&/g }, { 'name': 'comment', 'pattern': /\#[\s\S]*?$/gm }, { 'name': 'storage.function', 'pattern': /(.+?)(?=\(\)\s{0,}\{)/g }, /** * Environment variables */ { 'name': 'support.command', 'pattern': /\b(echo|rm|ls|(mk|rm)dir|cd|find|cp|exit|pwd|exec|trap|source|shift|unset)/g }, { 'matches': { 1: 'keyword' }, 'pattern': /\b(break|case|continue|do|done|elif|else|esac|eval|export|fi|for|function|if|in|local|return|set|then|unset|until|while)(?=\(|\b)/g } ], true); ccampbell-rainbow-9570daa/js/rainbow.js000066400000000000000000000622221173647220700201370ustar00rootroot00000000000000/** * Copyright 2012 Craig Campbell * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Rainbow is a simple code syntax highlighter * * @preserve @version 1.1.8 * @url rainbowco.de */ window['Rainbow'] = (function() { /** * array of replacements to process at the end * * @type {Object} */ var replacements = {}, /** * an array of start and end positions of blocks to be replaced * * @type {Object} */ replacement_positions = {}, /** * an array of the language patterns specified for each language * * @type {Object} */ language_patterns = {}, /** * an array of languages and whether they should bypass the default patterns * * @type {Object} */ bypass_defaults = {}, /** * processing level * * replacements are stored at this level so if there is a sub block of code * (for example php inside of html) it runs at a different level * * @type {number} */ CURRENT_LEVEL = 0, /** * constant used to refer to the default language * * @type {number} */ DEFAULT_LANGUAGE = 0, /** * used as counters so we can selectively call setTimeout * after processing a certain number of matches/replacements * * @type {number} */ match_counter = 0, /** * @type {number} */ replacement_counter = 0, /** * @type {null|string} */ global_class, /** * @type {null|Function} */ onHighlight; /** * cross browser get attribute for an element * * @see http://stackoverflow.com/questions/3755227/cross-browser-javascript-getattribute-method * * @param {Node} el * @param {string} attr attribute you are trying to get * @returns {string|number} */ function _attr(el, attr, attrs, i) { var result = (el.getAttribute && el.getAttribute(attr)) || 0; if (!result) { attrs = el.attributes; for (i = 0; i < attrs.length; ++i) { if (attrs[i].nodeName === attr) { return attrs[i].nodeValue; } } } return result; } /** * adds a class to a given code block * * @param {Element} el * @param {string} class_name class name to add * @returns void */ function _addClass(el, class_name) { el.className += el.className ? ' ' + class_name : class_name; } /** * checks if a block has a given class * * @param {Element} el * @param {string} class_name class name to check for * @returns {boolean} */ function _hasClass(el, class_name) { return (' ' + el.className + ' ').indexOf(' ' + class_name + ' ') > -1; } /** * gets the language for this block of code * * @param {Element} block * @returns {string|null} */ function _getLanguageForBlock(block) { // if this doesn't have a language but the parent does then use that // this means if for example you have:
        // with a bunch of  blocks inside then you do not have
        // to specify the language for each block
        var language = _attr(block, 'data-language') || _attr(block.parentNode, 'data-language');

        // this adds support for specifying language via a css class
        // you can use the Google Code Prettify style: 
        // or the HTML5 style: 

        if (!language) {
            var pattern = /\blang(?:uage)?-(\w+)/,
                match = block.className.match(pattern) || block.parentNode.className.match(pattern);

            if (match) {
                language = match[1];
            }
        }

        return language;
    }

    /**
     * makes sure html entities are always used for tags
     *
     * @param {string} code
     * @returns {string}
     */
    function _htmlEntities(code) {
        return code.replace(//g, '>').replace(/&(?![\w\#]+;)/g, '&');
    }

    /**
     * determines if a new match intersects with an existing one
     *
     * @param {number} start1    start position of existing match
     * @param {number} end1      end position of existing match
     * @param {number} start2    start position of new match
     * @param {number} end2      end position of new match
     * @returns {boolean}
     */
    function _intersects(start1, end1, start2, end2) {
        if (start2 >= start1 && start2 < end1) {
            return true;
        }

        return end2 > start1 && end2 < end1;
    }

    /**
     * determines if two different matches have complete overlap with each other
     *
     * @param {number} start1   start position of existing match
     * @param {number} end1     end position of existing match
     * @param {number} start2   start position of new match
     * @param {number} end2     end position of new match
     * @returns {boolean}
     */
    function _hasCompleteOverlap(start1, end1, start2, end2) {

        // if the starting and end positions are exactly the same
        // then the first one should stay and this one should be ignored
        if (start2 == start1 && end2 == end1) {
            return false;
        }

        return start2 <= start1 && end2 >= end1;
    }

    /**
     * determines if the match passed in falls inside of an existing match
     * this prevents a regex pattern from matching inside of a bigger pattern
     *
     * @param {number} start - start position of new match
     * @param {number} end - end position of new match
     * @returns {boolean}
     */
    function _matchIsInsideOtherMatch(start, end) {
        for (var key in replacement_positions[CURRENT_LEVEL]) {
            key = parseInt(key, 10);

            // if this block completely overlaps with another block
            // then we should remove the other block and return false
            if (_hasCompleteOverlap(key, replacement_positions[CURRENT_LEVEL][key], start, end)) {
                delete replacement_positions[CURRENT_LEVEL][key];
                delete replacements[CURRENT_LEVEL][key];
            }

            if (_intersects(key, replacement_positions[CURRENT_LEVEL][key], start, end)) {
                return true;
            }
        }

        return false;
    }

    /**
     * takes a string of code and wraps it in a span tag based on the name
     *
     * @param {string} name     name of the pattern (ie keyword.regex)
     * @param {string} code     block of code to wrap
     * @returns {string}
     */
    function _wrapCodeInSpan(name, code) {
        return '' + code + '';
    }

    /**
     * finds out the position of group match for a regular expression
     *
     * @see http://stackoverflow.com/questions/1985594/how-to-find-index-of-groups-in-match
     *
     * @param {Object} match
     * @param {number} group_number
     * @returns {number}
     */
    function _indexOfGroup(match, group_number) {
        var index = 0,
            i;

        for (i = 1; i < group_number; ++i) {
            if (match[i]) {
                index += match[i].length;
            }
        }

        return index;
    }

    /**
     * matches a regex pattern against a block of code
     * finds all matches that should be processed and stores the positions
     * of where they should be replaced within the string
     *
     * this is where pretty much all the work is done but it should not
     * be called directly
     *
     * @param {RegExp} pattern
     * @param {string} code
     * @returns void
     */
    function _processPattern(regex, pattern, code, callback)
    {
        var match = regex.exec(code);

        if (!match) {
            return callback();
        }

        ++match_counter;

        // treat match 0 the same way as name
        if (!pattern['name'] && typeof pattern['matches'][0] == 'string') {
            pattern['name'] = pattern['matches'][0];
            delete pattern['matches'][0];
        }

        var replacement = match[0],
            start_pos = match.index,
            end_pos = match[0].length + start_pos,

            /**
             * callback to process the next match of this pattern
             */
            processNext = function() {
                var nextCall = function() {
                    _processPattern(regex, pattern, code, callback);
                };

                // every 100 items we process let's call set timeout
                // to let the ui breathe a little
                return match_counter % 100 > 0 ? nextCall() : setTimeout(nextCall, 0);
            };

        // if this is not a child match and it falls inside of another
        // match that already happened we should skip it and continue processing
        if (_matchIsInsideOtherMatch(start_pos, end_pos)) {
            return processNext();
        }

        /**
         * callback for when a match was successfully processed
         *
         * @param {string} replacement
         * @returns void
         */
        var onMatchSuccess = function(replacement) {
                // if this match has a name then wrap it in a span tag
                if (pattern['name']) {
                    replacement = _wrapCodeInSpan(pattern['name'], replacement);
                }

                // console.log('LEVEL', CURRENT_LEVEL, 'replace', match[0], 'with', replacement, 'at position', start_pos, 'to', end_pos);

                // store what needs to be replaced with what at this position
                if (!replacements[CURRENT_LEVEL]) {
                    replacements[CURRENT_LEVEL] = {};
                    replacement_positions[CURRENT_LEVEL] = {};
                }

                replacements[CURRENT_LEVEL][start_pos] = {
                    'replace': match[0],
                    'with': replacement
                };

                // store the range of this match so we can use it for comparisons
                // with other matches later
                replacement_positions[CURRENT_LEVEL][start_pos] = end_pos;

                // process the next match
                processNext();
            },

            // if this pattern has sub matches for different groups in the regex
            // then we should process them one at a time by rerunning them through
            // this function to generate the new replacement
            //
            // we run through them backwards because the match position of earlier
            // matches will not change depending on what gets replaced in later
            // matches
            group_keys = keys(pattern['matches']),

            /**
             * callback for processing a sub group
             *
             * @param {number} i
             * @param {Array} group_keys
             * @param {Function} callback
             */
            processGroup = function(i, group_keys, callback) {
                if (i >= group_keys.length) {
                    return callback(replacement);
                }

                var processNextGroup = function() {
                        processGroup(++i, group_keys, callback);
                    },
                    block = match[group_keys[i]];

                // if there is no match here then move on
                if (!block) {
                    return processNextGroup();
                }

                var group = pattern['matches'][group_keys[i]],
                    language = group['language'],

                    /**
                     * process group is what group we should use to actually process
                     * this match group
                     *
                     * for example if the subgroup pattern looks like this
                     * 2: {
                     *     'name': 'keyword',
                     *     'pattern': /true/g
                     * }
                     *
                     * then we use that as is, but if it looks like this
                     *
                     * 2: {
                     *     'name': 'keyword',
                     *     'matches': {
                     *          'name': 'special',
                     *          'pattern': /whatever/g
                     *      }
                     * }
                     *
                     * we treat the 'matches' part as the pattern and keep
                     * the name around to wrap it with later
                     */
                    process_group = group['name'] && group['matches'] ? group['matches'] : group,

                    /**
                     * takes the code block matched at this group, replaces it
                     * with the highlighted block, and optionally wraps it with
                     * a span with a name
                     *
                     * @param {string} block
                     * @param {string} replace_block
                     * @param {string|null} match_name
                     */
                    _replaceAndContinue = function(block, replace_block, match_name) {
                        replacement = _replaceAtPosition(_indexOfGroup(match, group_keys[i]), block, match_name ? _wrapCodeInSpan(match_name, replace_block) : replace_block, replacement);
                        processNextGroup();
                    };

                // if this is a sublanguage go and process the block using that language
                if (language) {
                    return _highlightBlockForLanguage(block, language, function(code) {
                        _replaceAndContinue(block, code);
                    });
                }

                // if this is a string then this match is directly mapped to selector
                // so all we have to do is wrap it in a span and continue
                if (typeof group === 'string') {
                    return _replaceAndContinue(block, block, group);
                }

                // the process group can be a single pattern or an array of patterns
                // _processCodeWithPatterns always expects an array so we convert it here
                _processCodeWithPatterns(block, process_group.length ? process_group : [process_group], function(code) {
                    _replaceAndContinue(block, code, group['matches'] ? group['name'] : 0);
                });
            };

        processGroup(0, group_keys, onMatchSuccess);
    }

    /**
     * should a language bypass the default patterns?
     *
     * if you call Rainbow.extend() and pass true as the third argument
     * it will bypass the defaults
     */
    function _bypassDefaultPatterns(language)
    {
        return bypass_defaults[language];
    }

    /**
     * returns a list of regex patterns for this language
     *
     * @param {string} language
     * @returns {Array}
     */
    function _getPatternsForLanguage(language) {
        var patterns = language_patterns[language] || [],
            default_patterns = language_patterns[DEFAULT_LANGUAGE] || [];

        return _bypassDefaultPatterns(language) ? patterns : patterns.concat(default_patterns);
    }

    /**
     * substring replace call to replace part of a string at a certain position
     *
     * @param {number} position         the position where the replacement should happen
     * @param {string} replace          the text we want to replace
     * @param {string} replace_with     the text we want to replace it with
     * @param {string} code             the code we are doing the replacing in
     * @returns {string}
     */
    function _replaceAtPosition(position, replace, replace_with, code) {
        var sub_string = code.substr(position);
        return code.substr(0, position) + sub_string.replace(replace, replace_with);
    }

   /**
     * sorts an object by index descending
     *
     * @param {Object} object
     * @return {Array}
     */
    function keys(object) {
        var locations = [],
            replacement,
            pos;

        for(var location in object) {
            if (object.hasOwnProperty(location)) {
                locations.push(location);
            }
        }

        // numeric descending
        return locations.sort(function(a, b) {
            return b - a;
        });
    }

    /**
     * processes a block of code using specified patterns
     *
     * @param {string} code
     * @param {Array} patterns
     * @returns void
     */
    function _processCodeWithPatterns(code, patterns, callback)
    {
        // we have to increase the level here so that the
        // replacements will not conflict with each other when
        // processing sub blocks of code
        ++CURRENT_LEVEL;

        // patterns are processed one at a time through this function
        function _workOnPatterns(patterns, i)
        {
            // still have patterns to process, keep going
            if (i < patterns.length) {
                return _processPattern(patterns[i]['pattern'], patterns[i], code, function() {
                    _workOnPatterns(patterns, ++i);
                });
            }

            // we are done processing the patterns
            // process the replacements and update the DOM
            _processReplacements(code, function(code) {

                // when we are done processing replacements
                // we are done at this level so we can go back down
                delete replacements[CURRENT_LEVEL];
                delete replacement_positions[CURRENT_LEVEL];
                --CURRENT_LEVEL;
                callback(code);
            });
        }

        _workOnPatterns(patterns, 0);
    }

    /**
     * process replacements in the string of code to actually update the markup
     *
     * @param {string} code         the code to process replacements in
     * @param {Function} onComplete   what to do when we are done processing
     * @returns void
     */
    function _processReplacements(code, onComplete) {

        /**
         * processes a single replacement
         *
         * @param {string} code
         * @param {Array} positions
         * @param {number} i
         * @param {Function} onComplete
         * @returns void
         */
        function _processReplacement(code, positions, i, onComplete) {
            if (i < positions.length) {
                ++replacement_counter;
                var pos = positions[i],
                    replacement = replacements[CURRENT_LEVEL][pos];
                code = _replaceAtPosition(pos, replacement['replace'], replacement['with'], code);

                // process next function
                var next = function() {
                    _processReplacement(code, positions, ++i, onComplete);
                };

                // use a timeout every 250 to not freeze up the UI
                return replacement_counter % 250 > 0 ? next() : setTimeout(next, 0);
            }

            onComplete(code);
        }

        var string_positions = keys(replacements[CURRENT_LEVEL]);
        _processReplacement(code, string_positions, 0, onComplete);
    }

    /**
     * takes a string of code and highlights it according to the language specified
     *
     * @param {string} code
     * @param {string} language
     * @param {Function} onComplete
     * @returns void
     */
    function _highlightBlockForLanguage(code, language, onComplete) {
        var patterns = _getPatternsForLanguage(language);
        _processCodeWithPatterns(_htmlEntities(code), patterns, onComplete);
    }

    /**
     * highlight an individual code block
     *
     * @param {Array} code_blocks
     * @param {number} i
     * @returns void
     */
    function _highlightCodeBlock(code_blocks, i, onComplete) {
        if (i < code_blocks.length) {
            var block = code_blocks[i],
                language = _getLanguageForBlock(block);

            if (!_hasClass(block, 'rainbow') && language) {
                language = language.toLowerCase();

                _addClass(block, 'rainbow');

                return _highlightBlockForLanguage(block.innerHTML, language, function(code) {
                    block.innerHTML = code;

                    // reset the replacement arrays
                    replacements = {};
                    replacement_positions = {};

                    // if you have a listener attached tell it that this block is now highlighted
                    if (onHighlight) {
                        onHighlight(block, language);
                    }

                    // process the next block
                    setTimeout(function() {
                        _highlightCodeBlock(code_blocks, ++i, onComplete);
                    }, 0);
                });
            }
            return _highlightCodeBlock(code_blocks, ++i, onComplete);
        }

        if (onComplete) {
            onComplete();
        }
    }

    /**
     * start highlighting all the code blocks
     *
     * @returns void
     */
    function _highlight(node, onComplete) {

        // the first argument can be an Event or a DOM Element
        // I was originally checking instanceof Event but that makes it break
        // when using mootools
        //
        // @see https://github.com/ccampbell/rainbow/issues/32
        //
        node = node && typeof node.getElementsByTagName == 'function' ? node : document;

        var pre_blocks = node.getElementsByTagName('pre'),
            code_blocks = node.getElementsByTagName('code'),
            i,
            final_blocks = [];

        // @see http://stackoverflow.com/questions/2735067/how-to-convert-a-dom-node-list-to-an-array-in-javascript
        // we are going to process all  blocks
        for (i = 0; i < code_blocks.length; ++i) {
            final_blocks.push(code_blocks[i]);
        }

        // loop through the pre blocks to see which ones we should add
        for (i = 0; i < pre_blocks.length; ++i) {

            // if the pre block has no code blocks then process it directly
            if (!pre_blocks[i].getElementsByTagName('code').length) {
                final_blocks.push(pre_blocks[i]);
            }
        }

        _highlightCodeBlock(final_blocks, 0, onComplete);
    }

    /**
     * public methods
     */
    return {

        /**
         * extends the language pattern matches
         *
         * @param {*} language     name of language
         * @param {*} patterns      array of patterns to add on
         * @param {boolean|null} bypass      if true this will bypass the default language patterns
         */
        extend: function(language, patterns, bypass) {

            // if there is only one argument then we assume that we want to
            // extend the default language rules
            if (arguments.length == 1) {
                patterns = language;
                language = DEFAULT_LANGUAGE;
            }

            bypass_defaults[language] = bypass;
            language_patterns[language] = patterns.concat(language_patterns[language] || []);
        },

        /**
         * call back to let you do stuff in your app after a piece of code has been highlighted
         *
         * @param {Function} callback
         */
        onHighlight: function(callback) {
            onHighlight = callback;
        },

        /**
         * method to set a global class that will be applied to all spans
         *
         * @param {string} class_name
         */
        addClass: function(class_name) {
            global_class = class_name;
        },

        /**
         * starts the magic rainbow
         *
         * @returns void
         */
        color: function() {

            // if you want to straight up highlight a string you can pass the string of code,
            // the language, and a callback function
            if (typeof arguments[0] == 'string') {
                return _highlightBlockForLanguage(arguments[0], arguments[1], arguments[2]);
            }

            // if you pass a callback function then we rerun the color function
            // on all the code and call the callback function on complete
            if (typeof arguments[0] == 'function') {
                return _highlight(0, arguments[0]);
            }

            // otherwise we use whatever node you passed in with an optional
            // callback function as the second parameter
            _highlight(arguments[0], arguments[1]);
        }
    };
}) ();

/**
 * adds event listener to start highlighting
 */
(function() {
    if (window.addEventListener) {
        return window.addEventListener('load', Rainbow.color, false);
    }
    window.attachEvent('onload', Rainbow.color);
}) ();

Rainbow["onHighlight"] = Rainbow.onHighlight;
Rainbow["addClass"] = Rainbow.addClass;
ccampbell-rainbow-9570daa/js/rainbow.min.js000066400000000000000000000060711173647220700207210ustar00rootroot00000000000000/* Rainbow v1.1.8 rainbowco.de */
window.Rainbow=function(){function q(a){var b,c=a.getAttribute&&a.getAttribute("data-language")||0;if(!c){a=a.attributes;for(b=0;b=e[d][c])delete e[d][c],delete j[d][c];if(a>=c&&ac&&b'+b+""}function s(a,b,c,h){var f=a.exec(c);if(f){++t;!b.name&&"string"==typeof b.matches[0]&&(b.name=b.matches[0],delete b.matches[0]);var k=f[0],i=f.index,u=f[0].length+i,g=function(){function f(){s(a,b,c,h)}t%100>0?f():setTimeout(f,0)};if(C(i,u))g();else{var m=v(b.matches),l=function(a,c,h){if(a>=c.length)h(k);else{var d=f[c[a]];if(d){var e=b.matches[c[a]],i=e.language,g=e.name&&e.matches?
e.matches:e,j=function(b,d,e){var i;i=0;var g;for(g=1;g/g,">").replace(/&(?![\w\#]+;)/g,
"&"),b,c)}function o(a,b,c){if(b

Syntax Highlighting


    

API Test Page

code on page to begin with

var foo = false;
ccampbell-rainbow-9570daa/tests/index.html000066400000000000000000000024001173647220700206530ustar00rootroot00000000000000 Rainbow tests

Rainbow Tests

Select Language(s)
expand all
ccampbell-rainbow-9570daa/tests/language/000077500000000000000000000000001173647220700204455ustar00rootroot00000000000000ccampbell-rainbow-9570daa/tests/language/css-test.js000066400000000000000000000126541173647220700225600ustar00rootroot00000000000000/** * css tests * * @author Craig Campbell */ RainbowTester.startTest('css'); RainbowTester.run( 'comment', '/* comment */', '/* comment */' ); RainbowTester.run( 'multi-line comment', '/**\n' + ' * comment\n' + ' */', '/**\n' + ' * comment\n' + ' */' ); RainbowTester.run( 'pixels', 'margin:10px 20px 5px 30px;', 'margin:10px 20px 5px 30px;' ); RainbowTester.run( 'cm', 'margin: 1cm 2cm 1.3cm 4cm;', 'margin: 1cm 2cm 1.3cm 4cm;' ); RainbowTester.run( 'percentage', 'width: 100%\n' + 'height: 100%', 'width: 100%\n' + 'height: 100%' ); RainbowTester.run( 'string single quote', '\'test string\'', '\'test string\'' ); RainbowTester.run( 'string double quote', '"test string"', '"test string"' ); RainbowTester.run( 'transition - vendor prefix', 'code span {\n' + ' -moz-transition: color .8s ease-in;\n' + ' -o-transition: color .8s ease-in;\n' + ' -webkit-transition: color .8s ease-in;\n' + ' transition: color .8s ease-in;\n' + '}', 'code span {\n' + ' -moz-transition: color .8s ease-in;\n' + ' -o-transition: color .8s ease-in;\n' + ' -webkit-transition: color .8s ease-in;\n' + ' transition: color .8s ease-in;\n' + '}' ); RainbowTester.run( 'tag', 'p {', 'p {' ); RainbowTester.run( 'class', 'p.intro {', 'p.intro {' ); RainbowTester.run( 'id', 'p#intro {', 'p#intro {' ); RainbowTester.run( 'direct descendant', 'p > span {', 'p > span {' ); RainbowTester.run( 'scss', 'article {\n' + ' &.cool {\n' + ' p {\n' + ' margin-top: 20px;\n' + ' }\n' + ' }\n' + '}', 'article {\n' + ' &.cool {\n' + ' p {\n' + ' margin-top: 20px;\n' + ' }\n' + ' }\n' + '}' ); RainbowTester.run( 'style tag', '', '<style></style>' ); RainbowTester.run( 'style tag with type', '', '<style type="text/css"></style>' ); RainbowTester.run( 'one line', 'p { color: #fff; margin-top: 10px; }', 'p { color: #fff; margin-top: 10px; }' ); RainbowTester.endTest('css'); ccampbell-rainbow-9570daa/tests/language/generic-test.js000066400000000000000000000204031173647220700233730ustar00rootroot00000000000000RainbowTester.startTest('generic'); RainbowTester.run( 'string alone', 'foo = "this is a string"', 'foo = "this is a string"' ); RainbowTester.run( 'string after equal sign', 'foo=\'this is a string\'', 'foo=\'this is a string\'' ); RainbowTester.run( 'string in brackets', 'foo = ["one", "two", "three"];', 'foo = ["one", "two", "three"];' ); RainbowTester.run( 'string in function call', "someFunction('some string', true);", 'someFunction(\'some string\', true);' ); RainbowTester.run( 'concatenated string', "foo = 'string1' + 'string2';", 'foo = \'string1\' + \'string2\';' ); RainbowTester.run( 'quoted comment with string', '# someone\'s comment\n' + 'doSomething(\'js\')\n' + 'doSomethingElse()\n' + 'test = \'other string\'', '# someone\'s comment\n' + 'doSomething(\'js\')\n' + 'doSomethingElse()\n' + 'test = \'other string\'' ); RainbowTester.run( 'quoted comment with multi-line string', '/* someone\'s comment */\n' + 'doSomething(\'js\')\n' + 'doSomethingElse()\n' + 'test = \'other string\n' + 'string is still going\'', '/* someone\'s comment */\n' + 'doSomething(\'js\')\n' + 'doSomethingElse()\n' + 'test = \'other string\n' + 'string is still going\'' ); RainbowTester.run( 'quoted comment with multi-line directly after', '// someone\'s comment\n' + 'test = \'blah blah\n' + 'blah blah blah\'', '// someone\'s comment\n' + 'test = \'blah blah\n' + 'blah blah blah\'' ); RainbowTester.run( 'comment inline 1', '// this is a comment', '// this is a comment' ); RainbowTester.run( 'comment inline 2', '// this is a comment\n' + '//\n' + '// other comment', '// this is a comment\n' + '//\n' + '// other comment' ); RainbowTester.run( 'comment inline 3', '# this is a comment', '# this is a comment' ); RainbowTester.run( 'comment inline 4', '/* this is a comment */', '/* this is a comment */' ); RainbowTester.run( 'comment block', '/**\n' + ' * test comment\n' + ' */', '/**\n' + ' * test comment\n' + ' */' ); RainbowTester.run( 'integer', '23', '23' ); RainbowTester.run( 'decimal', '3.21', '3.21' ); RainbowTester.run( 'float', '23.5f', '23.5f' ); RainbowTester.run( 'exponential', '121.22e-10', '121.22e-10' ); RainbowTester.run( 'hex', '0x0A', '0x0A' ); RainbowTester.run( 'constant', 'TEST_CONSTANT', 'TEST_CONSTANT' ); RainbowTester.run( 'constant 2', '(TEST_CONSTANT_2)', '(TEST_CONSTANT_2)' ); RainbowTester.run( 'language constants', 'if (thing == true) {\n' + ' thing = false;\n' + '}\n' + 'other_thing = null;' , 'if (thing == true) {\n' + ' thing = false;\n' + '}\n' + 'other_thing = null;' ); RainbowTester.run( 'comment after string', 'var test = "some string" // comment after string', 'var test = "some string" // comment after string' ); RainbowTester.run( 'operator math', 'value = (25 * 2) + (14 / 2) - 10', 'value = (25 * 2) + (14 / 2) - 10' ); RainbowTester.run( 'operator comparison not escaped', 'if ((test > 0 && test < 25) || test == 50) {\n' + ' print "nice";\n' + '}', 'if ((test > 0 && test < 25) || test == 50) {\n' + ' print "nice";\n' + '}' ); RainbowTester.run( 'operator comparison escaped', 'if ((test > 0 && test < 25) || test == 50) {\n' + ' print "nice";\n' + '}', 'if ((test > 0 && test < 25) || test == 50) {\n' + ' print "nice";\n' + '}' ); RainbowTester.run( 'function call', 'someFunction(arg);', 'someFunction(arg);' ); RainbowTester.run( 'function definition', 'function someFunction(arg) {\n' + ' return strtolower(arg);\n' + '}', 'function someFunction(arg) {\n' + ' return strtolower(arg);\n' + '}' ); /** * these tests currently fail */ RainbowTester.run( 'comment after website string', 'var test = "http://website.com/index.html"; // sweet website', 'var test = "http://website.com/index.html"; // sweet website' ); RainbowTester.run( 'escaped string single quote', 'var test = \'someone\\\'s string\'', 'var test = \'someone\\\'s string\'' ); RainbowTester.run( 'escaped string double quote', 'var test = \"someone\\\"s string\"', 'var test = "someone\\\"s string"' ); RainbowTester.endTest('generic'); ccampbell-rainbow-9570daa/tests/language/html-test.js000066400000000000000000000255301173647220700227310ustar00rootroot00000000000000/** * html tests * * @author Craig Campbell */ RainbowTester.startTest('html'); RainbowTester.run( 'comment', '', '<!-- this is a comment -->' ); RainbowTester.run( 'multi-line comment', '', '<!-- this is a comment\n' + 'on two lines -->' ); RainbowTester.run( 'paragraph', '

this is a paragraph

', '<p class="test">this is a paragraph</p>' ); RainbowTester.run( 'inline php', '
    \n' + ' \n' + '
  • title; ?>
  • \n' + ' \n' + '
', '<ul class="articles">\n' + ' <?php foreach ($articles as $article): ?>\n' + ' <li><?php echo $article->title; ?></li>\n' + ' <?php endforeach; ?>\n' + '</ul>' ); RainbowTester.run( 'inline css 1', '', '<style type="text/css">\n' + ' body span.blah {\n' + ' background: #000;\n' + ' color: #fff;\n' + ' }\n' + '</style>' ); RainbowTester.run( 'inline css 2', '', '<style>\n' + ' body span.blah {\n' + ' background: #000;\n' + ' color: #fff;\n' + ' }\n' + '</style>' ); RainbowTester.run( 'inline js 1', '', '<script type="text/javascript">\n' + ' function prettyCool() {\n' + ' doSomeJQueryOrWhatever();\n' + ' }\n' + '</script>' ); RainbowTester.run( 'inline js 2', '', '<script>\n' + ' function prettyCool() {\n' + ' doSomeJQueryOrWhatever();\n' + ' }\n' + '</script>' ); RainbowTester.run( 'js include', '', '<script src="http://somewebsite.com/some-script.js" type="text/javascript"></script>' ); RainbowTester.run( 'attribute no quotes', '

test

', '<p class=test>test</p>' ); RainbowTester.run( 'attribute alone', '', '<input type="checkbox" name="whatever" checked>' ); RainbowTester.run( 'attribute middle', '', '<input checked type="checkbox">' ); RainbowTester.run( 'attribute alone self close', '', '<input type="checkbox" name="whatever" checked />' ); RainbowTester.run( 'string inside tags', '
def openFile(path):\n' +
    'file = open(path, "r")\n' +
    'content = file.read()\n' +
    'file.close()\n' +
    'return content
', '<pre><code data-language="python">def openFile(path):\n' + 'file = open(path, "r")\n' + 'content = file.read()\n' + 'file.close()\n' + 'return content</code></pre>' ); RainbowTester.endTest('html'); ccampbell-rainbow-9570daa/tests/language/javascript-test.js000066400000000000000000000070721173647220700241340ustar00rootroot00000000000000/** * javascript tests * * @author Craig Campbell */ RainbowTester.startTest('javascript'); RainbowTester.run( 'selector 1', '$.get()', '$.get()' ); RainbowTester.run( 'selector 2', ' $(\'.some_class\').show()', ' $(\'.some_class\').show()' ); RainbowTester.run( 'window', 'console.log(window.scrollX)', 'console.log(window.scrollX)' ); RainbowTester.run( 'document', 'document.getElementById(\'#some_id\')', 'document.getElementById(\'#some_id\')' ); RainbowTester.run( 'regex', 'var pattern = /\\((.*?)\\)/g', 'var pattern = /\\((.*?)\\)/g' ); RainbowTester.run( 'regex 2', 'var pattern = /true/', 'var pattern = /true/' ); RainbowTester.run( 'string no regex', 'var test = "http://website.com/could/match/regex/i";', 'var test = "http://website.com/could/match/regex/i";' ); RainbowTester.run( 'single line comment vs. regex', 'var Animal = function() { /* some comment */ };', 'var Animal = function() { /* some comment */ };' ); RainbowTester.run( 'inline function', 'var foo = true,\n' + ' something = function() {\n' + ' // do something\n' + ' };', 'var foo = true,\n' + ' something = function() {\n' + ' // do something\n' + ' };' ); RainbowTester.run( 'inline function beginning of line', 'something = function() {\n' + ' // do something\n' + '};', 'something = function() {\n' + ' // do something\n' + '};' ); RainbowTester.run( 'functions in object', 'window.Rainbow = {\n' + ' color: function() {\n' + ' // do something\n' + ' },\n' + '\n' + ' other: function() {}\n' + '};', 'window.Rainbow = {\n' + ' color: function() {\n' + ' // do something\n' + ' },\n' + '\n' + ' other: function() {}\n' + '};' ); RainbowTester.endTest('javascript'); ccampbell-rainbow-9570daa/tests/language/php-test.js000066400000000000000000000235051173647220700225540ustar00rootroot00000000000000/** * php tests * * @author Craig Campbell */ RainbowTester.startTest('php'); RainbowTester.run( 'echo', 'echo \'hello world\';', 'echo \'hello world\';' ); RainbowTester.run( 'variable', '$foo = true;', '$foo = true;' ); RainbowTester.run( 'string concatenation', "$foo = 'test' . 'string' . 'concatenation';", '$foo = \'test\' . \'string\' . \'concatenation\';' ); RainbowTester.run( 'include 1', "include 'App.php';", 'include \'App.php\';' ); RainbowTester.run( 'include 2', "include_once('App.php');", 'include_once(\'App.php\');' ); RainbowTester.run( 'instanceof', "$is_array_object = $collection instanceof ArrayObject;", '$is_array_object = $collection instanceof ArrayObject;' ); RainbowTester.run( 'instanceof namespace class', "$is_user = $object instanceof App\\User;", '$is_user = $object instanceof App\\User;' ); RainbowTester.run( 'array stuff', '$turtles = array(\n' + ' \'leonardo\',\n' + ' \'michaelangelo\',\n' + ' \'donatello\',\n' + ' \'raphael\'\n' + ');\n' + '\n' + '$exists = array_key_exists(0, $turtles);', '$turtles = array(\n' + ' \'leonardo\',\n' + ' \'michaelangelo\',\n' + ' \'donatello\',\n' + ' \'raphael\'\n' + ');\n' + '\n' + '$exists = array_key_exists(0, $turtles);' ); RainbowTester.run( 'php tag', '<?php echo $foo; ?>', '<?php echo $foo; ?>' ); RainbowTester.run( 'php short tag', '<?= $foo; ?>', '<?= $foo; ?>' ); RainbowTester.run( 'namespace declaration', 'namespace Sonic\\Database;', 'namespace Sonic\\Database;' ); RainbowTester.run( 'class declaration', 'class MyClass {}', 'class MyClass {}' ); RainbowTester.run( 'abstract class declaration', 'abstract class MyClass {}', 'abstract class MyClass {}' ); RainbowTester.run( 'final class declaration', 'final class TestClass\n' + '{\n' + '}', 'final class TestClass\n' + '{\n' + '}' ); RainbowTester.run( 'child class declaration', 'class Collection extends ArrayObject {}', 'class Collection extends ArrayObject {}' ); RainbowTester.run( 'final child class declaration', 'final class TestClass extends \\Some\\Other\\Class {}', 'final class TestClass extends \\Some\\Other\\Class {}' ); RainbowTester.run( 'test static', 'self::_doSomething();\n' + 'static::_doSomethingElse();', 'self::_doSomething();\n' + 'static::_doSomethingElse();' ); RainbowTester.run( 'test magic function', 'function __autoload($class)\n' + '{\n' + ' // do whatever\n' + '}', 'function __autoload($class)\n' + '{\n' + ' // do whatever\n' + '}' ); RainbowTester.run( 'test magic method', 'class SomeThing\n' + '{\n' + ' protected $_foo;\n' + '\n' + ' public function __construct($foo)\n' + ' {\n' + ' $this->_foo = $foo;\n' + ' }\n' + '}', 'class SomeThing\n' + '{\n' + ' protected $_foo;\n' + '\n' + ' public function __construct($foo)\n' + ' {\n' + ' $this->_foo = $foo;\n' + ' }\n' + '}' ); RainbowTester.run( 'test new class', 'new SomeClass();', 'new SomeClass();' ); RainbowTester.run( 'test new namespace class', 'new Sonic\\Database\\Query();', 'new Sonic\\Database\\Query();' ); RainbowTester.run( 'test new class without parenthesis', 'new Sonic\\Controller;', 'new Sonic\\Controller;' ); RainbowTester.run( 'test static class call', '$path = Sonic\\App::getInstance()->getPath();', '$path = Sonic\\App::getInstance()->getPath();' ); RainbowTester.run( 'class constant', '$version = Sonic\\App::VERSION', '$version = Sonic\\App::VERSION' ); RainbowTester.run( 'static variable access', '$foo = Sonic\\App::$static_property;', '$foo = Sonic\\App::$static_property;' ); RainbowTester.run( 'type hint', 'public static function getForUser(User $user, Sort $sort) {}', 'public static function getForUser(User $user, Sort $sort) {}' ); RainbowTester.run( 'type hint with namespace', 'public static function getForUser(\\SomeApp\\User $user) {}', 'public static function getForUser(\\SomeApp\\User $user) {}' ); RainbowTester.endTest('php'); ccampbell-rainbow-9570daa/tests/language/python-test.js000066400000000000000000000103421173647220700233010ustar00rootroot00000000000000/** * Python tests * * @author Craig Campbell */ RainbowTester.startTest('python'); RainbowTester.run( 'no constant', 'TEST_CONSTANT', 'TEST_CONSTANT' ); RainbowTester.run( 'no self', 'print self.something', 'print self.something' ); RainbowTester.run( 'comment', '# this is a comment', '# this is a comment' ); RainbowTester.run( 'language constants', 'var1 = None\n' + 'var2 = True\n' + 'someFunction(var3=False)', 'var1 = None\n' + 'var2 = True\n' + 'someFunction(var3=False)' ); RainbowTester.run( 'object', 'object', 'object' ); RainbowTester.run( 'import', 'from SomePackage import SomeThing', 'from SomePackage import SomeThing' ); RainbowTester.run( 'class', 'class Something(object):\n' + ' pass', 'class Something(object):\n' + ' pass' ); RainbowTester.run( 'special method', 'def __init__(self, some_var):\n' + ' pass', 'def __init__(self, some_var):\n' + ' pass' ); RainbowTester.run( 'function', 'def openFile(path):\n' + ' file = open(path, "r")\n' + ' content = file.read()\n' + ' file.close()\n' + ' return content', 'def openFile(path):\n' + ' file = open(path, "r")\n' + ' content = file.read()\n' + ' file.close()\n' + ' return content' ); RainbowTester.run( 'decorator', '@makebold\n' + '@makeitalic\n' + 'def hello():\n' + ' return "hello world"', '@makebold\n' + '@makeitalic\n' + 'def hello():\n' + ' return "hello world"' ); RainbowTester.run( '__main__', 'if __name__ == \'__main__\':\n' + ' pass', 'if __name__ == \'__main__\':\n' + ' pass' ); RainbowTester.run( 'try catch', 'try:\n' + ' import cPickle as pickle\n' + 'except ImportError:\n' + ' import pickle', 'try:\n' + ' import cPickle as pickle\n' + 'except ImportError:\n' + ' import pickle' ); RainbowTester.run( 'docstring single line double quotes', '"""docstring test"""', '"""docstring test"""' ); RainbowTester.run( 'docstring single line single quotes', "'''docstring test'''", '\'\'\'docstring test\'\'\'' ); RainbowTester.run( 'docstring multiline', '"""test\n' + 'multiline\n' + 'yes"""', '"""test\n' + 'multiline\n' + 'yes"""' ); RainbowTester.endTest('python'); ccampbell-rainbow-9570daa/tests/tests.css000066400000000000000000000025451173647220700205440ustar00rootroot00000000000000ul, li, h1, h2, h3, h4, h5, h6 { margin: 0px; padding: 0px; } h1 { margin-bottom: 15px; } body { font-family: helvetica; } a { text-decoration: none; color: #666; } select { width: 200px; height: 200px; font-size: 14px; } form label { display: block; margin-top: 10px; } form input { margin-top: 10px; } ul { padding-left: 20px; margin-left: 20px; } .global_toggle { position: relative; float: right; top: 15px; display: none; } h3 { margin-top: 30px; margin-bottom: 10px; } li { font-size: 30px; } .success a:hover, .failure a:hover, a:hover { color: #000; } a:active { color: #ff8009 !important; } pre { margin-bottom: 10px; } li h5 { font-size: 16px; color: #000; } .success, .success a { color: green; } .success .code, .failure .code { display: none; } .failure, .failure a { color: red; } .failure .code { margin-top: 5px; } h6 { font-size: 14px; color: #666; } table { margin-top: 25px; margin-bottom: 25px; /*border: 2px solid #000;*/ border-collapse: collapse; } table th { text-align: left; padding: 5px 20px 5px 5px; } table td { border: 1px solid #999; padding: 4px; } table tr td:first-child { /*border: 0px;*/ } table tr:last-child td:first-child { /*border-bottom: 0px;*/ } ccampbell-rainbow-9570daa/tests/tests.js000066400000000000000000000140561173647220700203700ustar00rootroot00000000000000window.RainbowTester = (function() { var _language, queue = [], results = {}; function _addScript(url, language) { var script = document.createElement('script'); script.src = url + '?' + new Date().getTime(); document.getElementsByTagName('body')[0].appendChild(script); } function _runTests(e) { var languages = $("select[name=languages]").val() || [], min = $("input[name=min]").attr("checked"), i; if (window.localStorage) { window.localStorage.setItem('languages', languages); } results = {}; $('.global_toggle').show(); $('#results').html(''); // add rainbow _addScript(RAINBOW_PATH + '/rainbow.' + (min ? 'min.' : '') + 'js'); // add all the languages $("select[name=languages] option").each(function() { _addScript(RAINBOW_PATH + '/language/' + this.value + '.js'); }); for (i = 0; i < languages.length; ++i) { _addScript('language/' + languages[i] + '-test.js', languages[i]); } setTimeout(_processQueue, 50); } function _toggleCode(e) { e.preventDefault(); $(this).parents('li').find('.code').toggle(); } function _globalToggleCode(e) { e.preventDefault(); if ($(this).text() == 'expand all') { $(".code").show(); return $(this).text('collapse all'); } $(".code").hide(); $(this).text('expand all'); } function _initResults(language) { if (!results[language]) { results[language] = {}; } } function _getTableRow(language, fail, pass) { return '' + language + '' + fail + '' + pass + ''; } function _showResults() { if (queue.length) { return _processQueue(); } var table = '', total_pass = 0, total_fail = 0; for (var lang in results) { var pass = 0, fail = 0; for (var key in results[lang]) { if (results[lang][key]['success']) { ++pass; continue; } ++fail; } total_pass += pass; total_fail += fail; table += _getTableRow(lang, fail, pass); } table += _getTableRow('total', total_fail, total_pass); table += '
LanguageFailedPassed
'; $("#results").append(table); _scroll(); } function _scroll() { $(window).scrollTop($(document).height()); } function _processQueue() { if (queue.length === 0) { return _showResults(); } _scroll(); var test = queue.shift(); Rainbow.color(test['code'], test['language'], function(actual) { if (test['expected'] == actual) { _pass(test['language'], test['name'], actual); return _processQueue(); } _fail(test['language'], test['name'], test['expected'], actual); _processQueue(); }); } function _pass(language, test_name, actual) { _initResults(language); results[language][test_name] = { success: true, actual: actual }; $('#' + language).append( '
  • ' + '
    ' + test_name + '
    ' + '
    ' + '
    ' + actual + '
    ' + '
    ' + '
  • ' ); } function _fail(language, test_name, expected, actual) { _initResults(language); results[language][test_name] = { success: false, expected: expected, actual: actual }; $('#' + language).append( '
  • ' + '
    ' + test_name + '
    ' + '
    ' + '
    Expected:
    ' + '
    ' + expected + '
    ' + '
    Actual:
    ' + '
    ' + actual + '
    ' + '
    ' + '
  • ' ); actual = actual.replace(/\n/g, '\\n\' + \n' + '\''); console.log('\'' + actual + '\''); } function _restoreLanguagesFromLastRun() { if (!window.localStorage) { return; } var languages = window.localStorage.getItem('languages').split(','); $("select[name=languages] option").each(function() { if ($.inArray(this.value, $(languages)) === -1) { $(this).attr("selected", false); } }); } return { init: function() { $("#run_tests").click(_runTests); $("#results").on('click', '.toggle', _toggleCode); $("body").on('click', '.global_toggle', _globalToggleCode); $(document).keyup(function(e) { if (e.keyCode == 79) { $(".global_toggle").click(); } if (e.keyCode == 82) { $("#run_tests").click(); } }); _restoreLanguagesFromLastRun(); }, startTest: function(name) { _language = name; $("#results").append('

    ' + _language + '

      '); }, endTest: function(name) { _language = null; }, run: function(test_name, code, expected) { var language = _language; queue.push({ 'language': _language, 'name': test_name, 'code': code, 'expected': expected }); } }; }) (); $(document).ready(RainbowTester.init); ccampbell-rainbow-9570daa/themes/000077500000000000000000000000001173647220700170055ustar00rootroot00000000000000ccampbell-rainbow-9570daa/themes/all-hallows-eve.css000066400000000000000000000012551173647220700225160ustar00rootroot00000000000000/** * All Hallows Eve theme * * @author Flinn Mueller * @version 1.0.1 * @attribution Adapted from Ultraviolet RubyGem */ pre { background: #000; word-wrap: break-word; margin: 0px; padding: 0px; padding: 10px; color: #fff; font-size: 14px; margin-bottom: 20px; } pre, code { font-family: 'Monaco', courier, monospace; } pre .comment { color: #9933CC; } pre .constant { color: #3387CC; } pre .storage { color: #CC7833; } pre .string { color: #66CC33; } pre .keyword, pre .selector { color: #CC7833; } pre .inherited-class { font-style: italic; } pre .entity, pre .meta { } pre .support { color: #C83730; } ccampbell-rainbow-9570daa/themes/blackboard.css000066400000000000000000000017011173647220700216020ustar00rootroot00000000000000/** * Blackboard theme * * @author Domenico Carbotta * @author Craig Campbell * @version 1.0.2 * * Adapated from Domenico Carbotta's TextMate theme of the same name */ pre { background: #0B1022; word-wrap: break-word; margin: 0px; padding: 0px; padding: 10px; color: #fff; font-size: 14px; margin-bottom: 20px; } pre, code { font-family: 'Monaco', courier, monospace; } pre .comment { color: #727272; } pre .constant { color: #D8FA3C; } pre .storage { color: #FBDE2D; } pre .string, pre .comment.docstring { color: #61CE3C; } pre .string.regexp, pre .support.tag.script, pre .support.tag.style { color: #fff; } pre .keyword, pre .selector { color: #FBDE2D; } pre .inherited-class { font-style: italic; } pre .entity, pre .meta { color: #FF6400; } pre .support { color: #8DA6CE; } pre .variable.global, pre .variable.class, pre .variable.instance { color: #FF6400; } ccampbell-rainbow-9570daa/themes/github.css000066400000000000000000000027001173647220700210000ustar00rootroot00000000000000/** * GitHub theme * * @author Craig Campbell * @version 1.0.2 */ pre { border: 1px solid #ccc; word-wrap: break-word; padding: 6px 10px; line-height: 19px; margin-bottom: 20px; } code { border: 1px solid #eaeaea; margin: 0px 2px; padding: 0px 5px; font-size: 12px; } pre code { border: 0px; padding: 0px; margin: 0px; -moz-border-radius: 0px; -webkit-border-radius: 0px; border-radius: 0px; } pre, code { font-family: 'Bitstream Vera Sans Mono', Courier, monospace; color: #333; background: #f8f8f8; -moz-border-radius: 3px; -webkit-border-radius: 3px; border-radius: 3px; } pre, pre code { font-size: 13px; } pre .comment { color: #998; } pre .support { color: #0086B3; } pre .tag, pre .tag-name { color: navy; } pre .keyword, pre .css-property, pre .vendor-prefix, pre .sass, pre .class, pre .id, pre .css-value, pre .entity.function, pre .storage.function { font-weight: bold; } pre .css-property, pre .css-value, pre .vendor-prefix, pre .support.namespace { color: #333; } pre .constant.numeric, pre .keyword.unit, pre .hex-color { font-weight: normal; color: #099; } pre .entity.class { color: #458; } pre .entity.id, pre .entity.function { color: #900; } pre .attribute, pre .variable { color: teal; } pre .string, pre .support.value { font-weight: normal; color: #d14; } pre .regexp { color: #009926; } ccampbell-rainbow-9570daa/themes/tricolore.css000066400000000000000000000014701173647220700215230ustar00rootroot00000000000000/** * Tricolore theme * * @author Jean Nicolas * @version 1.0.1 */ pre { background: #FFF; word-wrap: break-word; margin: 0px; padding: 0px; padding: 10px; color: #000; font-size: 12px; margin-bottom: 20px; line-height: 16px; } pre, code { font-family: 'Monaco', 'Consolas', monospace; } pre .comment { color: #7E7E7E; font-style: italic; } pre .constant { color: #18838A; font-weight: bold; } pre .storage { color: #0000A1; } pre .string { color: #8E0022; } pre .keyword, pre .selector { color: #0000A1; font-weight: bold; } pre .inherited-class { font-style: italic; } pre .entity, pre .meta { color: #3E853F; } pre .support { color: #192140; } pre .variable.global, pre .variable.class, pre .variable.instance { color: #3E853F; } ccampbell-rainbow-9570daa/themes/twilight.css000066400000000000000000000021721173647220700213540ustar00rootroot00000000000000/** * Twilight theme * * @author Michael Sheets * @author Jesse Farmer * @version 1.0.1 * * Adapted from Michael Sheets' TextMate theme of the same name */ pre { background: #141414; word-wrap: break-word; margin: 0px; padding: 0px; padding: 10px; color: #F8F8F8; font-size: 14px; margin-bottom: 20px; } pre, code { font-family: 'Monaco', courier, monospace; } pre .comment { color: #5F5A60; } pre .constant.numeric { color: #D87D50; } pre .constant { color: #889AB4; } pre .constant.symbol, pre .constant.language { color: #D87D50; } pre .storage { color: #F9EE98; } pre .string { color: #8F9D6A; } pre .string.regexp { color: #E9C062; } pre .keyword, pre .selector, pre .storage { color: #CDA869; } pre .inherited-class { color: #9B5C2E; } pre .entity, pre .meta { color: #FF6400; } pre .support { color: #9B859D; } pre .support.magic { color: #DAD69A; } pre .variable { color: #7587A6; } pre .function, pre .entity.class { color: #9B703F; } pre .support.class-name, pre .support.type { color: #AB99AC; } ccampbell-rainbow-9570daa/themes/zenburnesque.css000066400000000000000000000014361173647220700222510ustar00rootroot00000000000000/** * Zenburnesque theme * * @author Flinn Mueller * @version 1.0 * @attribution Adapted from Ultraviolet RubyGem */ pre { background: #404040; word-wrap: break-word; margin: 0px; padding: 0px; padding: 10px; color: #dedede; font-size: 14px; margin-bottom: 20px; } pre, code { font-family: 'Monaco', courier, monospace; } pre .comment { color: #709070; font-style: italic; } pre .integer { color: #22C0FF; } pre .storage { color: #6080FF; } /* This includes regexes */ pre .string { color: #FF2020; } pre .keyword, pre .selector { color: #ffffa0; } pre .inherited-class { font-style: italic; } pre .entity, pre .meta { color: #F09040; } pre .support { color: #C83730; } pre .variable.class { color: #FF8000; } ccampbell-rainbow-9570daa/util/000077500000000000000000000000001173647220700164755ustar00rootroot00000000000000ccampbell-rainbow-9570daa/util/builder.py000066400000000000000000000106601173647220700205000ustar00rootroot00000000000000import os import subprocess import zipfile import hashlib import re import glob from zipfile import ZipFile from StringIO import StringIO class RainbowBuilder(object): def __init__(self, js_path, closure_path, theme_path=None): self.versions = { 'c': '1.0.2', 'css': '1.0.6', 'generic': '1.0.6', 'html': '1.0.4', 'javascript': '1.0.6', 'php': '1.0.3', 'python': '1.0.5', 'ruby': '1.0.5', 'shell': '1.0.3' } self.js_path = js_path self.closure_path = closure_path self.js_files_to_include = [] self.file_name = "" self.theme_path = theme_path def getPathForLanguage(self, language): return os.path.join(self.js_path, 'language/' + language + '.js') def getRainbowPath(self): return os.path.join(self.js_path, 'rainbow.js') def verifyPaths(self): if not os.path.exists(self.js_path): raise Exception('directory does not exist at: %s' % self.js_path) if not os.path.isfile(self.closure_path): raise Exception('closure compiler does not exist at: %s' % self.closure_path) def getZipForLanguages(self, languages, path=None): self.verifyPaths() # strip out any duplicates languages = list(set(languages)) write_to = StringIO() if path is None else path zip_file = ZipFile(write_to, 'w') zip_file.write(self.getRainbowPath(), 'rainbow.js', zipfile.ZIP_DEFLATED) # include minimized version even when downloading the dev version zip_file.write(self.getRainbowPath().replace('.js', '.min.js'), 'rainbow.min.js', zipfile.ZIP_DEFLATED) # include themes as well if self.theme_path: files = glob.glob(self.theme_path + '/*.css') for file_name in files: zip_file.write(file_name, os.path.join('themes', os.path.basename(file_name)), zipfile.ZIP_DEFLATED) for language in languages: zip_file.write(self.getPathForLanguage(language), os.path.join('language', language + '.js'), zipfile.ZIP_DEFLATED) zip_file.close() return write_to def openFile(self, path): file = open(path, "r") content = file.read() file.close() return content def writeFile(self, path, content): file = open(path, "w") file.write(content) file.close() def getVersion(self): contents = self.openFile(self.getRainbowPath()) match = re.search(r'@version\s(.*)\s+?', contents) return match.group(1) def getLanguageVersions(self, languages): groups = [] for language in languages: if language in self.versions: groups.append(language + ' v' + self.versions[language]) return ', '.join(groups) def getFileForLanguages(self, languages, cache=None): self.verifyPaths() # strip out any duplicates languages = list(set(languages)) self.js_files_to_include = [self.getRainbowPath()] for language in languages: path = self.getPathForLanguage(language) if not os.path.exists(path): continue self.js_files_to_include.append(path) self.file_name = 'rainbow' + ('-custom' if len(languages) else '') + '.min.js' if cache is not None: version = self.getVersion() cache_key = 'rainbow_' + hashlib.md5(self.getLanguageVersions(languages)).hexdigest() + '_' + version cached_version = cache.get(cache_key) if cached_version: return cached_version command = ['java', '-jar', self.closure_path, '--compilation_level', 'ADVANCED_OPTIMIZATIONS'] + self.js_files_to_include proc = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) output, err = proc.communicate() lines = output.splitlines() comments = lines[0:4] version = comments[1].replace(' @version ', '') url = comments[2].replace(' @url ', '') new_comment = '/* Rainbow v' + version + ' ' + url if len(languages): new_comment += ' | included languages: ' + ', '.join(languages) new_comment += ' */' output = new_comment + '\n' + '\n'.join(lines[4:]) if cache is not None: cache.set(cache_key, output, 14400) # 4 hours return output ccampbell-rainbow-9570daa/util/compile.py000077500000000000000000000017161173647220700205070ustar00rootroot00000000000000#!/usr/bin/env python import sys import os from builder import RainbowBuilder sys.argv.pop(0) languages = sys.argv languages.sort() no_language_args = ['--alone', '--forever-alone', '--core', '--no-languages', '--without-languages', '--none'] rainbow_only = len(set(no_language_args) - set(sys.argv)) < len(no_language_args) if not rainbow_only: languages.insert(0, 'generic') js_path = os.path.dirname(__file__) + '/../js/' for language in languages[:]: if language.startswith('--'): languages.remove(language) builder = RainbowBuilder(js_path, '/usr/local/compiler-latest/compiler.jar') print 'waiting for closure compiler...' contents = builder.getFileForLanguages(languages) print "\nincluded:" for file in builder.js_files_to_include: print " ", os.path.basename(file) print "" print 'writing to file:', builder.file_name new_file = os.path.join(js_path, builder.file_name) file = open(new_file, "w") file.write(contents) file.close()