Skip to content

Commit

Permalink
feat: Support comment extended
Browse files Browse the repository at this point in the history
  • Loading branch information
bokuweb committed Aug 13, 2020
1 parent ac3cfac commit 65ee921
Show file tree
Hide file tree
Showing 26 changed files with 118 additions and 321 deletions.
2 changes: 1 addition & 1 deletion docx-core/examples/comment.rs
@@ -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
@@ -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(())
}
9 changes: 4 additions & 5 deletions docx-core/src/documents/comments_extended.rs
Expand Up @@ -17,9 +17,8 @@ impl CommentsExtended {
Default::default()
}

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

Expand All @@ -41,7 +40,6 @@ impl BuildXML for CommentsExtended {
}
}


#[cfg(test)]
mod tests {

Expand All @@ -51,7 +49,8 @@ mod tests {

#[test]
fn test_settings() {
let c = CommentsExtended::new().add_comment_extended(CommentExtended::new("123"));
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());
}
Expand Down
5 changes: 5 additions & 0 deletions docx-core/src/documents/content_types.rs
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
9 changes: 7 additions & 2 deletions docx-core/src/documents/document_rels.rs
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
58 changes: 58 additions & 0 deletions docx-core/src/documents/mod.rs
@@ -1,3 +1,5 @@
use std::collections::HashMap;

mod build_xml;
mod comments;
mod comments_extended;
Expand Down Expand Up @@ -55,6 +57,7 @@ pub struct Docx {
pub font_table: FontTable,
pub media: Vec<(usize, Vec<u8>)>,
pub header: Header,
pub comments_extended: CommentsExtended,
}

impl Default for Docx {
Expand All @@ -71,6 +74,8 @@ impl Default for Docx {
let numberings = Numberings::new();
let media = vec![];
let header = Header::new();
let comments_extended = CommentsExtended::new();

Docx {
content_type,
rels,
Expand All @@ -84,6 +89,7 @@ impl Default for Docx {
numberings,
media,
header,
comments_extended,
}
}
}
Expand Down Expand Up @@ -191,6 +197,7 @@ impl Docx {
numberings: self.numberings.build(),
media: images,
header: self.header.build(),
comments_extended: self.comments_extended.build(),
}
}

Expand All @@ -202,12 +209,59 @@ impl Docx {
// Traverse and clone comments from document and add to comments node.
fn update_comments(&mut self) {
let mut comments: Vec<Comment> = vec![];
let mut comments_extended: Vec<CommentExtended> = vec![];

let mut comment_map: HashMap<usize, String> = HashMap::new();
for child in &self.document.children {
match child {
DocumentChild::Paragraph(paragraph) => {
for child in &paragraph.children {
if let ParagraphChild::CommentStart(c) = child {
let comment = c.comment();
let para_id = comment.paragraph.id.clone();
comment_map.insert(comment.id(), para_id.clone());
}
}
}
DocumentChild::Table(table) => {
for row in &table.rows {
for cell in &row.cells {
for content in &cell.children {
match content {
TableCellContent::Paragraph(paragraph) => {
for child in &paragraph.children {
if let ParagraphChild::CommentStart(c) = child {
let comment = c.comment();
let para_id = comment.paragraph.id.clone();
comment_map.insert(comment.id(), para_id.clone());
}
}
}
}
}
}
}
}
}
}

for child in &self.document.children {
match child {
DocumentChild::Paragraph(paragraph) => {
for child in &paragraph.children {
if let ParagraphChild::CommentStart(c) = child {
let comment = c.comment();
let para_id = comment.paragraph.id.clone();
comments.push(c.comment());
let comment_extended = CommentExtended::new(para_id);
if let Some(parent_comment_id) = comment.parent_comment_id {
let parent_para_id =
comment_map.get(&parent_comment_id).unwrap().clone();
comments_extended
.push(comment_extended.parent_paragraph_id(parent_para_id));
} else {
comments_extended.push(comment_extended);
}
}
}
}
Expand Down Expand Up @@ -235,6 +289,10 @@ impl Docx {
if !comments.is_empty() {
self.document_rels.has_comments = true;
}

self.comments_extended
.add_comments_extended(comments_extended);

self.comments.add_comments(comments);
}

Expand Down
1 change: 1 addition & 0 deletions docx-core/src/documents/xml_docx.rs
Expand Up @@ -18,6 +18,7 @@ pub struct XMLDocx {
pub numberings: Vec<u8>,
pub media: Vec<(usize, Vec<u8>)>,
pub header: Vec<u8>,
pub comments_extended: Vec<u8>,
}

impl XMLDocx {
Expand Down
4 changes: 4 additions & 0 deletions docx-core/src/xml_builder/document.rs
Expand Up @@ -42,6 +42,10 @@ impl XMLBuilder {
"xmlns:w14",
"http://schemas.microsoft.com/office/word/2010/wordml",
)
.attr(
"xmlns:w15",
"http://schemas.microsoft.com/office/word/2012/wordml",
)
.attr("mc:Ignorable", "w14 wp14"),
)
.expect("should write to buf");
Expand Down
2 changes: 2 additions & 0 deletions docx-core/src/zipper/mod.rs
Expand Up @@ -43,6 +43,8 @@ where
zip.write_all(&xml.numberings)?;
zip.start_file("word/header1.xml", options)?;
zip.write_all(&xml.header)?;
zip.start_file("word/CommentsExtended.xml", options)?;
zip.write_all(&xml.comments_extended)?;

if !xml.media.is_empty() {
zip.add_directory("word/media/", Default::default())?;
Expand Down
2 changes: 0 additions & 2 deletions fixtures/nested_comments/aa/[Content_Types].xml

This file was deleted.

2 changes: 0 additions & 2 deletions fixtures/nested_comments/aa/_rels/.rels

This file was deleted.

2 changes: 0 additions & 2 deletions fixtures/nested_comments/aa/docProps/app.xml

This file was deleted.

2 changes: 0 additions & 2 deletions fixtures/nested_comments/aa/docProps/core.xml

This file was deleted.

2 changes: 0 additions & 2 deletions fixtures/nested_comments/aa/word/_rels/document.xml.rels

This file was deleted.

0 comments on commit 65ee921

Please sign in to comment.