feat: Add paragraph

main
bokuweb 2019-11-07 16:08:59 +09:00
parent f5f089c54e
commit d4f08f9703
31 changed files with 359 additions and 64 deletions

View File

@ -0,0 +1,45 @@
use super::{DocDefaults, Style};
use crate::documents::BuildXML;
use crate::xml_builder::*;
use crate::StyleType;
pub struct Document {}
impl Document {
pub fn new() -> Document {
Default::default()
}
}
impl Default for Document {
fn default() -> Self {
Self {}
}
}
impl BuildXML for Document {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.open_document().open_body().close().close().build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_document() {
let b = Document::new().build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:document xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" mc:Ignorable="w14 wp14">
<w:body />
</w:document>"#
);
}
}

View File

@ -3,21 +3,27 @@ mod color;
mod doc_defaults;
mod name;
mod next;
mod paragraph;
mod paragraph_property;
mod q_format;
mod run;
mod run_property;
mod run_property_default;
mod style;
mod sz;
mod text;
pub use based_on::*;
pub use color::*;
pub use doc_defaults::*;
pub use name::*;
pub use next::*;
pub use paragraph::*;
pub use paragraph_property::*;
pub use q_format::*;
pub use run::*;
pub use run_property::*;
pub use run_property_default::*;
pub use style::*;
pub use sz::*;
pub use text::*;

View File

@ -0,0 +1,52 @@
use super::{Run, RunProperty, Text};
use crate::documents::BuildXML;
use crate::xml_builder::*;
pub struct Paragraph {
runs: Vec<Run>,
}
impl Default for Paragraph {
fn default() -> Self {
Self { runs: Vec::new() }
}
}
impl Paragraph {
pub fn new() -> Paragraph {
Default::default()
}
pub fn add_run(mut self, run: Run) -> Paragraph {
self.runs.push(run);
self
}
}
impl BuildXML for Paragraph {
fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new().open_paragraph();
for r in self.runs.iter() {
b = b.add_child(r)
}
b.close().build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_paragraph() {
let b = Paragraph::new().add_run(Run::new("Hello")).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p><w:r><w:rPr /><w:t>Hello</w:t></w:r></w:p>"#
);
}
}

View File

@ -0,0 +1,54 @@
use super::{RunProperty, Text};
use crate::documents::BuildXML;
use crate::xml_builder::*;
pub struct Run {
run_property: RunProperty,
text: Text,
}
impl Run {
pub fn new(text: impl Into<String>) -> Run {
Run {
text: Text::new(text),
..Default::default()
}
}
}
impl Default for Run {
fn default() -> Self {
let run_property = RunProperty::new();
let text = Text::new("");
Self { run_property, text }
}
}
impl BuildXML for Run {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.open_run()
.add_child(&self.run_property)
.add_child(&self.text)
.close()
.build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_build() {
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>"#
);
}
}

View File

@ -1,5 +1,6 @@
use crate::documents::BuildXML;
use crate::xml_builder::*;
use crate::StyleType;
use super::{BasedOn, Name, Next, ParagraphProperty, QFormat, RunProperty};

View File

