|
1 | 1 | use crate::markdown::text_style::{Color, Colors, FixedStr, UndefinedPaletteColorError};
|
2 | 2 | use serde::{Deserialize, Serialize};
|
3 |
| -use std::{collections::BTreeMap, fs, io, path::Path}; |
| 3 | +use std::{collections::BTreeMap, fmt, fs, io, marker::PhantomData, path::Path}; |
4 | 4 |
|
5 | 5 | include!(concat!(env!("OUT_DIR"), "/themes.rs"));
|
6 | 6 |
|
@@ -395,7 +395,7 @@ pub(crate) struct BlockQuoteStyle {
|
395 | 395 |
|
396 | 396 | impl BlockQuoteStyle {
|
397 | 397 | fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> {
|
398 |
| - let Self { colors, alignment: _alignment, prefix: _prefix } = self; |
| 398 | + let Self { colors, alignment: _, prefix: _ } = self; |
399 | 399 | colors.resolve_palette_colors(palette)?;
|
400 | 400 | Ok(())
|
401 | 401 | }
|
@@ -431,82 +431,183 @@ pub(crate) struct AlertStyle {
|
431 | 431 | #[serde(flatten, default)]
|
432 | 432 | pub(crate) alignment: Option<Alignment>,
|
433 | 433 |
|
| 434 | + /// The base colors. |
| 435 | + #[serde(default)] |
| 436 | + pub(crate) base_colors: Colors, |
| 437 | + |
434 | 438 | /// The prefix to be added to this block quote.
|
435 | 439 | ///
|
436 | 440 | /// This allows adding something like a vertical bar before the text.
|
437 | 441 | #[serde(default)]
|
438 | 442 | pub(crate) prefix: Option<String>,
|
439 | 443 |
|
440 |
| - /// The colors to be used. |
| 444 | + /// The style for each alert type. |
441 | 445 | #[serde(default)]
|
442 |
| - pub(crate) colors: AlertColors, |
| 446 | + pub(crate) styles: AlertTypeStyles, |
443 | 447 | }
|
444 | 448 |
|
445 | 449 | impl AlertStyle {
|
446 | 450 | fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> {
|
447 |
| - let Self { colors, alignment: _alignment, prefix: _prefix } = self; |
448 |
| - colors.resolve_palette_colors(palette)?; |
| 451 | + let Self { base_colors, styles, alignment: _, prefix: _ } = self; |
| 452 | + *base_colors = base_colors.resolve(palette)?; |
| 453 | + styles.resolve_palette_colors(palette)?; |
449 | 454 | Ok(())
|
450 | 455 | }
|
451 | 456 | }
|
452 | 457 |
|
453 |
| -/// The colors of an alert. |
| 458 | +/// The style for each alert type. |
454 | 459 | #[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
455 |
| -pub(crate) struct AlertColors { |
456 |
| - /// The foreground/background colors. |
457 |
| - #[serde(flatten)] |
458 |
| - pub(crate) base: Colors, |
| 460 | +pub(crate) struct AlertTypeStyles { |
| 461 | + /// The style for note alert types. |
| 462 | + #[serde(default)] |
| 463 | + pub(crate) note: AlertTypeStyle<NoteAlertType>, |
459 | 464 |
|
460 |
| - /// The color of the vertical bar that prefixes each line in the quote. |
| 465 | + /// The style for tip alert types. |
461 | 466 | #[serde(default)]
|
462 |
| - pub(crate) types: AlertTypeColors, |
| 467 | + pub(crate) tip: AlertTypeStyle<TipAlertType>, |
| 468 | + |
| 469 | + /// The style for important alert types. |
| 470 | + #[serde(default)] |
| 471 | + pub(crate) important: AlertTypeStyle<ImportantAlertType>, |
| 472 | + |
| 473 | + /// The style for warning alert types. |
| 474 | + #[serde(default)] |
| 475 | + pub(crate) warning: AlertTypeStyle<WarningAlertType>, |
| 476 | + |
| 477 | + /// The style for caution alert types. |
| 478 | + #[serde(default)] |
| 479 | + pub(crate) caution: AlertTypeStyle<CautionAlertType>, |
463 | 480 | }
|
464 | 481 |
|
465 |
| -impl AlertColors { |
| 482 | +impl AlertTypeStyles { |
466 | 483 | fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> {
|
467 |
| - let Self { base, types } = self; |
468 |
| - *base = base.resolve(palette)?; |
469 |
| - types.resolve_palette_colors(palette)?; |
| 484 | + let Self { note, tip, important, warning, caution } = self; |
| 485 | + note.resolve_palette_colors(palette)?; |
| 486 | + tip.resolve_palette_colors(palette)?; |
| 487 | + important.resolve_palette_colors(palette)?; |
| 488 | + warning.resolve_palette_colors(palette)?; |
| 489 | + caution.resolve_palette_colors(palette)?; |
470 | 490 | Ok(())
|
471 | 491 | }
|
472 | 492 | }
|
473 | 493 |
|
474 |
| -/// The colors of each alert type. |
475 |
| -#[derive(Clone, Debug, Default, Deserialize, Serialize)] |
476 |
| -pub(crate) struct AlertTypeColors { |
477 |
| - /// The color for note type alerts. |
478 |
| - #[serde(default)] |
479 |
| - pub(crate) note: Option<Color>, |
480 |
| - |
481 |
| - /// The color for tip type alerts. |
| 494 | +/// The style for an alert type. |
| 495 | +#[derive(Deserialize, Serialize)] |
| 496 | +pub(crate) struct AlertTypeStyle<S: AlertTypeProperties> { |
| 497 | + /// The color to be used. |
482 | 498 | #[serde(default)]
|
483 |
| - pub(crate) tip: Option<Color>, |
| 499 | + pub(crate) color: Option<Color>, |
484 | 500 |
|
485 |
| - /// The color for important type alerts. |
486 |
| - #[serde(default)] |
487 |
| - pub(crate) important: Option<Color>, |
| 501 | + /// The title to be used. |
| 502 | + #[serde(default = "S::default_title")] |
| 503 | + pub(crate) title: String, |
488 | 504 |
|
489 |
| - /// The color for warning type alerts. |
490 |
| - #[serde(default)] |
491 |
| - pub(crate) warning: Option<Color>, |
| 505 | + /// The symbol to be used. |
| 506 | + #[serde(default = "S::default_symbol")] |
| 507 | + pub(crate) symbol: Option<String>, |
492 | 508 |
|
493 |
| - /// The color for caution type alerts. |
494 |
| - #[serde(default)] |
495 |
| - pub(crate) caution: Option<Color>, |
| 509 | + #[serde(skip)] |
| 510 | + _unused: PhantomData<S>, |
496 | 511 | }
|
497 | 512 |
|
498 |
| -impl AlertTypeColors { |
| 513 | +impl<S: AlertTypeProperties> AlertTypeStyle<S> { |
| 514 | + pub(crate) fn as_parts(&self) -> (&Option<Color>, &str, Option<&str>) { |
| 515 | + (&self.color, &self.title, self.symbol.as_deref()) |
| 516 | + } |
| 517 | + |
499 | 518 | fn resolve_palette_colors(&mut self, palette: &ColorPalette) -> Result<(), UndefinedPaletteColorError> {
|
500 |
| - let Self { note, tip, important, warning, caution } = self; |
501 |
| - for c in [note, tip, important, warning, caution] { |
502 |
| - if let Some(c) = c.as_mut() { |
503 |
| - *c = c.resolve(palette)?; |
504 |
| - } |
| 519 | + let Self { color, title: _, symbol: _, _unused: _ } = self; |
| 520 | + if let Some(color) = color.as_mut() { |
| 521 | + *color = color.resolve(palette)?; |
505 | 522 | }
|
506 | 523 | Ok(())
|
507 | 524 | }
|
508 | 525 | }
|
509 | 526 |
|
| 527 | +impl<S: AlertTypeProperties> fmt::Debug for AlertTypeStyle<S> { |
| 528 | + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { |
| 529 | + f.debug_struct("AlertTypeStyle") |
| 530 | + .field("color", &self.color) |
| 531 | + .field("title", &self.title) |
| 532 | + .field("symbol", &self.symbol) |
| 533 | + .field("_unused", &self._unused) |
| 534 | + .finish() |
| 535 | + } |
| 536 | +} |
| 537 | + |
| 538 | +impl<S: AlertTypeProperties> Clone for AlertTypeStyle<S> { |
| 539 | + fn clone(&self) -> Self { |
| 540 | + Self { color: self.color, title: self.title.clone(), symbol: self.symbol.clone(), _unused: PhantomData } |
| 541 | + } |
| 542 | +} |
| 543 | + |
| 544 | +impl<S: AlertTypeProperties> Default for AlertTypeStyle<S> { |
| 545 | + fn default() -> Self { |
| 546 | + Self { color: None, title: S::default_title(), symbol: S::default_symbol(), _unused: PhantomData } |
| 547 | + } |
| 548 | +} |
| 549 | + |
| 550 | +pub(crate) trait AlertTypeProperties { |
| 551 | + fn default_title() -> String; |
| 552 | + fn default_symbol() -> Option<String>; |
| 553 | +} |
| 554 | + |
| 555 | +pub(crate) struct NoteAlertType; |
| 556 | +pub(crate) struct TipAlertType; |
| 557 | +pub(crate) struct ImportantAlertType; |
| 558 | +pub(crate) struct WarningAlertType; |
| 559 | +pub(crate) struct CautionAlertType; |
| 560 | + |
| 561 | +impl AlertTypeProperties for NoteAlertType { |
| 562 | + fn default_title() -> String { |
| 563 | + "Note".into() |
| 564 | + } |
| 565 | + |
| 566 | + fn default_symbol() -> Option<String> { |
| 567 | + Some("".into()) |
| 568 | + } |
| 569 | +} |
| 570 | + |
| 571 | +impl AlertTypeProperties for TipAlertType { |
| 572 | + fn default_title() -> String { |
| 573 | + "Tip".into() |
| 574 | + } |
| 575 | + |
| 576 | + fn default_symbol() -> Option<String> { |
| 577 | + Some("".into()) |
| 578 | + } |
| 579 | +} |
| 580 | + |
| 581 | +impl AlertTypeProperties for ImportantAlertType { |
| 582 | + fn default_title() -> String { |
| 583 | + "Important".into() |
| 584 | + } |
| 585 | + |
| 586 | + fn default_symbol() -> Option<String> { |
| 587 | + Some("".into()) |
| 588 | + } |
| 589 | +} |
| 590 | + |
| 591 | +impl AlertTypeProperties for WarningAlertType { |
| 592 | + fn default_title() -> String { |
| 593 | + "Warning".into() |
| 594 | + } |
| 595 | + |
| 596 | + fn default_symbol() -> Option<String> { |
| 597 | + Some("".into()) |
| 598 | + } |
| 599 | +} |
| 600 | + |
| 601 | +impl AlertTypeProperties for CautionAlertType { |
| 602 | + fn default_title() -> String { |
| 603 | + "Caution".into() |
| 604 | + } |
| 605 | + |
| 606 | + fn default_symbol() -> Option<String> { |
| 607 | + Some("".into()) |
| 608 | + } |
| 609 | +} |
| 610 | + |
510 | 611 | /// The style for the presentation introduction slide.
|
511 | 612 | #[derive(Clone, Debug, Default, Deserialize, Serialize)]
|
512 | 613 | pub(crate) struct IntroSlideStyle {
|
|
0 commit comments