Use syntect instead of highlight.js
This commit is contained in:
parent
fff067b2a8
commit
8d8c103eca
|
@ -2,6 +2,12 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.18"
|
||||
|
@ -78,6 +84,15 @@ version = "0.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.2"
|
||||
|
@ -158,6 +173,12 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b700ce4376041dcd0a327fd0097c41095743c4c8af8887265942faf1100bd040"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79c2681d6594606957bbb8631c4b90a7fcaaa72cdb714743a437b156d6a7eedd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "0.1.10"
|
||||
|
@ -217,6 +238,15 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81156fece84ab6a9f2afdb109ce3ae577e42b1228441eded99bd77f627953b1a"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.20"
|
||||
|
@ -312,6 +342,18 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"crc32fast",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "float-cmp"
|
||||
version = "0.9.0"
|
||||
|
@ -741,6 +783,21 @@ version = "0.2.100"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5"
|
||||
|
||||
[[package]]
|
||||
name = "line-wrap"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f30344350a2a51da54c1d53be93fade8a237e545dbcc4bdbe635413f2117cab9"
|
||||
dependencies = [
|
||||
"safemem",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3"
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.14"
|
||||
|
@ -823,6 +880,7 @@ dependencies = [
|
|||
"serde",
|
||||
"serde_json",
|
||||
"shlex",
|
||||
"syntect",
|
||||
"tempfile",
|
||||
"tokio",
|
||||
"toml",
|
||||
|
@ -853,6 +911,16 @@ dependencies = [
|
|||
"unicase",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.6.23"
|
||||
|
@ -997,6 +1065,28 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "onig"
|
||||
version = "6.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b17403cf40f61e3ee059e3e90b7fc0a2953297168d4379b160f80d18fed848a4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"onig_sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "onig_sys"
|
||||
version = "69.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5dd3eee045c84695b53b20255bb7317063df090b68e18bfac0abb6c39cf7f33e"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
|
@ -1156,6 +1246,26 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c9b1041b4387893b91ee6746cddfc28516aff326a3519fb2adf820932c5e6cb"
|
||||
|
||||
[[package]]
|
||||
name = "plist"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a38d026d73eeaf2ade76309d0c65db5a35ecf649e3cec428db316243ea9d6711"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"chrono",
|
||||
"indexmap",
|
||||
"line-wrap",
|
||||
"serde",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.10"
|
||||
|
@ -1395,6 +1505,12 @@ version = "1.0.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e"
|
||||
|
||||
[[package]]
|
||||
name = "safemem"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||
|
||||
[[package]]
|
||||
name = "same-file"
|
||||
version = "1.0.6"
|
||||
|
@ -1565,6 +1681,28 @@ dependencies = [
|
|||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "syntect"
|
||||
version = "4.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b20815bbe80ee0be06e6957450a841185fcf690fe0178f14d77a05ce2caa031"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags",
|
||||
"flate2",
|
||||
"fnv",
|
||||
"lazy_static",
|
||||
"lazycell",
|
||||
"onig",
|
||||
"plist",
|
||||
"regex-syntax",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"walkdir",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.2.0"
|
||||
|
@ -1978,6 +2116,12 @@ dependencies = [
|
|||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xml-rs"
|
||||
version = "0.8.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2d7d3948613f75c98fd9328cfdcc45acc4d360655289d0a7d4ec931392200a3"
|
||||
|
||||
[[package]]
|
||||
name = "xml5ever"
|
||||
version = "0.16.1"
|
||||
|
@ -1989,3 +2133,12 @@ dependencies = [
|
|||
"markup5ever",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||
dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
|
|
@ -34,6 +34,7 @@ shlex = "1"
|
|||
tempfile = "3.0"
|
||||
toml = "0.5.1"
|
||||
topological-sort = "0.1.0"
|
||||
syntect = { version = "4.6.0", default-features = false, features = ["regex-onig", "parsing", "html", "dump-load", "yaml-load"] }
|
||||
|
||||
# Watch feature
|
||||
notify = { version = "4.0", optional = true }
|
||||
|
@ -65,3 +66,8 @@ search = ["elasticlunr-rs", "ammonia"]
|
|||
[[bin]]
|
||||
doc = false
|
||||
name = "mdbook"
|
||||
|
||||
# For profiling only.
|
||||
# If this ends up uncommented in a commit, let me know.
|
||||
[profile.release]
|
||||
debug = true
|
||||
|
|
|
@ -20,5 +20,6 @@ shout-out to them!
|
|||
- Vivek Akupatni ([apatniv](https://github.com/apatniv))
|
||||
- Eric Huss ([ehuss](https://github.com/ehuss))
|
||||
- Josh Rotenberg ([joshrotenberg](https://github.com/joshrotenberg))
|
||||
- James ([ThePuzzlemaker](https://github.com/ThePuzzlemaker))
|
||||
|
||||
If you feel you're missing from this list, feel free to add yourself in a PR.
|
||||
|
|
|
@ -151,11 +151,13 @@ impl BookBuilder {
|
|||
let mut js = File::create(themedir.join("book.js"))?;
|
||||
js.write_all(theme::JS)?;
|
||||
|
||||
let mut highlight_css = File::create(themedir.join("highlight.css"))?;
|
||||
highlight_css.write_all(theme::HIGHLIGHT_CSS)?;
|
||||
let syntax_dir = cssdir.join("syntax");
|
||||
if !syntax_dir.exists() {
|
||||
fs::create_dir(&syntax_dir)?;
|
||||
}
|
||||
|
||||
let mut highlight_js = File::create(themedir.join("highlight.js"))?;
|
||||
highlight_js.write_all(theme::HIGHLIGHT_JS)?;
|
||||
let mut highlight_css = File::create(syntax_dir.join("light.css"))?;
|
||||
highlight_css.write_all(theme::SYNTAX_LIGHT_CSS)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ use crate::theme::{self, playground_editor, Theme};
|
|||
use crate::utils;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::cell::RefCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::collections::HashMap;
|
||||
use std::fs::{self, File};
|
||||
|
@ -15,13 +16,18 @@ use std::path::{Path, PathBuf};
|
|||
use crate::utils::fs::get_404_output_file;
|
||||
use handlebars::Handlebars;
|
||||
use regex::{Captures, Regex};
|
||||
use syntect::parsing::SyntaxSet;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct HtmlHandlebars;
|
||||
pub struct HtmlHandlebars {
|
||||
pub(crate) syntaxes: RefCell<Option<SyntaxSet>>,
|
||||
}
|
||||
|
||||
impl HtmlHandlebars {
|
||||
pub fn new() -> Self {
|
||||
HtmlHandlebars
|
||||
HtmlHandlebars {
|
||||
syntaxes: RefCell::new(None),
|
||||
}
|
||||
}
|
||||
|
||||
fn render_item(
|
||||
|
@ -52,10 +58,18 @@ impl HtmlHandlebars {
|
|||
}
|
||||
|
||||
let content = ch.content.clone();
|
||||
let content = utils::render_markdown(&content, ctx.html_config.curly_quotes);
|
||||
let content = utils::render_markdown(
|
||||
&content,
|
||||
ctx.html_config.curly_quotes,
|
||||
self.syntaxes.borrow().as_ref().unwrap(),
|
||||
);
|
||||
|
||||
let fixed_content =
|
||||
utils::render_markdown_with_path(&ch.content, ctx.html_config.curly_quotes, Some(path));
|
||||
let fixed_content = utils::render_markdown_with_path(
|
||||
&ch.content,
|
||||
ctx.html_config.curly_quotes,
|
||||
Some(&path),
|
||||
self.syntaxes.borrow().as_ref().unwrap(),
|
||||
);
|
||||
if !ctx.is_index && ctx.html_config.print.page_break {
|
||||
// Add page break between chapters
|
||||
// See https://developer.mozilla.org/en-US/docs/Web/CSS/break-before and https://developer.mozilla.org/en-US/docs/Web/CSS/page-break-before
|
||||
|
@ -153,7 +167,11 @@ impl HtmlHandlebars {
|
|||
.to_string()
|
||||
}
|
||||
};
|
||||
let html_content_404 = utils::render_markdown(&content_404, html_config.curly_quotes);
|
||||
let html_content_404 = utils::render_markdown(
|
||||
&content_404,
|
||||
html_config.curly_quotes,
|
||||
self.syntaxes.borrow().as_ref().unwrap(),
|
||||
);
|
||||
|
||||
let mut data_404 = data.clone();
|
||||
let base_url = if let Some(site_url) = &html_config.site_url {
|
||||
|
@ -232,10 +250,9 @@ impl HtmlHandlebars {
|
|||
if let Some(contents) = &theme.favicon_svg {
|
||||
write_file(destination, "favicon.svg", contents)?;
|
||||
}
|
||||
write_file(destination, "highlight.css", &theme.highlight_css)?;
|
||||
write_file(destination, "tomorrow-night.css", &theme.tomorrow_night_css)?;
|
||||
write_file(destination, "ayu-highlight.css", &theme.ayu_highlight_css)?;
|
||||
write_file(destination, "highlight.js", &theme.highlight_js)?;
|
||||
write_file(destination, "css/syntax/ayu.css", &theme.syntax_ayu_css)?;
|
||||
write_file(destination, "css/syntax/dark.css", &theme.syntax_dark_css)?;
|
||||
write_file(destination, "css/syntax/light.css", &theme.syntax_light_css)?;
|
||||
write_file(destination, "clipboard.min.js", &theme.clipboard_js)?;
|
||||
write_file(
|
||||
destination,
|
||||
|
@ -438,6 +455,21 @@ impl HtmlHandlebars {
|
|||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn build_syntaxset(&self, theme: &Theme, theme_dir: &Path) {
|
||||
let base: SyntaxSet = syntect::dumps::from_binary(&theme.base_syntaxes);
|
||||
let mut base_builder = base.into_builder();
|
||||
|
||||
let syntaxes_path = theme_dir.join("syntaxes");
|
||||
if syntaxes_path.is_dir() {
|
||||
if let Err(e) = base_builder.add_from_folder(&theme_dir.join("syntaxes"), true) {
|
||||
warn!("Couldn't load custom syntax definitions: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
let syntaxes = base_builder.build();
|
||||
self.syntaxes.replace(Some(syntaxes));
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(mattico): Remove some time after the 0.1.8 release
|
||||
|
@ -501,7 +533,10 @@ impl Renderer for HtmlHandlebars {
|
|||
warn!("Please move your theme files to `./theme` for them to continue being used");
|
||||
}
|
||||
|
||||
let theme = theme::Theme::new(theme_dir);
|
||||
let theme = theme::Theme::new(&theme_dir);
|
||||
|
||||
debug!("Collect syntaxes into a syntax set");
|
||||
self.build_syntaxset(&theme, &theme_dir);
|
||||
|
||||
debug!("Register the index handlebars template");
|
||||
handlebars.register_template_string("index", String::from_utf8(theme.index.clone())?)?;
|
||||
|
@ -873,6 +908,7 @@ fn add_playground_pre(
|
|||
{
|
||||
let content: Cow<'_, str> = if playground_config.editable
|
||||
&& classes.contains("editable")
|
||||
|| text.contains("fn</span> </span><span class=\"syn-entity syn-name syn-function syn-rust\">main")
|
||||
|| text.contains("fn main")
|
||||
|| text.contains("quick_main!")
|
||||
{
|
||||
|
@ -881,7 +917,17 @@ fn add_playground_pre(
|
|||
// we need to inject our own main
|
||||
let (attrs, code) = partition_source(code);
|
||||
|
||||
format!("# #![allow(unused)]\n{}#fn main() {{\n{}#}}", attrs, code)
|
||||
// FIXME: This doesn't highlight the added playground preamble, as it's added
|
||||
// *after* syntax highlighting.
|
||||
// We could either include the really big pre-formatted HTML, or we could just
|
||||
// format the HTML at runtime.
|
||||
// Maybe we can do this part before the highlighting step?
|
||||
// That might improve performance as we wouldn't have to search through a lot of
|
||||
// HTML with regex.
|
||||
format!(
|
||||
"\n# #![allow(unused)]\n{}#fn main() {{\n{}#}}",
|
||||
attrs, code
|
||||
)
|
||||
.into()
|
||||
};
|
||||
hide_lines(&content)
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
/*
|
||||
Based off of the Ayu theme
|
||||
Original by Dempfi (https://github.com/dempfi/ayu)
|
||||
*/
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #191f26;
|
||||
color: #e6e1cf;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #5c6773;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-attr,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #ff7733;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #ffee99;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-bullet {
|
||||
color: #b8cc52;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-built_in,
|
||||
.hljs-section {
|
||||
color: #ffb454;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag,
|
||||
.hljs-symbol {
|
||||
color: #ff7733;
|
||||
}
|
||||
|
||||
.hljs-name {
|
||||
color: #36a3d9;
|
||||
}
|
||||
|
||||
.hljs-tag {
|
||||
color: #00568d;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #91b362;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #d96c75;
|
||||
}
|
|
@ -101,7 +101,7 @@ function playground_text(playground) {
|
|||
var result_block = code_block.querySelector(".result");
|
||||
if (!result_block) {
|
||||
result_block = document.createElement('code');
|
||||
result_block.className = 'result hljs language-bash';
|
||||
result_block.className = 'result syn-source syn-bash';
|
||||
|
||||
code_block.append(result_block);
|
||||
}
|
||||
|
@ -148,35 +148,14 @@ function playground_text(playground) {
|
|||
.catch(error => result_block.innerText = "Playground Communication: " + error.message);
|
||||
}
|
||||
|
||||
// Syntax highlighting Configuration
|
||||
hljs.configure({
|
||||
tabReplace: ' ', // 4 spaces
|
||||
languages: [], // Languages used for auto-detection
|
||||
});
|
||||
|
||||
let code_nodes = Array
|
||||
.from(document.querySelectorAll('code'))
|
||||
// Don't highlight `inline code` blocks in headers.
|
||||
.filter(function (node) {return !node.parentElement.classList.contains("header"); });
|
||||
|
||||
if (window.ace) {
|
||||
// language-rust class needs to be removed for editable
|
||||
// blocks or highlightjs will capture events
|
||||
code_nodes
|
||||
.filter(function (node) {return node.classList.contains("editable"); })
|
||||
.forEach(function (block) { block.classList.remove('language-rust'); });
|
||||
|
||||
Array
|
||||
code_nodes
|
||||
.filter(function (node) {return !node.classList.contains("editable"); })
|
||||
.forEach(function (block) { hljs.highlightBlock(block); });
|
||||
} else {
|
||||
code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
|
||||
}
|
||||
|
||||
// Adding the hljs class gives code blocks the color css
|
||||
// Adding the scode class gives code blocks the color css
|
||||
// even if highlighting doesn't apply
|
||||
code_nodes.forEach(function (block) { block.classList.add('hljs'); });
|
||||
code_nodes.forEach(function (block) { block.classList.add('scode'); });
|
||||
|
||||
Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
|
||||
|
||||
|
@ -289,9 +268,9 @@ function playground_text(playground) {
|
|||
var themePopup = document.getElementById('theme-list');
|
||||
var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
|
||||
var stylesheets = {
|
||||
ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
|
||||
tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
|
||||
highlight: document.querySelector("[href$='highlight.css']"),
|
||||
ayuHighlight: document.querySelector("[href$='css/syntax/ayu.css']"),
|
||||
tomorrowNight: document.querySelector("[href$='css/syntax/dark.css']"),
|
||||
highlight: document.querySelector("[href$='css/syntax/light.css']"),
|
||||
};
|
||||
|
||||
function showThemes() {
|
||||
|
|
|
@ -14,7 +14,7 @@ html {
|
|||
#searchresults a,
|
||||
.content a:link,
|
||||
a:visited,
|
||||
a > .hljs {
|
||||
a > .scode {
|
||||
color: var(--links);
|
||||
}
|
||||
|
||||
|
@ -187,18 +187,18 @@ a > .hljs {
|
|||
|
||||
/* Inline code */
|
||||
|
||||
:not(pre) > .hljs {
|
||||
:not(pre) > .scode {
|
||||
display: inline;
|
||||
padding: 0.1em 0.3em;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
:not(pre):not(a) > .hljs {
|
||||
:not(pre):not(a) > .scode {
|
||||
color: var(--inline-code-color);
|
||||
overflow-x: initial;
|
||||
}
|
||||
|
||||
a:hover > .hljs {
|
||||
a:hover > .scode {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,412 @@
|
|||
/*
|
||||
* theme "ayu" generated by syntect
|
||||
* based off of Ayu by Dempfi
|
||||
* https://github.com/dempfi/ayu/blob/master/ayu-dark.sublime-color-scheme
|
||||
*/
|
||||
|
||||
.syn-code {
|
||||
color: #b3b1ad;
|
||||
background-color: #0a0e14;
|
||||
}
|
||||
|
||||
.syn-comment {
|
||||
color: #626a73;
|
||||
font-style: italic;
|
||||
}
|
||||
.syn-string {
|
||||
color: #c2d94c;
|
||||
}
|
||||
.syn-constant.syn-other.syn-symbol {
|
||||
color: #c2d94c;
|
||||
}
|
||||
.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-keyword.syn-operator {
|
||||
color: #f29668;
|
||||
}
|
||||
.syn-punctuation.syn-separator {
|
||||
color: #b3b1ad;
|
||||
}
|
||||
.syn-punctuation.syn-terminator {
|
||||
color: #b3b1ad;
|
||||
}
|
||||
.syn-punctuation.syn-section {
|
||||
color: #b3b1ad;
|
||||
}
|
||||
.syn-punctuation.syn-accessor {
|
||||
color: #f29668;
|
||||
}
|
||||
.syn-source.syn-java {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.syn-storage.syn-type {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.syn-source.syn-haskell {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.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-support.syn-function {
|
||||
color: #f07178;
|
||||
}
|
||||
.syn-support.syn-macro {
|
||||
color: #f07178;
|
||||
}
|
||||
.syn-entity.syn-name.syn-import {
|
||||
color: #c2d94c;
|
||||
}
|
||||
.syn-entity.syn-name.syn-package {
|
||||
color: #c2d94c;
|
||||
}
|
||||
.syn-entity.syn-name {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.syn-source.syn-js {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.syn-meta.syn-function-call.syn-constructor {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.syn-variable.syn-type {
|
||||
color: #59c2ff;
|
||||
}
|
||||
.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;
|
||||
}
|
||||
.syn-entity.syn-other.syn-attribute-name {
|
||||
color: #ffb454;
|
||||
}
|
||||
.syn-support.syn-constant {
|
||||
color: #f29668;
|
||||
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;
|
||||
}
|
||||
.syn-meta.syn-separator {
|
||||
color: #626a73;
|
||||
background-color: #b3b1ad;
|
||||
font-weight: bold;
|
||||
}
|
||||
.syn-markup.syn-quote {
|
||||
color: #95e6cb;
|
||||
font-style: italic;
|
||||
}
|
||||
.syn-markup.syn-list {
|
||||
color: #ffb454;
|
||||
}
|
||||
.syn-punctuation.syn-definition.syn-list.syn-begin {
|
||||
color: #ffb454;
|
||||
}
|
||||
.syn-markup.syn-inserted {
|
||||
color: #91b362;
|
||||
}
|
||||
.syn-markup.syn-changed {
|
||||
color: #6994bf;
|
||||
}
|
||||
.syn-markup.syn-deleted {
|
||||
color: #d96c75;
|
||||
}
|
||||
.syn-markup.syn-strike {
|
||||
color: #e6b673;
|
||||
}
|
||||
.syn-markup.syn-table {
|
||||
color: #39bae6;
|
||||
background-color: #b3b1ad;
|
||||
}
|
||||
.syn-text.syn-html.syn-markdown {
|
||||
color: #f29668;
|
||||
}
|
||||
.syn-markup.syn-inline.syn-raw {
|
||||
color: #f29668;
|
||||
}
|
||||
.syn-text.syn-html.syn-markdown {
|
||||
color: #626a73;
|
||||
background-color: #626a73;
|
||||
}
|
||||
.syn-meta.syn-dummy.syn-line-break {
|
||||
color: #626a73;
|
||||
background-color: #626a73;
|
||||
}
|
||||
.syn-punctuation.syn-definition.syn-markdown {
|
||||
color: #626a73;
|
||||
background-color: #b3b1ad;
|
||||
}
|
||||
.scode {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #191f26;
|
||||
color: #e6e1cf;
|
||||
padding: 0.5em;
|
||||
}
|
|
@ -0,0 +1,222 @@
|
|||
* 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
|
||||
*/
|
||||
|
||||
.syn-code {
|
||||
color: #c5c8c6;
|
||||
background-color: #1d1f21;
|
||||
}
|
||||
|
||||
.syn-variable.syn-parameter.syn-function {
|
||||
color: #c5c8c6;
|
||||
}
|
||||
.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-none {
|
||||
color: #c5c8c6;
|
||||
}
|
||||
.syn-keyword.syn-operator {
|
||||
color: #c5c8c6;
|
||||
}
|
||||
.syn-keyword {
|
||||
color: #b294bb;
|
||||
}
|
||||
.syn-variable {
|
||||
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-label {
|
||||
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-meta.syn-class {
|
||||
color: #ffffff;
|
||||
}
|
||||
.syn-keyword.syn-other.syn-special-method {
|
||||
color: #81a2be;
|
||||
}
|
||||
.syn-storage {
|
||||
color: #b294bb;
|
||||
}
|
||||
.syn-support.syn-function {
|
||||
color: #8abeb7;
|
||||
}
|
||||
.syn-string {
|
||||
color: #b5bd68;
|
||||
}
|
||||
.syn-constant.syn-other.syn-symbol {
|
||||
color: #b5bd68;
|
||||
}
|
||||
.syn-entity.syn-other.syn-inherited-class {
|
||||
color: #b5bd68;
|
||||
}
|
||||
.syn-constant.syn-numeric {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-none {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-none {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-constant {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-entity.syn-name.syn-tag {
|
||||
color: #cc6666;
|
||||
}
|
||||
.syn-entity.syn-other.syn-attribute-name {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-entity.syn-other.syn-attribute-name.syn-id {
|
||||
color: #81a2be;
|
||||
}
|
||||
.syn-punctuation.syn-definition.syn-entity {
|
||||
color: #81a2be;
|
||||
}
|
||||
.syn-meta.syn-selector {
|
||||
color: #b294bb;
|
||||
}
|
||||
.syn-none {
|
||||
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-keyword.syn-other.syn-unit {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-markup.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;
|
||||
font-style: italic;
|
||||
}
|
||||
.syn-markup.syn-raw.syn-inline {
|
||||
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-meta.syn-link {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-markup.syn-list {
|
||||
color: #cc6666;
|
||||
}
|
||||
.syn-markup.syn-quote {
|
||||
color: #de935f;
|
||||
}
|
||||
.syn-meta.syn-separator {
|
||||
color: #c5c8c6;
|
||||
background-color: #373b41;
|
||||
}
|
||||
.syn-markup.syn-inserted {
|
||||
color: #b5bd68;
|
||||
}
|
||||
.syn-markup.syn-deleted {
|
||||
color: #cc6666;
|
||||
}
|
||||
.syn-markup.syn-changed {
|
||||
color: #b294bb;
|
||||
}
|
||||
.syn-constant.syn-other.syn-color {
|
||||
color: #8abeb7;
|
||||
}
|
||||
.syn-string.syn-regexp {
|
||||
color: #8abeb7;
|
||||
}
|
||||
.syn-constant.syn-character.syn-escape {
|
||||
color: #8abeb7;
|
||||
}
|
||||
.syn-punctuation.syn-section.syn-embedded {
|
||||
color: #b294bb;
|
||||
}
|
||||
.syn-variable.syn-interpolation {
|
||||
color: #b294bb;
|
||||
}
|
||||
.syn-invalid.syn-illegal {
|
||||
color: #ffffff;
|
||||
background-color: #cc6666;
|
||||
}
|
||||
.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: #1d1f21;
|
||||
color: #c5c8c6;
|
||||
padding: 0.5em;
|
||||
-webkit-text-size-adjust: none;
|
||||
}
|
|
@ -0,0 +1,215 @@
|
|||
/*
|
||||
* 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)
|
||||
*/
|
||||
|
||||
.syn-code {
|
||||
color: #6e6b5e;
|
||||
background-color: #fefbec;
|
||||
}
|
||||
|
||||
.syn-variable.syn-parameter.syn-function {
|
||||
color: #6e6b5e;
|
||||
}
|
||||
.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-none {
|
||||
color: #6e6b5e;
|
||||
}
|
||||
.syn-keyword.syn-operator {
|
||||
color: #6e6b5e;
|
||||
}
|
||||
.syn-keyword {
|
||||
color: #b854d4;
|
||||
}
|
||||
.syn-variable {
|
||||
color: #d73737;
|
||||
}
|
||||
.syn-entity.syn-name.syn-function {
|
||||
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-meta.syn-class {
|
||||
color: #292824;
|
||||
}
|
||||
.syn-keyword.syn-other.syn-special-method {
|
||||
color: #6684e1;
|
||||
}
|
||||
.syn-storage {
|
||||
color: #b854d4;
|
||||
}
|
||||
.syn-support.syn-function {
|
||||
color: #1fad83;
|
||||
}
|
||||
.syn-string {
|
||||
color: #60ac39;
|
||||
}
|
||||
.syn-constant.syn-other.syn-symbol {
|
||||
color: #60ac39;
|
||||
}
|
||||
.syn-entity.syn-other.syn-inherited-class {
|
||||
color: #60ac39;
|
||||
}
|
||||
.syn-constant.syn-numeric {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-none {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-none {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-constant {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-entity.syn-name.syn-tag {
|
||||
color: #d73737;
|
||||
}
|
||||
.syn-entity.syn-other.syn-attribute-name {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-entity.syn-other.syn-attribute-name.syn-id {
|
||||
color: #6684e1;
|
||||
}
|
||||
.syn-punctuation.syn-definition.syn-entity {
|
||||
color: #6684e1;
|
||||
}
|
||||
.syn-meta.syn-selector {
|
||||
color: #b854d4;
|
||||
}
|
||||
.syn-none {
|
||||
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-keyword.syn-other.syn-unit {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-markup.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;
|
||||
font-style: italic;
|
||||
}
|
||||
.syn-markup.syn-raw.syn-inline {
|
||||
color: #60ac39;
|
||||
}
|
||||
.syn-string.syn-other.syn-link {
|
||||
color: #d73737;
|
||||
}
|
||||
.syn-meta.syn-link {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-markup.syn-list {
|
||||
color: #d73737;
|
||||
}
|
||||
.syn-markup.syn-quote {
|
||||
color: #b65611;
|
||||
}
|
||||
.syn-meta.syn-separator {
|
||||
color: #6e6b5e;
|
||||
background-color: #e8e4cf;
|
||||
}
|
||||
.syn-markup.syn-inserted {
|
||||
color: #60ac39;
|
||||
}
|
||||
.syn-markup.syn-deleted {
|
||||
color: #d73737;
|
||||
}
|
||||
.syn-markup.syn-changed {
|
||||
color: #b854d4;
|
||||
}
|
||||
.syn-constant.syn-other.syn-color {
|
||||
color: #1fad83;
|
||||
}
|
||||
.syn-string.syn-regexp {
|
||||
color: #1fad83;
|
||||
}
|
||||
.syn-constant.syn-character.syn-escape {
|
||||
color: #1fad83;
|
||||
}
|
||||
.syn-punctuation.syn-section.syn-embedded {
|
||||
color: #d43552;
|
||||
}
|
||||
.syn-variable.syn-interpolation {
|
||||
color: #d43552;
|
||||
}
|
||||
.syn-invalid.syn-illegal {
|
||||
color: #fefbec;
|
||||
background-color: #d73737;
|
||||
}
|
||||
.syn-invalid.syn-broken {
|
||||
color: #20201d;
|
||||
background-color: #b65611;
|
||||
}
|
||||
.syn-invalid.syn-deprecated {
|
||||
color: #fefbec;
|
||||
background-color: #d43552;
|
||||
}
|
||||
.syn-invalid.syn-unimplemented {
|
||||
color: #20201d;
|
||||
background-color: #a6a28c;
|
||||
}
|
||||
.scode {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f6f7f6;
|
||||
color: #000;
|
||||
padding: 0.5em;
|
||||
}
|
|
@ -1,82 +0,0 @@
|
|||
/*
|
||||
* An increased contrast highlighting scheme loosely based on 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)
|
||||
*/
|
||||
|
||||
/* Comment */
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #575757;
|
||||
}
|
||||
|
||||
/* Red */
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #d70025;
|
||||
}
|
||||
|
||||
/* Orange */
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #b21e00;
|
||||
}
|
||||
|
||||
/* Green */
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #008200;
|
||||
}
|
||||
|
||||
/* Blue */
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #0030f2;
|
||||
}
|
||||
|
||||
/* Purple */
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #9d00ec;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #f6f7f6;
|
||||
color: #000;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #22863a;
|
||||
background-color: #f0fff4;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #b31d28;
|
||||
background-color: #ffeef0;
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -39,10 +39,10 @@
|
|||
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
|
||||
{{/if}}
|
||||
|
||||
<!-- Highlight.js Stylesheets -->
|
||||
<link rel="stylesheet" href="{{ path_to_root }}highlight.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
|
||||
<!-- Syntax Highlighting Stylesheets -->
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/syntax/light.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/syntax/dark.css">
|
||||
<link rel="stylesheet" href="{{ path_to_root }}css/syntax/ayu.css">
|
||||
|
||||
<!-- Custom theme stylesheets -->
|
||||
{{#each additional_css}}
|
||||
|
@ -284,7 +284,6 @@
|
|||
{{/if}}
|
||||
|
||||
<script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
|
||||
<script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
|
||||
|
||||
<!-- Custom JS scripts -->
|
||||
|
|
|
@ -24,10 +24,9 @@ pub static VARIABLES_CSS: &[u8] = include_bytes!("css/variables.css");
|
|||
pub static FAVICON_PNG: &[u8] = include_bytes!("favicon.png");
|
||||
pub static FAVICON_SVG: &[u8] = include_bytes!("favicon.svg");
|
||||
pub static JS: &[u8] = include_bytes!("book.js");
|
||||
pub static HIGHLIGHT_JS: &[u8] = include_bytes!("highlight.js");
|
||||
pub static TOMORROW_NIGHT_CSS: &[u8] = include_bytes!("tomorrow-night.css");
|
||||
pub static HIGHLIGHT_CSS: &[u8] = include_bytes!("highlight.css");
|
||||
pub static AYU_HIGHLIGHT_CSS: &[u8] = include_bytes!("ayu-highlight.css");
|
||||
pub static SYNTAX_DARK_CSS: &[u8] = include_bytes!("css/syntax/dark.css");
|
||||
pub static SYNTAX_LIGHT_CSS: &[u8] = include_bytes!("css/syntax/light.css");
|
||||
pub static SYNTAX_AYU_CSS: &[u8] = include_bytes!("css/syntax/ayu.css");
|
||||
pub static CLIPBOARD_JS: &[u8] = include_bytes!("clipboard.min.js");
|
||||
pub static FONT_AWESOME: &[u8] = include_bytes!("FontAwesome/css/font-awesome.min.css");
|
||||
pub static FONT_AWESOME_EOT: &[u8] = include_bytes!("FontAwesome/fonts/fontawesome-webfont.eot");
|
||||
|
@ -37,6 +36,7 @@ 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");
|
||||
|
||||
/// 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
|
||||
|
@ -57,11 +57,11 @@ pub struct Theme {
|
|||
pub favicon_png: Option<Vec<u8>>,
|
||||
pub favicon_svg: Option<Vec<u8>>,
|
||||
pub js: Vec<u8>,
|
||||
pub highlight_css: Vec<u8>,
|
||||
pub tomorrow_night_css: Vec<u8>,
|
||||
pub ayu_highlight_css: Vec<u8>,
|
||||
pub highlight_js: Vec<u8>,
|
||||
pub syntax_dark_css: Vec<u8>,
|
||||
pub syntax_light_css: Vec<u8>,
|
||||
pub syntax_ayu_css: Vec<u8>,
|
||||
pub clipboard_js: Vec<u8>,
|
||||
pub base_syntaxes: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Theme {
|
||||
|
@ -91,17 +91,20 @@ impl Theme {
|
|||
theme_dir.join("css/variables.css"),
|
||||
&mut theme.variables_css,
|
||||
),
|
||||
(theme_dir.join("highlight.js"), &mut theme.highlight_js),
|
||||
(theme_dir.join("clipboard.min.js"), &mut theme.clipboard_js),
|
||||
(theme_dir.join("highlight.css"), &mut theme.highlight_css),
|
||||
(
|
||||
theme_dir.join("tomorrow-night.css"),
|
||||
&mut theme.tomorrow_night_css,
|
||||
theme_dir.join("css/syntax/light.css"),
|
||||
&mut theme.syntax_light_css,
|
||||
),
|
||||
(
|
||||
theme_dir.join("ayu-highlight.css"),
|
||||
&mut theme.ayu_highlight_css,
|
||||
theme_dir.join("css/syntax/dark.css"),
|
||||
&mut theme.syntax_dark_css,
|
||||
),
|
||||
(
|
||||
theme_dir.join("css/syntax/ayu.css"),
|
||||
&mut theme.syntax_ayu_css,
|
||||
),
|
||||
(theme_dir.join("syntaxes.bin"), &mut theme.base_syntaxes),
|
||||
];
|
||||
|
||||
let load_with_warn = |filename: &Path, dest| {
|
||||
|
@ -156,11 +159,11 @@ impl Default for Theme {
|
|||
favicon_png: Some(FAVICON_PNG.to_owned()),
|
||||
favicon_svg: Some(FAVICON_SVG.to_owned()),
|
||||
js: JS.to_owned(),
|
||||
highlight_css: HIGHLIGHT_CSS.to_owned(),
|
||||
tomorrow_night_css: TOMORROW_NIGHT_CSS.to_owned(),
|
||||
ayu_highlight_css: AYU_HIGHLIGHT_CSS.to_owned(),
|
||||
highlight_js: HIGHLIGHT_JS.to_owned(),
|
||||
syntax_dark_css: SYNTAX_DARK_CSS.to_owned(),
|
||||
syntax_ayu_css: SYNTAX_AYU_CSS.to_owned(),
|
||||
syntax_light_css: SYNTAX_LIGHT_CSS.to_owned(),
|
||||
clipboard_js: CLIPBOARD_JS.to_owned(),
|
||||
base_syntaxes: SYNTAXES_BIN.to_owned(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -212,17 +215,18 @@ mod tests {
|
|||
"css/fonts.css",
|
||||
"css/general.css",
|
||||
"css/print.css",
|
||||
"css/syntax/ayu.css",
|
||||
"css/syntax/dark.css",
|
||||
"css/syntax/light.css",
|
||||
"css/variables.css",
|
||||
"book.js",
|
||||
"highlight.js",
|
||||
"tomorrow-night.css",
|
||||
"highlight.css",
|
||||
"ayu-highlight.css",
|
||||
"clipboard.min.js",
|
||||
"syntaxes.bin",
|
||||
];
|
||||
|
||||
let temp = TempFileBuilder::new().prefix("mdbook-").tempdir().unwrap();
|
||||
fs::create_dir(temp.path().join("css")).unwrap();
|
||||
fs::create_dir(temp.path().join("css/syntax")).unwrap();
|
||||
|
||||
// "touch" all of the special files so we have empty copies
|
||||
for file in &files {
|
||||
|
@ -243,11 +247,11 @@ mod tests {
|
|||
favicon_png: Some(Vec::new()),
|
||||
favicon_svg: Some(Vec::new()),
|
||||
js: Vec::new(),
|
||||
highlight_css: Vec::new(),
|
||||
tomorrow_night_css: Vec::new(),
|
||||
ayu_highlight_css: Vec::new(),
|
||||
highlight_js: Vec::new(),
|
||||
syntax_ayu_css: Vec::new(),
|
||||
syntax_dark_css: Vec::new(),
|
||||
syntax_light_css: Vec::new(),
|
||||
clipboard_js: Vec::new(),
|
||||
base_syntaxes: Vec::new(),
|
||||
};
|
||||
|
||||
assert_eq!(got, empty);
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1,476 @@
|
|||
%YAML 1.2
|
||||
---
|
||||
# http://www.sublimetext.com/docs/3/syntax.html
|
||||
name: Handlebars
|
||||
file_extensions:
|
||||
- handlebars
|
||||
- handlebars.html
|
||||
- hbr
|
||||
- hbrs
|
||||
- hbs
|
||||
- hdbs
|
||||
- hjs
|
||||
- mu
|
||||
- mustache
|
||||
- rac
|
||||
- stache
|
||||
- template
|
||||
- tmpl
|
||||
scope: text.html.handlebars
|
||||
contexts:
|
||||
main:
|
||||
- include: yfm
|
||||
- include: extends
|
||||
- include: block_comments
|
||||
- include: comments
|
||||
- include: block_helper
|
||||
- include: end_block
|
||||
- include: else_token
|
||||
- include: partial_and_var
|
||||
- include: inline_script
|
||||
- include: html_tags
|
||||
- include: scope:text.html.basic
|
||||
block_comments:
|
||||
- match: '\{\{!--'
|
||||
push:
|
||||
- meta_scope: comment.block.handlebars
|
||||
- match: '--\}\}'
|
||||
pop: true
|
||||
- match: '@\w*'
|
||||
scope: keyword.annotation.handlebars
|
||||
- include: comments
|
||||
- match: <!--
|
||||
captures:
|
||||
0: punctuation.definition.comment.html
|
||||
push:
|
||||
- meta_scope: comment.block.html
|
||||
- match: '-{2,3}\s*>'
|
||||
captures:
|
||||
0: punctuation.definition.comment.html
|
||||
pop: true
|
||||
- match: "--"
|
||||
scope: invalid.illegal.bad-comments-or-CDATA.html
|
||||
block_helper:
|
||||
- match: '(\{\{)(~?\#)([-a-zA-Z0-9_\./>]+)\s?(@?[-a-zA-Z0-9_\./]+)*\s?(@?[-a-zA-Z0-9_\./]+)*\s?(@?[-a-zA-Z0-9_\./]+)*'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
2: support.constant.handlebars keyword.control
|
||||
3: support.constant.handlebars keyword.control
|
||||
4: variable.parameter.handlebars
|
||||
5: support.constant.handlebars
|
||||
6: variable.parameter.handlebars
|
||||
7: support.constant.handlebars
|
||||
push:
|
||||
- meta_scope: meta.function.block.start.handlebars
|
||||
- match: '(~?\}\})'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
pop: true
|
||||
- include: string
|
||||
- include: handlebars_attribute
|
||||
comments:
|
||||
- match: '\{\{!'
|
||||
push:
|
||||
- meta_scope: comment.block.handlebars
|
||||
- match: '\}\}'
|
||||
pop: true
|
||||
- match: '@\w*'
|
||||
scope: keyword.annotation.handlebars
|
||||
- include: comments
|
||||
- match: <!--
|
||||
captures:
|
||||
0: punctuation.definition.comment.html
|
||||
push:
|
||||
- meta_scope: comment.block.html
|
||||
- match: '-{2,3}\s*>'
|
||||
captures:
|
||||
0: punctuation.definition.comment.html
|
||||
pop: true
|
||||
- match: "--"
|
||||
scope: invalid.illegal.bad-comments-or-CDATA.html
|
||||
else_token:
|
||||
- match: '(\{\{)(~?else)(@?\s(if)\s([-a-zA-Z0-9_\.\(\s\)/]+))?'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
2: support.constant.handlebars keyword.control
|
||||
3: support.constant.handlebars
|
||||
4: variable.parameter.handlebars
|
||||
push:
|
||||
- meta_scope: meta.function.inline.else.handlebars
|
||||
- match: '(~?\}\}\}*)'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
pop: true
|
||||
end_block:
|
||||
- match: '(\{\{)(~?/)([a-zA-Z0-9/_\.-]+)\s*'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
2: support.constant.handlebars keyword.control
|
||||
3: support.constant.handlebars keyword.control
|
||||
push:
|
||||
- meta_scope: meta.function.block.end.handlebars
|
||||
- match: '(~?\}\})'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
pop: true
|
||||
entities:
|
||||
- match: "(&)([a-zA-Z0-9]+|#[0-9]+|#x[0-9a-fA-F]+)(;)"
|
||||
scope: constant.character.entity.html
|
||||
captures:
|
||||
1: punctuation.definition.entity.html
|
||||
3: punctuation.definition.entity.html
|
||||
- match: "&"
|
||||
scope: invalid.illegal.bad-ampersand.html
|
||||
escaped-double-quote:
|
||||
- match: \\"
|
||||
scope: constant.character.escape.js
|
||||
escaped-single-quote:
|
||||
- match: \\'
|
||||
scope: constant.character.escape.js
|
||||
extends:
|
||||
- match: '(\{\{!<)\s([-a-zA-Z0-9_\./]+)'
|
||||
captures:
|
||||
1: support.function.handlebars
|
||||
2: support.class.handlebars
|
||||
push:
|
||||
- meta_scope: meta.preprocessor.handlebars
|
||||
- match: '(\}\})'
|
||||
captures:
|
||||
1: support.function.handlebars
|
||||
pop: true
|
||||
handlebars_attribute:
|
||||
- include: handlebars_attribute_name
|
||||
- include: handlebars_attribute_value
|
||||
handlebars_attribute_name:
|
||||
- match: '\b([-a-zA-Z0-9_\.]+)\b='
|
||||
captures:
|
||||
1: variable.parameter.handlebars
|
||||
push:
|
||||
- meta_scope: entity.other.attribute-name.handlebars
|
||||
- match: (?='|"|)
|
||||
captures:
|
||||
1: variable.parameter.handlebars
|
||||
pop: true
|
||||
handlebars_attribute_value:
|
||||
- match: '([-a-zA-Z0-9_\./]+)\b'
|
||||
captures:
|
||||
1: variable.parameter.handlebars
|
||||
push:
|
||||
- meta_scope: entity.other.attribute-value.handlebars
|
||||
- match: ('|"|)
|
||||
captures:
|
||||
1: variable.parameter.handlebars
|
||||
pop: true
|
||||
- include: string
|
||||
html_tags:
|
||||
- match: '(<)([a-zA-Z0-9:-]+)(?=[^>]*></\2>)'
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.html
|
||||
push:
|
||||
- meta_scope: meta.tag.any.html
|
||||
- match: (>(<)/)(\2)(>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: meta.scope.between-tag-pair.html
|
||||
3: entity.name.tag.html
|
||||
4: punctuation.definition.tag.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: (<\?)(xml)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.xml.html
|
||||
push:
|
||||
- meta_scope: meta.tag.preprocessor.xml.html
|
||||
- match: (\?>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.xml.html
|
||||
pop: true
|
||||
- include: tag_generic_attribute
|
||||
- include: string
|
||||
- match: <!--
|
||||
captures:
|
||||
0: punctuation.definition.comment.html
|
||||
push:
|
||||
- meta_scope: comment.block.html
|
||||
- match: '--\s*>'
|
||||
captures:
|
||||
0: punctuation.definition.comment.html
|
||||
pop: true
|
||||
- match: "--"
|
||||
scope: invalid.illegal.bad-comments-or-CDATA.html
|
||||
- match: <!
|
||||
captures:
|
||||
0: punctuation.definition.tag.html
|
||||
push:
|
||||
- meta_scope: meta.tag.sgml.html
|
||||
- match: ">"
|
||||
captures:
|
||||
0: punctuation.definition.tag.html
|
||||
pop: true
|
||||
- match: (DOCTYPE|doctype)
|
||||
captures:
|
||||
1: entity.name.tag.doctype.html
|
||||
push:
|
||||
- meta_scope: meta.tag.sgml.doctype.html
|
||||
- match: (?=>)
|
||||
captures:
|
||||
1: entity.name.tag.doctype.html
|
||||
pop: true
|
||||
- match: '"[^">]*"'
|
||||
scope: string.quoted.double.doctype.identifiers-and-DTDs.html
|
||||
- match: '\[CDATA\['
|
||||
push:
|
||||
- meta_scope: constant.other.inline-data.html
|
||||
- match: "]](?=>)"
|
||||
pop: true
|
||||
- match: (\s*)(?!--|>)\S(\s*)
|
||||
scope: invalid.illegal.bad-comments-or-CDATA.html
|
||||
- match: '(?:^\s+)?(<)((?i:style))\b(?![^>]*/>)'
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.style.html
|
||||
3: punctuation.definition.tag.html
|
||||
push:
|
||||
- meta_scope: source.css.embedded.html
|
||||
- match: (</)((?i:style))(>)(?:\s*\n)?
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.style.html
|
||||
3: punctuation.definition.tag.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: (>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
push:
|
||||
- match: (?=</(?i:style))
|
||||
pop: true
|
||||
- include: scope:source.css
|
||||
- match: '(?:^\s+)?(<)((?i:script))\b(?![^>]*/>)'
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.script.html
|
||||
push:
|
||||
- meta_scope: source.js.embedded.html
|
||||
- match: (?<=</(script|SCRIPT))(>)(?:\s*\n)?
|
||||
captures:
|
||||
2: punctuation.definition.tag.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: (?<!</(?:script|SCRIPT))(>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.script.html
|
||||
push:
|
||||
- match: (</)((?i:script))
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.script.html
|
||||
pop: true
|
||||
- match: (//).*?((?=</script)|$\n?)
|
||||
scope: comment.line.double-slash.js
|
||||
captures:
|
||||
1: punctuation.definition.comment.js
|
||||
- match: /\*
|
||||
captures:
|
||||
0: punctuation.definition.comment.js
|
||||
push:
|
||||
- meta_scope: comment.block.js
|
||||
- match: \*/|(?=</script)
|
||||
captures:
|
||||
0: punctuation.definition.comment.js
|
||||
pop: true
|
||||
- include: scope:source.js
|
||||
- match: (</?)((?i:body|head|html)\b)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.structure.any.html
|
||||
push:
|
||||
- meta_scope: meta.tag.structure.any.html
|
||||
- match: (>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.structure.any.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: (</?)((?i:address|blockquote|dd|div|header|section|footer|aside|nav|dl|dt|fieldset|form|frame|frameset|h1|h2|h3|h4|h5|h6|iframe|noframes|object|ol|p|ul|applet|center|dir|hr|menu|pre)\b)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.block.any.html
|
||||
push:
|
||||
- meta_scope: meta.tag.block.any.html
|
||||
- match: (>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.block.any.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: (</?)((?i:a|abbr|acronym|area|b|base|basefont|bdo|big|br|button|caption|cite|code|col|colgroup|del|dfn|em|font|head|html|i|img|input|ins|isindex|kbd|label|legend|li|link|map|meta|noscript|optgroup|option|param|q|s|samp|script|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|title|tr|tt|u|var)\b)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.inline.any.html
|
||||
push:
|
||||
- meta_scope: meta.tag.inline.any.html
|
||||
- match: "((?: ?/)?>)"
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.inline.any.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: "(</?)([a-zA-Z0-9:-]+)"
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.other.html
|
||||
push:
|
||||
- meta_scope: meta.tag.other.html
|
||||
- match: (>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.other.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: "(</?)([a-zA-Z0-9{}:-]+)"
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.tokenised.html
|
||||
push:
|
||||
- meta_scope: meta.tag.tokenised.html
|
||||
- match: (>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.tokenised.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- include: entities
|
||||
- match: <>
|
||||
scope: invalid.illegal.incomplete.html
|
||||
- match: <
|
||||
scope: invalid.illegal.bad-angle-bracket.html
|
||||
inline_script:
|
||||
- match: '(?:^\s+)?(<)((?i:script))\b(?:.*(type)=(["''](?:text/x-handlebars-template|text/x-handlebars|text/template|x-tmpl-handlebars)["'']))(?![^>]*/>)'
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.script.html
|
||||
3: entity.other.attribute-name.html
|
||||
4: string.quoted.double.html
|
||||
push:
|
||||
- meta_scope: source.handlebars.embedded.html
|
||||
- match: (?<=</(script|SCRIPT))(>)(?:\s*\n)?
|
||||
captures:
|
||||
2: punctuation.definition.tag.html
|
||||
pop: true
|
||||
- include: tag-stuff
|
||||
- match: (?<!</(?:script|SCRIPT))(>)
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.script.html
|
||||
push:
|
||||
- match: (</)((?i:script))
|
||||
captures:
|
||||
1: punctuation.definition.tag.html
|
||||
2: entity.name.tag.script.html
|
||||
pop: true
|
||||
- include: block_comments
|
||||
- include: comments
|
||||
- include: block_helper
|
||||
- include: end_block
|
||||
- include: else_token
|
||||
- include: partial_and_var
|
||||
- include: html_tags
|
||||
- include: scope:text.html.basic
|
||||
partial_and_var:
|
||||
- match: '(\{\{~?\{*(>|!<)*)\s*(@?[-a-zA-Z0-9$_\./]+)*'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
3: variable.parameter.handlebars
|
||||
push:
|
||||
- meta_scope: meta.function.inline.other.handlebars
|
||||
- match: '(~?\}\}\}*)'
|
||||
captures:
|
||||
1: support.constant.handlebars
|
||||
pop: true
|
||||
- include: string
|
||||
- include: handlebars_attribute
|
||||
string:
|
||||
- include: string-single-quoted
|
||||
- include: string-double-quoted
|
||||
string-double-quoted:
|
||||
- match: '"'
|
||||
captures:
|
||||
0: punctuation.definition.string.begin.html
|
||||
push:
|
||||
- meta_scope: string.quoted.double.handlebars
|
||||
- match: '"'
|
||||
captures:
|
||||
0: punctuation.definition.string.end.html
|
||||
pop: true
|
||||
- include: escaped-double-quote
|
||||
- include: block_comments
|
||||
- include: comments
|
||||
- include: block_helper
|
||||
- include: else_token
|
||||
- include: end_block
|
||||
- include: partial_and_var
|
||||
string-single-quoted:
|
||||
- match: "'"
|
||||
captures:
|
||||
0: punctuation.definition.string.begin.html
|
||||
push:
|
||||
- meta_scope: string.quoted.single.handlebars
|
||||
- match: "'"
|
||||
captures:
|
||||
0: punctuation.definition.string.end.html
|
||||
pop: true
|
||||
- include: escaped-single-quote
|
||||
- include: block_comments
|
||||
- include: comments
|
||||
- include: block_helper
|
||||
- include: else_token
|
||||
- include: end_block
|
||||
- include: partial_and_var
|
||||
tag-stuff:
|
||||
- include: tag_id_attribute
|
||||
- include: tag_generic_attribute
|
||||
- include: string
|
||||
- include: block_comments
|
||||
- include: comments
|
||||
- include: block_helper
|
||||
- include: end_block
|
||||
- include: else_token
|
||||
- include: partial_and_var
|
||||
tag_generic_attribute:
|
||||
- match: '\b([a-zA-Z0-9_-]+)\b\s*(=)'
|
||||
captures:
|
||||
1: entity.other.attribute-name.generic.html
|
||||
2: punctuation.separator.key-value.html
|
||||
push:
|
||||
- meta_scope: entity.other.attribute-name.html
|
||||
- match: (?<='|"|)
|
||||
captures:
|
||||
1: entity.other.attribute-name.generic.html
|
||||
2: punctuation.separator.key-value.html
|
||||
pop: true
|
||||
- include: string
|
||||
tag_id_attribute:
|
||||
- match: \b(id)\b\s*(=)
|
||||
captures:
|
||||
1: entity.other.attribute-name.id.html
|
||||
2: punctuation.separator.key-value.html
|
||||
push:
|
||||
- meta_scope: meta.attribute-with-value.id.html
|
||||
- match: (?<='|"|)
|
||||
captures:
|
||||
1: entity.other.attribute-name.id.html
|
||||
2: punctuation.separator.key-value.html
|
||||
pop: true
|
||||
- include: string
|
||||
yfm:
|
||||
- match: (?<!\s)---\n$
|
||||
push:
|
||||
- meta_scope: markup.raw.yaml.front-matter
|
||||
- match: ^---\s
|
||||
pop: true
|
||||
- include: scope:source.yaml
|
|
@ -0,0 +1,16 @@
|
|||
# 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.
|
||||
|
||||
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.
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/env bash
|
||||
set -Eeuxo pipefail
|
||||
|
||||
bat cache --build --source=".." --target=".."
|
||||
rm -f ../themes.bin
|
||||
rm -f ../metadata.yaml
|
|
@ -1,102 +0,0 @@
|
|||
/* Tomorrow Night Theme */
|
||||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
|
||||
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
|
||||
|
||||
/* Tomorrow Comment */
|
||||
.hljs-comment {
|
||||
color: #969896;
|
||||
}
|
||||
|
||||
/* Tomorrow Red */
|
||||
.hljs-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-regexp,
|
||||
.ruby .hljs-constant,
|
||||
.xml .hljs-tag .hljs-title,
|
||||
.xml .hljs-pi,
|
||||
.xml .hljs-doctype,
|
||||
.html .hljs-doctype,
|
||||
.css .hljs-id,
|
||||
.css .hljs-class,
|
||||
.css .hljs-pseudo {
|
||||
color: #cc6666;
|
||||
}
|
||||
|
||||
/* Tomorrow Orange */
|
||||
.hljs-number,
|
||||
.hljs-preprocessor,
|
||||
.hljs-pragma,
|
||||
.hljs-built_in,
|
||||
.hljs-literal,
|
||||
.hljs-params,
|
||||
.hljs-constant {
|
||||
color: #de935f;
|
||||
}
|
||||
|
||||
/* Tomorrow Yellow */
|
||||
.ruby .hljs-class .hljs-title,
|
||||
.css .hljs-rule .hljs-attribute {
|
||||
color: #f0c674;
|
||||
}
|
||||
|
||||
/* Tomorrow Green */
|
||||
.hljs-string,
|
||||
.hljs-value,
|
||||
.hljs-inheritance,
|
||||
.hljs-header,
|
||||
.hljs-name,
|
||||
.ruby .hljs-symbol,
|
||||
.xml .hljs-cdata {
|
||||
color: #b5bd68;
|
||||
}
|
||||
|
||||
/* Tomorrow Aqua */
|
||||
.hljs-title,
|
||||
.css .hljs-hexcolor {
|
||||
color: #8abeb7;
|
||||
}
|
||||
|
||||
/* Tomorrow Blue */
|
||||
.hljs-function,
|
||||
.python .hljs-decorator,
|
||||
.python .hljs-title,
|
||||
.ruby .hljs-function .hljs-title,
|
||||
.ruby .hljs-title .hljs-keyword,
|
||||
.perl .hljs-sub,
|
||||
.javascript .hljs-title,
|
||||
.coffeescript .hljs-title {
|
||||
color: #81a2be;
|
||||
}
|
||||
|
||||
/* Tomorrow Purple */
|
||||
.hljs-keyword,
|
||||
.javascript .hljs-function {
|
||||
color: #b294bb;
|
||||
}
|
||||
|
||||
.hljs {
|
||||
display: block;
|
||||
overflow-x: auto;
|
||||
background: #1d1f21;
|
||||
color: #c5c8c6;
|
||||
}
|
||||
|
||||
.coffeescript .javascript,
|
||||
.javascript .xml,
|
||||
.tex .hljs-formula,
|
||||
.xml .javascript,
|
||||
.xml .vbscript,
|
||||
.xml .css,
|
||||
.xml .hljs-cdata {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.hljs-addition {
|
||||
color: #718c00;
|
||||
}
|
||||
|
||||
.hljs-deletion {
|
||||
color: #c82829;
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
//! Syntax highlighter with support for hiding lines.
|
||||
//! This is essentially a version of [`syntect::html::ClassedHTMLGenerator`]
|
||||
//! which allows you to mark a line as boring (hidden).
|
||||
|
||||
use std::borrow::Cow;
|
||||
|
||||
use regex::Regex;
|
||||
use syntect::{
|
||||
html::{self, ClassStyle},
|
||||
parsing::{ParseState, ScopeStack, SyntaxReference, SyntaxSet},
|
||||
};
|
||||
|
||||
pub struct HtmlGenerator<'a> {
|
||||
syntaxes: &'a SyntaxSet,
|
||||
open_spans: isize,
|
||||
parse_state: ParseState,
|
||||
scope_stack: ScopeStack,
|
||||
html: String,
|
||||
style: ClassStyle,
|
||||
}
|
||||
|
||||
impl<'a> HtmlGenerator<'a> {
|
||||
pub fn new(syntax: &'a SyntaxReference, syntaxes: &'a SyntaxSet, style: ClassStyle) -> Self {
|
||||
let parse_state = ParseState::new(syntax);
|
||||
let open_spans = 0;
|
||||
let html = String::new();
|
||||
let scope_stack = ScopeStack::new();
|
||||
Self {
|
||||
syntaxes,
|
||||
open_spans,
|
||||
parse_state,
|
||||
scope_stack,
|
||||
html,
|
||||
style,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn parse_line(&mut self, line: &str, is_rust: bool) {
|
||||
let (line, did_boringify) = if is_rust {
|
||||
let (line, did_boringify) = boringify(line);
|
||||
(Cow::from(line), did_boringify)
|
||||
} else {
|
||||
(Cow::from(line), false)
|
||||
};
|
||||
let parsed_line = self.parse_state.parse_line(&line, self.syntaxes);
|
||||
let (formatted_line, delta) = html::line_tokens_to_classed_spans(
|
||||
&line,
|
||||
parsed_line.as_slice(),
|
||||
self.style,
|
||||
&mut self.scope_stack,
|
||||
);
|
||||
self.open_spans += delta;
|
||||
self.html.push_str(&if did_boringify {
|
||||
format!("<span class=\"boring\">{}</span>", formatted_line)
|
||||
} else {
|
||||
formatted_line
|
||||
});
|
||||
}
|
||||
|
||||
pub fn finalize(mut self) -> String {
|
||||
for _ in 0..self.open_spans {
|
||||
self.html.push_str("</span>");
|
||||
}
|
||||
self.html
|
||||
}
|
||||
}
|
||||
|
||||
lazy_static! {
|
||||
static ref BORING_LINE_REGEX: Regex = Regex::new(r"^(\s*)#(.?)(.*)\n$").unwrap();
|
||||
}
|
||||
|
||||
fn boringify(line: &str) -> (String, bool) {
|
||||
let mut result = String::with_capacity(line.len());
|
||||
if let Some(caps) = BORING_LINE_REGEX.captures(line) {
|
||||
if &caps[2] == "#" {
|
||||
result += &caps[1];
|
||||
result += &caps[2];
|
||||
result += &caps[3];
|
||||
result += "\n";
|
||||
return (result, true);
|
||||
} else if &caps[2] != "!" && &caps[2] != "[" {
|
||||
result += &caps[1];
|
||||
if &caps[2] != " " {
|
||||
result += &caps[2];
|
||||
}
|
||||
result += &caps[3];
|
||||
result += "\n";
|
||||
return (result, true);
|
||||
}
|
||||
}
|
||||
result += line;
|
||||
result += "\n";
|
||||
|
||||
(result, false)
|
||||
}
|
184
src/utils/mod.rs
184
src/utils/mod.rs
|
@ -1,12 +1,17 @@
|
|||
#![allow(missing_docs)] // FIXME: Document this
|
||||
|
||||
pub mod fs;
|
||||
pub mod highlight;
|
||||
mod string;
|
||||
pub(crate) mod toml_ext;
|
||||
use crate::errors::Error;
|
||||
use regex::Regex;
|
||||
|
||||
use pulldown_cmark::{html, CodeBlockKind, CowStr, Event, Options, Parser, Tag};
|
||||
use syntect::html::ClassStyle;
|
||||
use syntect::parsing::SyntaxReference;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
use syntect::util::LinesWithEndings;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
|
@ -179,8 +184,8 @@ fn adjust_links<'a>(event: Event<'a>, path: Option<&Path>) -> Event<'a> {
|
|||
}
|
||||
|
||||
/// Wrapper around the pulldown-cmark parser for rendering markdown to HTML.
|
||||
pub fn render_markdown(text: &str, curly_quotes: bool) -> String {
|
||||
render_markdown_with_path(text, curly_quotes, None)
|
||||
pub fn render_markdown(text: &str, curly_quotes: bool, syntaxes: &SyntaxSet) -> String {
|
||||
render_markdown_with_path(text, curly_quotes, None, syntaxes)
|
||||
}
|
||||
|
||||
pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> {
|
||||
|
@ -195,11 +200,18 @@ pub fn new_cmark_parser(text: &str, curly_quotes: bool) -> Parser<'_, '_> {
|
|||
Parser::new_ext(text, opts)
|
||||
}
|
||||
|
||||
pub fn render_markdown_with_path(text: &str, curly_quotes: bool, path: Option<&Path>) -> String {
|
||||
pub fn render_markdown_with_path(
|
||||
text: &str,
|
||||
curly_quotes: bool,
|
||||
path: Option<&Path>,
|
||||
syntaxes: &SyntaxSet,
|
||||
) -> String {
|
||||
let mut s = String::with_capacity(text.len() * 3 / 2);
|
||||
let p = new_cmark_parser(text, curly_quotes);
|
||||
let mut highlighter = SyntaxHighlighter::default();
|
||||
let events = p
|
||||
.map(clean_codeblock_headers)
|
||||
.map(|event| highlighter.highlight(syntaxes, event))
|
||||
.map(|event| adjust_links(event, path))
|
||||
.flat_map(|event| {
|
||||
let (a, b) = wrap_tables(event);
|
||||
|
@ -222,6 +234,107 @@ fn wrap_tables(event: Event<'_>) -> (Option<Event<'_>>, Option<Event<'_>>) {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct SyntaxHighlighter<'a> {
|
||||
highlight: bool,
|
||||
is_rust: bool,
|
||||
syntax: Option<&'a SyntaxReference>,
|
||||
}
|
||||
|
||||
impl<'a> SyntaxHighlighter<'a> {
|
||||
fn highlight<'b>(&mut self, syntaxes: &'a SyntaxSet, event: Event<'b>) -> Event<'b> {
|
||||
match event {
|
||||
Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(ref info))) => {
|
||||
self.highlight = true;
|
||||
let lang_name = info.split(',').next();
|
||||
if let Some(name) = lang_name {
|
||||
// If we're given an empty name, or it is marked as
|
||||
// plaintext, we shouldn't highlight it.
|
||||
if name.is_empty()
|
||||
|| name.eq_ignore_ascii_case("plaintext")
|
||||
|| name.eq_ignore_ascii_case("text")
|
||||
|| name.eq_ignore_ascii_case("plain")
|
||||
|| name.eq_ignore_ascii_case("txt")
|
||||
{
|
||||
self.highlight = false;
|
||||
return event;
|
||||
}
|
||||
|
||||
self.syntax = syntaxes.find_syntax_by_token(name);
|
||||
if self.syntax.is_none() {
|
||||
self.highlight = false;
|
||||
return event;
|
||||
}
|
||||
if let Some(syntax) = self.syntax {
|
||||
if syntax.name == "Rust" {
|
||||
self.is_rust = true;
|
||||
}
|
||||
}
|
||||
event
|
||||
} else {
|
||||
// We also don't perform auto-detection of languages, so we
|
||||
// shouldn't highlight code blocks without lang tags.
|
||||
self.highlight = false;
|
||||
event
|
||||
}
|
||||
}
|
||||
Event::End(Tag::CodeBlock(CodeBlockKind::Fenced(_))) => {
|
||||
self.highlight = false;
|
||||
self.is_rust = false;
|
||||
self.syntax = None;
|
||||
event
|
||||
}
|
||||
Event::Text(ref code) if self.highlight => {
|
||||
let mut gen = highlight::HtmlGenerator::new(
|
||||
self.syntax.unwrap(),
|
||||
syntaxes,
|
||||
ClassStyle::SpacedPrefixed { prefix: "syn-" },
|
||||
);
|
||||
for line in LinesWithEndings::from(code) {
|
||||
gen.parse_line(line, self.is_rust);
|
||||
}
|
||||
Event::Html(CowStr::from(gen.finalize()))
|
||||
}
|
||||
_ => event,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct EventQuoteConverter {
|
||||
enabled: bool,
|
||||
convert_text: bool,
|
||||
}
|
||||
|
||||
impl EventQuoteConverter {
|
||||
fn new(enabled: bool) -> Self {
|
||||
EventQuoteConverter {
|
||||
enabled,
|
||||
convert_text: true,
|
||||
}
|
||||
}
|
||||
|
||||
fn convert<'a>(&mut self, event: Event<'a>) -> Event<'a> {
|
||||
if !self.enabled {
|
||||
return event;
|
||||
}
|
||||
|
||||
match event {
|
||||
Event::Start(Tag::CodeBlock(_)) => {
|
||||
self.convert_text = false;
|
||||
event
|
||||
}
|
||||
Event::End(Tag::CodeBlock(_)) => {
|
||||
self.convert_text = true;
|
||||
event
|
||||
}
|
||||
Event::Text(ref text) if self.convert_text => {
|
||||
Event::Text(CowStr::from(convert_quotes_to_curly(text)))
|
||||
}
|
||||
_ => event,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn clean_codeblock_headers(event: Event<'_>) -> Event<'_> {
|
||||
match event {
|
||||
Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(ref info))) => {
|
||||
|
@ -270,12 +383,21 @@ mod tests {
|
|||
use super::bracket_escape;
|
||||
|
||||
mod render_markdown {
|
||||
use syntect::parsing::SyntaxSet;
|
||||
fn default_syntaxes() -> SyntaxSet {
|
||||
syntect::dumps::from_binary(crate::theme::SYNTAXES_BIN)
|
||||
}
|
||||
|
||||
use super::super::render_markdown;
|
||||
|
||||
#[test]
|
||||
fn preserves_external_links() {
|
||||
assert_eq!(
|
||||
render_markdown("[example](https://www.rust-lang.org/)", false),
|
||||
render_markdown(
|
||||
"[example](https://www.rust-lang.org/)",
|
||||
false,
|
||||
&default_syntaxes()
|
||||
),
|
||||
"<p><a href=\"https://www.rust-lang.org/\">example</a></p>\n"
|
||||
);
|
||||
}
|
||||
|
@ -283,17 +405,25 @@ mod tests {
|
|||
#[test]
|
||||
fn it_can_adjust_markdown_links() {
|
||||
assert_eq!(
|
||||
render_markdown("[example](example.md)", false),
|
||||
render_markdown("[example](example.md)", false, &default_syntaxes()),
|
||||
"<p><a href=\"example.html\">example</a></p>\n"
|
||||
);
|
||||
assert_eq!(
|
||||
render_markdown("[example_anchor](example.md#anchor)", false),
|
||||
render_markdown(
|
||||
"[example_anchor](example.md#anchor)",
|
||||
false,
|
||||
&default_syntaxes()
|
||||
),
|
||||
"<p><a href=\"example.html#anchor\">example_anchor</a></p>\n"
|
||||
);
|
||||
|
||||
// this anchor contains 'md' inside of it
|
||||
assert_eq!(
|
||||
render_markdown("[phantom data](foo.html#phantomdata)", false),
|
||||
render_markdown(
|
||||
"[phantom data](foo.html#phantomdata)",
|
||||
false,
|
||||
&default_syntaxes()
|
||||
),
|
||||
"<p><a href=\"foo.html#phantomdata\">phantom data</a></p>\n"
|
||||
);
|
||||
}
|
||||
|
@ -316,7 +446,10 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn it_can_keep_quotes_straight() {
|
||||
assert_eq!(render_markdown("'one'", false), "<p>'one'</p>\n");
|
||||
assert_eq!(
|
||||
render_markdown("'one'", false, &default_syntaxes()),
|
||||
"<p>'one'</p>\n"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -332,7 +465,7 @@ mod tests {
|
|||
</code></pre>
|
||||
<p><code>'three'</code> ‘four’</p>
|
||||
"#;
|
||||
assert_eq!(render_markdown(input, true), expected);
|
||||
assert_eq!(render_markdown(input, true, &default_syntaxes()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -348,14 +481,17 @@ more text with spaces
|
|||
"#;
|
||||
|
||||
let expected = r#"<p>some text with spaces</p>
|
||||
<pre><code class="language-rust">fn main() {
|
||||
// code inside is unchanged
|
||||
}
|
||||
</code></pre>
|
||||
<pre><code class="language-rust"><span class="syn-source syn-rust"><span class="syn-meta syn-function syn-rust"><span class="syn-meta syn-function syn-rust"><span class="syn-storage syn-type syn-function syn-rust">fn</span> </span><span class="syn-entity syn-name syn-function syn-rust">main</span></span><span class="syn-meta syn-function syn-rust"><span class="syn-meta syn-function syn-parameters syn-rust"><span class="syn-punctuation syn-section syn-parameters syn-begin syn-rust">(</span></span><span class="syn-meta syn-function syn-rust"><span class="syn-meta syn-function syn-parameters syn-rust"><span class="syn-punctuation syn-section syn-parameters syn-end syn-rust">)</span></span></span></span><span class="syn-meta syn-function syn-rust"> </span><span class="syn-meta syn-function syn-rust"><span class="syn-meta syn-block syn-rust"><span class="syn-punctuation syn-section syn-block syn-begin syn-rust">{</span>
|
||||
|
||||
<span class="syn-comment syn-line syn-double-slash syn-rust"><span class="syn-punctuation syn-definition syn-comment syn-rust">//</span> code inside is unchanged
|
||||
</span>
|
||||
</span><span class="syn-meta syn-block syn-rust"><span class="syn-punctuation syn-section syn-block syn-end syn-rust">}</span></span></span>
|
||||
|
||||
</span></code></pre>
|
||||
<p>more text with spaces</p>
|
||||
"#;
|
||||
assert_eq!(render_markdown(input, false), expected);
|
||||
assert_eq!(render_markdown(input, true), expected);
|
||||
assert_eq!(render_markdown(input, false, &default_syntaxes()), expected);
|
||||
assert_eq!(render_markdown(input, true, &default_syntaxes()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -367,8 +503,8 @@ more text with spaces
|
|||
|
||||
let expected = r#"<pre><code class="language-rust,no_run,should_panic,property_3"></code></pre>
|
||||
"#;
|
||||
assert_eq!(render_markdown(input, false), expected);
|
||||
assert_eq!(render_markdown(input, true), expected);
|
||||
assert_eq!(render_markdown(input, false, &default_syntaxes()), expected);
|
||||
assert_eq!(render_markdown(input, true, &default_syntaxes()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -380,8 +516,8 @@ more text with spaces
|
|||
|
||||
let expected = r#"<pre><code class="language-rust,,,,,no_run,,,should_panic,,,,property_3"></code></pre>
|
||||
"#;
|
||||
assert_eq!(render_markdown(input, false), expected);
|
||||
assert_eq!(render_markdown(input, true), expected);
|
||||
assert_eq!(render_markdown(input, false, &default_syntaxes()), expected);
|
||||
assert_eq!(render_markdown(input, true, &default_syntaxes()), expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -393,15 +529,17 @@ more text with spaces
|
|||
|
||||
let expected = r#"<pre><code class="language-rust"></code></pre>
|
||||
"#;
|
||||
assert_eq!(render_markdown(input, false), expected);
|
||||
assert_eq!(render_markdown(input, true), expected);
|
||||
assert_eq!(render_markdown(input, false, &default_syntaxes()), expected);
|
||||
assert_eq!(render_markdown(input, true, &default_syntaxes()), expected);
|
||||
|
||||
// FIXME: Why are we doing this twice? It seems to be the same
|
||||
// input and assertions.
|
||||
let input = r#"
|
||||
```rust
|
||||
```
|
||||
"#;
|
||||
assert_eq!(render_markdown(input, false), expected);
|
||||
assert_eq!(render_markdown(input, true), expected);
|
||||
assert_eq!(render_markdown(input, false, &default_syntaxes()), expected);
|
||||
assert_eq!(render_markdown(input, true, &default_syntaxes()), expected);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -118,11 +118,10 @@ fn copy_theme() {
|
|||
"css/chrome.css",
|
||||
"css/general.css",
|
||||
"css/print.css",
|
||||
"css/syntax/light.css",
|
||||
"css/variables.css",
|
||||
"favicon.png",
|
||||
"favicon.svg",
|
||||
"highlight.css",
|
||||
"highlight.js",
|
||||
"index.hbs",
|
||||
];
|
||||
let theme_dir = temp.path().join("theme");
|
||||
|
|
|
@ -193,8 +193,8 @@ fn rustdoc_include_hides_the_unspecified_part_of_the_file() {
|
|||
|
||||
let nested = temp.path().join("book/first/nested.html");
|
||||
let text = vec![
|
||||
"<span class=\"boring\">fn some_function() {",
|
||||
"<span class=\"boring\">fn some_other_function() {",
|
||||
r#"<span class="boring"><span class="syn-source syn-rust"><span class="syn-meta syn-function syn-rust"><span class="syn-meta syn-function syn-rust"><span class="syn-storage syn-type syn-function syn-rust">fn</span> </span><span class="syn-entity syn-name syn-function syn-rust">some_function"#,
|
||||
r#"<span class="boring"><span class="syn-source syn-rust"><span class="syn-meta syn-function syn-rust"><span class="syn-meta syn-function syn-rust"><span class="syn-storage syn-type syn-function syn-rust">fn</span> </span><span class="syn-entity syn-name syn-function syn-rust">some_other_function"#,
|
||||
];
|
||||
|
||||
assert_contains_strings(nested, &text);
|
||||
|
@ -378,7 +378,7 @@ fn able_to_include_playground_files_in_chapters() {
|
|||
|
||||
let playground_strings = &[
|
||||
r#"class="playground""#,
|
||||
r#"println!("Hello World!");"#,
|
||||
r#"<span class="syn-support syn-macro syn-rust">println!</span><span class="syn-meta syn-group syn-rust"><span class="syn-punctuation syn-section syn-group syn-begin syn-rust">(</span></span><span class="syn-meta syn-group syn-rust"><span class="syn-string syn-quoted syn-double syn-rust"><span class="syn-punctuation syn-definition syn-string syn-begin syn-rust">"</span>Hello World!"#,
|
||||
];
|
||||
|
||||
assert_contains_strings(&second, playground_strings);
|
||||
|
|
Loading…
Reference in New Issue