use super::clone::elements_to_owned;
use super::{Alignment, AttributeMap, Element, Heading, HtmlTag};
use crate::layout::Layout;
use crate::next_index::{NextIndex, TableOfContentsIndex};
use strum_macros::IntoStaticStr;
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[serde(rename_all = "kebab-case")]
pub struct Container<'t> {
#[serde(rename = "type")]
ctype: ContainerType,
attributes: AttributeMap<'t>,
elements: Vec<Element<'t>>,
}
impl<'t> Container<'t> {
#[inline]
pub fn new(
ctype: ContainerType,
elements: Vec<Element<'t>>,
attributes: AttributeMap<'t>,
) -> Self {
Container {
ctype,
attributes,
elements,
}
}
#[inline]
pub fn ctype(&self) -> ContainerType {
self.ctype
}
#[inline]
pub fn elements(&self) -> &[Element<'t>] {
&self.elements
}
#[inline]
pub fn attributes(&self) -> &AttributeMap<'t> {
&self.attributes
}
#[inline]
pub fn attributes_mut(&mut self) -> &mut AttributeMap<'t> {
&mut self.attributes
}
pub fn to_owned(&self) -> Container<'static> {
Container {
ctype: self.ctype,
attributes: self.attributes.to_owned(),
elements: elements_to_owned(&self.elements),
}
}
}
impl<'t> From<Container<'t>> for Vec<Element<'t>> {
#[inline]
fn from(container: Container<'t>) -> Vec<Element<'t>> {
let Container { elements, .. } = container;
elements
}
}
#[derive(
Serialize, Deserialize, IntoStaticStr, Debug, Copy, Clone, Hash, PartialEq, Eq,
)]
#[serde(rename_all = "kebab-case")]
pub enum ContainerType {
Bold,
Italics,
Underline,
Superscript,
Subscript,
Strikethrough,
Monospace,
Span,
Div,
Mark,
Blockquote,
Insertion,
Deletion,
Hidden,
Invisible,
Size,
Ruby,
RubyText,
Paragraph,
Align(Alignment),
Header(Heading),
}
impl ContainerType {
#[inline]
pub fn name(self) -> &'static str {
self.into()
}
#[inline]
pub fn html_tag(
self,
layout: Layout,
indexer: &mut dyn NextIndex<TableOfContentsIndex>,
) -> HtmlTag {
match self {
ContainerType::Bold => HtmlTag::new("strong"),
ContainerType::Italics => HtmlTag::new("em"),
ContainerType::Underline => HtmlTag::new("u"),
ContainerType::Superscript => HtmlTag::new("sup"),
ContainerType::Subscript => HtmlTag::new("sub"),
ContainerType::Strikethrough => HtmlTag::new("s"),
ContainerType::Monospace => HtmlTag::with_class("code", "wj-monospace"),
ContainerType::Span => HtmlTag::new("span"),
ContainerType::Div => HtmlTag::new("div"),
ContainerType::Mark => HtmlTag::new("mark"),
ContainerType::Blockquote => HtmlTag::new("blockquote"),
ContainerType::Insertion => HtmlTag::new("ins"),
ContainerType::Deletion => HtmlTag::new("del"),
ContainerType::Hidden => HtmlTag::with_class("span", "wj-hidden"),
ContainerType::Invisible => HtmlTag::with_class("span", "wj-invisible"),
ContainerType::Size => HtmlTag::new("span"),
ContainerType::Ruby => HtmlTag::new("ruby"),
ContainerType::RubyText => HtmlTag::new("rt"),
ContainerType::Paragraph => HtmlTag::new("p"),
ContainerType::Align(alignment) => match layout {
Layout::Wikidot => HtmlTag::with_style("div", alignment.wd_html_style()),
Layout::Wikijump => HtmlTag::with_class("div", alignment.wj_html_class()),
},
ContainerType::Header(heading) => heading.html_tag(indexer),
}
}
#[inline]
pub fn paragraph_safe(self) -> bool {
match self {
ContainerType::Bold => true,
ContainerType::Italics => true,
ContainerType::Underline => true,
ContainerType::Superscript => true,
ContainerType::Subscript => true,
ContainerType::Strikethrough => true,
ContainerType::Monospace => true,
ContainerType::Span => true,
ContainerType::Div => false,
ContainerType::Mark => true,
ContainerType::Blockquote => false,
ContainerType::Insertion => true,
ContainerType::Deletion => true,
ContainerType::Hidden => true,
ContainerType::Invisible => true,
ContainerType::Size => true,
ContainerType::Ruby => true,
ContainerType::RubyText => true,
ContainerType::Paragraph => false,
ContainerType::Align(_) => false,
ContainerType::Header(_) => false,
}
}
}