Skip to content

Commit

Permalink
document: support for controlling paragraph numbering
Browse files Browse the repository at this point in the history
  • Loading branch information
tbaliance committed Dec 16, 2017
1 parent 12b7484 commit 259724d
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 15 deletions.
11 changes: 11 additions & 0 deletions _examples/document/simple/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
package main

import (
"fmt"

"baliance.com/gooxml/color"
"baliance.com/gooxml/document"
"baliance.com/gooxml/measurement"
Expand Down Expand Up @@ -81,6 +83,15 @@ func main() {
run = createParaRun(doc, "text effects")
run.Properties().SetEffect(wml.ST_TextEffectAntsRed)

nd := doc.Numbering.Definitions()[0]

for i := 1; i < 5; i++ {
p := doc.AddParagraph()
p.SetNumberingLevel(i - 1)
p.SetNumberingDefinition(nd)
run := p.AddRun()
run.AddText(fmt.Sprintf("Level %d", i))
}
doc.SaveToFile("simple.docx")
}

Expand Down
Binary file modified _examples/document/simple/simple.docx
Binary file not shown.
56 changes: 41 additions & 15 deletions document/numbering.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
package document

import (
"fmt"

"baliance.com/gooxml"
"baliance.com/gooxml/schema/soo/ofc/sharedTypes"
"baliance.com/gooxml/schema/soo/wml"
Expand Down Expand Up @@ -42,44 +40,46 @@ func (n Numbering) Clear() {
// InitializeDefault constructs a default numbering.
func (n Numbering) InitializeDefault() {
abs := wml.NewCT_AbstractNum()
abs.MultiLevelType = wml.NewCT_MultiLevelType()
abs.MultiLevelType.ValAttr = wml.ST_MultiLevelTypeHybridMultilevel

n.x.AbstractNum = append(n.x.AbstractNum, abs)
abs.AbstractNumIdAttr = 1
const indentStart = 432
const indentDelta = 144
const indentStart = 720
const indentDelta = 720
const hangingIndent = 360
for i := 0; i < 9; i++ {
lvl := wml.NewCT_Lvl()
lvl.IlvlAttr = int64(i)
lvl.Start = wml.NewCT_DecimalNumber()
lvl.Start.ValAttr = 1

lvl.PStyle = wml.NewCT_String()
lvl.PStyle.ValAttr = fmt.Sprintf("Heading%d", i+1)

lvl.NumFmt = wml.NewCT_NumFmt()
lvl.NumFmt.ValAttr = wml.ST_NumberFormatNone
lvl.NumFmt.ValAttr = wml.ST_NumberFormatBullet

lvl.Suff = wml.NewCT_LevelSuffix()
lvl.Suff.ValAttr = wml.ST_LevelSuffixNothing

lvl.LvlText = wml.NewCT_LevelText()
lvl.LvlText.ValAttr = gooxml.String("")
lvl.LvlText.ValAttr = gooxml.String("")

lvl.LvlJc = wml.NewCT_Jc()
lvl.LvlJc.ValAttr = wml.ST_JcLeft

lvl.RPr = wml.NewCT_RPr()
lvl.RPr.RFonts = wml.NewCT_Fonts()
lvl.RPr.RFonts.AsciiAttr = gooxml.String("Symbol")
lvl.RPr.RFonts.HAnsiAttr = gooxml.String("Symbol")
lvl.RPr.RFonts.HintAttr = wml.ST_HintDefault

lvl.PPr = wml.NewCT_PPrGeneral()
lvl.PPr.Tabs = wml.NewCT_Tabs()
tab := wml.NewCT_TabStop()
tab.ValAttr = wml.ST_TabJcNum

indent := int64(i*indentDelta + indentStart)
tab.PosAttr.Int64 = gooxml.Int64(indent)
lvl.PPr.Tabs.Tab = append(lvl.PPr.Tabs.Tab, tab)
lvl.PPr.Ind = wml.NewCT_Ind()
lvl.PPr.Ind.LeftAttr = &wml.ST_SignedTwipsMeasure{}
lvl.PPr.Ind.LeftAttr.Int64 = gooxml.Int64(indent)
lvl.PPr.Ind.HangingAttr = &sharedTypes.ST_TwipsMeasure{}
lvl.PPr.Ind.HangingAttr.ST_UnsignedDecimalNumber = gooxml.Uint64(uint64(indent))
lvl.PPr.Ind.HangingAttr.ST_UnsignedDecimalNumber = gooxml.Uint64(uint64(hangingIndent))

abs.Lvl = append(abs.Lvl, lvl)
}
Expand All @@ -89,3 +89,29 @@ func (n Numbering) InitializeDefault() {
num.AbstractNumId.ValAttr = 1
n.x.Num = append(n.x.Num, num)
}

// Definitions returns the defined numbering definitions.
func (n Numbering) Definitions() []NumberingDefinition {
ret := []NumberingDefinition{}
for _, n := range n.x.Num {
ret = append(ret, NumberingDefinition{n})
}
return ret
}

// AddDefinition adds a new numbering definition.
func (n Numbering) AddDefinition() NumberingDefinition {
nx := wml.NewCT_Num()

nextID := int64(1)
for _, nd := range n.Definitions() {
if nd.AbstractNumberID() >= nextID {
nextID = nd.AbstractNumberID() + 1
}
}
nx.AbstractNumId = wml.NewCT_DecimalNumber()
nx.AbstractNumId.ValAttr = nextID

n.x.Num = append(n.x.Num, nx)
return NumberingDefinition{nx}
}
46 changes: 46 additions & 0 deletions document/numberingdefinition.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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 [email protected].

package document

import "baliance.com/gooxml/schema/soo/wml"

// NumberingDefinition defines a numbering definition for a list of pragraphs.
type NumberingDefinition struct {
x *wml.CT_Num
}

// X returns the inner wrapped XML type.
func (n NumberingDefinition) X() *wml.CT_Num {
return n.x
}

// AbstractNumberID returns the ID that is unique within all numbering
// definitions that is used to assign the definition to a paragraph.
func (n NumberingDefinition) AbstractNumberID() int64 {
if n.x.AbstractNumId == nil {
return 0
}
return n.x.AbstractNumId.ValAttr
}

// Levels returns all of the numbering levels defined in the definition.
func (n NumberingDefinition) Levels() []NumberingLevel {
ret := []NumberingLevel{}
for _, nl := range n.x.LvlOverride {
ret = append(ret, NumberingLevel{nl})
}
return ret
}

// AddLevel adds a new numbering level to a NumberingDefinition.
func (n NumberingDefinition) AddLevel() NumberingLevel {
nl := wml.NewCT_NumLvl()
nl.IlvlAttr = int64(len(n.x.LvlOverride))
n.x.LvlOverride = append(n.x.LvlOverride, nl)
return NumberingLevel{nl}
}
34 changes: 34 additions & 0 deletions document/numberinglevel.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// 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 [email protected].

package document

import "baliance.com/gooxml/schema/soo/wml"

// NumberingLevel is the definition for numbering for a particular level within
// a NumberingDefinition.
type NumberingLevel struct {
x *wml.CT_NumLvl
}

// X returns the inner wrapped XML type.
func (n NumberingLevel) X() *wml.CT_NumLvl {
return n.x
}

func (n NumberingLevel) ensureLevel() {
if n.x.Lvl == nil {
n.x.Lvl = wml.NewCT_Lvl()
}
}

// SetStartOverride sets the Numbering Level Starting Value Override.
func (n NumberingLevel) SetStartOverride(v int64) {
n.ensureLevel()
n.x.StartOverride = wml.NewCT_DecimalNumber()
n.x.StartOverride.ValAttr = v
}
37 changes: 37 additions & 0 deletions document/paragraph.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,3 +192,40 @@ func (p Paragraph) AddBookmark(name string) Bookmark {
bm.SetName(name)
return bm
}

// SetNumberingLevel sets the numbering level of a paragraph. If used, then the
// NumberingDefinition must also be set via SetNumberingDefinition or
// SetNumberingDefinitionByID.
func (p Paragraph) SetNumberingLevel(listLevel int) {
p.ensurePPr()
if p.x.PPr.NumPr == nil {
p.x.PPr.NumPr = wml.NewCT_NumPr()
}
lvl := wml.NewCT_DecimalNumber()
lvl.ValAttr = int64(listLevel)
p.x.PPr.NumPr.Ilvl = lvl
}

// SetNumberingDefinition sets the numbering definition ID via a NumberingDefinition
// defined in numbering.xml
func (p Paragraph) SetNumberingDefinition(nd NumberingDefinition) {
p.ensurePPr()
if p.x.PPr.NumPr == nil {
p.x.PPr.NumPr = wml.NewCT_NumPr()
}
lvl := wml.NewCT_DecimalNumber()
lvl.ValAttr = int64(nd.AbstractNumberID())
p.x.PPr.NumPr.NumId = lvl
}

// SetNumberingDefinitionByID sets the numbering definition ID directly, which must
// match an ID defined in numbering.xml
func (p Paragraph) SetNumberingDefinitionByID(abstractNumberID int64) {
p.ensurePPr()
if p.x.PPr.NumPr == nil {
p.x.PPr.NumPr = wml.NewCT_NumPr()
}
lvl := wml.NewCT_DecimalNumber()
lvl.ValAttr = int64(abstractNumberID)
p.x.PPr.NumPr.NumId = lvl
}
Binary file modified document/testdata/header-footer-multiple.docx
Binary file not shown.
Binary file modified document/testdata/simple-1.docx
Binary file not shown.

0 comments on commit 259724d

Please sign in to comment.