From 67a3ae1c4023b658f99d6bc82136002c07f389b6 Mon Sep 17 00:00:00 2001 From: Julien Blanchard Date: Wed, 20 May 2020 17:47:34 +0200 Subject: [PATCH] Font are customizable - Can change family (sans/serif/monospace) - Can change size - Can change style (normal/italic/oblique) --- Cargo.lock | 3 +- Cargo.toml | 3 +- README.md | 33 ++- data/castor_settings.toml.example | 31 ++- src/draw.rs | 82 ++++--- src/finger/client.rs | 6 +- src/gemini/client.rs | 4 +- src/gopher/link.rs | 8 + src/gopher/parser.rs | 7 +- src/main.rs | 4 +- src/settings.rs | 377 +++++++++++++++++++++++------- 11 files changed, 406 insertions(+), 152 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b6c7e86..55addff 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -112,7 +112,7 @@ dependencies = [ [[package]] name = "castor" -version = "0.8.8" +version = "0.8.9" dependencies = [ "ansi-parser", "dirs", @@ -127,6 +127,7 @@ dependencies = [ "open", "openssl", "pango", + "pango-sys", "percent-encoding", "regex", "serde", diff --git a/Cargo.toml b/Cargo.toml index 71ecea8..ab14b33 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "castor" -version = "0.8.8" +version = "0.8.9" authors = ["Julien Blanchard "] edition = "2018" @@ -13,6 +13,7 @@ gio = "*" glib = "*" glib-sys = "*" pango = "*" +pango-sys = "*" open = "*" regex = "*" native-tls = "*" diff --git a/README.md b/README.md index 4c3586a..89af274 100644 --- a/README.md +++ b/README.md @@ -82,12 +82,33 @@ background = "#FFC0CB" h1 = ">" h2 = "))" h3 = "}}}" -list = "🌼" - -[monospace] -gemini=false -gopher=true -finger=true +list = "🌼 " + +[fonts] +[fonts.finger] + family = "monospace" + size = 11 +[fonts.gemini] + family = "serif" + size = 11 +[fonts.gemini.h1] + family = "sans" + size = 16 + style = "normal" +[fonts.gemini.h2] + family = "monospace" + size = 13 + style = "italic" +[fonts.gemini.h3] + family = "monospace" + size = 12 +[fonts.gemini.list] + family = "sans" + size = 11 + style = "oblique" +[fonts.gopher] + family = "monospace" + size = 11 ``` diff --git a/data/castor_settings.toml.example b/data/castor_settings.toml.example index c0f0d4c..28b5243 100644 --- a/data/castor_settings.toml.example +++ b/data/castor_settings.toml.example @@ -13,9 +13,30 @@ background = "#FFC0CB" h1 = ">" h2 = "))" h3 = "}}}" -list = "🌼" +list = "🌼 " -[monospace] -gemini=false -gopher=true -finger=true +[fonts] +[fonts.finger] + family = "monospace" + size = 11 +[fonts.gemini] + family = "serif" + size = 11 +[fonts.gemini.h1] + family = "sans" + size = 16 + style = "normal" +[fonts.gemini.h2] + family = "monospace" + size = 13 + style = "italic" +[fonts.gemini.h3] + family = "monospace" + size = 12 +[fonts.gemini.list] + family = "sans" + size = 11 + style = "oblique" +[fonts.gopher] + family = "monospace" + size = 11 diff --git a/src/draw.rs b/src/draw.rs index 4d81533..d445787 100644 --- a/src/draw.rs +++ b/src/draw.rs @@ -19,11 +19,7 @@ pub fn gemini_content( let buffer = content_view.get_buffer().unwrap(); let mut mono_toggle = false; - let font_family = if crate::settings::gemini_monospace() { - "monospace" - } else { - "sans" - }; + let font_family = crate::settings::get_gemini_text_font_family(); for el in content { match el { @@ -32,10 +28,12 @@ pub fn gemini_content( buffer.insert_markup( &mut end_iter, &format!( - "{}{}\n", - crate::settings::h1_color(), - font_family, - crate::settings::h1_character(), + "{}{}\n", + crate::settings::get_h1_color(), + crate::settings::get_gemini_h1_font_size(), + crate::settings::get_gemini_h1_font_family(), + crate::settings::get_gemini_h1_font_style(), + crate::settings::get_h1_character(), escape_text(&header) ), ); @@ -45,10 +43,12 @@ pub fn gemini_content( buffer.insert_markup( &mut end_iter, &format!( - "{}{}\n", - crate::settings::h2_color(), - font_family, - crate::settings::h2_character(), + "{}{}\n", + crate::settings::get_h2_color(), + crate::settings::get_gemini_h2_font_size(), + crate::settings::get_gemini_h2_font_family(), + crate::settings::get_gemini_h2_font_style(), + crate::settings::get_h2_character(), escape_text(&header) ), ); @@ -58,10 +58,12 @@ pub fn gemini_content( buffer.insert_markup( &mut end_iter, &format!( - "{}{}\n", - crate::settings::h3_color(), - font_family, - crate::settings::h3_character(), + "{}{}\n", + crate::settings::get_h3_color(), + crate::settings::get_gemini_h3_font_size(), + crate::settings::get_gemini_h3_font_family(), + crate::settings::get_gemini_h3_font_style(), + crate::settings::get_h3_character(), escape_text(&header) ), ); @@ -71,10 +73,12 @@ pub fn gemini_content( buffer.insert_markup( &mut end_iter, &format!( - "{} {}\n", - crate::settings::list_color(), - font_family, - crate::settings::list_character(), + "{}{}\n", + crate::settings::get_list_color(), + crate::settings::get_gemini_list_font_size(), + crate::settings::get_gemini_list_font_family(), + crate::settings::get_gemini_list_font_style(), + crate::settings::get_list_character(), escape_text(&item) ), ); @@ -94,8 +98,9 @@ pub fn gemini_content( buffer.insert_markup( &mut end_iter, &format!( - "{}\n", - crate::settings::text_color(), + "{}\n", + crate::settings::get_text_color(), + crate::settings::get_gemini_text_font_size(), text ), ); @@ -103,9 +108,10 @@ pub fn gemini_content( buffer.insert_markup( &mut end_iter, &format!( - "{}\n", - crate::settings::text_color(), + "{}\n", + crate::settings::get_text_color(), font_family, + crate::settings::get_gemini_text_font_size(), text ), ); @@ -130,7 +136,7 @@ pub fn gemini_text_content(gui: &Arc, content: std::str::Lines) -> TextBuff &mut end_iter, &format!( "{}\n", - crate::settings::text_color(), + crate::settings::get_text_color(), escape_text(&line) ), ); @@ -149,11 +155,6 @@ pub fn gopher_content( match el { Ok(crate::gopher::parser::TextElement::Text(text)) => { let mut end_iter = buffer.get_end_iter(); - let font_family = if crate::settings::gopher_monospace() { - "font_family=\"monospace\"" - } else { - "font_family=\"serif\"" - }; let text = if text.contains("{}\n", - crate::settings::text_color(), - font_family, + "{}\n", + crate::settings::get_text_color(), + crate::settings::get_gopher_font_family(), + crate::settings::get_gopher_font_size(), text ), ); @@ -200,18 +202,14 @@ pub fn finger_content( match el { Ok(crate::finger::parser::TextElement::Text(text)) => { let mut end_iter = buffer.get_end_iter(); - let font_family = if crate::settings::finger_monospace() { - "font_family=\"monospace\"" - } else { - "font_family=\"serif\"" - }; buffer.insert_markup( &mut end_iter, &format!( - "{}\n", - crate::settings::text_color(), - font_family, + "{}\n", + crate::settings::get_text_color(), + crate::settings::get_finger_font_family(), + crate::settings::get_finger_font_size(), escape_text(&text) ), ); diff --git a/src/finger/client.rs b/src/finger/client.rs index 5b1efcb..b3abefd 100644 --- a/src/finger/client.rs +++ b/src/finger/client.rs @@ -37,13 +37,13 @@ pub fn get_data(url: T) -> Result<(Option>, Vec), Strin Ok((None, res)) }) - .join() - .unwrap(), + .join() + .unwrap(), Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)), } } None => Err(format!("Could not connect to {}\n", urlf)), - } + }, Err(e) => Err(format!("Could not connect to {}\n{}", urlf, e)), } } diff --git a/src/gemini/client.rs b/src/gemini/client.rs index b096bdb..d62e5d8 100644 --- a/src/gemini/client.rs +++ b/src/gemini/client.rs @@ -31,8 +31,8 @@ pub fn get_data(url: T) -> Result<(Option>, Vec), Strin V4(ip) => V4(ip), V6(ip) => match addrs_iter.next() { Some(addr) => addr, - None => V6(ip) - } + None => V6(ip), + }, }; let stream = TcpStream::connect_timeout(&socket_addr, Duration::new(5, 0)); diff --git a/src/gopher/link.rs b/src/gopher/link.rs index 3c8dfac..6da4aed 100644 --- a/src/gopher/link.rs +++ b/src/gopher/link.rs @@ -170,6 +170,14 @@ impl FromStr for Link { } else { Err(ParseError) } + // } else if line.contains("://") { + // let url = extract_url(line); + // let label = String::from(line); + + // match make_link(String::from(url), label) { + // Some(link) => Ok(link), + // None => Err(ParseError), + // } } else { Err(ParseError) } diff --git a/src/gopher/parser.rs b/src/gopher/parser.rs index 5d8b0d3..7c99041 100644 --- a/src/gopher/parser.rs +++ b/src/gopher/parser.rs @@ -42,7 +42,12 @@ impl FromStr for TextElement { // Text line if line.contains("gopher://") { Ok(TextElement::LinkItem(String::from(line))) - } else if line.contains("http://") || line.contains("https://") || line.contains("gemini://") || line.contains("finger://") || line.contains("ftp://") { + } else if line.contains("http://") + || line.contains("https://") + || line.contains("gemini://") + || line.contains("finger://") + || line.contains("ftp://") + { Ok(TextElement::ExternalLinkItem(String::from(line))) } else { Ok(TextElement::Text(colors::colorize(line))) diff --git a/src/main.rs b/src/main.rs index c8d8393..a2db1c1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -190,7 +190,9 @@ pub fn visit_url(gui: &Arc, url: T) { let absolute_url = url.to_absolute_url(); match absolute_url { - Ok(absolute_url) => match gemini::client::get_data(Gemini { source: absolute_url.to_string() }) { + Ok(absolute_url) => match gemini::client::get_data(Gemini { + source: absolute_url.to_string(), + }) { Ok((meta, new_content)) => { let meta_str = String::from_utf8_lossy(&meta.unwrap()).to_string(); diff --git a/src/settings.rs b/src/settings.rs index ac8232c..8d96b6b 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -12,7 +12,7 @@ struct Settings { general: Option, colors: Option, characters: Option, - monospace: Option, + fonts: Option, } #[derive(Deserialize)] @@ -38,11 +38,27 @@ struct Character { list: Option, } -#[derive(Deserialize)] -struct Monospace { - finger: Option, - gemini: Option, - gopher: Option, +#[derive(Debug, Deserialize)] +struct Font { + finger: Option, + gemini: Option, + gopher: Option, +} + +#[derive(Debug, Deserialize)] +struct FontAttr { + family: Option, + style: Option, + size: Option, +} + +#[derive(Debug, Deserialize)] +struct GeminiFontAttr { + text: Option, + h1: Option, + h2: Option, + h3: Option, + list: Option, } pub fn start_url() -> Option { @@ -52,130 +68,311 @@ pub fn start_url() -> Option { } } -pub fn h1_color() -> String { - match read().colors { - Some(colors) => match colors.h1 { - Some(color) => color, - None => String::from("#9932CC"), - }, +const DEFAULT_FONT: &str = "serif"; +const DEFAULT_FONT_STYLE: &str = "normal"; +const DEFAULT_FONT_SIZE: i32 = 11 * pango_sys::PANGO_SCALE; +const DEFAULT_H1_FONT_SIZE: i32 = 16 * pango_sys::PANGO_SCALE; +const DEFAULT_H2_FONT_SIZE: i32 = 13 * pango_sys::PANGO_SCALE; +const DEFAULT_H3_FONT_SIZE: i32 = 12 * pango_sys::PANGO_SCALE; + +fn finger_font_family() -> Option { + read().fonts?.finger?.family +} + +fn finger_font_size() -> Option { + read().fonts?.finger?.size.or(Some(DEFAULT_FONT_SIZE)) +} + +pub fn get_finger_font_family() -> String { + match finger_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +pub fn get_finger_font_size() -> i32 { + match finger_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_FONT_SIZE, + } +} + +fn gemini_text_font_family() -> Option { + read().fonts?.gemini?.text?.family +} + +pub fn get_gemini_text_font_family() -> String { + match gemini_text_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +fn gemini_text_font_size() -> Option { + read().fonts?.gemini?.text?.size +} + +pub fn get_gemini_text_font_size() -> i32 { + match gemini_text_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_FONT_SIZE, + } +} + +fn gemini_h1_font_family() -> Option { + read().fonts?.gemini?.h1?.family +} + +fn gemini_h1_font_size() -> Option { + read().fonts?.gemini?.h1?.size +} + +fn gemini_h1_font_style() -> Option { + read().fonts?.gemini?.h1?.style +} + +pub fn get_gemini_h1_font_size() -> i32 { + match gemini_h1_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_H1_FONT_SIZE, + } +} + +pub fn get_gemini_h1_font_family() -> String { + match gemini_h1_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +pub fn get_gemini_h1_font_style() -> String { + match gemini_h1_font_style() { + Some(style) => style, + None => String::from(DEFAULT_FONT_STYLE), + } +} + +fn gemini_h2_font_family() -> Option { + read().fonts?.gemini?.h2?.family +} + +fn gemini_h2_font_size() -> Option { + read().fonts?.gemini?.h2?.size +} + +fn gemini_h2_font_style() -> Option { + read().fonts?.gemini?.h2?.style +} + +pub fn get_gemini_h2_font_size() -> i32 { + match gemini_h2_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_H2_FONT_SIZE, + } +} + +pub fn get_gemini_h2_font_family() -> String { + match gemini_h2_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +pub fn get_gemini_h2_font_style() -> String { + match gemini_h2_font_style() { + Some(style) => style, + None => String::from(DEFAULT_FONT_STYLE), + } +} + +fn gemini_h3_font_family() -> Option { + read().fonts?.gemini?.h3?.family +} + +fn gemini_h3_font_size() -> Option { + read().fonts?.gemini?.h3?.size +} + +fn gemini_h3_font_style() -> Option { + read().fonts?.gemini?.h3?.style +} + +pub fn get_gemini_h3_font_size() -> i32 { + match gemini_h3_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_H3_FONT_SIZE, + } +} + +pub fn get_gemini_h3_font_family() -> String { + match gemini_h3_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +pub fn get_gemini_h3_font_style() -> String { + match gemini_h3_font_style() { + Some(style) => style, + None => String::from(DEFAULT_FONT_STYLE), + } +} + +fn gemini_list_font_family() -> Option { + read().fonts?.gemini?.list?.family +} + +fn gemini_list_font_size() -> Option { + read().fonts?.gemini?.list?.size +} + +fn gemini_list_font_style() -> Option { + read().fonts?.gemini?.list?.style +} + +pub fn get_gemini_list_font_size() -> i32 { + match gemini_list_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_FONT_SIZE, + } +} + +pub fn get_gemini_list_font_family() -> String { + match gemini_list_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +pub fn get_gemini_list_font_style() -> String { + match gemini_list_font_style() { + Some(style) => style, + None => String::from(DEFAULT_FONT_STYLE), + } +} + +fn gopher_font_family() -> Option { + read().fonts?.gopher?.family +} + +fn gopher_font_size() -> Option { + read().fonts?.gopher?.size +} + +pub fn get_gopher_font_family() -> String { + match gopher_font_family() { + Some(family) => family, + None => String::from(DEFAULT_FONT), + } +} + +pub fn get_gopher_font_size() -> i32 { + match gopher_font_size() { + Some(size) => size * pango_sys::PANGO_SCALE, + None => DEFAULT_FONT_SIZE, + } +} + +fn h1_color() -> Option { + read().colors?.h1 +} + +pub fn get_h1_color() -> String { + match h1_color() { + Some(color) => color, None => String::from("#9932CC"), } } -pub fn h2_color() -> String { - match read().colors { - Some(colors) => match colors.h2 { - Some(color) => color, - None => String::from("#FF1493"), - }, +fn h2_color() -> Option { + read().colors?.h2 +} + +pub fn get_h2_color() -> String { + match h2_color() { + Some(color) => color, None => String::from("#FF1493"), } } -pub fn h3_color() -> String { - match read().colors { - Some(colors) => match colors.h3 { - Some(color) => color, - None => String::from("#87CEFA"), - }, +fn h3_color() -> Option { + read().colors?.h3 +} + +pub fn get_h3_color() -> String { + match h3_color() { + Some(color) => color, None => String::from("#87CEFA"), } } -pub fn list_color() -> String { - match read().colors { - Some(colors) => match colors.list { - Some(color) => color, - None => String::from("green"), - }, +fn list_color() -> Option { + read().colors?.list +} + +pub fn get_list_color() -> String { + match list_color() { + Some(color) => color, None => String::from("green"), } } -pub fn text_color() -> String { - match read().colors { - Some(colors) => match colors.text { - Some(color) => color, - None => String::from("black"), - }, +fn text_color() -> Option { + read().colors?.text +} + +pub fn get_text_color() -> String { + match text_color() { + Some(color) => color, None => String::from("black"), } } pub fn background_color() -> Option { - match read().colors { - Some(colors) => colors.background, - None => None, - } + read().colors?.background } -pub fn h1_character() -> String { - match read().characters { - Some(characters) => match characters.h1 { - Some(character) => character, - None => String::new(), - }, - None => String::new(), - } +fn h1_character() -> Option { + read().characters?.h1 } -pub fn h2_character() -> String { - match read().characters { - Some(characters) => match characters.h2 { - Some(character) => character, - None => String::new(), - }, +pub fn get_h1_character() -> String { + match h1_character() { + Some(char) => char, None => String::new(), } } -pub fn h3_character() -> String { - match read().characters { - Some(characters) => match characters.h3 { - Some(character) => character, - None => String::new(), - }, +fn h2_character() -> Option { + read().characters?.h2 +} + +pub fn get_h2_character() -> String { + match h2_character() { + Some(char) => char, None => String::new(), } } -pub fn list_character() -> String { - match read().characters { - Some(characters) => match characters.list { - Some(character) => character, - None => String::from("■"), - }, - None => String::from("■"), - } +fn h3_character() -> Option { + read().characters?.h3 } -pub fn finger_monospace() -> bool { - match read().monospace { - Some(monospace) => match monospace.finger { - Some(setting) => setting, - None => true, - }, - None => true, +pub fn get_h3_character() -> String { + match h3_character() { + Some(char) => char, + None => String::new(), } } -pub fn gemini_monospace() -> bool { - match read().monospace { - Some(monospace) => match monospace.gemini { - Some(setting) => setting, - None => true, - }, - None => true, - } +fn list_character() -> Option { + read().characters?.list } -pub fn gopher_monospace() -> bool { - match read().monospace { - Some(monospace) => match monospace.gopher { - Some(setting) => setting, - None => true, - }, - None => true, +pub fn get_list_character() -> String { + match list_character() { + Some(char) => char, + None => String::from("■"), } } -- 2.38.5