Skip to content

Run Properties

A run is the smallest span of text that carries uniform character formatting, and RunProperties is where that formatting lives. Writing to it is straightforward. Reading it back off a document somebody else produced is the harder half, because the text you are looking for is not always in the place Paragraphs() and Runs() look.

Doing it

doc, err := document.Open("input.docx")
if err != nil {
    log.Fatalf("error opening document: %s", err)
}
defer doc.Close()

for _, p := range doc.Paragraphs() {
    for _, r := range p.Runs() {
        props := r.Properties()
        fmt.Printf("%q bold=%v italic=%v size=%.1fpt font=%q\n",
            r.Text(), props.IsBold(), props.IsItalic(), props.SizeValue(), props.Font())
    }
}

defer doc.Close() matters here in a way it does not for a document built with document.New(). Open may write temporary files, and Close is what removes them.

Run.Text() concatenates every text element in the run and turns tabs into \t. Breaks, drawings and field characters contribute nothing, so a run holding only a page break returns an empty string.

The getters

GetterReturns
IsBold, IsItalicWhether the run’s own property is on.
Bold, ItalicThe same, but also true when only the complex-script attribute is set.
BoldValue, ItalicValueOnOffValue, which distinguishes unset from off.
Font, EastAsiaFontFont family names.
SizeValue, SizeMeasureFont size in points, and as a formatted string with its unit.
ComplexSizeValue, ComplexSizeMeasureThe same for complex scripts.
GetColor, GetHighlight, GetShadingText color, highlight and background shading.
Underline, UnderlineColorUnderline style and its hex color.
Caps, Strike, DoubleStrike, Outline, Shadow, Emboss, ImprintIndividual effect flags.
RStyleThe character style ID applied to the run, if any.
GetRightToLeftWhether the run is marked right-to-left.

IsBold and Bold are not the same call. IsBold reads only w:b, while Bold returns true if either w:b or w:bCs is set. Documents produced with mixed-script content often set both, so Bold is the safer question to ask.

These getters report only what the run itself carries. Formatting inherited from a paragraph style or from the document defaults does not appear, so props.IsBold() returning false does not mean the text renders upright. To resolve inheritance you have to look the style up in doc.Styles yourself.

What Paragraphs() and Runs() do not reach

Document.Paragraphs() covers the body, table cells, and content wrapped in structured document tags or CustomXml blocks. Paragraph.Runs() descends into hyperlinks and inline structured document tags. Neither reaches headers, footers, footnotes, endnotes, comments, or text inside a drawing.

Text boxes and shapes are the case the example is built around. Word stores them as an mc:AlternateContent block inside a run, which UniOffice keeps in the run’s Extra slice rather than modelling it. Getting at that text means casting each entry to *wml.AlternateContentRun and walking down through the drawing anchor, the graphic data, the wml.WdWsp shape, its text box content and finally the paragraphs and runs inside it. There is no shortcut API for this; the example is the shortcut.

Limitations

The Extra walk is against the raw schema types, so it is sensitive to how the producing application wrote the file. A shape stored as a VML fallback rather than a DrawingML choice will not be found by the same traversal.

Run.Copy() dereferences the run’s properties without checking for nil, so copying a run that has never had a property set panics. Call run.Properties() once first if you need a copy of a bare run.

SetProperties clones the properties it is given rather than sharing them, so applying one run’s formatting to many runs works and later edits to the source run do not propagate.

Run the example

The example opens new_resume_001.docx from its own directory, walks every paragraph and run, and prints the text it finds inside the resume’s text boxes along with the hyperlink text. The nesting in the middle of main is the AlternateContent traversal described above; read it from the *wml.AlternateContentRun cast downward.

git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/document/run-properties
go run main.go

If this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.

View the full source
Last updated on