Skip to main content

mdcat/
theme.rs

1// Copyright 2018-2020 Sebastian Wiesner <sebastian@swsnr.de>
2
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7//! Provide a colour theme for mdcat.
8
9use anstyle::{AnsiColor, Color, Style};
10
11/// A colour theme for mdcat.
12///
13/// Currently you cannot create custom styles, but only use the default theme via [`Theme::default`].
14#[derive(Debug, Clone)]
15pub struct Theme {
16    /// Style for HTML blocks.
17    pub(crate) html_block_style: Style,
18    /// Style for inline HTML.
19    pub(crate) inline_html_style: Style,
20    /// Style for code, unless the code is syntax-highlighted.
21    pub(crate) code_style: Style,
22    /// Style for links.
23    pub(crate) link_style: Style,
24    /// Color for image links (unless the image is rendered inline)
25    pub(crate) image_link_style: Style,
26    /// Color for rulers.
27    pub(crate) rule_color: Color,
28    /// Color for borders around code blocks.
29    pub(crate) code_block_border_color: Color,
30    /// Color for the `▌` bar drawn on every line of a blockquote.
31    pub(crate) quote_bar_color: Color,
32    /// Color for headings
33    pub(crate) heading_style: Style,
34}
35
36impl Default for Theme {
37    /// The default theme from mdcat 1.x
38    fn default() -> Self {
39        Self {
40            html_block_style: Style::new().fg_color(Some(AnsiColor::Green.into())),
41            inline_html_style: Style::new().fg_color(Some(AnsiColor::Green.into())),
42            code_style: Style::new().fg_color(Some(AnsiColor::Yellow.into())),
43            link_style: Style::new().fg_color(Some(AnsiColor::Blue.into())),
44            image_link_style: Style::new().fg_color(Some(AnsiColor::Magenta.into())),
45            rule_color: AnsiColor::Green.into(),
46            code_block_border_color: AnsiColor::Green.into(),
47            quote_bar_color: AnsiColor::BrightBlack.into(),
48            heading_style: Style::new().fg_color(Some(AnsiColor::Blue.into())).bold(),
49        }
50    }
51}
52
53/// Combine styles.
54pub trait CombineStyle {
55    /// Put this style on top of the other style.
56    ///
57    /// Return a new style which falls back to the `other` style for all style attributes not
58    /// specified in this style.
59    fn on_top_of(self, other: &Self) -> Self;
60}
61
62impl CombineStyle for Style {
63    /// Put this style on top of the `other` style.
64    fn on_top_of(self, other: &Style) -> Style {
65        Style::new()
66            .fg_color(self.get_fg_color().or(other.get_fg_color()))
67            .bg_color(self.get_bg_color().or(other.get_bg_color()))
68            .effects(other.get_effects() | self.get_effects())
69            .underline_color(self.get_underline_color().or(other.get_underline_color()))
70    }
71}