Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support nest comment #116

Merged
merged 7 commits into from
Aug 13, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docx-core/examples/comment.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use docx_rs::*;

pub fn main() -> Result<(), DocxError> {
let path = std::path::Path::new("./comment.docx");
let path = std::path::Path::new("./output/comment.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_paragraph(
Expand Down
36 changes: 36 additions & 0 deletions docx-core/examples/nested_comment.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
use docx_rs::*;

pub fn main() -> Result<(), DocxError> {
let path = std::path::Path::new("./output/nested_comment.docx");
let file = std::fs::File::create(&path).unwrap();
Docx::new()
.add_paragraph(
Paragraph::new()
.add_comment_start(
Comment::new(1)
.author("bokuweb")
.date("2019-01-01T00:00:00Z")
.paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))),
)
.add_comment_end(1)
.add_comment_start(
Comment::new(2)
.author("bokuweb")
.date("2019-01-02T00:00:00Z")
.parent_comment_id(1)
.paragraph(Paragraph::new().add_run(Run::new().add_text("World"))),
)
.add_comment_end(2)
.add_comment_start(
Comment::new(3)
.author("bokuweb")
.date("2019-01-02T00:00:00Z")
.parent_comment_id(1)
.paragraph(Paragraph::new().add_run(Run::new().add_text("!!!!!"))),
)
.add_comment_end(3),
)
.build()
.pack(file)?;
Ok(())
}
57 changes: 57 additions & 0 deletions docx-core/src/documents/comments_extended.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use serde::Serialize;

use super::*;
use crate::documents::BuildXML;
use crate::xml_builder::*;

// i.e. <w15:commentEx w15:paraId="00000001" w15:paraIdParent="57D1BD7C" w15:done="0"/>

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CommentsExtended {
children: Vec<CommentExtended>,
}

impl CommentsExtended {
pub fn new() -> CommentsExtended {
Default::default()
}

pub fn add_comments_extended(&mut self, c: Vec<CommentExtended>) {
self.children = c;
}
}

impl Default for CommentsExtended {
fn default() -> Self {
Self { children: vec![] }
}
}

impl BuildXML for CommentsExtended {
fn build(&self) -> Vec<u8> {
let mut b = XMLBuilder::new();
b = b.open_comments_extended();

for c in &self.children {
b = b.add_child(c)
}
b.close().build()
}
}

#[cfg(test)]
mod tests {

use super::*;
use insta::assert_snapshot;
use std::str;

#[test]
fn test_settings() {
let mut c = CommentsExtended::new();
c.add_comments_extended(vec![CommentExtended::new("123")]);
let b = c.build();
assert_snapshot!("comments_extended_snapshot", str::from_utf8(&b).unwrap());
}
}
5 changes: 5 additions & 0 deletions docx-core/src/documents/content_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ impl ContentTypes {
"/word/header1.xml".to_owned(),
"application/vnd.openxmlformats-officedocument.wordprocessingml.header+xml".to_owned(),
);
self.types.insert(
"/word/commentsExtended.xml".to_owned(),
"application/vnd.openxmlformats-officedocument.wordprocessingml.commentsExtended+xml"
.to_owned(),
);
self
}
}
Expand Down
4 changes: 2 additions & 2 deletions docx-core/src/documents/document.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,8 @@ mod tests {
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<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:p><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p><w:sectPr><w:pgSz w:w="11906" w:h="16838" /><w:pgMar w:top="1985" w:right="1701" w:bottom="1701" w:left="1701" w:header="851" w:footer="992" w:gutter="0" /><w:headerReference w:type="default" r:id="rId4" /><w:cols w:space="425" />
<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" xmlns:w15="http://schemas.microsoft.com/office/word/2012/wordml" mc:Ignorable="w14 wp14">
<w:body><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p><w:sectPr><w:pgSz w:w="11906" w:h="16838" /><w:pgMar w:top="1985" w:right="1701" w:bottom="1701" w:left="1701" w:header="851" w:footer="992" w:gutter="0" /><w:headerReference w:type="default" r:id="rId4" /><w:cols w:space="425" />
<w:docGrid w:type="lines" w:linePitch="360" />
</w:sectPr></w:body>
</w:document>"#
Expand Down
9 changes: 7 additions & 2 deletions docx-core/src/documents/document_rels.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,19 +53,24 @@ impl BuildXML for DocumentRels {
"rId4",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",
"header1.xml",
)
.relationship(
"rId5",
"http://schemas.microsoft.com/office/2011/relationships/commentsExtended",
"commentsExtended.xml",
);

if self.has_comments {
b = b.relationship(
"rId5",
"rId6",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments",
"comments.xml",
)
}

if self.has_numberings {
b = b.relationship(
"rId6",
"rId7",
"http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering",
"numbering.xml",
)
Expand Down
2 changes: 1 addition & 1 deletion docx-core/src/documents/elements/a_graphic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ mod tests {
);
assert_eq!(
serde_json::to_string(&graphic).unwrap(),
r#"{"children":[{"dataType":"wpShape","children":[{"type":"shape","data":{"children":[{"type":"textbox","data":{"children":[{"children":[{"type":"paragraph","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false,"attrs":[]}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"#
r#"{"children":[{"dataType":"wpShape","children":[{"type":"shape","data":{"children":[{"type":"textbox","data":{"children":[{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"pattern1"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false}}],"has_numbering":false}],"hasNumbering":false}}]}}]}]}"#
);
}
}
9 changes: 8 additions & 1 deletion docx-core/src/documents/elements/comment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ pub struct Comment {
pub author: String,
pub date: String,
pub paragraph: Paragraph,
pub parent_comment_id: Option<usize>,
}

