Syntax highlighting, color tweaks

This commit is contained in:
Shadowfacts 2025-01-12 15:48:13 -05:00
parent 64332a137b
commit 3adf6031a4
12 changed files with 365 additions and 408 deletions

186
Cargo.lock generated
View File

@ -1243,7 +1243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc"
dependencies = [ dependencies = [
"memchr", "memchr",
"thiserror", "thiserror 2.0.9",
"ucd-trie", "ucd-trie",
] ]
@ -1662,6 +1662,21 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "splash-rs"
version = "0.3.1"
source = "git+https://git.shadowfacts.net/shadowfacts/splash-rs.git#7f3b67c59a4753ae50367eba292c8717ccbb5542"
dependencies = [
"serde",
"serde_json",
]
[[package]]
name = "streaming-iterator"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b2231b7c3057d5e4ad0156fb3dc807d900806020c5ffa3ee6ff2c8c76fb8520"
[[package]] [[package]]
name = "string_cache" name = "string_cache"
version = "0.8.7" version = "0.8.7"
@ -1744,13 +1759,33 @@ dependencies = [
"unic-segment", "unic-segment",
] ]
[[package]]
name = "thiserror"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52"
dependencies = [
"thiserror-impl 1.0.69",
]
[[package]] [[package]]
name = "thiserror" name = "thiserror"
version = "2.0.9" version = "2.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc"
dependencies = [ dependencies = [
"thiserror-impl", "thiserror-impl 2.0.9",
]
[[package]]
name = "thiserror-impl"
version = "1.0.69"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1"
dependencies = [
"proc-macro2",
"quote",
"syn",
] ]
[[package]] [[package]]
@ -1945,6 +1980,138 @@ version = "0.1.33"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
[[package]]
name = "tree-sitter"
version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5f2434c86ba59ed15af56039cc5bf1acf8ba76ce301e32ef08827388ef285ec5"
dependencies = [
"cc",
"regex",
"regex-syntax",
"streaming-iterator",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-bash"
version = "0.23.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "329a4d48623ac337d42b1df84e81a1c9dbb2946907c102ca72db158c1964a52e"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-c"
version = "0.23.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "afd2b1bf1585dc2ef6d69e87d01db8adb059006649dd5f96f31aa789ee6e9c71"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-css"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5ad6489794d41350d12a7fbe520e5199f688618f43aace5443980d1ddcf1b29e"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-elixir"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23d7310aea06158653d18959123a64262bfbf122b7437899dea0c338654a51d3"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-highlight"
version = "0.24.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1df627d3607f08557788a3c85b85042d8ccd5155eb119afff5f0c7b67a40924"
dependencies = [
"lazy_static",
"regex",
"streaming-iterator",
"thiserror 1.0.69",
"tree-sitter",
]
[[package]]
name = "tree-sitter-html"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "261b708e5d92061ede329babaaa427b819329a9d427a1d710abb0f67bbef63ee"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-java"
version = "0.23.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0aa6cbcdc8c679b214e616fd3300da67da0e492e066df01bcf5a5921a71e90d6"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-javascript"
version = "0.23.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bf40bf599e0416c16c125c3cec10ee5ddc7d1bb8b0c60fa5c4de249ad34dc1b1"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-json"
version = "0.24.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d727acca406c0020cffc6cf35516764f36c8e3dc4408e5ebe2cb35a947ec471"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-language"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c199356c799a8945965bb5f2c55b2ad9d9aa7c4b4f6e587fe9dea0bc715e5f9c"
[[package]]
name = "tree-sitter-objc"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ca8bb556423fc176f0535e79d525f783a6684d3c9da81bf9d905303c129e1d2"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]]
name = "tree-sitter-rust"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4d64d449ca63e683c562c7743946a646671ca23947b9c925c0cfbe65051a4af"
dependencies = [
"cc",
"tree-sitter-language",
]
[[package]] [[package]]
name = "tungstenite" name = "tungstenite"
version = "0.26.1" version = "0.26.1"
@ -1959,7 +2126,7 @@ dependencies = [
"log", "log",
"rand", "rand",
"sha1", "sha1",
"thiserror", "thiserror 2.0.9",
"utf-8", "utf-8",
] ]
@ -2090,16 +2257,29 @@ dependencies = [
"notify", "notify",
"once_cell", "once_cell",
"pulldown-cmark", "pulldown-cmark",
"pulldown-cmark-escape",
"regex", "regex",
"rss", "rss",
"serde", "serde",
"serde_json", "serde_json",
"splash-rs",
"tera", "tera",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
"toml", "toml",
"tower", "tower",
"tower-http", "tower-http",
"tree-sitter-bash",
"tree-sitter-c",
"tree-sitter-css",
"tree-sitter-elixir",
"tree-sitter-highlight",
"tree-sitter-html",
"tree-sitter-java",
"tree-sitter-javascript",
"tree-sitter-json",
"tree-sitter-objc",
"tree-sitter-rust",
"unicode-normalization", "unicode-normalization",
] ]

