{"id":17079088,"url":"https://github.com/curlpipe/synoptic","last_synced_at":"2025-04-12T20:34:31.493Z","repository":{"id":57669170,"uuid":"326531209","full_name":"curlpipe/synoptic","owner":"curlpipe","description":"A simple, low-level, syntax highlighting library with unicode support","archived":false,"fork":false,"pushed_at":"2024-02-24T20:26:58.000Z","size":51118,"stargazers_count":15,"open_issues_count":1,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-04-25T22:43:42.608Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/curlpipe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-01-04T00:46:08.000Z","updated_at":"2024-07-17T20:44:21.612Z","dependencies_parsed_at":"2024-07-17T20:44:16.780Z","dependency_job_id":"c5924dc9-be5f-41ab-8995-dc780a37d051","html_url":"https://github.com/curlpipe/synoptic","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curlpipe%2Fsynoptic","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curlpipe%2Fsynoptic/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curlpipe%2Fsynoptic/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/curlpipe%2Fsynoptic/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/curlpipe","download_url":"https://codeload.github.com/curlpipe/synoptic/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248631052,"owners_count":21136547,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-14T12:24:34.295Z","updated_at":"2025-04-12T20:34:31.451Z","avatar_url":"https://github.com/curlpipe.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Synoptic\n\n\u003e Syntax highlighting for Rust applications\n\nThis is a pretty lightweight (only 3 main depedencies) and simple regex-based syntax highlighter for Rust. \n\nI originally wrote this for my text editor, Ox. It needed a fast, configurable and optimised syntax highlighter that could easily integrate with existing projects. However, you can (and are encouraged) to use it for any project you have in mind.\n\n---\n**Advantages:**\n- **Customisable** - You can highlight almost any language by adding in custom syntax highlighting rules\n- **Fast** - Is reasonably fast, enough so that it won't slow your projects down, even with large files and many different rules\n- **Simple** - You can get highlighting code pretty quickly (see example below)\n- **Incremental** - As this was designed for use with a text editor, it can really quickly re-highlight code upon edit commands\n- **Built in language rules** - Get highlighting even faster by choosing from existing syntax rules\n- **File Buffering** - Synoptic doesn't need the whole file to perform a correct highlighting job, thus allowing file buffering\n- **Escaping** - Will handle escaping if you need it (`\"here is a quote: \\\" tada!\"`)\n- **Interpolation**  - Will handle interpolation if you need it (`\"My name is {name}, nice to meet you!\"`)\n\n**Disadvantages:**\n- **Not very well established** - There may be inconsistencies in the included pre-built language highlighting rules\n- **Lacks understanding** - This will not be able to provide very detailed syntax highlighting, as no parsing is performed\n- **Interpolation is limited** - You can't nest interpolated tokens like `\"this is { \"f{ \"u\" }n\" }\"` \n\nDespite its disadvantages, if you just want a simple syntax highlighter with no frills or excess baggage, synoptic might just be your crate.\n\n## Installation\nJust add it to your `Cargo.toml`:\n```toml\n[dependencies]\nsynoptic = \"2\"\n```\n\n- Construct a `Highlighter` instance\n- Add regular expressions and keywords to the highlighter and assign each a name\n- Use the `run` method to generate tokens\n- Use the `line` method to obtain the tokens for each line\n\n## Built-in languages\n\nYou can also use some provided syntax highlighters for various popular languages using the `from_extension` function.\nThere is highly likely to be inconsistencies in the existing rules, please do open an issue if you spot any.\n\nCurrently, synoptic includes\n\n- [x] Various Higher Level Languages: Python, Ruby, Lua, Perl, Java, Visual Basic, Scala\n- [x] The C Family: C, C++, C#\n- [x] Various Lower Level Languages: Rust, Go, Assembly\n- [x] Web Technologies: HTML, CSS, PHP, Javascript, JSON, TypeScript\n- [x] Mathematical Languages: MATLAB, R, Haskell, Prolog\n- [x] Moblie Development: Kotlin, Swift, Dart\n- [x] Markup Languages: Markdown, YAML, TOML, XML, CSV\n- [x] Other: SQL, Bash, Nushell\n\nOpen an issue if there is a language not yet supported, or if you notice any issues in the built-in syntax highlighting rules.\n\n## Example\n\nHere's an example of a Rust syntax highlighter, using the lliw crate.\n\n```rust\nuse synoptic::{Highlighter, TokOpt};\nuse lliw::Fg;\n\n// Let's use some demonstration code\npub static CODE: \u0026str = \"\\\n/*\nMultiline comments\nWork great\n*/\n\npub fn main() -\u003e bool {\n    // Demonstrate syntax highlighting in Rust!\n    println!(\\\"Full Unicode Support: 你好\\\");\n    // Interpolation\n    let name = \\\"peter\\\";\n    println!(\\\"My name is {name}, nice to meet you!\\\");\n    // Bye!\n    return true;\n}\n\";\n\nfn main() {\n    // Setting up the highlighter\n    // The `4` here just means tabs are shown as 4 spaces\n    let mut h = Highlighter::new(4);\n    \n    // Bounded tokens are multiline tokens\n    // Let's define multiline comments\n    // In rust, these start with /* and end with */\n    // Remember to escape any regex characters (like *)\n    // The false here is whether or not to allow escaping\n    // When true, we ignore any end markers with a backslash in front of them\n    // So, if it were true: `/* this is a comment \\*/ this is still a comment */ this isn't`\n    h.bounded(\"comment\", r\"/\\*\", r\"\\*/\", false);\n    \n    // Now let's define a string\n    // In rust, format strings can be interpolated into between {}\n    // We first define the name of the token, the starting and ending pattern\n    // Then the starting and ending pattern of the interpolation section\n    // We also want strings to be escapable e.g. \"here's a quote: \\\" this is still a string\"\n    // Hence the true\n    h.bounded_interp(\"string\", \"\\\"\", \"\\\"\", \"\\\\{\", \"\\\\}\", true);\n    \n    // Now let's define some keywords\n    // These are single line snippets of text\n    h.keyword(\"keyword\", r\"\\b(pub|fn|bool|let|return)\\b\");\n    \n    // Let's get numbers being highlighted\n    h.keyword(\"digits\", r\"\\b\\d+\\.(?:\\.\\d+)\\b\");\n    \n    // ... and some remaining syntax rules\n    h.keyword(\"comment\", \"(//.*)$\");\n    h.keyword(\"boolean\", r\"\\b(true|false)\\b\");\n    h.keyword(\"macros\", \"[a-zA-Z_]+\\\\!\");\n    h.keyword(\"function\", r\"([a-z][a-zA-Z_]*)\\s*\\(\");\n    \n    // Now let's run the highlighter on the example code\n    // The run method takes a vector of strings (for each line)\n    let code = CODE\n        .split('\\n')\n        .map(|line| line.to_string())\n        .collect();\n    // Now we're ready to go\n    h.run(\u0026code);\n    \n    // Let's render the output\n    for (line_number, line) in code.iter().enumerate() {\n        // Line returns tokens for the corresponding line\n        for token in h.line(line_number, \u0026line) {\n            // Tokens can either require highlighting or not require highlighting\n            match token {\n                // This is some text that needs to be highlighted\n                TokOpt::Some(text, kind) =\u003e print!(\"{}{text}{}\", colour(\u0026kind), Fg::Reset),\n                // This is just normal text with no highlighting\n                TokOpt::None(text) =\u003e print!(\"{text}\"),\n            }\n        }\n        // Insert a newline at the end of every line\n        println!();\n    }\n}\n\nfn colour(name: \u0026str) -\u003e Fg {\n    // This function will take in the function name\n    // And it will output the correct foreground colour\n    match name {\n        \"comment\" =\u003e Fg::LightBlack,\n        \"digit\" =\u003e Fg::Purple,\n        \"string\" =\u003e Fg::Green,\n        \"macros\" =\u003e Fg::LightPurple,\n        \"boolean\" =\u003e Fg::Blue,\n        \"keyword\" =\u003e Fg::Yellow,\n        \"function\" =\u003e Fg::Red,\n        _ =\u003e panic!(\"unknown token name\"),\n    }\n}\n\n```\n\nThat will render a result similar to this (depending on your terminal's colour scheme):\n\n![](https://i.postimg.cc/0QJTsMbf/image.png)\n\n## License\n`MIT` license to ensure that you can use it in your project\n\nyou can check the `LICENSE` file for more info\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcurlpipe%2Fsynoptic","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcurlpipe%2Fsynoptic","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcurlpipe%2Fsynoptic/lists"}