Git Product home page Git Product logo

rainbow's Introduction

Rainbow

Rainbow is a code syntax highlighting library written in Javascript.

It was designed to be lightweight (~2.5kb), easy to use, and extendable.

It is completely themable via CSS.

Demo

You can see rainbow in action at http://rainbowco.de.

You can also build/download custom packages from there.

Contents

Quick Start

Browser

  1. Include some markup for code you want to be highlighted:

    <pre><code data-language="python">def openFile(path):
        file = open(path, "r")
        content = file.read()
        file.close()
        return content</code></pre>
  2. Include a CSS theme file in the <head>:

    <link href="/assets/css/theme.css" rel="stylesheet" type="text/css">
  3. Include rainbow.js and whatever languages you want before the closing </body>:

    <script src="/assets/js/rainbow.js"></script>
    <script src="/assets/js/language/generic.js"></script>
    <script src="/assets/js/language/python.js"></script>

By default dist/rainbow.min.js comes with some popular languages bundled together with it.

Node.js

Rainbow 2.0 introduced support for node.js. All of the existing API methods should work, but there is also a new Rainbow.colorSync method for synchronous highlighting.

Install rainbow

npm install --save rainbow-code

Highlight some code

var rainbow = require('rainbow-code');
var highlighted = rainbow.colorSync('// So meta\nrainbow.colorSync(\'var helloWorld = true;\');', 'javascript');
console.log(highlighted);

Supported Browsers

Rainbow 2.0 should work in the following browsers:

Chrome Firefox IE Safari
20+ 13+ 10+ 6+

For older browsers you can download the legacy 1.2.0 release.

Supported Languages

Currently supported languages are:

  • C
  • C#
  • Coffeescript
  • CSS
  • D
  • Go
  • Haskell
  • HTML
  • Java
  • JavaScript
  • JSON
  • Lua
  • PHP
  • Python
  • R
  • Ruby
  • Scheme
  • Shell
  • Smalltalk

Specifying a language

In your markup the data-language attribute is used to specify what language to use for highlighting. For example:

<pre><code data-language="javascript">var testing = true;</code></pre>

Rainbow also supports the HTML5 style for specifying languages:

<pre><code class="language-javascript">var testing = true;</code></pre>

And the Google prettify style:

<pre class="lang-javascript"><code>var testing = true;</code></pre>

Themes

Themes are located in the themes/sass directory. They are written using sass so that common logic can be shared among all themes without having to duplicate it in each theme file. You should not edit the css files directly.

_base.sass includes some default styles shared by almost every theme. _init.sass contains mixins and initialization logic that is shared by every theme.

Rendering code blocks

As of version 2.0 the themes use a clever trick to display the highlighted code. All code blocks default to opacity: 0, but an animation is triggered on page load to happen after a 2 second delay.

This means for users who do not have JavaScript enabled the code will fade in after 2 seconds. If JavaScript is enabled, the animation is stopped on load and the delay is reset to 0s. That ensures that as soon as the code is done being highlighted it will be able to show up instantly. This is used to prevent a flash of unstyled text on page load and ensure that the code blocks only show up after they have been highlighted.

There is also a preload animation that will show up for any code block that takes longer than 300ms to load.

Adding custom rules for specific languages

A SASS mixin was added to simplify defining styles that should only apply for a specific language. Using it looks like this:

@include language("html")
    .support.operator
        color: #fff

@include language(("javascript", "js"))
    .variable.super
        color: #66D9EF

You can pass a single language or a list of languages.

JavaScript API Documentation

Rainbow has four public methods:

Rainbow.color

Rainbow.color is used to highlight blocks of code.

For convenience, this method is called automatically to highlight all code blocks on the page when DOMContentLoaded fires. If you would like to highlight stuff that is not in the DOM you can use it on its own. There are three ways to use it.

  1. The first option is calling the color method on its own:

    Rainbow.color();

    Each time this is called, Rainbow will look for matching pre blocks on the page that have not yet been highlighted and highlight them.

    You can optionally pass a callback function that will fire when all the blocks have been highlighted.

    Rainbow.color(function() {
        console.log('The new blocks are now highlighted!');
    });
  2. The second option is passing a specific element to the color method.

    In this example we are creating a code block, highlighting it, then inserting it into the DOM:

    var div = document.createElement('div');
    div.innerHTML = '<pre><code data-language="javascript">var foo = true;</code></pre>';
    Rainbow.color(div, function() {
        document.getElementById('something-else').appendChild(div;)
    });
  3. The final option is passing in your code as a string to Rainbow.color.

    Rainbow.color('var foo = true;', 'javascript', function(highlightedCode) {
        console.log(highlightedCode);
    });