View File

@ -40,13 +40,26 @@ markup5ever_rcdom = "0.3.0"
notify = "7.0.0" notify = "7.0.0"
once_cell = "1.20.2" once_cell = "1.20.2"
pulldown-cmark = "0.12.2" pulldown-cmark = "0.12.2"
pulldown-cmark-escape = "0.11.0"
regex = "1.11.1" regex = "1.11.1"
rss = { version = "2.0.11", features = ["atom"] } rss = { version = "2.0.11", features = ["atom"] }
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
splash-rs = { version = "0.3.1", git = "https://git.shadowfacts.net/shadowfacts/splash-rs.git" }
tera = "1.20.0" tera = "1.20.0"
tokio = { version = "1.42.0", features = ["full"] } tokio = { version = "1.42.0", features = ["full"] }
tokio-stream = "0.1.17" tokio-stream = "0.1.17"
toml = "0.8.19" toml = "0.8.19"
tower = { version = "0.5.2", features = ["steer", "util"] } tower = { version = "0.5.2", features = ["steer", "util"] }
tower-http = { version = "0.6.2", features = ["fs"] } tower-http = { version = "0.6.2", features = ["fs"] }
tree-sitter-bash = "0.23.3"
tree-sitter-c = "0.23.4"
tree-sitter-css = "0.23.2"
tree-sitter-elixir = "0.3.3"
tree-sitter-highlight = "0.24.6"
tree-sitter-html = "0.23.2"
tree-sitter-java = "0.23.5"
tree-sitter-javascript = "0.23.1"
tree-sitter-json = "0.24.8"
tree-sitter-objc = "3.0.2"
tree-sitter-rust = "0.23.2"
unicode-normalization = "0.1.24" unicode-normalization = "0.1.24"

View File

