diff --git a/src/config.rs b/src/config.rs index 763a7ca..182a6db 100644 --- a/src/config.rs +++ b/src/config.rs @@ -2,7 +2,8 @@ use crate::{ code::snippet::SnippetLanguage, commands::keyboard::KeyBinding, terminal::{ - GraphicsMode, emulator::TerminalEmulator, image::protocols::kitty::KittyMode, query::TerminalCapabilities, + GraphicsMode, capabilities::TerminalCapabilities, emulator::TerminalEmulator, + image::protocols::kitty::KittyMode, }, }; use clap::ValueEnum; diff --git a/src/demo.rs b/src/demo.rs index bb92488..edf92f0 100644 --- a/src/demo.rs +++ b/src/demo.rs @@ -11,7 +11,7 @@ use crate::{ builder::{BuildError, PresentationBuilder}, }, render::TerminalDrawer, - terminal::TerminalWrite, + terminal::{TerminalWrite, emulator::TerminalEmulator}, }; use std::{io, rc::Rc}; @@ -104,7 +104,10 @@ impl ThemesDemo { let image_registry = ImageRegistry::default(); let mut resources = Resources::new("non_existent", image_registry.clone()); let mut third_party = ThirdPartyRender::default(); - let options = PresentationBuilderOptions::default(); + let options = PresentationBuilderOptions { + font_size_supported: TerminalEmulator::capabilities().font_size, + ..Default::default() + }; let executer = Rc::new(SnippetExecutor::default()); let bindings_config = Default::default(); let builder = PresentationBuilder::new( diff --git a/src/main.rs b/src/main.rs index 3bd6aa7..912e2fe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,7 @@ use std::{ rc::Rc, sync::Arc, }; +use terminal::emulator::TerminalEmulator; mod code; mod commands; @@ -258,6 +259,7 @@ impl CoreComponents { enable_snippet_execution_replace: config.snippet.exec_replace.enable, render_speaker_notes_only, auto_render_languages: config.options.auto_render_languages.clone(), + font_size_supported: TerminalEmulator::capabilities().font_size, } } @@ -349,6 +351,8 @@ fn run(cli: Cli) -> Result<(), Box> { println!("{}", String::from_utf8_lossy(acknowledgements)); return Ok(()); } else if cli.list_themes { + // Load this ahead of time so we don't do it when we're already in raw mode. + TerminalEmulator::capabilities(); let Customizations { config, themes, .. } = Customizations::load(cli.config_file.clone().map(PathBuf::from), ¤t_dir()?)?; let bindings = config.bindings.try_into()?; diff --git a/src/markdown/text.rs b/src/markdown/text.rs index 9d1c7e8..623db31 100644 --- a/src/markdown/text.rs +++ b/src/markdown/text.rs @@ -12,6 +12,7 @@ use unicode_width::{UnicodeWidthChar, UnicodeWidthStr}; pub(crate) struct WeightedLine { text: Vec, width: usize, + height: u8, } impl WeightedLine { @@ -25,6 +26,11 @@ impl WeightedLine { self.width } + /// The height of this line. + pub(crate) fn height(&self) -> u8 { + self.height + } + /// Get an iterator to the underlying text chunks. #[cfg(test)] pub(crate) fn iter_texts(&self) -> impl Iterator { @@ -43,6 +49,7 @@ impl From> for WeightedLine { let mut output = Vec::new(); let mut index = 0; let mut width = 0; + let mut height = 1; // Compact chunks so any consecutive chunk with the same style is merged into the same block. while index < texts.len() { let mut target = mem::replace(&mut texts[index], Text::from("")); @@ -52,11 +59,13 @@ impl From> for WeightedLine { target.content.push_str(¤t_content); current += 1; } - width += target.content.width(); + let size = target.style.size.max(1); + width += target.content.width() * size as usize; output.push(target.into()); index = current; + height = height.max(size); } - Self { text: output, width } + Self { text: output, width, height } } } @@ -64,7 +73,7 @@ impl From for WeightedLine { fn from(text: String) -> Self { let width = text.width(); let text = vec![WeightedText::from(text)]; - Self { text, width } + Self { text, width, height: 1 } } } @@ -325,7 +334,8 @@ mod test { #[test] fn no_split_necessary() { - let text = WeightedLine { text: vec![WeightedText::from("short"), WeightedText::from("text")], width: 0 }; + let text = + WeightedLine { text: vec![WeightedText::from("short"), WeightedText::from("text")], width: 0, height: 1 }; let lines = join_lines(text.split(50)); let expected = vec!["short text"]; assert_eq!(lines, expected); @@ -333,7 +343,7 @@ mod test { #[test] fn split_lines_single() { - let text = WeightedLine { text: vec![WeightedText::from("this is a slightly long line")], width: 0 }; + let text = WeightedLine { text: vec![WeightedText::from("this is a slightly long line")], width: 0, height: 1 }; let lines = join_lines(text.split(6)); let expected = vec!["this", "is a", "slight", "ly", "long", "line"]; assert_eq!(lines, expected); @@ -348,6 +358,7 @@ mod test { WeightedText::from("yet some other piece"), ], width: 0, + height: 1, }; let lines = join_lines(text.split(10)); let expected = vec!["this is a", "slightly", "long line", "another", "chunk yet", "some other", "piece"]; @@ -363,6 +374,7 @@ mod test { WeightedText::from("yet some other piece"), ], width: 0, + height: 1, }; let lines = join_lines(text.split(50)); let expected = vec!["this is a slightly long line another chunk yet some", "other piece"]; diff --git a/src/markdown/text_style.rs b/src/markdown/text_style.rs index eacda84..19fc645 100644 --- a/src/markdown/text_style.rs +++ b/src/markdown/text_style.rs @@ -1,5 +1,5 @@ use crate::theme::ColorPalette; -use crossterm::style::Stylize; +use crossterm::style::{StyledContent, Stylize}; use hex::{FromHex, FromHexError}; use serde::{Deserialize, Serialize}; use serde_with::{DeserializeFromStr, SerializeDisplay}; @@ -10,15 +10,27 @@ use std::{ }; /// The style of a piece of text. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)] +#[derive(Clone, Copy, Debug, PartialEq, Eq)] pub(crate) struct TextStyle { flags: u8, pub(crate) colors: Colors, + pub(crate) size: u8, +} + +impl Default for TextStyle { + fn default() -> Self { + Self { flags: Default::default(), colors: Default::default(), size: 1 } + } } impl TextStyle { pub(crate) fn colored(colors: Colors) -> Self { - Self { flags: Default::default(), colors } + Self { colors, ..Default::default() } + } + + pub(crate) fn size(mut self, size: u8) -> Self { + self.size = size.min(16); + self } /// Add bold to this style. @@ -107,13 +119,18 @@ impl TextStyle { /// Merge this style with another one. pub(crate) fn merge(&mut self, other: &TextStyle) { self.flags |= other.flags; + self.size = self.size.max(other.size); self.colors.background = self.colors.background.or(other.colors.background); self.colors.foreground = self.colors.foreground.or(other.colors.foreground); } /// Apply this style to a piece of text. - pub(crate) fn apply>(&self, text: T) -> Result<::Styled, PaletteColorError> { - let text: String = text.into(); + pub(crate) fn apply>(&self, text: T) -> Result, PaletteColorError> { + let text = text.into(); + let text = match self.size { + 0 | 1 => text, + size => format!("\x1b]66;s={size};{text}\x1b\\"), + }; let mut styled = text.stylize(); if self.is_bold() { styled = styled.bold(); diff --git a/src/presentation/builder.rs b/src/presentation/builder.rs index 06b2096..bc5acb2 100644 --- a/src/presentation/builder.rs +++ b/src/presentation/builder.rs @@ -77,6 +77,7 @@ pub struct PresentationBuilderOptions { pub enable_snippet_execution_replace: bool, pub render_speaker_notes_only: bool, pub auto_render_languages: Vec, + pub font_size_supported: bool, } impl PresentationBuilderOptions { @@ -114,6 +115,7 @@ impl Default for PresentationBuilderOptions { enable_snippet_execution_replace: false, render_speaker_notes_only: false, auto_render_languages: Default::default(), + font_size_supported: false, } } } @@ -395,7 +397,10 @@ impl<'a> PresentationBuilder<'a> { let styles = self.theme.intro_slide.clone(); let create_text = |text: Option, style: TextStyle| -> Option { text.map(|text| Text::new(text, style)) }; - let title = create_text(metadata.title, TextStyle::default().bold().colors(styles.title.colors)); + let title = create_text( + metadata.title, + TextStyle::default().bold().colors(styles.title.colors).size(self.font_size(styles.title.font_size)), + ); let sub_title = create_text(metadata.sub_title, TextStyle::default().colors(styles.subtitle.colors)); let event = create_text(metadata.event, TextStyle::default().colors(styles.event.colors)); let location = create_text(metadata.location, TextStyle::default().colors(styles.location.colors)); @@ -572,6 +577,7 @@ impl<'a> PresentationBuilder<'a> { let style = self.theme.slide_title.clone(); let mut text_style = TextStyle::default().colors(style.colors); + text_style = text_style.size(self.font_size(style.font_size)); if style.bold.unwrap_or_default() { text_style = text_style.bold(); } @@ -613,7 +619,7 @@ impl<'a> PresentationBuilder<'a> { prefix.push(' '); text.0.insert(0, Text::from(prefix)); } - let text_style = TextStyle::default().bold().colors(style.colors); + let text_style = TextStyle::default().bold().colors(style.colors).size(self.font_size(style.font_size)); text.apply_style(&text_style); self.push_text(text, element_type)?; @@ -1155,6 +1161,11 @@ impl<'a> PresentationBuilder<'a> { _ => Err(ImageAttributeError::UnknownAttribute(key.to_string())), } } + + fn font_size(&self, font_size: Option) -> u8 { + let Some(font_size) = font_size else { return 1 }; + if self.options.font_size_supported { font_size.clamp(1, 7) } else { 1 } + } } #[derive(Debug, Default)] diff --git a/src/render/engine.rs b/src/render/engine.rs index 91e3323..cb0519d 100644 --- a/src/render/engine.rs +++ b/src/render/engine.rs @@ -188,7 +188,7 @@ where } fn render_line_break(&mut self) -> RenderResult { - self.terminal.move_to_next_line(1)?; + self.terminal.move_to_next_line()?; Ok(()) } diff --git a/src/render/text.rs b/src/render/text.rs index 739f5ce..bd7ba53 100644 --- a/src/render/text.rs +++ b/src/render/text.rs @@ -5,7 +5,7 @@ use crate::{ text_style::{Color, Colors}, }, render::{RenderError, RenderResult, layout::Positioning}, - terminal::{Terminal, TerminalWrite}, + terminal::{Terminal, TerminalWrite, printer::TextProperties}, }; const MINIMUM_LINE_LENGTH: u16 = 10; @@ -23,6 +23,7 @@ pub(crate) struct TextDrawer<'a> { draw_block: bool, block_color: Option, repeat_prefix: bool, + properties: TextProperties, } impl<'a> TextDrawer<'a> { @@ -56,6 +57,7 @@ impl<'a> TextDrawer<'a> { draw_block: false, block_color: None, repeat_prefix: false, + properties: TextProperties { height: line.height() }, }) } } @@ -86,7 +88,7 @@ impl<'a> TextDrawer<'a> { style.apply(content)? }; terminal.move_to_column(self.positioning.start_column)?; - terminal.print_styled_line(styled_prefix.clone())?; + terminal.print_styled_line(styled_prefix.clone(), &self.properties)?; let start_column = self.positioning.start_column + self.prefix_length; for (line_index, line) in self.line.split(self.positioning.max_line_length as usize).enumerate() { @@ -100,7 +102,7 @@ impl<'a> TextDrawer<'a> { if self.prefix_length > 0 { terminal.move_to_column(self.positioning.start_column)?; if self.repeat_prefix { - terminal.print_styled_line(styled_prefix.clone())?; + terminal.print_styled_line(styled_prefix.clone(), &self.properties)?; } else { self.print_block_background(self.prefix_length, terminal)?; } @@ -112,7 +114,7 @@ impl<'a> TextDrawer<'a> { let (text, style) = chunk.into_parts(); let text = style.apply(text)?; - terminal.print_styled_line(text)?; + terminal.print_styled_line(text, &self.properties)?; // Crossterm resets colors if any attributes are set so let's just re-apply colors // if the format has anything on it at all. @@ -137,7 +139,7 @@ impl<'a> TextDrawer<'a> { terminal.set_background_color(color)?; } let text = " ".repeat(remaining as usize); - terminal.print_line(&text)?; + terminal.print_line(&text, &self.properties)?; } } Ok(()) diff --git a/src/terminal/query.rs b/src/terminal/capabilities.rs similarity index 91% rename from src/terminal/query.rs rename to src/terminal/capabilities.rs index db4a1be..f822ed3 100644 --- a/src/terminal/query.rs +++ b/src/terminal/capabilities.rs @@ -1,6 +1,11 @@ use super::image::protocols::kitty::{Action, ControlCommand, ControlOption, ImageFormat, TransmissionMedium}; use base64::{Engine, engine::general_purpose::STANDARD}; -use crossterm::terminal::{disable_raw_mode, enable_raw_mode}; +use crossterm::{ + QueueableCommand, + cursor::{self}, + style::Print, + terminal, +}; use image::{DynamicImage, EncodableLayout}; use std::{ env, @@ -8,12 +13,13 @@ use std::{ }; use tempfile::NamedTempFile; -#[derive(Default, Debug)] +#[derive(Default, Debug, Clone)] pub(crate) struct TerminalCapabilities { pub(crate) kitty_local: bool, pub(crate) kitty_remote: bool, pub(crate) sixel: bool, pub(crate) tmux: bool, + pub(crate) font_size: bool, } impl TerminalCapabilities { @@ -48,6 +54,19 @@ impl TerminalCapabilities { let mut response = Self::parse_response(io::stdin(), ids)?; response.tmux = tmux; + + // Use kitty's font size protocol to write 1 character using size 2. If after writing the + // cursor has moves 2 columns, the protocol is supported. + stdout.queue(terminal::EnterAlternateScreen)?; + stdout.queue(cursor::MoveTo(0, 0))?; + stdout.queue(Print("\x1b]66;s=2; \x1b\\"))?; + stdout.flush()?; + let position = cursor::position()?; + if position.0 == 2 { + response.font_size = true; + } + stdout.queue(terminal::LeaveAlternateScreen)?; + Ok(response) } @@ -113,14 +132,14 @@ struct RawModeGuard; impl RawModeGuard { fn new() -> io::Result { - enable_raw_mode()?; + terminal::enable_raw_mode()?; Ok(Self) } } impl Drop for RawModeGuard { fn drop(&mut self) { - let _ = disable_raw_mode(); + let _ = terminal::disable_raw_mode(); } } diff --git a/src/terminal/emulator.rs b/src/terminal/emulator.rs index 45187ed..e102c03 100644 --- a/src/terminal/emulator.rs +++ b/src/terminal/emulator.rs @@ -1,7 +1,10 @@ -use super::{GraphicsMode, image::protocols::kitty::KittyMode, query::TerminalCapabilities}; +use super::{GraphicsMode, capabilities::TerminalCapabilities, image::protocols::kitty::KittyMode}; +use once_cell::sync::Lazy; use std::env; use strum::IntoEnumIterator; +static CAPABILITIES: Lazy = Lazy::new(|| TerminalCapabilities::query().unwrap_or_default()); + #[derive(Debug, strum::EnumIter)] pub enum TerminalEmulator { Iterm2, @@ -30,8 +33,12 @@ impl TerminalEmulator { TerminalEmulator::Unknown } + pub(crate) fn capabilities() -> TerminalCapabilities { + CAPABILITIES.clone() + } + pub fn preferred_protocol(&self) -> GraphicsMode { - let capabilities = TerminalCapabilities::query().unwrap_or_default(); + let capabilities = Self::capabilities(); let modes = [ GraphicsMode::Iterm2, GraphicsMode::Kitty { mode: KittyMode::Local, inside_tmux: capabilities.tmux }, diff --git a/src/terminal/mod.rs b/src/terminal/mod.rs index 0f5c3a9..d11b5c3 100644 --- a/src/terminal/mod.rs +++ b/src/terminal/mod.rs @@ -1,8 +1,8 @@ pub(crate) mod ansi; +pub(crate) mod capabilities; pub(crate) mod emulator; pub(crate) mod image; pub(crate) mod printer; -pub(crate) mod query; pub(crate) use printer::{Terminal, TerminalWrite, should_hide_cursor}; diff --git a/src/terminal/printer.rs b/src/terminal/printer.rs index 2c54a4c..dc12e53 100644 --- a/src/terminal/printer.rs +++ b/src/terminal/printer.rs @@ -23,12 +23,13 @@ where writer: W, image_printer: Arc, pub(crate) cursor_row: u16, + current_row_height: u16, } impl Terminal { pub(crate) fn new(mut writer: W, image_printer: Arc) -> io::Result { writer.init()?; - Ok(Self { writer, image_printer, cursor_row: 0 }) + Ok(Self { writer, image_printer, cursor_row: 0, current_row_height: 1 }) } pub(crate) fn begin_update(&mut self) -> io::Result<()> { @@ -64,19 +65,27 @@ impl Terminal { Ok(()) } - pub(crate) fn move_to_next_line(&mut self, amount: u16) -> io::Result<()> { + pub(crate) fn move_to_next_line(&mut self) -> io::Result<()> { + let amount = self.current_row_height; self.writer.queue(cursor::MoveToNextLine(amount))?; self.cursor_row += amount; + self.current_row_height = 1; Ok(()) } - pub(crate) fn print_line(&mut self, text: &str) -> io::Result<()> { + pub(crate) fn print_line(&mut self, text: &str, properties: &TextProperties) -> io::Result<()> { self.writer.queue(style::Print(text))?; + self.current_row_height = self.current_row_height.max(properties.height as u16); Ok(()) } - pub(crate) fn print_styled_line(&mut self, content: StyledContent) -> io::Result<()> { - self.writer.queue(style::PrintStyledContent(content))?; + pub(crate) fn print_styled_line( + &mut self, + string: StyledContent, + properties: &TextProperties, + ) -> io::Result<()> { + self.writer.queue(style::PrintStyledContent(string))?; + self.current_row_height = self.current_row_height.max(properties.height as u16); Ok(()) } @@ -120,6 +129,17 @@ impl Terminal { } } +#[derive(Clone, Debug)] +pub(crate) struct TextProperties { + pub(crate) height: u8, +} + +impl Default for TextProperties { + fn default() -> Self { + Self { height: 1 } + } +} + impl Drop for Terminal where W: TerminalWrite, diff --git a/src/theme.rs b/src/theme.rs index f3b2be3..0fe06e1 100644 --- a/src/theme.rs +++ b/src/theme.rs @@ -303,6 +303,10 @@ pub(crate) struct SlideTitleStyle { /// Whether to use underlined font for slide titles. #[serde(default)] pub(crate) underlined: Option, + + /// The font size to be used if the terminal supports it. + #[serde(default)] + pub(crate) font_size: Option, } impl SlideTitleStyle { @@ -366,11 +370,16 @@ pub(crate) struct HeadingStyle { /// The colors to be used. #[serde(default)] pub(crate) colors: Colors, + + /// The font size to be used if the terminal supports it. + #[serde(default)] + pub(crate) font_size: Option, } impl HeadingStyle { fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> { - self.colors = self.colors.resolve(palette)?; + let Self { colors, alignment: _, prefix: _, font_size: _ } = self; + *colors = colors.resolve(palette)?; Ok(()) } } @@ -643,7 +652,7 @@ impl AlertTypeProperties for CautionAlertType { pub(crate) struct IntroSlideStyle { /// The style of the title line. #[serde(default)] - pub(crate) title: BasicStyle, + pub(crate) title: IntroSlideTitleStyle, /// The style of the subtitle line. #[serde(default)] @@ -673,9 +682,10 @@ pub(crate) struct IntroSlideStyle { impl IntroSlideStyle { fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> { let Self { title, subtitle, event, location, date, author, footer: _footer } = self; - for s in [title, subtitle, event, location, date] { + for s in [subtitle, event, location, date] { s.resolve_palette_colors(palette)?; } + title.resolve_palette_colors(palette)?; author.resolve_palette_colors(palette)?; Ok(()) } @@ -721,6 +731,30 @@ impl BasicStyle { } } +/// The intro slide title's style. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +pub(crate) struct IntroSlideTitleStyle { + /// The alignment. + #[serde(flatten, default)] + pub(crate) alignment: Option, + + /// The colors to be used. + #[serde(default)] + pub(crate) colors: Colors, + + /// The font size to be used if the terminal supports it. + #[serde(default)] + pub(crate) font_size: Option, +} + +impl IntroSlideTitleStyle { + fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> { + let Self { colors, alignment: _, font_size: _ } = self; + *colors = colors.resolve(palette)?; + Ok(()) + } +} + /// Text alignment. /// /// This allows anchoring presentation elements to the left, center, or right of the screen. diff --git a/themes/catppuccin-frappe.yaml b/themes/catppuccin-frappe.yaml index cdffc16..fe53c52 100644 --- a/themes/catppuccin-frappe.yaml +++ b/themes/catppuccin-frappe.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: "e5c890" bold: true + font_size: 2 code: alignment: center @@ -47,6 +48,7 @@ intro_slide: alignment: center colors: foreground: "a6d189" + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/catppuccin-latte.yaml b/themes/catppuccin-latte.yaml index 2431a5f..7a56e17 100644 --- a/themes/catppuccin-latte.yaml +++ b/themes/catppuccin-latte.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: "df8e1d" bold: true + font_size: 2 code: alignment: center @@ -47,6 +48,7 @@ intro_slide: alignment: center colors: foreground: "40a02b" + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/catppuccin-macchiato.yaml b/themes/catppuccin-macchiato.yaml index 7fc50da..d17a1df 100644 --- a/themes/catppuccin-macchiato.yaml +++ b/themes/catppuccin-macchiato.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: "eed49f" bold: true + font_size: 2 code: alignment: center @@ -47,6 +48,7 @@ intro_slide: alignment: center colors: foreground: "a6da95" + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/catppuccin-mocha.yaml b/themes/catppuccin-mocha.yaml index ea17735..0974c5e 100644 --- a/themes/catppuccin-mocha.yaml +++ b/themes/catppuccin-mocha.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: "f9e2af" bold: true + font_size: 2 code: alignment: center @@ -47,6 +48,7 @@ intro_slide: alignment: center colors: foreground: "a6e3a1" + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/dark.yaml b/themes/dark.yaml index 13c18db..15576be 100644 --- a/themes/dark.yaml +++ b/themes/dark.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: palette:orange bold: true + font_size: 2 code: alignment: center @@ -48,6 +49,7 @@ intro_slide: alignment: center colors: foreground: palette:light_blue + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/light.yaml b/themes/light.yaml index 826771b..8a8e7d5 100644 --- a/themes/light.yaml +++ b/themes/light.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: "f77f00" bold: true + font_size: 2 code: alignment: center @@ -48,6 +49,7 @@ intro_slide: alignment: center colors: foreground: "52b788" + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/terminal-dark.yaml b/themes/terminal-dark.yaml index f4cc7c3..e43d63b 100644 --- a/themes/terminal-dark.yaml +++ b/themes/terminal-dark.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: yellow bold: true + font_size: 2 code: alignment: center @@ -46,6 +47,7 @@ intro_slide: alignment: center colors: foreground: green + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/terminal-light.yaml b/themes/terminal-light.yaml index 04c4e92..d939b52 100644 --- a/themes/terminal-light.yaml +++ b/themes/terminal-light.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: dark_yellow bold: true + font_size: 2 code: alignment: center @@ -46,6 +47,7 @@ intro_slide: alignment: center colors: foreground: dark_green + font_size: 2 subtitle: alignment: center colors: diff --git a/themes/tokyonight-storm.yaml b/themes/tokyonight-storm.yaml index a2a5706..76cfc63 100644 --- a/themes/tokyonight-storm.yaml +++ b/themes/tokyonight-storm.yaml @@ -13,6 +13,7 @@ slide_title: colors: foreground: "e0af68" bold: true + font_size: 2 code: alignment: center @@ -48,6 +49,7 @@ intro_slide: alignment: center colors: foreground: "7aa2f7" + font_size: 2 subtitle: alignment: center colors: