diff --git a/README.md b/README.md index 16429bc..771320d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,8 @@ Dedicated to chasing the [`bat` man](https://github.com/sharkdp) Extra syntax and theme definitions for [`syntect`](https://docs.rs/syntect/latest/syntect/) including many common ones -that are missing from the default set like TOML, TypeScript, and Dockerfile +that are missing from the default set like TOML, TypeScript, and Dockerfile. +Curated by the [`bat` Project](https://github.com/sharkdp/bat) ## Example @@ -55,26 +56,102 @@ will print this ## Feature Flags -Some embedded syntaxes use features that aren't available with `fancy-regex`. To -keep regex compilation infallible it's important to match this library's regex -implementation with the one you're using from syntect - -To use [`Oniguruma`](https://github.com/kkos/oniguruma) aka onig - -```cmd -[dependencies] -# `onig` is the default -syntect = "0.5.1" -two-face = "0.3.1" -``` - -To use [`fancy-regex`](https://github.com/fancy-regex/fancy-regex) - -```toml -[dependencies] -syntect = { version = "0.5.1", default-features = false, features = ["default-fancy"] } -two-face = { version = "0.3.1", default-features = false, features = ["syntect-fancy"] } -``` +The feature flags are divided by `syntect`'s underlying regex implementation +with [`Oniguruma`](https://github.com/kkos/oniguruma) aka `onig` being the +default and [`fancy-regex`](https://github.com/fancy-regex/fancy-regex) aka +`fancy` as an alternative pure-Rust implementation. `fancy`: however, doesn't +support all of the features used by some of the syntax definitions, so some of +the defintions are excluded when `fancy` is selected\* to keep the regex +compilation infallible. This means that it's important to match whichever regex +implementation `syntect` is using + +_\* This is also why fancy's bundled syntax definitions are smaller than onig's_ + +default: `syntect-onig` + +| Feature | Desc. | +| :---: | :--- | +| `syntect-onig` / `syntect-fancy` | Enables the minimal feature set that we require from `syntect` | +| `syntect-default-onig` / `syntect-default-fancy` | The mimimal feature sets along with `syntect`'s default feature set (useful when using the `syntect` re-export) | + +## Embedded Asset Sizes + +This crate embeds some reasonably large assets in the final binary in order to +work. Luckily the linker is smart enough to discard unused assets, so you +generally only pay for what you use + +For reference here are the sizes associated with their different functions + +| function | `two-face` (KiB) | `syntect` (KiB) | +| ---: | ---: | ---: | +| [`acknowledgement::listing()`](https://docs.rs/two-face/latest/two_face/acknowledgement/fn.listing.html) | 10 | - | +| [`syntax::extra_newlines()`](https://docs.rs/two-face/latest/two_face/syntax/fn.extra_newlines.html) (onig) | 867 | 360 | +| ^^ (fancy) | 812 | 360 | +| [`syntax::extra_no_newlines()`](https://docs.rs/two-face/latest/two_face/syntax/fn.extra_no_newlines.html) (onig) | 865 | 359 | +| ^^ (fancy) | 811 | 359 | +| [`theme::extra()`](https://docs.rs/two-face/latest/two_face/theme/index.html) | 45 | 5 | + +In short the syntax definitions are the real chonky part, and if you're +switching from `syntect` to `two-face`, then you can expect a ~0.5MiB increase +in binary size from them (in exchange for _a lot_ of syntax definitions) + +## Syntaxes + +The full listing of all syntaxes included in [`two_face::syntax`](https://docs.rs/two-face/latest/two_face/syntax/index.html) + +- \* Exluded when using the `fancy-regex` implementation +- † Included in `syntect`'s bundled defaults + +| | Syntax Definition | +| :---: | :---: | +| A | ActionScript†, Ada, Apache Conf, AppleScript†, AsciiDoc, ASP†, ARM Assembly\*, Assembly (x86_64), AWK | +| B | Bash†, Batch File†, BibTeX† | +| C | C†, C#†, C++†, Cabal, Clojure†, CMake, CoffeeScript, Crontab, Crystal, CSS†, CSV† | +| D | D†, Dart, Dockerfile, DotENV, Diff† | +| E | Elixir, Elm, Email, Erlang† | +| F | F#, Fish, Fortran, fstab | +| G | Git (commit, config, ignore, etc.)†, GLSL, Go†, GraphQL, Graphviz (DOT)†, Groff/troff†, Groovy† | +| H | Haskell†, HTML† | +| I | INI | +| J | Java†, Javadoc†, Java Server Page (JSP)†, JavaScript†, JavaScript (Babel)\*, Jinja2, JQ, JSON†, Julia | +| K | Kotlin | +| L | LaTeX†, LaTeX Log†, Lean, LESS, Lisp†, Literate Haskell†, LiveScript\*, LLVM, Lua† | +| M | Makefile†, Manpage, Markdown†, MATLAB†, Mediawiki, MutliMarkdown† | +| N | NAnt Build File†, Nginx, Nim, Ninja, Nix | +| O | Objective-C†, Objective-C++†, OCaml†, OCamllex†, OCamlyacc†, Org Mode | +| P | Pascal†, Perl†, PHP†, PowerShell\*, Protobuf, Puppet, PureScript, Python† | +| Q | QML | +| R | R†, Racket, Rd†, Rego, Regular Expression†, Requirements.txt, reStructuredText†, Robot Framework, Ruby†, Ruby Haml†, Ruby on Rails†, Ruby Slim, Rust† | +| S | Sass\*, Scala†, SCSS, Salt State SLS\*, SML, Solidity, SQL†, Strace, Stylus, Svelte, Swift, SystemVerilog | +| T | Tcl†, Terraform, TeX†, Textile†, Todo.txt, TOML, TypeScript, TypescriptReact | +| V | Varlink, Verilog, VimL, Vue, Vyper | +| X | XML† | +| Y | YAML† | +| Z | Zig | + +## Themes + +The full listing of themes provided by `two_face::theme`. Many of these themes +only make sense situationally, so you'll likely want to only expose a subset + +- † Included in `syntect`'s bundled defaults + +| | Theme | +| :---: | :---: | +| 1 | 1337 (aka leet) | +| A | Ansi | +| B | Base16, Base16-256, Base16-Eighties (dark)†, Base16-Mocha (dark)†, Base16-Ocean (light/dark)† | +| C | Coldark (cold/dark aka light/dark) | +| D | DarkNeon, Dracula | +| G | GitHub, gruvbox (light/dark) | +| I | InspiredGitHub† | +| M | Monokai Extended (plain, bright, light, and origin) | +| N | Nord | +| O | One Half (light/dark) | +| S | Solarized (light/dark)† | +| T | TwoDark | +| V | Visual Studio Dark+ | +| Z | Zenburn | ## Legal @@ -86,6 +163,11 @@ and Apache-2.0. See the [LICENSE-APACHE](LICENSE-APACHE) and [LICENSE-MIT](LICENSE-MIT) files for license details. +The embedded syntax definitions and assets also have their own licenses which +are compiled into +[this markdown file](https://github.com/CosmicHorrorDev/two-face/blob/main/generated/acknowledgements_full.md) +along with programmatic in the `acknowledgement` module. + ### `bat`'s NOTICE Copyright (c) 2018-2021 bat-developers (https://github.com/sharkdp/bat). @@ -93,4 +175,5 @@ Copyright (c) 2018-2021 bat-developers (https://github.com/sharkdp/bat). bat is made available under the terms of either the MIT License or the Apache License 2.0, at your option. -See the LICENSE-APACHE and LICENSE-MIT files for license details. +See the [LICENSE-APACHE](./bat/LICENSE-APACHE) and +[LICENSE-MIT](./bat/LICENSE-MIT) files for license details. diff --git a/src/lib.rs b/src/lib.rs index 7bdc099..5283fad 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,12 +1,15 @@ //! Dedicated to chasing the [`bat` man](https://github.com/sharkdp) //! //! Extra syntax and theme definitions for -//! [`syntect`](https://docs.rs/syntect/latest/syntect/) including many common ones that are missing -//! from the default set like TOML, TypeScript, and Dockerfile +//! [`syntect`] including many common ones +//! that are missing from the default set like TOML, TypeScript, and Dockerfile. +//! Curated by the [`bat` Project](https://github.com/sharkdp/bat) //! -//! # Example +//! ## Example //! -//! ```text +//! The following +//! +//! ```cmd //! $ cargo add two-face --features syntect-default-onig //! ``` //! @@ -36,33 +39,119 @@ //! } //! ``` //! +//! where `htmlified` displays as +//! //!
//! [section] //! key = 123 //!//! -//! # Feature Flags //! -//! Some embedded syntaxes use features that aren't available with `fancy-regex`. To keep regex -//! compilation infallible it's important to match this library's regex implementation with the one -//! you're using from syntect +//! ## Feature Flags //! -//! To use [Oniguruma](https://github.com/kkos/oniguruma) aka `onig` +//! The feature flags are divided by `syntect`'s underlying regex implementation +//! with [`Oniguruma`](https://github.com/kkos/oniguruma) aka `onig` being the +//! default and [`fancy-regex`](https://github.com/fancy-regex/fancy-regex) aka +//! `fancy` as an alternative pure-Rust implementation. `fancy`: however, doesn't +//! support all of the features used by some of the syntax definitions, so some of +//! the defintions are excluded when `fancy` is selected\* to keep the regex +//! compilation infallible. This means that it's important to match whichever regex +//! implementation `syntect` is using //! -//! ```toml -//! [dependencies] -//! # `onig` is the default -//! syntect = "0.5.1" -//! two-face = "0.3.1" -//! ``` +//! _\* This is also why fancy's bundled syntax definitions are smaller than onig's_ //! -//! To use [`fancy-regex`](https://github.com/fancy-regex/fancy-regex) +//! default: `syntect-onig` //! -//! ```toml -//! [dependencies] -//! syntect = { version = "0.5.1", default-features = false, features = ["default-fancy"] } -//! two-face = { version = "0.3.1", default-features = false, features = ["syntect-fancy"] } -//! ``` +//! | Feature | Desc. | +//! | :---: | :--- | +//! | `syntect-onig` / `syntect-fancy` | Enables the minimal feature set that we require from `syntect` | +//! | `syntect-default-onig` / `syntect-default-fancy` | The mimimal feature sets along with `syntect`'s default feature set (useful when using the `syntect` re-export) | +//! +//! ## Embedded Asset Sizes +//! +//! This crate embeds some reasonably large assets in the final binary in order to +//! work. Luckily the linker is smart enough to discard unused assets, so you +//! generally only pay for what you use +//! +//! For reference here are the sizes associated with their different functions +//! +//! | function | `two-face` (KiB) | `syntect` (KiB) | +//! | ---: | ---: | ---: | +//! | [`acknowledgement::listing()`] | 10 | - | +//! | [`syntax::extra_newlines()`] (onig) | 867 | 360 | +//! | ^^ (fancy) | 812 | 360 | +//! | [`syntax::extra_no_newlines()`] (onig) | 865 | 359 | +//! | ^^ (fancy) | 811 | 359 | +//! | [`theme::extra()`] | 45 | 5 | +//! +//! In short the syntax definitions are the real chonky part, and if you're +//! switching from `syntect` to `two-face`, then you can expect a ~0.5MiB increase +//! in binary size from them (in exchange for _a lot_ of syntax definitions) +//! +//! ## Syntaxes +//! +//! The full listing of all syntaxes included in [`syntax`] +//! +//! - \* Exluded when using the `fancy-regex` implementation +//! - † Included in `syntect`'s bundled defaults +//! +//! | | Syntax Definition | +//! | :---: | :---: | +//! | A | ActionScript†, Ada, Apache Conf, AppleScript†, AsciiDoc, ASP†, ARM Assembly\*, Assembly (x86_64), AWK | +//! | B | Bash†, Batch File†, BibTeX† | +//! | C | C†, C#†, C++†, Cabal, Clojure†, CMake, CoffeeScript, Crontab, Crystal, CSS†, CSV† | +//! | D | D†, Dart, Dockerfile, DotENV, Diff† | +//! | E | Elixir, Elm, Email, Erlang† | +//! | F | F#, Fish, Fortran, fstab | +//! | G | Git (commit, config, ignore, etc.)†, GLSL, Go†, GraphQL, Graphviz (DOT)†, Groff/troff†, Groovy† | +//! | H | Haskell†, HTML† | +//! | I | INI | +//! | J | Java†, Javadoc†, Java Server Page (JSP)†, JavaScript†, JavaScript (Babel)\*, Jinja2, JQ, JSON†, Julia | +//! | K | Kotlin | +//! | L | LaTeX†, LaTeX Log†, Lean, LESS, Lisp†, Literate Haskell†, LiveScript\*, LLVM, Lua† | +//! | M | Makefile†, Manpage, Markdown†, MATLAB†, Mediawiki, MutliMarkdown† | +//! | N | NAnt Build File†, Nginx, Nim, Ninja, Nix | +//! | O | Objective-C†, Objective-C++†, OCaml†, OCamllex†, OCamlyacc†, Org Mode | +//! | P | Pascal†, Perl†, PHP†, PowerShell\*, Protobuf, Puppet, PureScript, Python† | +//! | Q | QML | +//! | R | R†, Racket, Rd†, Rego, Regular Expression†, Requirements.txt, reStructuredText†, Robot Framework, Ruby†, Ruby Haml†, Ruby on Rails†, Ruby Slim, Rust† | +//! | S | Sass\*, Scala†, SCSS, Salt State SLS\*, SML, Solidity, SQL†, Strace, Stylus, Svelte, Swift, SystemVerilog | +//! | T | Tcl†, Terraform, TeX†, Textile†, Todo.txt, TOML, TypeScript, TypescriptReact | +//! | V | Varlink, Verilog, VimL, Vue, Vyper | +//! | X | XML† | +//! | Y | YAML† | +//! | Z | Zig | +//! +//! ## Themes +//! +//! The full listing of themes provided by [`theme`]. Many of these themes +//! only make sense situationally, so you'll likely want to only expose a subset +//! +//! - † Included in `syntect`'s bundled defaults +//! +//! | | Theme | +//! | :---: | :---: | +//! | 1 | 1337 (aka leet) | +//! | A | Ansi | +//! | B | Base16, Base16-256, Base16-Eighties (dark)†, Base16-Mocha (dark)†, Base16-Ocean (light/dark)† | +//! | C | Coldark (cold/dark aka light/dark) | +//! | D | DarkNeon, Dracula | +//! | G | GitHub, gruvbox (light/dark) | +//! | I | InspiredGitHub† | +//! | M | Monokai Extended (plain, bright, light, and origin) | +//! | N | Nord | +//! | O | One Half (light/dark) | +//! | S | Solarized (light/dark)† | +//! | T | TwoDark | +//! | V | Visual Studio Dark+ | +//! | Z | Zenburn | +//! +//! ## Legal +//! +//! The embedded syntax definitions and assets also have their own licenses which +//! are compiled into +//! [this markdown file](https://github.com/CosmicHorrorDev/two-face/blob/main/generated/acknowledgements_full.md) +//! along with programmatic in the [`acknowledgement`] module #[cfg(doctest)] #[doc = include_str!("../README.md")] diff --git a/tests/docs_watchdog/mod.rs b/tests/docs_watchdog/mod.rs new file mode 100644 index 0000000..a122400 --- /dev/null +++ b/tests/docs_watchdog/mod.rs @@ -0,0 +1 @@ +mod readme; diff --git a/tests/docs_watchdog/readme.rs b/tests/docs_watchdog/readme.rs new file mode 100644 index 0000000..b4ff0ca --- /dev/null +++ b/tests/docs_watchdog/readme.rs @@ -0,0 +1,140 @@ +use std::{collections::BTreeSet, fs}; + +#[test] +fn embedded_asset_sizes() { + #[track_caller] + fn kib(path: &str) -> usize { + let meta = fs::metadata(path).unwrap(); + (meta.len() as f64 / 1_024.0).round() as usize + } + + assert_eq!(10, kib("generated/acknowledgements_full.bin")); + + assert_eq!(867, kib("generated/syntaxes-onig-newlines.bin")); + assert_eq!(812, kib("generated/syntaxes-fancy-newlines.bin")); + + assert_eq!(865, kib("generated/syntaxes-onig-no-newlines.bin")); + assert_eq!(811, kib("generated/syntaxes-fancy-no-newlines.bin")); + + assert_eq!(45, kib("generated/themes.bin")); +} + +#[rustfmt::skip] +const EXPECTED: &[&str] = &[ + // A + "ActionScript", "Ada", "Apache Conf", "AppleScript", "AsciiDoc (Asciidoctor)", + "Assembly (x86_64)", "ASP", "AWK", + // B + "Bourne Again Shell (bash)", "Batch File", "BibTeX", + // C + "C", "C#", "C++", "Cabal", "Clojure", "CMake", "CoffeeScript", "Comma Separated Values", + "Crontab", "Crystal", "CSS", + // D + "D", "Dart", "Diff", "Dockerfile", "DotENV", + // E + "Elixir", "Elm", "Email", "Erlang", + // F + "F#", "Fish", "Fortran (Fixed Form)", + // G + "Git Attributes", "Git Commit", "Git Config", "Git Ignore", "Git Link", "Git Log", + "Git Mailmap", "Git Rebase Todo", + "GLSL", "Go", "GraphQL", "Graphviz (DOT)", "Groff/troff", "Groovy", + // H + "Haskell", "HTML", + // I + "INI", + // J + "Java", "Java Server Page (JSP)", "JavaScript", "Jinja2", "JQ", "JSON", "Julia", + // K + "Kotlin", + // L + "LaTeX", "LaTeX Log", "Lean", "Less", "Lisp", "Literate Haskell", "LLVM", "Lua", + // M + "Makefile", "Manpage", "Markdown", "MATLAB", "MediaWiki", "MultiMarkdown", + // N + "NAnt Build File", "nginx", "Nim", "Ninja", "Nix", + // O + "Objective-C", "Objective-C++", "OCaml", "OCamllex", "OCamlyacc", "orgmode", + // P + "Pascal", "Perl", "PHP", "Protocol Buffer", "Puppet", "PureScript", "Python", + // Q + "QML", + // R + "R", "Racket", "Rd (R Documentation)", "Rego", "Regular Expression", "Requirements.txt", + "reStructuredText", "Robot Framework", "Ruby", "Ruby Haml", "Ruby Slim", "Ruby on Rails", + "Rust", + // S + "Scala", "SCSS", "Solidity", "SML", "SQL", "Strace", "Stylus", "Svelte", "Swift", + "SystemVerilog", + // T + "Tcl", "Terraform", "TeX", "Textile", "Todo.txt", "TOML", "TypeScript", "TypeScriptReact", + // V + "varlink", "Verilog", "VimL", "Vyper", + // X + "XML", + // Y + "YAML", + // Z + "Zig", + + // Not worth displaying in docs + + // Various linux files + "CpuInfo", "fstab", "group", "hosts", "MemInfo", "passwd", "resolv", + // Cmake stuff beyond the base + "CMakeCache", "CMake C Header", "CMake C++ Header", + // Fortran stuff beyond the base + "Fortran (Modern)", "Fortran Namelist", + // Various HTML support for various languages + "HTML (ASP)", "HTML (EEx)", "HTML (Erlang)", "HTML (Jinja2)", "HTML (Rails)", "HTML (Tcl)", + "HTML (Twig)", + // SSH + "Authorized Keys", "Known Hosts", "Private Key", "SSH Config", "SSHD Config", + // Misc + "Java Properties", "JavaScript (Rails)", "jsonnet", "Vue Component", "camlp4", "Plain Text", + "R Console", "SQL (Rails)", "Protocol Buffer (TEXT)", "gnuplot", "HTTP Request and Response", + "log", "syslog", "Highlight non-printables", +]; + +/// Some syntax definitions use regex features that aren't supported by `fancy-regex` +const ONIG_ONLY: &[&str] = &[ + // A + "ARM Assembly", + // J + "JavaScript (Babel)", + // L + "LiveScript", + // P + "PowerShell", + // S + "Salt State (SLS)", + "Sass", + // Misc + "Command Help", + "VimHelp", +]; + +#[test] +fn syntaxes() { + let extra = if cfg!(feature = "syntect-onig") { + ONIG_ONLY.iter() + } else { + [].iter() + }; + let mut expected: BTreeSet<_> = EXPECTED.iter().chain(extra).copied().collect(); + + // Ensure that `expected` perfectly matches non-hidden syntaxes + for syntax in two_face::syntax::extra_newlines().syntaxes() { + if syntax.hidden { + // Not worth listing in documentation + continue; + } + + let name = syntax.name.as_str(); + assert!(expected.remove(name), "Missing syntax: {name}"); + } + assert!( + expected.is_empty(), + "Missing expected syntaxes: {expected:#?}" + ); +} diff --git a/tests/stub.rs b/tests/stub.rs new file mode 100644 index 0000000..71a85c0 --- /dev/null +++ b/tests/stub.rs @@ -0,0 +1 @@ +mod docs_watchdog;