attribute.rs 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183
  1. #![allow(non_snake_case)]
  2. use crate::{block_attribute, core::Attributes, ignore_attribute, inline_attribute, list_attribute};
  3. use lazy_static::lazy_static;
  4. use std::{collections::HashSet, fmt, fmt::Formatter, iter::FromIterator};
  5. use strum_macros::Display;
  6. #[derive(Debug, Clone)]
  7. pub struct Attribute {
  8. pub key: AttributeKey,
  9. pub value: AttributeValue,
  10. pub scope: AttributeScope,
  11. }
  12. impl Attribute {
  13. // inline
  14. inline_attribute!(Bold, bool);
  15. inline_attribute!(Italic, bool);
  16. inline_attribute!(Underline, bool);
  17. inline_attribute!(StrikeThrough, bool);
  18. inline_attribute!(Link, &str);
  19. inline_attribute!(Color, String);
  20. inline_attribute!(Font, usize);
  21. inline_attribute!(Size, usize);
  22. inline_attribute!(Background, String);
  23. // block
  24. block_attribute!(Header, usize);
  25. block_attribute!(Indent, usize);
  26. block_attribute!(Align, String);
  27. block_attribute!(List, &str);
  28. block_attribute!(CodeBlock, bool);
  29. block_attribute!(QuoteBlock, bool);
  30. // ignore
  31. ignore_attribute!(Width, usize);
  32. ignore_attribute!(Height, usize);
  33. // List extension
  34. list_attribute!(Bullet, "bullet");
  35. list_attribute!(Ordered, "ordered");
  36. list_attribute!(Checked, "checked");
  37. list_attribute!(UnChecked, "unchecked");
  38. }
  39. impl fmt::Display for Attribute {
  40. fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
  41. let s = format!("{:?}:{:?} {:?}", self.key, self.value.0, self.scope);
  42. f.write_str(&s)
  43. }
  44. }
  45. impl std::convert::Into<Attributes> for Attribute {
  46. fn into(self) -> Attributes {
  47. let mut attributes = Attributes::new();
  48. attributes.add(self);
  49. attributes
  50. }
  51. }
  52. #[derive(Clone, Debug, Display, Hash, Eq, PartialEq, serde::Serialize, serde::Deserialize)]
  53. // serde.rs/variant-attrs.html
  54. // #[serde(rename_all = "snake_case")]
  55. pub enum AttributeKey {
  56. #[serde(rename = "bold")]
  57. Bold,
  58. #[serde(rename = "italic")]
  59. Italic,
  60. #[serde(rename = "underline")]
  61. Underline,
  62. #[serde(rename = "strikethrough")]
  63. StrikeThrough,
  64. #[serde(rename = "font")]
  65. Font,
  66. #[serde(rename = "size")]
  67. Size,
  68. #[serde(rename = "link")]
  69. Link,
  70. #[serde(rename = "color")]
  71. Color,
  72. #[serde(rename = "background")]
  73. Background,
  74. #[serde(rename = "indent")]
  75. Indent,
  76. #[serde(rename = "align")]
  77. Align,
  78. #[serde(rename = "code_block")]
  79. CodeBlock,
  80. #[serde(rename = "list")]
  81. List,
  82. #[serde(rename = "quote_block")]
  83. QuoteBlock,
  84. #[serde(rename = "width")]
  85. Width,
  86. #[serde(rename = "height")]
  87. Height,
  88. #[serde(rename = "header")]
  89. Header,
  90. }
  91. // pub trait AttributeValueData<'a>: Serialize + Deserialize<'a> {}
  92. #[derive(Debug, Clone, PartialEq, Eq, Hash)]
  93. pub struct AttributeValue(pub(crate) Option<String>);
  94. impl std::convert::From<&usize> for AttributeValue {
  95. fn from(val: &usize) -> Self { AttributeValue::from(*val) }
  96. }
  97. impl std::convert::From<usize> for AttributeValue {
  98. fn from(val: usize) -> Self {
  99. if val > (0 as usize) {
  100. AttributeValue(Some(format!("{}", val)))
  101. } else {
  102. AttributeValue(None)
  103. }
  104. }
  105. }
  106. impl std::convert::From<&str> for AttributeValue {
  107. fn from(val: &str) -> Self { val.to_owned().into() }
  108. }
  109. impl std::convert::From<String> for AttributeValue {
  110. fn from(val: String) -> Self {
  111. if val.is_empty() {
  112. AttributeValue(None)
  113. } else {
  114. AttributeValue(Some(val))
  115. }
  116. }
  117. }
  118. impl std::convert::From<&bool> for AttributeValue {
  119. fn from(val: &bool) -> Self { AttributeValue::from(*val) }
  120. }
  121. impl std::convert::From<bool> for AttributeValue {
  122. fn from(val: bool) -> Self {
  123. let val = match val {
  124. true => Some("true".to_owned()),
  125. false => None,
  126. };
  127. AttributeValue(val)
  128. }
  129. }
  130. pub fn is_block_except_header(k: &AttributeKey) -> bool {
  131. if k == &AttributeKey::Header {
  132. return false;
  133. }
  134. BLOCK_KEYS.contains(k)
  135. }
  136. lazy_static! {
  137. static ref BLOCK_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![
  138. AttributeKey::Header,
  139. AttributeKey::Indent,
  140. AttributeKey::Align,
  141. AttributeKey::CodeBlock,
  142. AttributeKey::List,
  143. AttributeKey::QuoteBlock,
  144. ]);
  145. static ref INLINE_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![
  146. AttributeKey::Bold,
  147. AttributeKey::Italic,
  148. AttributeKey::Underline,
  149. AttributeKey::StrikeThrough,
  150. AttributeKey::Link,
  151. AttributeKey::Color,
  152. AttributeKey::Font,
  153. AttributeKey::Size,
  154. AttributeKey::Background,
  155. ]);
  156. static ref INGORE_KEYS: HashSet<AttributeKey> = HashSet::from_iter(vec![AttributeKey::Width, AttributeKey::Height,]);
  157. }
  158. #[derive(Debug, PartialEq, Eq, Clone)]
  159. pub enum AttributeScope {
  160. Inline,
  161. Block,
  162. Embeds,
  163. Ignore,
  164. }