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
parent
0284e7aa4c
commit
2005b0a382
|
@ -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::*;
|
||||||
|
|
|
@ -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()
|
||||||
|
}
|
||||||
|
}
|
|
@ -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(
|
||||||
|
|
|
@ -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::*;
|
||||||
|
|
|
@ -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())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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())),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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();
|
||||||
|
|
Loading…
Reference in New Issue