Preventing automatic highlighting on page load

If you want to prevent code on the page from being highlighted when the page loads you can set the defer property to true.

Rainbow.defer = true;

Note that you have to set this before DOMContentLoaded fires or else it will not do anything.

Extra options for color

As of right now there is one extra option for color.

globalClass

This option allows you to have an extra class added to every span that Rainbow renders. This can be useful if you want to remove the classes in order to trigger a special effect of some sort.

To apply a global class you can add it in your markup:

<pre><code data-language="javascript" data-global-class="animate">var hello = true;</code></pre>

Or you can pass it into a Rainbow.color call like this:

Rainbow.color('var hello = true;', {
    language: 'javascript',
    globalClass: 'animate'
});

Rainbow.extend

Rainbow.extend is used to define language grammars which are used to highlight the code you pass in. It can be used to define new languages or to extend existing languages.

A very simple language grammer looks something like this:

Rainbow.extend('example', [
    {
        name: 'keyword',
        pattern: /function|return|continue|break/g
    }
]);

Any pattern used with extend will take precedence over an existing pattern that matches the same block. It will also take precedence over any pattern that is included as part of the generic patterns.

For example if you were to call

Rainbow.extend('example', [
    {
        name: 'keyword.magic',
        pattern: /function/g
    }
]);

This would mean that function will be highlighted as <span class="keyword magic">function</span>, but return, continue, and break will still be highlighted as just <span class="keyword">return</span>, etc.

Extending existing languages

By default languages are considered to be standalone, but if you specify an optional third parameter you can have your language inherit from another one.

For example the python language grammars inherit from the generic ones:

Rainbow.extend('python', [
    {
        name: 'constant.language',
        pattern: /True|False|None/g
    }
], 'generic');

If you wanted to remove the default boolean values you should be able to do something like this:

Rainbow.extend('python', [
    {
        name: '',
        pattern: /true|false/g
    }
]);

How code is highlighted

The name value determines what classes will be added to a span that matches the pattern you specify. For example, if you name a pattern constant.hex-color the code that matches that pattern will be wrapped in <span class="constant hex-color></span>. This allows you to share common base styles but add more customization in your themes for more specific matches.

How grammars are defined

Match by name

The simplest way to define a grammar is to define a regular expression and a name to go along with that.

Rainbow.extend([
    {
        name: 'constant.boolean',
        pattern: /true|false/g
    }
]);
Match by group

This allows you to take a more complicated regular expression and map certain parts of it to specific scopes.

Rainbow.extend([
    {
        matches: {
            1: 'constant.boolean.true',
            2: 'constant.boolean.false'
        },
        pattern: /(true)|(false)/g
    }
]);
Match by array of sub-patterns

For more complicated matches you may want to process code within another match group.

Rainbow.extend([
    {
        matches: [
            {
                name: 'constant.boolean.true',
                pattern: /true/
            },
            {
                name: 'constant.boolean.false',
                pattern: /false/
            }
        ],
        pattern: /true|false/g
    }
]);
Match using another language

Sometimes a language supports other languages being embedded inside of it such as JavaScript inside HTML. Rainbow supports that out of the box. Here is an example of how you would highlight PHP tags inside of HTML code.

Rainbow.extend('html', [
    {
        name: 'source.php.embedded',
        matches: {
            2: {
                language: 'php'
            }
        },
        pattern: /&lt;\?(php)?([\s\S]*?)(\?&gt;)/gm
    }
]);

You should be able to nest sub-patterns as many levels deep as you would like.

Extending an existing language

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 in your own javascript.

Let's say for example you want to highlight PHP's apc functions. You can include the php language then in the markup on your page add:

