1
0
mirror of https://github.com/fumiama/go-docx.git synced 2026-06-05 07:40:24 +08:00
Files
go-docx/structrun.go
2023-02-26 20:20:04 +08:00

209 lines
4.8 KiB
Go

/*
Copyright (c) 2020 gingfrederik
Copyright (c) 2021 Gonzalo Fernandez-Victorio
Copyright (c) 2021 Basement Crowd Ltd (https://www.basementcrowd.com)
Copyright (c) 2023 Fumiama Minamoto (源文雨)
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published
by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package docx
import (
"encoding/xml"
"io"
"strings"
)
// Run is part of a paragraph that has its own style. It could be
// a piece of text in bold, or a link
type Run struct {
XMLName xml.Name `xml:"w:r,omitempty"`
RunProperties *RunProperties `xml:"w:rPr,omitempty"`
InstrText string `xml:"w:instrText,omitempty"`
Children []interface{}
}
// UnmarshalXML ...
func (r *Run) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
var child interface{}
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "rPr":
var value RunProperties
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.RunProperties = &value
continue
case "instrText":
var value string
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.InstrText = value
continue
case "t":
var value Text
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
child = &value
case "drawing":
var value Drawing
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
child = &value
case "tab":
child = &Tab{}
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
r.Children = append(r.Children, child)
}
}
return nil
}
// RunProperties encapsulates visual properties of a run
type RunProperties struct {
XMLName xml.Name `xml:"w:rPr,omitempty"`
Fonts *RunFonts
Bold *Bold
Italic *Italic
Underline *Underline
Highlight *Highlight
Color *Color
Size *Size
RunStyle *RunStyle
Style *Style
Shade *Shade
}
// UnmarshalXML ...
func (r *RunProperties) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for {
t, err := d.Token()
if err == io.EOF {
break
}
if err != nil {
return err
}
if tt, ok := t.(xml.StartElement); ok {
switch tt.Name.Local {
case "rFonts":
var value RunFonts
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Fonts = &value
case "b":
r.Bold = &Bold{}
case "i":
r.Italic = &Italic{}
case "u":
var value Underline
value.Val = getAtt(tt.Attr, "val")
r.Underline = &value
case "highlight":
var value Highlight
value.Val = getAtt(tt.Attr, "val")
r.Highlight = &value
case "color":
var value Color
value.Val = getAtt(tt.Attr, "val")
r.Color = &value
case "sz":
var value Size
value.Val = getAtt(tt.Attr, "val")
r.Size = &value
case "rStyle":
var value RunStyle
value.Val = getAtt(tt.Attr, "val")
r.RunStyle = &value
case "pStyle":
var value Style
value.Val = getAtt(tt.Attr, "val")
r.Style = &value
case "shd":
var value Shade
err = d.DecodeElement(&value, &tt)
if err != nil && !strings.HasPrefix(err.Error(), "expected") {
return err
}
r.Shade = &value
default:
err = d.Skip() // skip unsupported tags
if err != nil {
return err
}
continue
}
}
}
return nil
}
// RunFonts specifies the fonts used in the text of a run.
type RunFonts struct {
XMLName xml.Name `xml:"w:rFonts,omitempty"`
ASCII string `xml:"w:ascii,attr,omitempty"`
HAnsi string `xml:"w:hAnsi,attr,omitempty"`
Hint string `xml:"w:hint,attr,omitempty"`
}
// UnmarshalXML ...
func (f *RunFonts) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
for _, attr := range start.Attr {
switch attr.Name.Local {
case "ascii":
f.ASCII = attr.Value
case "hAnsi":
f.HAnsi = attr.Value
case "hint":
f.Hint = attr.Value
}
}
// Consume the end element
_, err := d.Token()
return err
}