mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-25 13:48:53 +08:00

* update license and terms * Fixes * Create ACKNOWLEDGEMENTS.md * Update ACKNOWLEDGEMENTS.md * Revert go.mod changes and remove go1.11 tests
387 lines
11 KiB
Go
387 lines
11 KiB
Go
// Copyright 2017 FoxyUtils ehf. All rights reserved.
|
|
//
|
|
// Use of this software package and source code is governed by the terms of the
|
|
// UniDoc End User License Agreement (EULA) that is available at:
|
|
// https://unidoc.io/eula/
|
|
// A trial license code for evaluation can be obtained at https://unidoc.io.
|
|
|
|
package document
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/unidoc/unioffice"
|
|
"github.com/unidoc/unioffice/color"
|
|
"github.com/unidoc/unioffice/measurement"
|
|
"github.com/unidoc/unioffice/schema/soo/ofc/sharedTypes"
|
|
"github.com/unidoc/unioffice/schema/soo/wml"
|
|
)
|
|
|
|
// ParagraphProperties are the properties for a paragraph.
|
|
type ParagraphProperties struct {
|
|
d *Document
|
|
x *wml.CT_PPr
|
|
}
|
|
|
|
// X returns the inner wrapped XML type.
|
|
func (p ParagraphProperties) X() *wml.CT_PPr {
|
|
return p.x
|
|
}
|
|
|
|
// SetSpacing sets the spacing that comes before and after the paragraph.
|
|
// Deprecated: See Spacing() instead which allows finer control.
|
|
func (p ParagraphProperties) SetSpacing(before, after measurement.Distance) {
|
|
if p.x.Spacing == nil {
|
|
p.x.Spacing = wml.NewCT_Spacing()
|
|
}
|
|
p.x.Spacing.BeforeAttr = &sharedTypes.ST_TwipsMeasure{}
|
|
p.x.Spacing.BeforeAttr.ST_UnsignedDecimalNumber = unioffice.Uint64(uint64(before / measurement.Twips))
|
|
p.x.Spacing.AfterAttr = &sharedTypes.ST_TwipsMeasure{}
|
|
p.x.Spacing.AfterAttr.ST_UnsignedDecimalNumber = unioffice.Uint64(uint64(after / measurement.Twips))
|
|
}
|
|
|
|
// Spacing returns the paragraph spacing settings.
|
|
func (p ParagraphProperties) Spacing() ParagraphSpacing {
|
|
if p.x.Spacing == nil {
|
|
p.x.Spacing = wml.NewCT_Spacing()
|
|
}
|
|
return ParagraphSpacing{p.x.Spacing}
|
|
}
|
|
|
|
// SetAlignment controls the paragraph alignment
|
|
func (p ParagraphProperties) SetAlignment(align wml.ST_Jc) {
|
|
if align == wml.ST_JcUnset {
|
|
p.x.Jc = nil
|
|
} else {
|
|
p.x.Jc = wml.NewCT_Jc()
|
|
p.x.Jc.ValAttr = align
|
|
}
|
|
}
|
|
|
|
// Style returns the style for a paragraph, or an empty string if it is unset.
|
|
func (p ParagraphProperties) Style() string {
|
|
if p.x.PStyle != nil {
|
|
return p.x.PStyle.ValAttr
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// SetStyle sets the style of a paragraph.
|
|
func (p ParagraphProperties) SetStyle(s string) {
|
|
if s == "" {
|
|
p.x.PStyle = nil
|
|
} else {
|
|
p.x.PStyle = wml.NewCT_String()
|
|
p.x.PStyle.ValAttr = s
|
|
}
|
|
}
|
|
|
|
// AddTabStop adds a tab stop to the paragraph. It controls the position of text when using Run.AddTab()
|
|
func (p ParagraphProperties) AddTabStop(position measurement.Distance, justificaton wml.ST_TabJc, leader wml.ST_TabTlc) {
|
|
if p.x.Tabs == nil {
|
|
p.x.Tabs = wml.NewCT_Tabs()
|
|
}
|
|
tab := wml.NewCT_TabStop()
|
|
tab.LeaderAttr = leader
|
|
tab.ValAttr = justificaton
|
|
tab.PosAttr.Int64 = unioffice.Int64(int64(position / measurement.Twips))
|
|
p.x.Tabs.Tab = append(p.x.Tabs.Tab, tab)
|
|
}
|
|
|
|
// AddSection adds a new document section with an optional section break. If t
|
|
// is ST_SectionMarkUnset, then no break will be inserted.
|
|
func (p ParagraphProperties) AddSection(t wml.ST_SectionMark) Section {
|
|
p.x.SectPr = wml.NewCT_SectPr()
|
|
if t != wml.ST_SectionMarkUnset {
|
|
p.x.SectPr.Type = wml.NewCT_SectType()
|
|
p.x.SectPr.Type.ValAttr = t
|
|
}
|
|
return Section{p.d, p.x.SectPr}
|
|
}
|
|
|
|
// SetHeadingLevel sets a heading level and style based on the level to a
|
|
// paragraph. The default styles for a new gooxml document support headings
|
|
// from level 1 to 8.
|
|
func (p ParagraphProperties) SetHeadingLevel(idx int) {
|
|
p.SetStyle(fmt.Sprintf("Heading%d", idx))
|
|
if p.x.NumPr == nil {
|
|
p.x.NumPr = wml.NewCT_NumPr()
|
|
}
|
|
p.x.NumPr.Ilvl = wml.NewCT_DecimalNumber()
|
|
p.x.NumPr.Ilvl.ValAttr = int64(idx)
|
|
}
|
|
|
|
// SetKeepWithNext controls if this paragraph should be kept with the next.
|
|
func (p ParagraphProperties) SetKeepWithNext(b bool) {
|
|
if !b {
|
|
p.x.KeepNext = nil
|
|
} else {
|
|
p.x.KeepNext = wml.NewCT_OnOff()
|
|
}
|
|
}
|
|
|
|
// SetKeepOnOnePage controls if all lines in a paragraph are kept on the same
|
|
// page.
|
|
func (p ParagraphProperties) SetKeepOnOnePage(b bool) {
|
|
if !b {
|
|
p.x.KeepLines = nil
|
|
} else {
|
|
p.x.KeepLines = wml.NewCT_OnOff()
|
|
}
|
|
}
|
|
|
|
// SetPageBreakBefore controls if there is a page break before this paragraph.
|
|
func (p ParagraphProperties) SetPageBreakBefore(b bool) {
|
|
if !b {
|
|
p.x.PageBreakBefore = nil
|
|
} else {
|
|
p.x.PageBreakBefore = wml.NewCT_OnOff()
|
|
}
|
|
}
|
|
|
|
// SetWindowControl controls if the first or last line of the paragraph is
|
|
// allowed to dispay on a separate page.
|
|
func (p ParagraphProperties) SetWindowControl(b bool) {
|
|
if !b {
|
|
p.x.WidowControl = nil
|
|
} else {
|
|
p.x.WidowControl = wml.NewCT_OnOff()
|
|
}
|
|
}
|
|
|
|
// SetFirstLineIndent controls the indentation of the first line in a paragraph.
|
|
func (p ParagraphProperties) SetFirstLineIndent(m measurement.Distance) {
|
|
if p.x.Ind == nil {
|
|
p.x.Ind = wml.NewCT_Ind()
|
|
}
|
|
if m == measurement.Zero {
|
|
p.x.Ind.FirstLineAttr = nil
|
|
} else {
|
|
p.x.Ind.FirstLineAttr = &sharedTypes.ST_TwipsMeasure{}
|
|
p.x.Ind.FirstLineAttr.ST_UnsignedDecimalNumber = unioffice.Uint64(uint64(m / measurement.Twips))
|
|
}
|
|
}
|
|
|
|
// SetStartIndent controls the start indentation.
|
|
func (p ParagraphProperties) SetStartIndent(m measurement.Distance) {
|
|
if p.x.Ind == nil {
|
|
p.x.Ind = wml.NewCT_Ind()
|
|
}
|
|
if m == measurement.Zero {
|
|
p.x.Ind.StartAttr = nil
|
|
} else {
|
|
p.x.Ind.StartAttr = &wml.ST_SignedTwipsMeasure{}
|
|
p.x.Ind.StartAttr.Int64 = unioffice.Int64(int64(m / measurement.Twips))
|
|
}
|
|
}
|
|
|
|
// SetEndIndent controls the end indentation.
|
|
func (p ParagraphProperties) SetEndIndent(m measurement.Distance) {
|
|
if p.x.Ind == nil {
|
|
p.x.Ind = wml.NewCT_Ind()
|
|
}
|
|
if m == measurement.Zero {
|
|
p.x.Ind.EndAttr = nil
|
|
} else {
|
|
p.x.Ind.EndAttr = &wml.ST_SignedTwipsMeasure{}
|
|
p.x.Ind.EndAttr.Int64 = unioffice.Int64(int64(m / measurement.Twips))
|
|
}
|
|
}
|
|
|
|
// SetHangingIndent controls the indentation of the non-first lines in a paragraph.
|
|
func (p ParagraphProperties) SetHangingIndent(m measurement.Distance) {
|
|
if p.x.Ind == nil {
|
|
p.x.Ind = wml.NewCT_Ind()
|
|
}
|
|
if m == measurement.Zero {
|
|
p.x.Ind.HangingAttr = nil
|
|
} else {
|
|
p.x.Ind.HangingAttr = &sharedTypes.ST_TwipsMeasure{}
|
|
p.x.Ind.HangingAttr.ST_UnsignedDecimalNumber = unioffice.Uint64(uint64(m / measurement.Twips))
|
|
}
|
|
}
|
|
|
|
// Bold returns true if paragraph font is bold.
|
|
func (p ParagraphProperties) Bold() bool {
|
|
x := p.x.RPr
|
|
return getBool(x.B) || getBool(x.BCs)
|
|
}
|
|
|
|
// Italic returns true if paragraph font is italic.
|
|
func (p ParagraphProperties) Italic() bool {
|
|
x := p.x.RPr
|
|
return getBool(x.I) || getBool(x.ICs)
|
|
}
|
|
|
|
// Caps returns true if paragraph font is capitalized.
|
|
func (p ParagraphProperties) Caps() bool {
|
|
return getBool(p.x.RPr.Caps)
|
|
}
|
|
|
|
// Strike returns true if paragraph is striked.
|
|
func (p ParagraphProperties) Strike() bool {
|
|
return getBool(p.x.RPr.Strike)
|
|
}
|
|
|
|
// DoubleStrike returns true if paragraph is double striked.
|
|
func (p ParagraphProperties) DoubleStrike() bool {
|
|
return getBool(p.x.RPr.Dstrike)
|
|
}
|
|
|
|
// Outline returns true if paragraph outline is on.
|
|
func (p ParagraphProperties) Outline() bool {
|
|
return getBool(p.x.RPr.Outline)
|
|
}
|
|
|
|
// Shadow returns true if paragraph shadow is on.
|
|
func (p ParagraphProperties) Shadow() bool {
|
|
return getBool(p.x.RPr.Shadow)
|
|
}
|
|
|
|
// Emboss returns true if paragraph emboss is on.
|
|
func (p ParagraphProperties) Emboss() bool {
|
|
return getBool(p.x.RPr.Emboss)
|
|
}
|
|
|
|
// RightToLeft returns true if paragraph text goes from right to left.
|
|
func (p ParagraphProperties) RightToLeft() bool {
|
|
return getBool(p.x.RPr.Rtl)
|
|
}
|
|
|
|
// RStyle returns the name of character style.
|
|
// It is defined here http://officeopenxml.com/WPstyleCharStyles.php
|
|
func (p ParagraphProperties) RStyle() string {
|
|
if p.x.RPr.RStyle != nil {
|
|
return p.x.RPr.RStyle.ValAttr
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Font returns the name of paragraph font family.
|
|
func (p ParagraphProperties) Font() string {
|
|
if fonts := p.x.RPr.RFonts; fonts != nil {
|
|
if fonts.AsciiAttr != nil {
|
|
return *fonts.AsciiAttr
|
|
} else if fonts.HAnsiAttr != nil {
|
|
return *fonts.HAnsiAttr
|
|
} else if fonts.CsAttr != nil {
|
|
return *fonts.CsAttr
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// EastAsiaFont returns the name of paragraph font family for East Asia.
|
|
func (p ParagraphProperties) EastAsiaFont() string {
|
|
if fonts := p.x.RPr.RFonts; fonts != nil {
|
|
if fonts.EastAsiaAttr != nil {
|
|
return *fonts.EastAsiaAttr
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// GetColor returns the color.Color object representing the run color.
|
|
func (p ParagraphProperties) GetColor() color.Color {
|
|
if c := p.x.RPr.Color; c != nil {
|
|
valAttr := c.ValAttr
|
|
if valAttr.ST_HexColorRGB != nil {
|
|
return color.FromHex(*valAttr.ST_HexColorRGB)
|
|
}
|
|
}
|
|
return color.Color{}
|
|
}
|
|
|
|
// CharacterSpacingValue returns the value of characters spacing in twips (1/20 of point).
|
|
func (p ParagraphProperties) CharacterSpacingValue() int64 {
|
|
if spacing := p.x.RPr.Spacing; spacing != nil {
|
|
valAttr := spacing.ValAttr
|
|
if valAttr.Int64 != nil {
|
|
return *valAttr.Int64
|
|
}
|
|
}
|
|
return int64(0)
|
|
}
|
|
|
|
// CharacterSpacingMeasure returns paragraph characters spacing with its measure which can be mm, cm, in, pt, pc or pi.
|
|
func (p ParagraphProperties) CharacterSpacingMeasure() string {
|
|
if spacing := p.x.RPr.Spacing; spacing != nil {
|
|
valAttr := spacing.ValAttr
|
|
if valAttr.ST_UniversalMeasure != nil {
|
|
return *valAttr.ST_UniversalMeasure
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// SizeValue returns the value of paragraph font size in points.
|
|
func (p ParagraphProperties) SizeValue() float64 {
|
|
if sz := p.x.RPr.Sz; sz != nil {
|
|
valAttr := sz.ValAttr
|
|
if valAttr.ST_UnsignedDecimalNumber != nil {
|
|
return float64(*valAttr.ST_UnsignedDecimalNumber) / 2
|
|
}
|
|
}
|
|
return 0.0
|
|
}
|
|
|
|
// SizeMeasure returns font with its measure which can be mm, cm, in, pt, pc or pi.
|
|
func (p ParagraphProperties) SizeMeasure() string {
|
|
if sz := p.x.RPr.Sz; sz != nil {
|
|
valAttr := sz.ValAttr
|
|
if valAttr.ST_PositiveUniversalMeasure != nil {
|
|
return *valAttr.ST_PositiveUniversalMeasure
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// ComplexSizeValue returns the value of paragraph font size for complex fonts in points.
|
|
func (p ParagraphProperties) ComplexSizeValue() float64 {
|
|
if szCs := p.x.RPr.SzCs; szCs != nil {
|
|
valAttr := szCs.ValAttr
|
|
if valAttr.ST_UnsignedDecimalNumber != nil {
|
|
return float64(*valAttr.ST_UnsignedDecimalNumber) / 2
|
|
}
|
|
}
|
|
return 0.0
|
|
}
|
|
|
|
// ComplexSizeMeasure returns font with its measure which can be mm, cm, in, pt, pc or pi.
|
|
func (p ParagraphProperties) ComplexSizeMeasure() string {
|
|
if szCs := p.x.RPr.SzCs; szCs != nil {
|
|
valAttr := szCs.ValAttr
|
|
if valAttr.ST_PositiveUniversalMeasure != nil {
|
|
return *valAttr.ST_PositiveUniversalMeasure
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// Underline returns the type of paragraph underline.
|
|
func (p ParagraphProperties) Underline() wml.ST_Underline {
|
|
if underline := p.x.RPr.U; underline != nil {
|
|
return underline.ValAttr
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// UnderlineColor returns the hex color value of paragraph underline.
|
|
func (p ParagraphProperties) UnderlineColor() string {
|
|
if underline := p.x.RPr.U; underline != nil {
|
|
color := underline.ColorAttr
|
|
if color != nil && color.ST_HexColorRGB != nil {
|
|
return *color.ST_HexColorRGB
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// VerticalAlign returns the value of paragraph vertical align.
|
|
func (p ParagraphProperties) VerticalAlignment() sharedTypes.ST_VerticalAlignRun {
|
|
if vertAlign := p.x.RPr.VertAlign; vertAlign != nil {
|
|
return vertAlign.ValAttr
|
|
}
|
|
return 0
|
|
}
|