zola/components/config/src/highlighting.rs
Vincent Prouillet 4a87689cfb Add class based syntax higlighting + line numbers (#1531)
* Add class based syntax higlighting + line numbers

* Use fork of syntect for now

* Fix tests

* Fix diff background on inline highlighter

Co-authored-by: evan-brass <evan-brass@protonmail.com>
2021-07-10 08:53:19 +02:00

96 lines
3.1 KiB
Rust

use lazy_static::lazy_static;
use syntect::dumps::from_binary;
use syntect::highlighting::{Theme, ThemeSet};
use syntect::parsing::{SyntaxReference, SyntaxSet};
use crate::config::Config;
use syntect::html::{css_for_theme_with_class_style, ClassStyle};
lazy_static! {
pub static ref SYNTAX_SET: SyntaxSet = {
let ss: SyntaxSet =
from_binary(include_bytes!("../../../sublime/syntaxes/newlines.packdump"));
ss
};
pub static ref THEME_SET: ThemeSet =
from_binary(include_bytes!("../../../sublime/themes/all.themedump"));
}
pub const CLASS_STYLE: ClassStyle = ClassStyle::SpacedPrefixed { prefix: "z-" };
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum HighlightSource {
/// One of the built-in Zola syntaxes
BuiltIn,
/// Found in the extra syntaxes
Extra,
/// No language specified
Plain,
/// We didn't find the language in built-in and extra syntaxes
NotFound,
}
pub struct SyntaxAndTheme<'config> {
pub syntax: &'config SyntaxReference,
pub syntax_set: &'config SyntaxSet,
/// None if highlighting via CSS
pub theme: Option<&'config Theme>,
pub source: HighlightSource,
}
pub fn resolve_syntax_and_theme<'config>(
language: Option<&'_ str>,
config: &'config Config,
) -> SyntaxAndTheme<'config> {
let theme = if config.markdown.highlight_theme != "css" {
Some(&THEME_SET.themes[&config.markdown.highlight_theme])
} else {
None
};
if let Some(ref lang) = language {
if let Some(ref extra_syntaxes) = config.markdown.extra_syntax_set {
if let Some(syntax) = extra_syntaxes.find_syntax_by_token(lang) {
return SyntaxAndTheme {
syntax,
syntax_set: extra_syntaxes,
theme,
source: HighlightSource::Extra,
};
}
}
// The JS syntax hangs a lot... the TS syntax is probably better anyway.
// https://github.com/getzola/zola/issues/1241
// https://github.com/getzola/zola/issues/1211
// https://github.com/getzola/zola/issues/1174
let hacked_lang = if *lang == "js" || *lang == "javascript" { "ts" } else { lang };
if let Some(syntax) = SYNTAX_SET.find_syntax_by_token(hacked_lang) {
SyntaxAndTheme {
syntax,
syntax_set: &SYNTAX_SET as &SyntaxSet,
theme,
source: HighlightSource::BuiltIn,
}
} else {
SyntaxAndTheme {
syntax: SYNTAX_SET.find_syntax_plain_text(),
syntax_set: &SYNTAX_SET as &SyntaxSet,
theme,
source: HighlightSource::NotFound,
}
}
} else {
SyntaxAndTheme {
syntax: SYNTAX_SET.find_syntax_plain_text(),
syntax_set: &SYNTAX_SET as &SyntaxSet,
theme,
source: HighlightSource::Plain,
}
}
}
pub fn export_theme_css(theme_name: &str) -> String {
let theme = &THEME_SET.themes[theme_name];
css_for_theme_with_class_style(theme, CLASS_STYLE)
}