impl Default for Comment {
Expand All @@ -18,6 +19,7 @@ impl Default for Comment {
author: "unnamed".to_owned(),
date: "1970-01-01T00:00:00Z".to_owned(),
paragraph: Paragraph::new(),
parent_comment_id: None,
}
}
}
Expand Down Expand Up @@ -45,6 +47,11 @@ impl Comment {
self
}

pub fn parent_comment_id(mut self, parent_comment_id: usize) -> Comment {
self.parent_comment_id = Some(parent_comment_id);
self
}

pub fn id(&self) -> usize {
self.id
}
Expand Down Expand Up @@ -73,7 +80,7 @@ mod tests {
let b = Comment::new(1).build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:comment w:id="1" w:author="unnamed" w:date="1970-01-01T00:00:00Z" w:initials=""><w:p><w:pPr><w:rPr /></w:pPr></w:p></w:comment>"#
r#"<w:comment w:id="1" w:author="unnamed" w:date="1970-01-01T00:00:00Z" w:initials=""><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr></w:p></w:comment>"#
);
}
}
40 changes: 40 additions & 0 deletions docx-core/src/documents/elements/comment_extended.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
use serde::Serialize;

use crate::documents::BuildXML;
use crate::xml_builder::*;

#[derive(Debug, Clone, PartialEq, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct CommentExtended {
paragraph_id: String,
done: bool,
parent_paragraph_id: Option<String>,
}

impl CommentExtended {
pub fn new(paragraph_id: impl Into<String>) -> CommentExtended {
Self {
paragraph_id: paragraph_id.into(),
done: false,
parent_paragraph_id: None,
}
}

pub fn done(mut self) -> CommentExtended {
self.done = true;
self
}

pub fn parent_paragraph_id(mut self, id: impl Into<String>) -> CommentExtended {
self.parent_paragraph_id = Some(id.into());
self
}
}

impl BuildXML for CommentExtended {
fn build(&self) -> Vec<u8> {
XMLBuilder::new()
.comment_extended(&self.paragraph_id, self.done, &self.parent_paragraph_id)
.build()
}
}
2 changes: 2 additions & 0 deletions docx-core/src/documents/elements/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ mod bookmark_start;
mod br;
mod color;
mod comment;
mod comment_extended;
mod comment_range_end;
mod comment_range_start;
mod default_tab_stop;
Expand Down Expand Up @@ -89,6 +90,7 @@ pub use bookmark_start::*;
pub use br::*;
pub use color::*;
pub use comment::*;
pub use comment_extended::*;
pub use comment_range_end::*;
pub use comment_range_start::*;
pub use default_tab_stop::*;
Expand Down
35 changes: 9 additions & 26 deletions docx-core/src/documents/elements/paragraph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ use crate::xml_builder::*;
#[derive(Serialize, Debug, Clone, PartialEq)]
#[serde(rename_all = "camelCase")]
pub struct Paragraph {
pub id: String,
pub children: Vec<ParagraphChild>,
pub property: ParagraphProperty,
pub has_numbering: bool,
pub attrs: Vec<(String, String)>,
}

impl Default for Paragraph {
fn default() -> Self {
Self {
id: crate::generate_para_id(),
children: Vec::new(),
property: ParagraphProperty::new(),
has_numbering: false,
attrs: Vec::new(),
}
}
}
Expand Down Expand Up @@ -121,11 +121,6 @@ impl Paragraph {
self
}

pub fn add_attr(mut self, key: impl Into<String>, val: impl Into<String>) -> Paragraph {
self.attrs.push((key.into(), val.into()));
self
}