<script>
    Rainbow.extend('php', [
        {
            'matches': {
                1: 'support.function'
            },
            'pattern': /\b(apc_(store|fetch|add|inc))(?=\()/g
        }
    ]);
</script>

How Rainbow chooses a match

In general the best practice is to make your patterns as specific as possible (for example targetting specific keywords).

When you create a new language it gets pushed to the front of whatever language it is inheriting from. This means whatever rules are added last will be checked against first.

Rainbow chooses the first match it finds for a block. If another pattern overlaps with a pattern that has already been chosen then it is ignored.

There is one exception to this. If a match that comes later is more specific (the start AND end points stretch beyond another pattern already matched) then the new match will take precedence and the old one will be discarded.

That means if you have a pattern that matches function test() and you add a pattern that matches public function test() the new one will be used instead.

Known limitations

Regular expressions lookbehind assertions

Javascript does not allow positive or negative lookbehind assertions so this means it is possible to have conflicts with the starting and end positions of matches. If you want to match a pattern that ends with a specific character it is recommended that you use a positive lookahead for that character instead of including it in the regex. That allows the same character to be used at the start of another match group without overlapping.

Regular expression subgroup matches

You cannot match part of a subgroup directly to a scope. For example if you have:

{
    matches: {
        1: 'name.attribute',
        2: 'value'
    },
    pattern: /(name=\"(.*?)\")/g
}

This will result in code name="value" being highlighted as:

<span class="name attribute">name="value"</span>

You see the value class never gets applied.

To achieve what you really want you would have to use a subpattern like this:

{
    name: 'name.attribute',
    matches: [{
        matches: {
            1: 'value'
        },
        pattern: /\"(.*?)\"/g
    }],
    pattern: /(name=\"(.*?)\")/g
}

This means the entire block is wrapped with name.attribute scope and then within that any part in double quotes will be wrapped as value.

That means the entire block will behighlighted as

<span class="name attribute">name="<span class="value">value</span>"</span>

In this example you could avoid subpatterns completely by using a regex like this to begin with:

/(name=)\"(.*?)\"/g

Rainbow.addAlias

The addAlias function allows you to map a different name to a language. For example:

Rainbow.addAlias('js', 'javascript');

This allows you to highlight javascript code by using the language js instead of javascript.

Rainbow.onHighlight

This method notifies you as soon as a block of code has been highlighted.

Rainbow.onHighlight(function(block, language) {
    console.log(block, 'for language', language, 'was highlighted');
});

The first parameter returns a reference to that code block in the DOM. The second parameter returns a string of the language being highlighted.

Rainbow.remove

This method allows you to remove syntax rules for a specific language. It is only really useful for development if you want to be able to reload language grammars on the fly without having to refresh the page.

// Remove all the javascript patterns
Rainbow.remove('javascript');

Building

Rainbow is compiled using rollup and buble.

Gulp is used for all build related tasks.

Getting a local environment set up

git clone [email protected]:ccampbell/rainbow.git
cd rainbow
npm install

Build commands

gulp build

The build command is used to build a custom version of rainbow.js. If you run

gulp build

A file will be created at dist/rainbow-custom.min.js containing rainbow.js as well as popular languages. If you want to specify specific languages you can use:

gulp build --languages=html,css,php,javascript

If you want a minimized version of rainbow without any languages you can pass

gulp build --languages=none

If you want a minimized version with all languages you can pass

gulp build --languages=all

gulp lint

The lint command will check all the javascript files for things that do not match the styleguide from the .eslintrc file.

gulp pack

The pack command will run a buble + rollup build and save the resulting file to dist/rainbow.js

gulp sass

The sass command will compile all the rainbow themes

gulp test

The test command will run the unit tests. You can pass the --watch flag to keep the tests running and have them rerun when you make changes. That is a little buggy though which has something to do with karma + rollup.

You can also use the --browsers flag to specify a browser to run the tests in. Currently only PhantomJS and Chrome are supported.

gulp watch

The watch command will look at sass files and src js files and build the css or js (using gulp sass and gulp pack) every time you make a change.

More Info

If you are looking for line number support you can try one of the following:

You can check out demos and build custom packages at rainbowco.de.

rainbow's People

Contributors

actsasflinn avatar asandroq avatar bbqsrc avatar ccampbell avatar chuckharmston avatar colinwren avatar davidlitmark avatar eikimart avatar fasani avatar firien avatar frankshearar avatar fredwu avatar geertdd avatar idleberg avatar javaguirre avatar jfarmer avatar loopj avatar lucaswerkmeister avatar mking avatar okcoker avatar orangeduck avatar rachelbaker avatar sjp avatar workhorsy avatar yonjah avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

rainbow's Issues

The regular expression for Python multi-line strings (in python.js) should not be greedy.

Try highlighting this:

"""
x
"""
2+2
"""
y
"""

The 2+2 will be interpreted as part of the multiline string. This is because the relevant regular expression in python.js is:

{
    'name': 'comment.docstring',
    'pattern': /('{3}|"{3})[\s\S]*\1/gm
}

but it should be

{
    'name': 'comment.docstring',
    'pattern': /('{3}|"{3})[\s\S]*?\1/gm
}

Note the ?, which makes the capture not greedy.

Add tests

Add tests to test expected results so I can easily catch regressions after updating language patterns.

Sass ampersand characters converted to '&amp;'

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

is converted to:

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

The CSS syntax seems to work well for Sass code otherwise.

Uncaught TypeError: Cannot read property 'getAttribute' of null

This is what I get when using Rainbow in my actual project. I'm not using the data-language attribute but classes, and I think there is the problem.

Except for this error it's working very well! Maybe you should add a try..catch block around the problematic function, not really sure.

Uncaught TypeError: Cannot read property 'getAttribute' of null rainbow.js:101
_attr rainbow.js:101
_getLanguageForBlock rainbow.js:150
_highlightCodeBlock rainbow.js:619
_highlightCodeBlock rainbow.js:644
_highlightCodeBlock rainbow.js:644
_highlightCodeBlock rainbow.js:644
_highlightCodeBlock rainbow.js:644
_highlightCodeBlock rainbow.js:644
(anonymous function)

Comments recognized as regex & 2 vars in a row

Having a comment end with "/" causes it be parsed as a Regex instead of a comment
(adding a space at the end of the line fixes this).

Having two "var" declarations in a row can cause problems:

//   [Showdown]: http://attacklab.net/showdown/
var language = getLanguage(source);
var parseAndHighlight = function() {

gets

<span class="string regexp"><span class="string regexp open">/</span>/   [Showdown]: http://attacklab.net/showdown<span class="string regexp close">/</span></span>
<span class="keyword">var</span> language <span class="keyword operator">=</span> <span class="function call">getLanguage</span>(source);
<span class="entity function"> var parseAndHighlight </span><span class="keyword operator">=</span> <span class="keyword">function</span>() {

Notice that the second var is included in the "entity function" instead of as a "keyword".

node.js support?

Looks like a fine and compact syntax package.

Any plans to support node.js so that you can do syntax hilite on the server too?

Also makes testing more easy.

Keep up the good, minimal work!

C "variable"

The pattern /\b[A-Z0-9_]{2,}\b/g would seem to match only strings without lower-case letters; this tends to highlight a lot of (capitalized by convention) macros in my test code. Adding a-z to that pattern ends up catching way too much, though.

Add the list of support languages to the readme

It's important enough information that I think it should be part of the core documentation, front and center. It's unintuitive to have to dig through Rainbow's folder structure on Github to discover this list.

Rainbow.color can highlight code twice?

From @josher19

Somewhat related: I have a script which modifies the DOM after the rainbowcode highlighting is completed by adding tooltips and a Table of Contents.

Right now I'm doing a setTimeout because when I tried an onload listener it was called before the rainbow code was completed. Doing Rainbow.color(callback) means > that the highlighting happens twice (once when called by my code and once by the document 'onload' listener). Any further suggestions? Really want a Rainbow.ready> (> callback) jQuery-type of function that will call the function immediately if Rainbow code has already completed parsing the DOM.>

Any further suggestions? Should I add it to the code and make a pull request?

Use rainbow with Mootools - my solution

Hi,
as I use Mootools (1.4.5) as my main JS lib, I encountered an error on ±line 582, rainbow.js file.

My solution is :

function _highlight(node, onComplete) {
/**/
var node = $(node);
/**/

var pre_blocks = (node || document).getElementsByTagName('pre'),
etc ...

Tks for this lightweight JS Syntax Highlighter.

Generic keywords too generic?

I understand that the more stuff goes into the generic.js language file, the smaller the other language files can be. This is good for keeping the whole package small.

However, when I look at the keyword list there are some words in there that are not constants in PHP, and probably in other languages too. It's unlikely I'd ever write the following PHP, but if I did the "struct" should be marked as a constant not as a keyword:

define('struct', 'test');
echo struct;

move the minified js to dist folder.

[enhancement] maybe it will be better if we move the production version to the 'dist' folder, then we can split the main js into more files to make it more testable. any ideas?

dynamically created blocks

If i create a div (say with jquery) after the page is loaded. There should be a way to color that div -

var mynewDiv = $('<div>My code here:<pre><code language="javascript">...</code></pre></div>');
Rainbow.color(mynewDiv);
someDiv.append(mynewDiv);

Request: Non-Conflicting Class Names

Hi,

I know this kinda stinks...But for closing tags, the close class is applied to the span element. There's a conflict with this and Twitter Bootstrap which defines styles for .close globally. I couldn't seem to flip the CSS around in the right order to avoid conflict.

I know it's literally impossible to know what people may be using alongside Rainbow...But perhaps prefixing class names with something like rainbow-close for example. Something more unique so that this doesn't happen. close is a very common word and class name. You'll have all sorts of close classes for buttons and links to close dialogs, etc.

Unless Rainbow is used in a sterile environment, then we're left to hack it up and I'd rather not for maintenance reasons. It's much nicer to just be able to grab updates without having to go back in and edit things.

I totally understand if this is low on your priority list there...But I think it's pretty important.

Thanks.

PHPDoc Comments

I am trying to add support for PHPDoc comments. So inside a comment block like this...

/**
 * Util
 *
 * @package Util
 * @author Jason Davis
 */

the @package and @author would be wrapped in a phpdoc css class.

Here is the code I have tried so far with no luck...

Rainbow.extend('php', [
    {
        'matches': {
            1: 'phpdoc'
        },
        'pattern': /@[a-z]+/g
    }
]);

It works if I remove the generic Comment matching regex but I need for the current comment regex to work and then match the PHPDoc comments inside of a comment block.

CSS child selector '>' converted to &gt;

 body > section

becomes

 body &gt; section

When using data-language="css". Tested with /* Rainbow v1.1.1 rainbowco.de | included languages: generic, shell, html, css */

A public highlight() method

I'd like to call highlight for certain code blocks directly from my code. Think of dynamic applications like previews.

I can see a private _highlightCodeBlock method.

Maybe split out the generic highlight part from your code?

Get language by class

I use markdown and markdown creates code snippets in this format:

  <pre>
    <code class="language"></code>
  </pre>

So, using data-language as the language selector for rainbow is kind of bad for me. It would be nice if I could specify it.

VB drag

I'm trying to use the rainbow code in a "Pastebin" style website, but I can't seem to get it too work in conjunction with my VB script, it drags and formats the code into the correct lines, just refuses to colour the code in any way. I've tried multiple different ways to resolve this issue, but can't seem to get it too work =/

I can't find if you have already covered this matter, but if you could help it would be greatly appreciated.

<h3>Current Article</h3>
<h5>Last edited by <asp:Label ID="cuen" runat="server" Text="Myth-Inc"/></h5>

<pre id="curview" runat="server"></pre>
    <script type="text/javascript" src="rainbow-dev-custom/rainbow.min.js"></script>
<script type="text/javascript" src="rainbow-dev-custom/language/generic.js"></script>
<script type="text/javascript" src="rainbow-dev-custom/language/css.js"></script>
<script type="text/javascript" src="rainbow-dev-custom/language/html.js"></script>
<script type="text/javascript" src="rainbow-dev-custom/language/javascript.js"></script>



Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Dim itemcode As Integer = -1
    If Integer.TryParse(Request.QueryString("pk"), itemcode) Then
        CommandObject = New Data.SqlClient.SqlCommand
        CommandObject.CommandText = ("rsp_curview")
        CommandObject.CommandType = Data.CommandType.StoredProcedure
        CommandObject.Parameters.AddWithValue("@cv", itemcode)
        datarow = function-page.ReadDataRow(CO, dbconn)
        Dim output = ("<code >" & datarow("textdrop") & "</code>")
        curview.InnerHtml = output
        cuen.text=datarow("nameuser")
    Else
        Server.Transfer("Default.aspx")
    End If
End Sub

python highlight hash comment

Hi, can you add these lines to python js:

{
'name': 'comment.docstring',
'pattern': /#+[^\n]+/g
}

so it highlights hash (one line) comments as well

Go language support

Good afternoon,

I think I'm gonna spend some time doing this one, Has anyone started doing it?

Cheers!

Javi.

Error: Too much recursion

Hello, today Rainbow threw an error: too much recursion at line 510 or sometimes at line 375!
Here's a paste of the code it ran on: http://pastie.org/4058180
There's nothing else on the page.
It only happens in Firefox 13 under Windows. In Opera 11, Chrome 19 and IE 9 it works fine..

Maybe, contenteditable?

First of all, Thank you for your codes.

I'm working on script editor which need to do some syntax highlighting. So I try to use CodeMirror. My web app is an one page app. The minified JS file is really big: 401KB in total. If I can use rainbow + contenteditable without Codemirror. I can make it 130KB smaller, Which is a really huge deal.

Do you think it's possible to do that? None of other highlighter can do this kind of stuff.

Thank you again.

Passing html directly to Rainbow.color doesn't seem to parse

Here's what I've been testing with. Any ideas?

<html>
  <head>
    <link rel="stylesheet" href="https://raw.github.com/ccampbell/rainbow/master/themes/tricolore.css">
  </head>
  <body>

    <script src = "https://raw.github.com/ccampbell/rainbow/master/js/rainbow.js" type="text/javascript"></script>
    <script src="https://raw.github.com/ccampbell/rainbow/master/js/language/generic.js" type="text/javascript"></script>
    <script src = "https://raw.github.com/ccampbell/rainbow/master/js/language/html.js" type="text/javascript"></script>
    <script type="text/javascript">

    var html = "<html><h2>Hi World!</h2></html>";


    Rainbow.color(html, 'html', function(highlighted_code) {
        console.log(highlighted_code); // => "<html><h2>Hi World!</h2></html>"
    });

    </script>
  </body>
</html>

Note: Javascript will parse correctly

Thanks!
Matt

Objective-C Support

I make Cocoa frameworks sometimes, and sites may require some nice Objective-C support, better than Github's.

JavaScript multiline comments recognized as regex

I've created an example using the following code:

var Animal = function() { /* ... */ };

And it was translated to the following HTML

        <span class="keyword">var</span> Animal <span class="keyword operator">=</span> <span class="keyword">function</span>() { <span class="regex"><span class="regex open">/</span>* ... *<span class="regex close">/</span></span> };
    Animal.prototype <span class="keyword operator">=</span> { <span class="regex"><span class="regex open">/</span>* ... *<span class="regex close">/</span></span> };

So the slashes that open/close the comments are recognized as regex instead.

Javascript highlighting doesn't always work properly for JSON

If there is no space after the colon, it won't highlight a string properly. For example:

{
  "generated_in": "0.0423",
  "stat": "fail",
  "err": {
    "code": "1",
    "expl": "The user id or name was either not valid or not provided.",
    "msg": "User not found"
  }
}

highlights properly, while this does not:

{
  "generated_in":"0.0423",
  "stat":"fail",
  "err":{
    "code":"1",
    "expl":"The user id or name was either not valid or not provided.",
    "msg":"User not found"
  }
}

Don't color/highlight onload

It looks impossible to stop Rainbow on load.
Sometimes you want to build the page dynamically, and only at a later stage trigger Rainbow.

JSON highlighter breaking on date strings

This doesn't work:

{
    "apiKey" : "YOUR_TEST_OR_LIVE_KEY",
    "batch"  : [
        {
            "method"    : "identify",
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "sessionId" : "fj2hvu328vh38uvh83kxjf",
            "userId"    : "[email protected]",
            "traits"    : {
                "Subscription Plan" : "Gold",
                "Friend Count"      : 42
            }
        },
        {
            "method"    : "track",
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "sessionId" : "fj2hvu328vh38uvh83kxjf",
            "userId"    : "[email protected]",
            "event"     : "Played a Song",
            "properties" : {
                "genre"  : "Hip Hop",
                "artist" : "Theophilus London"
            }
        }
    ]
}

But remove some properties from the second object and it does work again:

{
    "apiKey" : "YOUR_TEST_OR_LIVE_KEY",
    "batch"  : [
        {
            "method"    : "identify",
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "sessionId" : "fj2hvu328vh38uvh83kxjf",
            "userId"    : "[email protected]",
            "traits"    : {
                "Subscription Plan" : "Gold",
                "Friend Count"      : 42
            }
        },
        {
            "method"    : "track",
            "event"     : "Played a Song",
            "properties" : {
                "genre"  : "Hip Hop",
                "artist" : "Theophilus London"
            }
        }
    ]
}

This doesn't work:

{
    "apiKey" : "YOUR_TEST_OR_LIVE_KEY",
    "batch"  : [
        {
            "method"    : "identify",
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "traits"    : {
                "Subscription Plan" : "Gold",
                "Friend Count"      : 42
            }
        },
        {
            "method"    : "track",
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "properties" : {
                "genre"  : "Hip Hop",
                "artist" : "Theophilus London"
            }
        }
    ]
}

But when I remove the "method" it does work again even with two date strings:

{
    "apiKey" : "YOUR_TEST_OR_LIVE_KEY",
    "batch"  : [
        {
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "traits"    : {
                "Subscription Plan" : "Gold",
                "Friend Count"      : 42
            }
        },
        {
            "timestamp" : "Mon Apr 16 2012 14:21:48 GMT-0400 (EDT)",
            "properties" : {
                "genre"  : "Hip Hop",
                "artist" : "Theophilus London"
            }
        }
    ]
}

Tab size

Since most browsers do eight spaces for tab inside pre, and untill all browsers support CSS tab-width, it would be nice to have something like /^\t?/g in language/generic.js for tab size control.

Provide a synchronous API

It makes sense that the API is asynchronous by default, but it would be nice to have another API which is synchronous (it returns the highlighted text and doesn't take a callback). This is particularly useful for server-side usage of Rainbow. Otherwise setTimeout gymnastics are required (see #7).

Custom Comment blocks breaks my highlighting

I have added this code to identify and adds a CSS class to PHP Doc Comment variables @comment

Rainbow.extend('php', [{
    'name': 'comment',
    'matches': {
        1: {
            'name': 'keyword.phpdoc',
            'pattern': /\s+@\w+/g
        }
    },
    'pattern': /\/\*([\s\S]*)?\*\/|(\/\/|\#)[\s\S]*?$/gm
}]);

It works great for doing this but it seems to cause a problem on some code snippets.

On this example code snippet http://www.codedevelopr.com/uploads/rainbow/bug.html you can see that my Doc Comments are properly highlighted but after the first comment block, it messes up the rest of the highlighting.

I then created the same code snippet on this page http://www.codedevelopr.com/uploads/rainbow/bug2.html but without the first comment block, you can see everything is going well until it runs into comments again and then it breaks.

Any ideas on how I can resolve this issue

Pick an open source license

It would make it clearer what folks can do with your code if you pick a license. The most lightweight option is to just link to it from your readme. For example:

Rainbow is released under [the MIT license](http://www.opensource.org/licenses/mit-license.php).

Feature Request: Automatically detect language

I use Jekyll to host my blog using Github Pages. The markdown syntax to wrap a block of code is to indent with 4 spaces, this wraps using <pre><code></code></pre>.

So I am not able to apply the appropriate value to a data-language attribute, as the <pre><code></code></pre> isn't actually in my markdown file, it is generated.

Well, I could wrap the code blocks with the HTML manually, but I want to keep my articles written purely in markdown, so the Github preview works.

So I'm wondering how difficult it would be to detect the language of the code inside the <pre><code></code></pre> block, and then apply the appropriate styling to it. It doesn't have to be 100% accurate, just better than what I am doing at the moment:

$(function() {
    $("pre > code").attr('data-language', 'generic');
    Rainbow.color();
});

Markdown Source:
https://raw.github.com/lukearmstrong/lukearmstrong.github.com/master/_posts/2012-10-18-minify-your-css-and-javascript.markdown

Markdown Preview:
https://github.com/lukearmstrong/lukearmstrong.github.com/blob/master/_posts/2012-10-18-minify-your-css-and-javascript.markdown

Resulting HTML generated by Jekyll:
http://lukearmstrong.co.uk/2012/10/18/minify-your-css-and-javascript/

Incorrect highlighting for onClick HTML attribute

I noticed that the highlighting for the following code is incorrect:

<button onClick="test()">Click me</button>

The "onC" portion of the attribute isn't tagged at all and "lick" is tagged as "support tag".

Ruby highlighter should support multi-line strings

Ruby supports multi-line strings, for both single and double-quoted strings.

e.g.,

str = "This
is
a valid string."

str = 'So
is
this string.'

Any implementation should deal with the following edge case:

# This comment contains a single quote: '

str = 'This
string \'should\' be
highlighted, including the escaped quotes'

The way rainbow's parser works is by generating all possible matches for a regex and discarding those that intersect another regex. In this case, the regex to match a multi-line string will most likely start by picking up the single quote in the comment.

This has nothing to do with comments, per se. It would also trip up if, say, there were a single quote in a double-quoted string immediately preceding a single-quoted string.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.