synoptic 0.3.3

A simple, low-level, syntax highlighting library with unicode support
Documentation
# Synoptic
### Syntax highlighting for Rust applications

I originally wrote this for my text editor, Ox. It needed a fast, robust and reliable syntax highlighter that was configurable and was able to easily plug-in to a front end.

## Low-level
No pre-built language rules so everything is entirely up to you. Outputs a simple stream of tokens.

## Fast
Takes advantage of Rust's speed. Benches say that it can highlight 18470 lines of Rust code in around 60 milliseconds

## Simple
You can highlight code for most languages in just a few steps:

- Construct a `Highlighter` instance
- Add regular expressions and keywords to the highlighter and assign each a name
- Use the `run` method to recieve a stream of start, end and text tokens to use in your program.

You can also very quickly add, remove and modify build syntax highlighting rules to adjust to your liking.

## Example

Here's an example of a Rust syntax highlighter, using the termion crate.

```rust
use synoptic::{Token, Highlighter};
use termion::color;

const DEMO: &str = r#"/*
Multiline comments
Work great
*/

pub fn main() -> bool {
	// Demonstrate syntax highlighting in Rust!
	println!("Full Unicode Support: 你好!Pretty cool");
	return true;
}
"#;

fn main() {
	// Build the rust syntax highlighter
    let mut rust = Highlighter::new();
    // Add keywords
    rust.join(&["fn", "return", "pub"], "keyword").unwrap();
    rust.join(&["bool"], "type").unwrap();
    rust.join(&["true", "false"], "boolean").unwrap();
	// Add comment definitions
    rust.add(r"(?m)(//.*)$", "comment").unwrap();
    rust.add(r"(?ms)/\*.*?\*/", "comment").unwrap();
    // Add string definition
    rust.add("\".*?\"", "string").unwrap();
    // Add identifier definition
    rust.add(r"([a-z_][A-Za-z0-9_]*)\s*\(", "identifier").unwrap();
    // Add macro definition
    rust.add(r"([a-z_][A-Za-z0-9_]*!)\s*", "macro").unwrap();

    // Run highlighter
    let highlighting = rust.run(DEMO);
    
    // For each row
    for (c, row) in highlighting.iter().enumerate() {
    	// Print line number (with padding)
        print!("{: >3} |", c);
        // For each token within each row
        for tok in row {
        	// Handle the tokens
            match tok {
            	// Handle the start token (start foreground colour)
                Token::Start(kind) => match *kind {
                    "comment" => print!("{}", color::Fg(color::Black)),
                    "string" => print!("{}", color::Fg(color::Green)),
                    "keyword" => print!("{}", color::Fg(color::Blue)),
                    "type" => print!("{}", color::Fg(color::LightMagenta)),
                    "boolean" => print!("{}", color::Fg(color::LightGreen)),
                    "identifier" => print!("{}", color::Fg(color::Yellow)),
                    "macro" => print!("{}", color::Fg(color::Magenta)),
                    _ => (),
                }
                // Handle a text token (print out the contents)
                Token::Text(txt) => print!("{}", txt),
                // Handle an end token (reset foreground colour)
                Token::End(_) => print!("{}", color::Fg(color::Reset)),
            }
        }
        // Prevent text being cut off without a newline
        println!("");
    }
}
```

That will render this result:

![](https://i.postimg.cc/1t32c35k/image.png)

## Installation
Just add it to your `Cargo.toml`:

```toml
[dependencies]
synoptic = "0"
```

## License
`MIT` license to ensure that you can use it in your project

you can check the `LICENSE` file for more info