From 5dcd4d73ae42125f39a36b9bd68161e7821a6b85 Mon Sep 17 00:00:00 2001 From: bokuweb Date: Wed, 2 Sep 2020 18:23:53 +0900 Subject: [PATCH] feat: Support top level bookmark (#133) --- docx-core/examples/bookmark.rs | 13 +++++++++++++ docx-core/src/documents/document.rs | 30 ++++++++++++++++++++++++++++- docx-core/src/documents/mod.rs | 14 ++++++++++++++ docx-wasm/example/index.ts | 2 ++ docx-wasm/js/index.ts | 16 ++++++++++++++- docx-wasm/src/doc.rs | 10 ++++++++++ 6 files changed, 83 insertions(+), 2 deletions(-) create mode 100644 docx-core/examples/bookmark.rs diff --git a/docx-core/examples/bookmark.rs b/docx-core/examples/bookmark.rs new file mode 100644 index 0000000..84fe01b --- /dev/null +++ b/docx-core/examples/bookmark.rs @@ -0,0 +1,13 @@ +use docx_rs::*; + +pub fn main() -> Result<(), DocxError> { + let path = std::path::Path::new("./output/bookmark.docx"); + let file = std::fs::File::create(&path).unwrap(); + Docx::new() + .add_bookmark_start(1, "hello") + .add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello"))) + .add_bookmark_end(1) + .build() + .pack(file)?; + Ok(()) +} diff --git a/docx-core/src/documents/document.rs b/docx-core/src/documents/document.rs index 92ea681..744075a 100644 --- a/docx-core/src/documents/document.rs +++ b/docx-core/src/documents/document.rs @@ -1,7 +1,7 @@ use serde::ser::{SerializeStruct, Serializer}; use serde::Serialize; -use super::{Paragraph, SectionProperty, Table}; +use super::*; use crate::documents::BuildXML; use crate::xml_builder::*; @@ -17,6 +17,8 @@ pub struct Document { pub enum DocumentChild { Paragraph(Paragraph), Table(Table), + BookmarkStart(BookmarkStart), + BookmarkEnd(BookmarkEnd), } impl Serialize for DocumentChild { @@ -37,6 +39,18 @@ impl Serialize for DocumentChild { t.serialize_field("data", c)?; t.end() } + DocumentChild::BookmarkStart(ref c) => { + let mut t = serializer.serialize_struct("BookmarkStart", 2)?; + t.serialize_field("type", "bookmarkStart")?; + t.serialize_field("data", c)?; + t.end() + } + DocumentChild::BookmarkEnd(ref c) => { + let mut t = serializer.serialize_struct("BookmarkEnd", 2)?; + t.serialize_field("type", "bookmarkEnd")?; + t.serialize_field("data", c)?; + t.end() + } } } } @@ -71,6 +85,18 @@ impl Document { self.children.push(DocumentChild::Table(t)); self } + + pub fn add_bookmark_start(mut self, id: usize, name: impl Into) -> Self { + self.children + .push(DocumentChild::BookmarkStart(BookmarkStart::new(id, name))); + self + } + + pub fn add_bookmark_end(mut self, id: usize) -> Self { + self.children + .push(DocumentChild::BookmarkEnd(BookmarkEnd::new(id))); + self + } } impl BuildXML for Document { @@ -83,6 +109,8 @@ impl BuildXML for Document { match c { DocumentChild::Paragraph(p) => b = b.add_child(p), DocumentChild::Table(t) => b = b.add_child(t), + DocumentChild::BookmarkStart(s) => b = b.add_child(s), + DocumentChild::BookmarkEnd(e) => b = b.add_child(e), } } b.add_child(&self.section_property).close().close().build() diff --git a/docx-core/src/documents/mod.rs b/docx-core/src/documents/mod.rs index f7283c0..b56ecee 100644 --- a/docx-core/src/documents/mod.rs +++ b/docx-core/src/documents/mod.rs @@ -112,6 +112,7 @@ impl Docx { self.document_rels.has_numberings = true; } } + _ => {} } } self.document = d; @@ -138,6 +139,16 @@ impl Docx { self } + pub fn add_bookmark_start(mut self, id: usize, name: impl Into) -> Docx { + self.document = self.document.add_bookmark_start(id, name); + self + } + + pub fn add_bookmark_end(mut self, id: usize) -> Docx { + self.document = self.document.add_bookmark_end(id); + self + } + pub fn add_table(mut self, t: Table) -> Docx { if t.has_numbering { // If this document has numbering, set numberings.xml to document_rels. @@ -247,6 +258,7 @@ impl Docx { } } } + _ => {} } } @@ -305,6 +317,7 @@ impl Docx { } } } + _ => {} } } // If this document has comments, set comments.xml to document_rels. @@ -371,6 +384,7 @@ impl Docx { } } } + _ => {} } } (image_ids, images) diff --git a/docx-wasm/example/index.ts b/docx-wasm/example/index.ts index da08c16..0381655 100644 --- a/docx-wasm/example/index.ts +++ b/docx-wasm/example/index.ts @@ -2,6 +2,7 @@ import { saveAs } from "file-saver"; import("../js").then((w) => { const buf = new w.Docx() + .addBookmarkStart(0, "Hello") .addParagraph( new w.Paragraph() .addRun(new w.Run().addText("Hello ")) @@ -29,6 +30,7 @@ import("../js").then((w) => { ) .addCommentEnd(new w.CommentEnd(2)) ) + .addBookmarkEnd(0) .docId("12345678-1234-1234-1234-1234567890AB") .build(); saveAs(new Blob([buf]), "hello.docx"); diff --git a/docx-wasm/js/index.ts b/docx-wasm/js/index.ts index 611ec13..aeec539 100644 --- a/docx-wasm/js/index.ts +++ b/docx-wasm/js/index.ts @@ -48,7 +48,7 @@ const convertBorderType = (t: BorderType) => { }; export class Docx { - children: (Paragraph | Table)[] = []; + children: (Paragraph | Table | BookmarkStart | BookmarkEnd)[] = []; hasNumberings = false; abstractNumberings: AbstractNumbering[] = []; numberings: Numbering[] = []; @@ -62,6 +62,16 @@ export class Docx { return this; } + addBookmarkStart(id: number, name: string) { + this.children.push(new BookmarkStart(id, name)); + return this; + } + + addBookmarkEnd(id: number) { + this.children.push(new BookmarkEnd(id)); + return this; + } + addTable(t: Table) { if (t.hasNumberings) { this.hasNumberings = true; @@ -452,6 +462,10 @@ export class Docx { } else if (child instanceof Table) { let t = this.buildTable(child); docx = docx.add_table(t); + } else if (child instanceof BookmarkStart) { + docx = docx.add_bookmark_start(child.id, child.name); + } else if (child instanceof BookmarkEnd) { + docx = docx.add_bookmark_end(child.id); } }); diff --git a/docx-wasm/src/doc.rs b/docx-wasm/src/doc.rs index 8cb0c9e..bddc45c 100644 --- a/docx-wasm/src/doc.rs +++ b/docx-wasm/src/doc.rs @@ -18,6 +18,16 @@ impl Docx { self } + pub fn add_bookmark_start(mut self, id: usize, name: &str) -> Self { + self.0 = self.0.add_bookmark_start(id, name); + self + } + + pub fn add_bookmark_end(mut self, id: usize) -> Docx { + self.0 = self.0.add_bookmark_end(id); + self + } + pub fn add_table(mut self, t: Table) -> Docx { self.0.document = self.0.document.add_table(t.take()); self