diff --git a/.gitignore b/.gitignore index a23c771e..d89b8266 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,8 @@ test_book/book/ # Ignore Jetbrains specific files. .idea/ +src/theme/syntaxes.bin + # Ignore Vim temporary and swap files. *.sw? *~ diff --git a/Cargo.toml b/Cargo.toml index 3cff6528..6a2f60f8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,10 @@ license = "MPL-2.0" readme = "README.md" repository = "https://github.com/rust-lang/mdBook" description = "Creates a book from markdown files" +build = "build.rs" + +[build-dependencies] +syntect = { version = "4.6.0", default-features = false, features = ["regex-onig", "parsing", "html", "dump-load", "yaml-load", "dump-create", "assets"] } [dependencies] anyhow = "1.0.28" @@ -58,10 +62,11 @@ pretty_assertions = "1.2.1" walkdir = "2.0" [features] -default = ["watch", "serve", "search"] +default = ["watch", "serve", "search", "gen-syntax-cache"] watch = ["notify", "gitignore"] serve = ["futures-util", "tokio", "warp"] search = ["elasticlunr-rs", "ammonia"] +gen-syntax-cache = ["syntect/dump-create"] [[bin]] doc = false diff --git a/build.rs b/build.rs new file mode 100644 index 00000000..60d525b8 --- /dev/null +++ b/build.rs @@ -0,0 +1,18 @@ +use std::env; +use std::error::Error; +use syntect::dumps::dump_to_file; +use syntect::parsing::SyntaxSet; + +pub fn main() -> Result<(), Box> { + let src_dir = format!( + "{}/src/theme/syntaxes/", + env::var("CARGO_MANIFEST_DIR").unwrap() + ); + let dest = format!("{}/syntaxes.bin", env::var("OUT_DIR").unwrap()); + + let mut builder = SyntaxSet::load_defaults_newlines().into_builder(); + builder.add_from_folder(&src_dir, true)?; + dump_to_file(&builder.build(), dest)?; + + Ok(()) +} diff --git a/guide/src/format/theme/syntax-highlighting.md b/guide/src/format/theme/syntax-highlighting.md index f57540f0..32a25930 100644 --- a/guide/src/format/theme/syntax-highlighting.md +++ b/guide/src/format/theme/syntax-highlighting.md @@ -1,6 +1,6 @@ # Syntax Highlighting -mdBook uses [Highlight.js](https://highlightjs.org) with a custom theme +mdBook uses [syntect](https://docs.rs/syntect/4.6.0/syntect/) with a custom theme for syntax highlighting. Automatic language detection has been turned off, so you will probably want to @@ -17,65 +17,103 @@ fn main() { ## Supported languages These languages are supported by default, but you can add more by supplying -your own `highlight.js` file: +your own `.sublime-syntax` file: -- apache -- armasm -- bash -- c -- coffeescript -- cpp -- csharp -- css -- d -- diff -- go -- handlebars -- haskell -- http -- ini -- java -- javascript -- json -- julia -- kotlin -- less -- lua -- makefile -- markdown -- nginx -- objectivec -- perl -- php -- plaintext -- properties -- python -- r -- ruby -- rust -- scala -- scss -- shell -- sql -- swift -- typescript -- x86asm -- xml -- yaml + + + + Name | Extensions + -----|----------- + Plain Text | txt + ASP | asa + HTML (ASP) | asp + ActionScript | as + AppleScript | applescript script editor + Batch File | bat cmd + NAnt Build File | build + C# | cs csx + C++ | cpp cc cp cxx c++ C h hh hpp hxx h++ inl ipp + C | c h + CSS | css css.erb css.liquid + Clojure | clj + D | d di + Diff | diff patch + Erlang | erl hrl Emakefile emakefile + HTML (Erlang) | yaws + Go | go + Graphviz (DOT) | dot DOT gv + Groovy | groovy gvy gradle + HTML | html htm shtml xhtml inc tmpl tpl + Haskell | hs + Literate Haskell | lhs + Java Server Page (JSP) | jsp + Java | java bsh + JavaDoc | + Java Properties | properties + JSON | json sublime-settings sublime-menu sublime-keymap sublime-mousemap sublime-theme sublime-build sublime-project sublime-completions sublime-commands sublime-macro sublime-color-scheme + JavaScript | js htc + Regular Expressions (Javascript) | + BibTeX | bib + LaTeX Log | + LaTeX | tex ltx + TeX | sty cls + Lisp | lisp cl clisp l mud el scm ss lsp fasl + Lua | lua + Make Output | + Makefile | make GNUmakefile makefile Makefile OCamlMakefile mak mk + Markdown | md mdown markdown markdn + MultiMarkdown | + MATLAB | matlab + OCaml | ml mli + OCamllex | mll + OCamlyacc | mly + camlp4 | + Objective-C++ | mm M h + Objective-C | m h + PHP Source | + PHP | php php3 php4 php5 php7 phps phpt phtml + Pascal | pas p dpr + Perl | pl pm pod t PL + Python | py py3 pyw pyi pyx pyx.in pxd pxd.in pxi pxi.in rpy cpy SConstruct Sconstruct sconstruct SConscript gyp gypi Snakefile script + Regular Expressions (Python) | + R Console | + R | R r s S Rprofile + Rd (R Documentation) | rd + HTML (Rails) | rails rhtml erb html.erb + JavaScript (Rails) | js.erb + Ruby Haml | haml sass + Ruby on Rails | rxml builder + SQL (Rails) | erbsql sql.erb + Regular Expression | re + reStructuredText | rst rest + Ruby | rb Appfile Appraisals Berksfile Brewfile capfile cgi Cheffile config.ru Deliverfile Fastfile fcgi Gemfile gemspec Guardfile irbrc jbuilder podspec prawn rabl rake Rakefile Rantfile rbx rjs ruby.rail Scanfile simplecov Snapfile thor Thorfile Vagrantfile + Cargo Build Results | + Rust | rs + SQL | sql ddl dml + Scala | scala sbt + Bourne Again Shell (bash) | sh bash zsh fish .bash_aliases .bash_completions .bash_functions .bash_login .bash_logout .bash_profile .bash_variables .bashrc .profile .textmate_init + Shell-Unix-Generic | + commands-builtin-shell-bash | + HTML (Tcl) | adp + Tcl | tcl + Textile | textile + XML | xml xsd xslt tld dtml rss opml svg + YAML | yaml yml sublime-syntax + Handlebars | handlebars handlebars.html hbr hbrs hbs hdbs hjs mu mustache rac stache template tmpl] ## Custom theme -Like the rest of the theme, the files used for syntax highlighting can be -overridden with your own. -- ***highlight.js*** normally you shouldn't have to overwrite this file, unless - you want to use a more recent version. -- ***highlight.css*** theme used by highlight.js for syntax highlighting. +Use the `gen-syntax-cache` command to compile sublime text syntax definitions and textmate theme files for mdbook. -If you want to use another theme for `highlight.js` download it from their -website, or make it yourself, rename it to `highlight.css` and put it in -the `theme` folder of your book. + mdbook gen-syntax-cache --dest-dir=./theme ./syntax -Now your theme will be used instead of the default theme. +The `gen-syntax-cache` will process every `tmTheme` file, and generate a similarly-named file in `[dest-dir]/css/syntax`, +and will also process every `sublime-syntax` file and add it to the `syntaxes.bin` cache. When building your book, +mdBook will look in the ./theme directory for the `syntaxes.bin` cache and use it, and will also copy across the generated +CSS files. + +mdBook includes, by default, the above standard syntax definitions when generating the `syntaxes.bin` cache. If you want to +override all of the syntax definitions, pass the `--no-default-syntaxes` option. ## Hiding code lines diff --git a/src/cmd/gen_syntax_cache.rs b/src/cmd/gen_syntax_cache.rs new file mode 100644 index 00000000..a4c47d6a --- /dev/null +++ b/src/cmd/gen_syntax_cache.rs @@ -0,0 +1,97 @@ +use clap::{App, ArgMatches, SubCommand}; +use mdbook::errors::Result; +use std::env; +use std::io::Cursor; +use syntect::dumps::dump_to_file; +use syntect::highlighting::ThemeSet; +use syntect::html::css_for_theme_with_class_style; +use syntect::html::ClassStyle; +use syntect::parsing::{SyntaxSet, SyntaxSetBuilder}; + +// Create clap subcommand arguments +pub fn make_subcommand<'a, 'b>() -> App<'a, 'b> { + SubCommand::with_name("gen-syntax-cache") + .about("Generate syntaxes.bin and css/syntax") + .arg_from_usage( + "-d, --dest-dir=[dir] 'Output directory for the syntax cache{n}\ + Relative paths are interpreted relative to the current working directory.{n}\ + If omitted, mdBook uses `.`. + This command outputs files [dir]/syntaxes.bin and [dir]/css/syntax/*.css'", + ) + .arg_from_usage("--syntaxes-only 'Only generate syntaxes.bin, not css/syntax/*.css.'") + .arg_from_usage( + "--no-default-syntaxes 'Don't include Sublime Text's default open source syntaxes{n}\ + If included, only syntaxes from [dir] are used.'", + ) + .arg_from_usage("--themes-only 'Only generate themes, not syntaxes.bin.'") + .arg_from_usage( + "--no-default-themes 'Don't include mdbook's default light, dark, and ayu themes{n}\ + If included, only themes from [dir] are used.'", + ) + .arg_from_usage( + "[dir] 'Root directory for the syntax sources{n}\ + (Defaults to the Current Directory when omitted)'", + ) +} + +// Generate Syntax Cache command implementation +pub fn execute(args: &ArgMatches) -> Result<()> { + let src_dir = env::current_dir() + .unwrap() + .join(&format!("{}/", args.value_of("dir").unwrap_or("."))); + let dest_dir = env::current_dir() + .unwrap() + .join(&format!("{}/", args.value_of("dest-dir").unwrap_or("."))); + + if !args.is_present("themes-only") { + let mut builder = if args.is_present("no-default-syntaxes") { + SyntaxSetBuilder::new() + } else { + syntect::dumps::from_binary::(mdbook::theme::SYNTAXES_BIN).into_builder() + }; + builder.add_from_folder(&src_dir, true)?; + let set = builder.build(); + for syntax in set.syntaxes() { + info!( + "supports syntax: {} [{}]", + syntax.name, + syntax.file_extensions.join(" ") + ); + } + dump_to_file(&set, dest_dir.join("syntaxes.bin"))?; + } + + if !args.is_present("syntaxes-only") { + let mut builder = ThemeSet::load_from_folder(&src_dir)?; + if !args.is_present("no-default-themes") { + if !builder.themes.contains_key("light") { + let light = ThemeSet::load_from_reader(&mut Cursor::new( + mdbook::theme::SYNTAX_THEME_LIGHT, + ))?; + builder.themes.insert(String::from("light"), light); + } + if !builder.themes.contains_key("dark") { + let dark = + ThemeSet::load_from_reader(&mut Cursor::new(mdbook::theme::SYNTAX_THEME_DARK))?; + builder.themes.insert(String::from("dark"), dark); + } + if !builder.themes.contains_key("ayu") { + let ayu = + ThemeSet::load_from_reader(&mut Cursor::new(mdbook::theme::SYNTAX_THEME_AYU))?; + builder.themes.insert(String::from("ayu"), ayu); + } + } + for (name, theme) in builder.themes.iter() { + info!("supports theme: {}", name); + std::fs::write( + dest_dir.join(format!("css/syntax/{}.css", name)), + css_for_theme_with_class_style( + theme, + ClassStyle::SpacedPrefixed { prefix: "syn-" }, + ), + )?; + } + } + + Ok(()) +} diff --git a/src/cmd/mod.rs b/src/cmd/mod.rs index c5b6730f..27229b28 100644 --- a/src/cmd/mod.rs +++ b/src/cmd/mod.rs @@ -2,6 +2,8 @@ pub mod build; pub mod clean; +#[cfg(feature = "gen-syntax-cache")] +pub mod gen_syntax_cache; pub mod init; #[cfg(feature = "serve")] pub mod serve; diff --git a/src/main.rs b/src/main.rs index 35562e64..393f3d8e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -35,6 +35,9 @@ fn main() { Some(("serve", sub_matches)) => cmd::serve::execute(sub_matches), Some(("test", sub_matches)) => cmd::test::execute(sub_matches), Some(("completions", sub_matches)) => (|| { + #[cfg(feature = "gen_syntax_cache")] + ("gen-syntax-cache", Some(sub_matches)) => cmd::gen_syntax_cache::execute(sub_matches), + ("completions", Some(sub_matches)) => (|| { let shell: Shell = sub_matches .value_of("shell") .ok_or_else(|| anyhow!("Shell name missing."))? @@ -93,6 +96,8 @@ fn create_clap_app() -> App<'static> { let app = app.subcommand(cmd::watch::make_subcommand()); #[cfg(feature = "serve")] let app = app.subcommand(cmd::serve::make_subcommand()); + #[cfg(feature = "gen-syntax-cache")] + let app = app.subcommand(cmd::gen_syntax_cache::make_subcommand()); app } diff --git a/src/theme/css/syntax/ayu.css b/src/theme/css/syntax/ayu.css index aa8b26e5..5eafbdcf 100644 --- a/src/theme/css/syntax/ayu.css +++ b/src/theme/css/syntax/ayu.css @@ -1,412 +1,151 @@ /* - * theme "ayu" generated by syntect - * based off of Ayu by Dempfi - * https://github.com/dempfi/ayu/blob/master/ayu-dark.sublime-color-scheme + * theme "Base16 Tomorrow Night" generated by syntect */ .syn-code { - color: #b3b1ad; - background-color: #0a0e14; + color: #c5c8c6; + background-color: #1d1f21; } -.syn-comment { - color: #626a73; -font-style: italic; +.syn-variable.syn-parameter.syn-function { + color: #c5c8c6; } -.syn-string { - color: #c2d94c; +.syn-comment, .syn-punctuation.syn-definition.syn-comment { + color: #969896; } -.syn-constant.syn-other.syn-symbol { - color: #c2d94c; +.syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-variable, .syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-parameters, .syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-array { + color: #c5c8c6; } -.syn-string.syn-regexp { - color: #95e6cb; -} -.syn-constant.syn-character { - color: #95e6cb; -} -.syn-constant.syn-other { - color: #95e6cb; -} -.syn-constant.syn-numeric { - color: #e6b450; -} -.syn-constant.syn-language { - color: #e6b450; -} -.syn-meta.syn-constant { - color: #ffee99; -} -.syn-entity.syn-name.syn-constant { - color: #ffee99; -} -.syn-variable { - color: #b3b1ad; -} -.syn-variable.syn-member { - color: #f07178; -} -.syn-variable.syn-language { - color: #39bae6; -font-style: italic; -} -.syn-storage { - color: #ff8f40; -} -.syn-storage.syn-type.syn-keyword { - color: #ff8f40; -} -.syn-keyword { - color: #ff8f40; -} -.syn-source.syn-java { - color: #ff8f40; -} -.syn-meta.syn-class.syn-java { - color: #ff8f40; -} -.syn-meta.syn-class.syn-identifier.syn-java { - color: #ff8f40; -} -.syn-storage.syn-type.syn-java { - color: #ff8f40; +.syn-none { + color: #c5c8c6; } .syn-keyword.syn-operator { - color: #f29668; + color: #c5c8c6; } -.syn-punctuation.syn-separator { - color: #b3b1ad; +.syn-keyword { + color: #b294bb; } -.syn-punctuation.syn-terminator { - color: #b3b1ad; +.syn-variable { + color: #cc6666; } -.syn-punctuation.syn-section { - color: #b3b1ad; +.syn-entity.syn-name.syn-function, .syn-meta.syn-require, .syn-support.syn-function.syn-any-method { + color: #81a2be; } -.syn-punctuation.syn-accessor { - color: #f29668; +.syn-entity.syn-name.syn-label { + color: #a3685a; } -.syn-source.syn-java { - color: #59c2ff; +.syn-support.syn-class, .syn-entity.syn-name.syn-class, .syn-entity.syn-name.syn-type.syn-class { + color: #f0c674; } -.syn-storage.syn-type { - color: #59c2ff; +.syn-meta.syn-class { + color: #ffffff; } -.syn-source.syn-haskell { - color: #59c2ff; +.syn-keyword.syn-other.syn-special-method { + color: #81a2be; } -.syn-storage.syn-type { - color: #59c2ff; -} -.syn-source.syn-c { - color: #59c2ff; -} -.syn-storage.syn-type { - color: #59c2ff; -} -.syn-entity.syn-other.syn-inherited-class { - color: #39bae6; -} -.syn-storage.syn-type.syn-function { - color: #ff8f40; -} -.syn-source.syn-java { - color: #39bae6; -} -.syn-storage.syn-type.syn-primitive { - color: #39bae6; -} -.syn-entity.syn-name.syn-function { - color: #ffb454; -} -.syn-variable.syn-parameter { - color: #ffee99; -} -.syn-meta.syn-parameter { - color: #ffee99; -} -.syn-variable.syn-function { - color: #ffb454; -} -.syn-variable.syn-annotation { - color: #ffb454; -} -.syn-meta.syn-function-call.syn-generic { - color: #ffb454; -} -.syn-support.syn-function.syn-go { - color: #ffb454; +.syn-storage { + color: #b294bb; } .syn-support.syn-function { - color: #f07178; + color: #8abeb7; } -.syn-support.syn-macro { - color: #f07178; +.syn-string, .syn-constant.syn-other.syn-symbol, .syn-entity.syn-other.syn-inherited-class { + color: #b5bd68; } -.syn-entity.syn-name.syn-import { - color: #c2d94c; +.syn-constant.syn-numeric { + color: #de935f; } -.syn-entity.syn-name.syn-package { - color: #c2d94c; +.syn-none { + color: #de935f; } -.syn-entity.syn-name { - color: #59c2ff; +.syn-none { + color: #de935f; } -.syn-source.syn-js { - color: #59c2ff; -} -.syn-meta.syn-function-call.syn-constructor { - color: #59c2ff; -} -.syn-variable.syn-type { - color: #59c2ff; +.syn-constant { + color: #de935f; } .syn-entity.syn-name.syn-tag { - color: #39bae6; -} -.syn-meta.syn-tag.syn-sgml { - color: #39bae6; -} -.syn-punctuation.syn-definition.syn-tag.syn-end { - color: #39bae6; -} -.syn-punctuation.syn-definition.syn-tag.syn-begin { - color: #39bae6; -} -.syn-punctuation.syn-definition.syn-tag { - color: #39bae6; + color: #cc6666; } .syn-entity.syn-other.syn-attribute-name { - color: #ffb454; + color: #de935f; } -.syn-support.syn-constant { - color: #f29668; +.syn-entity.syn-other.syn-attribute-name.syn-id, .syn-punctuation.syn-definition.syn-entity { + color: #81a2be; +} +.syn-meta.syn-selector { + color: #b294bb; +} +.syn-none { + color: #de935f; +} +.syn-markup.syn-heading .syn-punctuation.syn-definition.syn-heading, .syn-entity.syn-name.syn-section { + color: #81a2be; +} +.syn-keyword.syn-other.syn-unit { + color: #de935f; +} +.syn-markup.syn-bold, .syn-punctuation.syn-definition.syn-bold { + color: #f0c674; +font-weight: bold; +} +.syn-markup.syn-italic, .syn-punctuation.syn-definition.syn-italic { + color: #b294bb; font-style: italic; } -.syn-support.syn-type { - color: #39bae6; -} -.syn-support.syn-class { - color: #39bae6; -} -.syn-source.syn-go { - color: #39bae6; -} -.syn-storage.syn-type { - color: #39bae6; -} -.syn-meta.syn-decorator { - color: #e6b673; -} -.syn-variable.syn-other { - color: #e6b673; -} -.syn-meta.syn-decorator { - color: #e6b673; -} -.syn-punctuation.syn-decorator { - color: #e6b673; -} -.syn-storage.syn-type.syn-annotation { - color: #e6b673; -} -.syn-variable.syn-annotation { - color: #e6b673; -} -.syn-punctuation.syn-definition.syn-annotation { - color: #e6b673; -} -.syn-invalid { - color: #ff3333; -} -.syn-meta.syn-diff { - color: #c594c5; -} -.syn-meta.syn-diff.syn-header { - color: #c594c5; -} -.syn-source.syn-ruby { - color: #ffb454; -} -.syn-variable.syn-other.syn-readwrite { - color: #ffb454; -} -.syn-source.syn-css { - color: #59c2ff; -} -.syn-entity.syn-name.syn-tag { - color: #59c2ff; -} -.syn-source.syn-sass { - color: #59c2ff; -} -.syn-entity.syn-name.syn-tag { - color: #59c2ff; -} -.syn-source.syn-scss { - color: #59c2ff; -} -.syn-entity.syn-name.syn-tag { - color: #59c2ff; -} -.syn-source.syn-less { - color: #59c2ff; -} -.syn-entity.syn-name.syn-tag { - color: #59c2ff; -} -.syn-source.syn-stylus { - color: #59c2ff; -} -.syn-entity.syn-name.syn-tag { - color: #59c2ff; -} -.syn-source.syn-css { - color: #626a73; -} -.syn-support.syn-type { - color: #626a73; -} -.syn-source.syn-sass { - color: #626a73; -} -.syn-support.syn-type { - color: #626a73; -} -.syn-source.syn-scss { - color: #626a73; -} -.syn-support.syn-type { - color: #626a73; -} -.syn-source.syn-less { - color: #626a73; -} -.syn-support.syn-type { - color: #626a73; -} -.syn-source.syn-stylus { - color: #626a73; -} -.syn-support.syn-type { - color: #626a73; -} -.syn-support.syn-type.syn-property-name { - color: #39bae6; -} -.syn-constant.syn-numeric.syn-line-number.syn-find-in-files { - color: #626a73; -} -.syn-constant.syn-numeric.syn-line-number.syn-match { - color: #ff8f40; -} -.syn-entity.syn-name.syn-filename.syn-find-in-files { - color: #c2d94c; -} -.syn-message.syn-error { - color: #ff3333; -} -.syn-markup.syn-heading { - color: #c2d94c; -font-weight: bold; -} -.syn-markup.syn-heading { - color: #c2d94c; -font-weight: bold; -} -.syn-entity.syn-name { - color: #c2d94c; -font-weight: bold; -} -.syn-markup.syn-underline.syn-link { - color: #39bae6; -} -.syn-string.syn-other.syn-link { - color: #39bae6; -} -.syn-markup.syn-italic { - color: #f07178; -font-style: italic; -} -.syn-markup.syn-bold { - color: #f07178; -font-weight: bold; -} -.syn-markup.syn-italic { -font-weight: bold; -font-style: italic; -} -.syn-markup.syn-bold { -font-weight: bold; -font-style: italic; -} -.syn-markup.syn-bold { -font-weight: bold; -font-style: italic; -} -.syn-markup.syn-italic { -font-weight: bold; -font-style: italic; -} -.syn-markup.syn-raw { - background: #191f26; -} .syn-markup.syn-raw.syn-inline { - background: #191f26; + color: #b5bd68; } -.syn-meta.syn-separator { - color: #626a73; - background-color: #b3b1ad; -font-weight: bold; +.syn-string.syn-other.syn-link, .syn-punctuation.syn-definition.syn-string.syn-end.syn-markdown, .syn-punctuation.syn-definition.syn-string.syn-begin.syn-markdown { + color: #cc6666; } -.syn-markup.syn-quote { - color: #95e6cb; -font-style: italic; +.syn-meta.syn-link { + color: #de935f; } .syn-markup.syn-list { - color: #ffb454; + color: #cc6666; } -.syn-punctuation.syn-definition.syn-list.syn-begin { - color: #ffb454; +.syn-markup.syn-quote { + color: #de935f; +} +.syn-meta.syn-separator { + color: #c5c8c6; + background-color: #373b41; } .syn-markup.syn-inserted { - color: #91b362; -} -.syn-markup.syn-changed { - color: #6994bf; + color: #b5bd68; } .syn-markup.syn-deleted { - color: #d96c75; + color: #cc6666; } -.syn-markup.syn-strike { - color: #e6b673; +.syn-markup.syn-changed { + color: #b294bb; } -.syn-markup.syn-table { - color: #39bae6; - background-color: #b3b1ad; +.syn-constant.syn-other.syn-color { + color: #8abeb7; } -.syn-text.syn-html.syn-markdown { - color: #f29668; +.syn-string.syn-regexp { + color: #8abeb7; } -.syn-markup.syn-inline.syn-raw { - color: #f29668; +.syn-constant.syn-character.syn-escape { + color: #8abeb7; } -.syn-text.syn-html.syn-markdown { - color: #626a73; - background-color: #626a73; +.syn-punctuation.syn-section.syn-embedded, .syn-variable.syn-interpolation { + color: #b294bb; } -.syn-meta.syn-dummy.syn-line-break { - color: #626a73; - background-color: #626a73; +.syn-invalid.syn-illegal { + color: #ffffff; + background-color: #cc6666; } -.syn-punctuation.syn-definition.syn-markdown { - color: #626a73; - background-color: #b3b1ad; +.syn-invalid.syn-broken { + color: #1d1f21; + background-color: #de935f; +} +.syn-invalid.syn-deprecated { + color: #ffffff; + background-color: #a3685a; +} +.syn-invalid.syn-unimplemented { + color: #ffffff; + background-color: #969896; } -.scode { - display: block; - overflow-x: auto; - background: #191f26; - color: #e6e1cf; - padding: 0.5em; -} \ No newline at end of file diff --git a/src/theme/css/syntax/dark.css b/src/theme/css/syntax/dark.css index 9c60c111..5eafbdcf 100644 --- a/src/theme/css/syntax/dark.css +++ b/src/theme/css/syntax/dark.css @@ -1,222 +1,151 @@ -* theme "Base16 Tomorrow Night" generated by syntect -* based off of Base16 Tomorrow Night by Chris Kempson -* https://github.com/chriskempson/base16-textmate/blob/master/Themes/base16-tomorrow-night.tmTheme -*/ +/* + * theme "Base16 Tomorrow Night" generated by syntect + */ .syn-code { -color: #c5c8c6; -background-color: #1d1f21; + color: #c5c8c6; + background-color: #1d1f21; } .syn-variable.syn-parameter.syn-function { -color: #c5c8c6; + color: #c5c8c6; } -.syn-comment { -color: #969896; +.syn-comment, .syn-punctuation.syn-definition.syn-comment { + color: #969896; } -.syn-punctuation.syn-definition.syn-comment { -color: #969896; -} -.syn-punctuation.syn-definition.syn-string { -color: #c5c8c6; -} -.syn-punctuation.syn-definition.syn-variable { -color: #c5c8c6; -} -.syn-punctuation.syn-definition.syn-string { -color: #c5c8c6; -} -.syn-punctuation.syn-definition.syn-parameters { -color: #c5c8c6; -} -.syn-punctuation.syn-definition.syn-string { -color: #c5c8c6; -} -.syn-punctuation.syn-definition.syn-array { -color: #c5c8c6; +.syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-variable, .syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-parameters, .syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-array { + color: #c5c8c6; } .syn-none { -color: #c5c8c6; + color: #c5c8c6; } .syn-keyword.syn-operator { -color: #c5c8c6; + color: #c5c8c6; } .syn-keyword { -color: #b294bb; + color: #b294bb; } .syn-variable { -color: #cc6666; + color: #cc6666; } -.syn-entity.syn-name.syn-function { -color: #81a2be; -} -.syn-meta.syn-require { -color: #81a2be; -} -.syn-support.syn-function.syn-any-method { -color: #81a2be; +.syn-entity.syn-name.syn-function, .syn-meta.syn-require, .syn-support.syn-function.syn-any-method { + color: #81a2be; } .syn-entity.syn-name.syn-label { -color: #a3685a; + color: #a3685a; } -.syn-support.syn-class { -color: #f0c674; -} -.syn-entity.syn-name.syn-class { -color: #f0c674; -} -.syn-entity.syn-name.syn-type.syn-class { -color: #f0c674; +.syn-support.syn-class, .syn-entity.syn-name.syn-class, .syn-entity.syn-name.syn-type.syn-class { + color: #f0c674; } .syn-meta.syn-class { -color: #ffffff; + color: #ffffff; } .syn-keyword.syn-other.syn-special-method { -color: #81a2be; + color: #81a2be; } .syn-storage { -color: #b294bb; + color: #b294bb; } .syn-support.syn-function { -color: #8abeb7; + color: #8abeb7; } -.syn-string { -color: #b5bd68; -} -.syn-constant.syn-other.syn-symbol { -color: #b5bd68; -} -.syn-entity.syn-other.syn-inherited-class { -color: #b5bd68; +.syn-string, .syn-constant.syn-other.syn-symbol, .syn-entity.syn-other.syn-inherited-class { + color: #b5bd68; } .syn-constant.syn-numeric { -color: #de935f; + color: #de935f; } .syn-none { -color: #de935f; + color: #de935f; } .syn-none { -color: #de935f; + color: #de935f; } .syn-constant { -color: #de935f; + color: #de935f; } .syn-entity.syn-name.syn-tag { -color: #cc6666; + color: #cc6666; } .syn-entity.syn-other.syn-attribute-name { -color: #de935f; + color: #de935f; } -.syn-entity.syn-other.syn-attribute-name.syn-id { -color: #81a2be; -} -.syn-punctuation.syn-definition.syn-entity { -color: #81a2be; +.syn-entity.syn-other.syn-attribute-name.syn-id, .syn-punctuation.syn-definition.syn-entity { + color: #81a2be; } .syn-meta.syn-selector { -color: #b294bb; + color: #b294bb; } .syn-none { -color: #de935f; + color: #de935f; } -.syn-markup.syn-heading { -color: #81a2be; -} -.syn-punctuation.syn-definition.syn-heading { -color: #81a2be; -} -.syn-entity.syn-name.syn-section { -color: #81a2be; +.syn-markup.syn-heading .syn-punctuation.syn-definition.syn-heading, .syn-entity.syn-name.syn-section { + color: #81a2be; } .syn-keyword.syn-other.syn-unit { -color: #de935f; + color: #de935f; } -.syn-markup.syn-bold { -color: #f0c674; +.syn-markup.syn-bold, .syn-punctuation.syn-definition.syn-bold { + color: #f0c674; font-weight: bold; } -.syn-punctuation.syn-definition.syn-bold { -color: #f0c674; -font-weight: bold; -} -.syn-markup.syn-italic { -color: #b294bb; -font-style: italic; -} -.syn-punctuation.syn-definition.syn-italic { -color: #b294bb; +.syn-markup.syn-italic, .syn-punctuation.syn-definition.syn-italic { + color: #b294bb; font-style: italic; } .syn-markup.syn-raw.syn-inline { -color: #b5bd68; + color: #b5bd68; } -.syn-string.syn-other.syn-link { -color: #cc6666; -} -.syn-punctuation.syn-definition.syn-string.syn-end.syn-markdown { -color: #cc6666; -} -.syn-punctuation.syn-definition.syn-string.syn-begin.syn-markdown { -color: #cc6666; +.syn-string.syn-other.syn-link, .syn-punctuation.syn-definition.syn-string.syn-end.syn-markdown, .syn-punctuation.syn-definition.syn-string.syn-begin.syn-markdown { + color: #cc6666; } .syn-meta.syn-link { -color: #de935f; + color: #de935f; } .syn-markup.syn-list { -color: #cc6666; + color: #cc6666; } .syn-markup.syn-quote { -color: #de935f; + color: #de935f; } .syn-meta.syn-separator { -color: #c5c8c6; -background-color: #373b41; + color: #c5c8c6; + background-color: #373b41; } .syn-markup.syn-inserted { -color: #b5bd68; + color: #b5bd68; } .syn-markup.syn-deleted { -color: #cc6666; + color: #cc6666; } .syn-markup.syn-changed { -color: #b294bb; + color: #b294bb; } .syn-constant.syn-other.syn-color { -color: #8abeb7; + color: #8abeb7; } .syn-string.syn-regexp { -color: #8abeb7; + color: #8abeb7; } .syn-constant.syn-character.syn-escape { -color: #8abeb7; + color: #8abeb7; } -.syn-punctuation.syn-section.syn-embedded { -color: #b294bb; -} -.syn-variable.syn-interpolation { -color: #b294bb; +.syn-punctuation.syn-section.syn-embedded, .syn-variable.syn-interpolation { + color: #b294bb; } .syn-invalid.syn-illegal { -color: #ffffff; -background-color: #cc6666; + color: #ffffff; + background-color: #cc6666; } .syn-invalid.syn-broken { -color: #1d1f21; -background-color: #de935f; + color: #1d1f21; + background-color: #de935f; } .syn-invalid.syn-deprecated { -color: #ffffff; -background-color: #a3685a; + color: #ffffff; + background-color: #a3685a; } .syn-invalid.syn-unimplemented { -color: #ffffff; -background-color: #969896; + color: #ffffff; + background-color: #969896; } -.scode { -display: block; -overflow-x: auto; -background: #1d1f21; -color: #c5c8c6; -padding: 0.5em; --webkit-text-size-adjust: none; -} \ No newline at end of file diff --git a/src/theme/css/syntax/light.css b/src/theme/css/syntax/light.css index d8af4090..ec72e9d5 100644 --- a/src/theme/css/syntax/light.css +++ b/src/theme/css/syntax/light.css @@ -1,215 +1,148 @@ /* -* theme "Base16 Atelier Dune Light" generated by syntect -* Based off of the "Base16 Atelier Dune Light" theme by Bram de Haan -* (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) -* Original Base16 color scheme by Chris Kempson -* (https://github.com/chriskempson/base16) -*/ + * theme "Base16 Atelier Dune Light" generated by syntect + */ .syn-code { -color: #6e6b5e; -background-color: #fefbec; + color: #6e6b5e; + background-color: #fefbec; } .syn-variable.syn-parameter.syn-function { -color: #6e6b5e; + color: #6e6b5e; } -.syn-comment { -color: #999580; +.syn-comment, .syn-punctuation.syn-definition.syn-comment { + color: #999580; } -.syn-punctuation.syn-definition.syn-comment { -color: #999580; -} -.syn-punctuation.syn-definition.syn-string { -color: #6e6b5e; -} -.syn-punctuation.syn-definition.syn-variable { -color: #6e6b5e; -} -.syn-punctuation.syn-definition.syn-string { -color: #6e6b5e; -} -.syn-punctuation.syn-definition.syn-parameters { -color: #6e6b5e; -} -.syn-punctuation.syn-definition.syn-string { -color: #6e6b5e; -} -.syn-punctuation.syn-definition.syn-array { -color: #6e6b5e; +.syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-variable, .syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-parameters, .syn-punctuation.syn-definition.syn-string, .syn-punctuation.syn-definition.syn-array { + color: #6e6b5e; } .syn-none { -color: #6e6b5e; + color: #6e6b5e; } .syn-keyword.syn-operator { -color: #6e6b5e; + color: #6e6b5e; } .syn-keyword { -color: #b854d4; + color: #b854d4; } .syn-variable { -color: #d73737; + color: #d73737; } -.syn-entity.syn-name.syn-function { -color: #6684e1; +.syn-entity.syn-name.syn-function, .syn-meta.syn-require, .syn-support.syn-function.syn-any-method { + color: #6684e1; } -.syn-meta.syn-require { -color: #6684e1; -} -.syn-support.syn-function.syn-any-method { -color: #6684e1; -} -.syn-support.syn-class { -color: #b65611; -} -.syn-entity.syn-name.syn-class { -color: #b65611; -} -.syn-entity.syn-name.syn-type.syn-class { -color: #b65611; +.syn-support.syn-class, .syn-entity.syn-name.syn-class, .syn-entity.syn-name.syn-type.syn-class { + color: #b65611; } .syn-meta.syn-class { -color: #292824; + color: #292824; } .syn-keyword.syn-other.syn-special-method { -color: #6684e1; + color: #6684e1; } .syn-storage { -color: #b854d4; + color: #b854d4; } .syn-support.syn-function { -color: #1fad83; + color: #1fad83; } -.syn-string { -color: #60ac39; -} -.syn-constant.syn-other.syn-symbol { -color: #60ac39; -} -.syn-entity.syn-other.syn-inherited-class { -color: #60ac39; +.syn-string, .syn-constant.syn-other.syn-symbol, .syn-entity.syn-other.syn-inherited-class { + color: #60ac39; } .syn-constant.syn-numeric { -color: #b65611; + color: #b65611; } .syn-none { -color: #b65611; + color: #b65611; } .syn-none { -color: #b65611; + color: #b65611; } .syn-constant { -color: #b65611; + color: #b65611; } .syn-entity.syn-name.syn-tag { -color: #d73737; + color: #d73737; } .syn-entity.syn-other.syn-attribute-name { -color: #b65611; + color: #b65611; } -.syn-entity.syn-other.syn-attribute-name.syn-id { -color: #6684e1; -} -.syn-punctuation.syn-definition.syn-entity { -color: #6684e1; +.syn-entity.syn-other.syn-attribute-name.syn-id, .syn-punctuation.syn-definition.syn-entity { + color: #6684e1; } .syn-meta.syn-selector { -color: #b854d4; + color: #b854d4; } .syn-none { -color: #b65611; + color: #b65611; } -.syn-markup.syn-heading { -color: #6684e1; -} -.syn-punctuation.syn-definition.syn-heading { -color: #6684e1; -} -.syn-entity.syn-name.syn-section { -color: #6684e1; +.syn-markup.syn-heading .syn-punctuation.syn-definition.syn-heading, .syn-entity.syn-name.syn-section { + color: #6684e1; } .syn-keyword.syn-other.syn-unit { -color: #b65611; + color: #b65611; } -.syn-markup.syn-bold { -color: #b65611; +.syn-markup.syn-bold, .syn-punctuation.syn-definition.syn-bold { + color: #b65611; font-weight: bold; } -.syn-punctuation.syn-definition.syn-bold { -color: #b65611; -font-weight: bold; -} -.syn-markup.syn-italic { -color: #b854d4; -font-style: italic; -} -.syn-punctuation.syn-definition.syn-italic { -color: #b854d4; +.syn-markup.syn-italic, .syn-punctuation.syn-definition.syn-italic { + color: #b854d4; font-style: italic; } .syn-markup.syn-raw.syn-inline { -color: #60ac39; + color: #60ac39; } .syn-string.syn-other.syn-link { -color: #d73737; + color: #d73737; } .syn-meta.syn-link { -color: #b65611; + color: #b65611; } .syn-markup.syn-list { -color: #d73737; + color: #d73737; } .syn-markup.syn-quote { -color: #b65611; + color: #b65611; } .syn-meta.syn-separator { -color: #6e6b5e; -background-color: #e8e4cf; + color: #6e6b5e; + background-color: #e8e4cf; } .syn-markup.syn-inserted { -color: #60ac39; + color: #60ac39; } .syn-markup.syn-deleted { -color: #d73737; + color: #d73737; } .syn-markup.syn-changed { -color: #b854d4; + color: #b854d4; } .syn-constant.syn-other.syn-color { -color: #1fad83; + color: #1fad83; } .syn-string.syn-regexp { -color: #1fad83; + color: #1fad83; } .syn-constant.syn-character.syn-escape { -color: #1fad83; + color: #1fad83; } -.syn-punctuation.syn-section.syn-embedded { -color: #d43552; -} -.syn-variable.syn-interpolation { -color: #d43552; +.syn-punctuation.syn-section.syn-embedded, .syn-variable.syn-interpolation { + color: #d43552; } .syn-invalid.syn-illegal { -color: #fefbec; -background-color: #d73737; + color: #fefbec; + background-color: #d73737; } .syn-invalid.syn-broken { -color: #20201d; -background-color: #b65611; + color: #20201d; + background-color: #b65611; } .syn-invalid.syn-deprecated { -color: #fefbec; -background-color: #d43552; + color: #fefbec; + background-color: #d43552; } .syn-invalid.syn-unimplemented { -color: #20201d; -background-color: #a6a28c; + color: #20201d; + background-color: #a6a28c; } -.scode { -display: block; -overflow-x: auto; -background: #f6f7f6; -color: #000; -padding: 0.5em; -} \ No newline at end of file diff --git a/src/theme/mod.rs b/src/theme/mod.rs index 2c4425e4..df3d53de 100644 --- a/src/theme/mod.rs +++ b/src/theme/mod.rs @@ -36,7 +36,10 @@ pub static FONT_AWESOME_WOFF: &[u8] = include_bytes!("FontAwesome/fonts/fontawes pub static FONT_AWESOME_WOFF2: &[u8] = include_bytes!("FontAwesome/fonts/fontawesome-webfont.woff2"); pub static FONT_AWESOME_OTF: &[u8] = include_bytes!("FontAwesome/fonts/FontAwesome.otf"); -pub static SYNTAXES_BIN: &[u8] = include_bytes!("syntaxes.bin"); +pub static SYNTAXES_BIN: &[u8] = include_bytes!(concat!(env!("OUT_DIR"), "/syntaxes.bin")); +pub static SYNTAX_THEME_LIGHT: &[u8] = include_bytes!("syntax-themes/light.tmTheme"); +pub static SYNTAX_THEME_DARK: &[u8] = include_bytes!("syntax-themes/dark.tmTheme"); +pub static SYNTAX_THEME_AYU: &[u8] = include_bytes!("syntax-themes/ayu.tmTheme"); /// The `Theme` struct should be used instead of the static variables because /// the `new()` method will look if the user has a theme directory in their diff --git a/src/theme/syntax-themes/README.md b/src/theme/syntax-themes/README.md new file mode 100644 index 00000000..84131f72 --- /dev/null +++ b/src/theme/syntax-themes/README.md @@ -0,0 +1,17 @@ +dark.tmTheme is from https://github.com/chriskempson/base16-textmate/blob/master/Themes/base16-tomorrow-night.tmTheme + +ayu.tmTheme is a tweaked version of the dark theme + +light.tmTheme is from https://github.com/atelierbram/syntax-highlighting/blob/master/docs/archive/atelier-schemes/output/textmate/base16-atelierdune.light.tmTheme which is described at https://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune/ + +This folder is not copied over to the book directory when using `mdbook init`, nor is it indexed at runtime. To modify the themes, modify the tmTheme file, then run: + +```shell +$ cargo run -- gen-syntax-cache --themes-only --no-default-themes --dest-dir=.. +``` + +The `--no-default-themes` flag is added because the whole point is to *not* use the ones embedded in the mdbook binary. + +Now, you may rebuild the `mdbook` binary and the new themes should be included. + +This only needs to be run when the themes in this folder are updated. diff --git a/src/theme/syntax-themes/ayu.tmTheme b/src/theme/syntax-themes/ayu.tmTheme new file mode 100644 index 00000000..b25c81db --- /dev/null +++ b/src/theme/syntax-themes/ayu.tmTheme @@ -0,0 +1,560 @@ + + + + + author + Template: Chris Kempson, Scheme: Chris Kempson (http://chriskempson.com) + name + Base16 Tomorrow Night + semanticClass + theme.base16.tomorrow-night + colorSpaceName + sRGB + gutterSettings + + background + #282a2e + divider + #282a2e + foreground + #969896 + selectionBackground + #373b41 + selectionForeground + #b4b7b4 + + settings + + + settings + + background + #1d1f21 + caret + #c5c8c6 + foreground + #c5c8c6 + invisibles + #969896 + lineHighlight + #96989655 + selection + #373b41 + + + + name + Text + scope + variable.parameter.function + settings + + foreground + #c5c8c6 + + + + name + Comments + scope + comment, punctuation.definition.comment + settings + + foreground + #969896 + + + + name + Punctuation + scope + punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array + settings + + foreground + #c5c8c6 + + + + name + Delimiters + scope + none + settings + + foreground + #c5c8c6 + + + + name + Operators + scope + keyword.operator + settings + + foreground + #c5c8c6 + + + + name + Keywords + scope + keyword + settings + + foreground + #b294bb + + + + name + Variables + scope + variable + settings + + foreground + #cc6666 + + + + name + Functions + scope + entity.name.function, meta.require, support.function.any-method + settings + + foreground + #81a2be + + + + name + Labels + scope + entity.name.label + settings + + foreground + #a3685a + + + + name + Classes + scope + support.class, entity.name.class, entity.name.type.class + settings + + foreground + #f0c674 + + + + name + Classes + scope + meta.class + settings + + foreground + #ffffff + + + + name + Methods + scope + keyword.other.special-method + settings + + foreground + #81a2be + + + + name + Storage + scope + storage + settings + + foreground + #b294bb + + + + name + Support + scope + support.function + settings + + foreground + #8abeb7 + + + + name + Strings, Inherited Class + scope + string, constant.other.symbol, entity.other.inherited-class + settings + + foreground + #b5bd68 + + + + name + Integers + scope + constant.numeric + settings + + foreground + #de935f + + + + name + Floats + scope + none + settings + + foreground + #de935f + + + + name + Boolean + scope + none + settings + + foreground + #de935f + + + + name + Constants + scope + constant + settings + + foreground + #de935f + + + + name + Tags + scope + entity.name.tag + settings + + foreground + #cc6666 + + + + name + Attributes + scope + entity.other.attribute-name + settings + + foreground + #de935f + + + + name + Attribute IDs + scope + entity.other.attribute-name.id, punctuation.definition.entity + settings + + foreground + #81a2be + + + + name + Selector + scope + meta.selector + settings + + foreground + #b294bb + + + + name + Values + scope + none + settings + + foreground + #de935f + + + + name + Headings + scope + markup.heading punctuation.definition.heading, entity.name.section + settings + + fontStyle + + foreground + #81a2be + + + + name + Units + scope + keyword.other.unit + settings + + foreground + #de935f + + + + name + Bold + scope + markup.bold, punctuation.definition.bold + settings + + fontStyle + bold + foreground + #f0c674 + + + + name + Italic + scope + markup.italic, punctuation.definition.italic + settings + + fontStyle + italic + foreground + #b294bb + + + + name + Code + scope + markup.raw.inline + settings + + foreground + #b5bd68 + + + + name + Link Text + scope + string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown + settings + + foreground + #cc6666 + + + + name + Link Url + scope + meta.link + settings + + foreground + #de935f + + + + name + Lists + scope + markup.list + settings + + foreground + #cc6666 + + + + name + Quotes + scope + markup.quote + settings + + foreground + #de935f + + + + name + Separator + scope + meta.separator + settings + + background + #373b41 + foreground + #c5c8c6 + + + + name + Inserted + scope + markup.inserted + settings + + foreground + #b5bd68 + + + + name + Deleted + scope + markup.deleted + settings + + foreground + #cc6666 + + + + name + Changed + scope + markup.changed + settings + + foreground + #b294bb + + + + name + Colors + scope + constant.other.color + settings + + foreground + #8abeb7 + + + + name + Regular Expressions + scope + string.regexp + settings + + foreground + #8abeb7 + + + + name + Escape Characters + scope + constant.character.escape + settings + + foreground + #8abeb7 + + + + name + Embedded + scope + punctuation.section.embedded, variable.interpolation + settings + + foreground + #b294bb + + + + name + Illegal + scope + invalid.illegal + settings + + background + #cc6666 + foreground + #ffffff + + + + name + Broken + scope + invalid.broken + settings + + background + #de935f + foreground + #1d1f21 + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #a3685a + foreground + #ffffff + + + + name + Unimplemented + scope + invalid.unimplemented + settings + + background + #969896 + foreground + #ffffff + + + + uuid + uuid + + diff --git a/src/theme/syntax-themes/dark.tmTheme b/src/theme/syntax-themes/dark.tmTheme new file mode 100644 index 00000000..b25c81db --- /dev/null +++ b/src/theme/syntax-themes/dark.tmTheme @@ -0,0 +1,560 @@ + + + + + author + Template: Chris Kempson, Scheme: Chris Kempson (http://chriskempson.com) + name + Base16 Tomorrow Night + semanticClass + theme.base16.tomorrow-night + colorSpaceName + sRGB + gutterSettings + + background + #282a2e + divider + #282a2e + foreground + #969896 + selectionBackground + #373b41 + selectionForeground + #b4b7b4 + + settings + + + settings + + background + #1d1f21 + caret + #c5c8c6 + foreground + #c5c8c6 + invisibles + #969896 + lineHighlight + #96989655 + selection + #373b41 + + + + name + Text + scope + variable.parameter.function + settings + + foreground + #c5c8c6 + + + + name + Comments + scope + comment, punctuation.definition.comment + settings + + foreground + #969896 + + + + name + Punctuation + scope + punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array + settings + + foreground + #c5c8c6 + + + + name + Delimiters + scope + none + settings + + foreground + #c5c8c6 + + + + name + Operators + scope + keyword.operator + settings + + foreground + #c5c8c6 + + + + name + Keywords + scope + keyword + settings + + foreground + #b294bb + + + + name + Variables + scope + variable + settings + + foreground + #cc6666 + + + + name + Functions + scope + entity.name.function, meta.require, support.function.any-method + settings + + foreground + #81a2be + + + + name + Labels + scope + entity.name.label + settings + + foreground + #a3685a + + + + name + Classes + scope + support.class, entity.name.class, entity.name.type.class + settings + + foreground + #f0c674 + + + + name + Classes + scope + meta.class + settings + + foreground + #ffffff + + + + name + Methods + scope + keyword.other.special-method + settings + + foreground + #81a2be + + + + name + Storage + scope + storage + settings + + foreground + #b294bb + + + + name + Support + scope + support.function + settings + + foreground + #8abeb7 + + + + name + Strings, Inherited Class + scope + string, constant.other.symbol, entity.other.inherited-class + settings + + foreground + #b5bd68 + + + + name + Integers + scope + constant.numeric + settings + + foreground + #de935f + + + + name + Floats + scope + none + settings + + foreground + #de935f + + + + name + Boolean + scope + none + settings + + foreground + #de935f + + + + name + Constants + scope + constant + settings + + foreground + #de935f + + + + name + Tags + scope + entity.name.tag + settings + + foreground + #cc6666 + + + + name + Attributes + scope + entity.other.attribute-name + settings + + foreground + #de935f + + + + name + Attribute IDs + scope + entity.other.attribute-name.id, punctuation.definition.entity + settings + + foreground + #81a2be + + + + name + Selector + scope + meta.selector + settings + + foreground + #b294bb + + + + name + Values + scope + none + settings + + foreground + #de935f + + + + name + Headings + scope + markup.heading punctuation.definition.heading, entity.name.section + settings + + fontStyle + + foreground + #81a2be + + + + name + Units + scope + keyword.other.unit + settings + + foreground + #de935f + + + + name + Bold + scope + markup.bold, punctuation.definition.bold + settings + + fontStyle + bold + foreground + #f0c674 + + + + name + Italic + scope + markup.italic, punctuation.definition.italic + settings + + fontStyle + italic + foreground + #b294bb + + + + name + Code + scope + markup.raw.inline + settings + + foreground + #b5bd68 + + + + name + Link Text + scope + string.other.link, punctuation.definition.string.end.markdown, punctuation.definition.string.begin.markdown + settings + + foreground + #cc6666 + + + + name + Link Url + scope + meta.link + settings + + foreground + #de935f + + + + name + Lists + scope + markup.list + settings + + foreground + #cc6666 + + + + name + Quotes + scope + markup.quote + settings + + foreground + #de935f + + + + name + Separator + scope + meta.separator + settings + + background + #373b41 + foreground + #c5c8c6 + + + + name + Inserted + scope + markup.inserted + settings + + foreground + #b5bd68 + + + + name + Deleted + scope + markup.deleted + settings + + foreground + #cc6666 + + + + name + Changed + scope + markup.changed + settings + + foreground + #b294bb + + + + name + Colors + scope + constant.other.color + settings + + foreground + #8abeb7 + + + + name + Regular Expressions + scope + string.regexp + settings + + foreground + #8abeb7 + + + + name + Escape Characters + scope + constant.character.escape + settings + + foreground + #8abeb7 + + + + name + Embedded + scope + punctuation.section.embedded, variable.interpolation + settings + + foreground + #b294bb + + + + name + Illegal + scope + invalid.illegal + settings + + background + #cc6666 + foreground + #ffffff + + + + name + Broken + scope + invalid.broken + settings + + background + #de935f + foreground + #1d1f21 + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #a3685a + foreground + #ffffff + + + + name + Unimplemented + scope + invalid.unimplemented + settings + + background + #969896 + foreground + #ffffff + + + + uuid + uuid + + diff --git a/src/theme/syntax-themes/light.tmTheme b/src/theme/syntax-themes/light.tmTheme new file mode 100644 index 00000000..87d3353b --- /dev/null +++ b/src/theme/syntax-themes/light.tmTheme @@ -0,0 +1,549 @@ + + + + + author + Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) + name + Base16 Atelier Dune Light + semanticClass + base16.atelierdune.light + colorSpaceName + sRGB + gutterSettings + + background + #fefbec + divider + #fefbec + foreground + #6e6b5e + selectionBackground + #fefbec + selectionForeground + #a6a28c + + settings + + + settings + + background + #fefbec + caret + #6e6b5e + foreground + #6e6b5e + invisibles + #e8e4cf + lineHighlight + #99958055 + selection + #e8e4cf + + + + name + Text + scope + variable.parameter.function + settings + + foreground + #6e6b5e + + + + name + Comments + scope + comment, punctuation.definition.comment + settings + + foreground + #999580 + + + + name + Punctuation + scope + punctuation.definition.string, punctuation.definition.variable, punctuation.definition.string, punctuation.definition.parameters, punctuation.definition.string, punctuation.definition.array + settings + + foreground + #6e6b5e + + + + name + Delimiters + scope + none + settings + + foreground + #6e6b5e + + + + name + Operators + scope + keyword.operator + settings + + foreground + #6e6b5e + + + + name + Keywords + scope + keyword + settings + + foreground + #b854d4 + + + + name + Variables + scope + variable + settings + + foreground + #d73737 + + + + name + Functions + scope + entity.name.function, meta.require, support.function.any-method + settings + + foreground + #6684e1 + + + + name + Classes + scope + support.class, entity.name.class, entity.name.type.class + settings + + foreground + #b65611 + + + + name + Classes + scope + meta.class + settings + + foreground + #292824 + + + + name + Methods + scope + keyword.other.special-method + settings + + foreground + #6684e1 + + + + name + Storage + scope + storage + settings + + foreground + #b854d4 + + + + name + Support + scope + support.function + settings + + foreground + #1fad83 + + + + name + Strings, Inherited Class + scope + string, constant.other.symbol, entity.other.inherited-class + settings + + foreground + #60ac39 + + + + name + Integers + scope + constant.numeric + settings + + foreground + #b65611 + + + + name + Floats + scope + none + settings + + foreground + #b65611 + + + + name + Boolean + scope + none + settings + + foreground + #b65611 + + + + name + Constants + scope + constant + settings + + foreground + #b65611 + + + + name + Tags + scope + entity.name.tag + settings + + foreground + #d73737 + + + + name + Attributes + scope + entity.other.attribute-name + settings + + foreground + #b65611 + + + + name + Attribute IDs + scope + entity.other.attribute-name.id, punctuation.definition.entity + settings + + foreground + #6684e1 + + + + name + Selector + scope + meta.selector + settings + + foreground + #b854d4 + + + + name + Values + scope + none + settings + + foreground + #b65611 + + + + name + Headings + scope + markup.heading punctuation.definition.heading, entity.name.section + settings + + fontStyle + + foreground + #6684e1 + + + + name + Units + scope + keyword.other.unit + settings + + foreground + #b65611 + + + + name + Bold + scope + markup.bold, punctuation.definition.bold + settings + + fontStyle + bold + foreground + #b65611 + + + + name + Italic + scope + markup.italic, punctuation.definition.italic + settings + + fontStyle + italic + foreground + #b854d4 + + + + name + Code + scope + markup.raw.inline + settings + + foreground + #60ac39 + + + + name + Link Text + scope + string.other.link + settings + + foreground + #d73737 + + + + name + Link Url + scope + meta.link + settings + + foreground + #b65611 + + + + name + Lists + scope + markup.list + settings + + foreground + #d73737 + + + + name + Quotes + scope + markup.quote + settings + + foreground + #b65611 + + + + name + Separator + scope + meta.separator + settings + + background + #e8e4cf + foreground + #6e6b5e + + + + name + Inserted + scope + markup.inserted + settings + + foreground + #60ac39 + + + + name + Deleted + scope + markup.deleted + settings + + foreground + #d73737 + + + + name + Changed + scope + markup.changed + settings + + foreground + #b854d4 + + + + name + Colors + scope + constant.other.color + settings + + foreground + #1fad83 + + + + name + Regular Expressions + scope + string.regexp + settings + + foreground + #1fad83 + + + + name + Escape Characters + scope + constant.character.escape + settings + + foreground + #1fad83 + + + + name + Embedded + scope + punctuation.section.embedded, variable.interpolation + settings + + foreground + #d43552 + + + + name + Illegal + scope + invalid.illegal + settings + + background + #d73737 + foreground + #fefbec + + + + name + Broken + scope + invalid.broken + settings + + background + #b65611 + foreground + #20201d + + + + name + Deprecated + scope + invalid.deprecated + settings + + background + #d43552 + foreground + #fefbec + + + + name + Unimplemented + scope + invalid.unimplemented + settings + + background + #a6a28c + foreground + #20201d + + + + uuid + f2aa1936-a9d9-40c6-a1db-c64d058b81dd + + diff --git a/src/theme/syntaxes.bin b/src/theme/syntaxes.bin deleted file mode 100644 index d8def0ea..00000000 Binary files a/src/theme/syntaxes.bin and /dev/null differ diff --git a/src/theme/syntaxes/README.md b/src/theme/syntaxes/README.md index 0f951d59..a03b1aa8 100644 --- a/src/theme/syntaxes/README.md +++ b/src/theme/syntaxes/README.md @@ -1,16 +1,5 @@ # Note -This folder is not copied over to the book directory when using `mdbook init`, nor is it indexed at runtime. To add new syntaxes, first add a `.sublime-syntax` file in this directory, then run (from inside this directory): -```shell -$ ./gen-syntaxcache.sh -``` -Make sure you have [`bat`](https://github.com/sharkdp/bat) installed, otherwise this won't work. +This folder is not copied over to the book directory when using `mdbook init`, nor is it indexed at runtime. All of the files in this folder are scraped by build.rs. -Don't worry if bat says: -``` -No themes were found in './themes', using the default set -``` - -Now, you may rebuild the `mdBook` binary and the new syntaxes should be included. - -This only needs to be run when the syntaxes in this folder are updated. \ No newline at end of file +To make build.rs run again without running `cargo clean`, touch the run `touch build.rs`. \ No newline at end of file diff --git a/src/theme/syntaxes/gen-syntaxcache.sh b/src/theme/syntaxes/gen-syntaxcache.sh deleted file mode 100755 index d73c3745..00000000 --- a/src/theme/syntaxes/gen-syntaxcache.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/env bash -set -Eeuxo pipefail - -bat cache --build --source=".." --target=".." -rm -f ../themes.bin -rm -f ../metadata.yaml \ No newline at end of file diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 7c04ddff..9eba634a 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -341,6 +341,9 @@ impl<'a> SyntaxHighlighter<'a> { r#"
"#,
                                 classes.join(" ")
                             )));
