feat: Add paragraph
parent
f5f089c54e
commit
d4f08f9703
|
@ -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>"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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::*;
|
||||
|
|
|
@ -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>"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -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>"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
use crate::documents::BuildXML;
|
||||
use crate::xml_builder::*;
|
||||
use crate::StyleType;
|
||||
|
||||
use super::{BasedOn, Name, Next, ParagraphProperty, QFormat, RunProperty};
|
||||
|
||||
|
|
|
@ -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>"#);
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
pub mod style_type;
|
||||
|
||||
pub use style_type::*;
|
|
@ -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"),
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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" />"#
|
||||
);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
use super::XMLBuilder;
|
||||
use super::XmlEvent;
|
||||
|
||||
impl XMLBuilder {
|
||||
// i.e. <w:body... >
|
||||
opened_el!(open_body, "w:body");
|
||||
}
|
|
@ -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};
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
use super::XMLBuilder;
|
||||
use super::XmlEvent;
|
||||
|
||||
impl XMLBuilder {
|
||||
// i.e. <w:p ... >
|
||||
opened_el!(open_paragraph, "w:p");
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
use super::XMLBuilder;
|
||||
use super::XmlEvent;
|
||||
|
||||
impl XMLBuilder {
|
||||
// i.e. <w:r ... >
|
||||
opened_el!(open_run, "w:r");
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
use super::XMLBuilder;
|
||||
use super::XmlEvent;
|
||||
|
||||
impl XMLBuilder {
|
||||
// i.e. <w:t ... >
|
||||
closed_el_with_child!(text, "w:t");
|
||||
}
|
|
@ -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>"#
|
||||
|
|
|
@ -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!(
|
||||
|
|
|
@ -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!(
|
||||
|
|
Loading…
Reference in New Issue