Skip to content

Commit 9f8f327

Browse files
authored
feat: 增加page margin和number (#48)
1 parent a751efd commit 9f8f327

File tree

4 files changed

+264
-0
lines changed

4 files changed

+264
-0
lines changed

apipara.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,3 +78,52 @@ func (p *Paragraph) Style(val string) *Paragraph {
7878
p.Properties.Style = &Style{Val: val}
7979
return p
8080
}
81+
82+
// NumPr number properties
83+
func (p *Paragraph) NumPr(numID, ilvl string) *Paragraph {
84+
if p.Properties == nil {
85+
p.Properties = &ParagraphProperties{}
86+
}
87+
// Initialize run properties if not exist
88+
if p.Properties.RunProperties == nil {
89+
p.Properties.RunProperties = &RunProperties{}
90+
}
91+
p.Properties.NumProperties = &NumProperties{
92+
NumID: &NumID{
93+
Val: numID,
94+
},
95+
Ilvl: &Ilevel{
96+
Val: ilvl,
97+
},
98+
}
99+
return p
100+
}
101+
102+
// NumFont sets the font for numbering
103+
func (p *Paragraph) NumFont(ascii, eastAsia, hansi, hint string) *Paragraph {
104+
if p.Properties == nil {
105+
p.Properties = &ParagraphProperties{}
106+
}
107+
if p.Properties.RunProperties == nil {
108+
p.Properties.RunProperties = &RunProperties{}
109+
}
110+
p.Properties.RunProperties.Fonts = &RunFonts{
111+
ASCII: ascii,
112+
EastAsia: eastAsia,
113+
HAnsi: hansi,
114+
Hint: hint,
115+
}
116+
return p
117+
}
118+
119+
// NumSize sets the size for numbering
120+
func (p *Paragraph) NumSize(size string) *Paragraph {
121+
if p.Properties == nil {
122+
p.Properties = &ParagraphProperties{}
123+
}
124+
if p.Properties.RunProperties == nil {
125+
p.Properties.RunProperties = &RunProperties{}
126+
}
127+
p.Properties.RunProperties.Size = &Size{Val: size}
128+
return p
129+
}

structnum.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*
2+
Copyright (c) 2024 l0g1n
3+
4+
This program is free software: you can redistribute it and/or modify
5+
it under the terms of the GNU Affero General Public License as published
6+
by the Free Software Foundation, either version 3 of the License, or
7+
(at your option) any later version.
8+
9+
This program is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
GNU Affero General Public License for more details.
13+
14+
You should have received a copy of the GNU Affero General Public License
15+
along with this program. If not, see <https://www.gnu.org/licenses/>.
16+
*/
17+
18+
package docx
19+
20+
import (
21+
"encoding/xml"
22+
"io"
23+
)
24+
25+
// NumProperties show the number properties
26+
type NumProperties struct {
27+
XMLName xml.Name `xml:"w:numPr,omitempty"`
28+
NumID *NumID
29+
Ilvl *Ilevel
30+
}
31+
32+
// NumID show the number id
33+
type NumID struct {
34+
XMLName xml.Name `xml:"w:numId,omitempty"`
35+
Val string `xml:"w:val,attr"`
36+
}
37+
38+
// Ilevel show the level
39+
type Ilevel struct {
40+
XMLName xml.Name `xml:"w:ilvl,omitempty"`
41+
Val string `xml:"w:val,attr"`
42+
}
43+
44+
// UnmarshalXML ...
45+
func (n *NumProperties) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error {
46+
for {
47+
t, err := d.Token()
48+
if err == io.EOF {
49+
break
50+
}
51+
if err != nil {
52+
return err
53+
}
54+
55+
if tt, ok := t.(xml.StartElement); ok {
56+
switch tt.Name.Local {
57+
case "numId":
58+
var value NumID
59+
value.Val = getAtt(tt.Attr, "val")
60+
n.NumID = &value
61+
case "ilvl":
62+
var value Ilevel
63+
value.Val = getAtt(tt.Attr, "val")
64+
n.Ilvl = &value
65+
default:
66+
err = d.Skip() // skip unsupported tags
67+
if err != nil {
68+
return err
69+
}
70+
continue
71+
}
72+
}
73+
}
74+
75+
return nil
76+
}

structpara.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ type ParagraphProperties struct {
3232
XMLName xml.Name `xml:"w:pPr,omitempty"`
3333
Tabs *Tabs
3434
Spacing *Spacing
35+
NumProperties *NumProperties
3536
Ind *Ind
3637
Justification *Justification
3738
Shade *Shade

structsect.go

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ import (
2828
type SectPr struct {
2929
XMLName xml.Name `xml:"w:sectPr,omitempty"` // properties of the document, including paper size
3030
PgSz *PgSz `xml:"w:pgSz,omitempty"`
31+
PgMar *PgMar `xml:"w:pgMar,omitempty"`
32+
Cols *Cols `xml:"w:cols,omitempty"`
33+
DocGrid *DocGrid `xml:"w:docGrid,omitempty"`
3134
}
3235

3336
// PgSz show the paper size
@@ -36,6 +39,28 @@ type PgSz struct {
3639
H int `xml:"w:h,attr"` // high of paper
3740
}
3841

42+
// PgMar show the page margin
43+
type PgMar struct {
44+
Top int `xml:"w:top,attr"`
45+
Left int `xml:"w:left,attr"`
46+
Bottom int `xml:"w:bottom,attr"`
47+
Right int `xml:"w:right,attr"`
48+
Header int `xml:"w:header,attr"`
49+
Footer int `xml:"w:footer,attr"`
50+
Gutter int `xml:"w:gutter,attr"`
51+
}
52+
53+
// Cols show the number of columns
54+
type Cols struct {
55+
Space int `xml:"w:space,attr"`
56+
}
57+
58+
// DocGrid show the document grid
59+
type DocGrid struct {
60+
Type string `xml:"w:type,attr"`
61+
LinePitch int `xml:"w:linePitch,attr"`
62+
}
63+
3964
// UnmarshalXML ...
4065
func (sect *SectPr) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error {
4166
for {
@@ -55,6 +80,27 @@ func (sect *SectPr) UnmarshalXML(d *xml.Decoder, _ xml.StartElement) error {
5580
return err
5681
}
5782
sect.PgSz = &value
83+
case "pgMar":
84+
var value PgMar
85+
err = d.DecodeElement(&value, &tt)
86+
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
87+
return err
88+
}
89+
sect.PgMar = &value
90+
case "cols":
91+
var value Cols
92+
err = d.DecodeElement(&value, &tt)
93+
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
94+
return err
95+
}
96+
sect.Cols = &value
97+
case "docGrid":
98+
var value DocGrid
99+
err = d.DecodeElement(&value, &tt)
100+
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
101+
return err
102+
}
103+
sect.DocGrid = &value
58104
default:
59105
err = d.Skip() // skip unsupported tags
60106
if err != nil {
@@ -90,3 +136,95 @@ func (pgsz *PgSz) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
90136
_, err = d.Token()
91137
return err
92138
}
139+
140+
// UnmarshalXML ...
141+
func (pgmar *PgMar) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
142+
var err error
143+
144+
for _, attr := range start.Attr {
145+
switch attr.Name.Local {
146+
case "top":
147+
pgmar.Top, err = strconv.Atoi(attr.Value)
148+
if err != nil {
149+
return err
150+
}
151+
case "left":
152+
pgmar.Left, err = strconv.Atoi(attr.Value)
153+
if err != nil {
154+
return err
155+
}
156+
case "bottom":
157+
pgmar.Bottom, err = strconv.Atoi(attr.Value)
158+
if err != nil {
159+
return err
160+
}
161+
case "right":
162+
pgmar.Right, err = strconv.Atoi(attr.Value)
163+
if err != nil {
164+
return err
165+
}
166+
case "header":
167+
pgmar.Header, err = strconv.Atoi(attr.Value)
168+
if err != nil {
169+
return err
170+
}
171+
case "footer":
172+
pgmar.Footer, err = strconv.Atoi(attr.Value)
173+
if err != nil {
174+
return err
175+
}
176+
case "gutter":
177+
pgmar.Gutter, err = strconv.Atoi(attr.Value)
178+
if err != nil {
179+
return err
180+
}
181+
default:
182+
// ignore other attributes now
183+
}
184+
}
185+
// Consume the end element
186+
_, err = d.Token()
187+
return err
188+
}
189+
190+
// UnmarshalXML ...
191+
func (cols *Cols) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
192+
var err error
193+
194+
for _, attr := range start.Attr {
195+
switch attr.Name.Local {
196+
case "space":
197+
cols.Space, err = strconv.Atoi(attr.Value)
198+
if err != nil {
199+
return err
200+
}
201+
default:
202+
// ignore other attributes now
203+
}
204+
}
205+
// Consume the end element
206+
_, err = d.Token()
207+
return err
208+
}
209+
210+
// UnmarshalXML ...
211+
func (dg *DocGrid) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
212+
var err error
213+
214+
for _, attr := range start.Attr {
215+
switch attr.Name.Local {
216+
case "linePitch":
217+
dg.LinePitch, err = strconv.Atoi(attr.Value)
218+
if err != nil {
219+
return err
220+
}
221+
case "type":
222+
dg.Type = attr.Value
223+
default:
224+
// ignore other attributes now
225+
}
226+
}
227+
// Consume the end element
228+
_, err = d.Token()
229+
return err
230+
}

0 commit comments

Comments
 (0)