PositionalTab initial support (#733)

* Initial positional tab support: add PositionalTab types related module

* Initial positional tab support: add PositionalTabAlignmentType

* Initial positional tab support: add PositionalTabRelativeTo

* Initial positional tab support: add PositionalTab related module

* Initial positional tab support: add PositionalTab

* Initial positional tab support: add ptab() for XMLBuilder

* Initial positional tab support: remove optional

* Initial positional tab support: remove optional

* Initial positional tab support: derive Partial Eq, Eq

* Initial positional tab support: add ptab()
main
git-noise 2024-06-30 07:13:29 -04:00 committed by GitHub
parent 0284e7aa4c
commit 2005b0a382
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 195 additions and 0 deletions

View File

@ -80,6 +80,7 @@ mod paragraph_property_change;
mod paragraph_property_default; mod paragraph_property_default;
mod paragraph_style; mod paragraph_style;
mod pic; mod pic;
mod positional_tab;
mod q_format; mod q_format;
mod run; mod run;
mod run_fonts; mod run_fonts;
@ -217,6 +218,7 @@ pub use paragraph_property_change::*;
pub use paragraph_property_default::*; pub use paragraph_property_default::*;
pub use paragraph_style::*; pub use paragraph_style::*;
pub use pic::*; pub use pic::*;
pub use positional_tab::*;
pub use q_format::*; pub use q_format::*;
pub use run::*; pub use run::*;
pub use run_fonts::*; pub use run_fonts::*;

View File

@ -0,0 +1,51 @@
use serde::{Deserialize, Serialize};
use crate::documents::BuildXML;
use crate::types::*;
use crate::xml_builder::*;
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq)]
#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
#[cfg_attr(feature = "wasm", ts(export))]
pub struct PositionalTab {
pub alignment: PositionalTabAlignmentType,
pub relative_to: PositionalTabRelativeTo,
pub leader: TabLeaderType,
}
impl PositionalTab {
pub fn new(
alignment: PositionalTabAlignmentType,
relative_to: PositionalTabRelativeTo,
leader: TabLeaderType,
) -> Self {
Self {
alignment,
relative_to,
leader,
}
}
pub fn relative_to(mut self, relative_to: PositionalTabRelativeTo) -> Self {
self.relative_to = relative_to;
self
}
pub fn leader(mut self, leader: TabLeaderType) -> Self {
self.leader = leader;
self
}
pub fn alignment(mut self, alignment: PositionalTabAlignmentType) -> Self {
self.alignment = alignment;
self
}
}
impl BuildXML for PositionalTab {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.ptab(self.alignment, self.relative_to, self.leader)
.build()
}
}

View File

