1use super::clone::elements_to_owned;
24use super::{Alignment, AttributeMap, Element, Heading, HtmlTag};
25use crate::next_index::{NextIndex, TableOfContentsIndex};
26use strum_macros::IntoStaticStr;
27
28#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
29#[serde(rename_all = "kebab-case")]
30pub struct Container<'t> {
31 #[serde(rename = "type")]
32 ctype: ContainerType,
33 attributes: AttributeMap<'t>,
34 elements: Vec<Element<'t>>,
35}
36
37impl<'t> Container<'t> {
38 #[inline]
39 pub fn new(
40 ctype: ContainerType,
41 elements: Vec<Element<'t>>,
42 attributes: AttributeMap<'t>,
43 ) -> Self {
44 Container {
45 ctype,
46 attributes,
47 elements,
48 }
49 }
50
51 #[inline]
52 pub fn ctype(&self) -> ContainerType {
53 self.ctype
54 }
55
56 #[inline]
57 pub fn elements(&self) -> &[Element<'t>] {
58 &self.elements
59 }
60
61 #[inline]
62 pub fn attributes(&self) -> &AttributeMap<'t> {
63 &self.attributes
64 }
65
66 #[inline]
67 pub fn attributes_mut(&mut self) -> &mut AttributeMap<'t> {
68 &mut self.attributes
69 }
70
71 pub fn to_owned(&self) -> Container<'static> {
72 Container {
73 ctype: self.ctype,
74 attributes: self.attributes.to_owned(),
75 elements: elements_to_owned(&self.elements),
76 }
77 }
78}
79
80impl<'t> From<Container<'t>> for Vec<Element<'t>> {
81 #[inline]
82 fn from(container: Container<'t>) -> Vec<Element<'t>> {
83 let Container { elements, .. } = container;
84
85 elements
86 }
87}
88
89#[derive(
90 Serialize, Deserialize, IntoStaticStr, Debug, Copy, Clone, Hash, PartialEq, Eq,
91)]
92#[serde(rename_all = "kebab-case")]
93pub enum ContainerType {
94 Bold,
95 Italics,
96 Underline,
97 Superscript,
98 Subscript,
99 Strikethrough,
100 Monospace,
101 Span,
102 Div,
103 Mark,
104 Blockquote,
105 Insertion,
106 Deletion,
107 Hidden,
108 Invisible,
109 Size,
110 Ruby,
111 RubyText,
112 Paragraph,
113 Align(Alignment),
114 Header(Heading),
115}
116
117impl ContainerType {
118 #[inline]
119 pub fn name(self) -> &'static str {
120 self.into()
121 }
122
123 #[inline]
124 pub fn html_tag(self, indexer: &mut dyn NextIndex<TableOfContentsIndex>) -> HtmlTag {
125 match self {
126 ContainerType::Bold => HtmlTag::new("strong"),
127 ContainerType::Italics => HtmlTag::new("em"),
128 ContainerType::Underline => HtmlTag::new("u"),
129 ContainerType::Superscript => HtmlTag::new("sup"),
130 ContainerType::Subscript => HtmlTag::new("sub"),
131 ContainerType::Strikethrough => HtmlTag::new("s"),
132 ContainerType::Monospace => HtmlTag::with_class("code", "wj-monospace"),
133 ContainerType::Span => HtmlTag::new("span"),
134 ContainerType::Div => HtmlTag::new("div"),
135 ContainerType::Mark => HtmlTag::new("mark"),
136 ContainerType::Blockquote => HtmlTag::new("blockquote"),
137 ContainerType::Insertion => HtmlTag::new("ins"),
138 ContainerType::Deletion => HtmlTag::new("del"),
139 ContainerType::Hidden => HtmlTag::with_class("span", "wj-hidden"),
140 ContainerType::Invisible => HtmlTag::with_class("span", "wj-invisible"),
141 ContainerType::Size => HtmlTag::new("span"),
142 ContainerType::Ruby => HtmlTag::new("ruby"),
143 ContainerType::RubyText => HtmlTag::new("rt"),
144 ContainerType::Paragraph => HtmlTag::new("p"),
145 ContainerType::Align(alignment) => {
146 HtmlTag::with_class("div", alignment.html_class())
147 }
148 ContainerType::Header(heading) => heading.html_tag(indexer),
149 }
150 }
151
152 #[inline]
156 pub fn paragraph_safe(self) -> bool {
157 match self {
158 ContainerType::Bold => true,
159 ContainerType::Italics => true,
160 ContainerType::Underline => true,
161 ContainerType::Superscript => true,
162 ContainerType::Subscript => true,
163 ContainerType::Strikethrough => true,
164 ContainerType::Monospace => true,
165 ContainerType::Span => true,
166 ContainerType::Div => false,
167 ContainerType::Mark => true,
168 ContainerType::Blockquote => false,
169 ContainerType::Insertion => true,
170 ContainerType::Deletion => true,
171 ContainerType::Hidden => true,
172 ContainerType::Invisible => true,
173 ContainerType::Size => true,
174 ContainerType::Ruby => true,
175 ContainerType::RubyText => true,
176 ContainerType::Paragraph => false,
177 ContainerType::Align(_) => false,
178 ContainerType::Header(_) => false,
179 }
180 }
181}