document: support removing runs/paragraphs

This commit is contained in:
Todd 2017-09-26 18:18:59 -05:00
parent ad46a6ae15
commit 82f22691b2
4 changed files with 119 additions and 2 deletions

View File

@ -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{}

View File

@ -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})
}
}
}
}
}

View File

@ -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()

View File

@ -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
}