Pick highlighting theme from config
This commit is contained in:
parent
81596af366
commit
9af85ba3e4
|
@ -34,10 +34,5 @@ markdown -> HTML for the content
|
|||
|
||||
### Themes
|
||||
Gallery at https://tmtheme-editor.herokuapp.com/#!/editor/theme/Agola%20Dark
|
||||
|
||||
# TODO:
|
||||
|
||||
- find a way to add tests
|
||||
- syntax highlighting
|
||||
- pass a --config arg to the CLI to change from `config.toml`
|
||||
- have verbosity levels with a `verbosity` config variable with a default
|
||||
Make .themedump file:
|
||||
`cargo run --example generate_themes themepack sublime_themes sublime_themes/all.themedump`
|
||||
|
|
45
examples/generate_themes.rs
Normal file
45
examples/generate_themes.rs
Normal file
|
@ -0,0 +1,45 @@
|
|||
//! This program is mainly intended for generating the dumps that are compiled in to
|
||||
//! syntect, not as a helpful example for beginners.
|
||||
//! Although it is a valid example for serializing syntaxes, you probably won't need
|
||||
//! to do this yourself unless you want to cache your own compiled grammars.
|
||||
extern crate syntect;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
use syntect::highlighting::ThemeSet;
|
||||
use syntect::dumps::*;
|
||||
use std::env;
|
||||
|
||||
fn usage_and_exit() -> ! {
|
||||
println!("USAGE: gendata synpack source-dir newlines.packdump nonewlines.packdump\n
|
||||
gendata themepack source-dir themepack.themedump");
|
||||
::std::process::exit(2);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
||||
let mut a = env::args().skip(1);
|
||||
match (a.next(), a.next(), a.next(), a.next()) {
|
||||
(Some(ref cmd),
|
||||
Some(ref package_dir),
|
||||
Some(ref packpath_newlines),
|
||||
Some(ref packpath_nonewlines)) if cmd == "synpack" => {
|
||||
let mut ps = SyntaxSet::new();
|
||||
ps.load_plain_text_syntax();
|
||||
ps.load_syntaxes(package_dir, true).unwrap();
|
||||
dump_to_file(&ps, packpath_newlines).unwrap();
|
||||
|
||||
ps = SyntaxSet::new();
|
||||
ps.load_plain_text_syntax();
|
||||
ps.load_syntaxes(package_dir, false).unwrap();
|
||||
dump_to_file(&ps, packpath_nonewlines).unwrap();
|
||||
|
||||
}
|
||||
(Some(ref s), Some(ref theme_dir), Some(ref packpath), None) if s == "themepack" => {
|
||||
let ts = ThemeSet::load_from_folder(theme_dir).unwrap();
|
||||
for (path, _) in &ts.themes {
|
||||
println!("{:?}", path);
|
||||
}
|
||||
dump_to_file(&ts, packpath).unwrap();
|
||||
}
|
||||
_ => usage_and_exit(),
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ use std::collections::HashMap;
|
|||
use toml::{Value as Toml, self};
|
||||
|
||||
use errors::{Result, ResultExt};
|
||||
use markdown::SETUP;
|
||||
|
||||
|
||||
// TO ADD:
|
||||
|
@ -22,6 +23,8 @@ pub struct Config {
|
|||
|
||||
/// Whether to highlight all code blocks found in markdown files. Defaults to false
|
||||
pub highlight_code: Option<bool>,
|
||||
/// Which themes to use for code highlighting. See Readme for supported themes
|
||||
pub highlight_theme: Option<String>,
|
||||
/// Description of the site
|
||||
pub description: Option<String>,
|
||||
/// The language used in the site. Defaults to "en"
|
||||
|
@ -50,6 +53,15 @@ impl Config {
|
|||
config.highlight_code = Some(false);
|
||||
}
|
||||
|
||||
match config.highlight_theme {
|
||||
Some(ref t) => {
|
||||
if !SETUP.theme_set.themes.contains_key(t) {
|
||||
bail!("Theme {} not available", t)
|
||||
}
|
||||
},
|
||||
None => config.highlight_theme = Some("base16-ocean-dark".to_string())
|
||||
};
|
||||
|
||||
if config.generate_rss.is_none() {
|
||||
config.generate_rss = Some(false);
|
||||
}
|
||||
|
@ -84,6 +96,7 @@ impl Default for Config {
|
|||
title: "".to_string(),
|
||||
base_url: "http://a-website.com/".to_string(),
|
||||
highlight_code: Some(true),
|
||||
highlight_theme: Some("base16-ocean-dark".to_string()),
|
||||
description: None,
|
||||
language_code: Some("en".to_string()),
|
||||
generate_rss: Some(false),
|
||||
|
|
|
@ -3,6 +3,7 @@ use std::borrow::Cow::Owned;
|
|||
use pulldown_cmark as cmark;
|
||||
use self::cmark::{Parser, Event, Tag};
|
||||
|
||||
use syntect::dumps::from_binary;
|
||||
use syntect::easy::HighlightLines;
|
||||
use syntect::parsing::SyntaxSet;
|
||||
use syntect::highlighting::ThemeSet;
|
||||
|
@ -10,18 +11,18 @@ use syntect::html::{start_coloured_html_snippet, styles_to_coloured_html, Includ
|
|||
|
||||
|
||||
// We need to put those in a struct to impl Send and sync
|
||||
struct Setup {
|
||||
pub struct Setup {
|
||||
syntax_set: SyntaxSet,
|
||||
theme_set: ThemeSet,
|
||||
pub theme_set: ThemeSet,
|
||||
}
|
||||
|
||||
unsafe impl Send for Setup {}
|
||||
unsafe impl Sync for Setup {}
|
||||
|
||||
lazy_static!{
|
||||
static ref SETUP: Setup = Setup {
|
||||
pub static ref SETUP: Setup = Setup {
|
||||
syntax_set: SyntaxSet::load_defaults_newlines(),
|
||||
theme_set: ThemeSet::load_defaults()
|
||||
theme_set: from_binary(include_bytes!("../sublime_themes/all.themedump"))
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -30,13 +31,15 @@ struct CodeHighlightingParser<'a> {
|
|||
// The block we're currently highlighting
|
||||
highlighter: Option<HighlightLines<'a>>,
|
||||
parser: Parser<'a>,
|
||||
theme: &'a str,
|
||||
}
|
||||
|
||||
impl<'a> CodeHighlightingParser<'a> {
|
||||
pub fn new(parser: Parser<'a>) -> CodeHighlightingParser<'a> {
|
||||
pub fn new(parser: Parser<'a>, theme: &'a str) -> CodeHighlightingParser<'a> {
|
||||
CodeHighlightingParser {
|
||||
highlighter: None,
|
||||
parser: parser,
|
||||
theme: theme,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -67,15 +70,16 @@ impl<'a> Iterator for CodeHighlightingParser<'a> {
|
|||
}
|
||||
},
|
||||
Event::Start(Tag::CodeBlock(ref info)) => {
|
||||
let theme = &SETUP.theme_set.themes[self.theme];
|
||||
let syntax = info
|
||||
.split(' ')
|
||||
.next()
|
||||
.and_then(|lang| SETUP.syntax_set.find_syntax_by_token(lang))
|
||||
.unwrap_or_else(|| SETUP.syntax_set.find_syntax_plain_text());
|
||||
self.highlighter = Some(
|
||||
HighlightLines::new(syntax, &SETUP.theme_set.themes["base16-ocean.dark"])
|
||||
HighlightLines::new(syntax, &theme)
|
||||
);
|
||||
let snippet = start_coloured_html_snippet(&SETUP.theme_set.themes["base16-ocean.dark"]);
|
||||
let snippet = start_coloured_html_snippet(&theme);
|
||||
Some(Event::Html(Owned(snippet)))
|
||||
},
|
||||
Event::End(Tag::CodeBlock(_)) => {
|
||||
|
@ -89,10 +93,10 @@ impl<'a> Iterator for CodeHighlightingParser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn markdown_to_html(content: &str, highlight_code: bool) -> String {
|
||||
pub fn markdown_to_html(content: &str, highlight_code: bool, highlight_theme: &str) -> String {
|
||||
let mut html = String::new();
|
||||
if highlight_code {
|
||||
let parser = CodeHighlightingParser::new(Parser::new(content));
|
||||
let parser = CodeHighlightingParser::new(Parser::new(content), highlight_theme);
|
||||
cmark::html::push_html(&mut html, parser);
|
||||
} else {
|
||||
let parser = Parser::new(content);
|
||||
|
@ -108,13 +112,13 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_markdown_to_html_simple() {
|
||||
let res = markdown_to_html("# hello", true);
|
||||
let res = markdown_to_html("# hello", true, "base16-ocean-dark");
|
||||
assert_eq!(res, "<h1>hello</h1>\n");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_markdown_to_html_code_block_highlighting_off() {
|
||||
let res = markdown_to_html("```\n$ gutenberg server\n```", false);
|
||||
let res = markdown_to_html("```\n$ gutenberg server\n```", false, "base16-ocean-dark");
|
||||
assert_eq!(
|
||||
res,
|
||||
"<pre><code>$ gutenberg server\n</code></pre>\n"
|
||||
|
@ -123,7 +127,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_markdown_to_html_code_block_no_lang() {
|
||||
let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", true);
|
||||
let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", true, "base16-ocean-dark");
|
||||
assert_eq!(
|
||||
res,
|
||||
"<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">$ gutenberg server\n</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">$ ping\n</span></pre>"
|
||||
|
@ -132,7 +136,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_markdown_to_html_code_block_with_lang() {
|
||||
let res = markdown_to_html("```python\nlist.append(1)\n```", true);
|
||||
let res = markdown_to_html("```python\nlist.append(1)\n```", true, "base16-ocean-dark");
|
||||
assert_eq!(
|
||||
res,
|
||||
"<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">.</span><span style=\"background-color:#2b303b;color:#bf616a;\">append</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">(</span><span style=\"background-color:#2b303b;color:#d08770;\">1</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">)</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">\n</span></pre>"
|
||||
|
@ -140,7 +144,7 @@ mod tests {
|
|||
}
|
||||
#[test]
|
||||
fn test_markdown_to_html_code_block_with_unknown_lang() {
|
||||
let res = markdown_to_html("```yolo\nlist.append(1)\n```", true);
|
||||
let res = markdown_to_html("```yolo\nlist.append(1)\n```", true, "base16-ocean-dark");
|
||||
// defaults to plain text
|
||||
assert_eq!(
|
||||
res,
|
||||
|
|
|
@ -132,12 +132,13 @@ impl Page {
|
|||
false
|
||||
};
|
||||
|
||||
page.content = markdown_to_html(&page.raw_content, should_highlight);
|
||||
let highlight_theme = config.highlight_theme.clone().unwrap();
|
||||
page.content = markdown_to_html(&page.raw_content, should_highlight, &highlight_theme);
|
||||
|
||||
if page.raw_content.contains("<!-- more -->") {
|
||||
page.summary = {
|
||||
let summary = page.raw_content.splitn(2, "<!-- more -->").collect::<Vec<&str>>()[0];
|
||||
markdown_to_html(summary, should_highlight)
|
||||
markdown_to_html(summary, should_highlight, &highlight_theme)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
BIN
sublime_themes/all.themedump
Normal file
BIN
sublime_themes/all.themedump
Normal file
Binary file not shown.
Loading…
Reference in a new issue