feat: Support alignment

main
bokuweb 2019-11-11 13:05:07 +09:00
parent 517c3b0b9f
commit 879189da3c
13 changed files with 132 additions and 13 deletions

3
.gitignore vendored
View File

@ -4,4 +4,5 @@ dist
node_modules
pkg
*.docx#
test.docx
test.docx
output/*.docx

View File

@ -0,0 +1,15 @@
use docx_core::*;
pub fn main() {
let path = std::path::Path::new("./output/alignment.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_paragraph(Paragraph::new().add_run(Run::new("Hello")))
.add_paragraph(
Paragraph::new()
.add_run(Run::new(" World"))
.align(AlignmentType::Right),
)
.build()
.pack(file);
}

View File

@ -0,0 +1,44 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
// 22.1.2.51
// jc (Justification)
// This element specifies justification of the math paragraph (a series of adjacent instances of mathematical text
// within the same paragraph). A math paragraph can be Left Justified, Right Justified, Centered, or Centered as
// Group. If this element is omitted, the math paragraph is Centered as Group. Whether the element is absent or
// present without the val attribute, the default of the val attribute is centerGroup . This means that the instances
// of mathematical text can be aligned with respect to each other, but the entire group of mathematical text is
// centered as a whole.
#[derive(Debug)]
pub struct Justification {
val: String,
}
impl Justification {
pub fn new(val: impl Into<String>) -> Justification {
Justification { val: val.into() }
}
}
impl BuildXML for Justification {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.justification(&self.val).build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_justification() {
let c = Justification::new("start");
let b = c.build();
assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:jc w:val="start" />"#);
}
}

View File

@ -1,6 +1,7 @@
mod based_on;
mod color;
mod doc_defaults;
mod justification;
mod name;
mod next;
mod paragraph;
@ -16,6 +17,7 @@ mod text;
pub use based_on::*;
pub use color::*;
pub use doc_defaults::*;
pub use justification::*;
pub use name::*;
pub use next::*;
pub use paragraph::*;

View File

@ -1,15 +1,20 @@
use super::{Run, RunProperty, Text};
use super::{ParagraphProperty, Run, RunProperty, Text};
use crate::documents::BuildXML;
use crate::types::*;
use crate::xml_builder::*;
#[derive(Debug)]
pub struct Paragraph {
runs: Vec<Run>,
property: ParagraphProperty,
}
impl Default for Paragraph {
fn default() -> Self {
Self { runs: Vec::new() }
Self {
runs: Vec::new(),
property: ParagraphProperty::new(),
}
}
}
@ -22,12 +27,18 @@ impl Paragraph {
self.runs.push(run);
self
}
pub fn align(mut self, alignment_type: AlignmentType) -> Paragraph {
self.property = self.property.align(alignment_type);
self
}
}
impl BuildXML for Paragraph {
fn build(&self) -> Vec<u8> {
XMLBuilder::new()
.open_paragraph()
.add_child(&self.property)
.add_children(&self.runs)
.close()
.build()

View File

@ -1,8 +1,18 @@
use super::Justification;
use crate::documents::BuildXML;
use crate::types::AlignmentType;
use crate::xml_builder::*;
#[derive(Debug)]
pub struct ParagraphProperty {}
pub struct ParagraphProperty {
alignment: Option<Justification>,
}
impl Default for ParagraphProperty {
fn default() -> Self {
ParagraphProperty { alignment: None }
}
}
// 17.3.1.26
// pPr (Paragraph Properties)
@ -11,14 +21,22 @@ pub struct ParagraphProperty {}
// as direct formatting, since they are directly applied to the paragraph and supersede any formatting from styles.
impl ParagraphProperty {
pub fn new() -> ParagraphProperty {
ParagraphProperty {}
Default::default()
}
pub fn align(mut self, alignment_type: AlignmentType) -> ParagraphProperty {
self.alignment = Some(Justification::new(alignment_type.to_string()));
self
}
}
impl BuildXML for ParagraphProperty {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.open_paragraph_property().close().build()
let p = b
.open_paragraph_property()
.add_optional_child(&self.alignment);
p.close().build()
}
}

View File

@ -49,7 +49,7 @@ mod tests {
let b = Run::new("Hello").build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:r><w:rPr /><w:t>Hello</w:t></w:r>"#
r#"<w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r>"#
);
}
}

View File

@ -34,6 +34,9 @@ mod tests {
#[test]
fn test_build() {
let b = Text::new("Hello").build();
assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:t>Hello</w:t>"#);
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:t xml:space="preserve">Hello</w:t>"#
);
}
}

View File

@ -11,11 +11,8 @@ pub fn simple() {
let path = std::path::Path::new("./test.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_paragraph(
Paragraph::new()
.add_run(Run::new("Hello"))
.add_run(Run::new(" World")),
)
.add_paragraph(Paragraph::new().add_run(Run::new("Hello")))
.add_paragraph(Paragraph::new().add_run(Run::new(" World")))
.build()
.pack(file);
}

View File

@ -0,0 +1,22 @@
use std::fmt;
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
#[derive(Copy, Clone, Debug)]
pub enum AlignmentType {
Center,
Left,
Right,
Justified,
}
impl fmt::Display for AlignmentType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
AlignmentType::Center => write!(f, "center"),
AlignmentType::Left => write!(f, "left"),
AlignmentType::Right => write!(f, "right"),
AlignmentType::Justified => write!(f, "justified"),
}
}
}

View File

@ -1,3 +1,5 @@
pub mod alignment_type;
pub mod style_type;
pub use alignment_type::*;
pub use style_type::*;

View File

@ -33,6 +33,10 @@ impl XMLBuilder {
opened_el!(open_doc_defaults, "w:docDefaults");
// i.e. <w:name ... >
only_str_val_el!(name, "w:name");
// i.e. <w:jc ... >
only_str_val_el!(justification, "w:jc");
// i.e. <w:pStyle ... >
only_str_val_el!(p_style, "w:pStyle");
// i.e. <w:sz ... >
pub(crate) fn sz(mut self, val: usize) -> Self {
self.writer

0
output/.keep 100644
View File