@ -0,0 +1,35 @@
use super::{RunProperty, Sz};
use crate::documents::BuildXML;
use crate::xml_builder::*;
pub struct Text {
text: String,
}
impl Text {
pub fn new(text: impl Into<String>) -> Text {
Text { text: text.into() }
}
}
impl BuildXML for Text {
fn build(&self) -> Vec<u8> {
let b = XMLBuilder::new();
b.text(&self.text).build()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_build() {
let b = Text::new("Hello").build();
assert_eq!(str::from_utf8(&b).unwrap(), r#"<w:t>Hello</w:t>"#);
}
}

View File

@ -1,6 +1,7 @@
mod build_xml;
mod content_types;
mod doc_props;
mod document;
mod elements;
mod rels;
mod styles;
@ -8,25 +9,26 @@ mod xml_document;
pub(crate) use build_xml::*;
use crate::xml_builder::*;
use content_types::*;
use doc_props::*;
use elements::*;
use rels::*;
use styles::*;
pub use crate::xml_builder::*;
pub use content_types::*;
pub use doc_props::*;
pub use document::*;
pub use elements::*;
pub use rels::*;
pub use styles::*;
pub(crate) struct Document {
pub(crate) struct Docx {
content_type: ContentTypes,
rels: Rels,
doc_props: DocProps,
}
impl Document {
pub fn new() -> Document {
impl Docx {
pub fn new() -> Docx {
let content_type = ContentTypes::new();
let rels = Rels::new();
let doc_props = DocProps::new(None, None /* TODO: */);
Document {
Docx {
content_type,
rels,
doc_props,

View File

@ -1,7 +1,7 @@
use super::{DocDefaults, Style};
use crate::documents::BuildXML;
use crate::xml_builder::*;
use super::{DocDefaults, Style, StyleType};
use crate::StyleType;
pub struct Styles {
doc_defaults: DocDefaults,

View File

@ -1,4 +1,4 @@
use super::Document;
use super::Docx;
use crate::documents::BuildXML;
pub(crate) struct XMLDocument {
@ -6,8 +6,8 @@ pub(crate) struct XMLDocument {
rels: Vec<u8>,
}
impl From<Document> for XMLDocument {
fn from(doc: Document) -> XMLDocument {
impl From<Docx> for XMLDocument {
fn from(doc: Docx) -> XMLDocument {
let content_type = doc.content_type.build();
XMLDocument {
content_type,

View File

@ -1,4 +1,5 @@
mod documents;
mod types;
mod xml_builder;
use documents::*;
@ -6,11 +7,12 @@ use xml_builder::*;
use std::fs::File;
use std::io::{self, Write};
use types::*;
use xml::writer::{EmitterConfig, EventWriter, Result, XmlEvent};
pub fn simple() {
let doc = Document::new();
let doc = Docx::new();
let mut file = File::create("./dist/output.xml").unwrap();
// let mut b = Vec::new();
// let mut w = EmitterConfig::new()

View File

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

View File

@ -0,0 +1,16 @@
use std::fmt;
#[derive(Copy, Clone, Debug)]
pub enum StyleType {
Paragraph,
Character,
}
impl fmt::Display for StyleType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
StyleType::Paragraph => write!(f, "paragraph"),
StyleType::Character => write!(f, "character"),
}
}
}

View File

@ -0,0 +1,71 @@
use std::fmt;
use super::XMLBuilder;
use super::XmlEvent;
impl XMLBuilder {
// i.e. <w:document ... >
pub(crate) fn open_document(mut self) -> Self {
self.writer
.write(
XmlEvent::start_element("w:document")
.attr("xmlns:o", "urn:schemas-microsoft-com:office:office")
.attr(
"xmlns:r",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships",
)
.attr("xmlns:v", "urn:schemas-microsoft-com:vml")
.attr(
"xmlns:w",
"http://schemas.openxmlformats.org/wordprocessingml/2006/main",
)
.attr("xmlns:w10", "urn:schemas-microsoft-com:office:word")
.attr(
"xmlns:wp",
"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",
)
.attr(
"xmlns:wps",
"http://schemas.microsoft.com/office/word/2010/wordprocessingShape",
)
.attr(
"xmlns:wpg",
"http://schemas.microsoft.com/office/word/2010/wordprocessingGroup",
)
.attr(
"xmlns:mc",
"http://schemas.openxmlformats.org/markup-compatibility/2006",
)
.attr(
"xmlns:wp14",
"http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing",
)
.attr(
"xmlns:w14",
"http://schemas.microsoft.com/office/word/2010/wordml",
)
.attr("mc:Ignorable", "w14 wp14"),
)
.expect("should write to buf");
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[cfg(test)]
use pretty_assertions::assert_eq;
use std::str;
#[test]
fn test_document() {
let b = XMLBuilder::new();
let r = b.open_document().close().build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<w:document xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:r="http://schemas.openxmlformats.org/officeDocument/2006/relationships" xmlns:v="urn:schemas-microsoft-com:vml" xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main" xmlns:w10="urn:schemas-microsoft-com:office:word" xmlns:wp="http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing" xmlns:wps="http://schemas.microsoft.com/office/word/2010/wordprocessingShape" xmlns:wpg="http://schemas.microsoft.com/office/word/2010/wordprocessingGroup" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:wp14="http://schemas.microsoft.com/office/word/2010/wordprocessingDrawing" xmlns:w14="http://schemas.microsoft.com/office/word/2010/wordml" mc:Ignorable="w14 wp14" />"#
);
}
}

View File

@ -0,0 +1,7 @@
use super::XMLBuilder;
use super::XmlEvent;
impl XMLBuilder {
// i.e. <w:body... >
opened_el!(open_body, "w:body");
}

View File

@ -1,29 +1,20 @@
#[macro_use]
mod macros;
mod based_on;
mod color;
mod doc_defaults;
mod name;
mod next;
mod paragraph_property;
mod q_format;
mod run_property;
mod run_property_default;
mod style;
mod sz;
pub mod based_on;
pub mod body;
pub mod color;
pub mod doc_defaults;
pub mod name;
pub mod next;
pub mod paragraph;
pub mod paragraph_property;
pub mod q_format;
pub mod run;
pub mod run_property;
pub mod run_property_default;
pub mod style;
pub mod sz;
pub mod text;
pub use based_on::*;
pub use color::*;
pub use doc_defaults::*;
pub use name::*;
pub use next::*;
pub use paragraph_property::*;
pub use q_format::*;
pub use run_property::*;
pub use run_property_default::*;
pub use style::*;
pub use sz::*;
use super::XMLBuilder;
use super::XmlEvent;
use super::{XMLBuilder, XmlEvent};

View File

@ -0,0 +1,7 @@
use super::XMLBuilder;
use super::XmlEvent;
impl XMLBuilder {
// i.e. <w:p ... >
opened_el!(open_paragraph, "w:p");
}

View File

@ -0,0 +1,7 @@
use super::XMLBuilder;
use super::XmlEvent;
impl XMLBuilder {
// i.e. <w:r ... >
opened_el!(open_run, "w:r");
}

View File

@ -1,22 +1,5 @@
use std::fmt;
use super::XMLBuilder;
use super::XmlEvent;
#[derive(Copy, Clone, Debug)]
pub enum StyleType {
Paragraph,
Character,
}
impl fmt::Display for StyleType {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
StyleType::Paragraph => write!(f, "paragraph"),
StyleType::Character => write!(f, "character"),
}
}
}
use super::{XMLBuilder, XmlEvent};
use crate::StyleType;
impl XMLBuilder {
// Build w:style element

View File

@ -0,0 +1,7 @@
use super::XMLBuilder;
use super::XmlEvent;
impl XMLBuilder {
// i.e. <w:t ... >
closed_el_with_child!(text, "w:t");
}

View File

@ -3,12 +3,14 @@ mod macros;
mod core_properties;
mod declaration;
mod document;
mod elements;
mod properties;
mod relationship;
mod styles;
use crate::BuildXML;
use std::str;
use xml::common::XmlVersion;
use xml::writer::{EmitterConfig, EventWriter, XmlEvent};
@ -91,7 +93,7 @@ impl XMLBuilder {
}
// Write plain text
pub(crate) fn text(mut self, t: &str) -> Self {
pub(crate) fn plain_text(mut self, t: &str) -> Self {
self.writer.write(t).unwrap();
self
}
@ -109,7 +111,11 @@ mod tests {
#[test]
fn test_open_types() {
let b = XMLBuilder::new();
let r = b.open_types("http://example").text("child").close().build();
let r = b
.open_types("http://example")
.plain_text("child")
.close()
.build();
assert_eq!(
str::from_utf8(&r).unwrap(),
r#"<Types xmlns="http://example">child</Types>"#

View File

@ -27,7 +27,7 @@ mod tests {
let b = XMLBuilder::new();
let r = b
.open_properties("http://example", "http://example2")
.text("child")
.plain_text("child")
.close()
.build();
assert_eq!(

View File

@ -21,7 +21,7 @@ mod tests {
let b = XMLBuilder::new();
let r = b
.open_relationships("http://example")
.text("child")
.plain_text("child")
.close()
.build();
assert_eq!(