@ -49,6 +49,8 @@ pub struct RunProperty {
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub strike: Option<Strike>, pub strike: Option<Strike>,
#[serde(skip_serializing_if = "Option::is_none")] #[serde(skip_serializing_if = "Option::is_none")]
pub positional_tab: Option<PositionalTab>,
#[serde(skip_serializing_if = "Option::is_none")]
pub shading: Option<Shading>, pub shading: Option<Shading>,
} }
@ -157,6 +159,11 @@ impl RunProperty {
self self
} }
pub fn ptab(mut self, ptab: PositionalTab) -> Self {
self.positional_tab = Some(ptab);
self
}
pub fn shading(mut self, s: Shading) -> Self { pub fn shading(mut self, s: Shading) -> Self {
self.shading = Some(s); self.shading = Some(s);
self self
@ -187,6 +194,7 @@ impl BuildXML for RunProperty {
.add_optional_child(&self.vert_align) .add_optional_child(&self.vert_align)
.add_optional_child(&self.character_spacing) .add_optional_child(&self.character_spacing)
.add_optional_child(&self.style) .add_optional_child(&self.style)
.add_optional_child(&self.positional_tab)
.add_optional_child(&self.shading) .add_optional_child(&self.shading)
.close() .close()
.build() .build()
@ -270,6 +278,7 @@ mod tests {
r#"<w:rPr><w:rFonts w:eastAsia="Hiragino" /></w:rPr>"# r#"<w:rPr><w:rFonts w:eastAsia="Hiragino" /></w:rPr>"#
); );
} }
#[test] #[test]
fn test_character_spacing() { fn test_character_spacing() {
let c = RunProperty::new().spacing(20); let c = RunProperty::new().spacing(20);
@ -280,6 +289,20 @@ mod tests {
); );
} }
#[test]
fn test_ptab() {
let c = RunProperty::new().ptab(PositionalTab::new(
PositionalTabAlignmentType::Left,
PositionalTabRelativeTo::Margin,
TabLeaderType::None,
));
let b = c.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:rPr><w:ptab w:alignment="left" w:relativeTo="margin" w:leader="none" /></w:rPr>"#
);
}
#[test] #[test]
fn test_character_shading() { fn test_character_shading() {
let c = RunProperty::new().shading( let c = RunProperty::new().shading(

View File

@ -15,6 +15,8 @@ pub mod level_suffix_type;
pub mod line_spacing_type; pub mod line_spacing_type;
pub mod page_margin; pub mod page_margin;
pub mod page_orientation_type; pub mod page_orientation_type;
pub mod positional_tab_alignment_type;
pub mod positional_tab_relative_to;
pub mod relative_from_type; pub mod relative_from_type;
pub mod section_type; pub mod section_type;
pub mod shd_type; pub mod shd_type;
@ -48,6 +50,8 @@ pub use level_suffix_type::*;
pub use line_spacing_type::*; pub use line_spacing_type::*;
pub use page_margin::*; pub use page_margin::*;
pub use page_orientation_type::*; pub use page_orientation_type::*;
pub use positional_tab_alignment_type::*;
pub use positional_tab_relative_to::*;
pub use relative_from_type::*; pub use relative_from_type::*;
pub use section_type::*; pub use section_type::*;
pub use shd_type::*; pub use shd_type::*;

View File

@ -0,0 +1,41 @@
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
use super::errors;
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
#[cfg_attr(feature = "wasm", ts(export))]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "camelCase")]
pub enum PositionalTabAlignmentType {
Center,
Left,
Right,
}
impl fmt::Display for PositionalTabAlignmentType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
PositionalTabAlignmentType::Center => write!(f, "center"),
PositionalTabAlignmentType::Left => write!(f, "left"),
PositionalTabAlignmentType::Right => write!(f, "right"),
}
}
}
impl FromStr for PositionalTabAlignmentType {
type Err = errors::TypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"center" => Ok(PositionalTabAlignmentType::Center),
"right" => Ok(PositionalTabAlignmentType::Right),
"left" => Ok(PositionalTabAlignmentType::Left),
_ => Err(errors::TypeError::Unsupported(s.to_string())),
}
}
}

View File

@ -0,0 +1,37 @@
use serde::{Deserialize, Serialize};
use std::fmt;
use std::str::FromStr;
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
use super::errors;
#[cfg_attr(feature = "wasm", wasm_bindgen)]
#[cfg_attr(feature = "wasm", derive(ts_rs::TS))]
#[cfg_attr(feature = "wasm", ts(export))]
#[derive(Debug, Copy, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum PositionalTabRelativeTo {
Indent,
Margin,
}
impl fmt::Display for PositionalTabRelativeTo {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
PositionalTabRelativeTo::Indent => write!(f, "indent"),
PositionalTabRelativeTo::Margin => write!(f, "margin"),
}
}
}
impl FromStr for PositionalTabRelativeTo {
type Err = errors::TypeError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"indent" => Ok(PositionalTabRelativeTo::Indent),
"margin" => Ok(PositionalTabRelativeTo::Margin),
_ => Err(errors::TypeError::Unsupported(s.to_string())),
}
}
}

View File

@ -733,6 +733,27 @@ impl XMLBuilder {
self.close() self.close()
} }
pub(crate) fn ptab(
mut self,
alignment: PositionalTabAlignmentType,
relative_to: PositionalTabRelativeTo,
leader: TabLeaderType,
) -> Self {
let alignment_string = alignment.to_string();
let relative_to_string = relative_to.to_string();
let leader_string = leader.to_string();
let mut t = XmlEvent::start_element("w:ptab");
t = t.attr("w:alignment", &alignment_string);
t = t.attr("w:relativeTo", &relative_to_string);
t = t.attr("w:leader", &leader_string);
self.writer.write(t).expect(EXPECT_MESSAGE);
self.close()
}
// FootnoteReference // FootnoteReference
// w:footnoteReference w:id="1" // w:footnoteReference w:id="1"
pub(crate) fn footnote_reference(mut self, id: usize) -> Self { pub(crate) fn footnote_reference(mut self, id: usize) -> Self {
@ -804,6 +825,22 @@ mod tests {
); );
} }
#[test]
fn test_ptab() {
let b = XMLBuilder::new();
let r = b
.ptab(
PositionalTabAlignmentType::Left,
PositionalTabRelativeTo::Indent,
TabLeaderType::None,
)
.build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<w:ptab w:alignment="left" w:relativeTo="indent" w:leader="none" />"#
);
}
#[test] #[test]
fn test_footnote_reference() { fn test_footnote_reference() {
let b = XMLBuilder::new(); let b = XMLBuilder::new();