@ -1,14 +1,17 @@
@import "normalize.scss"; @import "normalize.scss";
@import "fonts.scss"; @import "fonts.scss";
@import "syntax-highlighting.scss";
$page-horizontal-margin: 2rem; $page-horizontal-margin: 2rem;
$mobile-breakpoint: 480px; $mobile-breakpoint: 480px;
$container-max-width: 768px; $container-max-width: 768px;
$link-color: #c21e1e;
:root { :root {
--background-color: #f8e7cf; // solarized-base2
--background-color: #eee8d5;
--text-color: black; --text-color: black;
--secondary-text-color: #656565; --secondary-text-color: #656565;
--link-color: blue; --link-color: #c21e1e;
--page-vertical-margin: 3rem; --page-vertical-margin: 3rem;
} }
@ -55,6 +58,12 @@ code {
font-size: 0.9em; font-size: 0.9em;
} }
pre {
overflow-x: scroll;
tab-size: 4;
word-wrap: normal;
}
blockquote { blockquote {
position: relative; position: relative;
font-style: italic; font-style: italic;
@ -140,13 +149,20 @@ header {
display: none; display: none;
} }
} }
}
&:hover + .sidenote { .footnote-reference:hover + .sidenote,
color: black; .sidenote:hover,
aside:not(.inline):hover {
color: black;
a {
color: var(--link-color);
} }
} }
.sidenote { .sidenote,
aside:not(.inline) {
float: right; float: right;
margin-right: -50%; margin-right: -50%;
width: 40%; width: 40%;
@ -160,6 +176,19 @@ header {
margin: 20px 0; margin: 20px 0;
display: block; display: block;
} }
a {
color: lighten($link-color, 20%);
transition: color 0.2s ease-in-out;
}
}
aside:not(.inline) {
transform: translateY(-50%);
p:first-child {
margin-top: 0;
}
} }
.footnote { .footnote {
@ -186,6 +215,20 @@ header {
} }
} }
aside.inline {
font-size: 1rem;
/* background-color: #d8d7fe; */
background-color: lighten($link-color, 43%);
padding: 1rem;
p:first-child {
margin-top: 0;
}
p:last-child {
margin-bottom: 0;
}
}
// 1.5 to account for -50% margin-right on .sidenote // 1.5 to account for -50% margin-right on .sidenote
// plus page-horizontal-margin to effectively use that as the margin // plus page-horizontal-margin to effectively use that as the margin
@media (min-width: calc(1.5 * $container-max-width + 2 * $page-horizontal-margin)) { @media (min-width: calc(1.5 * $container-max-width + 2 * $page-horizontal-margin)) {
@ -197,7 +240,8 @@ header {
display: inline; display: inline;
} }
} }
.sidenote { .sidenote,
aside:not(.inline) {
display: block; display: block;
} }
.footnote { .footnote {

View File

@ -0,0 +1,67 @@
:root {
--solarized-base01: #586e75;
--solarized-base00: #657b83;
/* --solarized-base0: #839496; */
--solarized-base1: #93a1a1;
--solarized-base2: #eee8d5;
--solarized-base3: #fdf6e3;
--solarized-yellow: #b58900;
--solarized-orange: #cb4b16;
--solarized-red: #dc322f;
--solarized-blue: #268bd2;
--solarized-cyan: #2aa198;
--solarized-green: #859900;
}
.highlight {
display: block;
overflow-x: auto;
padding: 0.5em;
color: var(--solarized-base01);
// darkened base2
background: darken(#eee8d5, 4%);
}
.highlight > code {
display: block;
}
.hl-cmt {
color: var(--solarized-base00);
font-style: italic;
}
.hl-kw,
.hl-const {
color: var(--solarized-green);
}
.hl-punct-sp,
.hl-tag {
color: var(--solarized-blue);
}
.hl-emb {
color: var(--solarized-base01);
}
.hl-attr,
.hl-mod,
.hl-key,
.hl-prop {
color: var(--solarized-red);
}
.hl-str {
color: var(--solarized-cyan);
}
.hl-builtin,
.hl-type,
.hl-num {
color: var(--solarized-yellow);
}
.hl-fn {
color: var(--solarized-orange);
}

View File

@ -1,370 +0,0 @@
[
(comment)
(pragma)
] @comment
[
(self)
(super)
] @variable.builtin
[
(getter)
(setter)
(nonnull)
(nullable)
(null_resettable)
(unsafe_unretained)
(null_unspecified)
(direct)
(readwrite)
(readonly)
(strong)
(weak)
(copy)
(assign)
(retain)
(atomic)
(nonatomic)
(class)
(NS_NONATOMIC_IOSONLY)
(DISPATCH_QUEUE_REFERENCE_TYPE)
] @keyword
[
"@interface"
"@protocol"
"@property"
"@end"
"@implementation"
"@compatibility_alias"
"@autoreleasepool"
"@synchronized"
"@class"
"@synthesize"
"@dynamic"
"@defs"
"@try"
"@catch"
"@finally"
"@throw"
"@selector"
"@encode"
(private)
(public)
(protected)
(package)
(optional)
(required)
"NS_ENUM"
"NS_ERROR_ENUM"
"NS_OPTIONS"
"NS_SWIFT_NAME"
(type_qualifier)
(storage_class_specifier)
"NS_NOESCAPE"
"const"
"default"
"enum"
"extern"
"inline"
"static"
"struct"
"typedef"
"typeof"
"__typeof"
"__typeof__"
"_Atomic"
"union"
"volatile"
"goto"
"register"
"__covariant"
"__contravariant"
"__GENERICS"
] @keyword
"sizeof" @keyword.operator
"return" @keyword.return
[
"while"
"for"
"do"
"continue"
"break"
] @keyword.repeat
"#define" @constant.macro
[
"#if"
"#ifdef"
"#ifndef"
"#else"
"#elif"
"#endif"
(preproc_directive)
] @keyword
"#include" @include
"#import" @include
"@import" @include
[
"="
"-"
"*"
"/"
"+"
"%"
"~"
"|"
"&"
"^"
"<<"
">>"
"->"
"<"
"<="
">="
">"
"=="
"!="
"!"
"&&"
"||"
"-="
"+="
"*="
"/="
"%="
"|="
"&="
"^="
">>="
"<<="
"--"
"++"
"@"
] @operator
[
"if"
"else"
"case"
"switch"
] @keyword.conditional
(conditional_expression [ "?" ":" ] @keyword.conditional)
[
(true)
(false)
(YES)
(NO)
] @keyword.boolean
[ "." ";" ":" "," ] @punctuation.delimiter
"..." @punctuation.special
[ "(" ")" "[" "]" "{" "}"] @punctuation.bracket
[
(string_literal)
(string_expression)
(system_lib_string)
(module_string)
] @string
(escape_sequence) @string.escape
(null) @constant.builtin
(nil) @constant.builtin
(number_literal) @number
(number_expression) @number
(char_literal) @character
[
(preproc_arg)
(preproc_defined)
] @function.macro
; declarator: (identifier) @property
; (cast_expression value: (identifier) @property)
; (((field_expression
; (field_identifier) @property)) @_parent
; (#not-has-parent? @_parent function_declarator call_expression))
; (((field_identifier) @property)
; (#has-ancestor? @property field_declaration)
; (#not-has-ancestor? @property function_declarator))
[
(type_identifier)
(primitive_type)
(sized_type_specifier)
(type_descriptor)
(generics_type_reference)
] @type
[
(id)
(Class)
(Method)
(IMP)
(SEL)
(BOOL)
(instancetype)
(auto)
] @type.builtin
(declaration (type_qualifier) @type)
(cast_expression type: (type_descriptor) @type)
(sizeof_expression value: (parenthesized_expression (identifier) @type))
(class_interface name: (identifier) @type.class)
(category_interface name: (identifier) @type.class)
(category_interface category: (identifier) @type.category)
(superclass_reference name: (identifier) @type.class)
(parameterized_class_type_arguments) @type.class
(class_implementation name: (identifier) @type.class)
(category_implementation name: (identifier) @type.class)
(compatibility_alias_declaration (identifier) @type.class)
(category_implementation category: (identifier) @type.category)
(class_forward_declaration name: (identifier) @type.class)
(protocol_forward_declaration name: (identifier) @type.protocol)
(protocol_declaration name: (identifier) @type.protocol)
(protocol_qualifiers name: (identifier) @type.protocol)
(protocol_expression (identifier) @type.protocol)
;; Preproc def / undef
(preproc_def
name: (_) @constant)
(preproc_call
directive: (preproc_directive) @_u
argument: (_) @constant
(#eq? @_u "#undef"))
(call_expression
function: (identifier) @function)
(field_expression
field: (field_identifier) @function)
(function_declarator
declarator: (identifier) @function)
(preproc_function_def
name: (identifier) @function.macro)
(selector_expression
name: (identifier) @function)
(method_declaration
selector: (identifier) @function)
(method_declaration
(keyword_selector
(keyword_declarator
keyword: (identifier) @function)))
(method_declaration
(keyword_selector
(keyword_declarator
name: (identifier) @function)))
(message_expression
receiver: (field_expression
field: (field_identifier) @variable))
(method_definition
selector: (identifier) @function)
(method_definition
(keyword_selector
(keyword_declarator
keyword: (identifier) @function)))
(message_expression
selector: (identifier) @function)
(method_definition
(keyword_selector
(keyword_declarator
name: (identifier) @property)))
(message_expression
selector: (keyword_argument_list
(keyword_argument
keyword: (identifier) @function)))
; (message_expression
; selector: (keyword_argument_list
; (keyword_argument
; argument: (identifier) @property)))
(unary_expression argument: (identifier) @function)
(va_arg_expression) @function
; (va_arg_expression va_list: (identifier) @property)
; (enumerator name: (identifier) @property)
;; Parameters
(parameter_declaration
declarator: (identifier) @variable.parameter)
(parameter_declaration
declarator: (pointer_declarator) @variable.parameter)
(parameter_declaration
declarator: (pointer_declarator
declarator: (identifier) @variable.parameter))
(for_in_statement
loop: (identifier) @variable.parameter)
; (dictionary_expression
; key:(_expression) @property)
; (dictionary_expression
; value: (_expression) @property)
; (array_expression
; (identifier) @property)
; (argument_list
; (identifier) @property)
; (expression_statement
; (identifier) @property)
; (_expression (identifier) @property)
[
"__attribute"
"__attribute__"
"__cdecl"
"__clrcall"
"__stdcall"
"__fastcall"
"__thiscall"
"__vectorcall"
"_unaligned"
"__unaligned"
"__declspec"
"__unused"
"__builtin_available"
"@available"
(attribute_specifier)
(class_interface_attribute_sepcifier)
(method_variadic_arguments_attribute_specifier)
] @attribute
(attribute_specifier) @attribute
((identifier) @constant
(#match? @constant "^[A-Z][A-Z0-9_$]+$"))
(ERROR) @error

View File

@ -1,6 +1,7 @@
// use crate::generator::highlight::highlight;
use pulldown_cmark::{CodeBlockKind, Event, Tag, TagEnd}; use pulldown_cmark::{CodeBlockKind, Event, Tag, TagEnd};
use crate::generator::util::highlight::highlight;
pub fn new<'a, I: Iterator<Item = Event<'a>>>(iter: I) -> Highlight<'a, I> { pub fn new<'a, I: Iterator<Item = Event<'a>>>(iter: I) -> Highlight<'a, I> {
Highlight { iter } Highlight { iter }
} }
@ -16,8 +17,7 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for Highlight<'a, I> {
match self.iter.next() { match self.iter.next() {
Some(Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(label)))) => { Some(Event::Start(Tag::CodeBlock(CodeBlockKind::Fenced(label)))) => {
let code = self.consume_code_block(); let code = self.consume_code_block();
// let mut highlighted = highlight(&code, &label); let mut highlighted = highlight(&code, &label);
let mut highlighted = "TODO".to_owned();
highlighted.insert_str( highlighted.insert_str(
0, 0,
&format!("<pre class=\"highlight\" data-lang=\"{}\"><code>", label), &format!("<pre class=\"highlight\" data-lang=\"{}\"><code>", label),

View File

@ -3,7 +3,7 @@ mod swift;
mod tree_sitter; mod tree_sitter;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
use pulldown_cmark::escape::escape_html; use pulldown_cmark_escape::escape_html_body_text;
use tree_sitter::TreeSitterHighlighter; use tree_sitter::TreeSitterHighlighter;
use tree_sitter_highlight::HighlightConfiguration; use tree_sitter_highlight::HighlightConfiguration;
@ -17,7 +17,7 @@ pub fn highlight(code: &str, label: &str) -> String {
match lang_highlighter(label) { match lang_highlighter(label) {
None => { None => {
let mut buf = String::new(); let mut buf = String::new();
escape_html(&mut buf, &code).unwrap(); escape_html_body_text(&mut buf, &code).expect("escaping");
buf buf
} }
Some(highlighter) => highlighter.highlight(&code), Some(highlighter) => highlighter.highlight(&code),
@ -25,39 +25,61 @@ pub fn highlight(code: &str, label: &str) -> String {
} }
macro_rules! ts_config { macro_rules! ts_config {
($name:ident, $module:ident, $query:ident) => { ($static_name:ident, $module:ident, $name:literal, $query:ident) => {
static $name: Lazy<HighlightConfiguration> = Lazy::new(|| { static $static_name: Lazy<HighlightConfiguration> = Lazy::new(|| {
let mut config = let mut config = HighlightConfiguration::new(
HighlightConfiguration::new($module::language(), $module::$query, "", "").unwrap(); $module::LANGUAGE.into(),
$name,
$module::$query,
"",
"",
)
.unwrap();
config.configure(tree_sitter::HIGHLIGHT_NAMES); config.configure(tree_sitter::HIGHLIGHT_NAMES);
config config
}); });
}; };
($name:ident, $module:ident, $query:literal) => { ($static_name:ident, $module:ident, $name:literal, $query:literal) => {
static $name: Lazy<HighlightConfiguration> = Lazy::new(|| { static $static_name: Lazy<HighlightConfiguration> = Lazy::new(|| {
let mut config = let mut config = HighlightConfiguration::new(
HighlightConfiguration::new($module::language(), include_str!($query), "", "") $module::LANGUAGE.into(),
.unwrap(); $name,
include_str!($query),
"",
"",
)
.unwrap();
config.configure(tree_sitter::HIGHLIGHT_NAMES); config.configure(tree_sitter::HIGHLIGHT_NAMES);
config config
}); });
}; };
} }
ts_config!(BASH_CONFIG, tree_sitter_bash, HIGHLIGHTS_QUERY); ts_config!(BASH_CONFIG, tree_sitter_bash, "bash", HIGHLIGHT_QUERY);
ts_config!(C_CONFIG, tree_sitter_c, HIGHLIGHT_QUERY); ts_config!(C_CONFIG, tree_sitter_c, "c", HIGHLIGHT_QUERY);
ts_config!(CSS_CONFIG, tree_sitter_css, "highlight/css-highlight.scm");
ts_config!(ELIXIR_CONFIG, tree_sitter_elixir, HIGHLIGHTS_QUERY);
ts_config!(HTML_CONFIG, tree_sitter_html, HIGHLIGHTS_QUERY);
ts_config!(JAVA_CONFIG, tree_sitter_java, HIGHLIGHT_QUERY);
ts_config!(JS_CONFIG, tree_sitter_javascript, HIGHLIGHT_QUERY);
ts_config!(JSON_CONFIG, tree_sitter_json, HIGHLIGHT_QUERY);
ts_config!( ts_config!(
OBJC_CONFIG, CSS_CONFIG,
tree_sitter_objc, tree_sitter_css,
"highlight/objc-highlight.scm" "css",
"highlight/css-highlight.scm"
); );
ts_config!(RUST_CONFIG, tree_sitter_rust, HIGHLIGHT_QUERY); ts_config!(
ELIXIR_CONFIG,
tree_sitter_elixir,
"elixir",
HIGHLIGHTS_QUERY
);
ts_config!(HTML_CONFIG, tree_sitter_html, "html", HIGHLIGHTS_QUERY);
ts_config!(JAVA_CONFIG, tree_sitter_java, "java", HIGHLIGHTS_QUERY);
ts_config!(
JS_CONFIG,
tree_sitter_javascript,
"javascript",
HIGHLIGHT_QUERY
);
ts_config!(JSON_CONFIG, tree_sitter_json, "json", HIGHLIGHTS_QUERY);
ts_config!(OBJC_CONFIG, tree_sitter_objc, "objc", HIGHLIGHTS_QUERY);
ts_config!(RUST_CONFIG, tree_sitter_rust, "rust", HIGHLIGHTS_QUERY);
fn lang_highlighter(name: &str) -> Option<Box<dyn Highlighter>> { fn lang_highlighter(name: &str) -> Option<Box<dyn Highlighter>> {
match name { match name {

View File

@ -1,5 +1,5 @@
use super::Highlighter; use super::Highlighter;
use pulldown_cmark::escape::escape_html; use pulldown_cmark_escape::escape_html_body_text;
use std::fmt::Write; use std::fmt::Write;
use tree_sitter_highlight::{Highlight as TSHighlight, HighlightConfiguration, HighlightEvent}; use tree_sitter_highlight::{Highlight as TSHighlight, HighlightConfiguration, HighlightEvent};
@ -27,11 +27,11 @@ impl Highlighter for TreeSitterHighlighter {
let event = highlight.unwrap(); let event = highlight.unwrap();
match event { match event {
HighlightEvent::Source { start, end } => { HighlightEvent::Source { start, end } => {
escape_html( escape_html_body_text(
&mut buf, &mut buf,
std::str::from_utf8(&code.as_bytes()[start..end]).unwrap(), std::str::from_utf8(&code.as_bytes()[start..end]).unwrap(),
) )
.unwrap(); .expect("escaping");
} }
HighlightEvent::HighlightStart(TSHighlight(idx)) => { HighlightEvent::HighlightStart(TSHighlight(idx)) => {
write!( write!(

View File

@ -1,4 +1,5 @@
pub mod file_watcher; pub mod file_watcher;
pub mod highlight;
pub mod one_more; pub mod one_more;
pub mod slugify; pub mod slugify;
pub mod templates; pub mod templates;