pub fn add_bookmark_start(mut self, id: usize, name: impl Into<String>) -> Paragraph {
self.children
.push(ParagraphChild::BookmarkStart(BookmarkStart::new(id, name)));
Expand Down Expand Up @@ -207,7 +202,7 @@ impl Paragraph {
impl BuildXML for Paragraph {
fn build(&self) -> Vec<u8> {
XMLBuilder::new()
.open_paragraph(&self.attrs)
.open_paragraph(&self.id)
.add_child(&self.property)
.add_children(&self.children)
.close()
Expand All @@ -230,19 +225,7 @@ mod tests {
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
);
}

#[test]
fn test_custom_attr() {
let b = Paragraph::new()
.add_run(Run::new().add_text("Hello"))
.add_attr("customId", "abcd-1234-567890")
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p customId="abcd-1234-567890"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
r#"<w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
);
}

Expand All @@ -255,7 +238,7 @@ mod tests {
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p><w:pPr><w:rPr /></w:pPr><w:bookmarkStart w:id="0" w:name="article" /><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r><w:bookmarkEnd w:id="0" /></w:p>"#
r#"<w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:bookmarkStart w:id="0" w:name="article" /><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r><w:bookmarkEnd w:id="0" /></w:p>"#
);
}

Expand All @@ -268,7 +251,7 @@ mod tests {
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p><w:pPr><w:rPr /></w:pPr><w:commentRangeStart w:id="1" /><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r><w:r>
r#"<w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:commentRangeStart w:id="1" /><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r><w:r>
<w:rPr />
</w:r>
<w:commentRangeEnd w:id="1" />
Expand All @@ -286,7 +269,7 @@ mod tests {
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:p><w:pPr><w:rPr /><w:numPr><w:numId w:val="0" /><w:ilvl w:val="1" /></w:numPr></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
r#"<w:p w14:paraId="12345678"><w:pPr><w:rPr /><w:numPr><w:numId w:val="0" /><w:ilvl w:val="1" /></w:numPr></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p>"#
);
}

Expand All @@ -296,7 +279,7 @@ mod tests {
let p = Paragraph::new().add_run(run);
assert_eq!(
serde_json::to_string(&p).unwrap(),
r#"{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false,"attrs":[]}"#
r#"{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false}"#
);
}

Expand All @@ -307,7 +290,7 @@ mod tests {
let p = Paragraph::new().add_insert(ins);
assert_eq!(
serde_json::to_string(&p).unwrap(),
r#"{"children":[{"type":"insert","data":{"runs":[{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false,"attrs":[]}"#
r#"{"id":"12345678","children":[{"type":"insert","data":{"runs":[{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}],"author":"unnamed","date":"1970-01-01T00:00:00Z"}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false}"#
);
}
}
4 changes: 2 additions & 2 deletions docx-core/src/documents/elements/table_cell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ mod tests {
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:tc><w:tcPr /><w:p><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p></w:tc>"#
r#"<w:tc><w:tcPr /><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr><w:r><w:rPr /><w:t xml:space="preserve">Hello</w:t></w:r></w:p></w:tc>"#
);
}

Expand All @@ -146,7 +146,7 @@ mod tests {
.grid_span(2);
assert_eq!(
serde_json::to_string(&c).unwrap(),
r#"{"children":[{"type":"paragraph","data":{"children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false,"attrs":[]}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null},"hasNumbering":false}"#
r#"{"children":[{"type":"paragraph","data":{"id":"12345678","children":[{"type":"run","data":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"children":[{"type":"text","data":{"preserveSpace":true,"text":"Hello"}}]}}],"property":{"runProperty":{"sz":null,"szCs":null,"color":null,"highlight":null,"underline":null,"bold":null,"boldCs":null,"italic":null,"italicCs":null,"vanish":null,"fonts":null},"style":null,"numberingProperty":null,"alignment":null,"indent":null},"hasNumbering":false}}],"property":{"width":null,"borders":null,"gridSpan":2,"verticalMerge":null,"verticalAlign":null},"hasNumbering":false}"#
);
}
}
2 changes: 1 addition & 1 deletion docx-core/src/documents/elements/text_box_content.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ mod tests {
.build();
assert_eq!(
str::from_utf8(&b).unwrap(),
r#"<w:txbxContent><w:p><w:pPr><w:rPr /></w:pPr></w:p></w:txbxContent>"#
r#"<w:txbxContent><w:p w14:paraId="12345678"><w:pPr><w:rPr /></w:pPr></w:p></w:txbxContent>"#
);
}
}
Loading