+                        } else {
+                            self.is_editable = false;
+                            self.is_playground = false;
                         }
                     }
                 } else {
@@ -373,6 +376,7 @@ impl<'a> SyntaxHighlighter<'a> {
                 );
                 let needs_wrapped = self.is_rust
                     && !(self.playground_config.editable && self.is_editable)
+                    && self.is_playground
                     && !code.contains("fn main")
                     && !code.contains("quick_main!");
                 if needs_wrapped {
@@ -704,15 +708,15 @@ more text with spaces
               ("```rust\nfn main() {}\n```",
                "
fn main() {}\n
"), ("```rust editable\nlet s = \"foo\n # bar\n\";\n```", - "
let s = "foo\n bar\n";\n
"), + "
let s = "foo\n bar\n";\n
"), ("```rust editable\nlet s = \"foo\n ## bar\n\";\n```", - "
let s = "foo\n # bar\n";\n
"), + "
let s = "foo\n # bar\n";\n
"), ("```rust editable\nlet s = \"foo\n # bar\n#\n\";\n```", - "
let s = "foo\n bar\n\n";\n
"), + "
let s = "foo\n bar\n\n";\n
"), ("```rust ignore\nlet s = \"foo\n # bar\n\";\n```", - "
fn main() {\nlet s = "foo\n bar\n";\n}\n
"), + "
let s = "foo\n bar\n";\n
"), ("```rust editable\n#![no_std]\nlet s = \"foo\";\n #[some_attr]\n```", - "
#![no_std]\nlet s = "foo";\n #[some_attr]\n
"), + "
#![no_std]\nlet s = "foo";\n #[some_attr]\n
"), ]; for (src, should_be) in &inputs { let got = render_markdown( @@ -812,7 +816,7 @@ more text with spaces ("```html,testhtml\n

\n```", "

<p>\n
"), ("```js es7\nf()\n```", - "
f()\n
"), + "
f()\n
"), ]; for (src, should_be) in &inputs { let got = render_markdown( diff --git a/tests/rendered_output.rs b/tests/rendered_output.rs index 57389926..282930a4 100644 --- a/tests/rendered_output.rs +++ b/tests/rendered_output.rs @@ -515,6 +515,44 @@ fn theme_dir_overrides_work_correctly() { dummy_book::assert_contains_strings(built_index, &["This is a modified index.hbs!"]); } +#[test] +fn theme_dir_syntaxesdotbin_prevents_default_highlighting() { + let book_dir = dummy_book::new_copy_of_example_book().unwrap(); + let book_dir = book_dir.path(); + let theme_dir = book_dir.join("theme"); + + let empty_syntaxset = syntect::parsing::SyntaxSet::new(); + let empty_syntaxset_dump = syntect::dumps::dump_binary(&empty_syntaxset); + write_file(&theme_dir, "syntaxes.bin", &empty_syntaxset_dump).unwrap(); + + let md = MDBook::load(book_dir).unwrap(); + md.build().unwrap(); + + let second = book_dir.join("book/format/mdbook.html"); + + assert_doesnt_contain_strings(&second, &["syn-rust", "rustmodifiedtestfixture"]); +} + +#[test] +fn theme_dir_syntaxesdotbin_reads_syntaxes() { + let book_dir = dummy_book::new_copy_of_example_book().unwrap(); + let book_dir = book_dir.path(); + let theme_dir = book_dir.join("theme"); + + let syntaxset_test_fixture = + syntect::parsing::SyntaxSet::load_from_folder("tests/syntax_test_fixtures").unwrap(); + let syntaxset_test_fixture = syntect::dumps::dump_binary(&syntaxset_test_fixture); + write_file(&theme_dir, "syntaxes.bin", &syntaxset_test_fixture).unwrap(); + + let md = MDBook::load(book_dir).unwrap(); + md.build().unwrap(); + + let second = book_dir.join("book/format/mdbook.html"); + + assert_contains_strings(&second, &["syn-rustmodifiedtestfixture"]); + assert_doesnt_contain_strings(&second, &["syn-rust\""]); +} + #[test] fn no_index_for_print_html() { let temp = DummyBook::new().build().unwrap(); diff --git a/tests/syntax_test_fixtures/rust-modified.sublime-syntax b/tests/syntax_test_fixtures/rust-modified.sublime-syntax new file mode 100644 index 00000000..408a0a46 --- /dev/null +++ b/tests/syntax_test_fixtures/rust-modified.sublime-syntax @@ -0,0 +1,92 @@ +%YAML 1.2 +--- +# http://www.sublimetext.com/docs/3/syntax.html +# +# Based on https://github.com/sublimehq/Packages/tree/759d6eed9b4beed87e602a23303a121c3a6c2fb3/Rust +# but with rustmodifiedtestfixture added everywhere and somewhat truncated. +name: Rust +file_extensions: + - rs +scope: source.rustmodifiedtestfixture +variables: + identifier: '(?:(?:[[:alpha:]][_[:alnum:]]*|_[_[:alnum:]]+)\b)' # include a word boundary at the end to ensure all possible characters are consumed, to prevent catastrophic backtracking + escaped_byte: '\\(x\h{2}|n|r|t|0|"|''|\\)' + escaped_char: '\\(x\h{2}|n|r|t|0|"|''|\\|u\{\h{1,6}\})' + int_suffixes: 'i8|i16|i32|i64|i128|isize|u8|u16|u32|u64|u128|usize' + support_type: \b(Copy|Send|Sized|Sync|Drop|Fn|FnMut|FnOnce|Box|ToOwned|Clone|PartialEq|PartialOrd|Eq|Ord|AsRef|AsMut|Into|From|Default|Iterator|Extend|IntoIterator|DoubleEndedIterator|ExactSizeIterator|Option|Some|None|Result|Ok|Err|SliceConcatExt|String|ToString|Vec)\b +contexts: + main: + - include: statements + + prototype: + # Macro metavariables. Ideally we would do this as a with_prototype, + # however then we run into infinite recursion. It needs to be a prototype + # since macro_rules! allows constructing new code, thus the metavariables + # can be inserted in just about any position in the syntax. + - match: '\${{identifier}}' + scope: variable.other.rustmodifiedtestfixture + + else-pop: + - match: (?=\S) + pop: true + + pop-immediately: + - match: '' + pop: true + + statements: + + - match: '(''{{identifier}})\s*(:)' + captures: + 1: entity.name.label.rustmodifiedtestfixture + 2: punctuation.separator.rustmodifiedtestfixture + - match: '''{{identifier}}(?!\'')\b' + scope: storage.modifier.lifetime.rustmodifiedtestfixture + + - match: '\b(?:(pub)\s+)?\b(mod)\s+({{identifier}})\b' + captures: + 1: storage.modifier.rustmodifiedtestfixture + 2: storage.type.module.rustmodifiedtestfixture + 3: entity.name.module.rustmodifiedtestfixture + + - match: '\b({{identifier}})\s*(=)\s*(?=\|)' + captures: + 1: entity.name.function.rustmodifiedtestfixture + 2: keyword.operator.rustmodifiedtestfixture + + - match: '\b(?:(pub)\s+)?\b(fn)\s+(?={{identifier}})' + scope: meta.function.rustmodifiedtestfixture + captures: + 1: storage.modifier.rustmodifiedtestfixture + 2: storage.type.function.rustmodifiedtestfixture + + - match: '\b(?:(pub)\s+)?(struct)\s+' + scope: meta.struct.rustmodifiedtestfixture + captures: + 1: storage.modifier.rustmodifiedtestfixture + 2: storage.type.struct.rustmodifiedtestfixture + + - match: '\b(?:(pub)\s+)?(type)\s+({{identifier}})\b' + captures: + 1: storage.modifier.rustmodifiedtestfixture + 2: storage.type.type.rustmodifiedtestfixture + 3: entity.name.type.rustmodifiedtestfixture + + - match: '\b(?:(pub)\s+)?(trait)\s+({{identifier}})\b' + captures: + 1: storage.modifier.rustmodifiedtestfixture + 2: storage.type.trait.rustmodifiedtestfixture + 3: entity.name.trait.rustmodifiedtestfixture + + - match: '\bimpl\b' + scope: storage.type.impl.rustmodifiedtestfixture + + - match: '\b(?:(pub)\s+)?(enum)\s+({{identifier}})\b' + captures: + 1: storage.modifier.rustmodifiedtestfixture + 2: storage.type.enum.rustmodifiedtestfixture + 3: entity.name.enum.rustmodifiedtestfixture + + - match: \b(let|const|static)\b + scope: storage.type.rustmodifiedtestfixture +