RyuseiLight

RyuseiLight is a beautiful, lightweight and extensible syntax highlighter.
/**
* The component for highlighting lines.
*
* @since 0.0.1
*/
export function ActiveLines( { event, root, options }: Renderer ): void {
const lines = ( root && parseData( root ) ) || options.activeLines;
if ( isArray( lines ) ) {
const activeLines = normalize( lines );
event.on( 'gutter:row:open', ( html, classes, index ) => {
if ( activeLines[ index ] ) {
classes.push( activeLines[ index ] );
}
} );
}
}
TypeScript

Features

Lightweight

Only 10kB (4.2kB gzipped), including JavaScript, HTML, CSS and XML. Even with all extensions, the size will be only 16kB.
Get Started

Beautiful

Colors are carefully selected for harmonious appearance. Easy to create your own theme by SASS (SCSS).
Browse Themes

Modular

All extensions and languages are modular. Build your small highlighter with really necessary modules.
Browse Extensions

Extensible

Languages can be defined or modified as you like. New functionality can be added by creating your own extension.
View Documents

Examples

Default

The default style of RyuseiLight. No extension is required.

class AlertButton extends React.Component {
const { message, label } = this.props;
render() {
return (
<button className="button" onClick={ () => alert( message ) }>
{ label }
</button>
);
}
}

Line Numbers

The Gutter and LineNumbers extensions are required.

.button {
$root: &;
font-family: Roboto, 'Avenir Next Pro', sans-serif;
font-size: .9rem;
&__inner {
padding: 1rem;
}
&--primary {
color: white;
#{ $root }__inner {
background: $main-color;
}
}
}

Active Lines

The ActiveLines extension is required.

export function ActiveLines( { event, root, options }: Renderer ): void {
const lines = ( root && parseData( root ) ) || options.activeLines;
if ( isArray( lines ) ) {
const activeLines = normalize( lines );
event.on( 'gutter:row:open', ( html, classes, index ) => {
if ( activeLines[ index ] ) {
classes.push( activeLines[ index ] );
}
} );
event.on( 'line:open', ( html, classes, index ) => {
if ( activeLines[ index ] ) {
classes.push( activeLines[ index ] );
}
} );
}
}

Language Name

The Overlay and LanguageName extensions are required.

{
"users": {
"title": "Users",
"list": [
{
"name": "John Doe",
"id": "001",
"age": 38,
"entries": [ 1, 3, 4 ],
"premium": true,
"icon": null
},
]
}
}
JSON

Caption

The Caption extension is required.

Displaying Alert
class AlertButton extends React.Component {
const { message, label } = this.props;
render() {
return (
<button className="button" onClick={ () => alert( message ) }>
{ label }
</button>
);
}
}

Copy Button

The Copy extension is required.

class AlertButton extends React.Component {
const { message, label } = this.props;
render() {
return (
<button className="button" onClick={ () => alert( message ) }>
{ label }
</button>
);
}
}

Diff

The Diff extension is required.

export function ActiveLines( { event, root, options }: Renderer ): void {
const lines = ( root && parseData( root ) ) || options.activeLines;
if ( isArray( lines ) ) {
const activeLines = normalize( lines );
event.on( 'gutter:row:open', ( html, classes, index ) => {
if ( activeLines[ index ] ) {
classes.push( activeLines[ index ] );
}
} );
event.on( 'line:open', ( html, classes, index ) => {
if ( activeLines[ index ] ) {
classes.push( activeLines[ index ] );
}
} );
}
}

About

RyuseiLight is a beautiful, lightweight and extensible Syntax Highlighter, written in TypeScript. It tokenizes code by regular expressions likewise other popular highlighters. One of the biggest problem of regex based highlighter, however, is how to handle nested syntax, such as a template literal in JavaScript. That usually requires a very complex regex that is hard to understand.

RyuseiLight adopts a state system that can count "open" and "close" symbols, inspired by Monarch. Thanks to the system, it can be simply and correctly tokenized:

// A nested template literal
`container ${
isMobile()
? 'is-mobile'
: `container--${ page.isFront() ? 'front' : 'page' }`
}`;

RyuseiLight does not aim for a strict tokenizer, but for good balance with simplicity and correctness. Currently, (only) 11 languages are supported, sorry!

Here is a summary of features:

  • Only 10kB (4kB gzipped), including JavaScript, HTML, CSS and XML
  • Beautiful themes, easy to customize by SASS (SCSS)
  • Modular for minimal bundle size
  • Easy to add new languages and extensions
  • Displaying line numbers
  • Highlighting lines
  • Displaying a language name
  • Displaying a code caption
  • HTML generation for SSR
  • Internet Explorer 10

Ryusei(流星, 流=flow, 星=star) is my personal project code, that means a shooting star in Japanese. ⭐