mirror of
https://github.com/nushell/nushell
synced 2024-12-26 04:53:09 +00:00
Add 228 json html themes for to html (#2308)
* add 228 json html themes removed old assets, added new zipped asset added --list to get a list of the theme names reworked some older theme code added rust-embed and zip crate removed the dark tests * fmt * Updated, removed excess comments Changed usage a bit Updated the error handling Added some helper items in --list
This commit is contained in:
parent
f14c0df582
commit
f0dbffd761
7 changed files with 345 additions and 260 deletions
57
Cargo.lock
generated
57
Cargo.lock
generated
|
@ -472,6 +472,27 @@ version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42b7c3cbf0fa9c1b82308d57191728ca0256cb821220f4e2fd410a72ade26e3b"
|
||||||
|
dependencies = [
|
||||||
|
"bzip2-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2-sys"
|
||||||
|
version = "0.1.9+1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ad3b39a260062fca31f7b0b12f207e8f2590a67d32ec7d59c20484b07ea7285e"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cache-padded"
|
name = "cache-padded"
|
||||||
version = "1.1.1"
|
version = "1.1.1"
|
||||||
|
@ -2671,6 +2692,7 @@ dependencies = [
|
||||||
"regex",
|
"regex",
|
||||||
"roxmltree",
|
"roxmltree",
|
||||||
"rusqlite",
|
"rusqlite",
|
||||||
|
"rust-embed",
|
||||||
"rustyline",
|
"rustyline",
|
||||||
"serde 1.0.114",
|
"serde 1.0.114",
|
||||||
"serde-hjson 0.9.1",
|
"serde-hjson 0.9.1",
|
||||||
|
@ -2696,6 +2718,7 @@ dependencies = [
|
||||||
"users",
|
"users",
|
||||||
"uuid",
|
"uuid",
|
||||||
"which",
|
"which",
|
||||||
|
"zip",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3893,6 +3916,38 @@ dependencies = [
|
||||||
"crossbeam-utils 0.7.2",
|
"crossbeam-utils 0.7.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed"
|
||||||
|
version = "5.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "213acf1bc5a6dfcd70b62db1e9a7d06325c0e73439c312fcb8599d456d9686ee"
|
||||||
|
dependencies = [
|
||||||
|
"rust-embed-impl",
|
||||||
|
"rust-embed-utils",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed-impl"
|
||||||
|
version = "5.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7903c2cf599db8f310b392332f38367ca4acc84420fa1aee3536299f433c10d5"
|
||||||
|
dependencies = [
|
||||||
|
"quote",
|
||||||
|
"rust-embed-utils",
|
||||||
|
"syn",
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-embed-utils"
|
||||||
|
version = "5.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97655158074ccb2d2cfb1ccb4c956ef0f4054e43a2c1e71146d4991e6961e105"
|
||||||
|
dependencies = [
|
||||||
|
"walkdir",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rust-ini"
|
name = "rust-ini"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
|
@ -5100,7 +5155,9 @@ version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "58287c28d78507f5f91f2a4cf1e8310e2c76fd4c6932f93ac60fd1ceb402db7d"
|
checksum = "58287c28d78507f5f91f2a4cf1e8310e2c76fd4c6932f93ac60fd1ceb402db7d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"bzip2",
|
||||||
"crc32fast",
|
"crc32fast",
|
||||||
"flate2",
|
"flate2",
|
||||||
"podio",
|
"podio",
|
||||||
|
"time",
|
||||||
]
|
]
|
||||||
|
|
BIN
assets/228_themes.zip
Normal file
BIN
assets/228_themes.zip
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -67,6 +67,7 @@ query_interface = "0.3.5"
|
||||||
rand = "0.7"
|
rand = "0.7"
|
||||||
regex = "1"
|
regex = "1"
|
||||||
roxmltree = "0.13.0"
|
roxmltree = "0.13.0"
|
||||||
|
rust-embed = "5.6.0"
|
||||||
rustyline = "6.2.0"
|
rustyline = "6.2.0"
|
||||||
serde = {version = "1.0.114", features = ["derive"]}
|
serde = {version = "1.0.114", features = ["derive"]}
|
||||||
serde-hjson = "0.9.1"
|
serde-hjson = "0.9.1"
|
||||||
|
@ -88,6 +89,7 @@ umask = "1.0.0"
|
||||||
unicode-xid = "0.2.1"
|
unicode-xid = "0.2.1"
|
||||||
uuid_crate = {package = "uuid", version = "0.8.1", features = ["v4"], optional = true}
|
uuid_crate = {package = "uuid", version = "0.8.1", features = ["v4"], optional = true}
|
||||||
which = {version = "4.0.1", optional = true}
|
which = {version = "4.0.1", optional = true}
|
||||||
|
zip = "0.5.6"
|
||||||
|
|
||||||
clipboard = {version = "0.5", optional = true}
|
clipboard = {version = "0.5", optional = true}
|
||||||
encoding_rs = "0.8.23"
|
encoding_rs = "0.8.23"
|
||||||
|
|
|
@ -6,7 +6,79 @@ use nu_errors::ShellError;
|
||||||
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
use nu_protocol::{Primitive, ReturnSuccess, Signature, SyntaxShape, UntaggedValue, Value};
|
||||||
use nu_source::{AnchorLocation, Tagged};
|
use nu_source::{AnchorLocation, Tagged};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
use std::borrow::Cow;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::error::Error;
|
||||||
|
use std::io::Read;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct HtmlThemes {
|
||||||
|
themes: Vec<HtmlTheme>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(non_snake_case)]
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct HtmlTheme {
|
||||||
|
name: String,
|
||||||
|
black: String,
|
||||||
|
red: String,
|
||||||
|
green: String,
|
||||||
|
yellow: String,
|
||||||
|
blue: String,
|
||||||
|
purple: String,
|
||||||
|
cyan: String,
|
||||||
|
white: String,
|
||||||
|
brightBlack: String,
|
||||||
|
brightRed: String,
|
||||||
|
brightGreen: String,
|
||||||
|
brightYellow: String,
|
||||||
|
brightBlue: String,
|
||||||
|
brightPurple: String,
|
||||||
|
brightCyan: String,
|
||||||
|
brightWhite: String,
|
||||||
|
background: String,
|
||||||
|
foreground: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for HtmlThemes {
|
||||||
|
fn default() -> Self {
|
||||||
|
HtmlThemes {
|
||||||
|
themes: vec![HtmlTheme::default()],
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for HtmlTheme {
|
||||||
|
fn default() -> Self {
|
||||||
|
HtmlTheme {
|
||||||
|
name: "nu_default".to_string(),
|
||||||
|
black: "black".to_string(),
|
||||||
|
red: "red".to_string(),
|
||||||
|
green: "green".to_string(),
|
||||||
|
yellow: "#717100".to_string(),
|
||||||
|
blue: "blue".to_string(),
|
||||||
|
purple: "#c800c8".to_string(),
|
||||||
|
cyan: "#037979".to_string(),
|
||||||
|
white: "white".to_string(),
|
||||||
|
brightBlack: "black".to_string(),
|
||||||
|
brightRed: "red".to_string(),
|
||||||
|
brightGreen: "green".to_string(),
|
||||||
|
brightYellow: "#717100".to_string(),
|
||||||
|
brightBlue: "blue".to_string(),
|
||||||
|
brightPurple: "#c800c8".to_string(),
|
||||||
|
brightCyan: "#037979".to_string(),
|
||||||
|
brightWhite: "white".to_string(),
|
||||||
|
background: "white".to_string(),
|
||||||
|
foreground: "black".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "../../assets/"] // TODO: Should assets be part of the crate versus the project?
|
||||||
|
struct Assets;
|
||||||
|
|
||||||
pub struct ToHTML;
|
pub struct ToHTML;
|
||||||
|
|
||||||
|
@ -17,6 +89,7 @@ pub struct ToHTMLArgs {
|
||||||
dark: bool,
|
dark: bool,
|
||||||
partial: bool,
|
partial: bool,
|
||||||
theme: Option<Tagged<String>>,
|
theme: Option<Tagged<String>>,
|
||||||
|
list: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
|
@ -42,9 +115,10 @@ impl WholeStreamCommand for ToHTML {
|
||||||
.named(
|
.named(
|
||||||
"theme",
|
"theme",
|
||||||
SyntaxShape::String,
|
SyntaxShape::String,
|
||||||
"the name of the theme to use (default, campbell, github, blulocolight)",
|
"the name of the theme to use (github, blulocolight, ...)",
|
||||||
Some('t'),
|
Some('t'),
|
||||||
)
|
)
|
||||||
|
.switch("list", "list the names of all available themes", Some('l'))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn usage(&self) -> &str {
|
fn usage(&self) -> &str {
|
||||||
|
@ -60,183 +134,133 @@ impl WholeStreamCommand for ToHTML {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_campbell_theme(is_dark: bool) -> HashMap<&'static str, String> {
|
fn get_theme_from_asset_file(
|
||||||
// for reference here is Microsoft's Campbell Theme
|
is_dark: bool,
|
||||||
// taken from here
|
theme: &Option<Tagged<String>>,
|
||||||
// https://docs.microsoft.com/en-us/windows/terminal/customize-settings/color-schemes
|
theme_tag: &Tag,
|
||||||
let mut hm: HashMap<&str, String> = HashMap::new();
|
) -> Result<HashMap<&'static str, String>, ShellError> {
|
||||||
|
|
||||||
hm.insert("bold_black", "#767676".to_string());
|
|
||||||
hm.insert("bold_red", "#E74856".to_string());
|
|
||||||
hm.insert("bold_green", "#16C60C".to_string());
|
|
||||||
hm.insert("bold_yellow", "#F9F1A5".to_string());
|
|
||||||
hm.insert("bold_blue", "#3B78FF".to_string());
|
|
||||||
hm.insert("bold_magenta", "#B4009E".to_string());
|
|
||||||
hm.insert("bold_cyan", "#61D6D6".to_string());
|
|
||||||
hm.insert("bold_white", "#F2F2F2".to_string());
|
|
||||||
|
|
||||||
hm.insert("black", "#0C0C0C".to_string());
|
|
||||||
hm.insert("red", "#C50F1F".to_string());
|
|
||||||
hm.insert("green", "#13A10E".to_string());
|
|
||||||
hm.insert("yellow", "#C19C00".to_string());
|
|
||||||
hm.insert("blue", "#0037DA".to_string());
|
|
||||||
hm.insert("magenta", "#881798".to_string());
|
|
||||||
hm.insert("cyan", "#3A96DD".to_string());
|
|
||||||
hm.insert("white", "#CCCCCC".to_string());
|
|
||||||
|
|
||||||
// Try to make theme work with light or dark but
|
|
||||||
// flipping the foreground and background but leave
|
|
||||||
// the other colors the same.
|
|
||||||
if is_dark {
|
|
||||||
hm.insert("background", "#0C0C0C".to_string());
|
|
||||||
hm.insert("foreground", "#CCCCCC".to_string());
|
|
||||||
} else {
|
|
||||||
hm.insert("background", "#CCCCCC".to_string());
|
|
||||||
hm.insert("foreground", "#0C0C0C".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
hm
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_default_theme(is_dark: bool) -> HashMap<&'static str, String> {
|
|
||||||
let mut hm: HashMap<&str, String> = HashMap::new();
|
|
||||||
|
|
||||||
// This theme has different colors for dark and light
|
|
||||||
// so we can't just swap the background colors.
|
|
||||||
if is_dark {
|
|
||||||
hm.insert("bold_black", "black".to_string());
|
|
||||||
hm.insert("bold_red", "red".to_string());
|
|
||||||
hm.insert("bold_green", "green".to_string());
|
|
||||||
hm.insert("bold_yellow", "yellow".to_string());
|
|
||||||
hm.insert("bold_blue", "blue".to_string());
|
|
||||||
hm.insert("bold_magenta", "magenta".to_string());
|
|
||||||
hm.insert("bold_cyan", "cyan".to_string());
|
|
||||||
hm.insert("bold_white", "white".to_string());
|
|
||||||
|
|
||||||
hm.insert("black", "black".to_string());
|
|
||||||
hm.insert("red", "red".to_string());
|
|
||||||
hm.insert("green", "green".to_string());
|
|
||||||
hm.insert("yellow", "yellow".to_string());
|
|
||||||
hm.insert("blue", "blue".to_string());
|
|
||||||
hm.insert("magenta", "magenta".to_string());
|
|
||||||
hm.insert("cyan", "cyan".to_string());
|
|
||||||
hm.insert("white", "white".to_string());
|
|
||||||
|
|
||||||
hm.insert("background", "black".to_string());
|
|
||||||
hm.insert("foreground", "white".to_string());
|
|
||||||
} else {
|
|
||||||
hm.insert("bold_black", "black".to_string());
|
|
||||||
hm.insert("bold_red", "red".to_string());
|
|
||||||
hm.insert("bold_green", "green".to_string());
|
|
||||||
hm.insert("bold_yellow", "#717100".to_string());
|
|
||||||
hm.insert("bold_blue", "blue".to_string());
|
|
||||||
hm.insert("bold_magenta", "#c800c8".to_string());
|
|
||||||
hm.insert("bold_cyan", "#037979".to_string());
|
|
||||||
hm.insert("bold_white", "white".to_string());
|
|
||||||
|
|
||||||
hm.insert("black", "black".to_string());
|
|
||||||
hm.insert("red", "red".to_string());
|
|
||||||
hm.insert("green", "green".to_string());
|
|
||||||
hm.insert("yellow", "#717100".to_string());
|
|
||||||
hm.insert("blue", "blue".to_string());
|
|
||||||
hm.insert("magenta", "#c800c8".to_string());
|
|
||||||
hm.insert("cyan", "#037979".to_string());
|
|
||||||
hm.insert("white", "white".to_string());
|
|
||||||
|
|
||||||
hm.insert("background", "white".to_string());
|
|
||||||
hm.insert("foreground", "black".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
hm
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_github_theme(is_dark: bool) -> HashMap<&'static str, String> {
|
|
||||||
// Suggested by Jörn for use with demo site
|
|
||||||
// Taken from here https://github.com/mbadolato/iTerm2-Color-Schemes/blob/master/windowsterminal/Github.json
|
|
||||||
// This is a light theme named github, intended for a white background
|
|
||||||
// The next step will be to load these json themes if we ever get to that point
|
|
||||||
let mut hm: HashMap<&str, String> = HashMap::new();
|
|
||||||
|
|
||||||
hm.insert("bold_black", "#666666".to_string());
|
|
||||||
hm.insert("bold_red", "#de0000".to_string());
|
|
||||||
hm.insert("bold_green", "#87d5a2".to_string());
|
|
||||||
hm.insert("bold_yellow", "#f1d007".to_string());
|
|
||||||
hm.insert("bold_blue", "#2e6cba".to_string());
|
|
||||||
hm.insert("bold_magenta", "#ffa29f".to_string());
|
|
||||||
hm.insert("bold_cyan", "#1cfafe".to_string());
|
|
||||||
hm.insert("bold_white", "#ffffff".to_string());
|
|
||||||
|
|
||||||
hm.insert("black", "#3e3e3e".to_string());
|
|
||||||
hm.insert("red", "#970b16".to_string());
|
|
||||||
hm.insert("green", "#07962a".to_string());
|
|
||||||
hm.insert("yellow", "#f8eec7".to_string());
|
|
||||||
hm.insert("blue", "#003e8a".to_string());
|
|
||||||
hm.insert("magenta", "#e94691".to_string());
|
|
||||||
hm.insert("cyan", "#89d1ec".to_string());
|
|
||||||
hm.insert("white", "#ffffff".to_string());
|
|
||||||
|
|
||||||
// Try to make theme work with light or dark but
|
|
||||||
// flipping the foreground and background but leave
|
|
||||||
// the other colors the same.
|
|
||||||
if is_dark {
|
|
||||||
hm.insert("background", "#3e3e3e".to_string());
|
|
||||||
hm.insert("foreground", "#f4f4f4".to_string());
|
|
||||||
} else {
|
|
||||||
hm.insert("background", "#f4f4f4".to_string());
|
|
||||||
hm.insert("foreground", "#3e3e3e".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
hm
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_blulocolight_theme(is_dark: bool) -> HashMap<&'static str, String> {
|
|
||||||
let mut hm: HashMap<&str, String> = HashMap::new();
|
|
||||||
|
|
||||||
hm.insert("bold_black", "#dedfe8".to_string());
|
|
||||||
hm.insert("bold_red", "#fc4a6d".to_string());
|
|
||||||
hm.insert("bold_green", "#34b354".to_string());
|
|
||||||
hm.insert("bold_yellow", "#b89427".to_string());
|
|
||||||
hm.insert("bold_blue", "#1085d9".to_string());
|
|
||||||
hm.insert("bold_magenta", "#c00db3".to_string());
|
|
||||||
hm.insert("bold_cyan", "#5b80ad".to_string());
|
|
||||||
hm.insert("bold_white", "#1d1d22".to_string());
|
|
||||||
|
|
||||||
hm.insert("black", "#cbccd5".to_string());
|
|
||||||
hm.insert("red", "#c90e42".to_string());
|
|
||||||
hm.insert("green", "#21883a".to_string());
|
|
||||||
hm.insert("yellow", "#d54d17".to_string());
|
|
||||||
hm.insert("blue", "#1e44dd".to_string());
|
|
||||||
hm.insert("magenta", "#6d1bed".to_string());
|
|
||||||
hm.insert("cyan", "#1f4d7a".to_string());
|
|
||||||
hm.insert("white", "#000000".to_string());
|
|
||||||
|
|
||||||
// Try to make theme work with light or dark but
|
|
||||||
// flipping the foreground and background but leave
|
|
||||||
// the other colors the same.
|
|
||||||
if is_dark {
|
|
||||||
hm.insert("background", "#2a2c33".to_string());
|
|
||||||
hm.insert("foreground", "#f7f7f7".to_string());
|
|
||||||
} else {
|
|
||||||
hm.insert("background", "#f7f7f7".to_string());
|
|
||||||
hm.insert("foreground", "#2a2c33".to_string());
|
|
||||||
}
|
|
||||||
|
|
||||||
hm
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_colors(is_dark: bool, theme: &Option<Tagged<String>>) -> HashMap<&'static str, String> {
|
|
||||||
let theme_name = match theme {
|
let theme_name = match theme {
|
||||||
Some(s) => s.to_string(),
|
Some(s) => s.to_string(),
|
||||||
None => "default".to_string(),
|
None => "default".to_string(), // There is no theme named "default" so this will be HtmlTheme::default(), which is "nu_default".
|
||||||
};
|
};
|
||||||
|
|
||||||
match theme_name.as_ref() {
|
// 228 themes come from
|
||||||
"default" => get_default_theme(is_dark),
|
// https://github.com/mbadolato/iTerm2-Color-Schemes/tree/master/windowsterminal
|
||||||
"campbell" => get_campbell_theme(is_dark),
|
// we should find a hit on any name in there
|
||||||
"github" => get_github_theme(is_dark),
|
let asset = get_asset_by_name_as_html_themes("228_themes.zip", "228_themes.json");
|
||||||
"blulocolight" => get_blulocolight_theme(is_dark),
|
|
||||||
_ => get_default_theme(is_dark),
|
// If asset doesn't work, make sure to return the default theme
|
||||||
|
let asset = match asset {
|
||||||
|
Ok(a) => a,
|
||||||
|
_ => HtmlThemes::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Find the theme by theme name
|
||||||
|
let th = asset
|
||||||
|
.themes
|
||||||
|
.iter()
|
||||||
|
.find(|&n| n.name.to_lowercase() == *theme_name.to_lowercase().as_str()); // case insensitive search
|
||||||
|
|
||||||
|
// If no theme is found by the name provided, ensure we return the default theme
|
||||||
|
let default_theme = HtmlTheme::default();
|
||||||
|
let th = match th {
|
||||||
|
Some(t) => t,
|
||||||
|
None => &default_theme,
|
||||||
|
};
|
||||||
|
|
||||||
|
// this just means no theme was passed in
|
||||||
|
if th.name.to_lowercase().eq(&"nu_default".to_string())
|
||||||
|
// this means there was a theme passed in
|
||||||
|
&& theme.is_some()
|
||||||
|
{
|
||||||
|
return Err(ShellError::labeled_error(
|
||||||
|
"Error finding theme name",
|
||||||
|
"Error finding theme name",
|
||||||
|
theme_tag.span,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Ok(convert_html_theme_to_hash_map(is_dark, th))
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_asset_by_name_as_html_themes(
|
||||||
|
zip_name: &str,
|
||||||
|
json_name: &str,
|
||||||
|
) -> Result<HtmlThemes, Box<dyn Error>> {
|
||||||
|
match Assets::get(zip_name) {
|
||||||
|
Some(content) => {
|
||||||
|
let asset: Vec<u8> = match content {
|
||||||
|
Cow::Borrowed(bytes) => bytes.into(),
|
||||||
|
Cow::Owned(bytes) => bytes,
|
||||||
|
};
|
||||||
|
let reader = std::io::Cursor::new(asset);
|
||||||
|
let mut archive = zip::ZipArchive::new(reader)?;
|
||||||
|
let mut zip_file = archive.by_name(json_name)?;
|
||||||
|
let mut contents = String::new();
|
||||||
|
zip_file.read_to_string(&mut contents)?;
|
||||||
|
Ok(serde_json::from_str(&contents)?)
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let th = HtmlThemes::default();
|
||||||
|
Ok(th)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn convert_html_theme_to_hash_map(
|
||||||
|
is_dark: bool,
|
||||||
|
theme: &HtmlTheme,
|
||||||
|
) -> HashMap<&'static str, String> {
|
||||||
|
let mut hm: HashMap<&str, String> = HashMap::new();
|
||||||
|
|
||||||
|
hm.insert("bold_black", theme.brightBlack[..].to_string());
|
||||||
|
hm.insert("bold_red", theme.brightRed[..].to_string());
|
||||||
|
hm.insert("bold_green", theme.brightGreen[..].to_string());
|
||||||
|
hm.insert("bold_yellow", theme.brightYellow[..].to_string());
|
||||||
|
hm.insert("bold_blue", theme.brightBlue[..].to_string());
|
||||||
|
hm.insert("bold_magenta", theme.brightPurple[..].to_string());
|
||||||
|
hm.insert("bold_cyan", theme.brightCyan[..].to_string());
|
||||||
|
hm.insert("bold_white", theme.brightWhite[..].to_string());
|
||||||
|
|
||||||
|
hm.insert("black", theme.black[..].to_string());
|
||||||
|
hm.insert("red", theme.red[..].to_string());
|
||||||
|
hm.insert("green", theme.green[..].to_string());
|
||||||
|
hm.insert("yellow", theme.yellow[..].to_string());
|
||||||
|
hm.insert("blue", theme.blue[..].to_string());
|
||||||
|
hm.insert("magenta", theme.purple[..].to_string());
|
||||||
|
hm.insert("cyan", theme.cyan[..].to_string());
|
||||||
|
hm.insert("white", theme.white[..].to_string());
|
||||||
|
|
||||||
|
// Try to make theme work with light or dark but
|
||||||
|
// flipping the foreground and background but leave
|
||||||
|
// the other colors the same.
|
||||||
|
if is_dark {
|
||||||
|
hm.insert("background", theme.black[..].to_string());
|
||||||
|
hm.insert("foreground", theme.white[..].to_string());
|
||||||
|
} else {
|
||||||
|
hm.insert("background", theme.white[..].to_string());
|
||||||
|
hm.insert("foreground", theme.black[..].to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
hm
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_list_of_theme_names() -> Vec<String> {
|
||||||
|
let asset = get_asset_by_name_as_html_themes("228_themes.zip", "228_themes.json");
|
||||||
|
|
||||||
|
// If asset doesn't work, make sure to return the default theme
|
||||||
|
let html_themes = match asset {
|
||||||
|
Ok(a) => a,
|
||||||
|
_ => HtmlThemes::default(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let theme_names: Vec<String> = html_themes
|
||||||
|
.themes
|
||||||
|
.iter()
|
||||||
|
.map(|n| n.name[..].to_string())
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
theme_names
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn to_html(
|
async fn to_html(
|
||||||
|
@ -252,6 +276,7 @@ async fn to_html(
|
||||||
dark,
|
dark,
|
||||||
partial,
|
partial,
|
||||||
theme,
|
theme,
|
||||||
|
list,
|
||||||
},
|
},
|
||||||
input,
|
input,
|
||||||
) = args.process(®istry).await?;
|
) = args.process(®istry).await?;
|
||||||
|
@ -261,66 +286,100 @@ async fn to_html(
|
||||||
.filter(|headers| !headers.is_empty() && (headers.len() > 1 || headers[0] != ""));
|
.filter(|headers| !headers.is_empty() && (headers.len() > 1 || headers[0] != ""));
|
||||||
let mut output_string = String::new();
|
let mut output_string = String::new();
|
||||||
let mut regex_hm: HashMap<u32, (&str, String)> = HashMap::new();
|
let mut regex_hm: HashMap<u32, (&str, String)> = HashMap::new();
|
||||||
let color_hm = get_colors(dark, &theme);
|
|
||||||
|
|
||||||
// change the color of the page
|
if list {
|
||||||
if !partial {
|
// Get the list of theme names
|
||||||
output_string.push_str(&format!(
|
let theme_names = get_list_of_theme_names();
|
||||||
r"<html><style>body {{ background-color:{};color:{}; }}</style><body>",
|
|
||||||
color_hm
|
// Put that list into the output string
|
||||||
.get("background")
|
for s in theme_names.iter() {
|
||||||
.expect("Error getting background color"),
|
output_string.push_str(&format!("{}\n", s));
|
||||||
color_hm
|
}
|
||||||
.get("foreground")
|
|
||||||
.expect("Error getting foreground color")
|
output_string.push_str("\nScreenshots of themes can be found here:\n");
|
||||||
));
|
output_string.push_str("https://github.com/mbadolato/iTerm2-Color-Schemes\n");
|
||||||
|
|
||||||
|
// Short circuit and return the output_string
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
|
UntaggedValue::string(output_string).into_value(name_tag),
|
||||||
|
)))
|
||||||
} else {
|
} else {
|
||||||
output_string.push_str(&format!(
|
let theme_tag = match &theme {
|
||||||
"<div style=\"background-color:{};color:{};\">",
|
Some(v) => &v.tag,
|
||||||
color_hm
|
None => &name_tag,
|
||||||
.get("background")
|
};
|
||||||
.expect("Error getting background color"),
|
|
||||||
color_hm
|
|
||||||
.get("foreground")
|
|
||||||
.expect("Error getting foreground color")
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let inner_value = match input.len() {
|
let color_hm = get_theme_from_asset_file(dark, &theme, &theme_tag);
|
||||||
0 => String::default(),
|
let color_hm = match color_hm {
|
||||||
1 => match headers {
|
Ok(c) => c,
|
||||||
Some(headers) => html_table(input, headers),
|
_ => {
|
||||||
None => {
|
return Err(ShellError::labeled_error(
|
||||||
let value = &input[0];
|
"Error finding theme name",
|
||||||
html_value(value)
|
"Error finding theme name",
|
||||||
|
theme_tag.span,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
_ => match headers {
|
|
||||||
Some(headers) => html_table(input, headers),
|
|
||||||
None => html_list(input),
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
output_string.push_str(&inner_value);
|
// change the color of the page
|
||||||
|
if !partial {
|
||||||
|
output_string.push_str(&format!(
|
||||||
|
r"<html><style>body {{ background-color:{};color:{}; }}</style><body>",
|
||||||
|
color_hm
|
||||||
|
.get("background")
|
||||||
|
.expect("Error getting background color"),
|
||||||
|
color_hm
|
||||||
|
.get("foreground")
|
||||||
|
.expect("Error getting foreground color")
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
output_string.push_str(&format!(
|
||||||
|
"<div style=\"background-color:{};color:{};\">",
|
||||||
|
color_hm
|
||||||
|
.get("background")
|
||||||
|
.expect("Error getting background color"),
|
||||||
|
color_hm
|
||||||
|
.get("foreground")
|
||||||
|
.expect("Error getting foreground color")
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
if !partial {
|
let inner_value = match input.len() {
|
||||||
output_string.push_str("</body></html>");
|
0 => String::default(),
|
||||||
} else {
|
1 => match headers {
|
||||||
output_string.push_str("</div>")
|
Some(headers) => html_table(input, headers),
|
||||||
|
None => {
|
||||||
|
let value = &input[0];
|
||||||
|
html_value(value)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => match headers {
|
||||||
|
Some(headers) => html_table(input, headers),
|
||||||
|
None => html_list(input),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
output_string.push_str(&inner_value);
|
||||||
|
|
||||||
|
if !partial {
|
||||||
|
output_string.push_str("</body></html>");
|
||||||
|
} else {
|
||||||
|
output_string.push_str("</div>")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check to see if we want to remove all color or change ansi to html colors
|
||||||
|
if html_color {
|
||||||
|
setup_html_color_regexes(&mut regex_hm, &color_hm);
|
||||||
|
output_string = run_regexes(®ex_hm, &output_string);
|
||||||
|
} else if no_color {
|
||||||
|
setup_no_color_regexes(&mut regex_hm);
|
||||||
|
output_string = run_regexes(®ex_hm, &output_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(OutputStream::one(ReturnSuccess::value(
|
||||||
|
UntaggedValue::string(output_string).into_value(name_tag),
|
||||||
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check to see if we want to remove all color or change ansi to html colors
|
|
||||||
if html_color {
|
|
||||||
setup_html_color_regexes(&mut regex_hm, dark, &theme);
|
|
||||||
output_string = run_regexes(®ex_hm, &output_string);
|
|
||||||
} else if no_color {
|
|
||||||
setup_no_color_regexes(&mut regex_hm);
|
|
||||||
output_string = run_regexes(®ex_hm, &output_string);
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(OutputStream::one(ReturnSuccess::value(
|
|
||||||
UntaggedValue::string(output_string).into_value(name_tag),
|
|
||||||
)))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn html_list(list: Vec<Value>) -> String {
|
fn html_list(list: Vec<Value>) -> String {
|
||||||
|
@ -438,11 +497,8 @@ fn html_value(value: &Value) -> String {
|
||||||
|
|
||||||
fn setup_html_color_regexes(
|
fn setup_html_color_regexes(
|
||||||
hash: &mut HashMap<u32, (&'static str, String)>,
|
hash: &mut HashMap<u32, (&'static str, String)>,
|
||||||
is_dark: bool,
|
color_hm: &HashMap<&str, String>,
|
||||||
theme: &Option<Tagged<String>>,
|
|
||||||
) {
|
) {
|
||||||
let color_hm = get_colors(is_dark, theme);
|
|
||||||
|
|
||||||
// All the bold colors
|
// All the bold colors
|
||||||
hash.insert(
|
hash.insert(
|
||||||
0,
|
0,
|
||||||
|
|
|
@ -60,21 +60,6 @@ fn test_cd_html_color_flag_dark_false() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_cd_html_color_flag_dark_true() {
|
|
||||||
let actual = nu!(
|
|
||||||
cwd: ".", pipeline(
|
|
||||||
r#"
|
|
||||||
cd --help | to html --html_color --dark
|
|
||||||
"#
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
actual.out,
|
|
||||||
r"<html><style>body { background-color:black;color:white; }</style><body>Change to a new path.<br><br>Usage:<br> > cd (directory) {flags} <br><br>Parameters:<br> (directory) the directory to change to<br><br>Flags:<br> -h, --help: Display this help message<br><br>Examples:<br> Change to a new directory called 'dirname'<br> > <span style='color:cyan;font-weight:bold;'>cd<span style='color:white;font-weight:normal;'></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:cyan;'>dirname<span style='color:white;font-weight:normal;'><br><br> Change to your home directory<br> > </span><span style='color:cyan;font-weight:bold;'>cd<span style='color:white;font-weight:normal;'><br><br> Change to your home directory (alternate version)<br> > </span></span><span style='color:cyan;font-weight:bold;'>cd<span style='color:white;font-weight:normal;'></span></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:cyan;'>~<span style='color:white;font-weight:normal;'><br><br> Change to the previous directory<br> > </span><span style='color:cyan;font-weight:bold;'>cd<span style='color:white;font-weight:normal;'></span></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:cyan;'>-<span style='color:white;font-weight:normal;'><br><br></body></html></span></span></span>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_no_color_flag() {
|
fn test_no_color_flag() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
|
@ -90,21 +75,6 @@ fn test_no_color_flag() {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_html_color_where_flag_dark_true() {
|
|
||||||
let actual = nu!(
|
|
||||||
cwd: ".", pipeline(
|
|
||||||
r#"
|
|
||||||
where --help | to html --html_color --dark
|
|
||||||
"#
|
|
||||||
)
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
actual.out,
|
|
||||||
r"<html><style>body { background-color:black;color:white; }</style><body>Filter table to match the condition.<br><br>Usage:<br> > where <condition> {flags} <br><br>Parameters:<br> <condition> the condition that must match<br><br>Flags:<br> -h, --help: Display this help message<br><br>Examples:<br> List all files in the current directory with sizes greater than 2kb<br> > <span style='color:cyan;font-weight:bold;'>ls<span style='color:white;font-weight:normal;'></span></span><span style='color:white;'> | <span style='color:white;font-weight:normal;'></span><span style='color:cyan;font-weight:bold;'>where<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;font-weight:bold;'>size<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;'>><span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:magenta;font-weight:bold;'>2<span style='color:white;font-weight:normal;'></span></span><span style='color:cyan;font-weight:bold;'>kb<span style='color:white;font-weight:normal;'><br><br> List only the files in the current directory<br> > </span></span><span style='color:cyan;font-weight:bold;'>ls<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> | <span style='color:white;font-weight:normal;'></span><span style='color:cyan;font-weight:bold;'>where<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;font-weight:bold;'>type<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;'>==<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:green;'>File<span style='color:white;font-weight:normal;'><br><br> List all files with names that contain "Car"<br> > </span><span style='color:cyan;font-weight:bold;'>ls<span style='color:white;font-weight:normal;'></span></span></span></span><span style='color:white;'> | <span style='color:white;font-weight:normal;'></span><span style='color:cyan;font-weight:bold;'>where<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;font-weight:bold;'>name<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;'>=~<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:green;'>"Car"<span style='color:white;font-weight:normal;'><br><br> List all files that were modified in the last two months<br> > </span><span style='color:cyan;font-weight:bold;'>ls<span style='color:white;font-weight:normal;'></span></span></span></span><span style='color:white;'> | <span style='color:white;font-weight:normal;'></span><span style='color:cyan;font-weight:bold;'>where<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;font-weight:bold;'>modified<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:yellow;'><=<span style='color:white;font-weight:normal;'></span></span></span><span style='color:white;'> <span style='color:white;font-weight:normal;'></span><span style='color:magenta;font-weight:bold;'>2<span style='color:white;font-weight:normal;'></span></span><span style='color:cyan;font-weight:bold;'>M<span style='color:white;font-weight:normal;'><br><br></body></html></span></span></span>"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_html_color_where_flag_dark_false() {
|
fn test_html_color_where_flag_dark_false() {
|
||||||
let actual = nu!(
|
let actual = nu!(
|
||||||
|
|
Loading…
Reference in a new issue