diff --git a/document/document.go b/document/document.go index 876369bb..02979cf2 100644 --- a/document/document.go +++ b/document/document.go @@ -249,6 +249,49 @@ func (d *Document) AddParagraph() Paragraph { return Paragraph{d, p} } +func (d *Document) removeParagraph(rp *wml.CT_P) { + if d.x.Body == nil { + return + } + + for _, ble := range d.x.Body.EG_BlockLevelElts { + for _, c := range ble.EG_ContentBlockContent { + for i, p := range c.P { + // do we need to remove this paragraph + if p == rp { + copy(c.P[i:], c.P[i+1:]) + c.P = c.P[0 : len(c.P)-1] + return + } + } + + if c.Sdt != nil && c.Sdt.SdtContent != nil && c.Sdt.SdtContent.P != nil { + for i, p := range c.Sdt.SdtContent.P { + if p == rp { + copy(c.P[i:], c.P[i+1:]) + c.P = c.P[0 : len(c.P)-1] + return + } + } + } + } + } +} + +// StructuredDocumentTags returns the structured document tags in the document +// which are commonly used in document templates. +func (d *Document) StructuredDocumentTags() []StructuredDocumentTag { + ret := []StructuredDocumentTag{} + for _, ble := range d.x.Body.EG_BlockLevelElts { + for _, c := range ble.EG_ContentBlockContent { + if c.Sdt != nil { + ret = append(ret, StructuredDocumentTag{d, c.Sdt}) + } + } + } + return ret +} + // Paragraphs returns all of the paragraphs in the document body. func (d *Document) Paragraphs() []Paragraph { ret := []Paragraph{} diff --git a/document/paragraph.go b/document/paragraph.go index 0e10d00e..329fc0e3 100644 --- a/document/paragraph.go +++ b/document/paragraph.go @@ -28,6 +28,32 @@ func (p Paragraph) ensurePPr() { } } +// Remove removes the paragraph from its parent element, effectively deleting it +// from a document. +func (p Paragraph) Remove() { + p.d.removeParagraph(p.x) +} + +// removeChildRun removes a child run from a paragraph. +func (p Paragraph) removeChildRun(rr *wml.CT_R) { + for _, c := range p.x.EG_PContent { + for i, rc := range c.EG_ContentRunContent { + if rc.R == rr { + copy(c.EG_ContentRunContent[i:], c.EG_ContentRunContent[i+1:]) + c.EG_ContentRunContent = c.EG_ContentRunContent[0 : len(c.EG_ContentRunContent)-1] + } + if rc.Sdt != nil && rc.Sdt.SdtContent != nil { + for i, rc2 := range rc.Sdt.SdtContent.EG_ContentRunContent { + if rc2.R == rr { + copy(rc.Sdt.SdtContent.EG_ContentRunContent[i:], rc.Sdt.SdtContent.EG_ContentRunContent[i+1:]) + rc.Sdt.SdtContent.EG_ContentRunContent = rc.Sdt.SdtContent.EG_ContentRunContent[0 : len(rc.Sdt.SdtContent.EG_ContentRunContent)-1] + } + } + } + } + } +} + // Properties returns the paragraph properties. func (p Paragraph) Properties() ParagraphProperties { p.ensurePPr() @@ -69,7 +95,7 @@ func (p Paragraph) AddRun() Run { pc.EG_ContentRunContent = append(pc.EG_ContentRunContent, rc) r := wml.NewCT_R() rc.R = r - return Run{p.d, r} + return Run{p.d, p.x, r} } // Runs returns all of the runs in a paragraph. @@ -78,7 +104,14 @@ func (p Paragraph) Runs() []Run { for _, c := range p.x.EG_PContent { for _, rc := range c.EG_ContentRunContent { if rc.R != nil { - ret = append(ret, Run{p.d, rc.R}) + ret = append(ret, Run{p.d, p.x, rc.R}) + } + if rc.Sdt != nil && rc.Sdt.SdtContent != nil { + for _, rc2 := range rc.Sdt.SdtContent.EG_ContentRunContent { + if rc2.R != nil { + ret = append(ret, Run{p.d, p.x, rc2.R}) + } + } } } } diff --git a/document/run.go b/document/run.go index ef32f6d3..770c87b8 100644 --- a/document/run.go +++ b/document/run.go @@ -25,6 +25,7 @@ import ( // Run is a run of text within a paragraph that shares the same formatting. type Run struct { d *Document + p *wml.CT_P x *wml.CT_R } @@ -50,6 +51,18 @@ func (r Run) Text() string { return buf.String() } +// Remove removes the run from its parent paragraph. This effectively deletes it +// from a document. +func (r Run) Remove() { + p := Paragraph{r.d, r.p} + p.removeChildRun(r.x) +} + +// ClearContent clears any content in the run (text, tabs, breaks, etc.) +func (r Run) ClearContent() { + r.x.EG_RunInnerContent = nil +} + // AddText adds tet to a run. func (r Run) AddText(s string) { ic := wml.NewEG_RunInnerContent() diff --git a/document/structuredocumenttag.go b/document/structuredocumenttag.go new file mode 100644 index 00000000..38b30a0d --- /dev/null +++ b/document/structuredocumenttag.go @@ -0,0 +1,28 @@ +// Copyright 2017 Baliance. All rights reserved. +// +// Use of this source code is governed by the terms of the Affero GNU General +// Public License version 3.0 as published by the Free Software Foundation and +// appearing in the file LICENSE included in the packaging of this file. A +// commercial license can be purchased by contacting sales@baliance.com. + +package document + +import "baliance.com/gooxml/schema/soo/wml" + +// StructuredDocumentTag are a tagged bit of content in a document. +type StructuredDocumentTag struct { + d *Document + x *wml.CT_SdtBlock +} + +// Paragraphs returns the paragraphs within a structured document tag. +func (s StructuredDocumentTag) Paragraphs() []Paragraph { + if s.x.SdtContent == nil { + return nil + } + ret := []Paragraph{} + for _, p := range s.x.SdtContent.P { + ret = append(ret, Paragraph{s.d, p}) + } + return ret +}