Add Notes
A footnote and an endnote are the same construct pointed at two different
places. The note body lives in its own part of the document package, and the
place it is anchored is a run inside a paragraph carrying nothing but a
reference to that body. UniOffice puts each behind a single call on
Paragraph, and the object that call returns is how you add anything past the
first line of text.
| Call | Body part | Styles it creates | Where Word puts the body |
|---|---|---|---|
para.AddFootnote(text) | word/footnotes.xml | FootnoteText, FootnoteReference | Bottom of the page holding the mark |
para.AddEndnote(text) | word/endnotes.xml | EndnoteText, EndnoteReference | End of the document |
Nothing else differs. The two run the same code with different targets, and they keep separate id sequences, so a document can hold footnote 1 and endnote 1 at once. Pick by where you want the reader to look: down the page, or at the back.
Adding a note
doc := document.New()
defer doc.Close()
para := doc.AddParagraph()
para.AddRun().AddText("This paragraph has a footnote.")
fn := para.AddFootnote("This is a footnote.")
fn.AddParagraph().AddRun().AddText("And this is its second paragraph.")
para.AddRun().AddText(" Text after the mark.")
para.AddEndnote("This is an endnote.")
doc.SaveToFile("add_footnote_endnote.docx")The mark is a run appended to the end of the paragraph as it stands when the call is made. That is the whole of the placement control you get: text added before the call sits in front of the mark, text added afterwards sits behind it. There is no call that drops a mark next to a word in a paragraph that is already finished.
The string argument is a convenience. It becomes the last run of the note’s
first paragraph, behind an auto-number run and a space. Everything beyond that
goes through the returned Footnote or Endnote, whose AddParagraph copies
the style of the paragraph before it, so extra paragraphs stay in FootnoteText
or EndnoteText without being told to.
The first note of its kind sets the rest up: it creates the part, registers the content type and relationship, adds the paragraph and character styles at 10 point with a superscript mark, and writes the separator and continuation separator entries Word expects. There is no setup call to make first.
Numbering
You do not set the number a reader sees. AddFootnote assigns the note an id
one past the highest id already in the part, starting at 1, and writes the same
id into the reference run so the two stay connected. The visible number comes
from the auto-number run at the head of the note body, which Word fills from the
order the marks appear in the text.
Ids and printed numbers are therefore two different things, and they part company as soon as marks are added out of order or a note is removed. Treat the id as a handle for finding the note again, not as its number.
Limitations
A note body holds paragraphs. Footnote and Endnote expose Paragraphs,
AddParagraph, RemoveParagraph and X(), and nothing for tables, so a table
inside a note means assembling the schema types through X() yourself.
Footnotes() and Endnotes() dereference the part without checking for it, so
calling either on a document that has no notes panics with a nil pointer.
HasFootnotes() and HasEndnotes() are the guard, and the examples that use
them are not being decorative.
Both slices also include the separator and continuation separator entries, which
are not notes. Their length is two more than the note count, and calling
AddParagraph on one of them panics, because those entries deliberately carry no
paragraph properties for the copy to read.
Run.AddFootnoteReference is not how you place a mark. It writes the
auto-number element used inside a note body; the anchor element carrying the id
is written only by AddFootnote and AddEndnote.
Run the example
The example builds a four-paragraph document with two footnotes and two
endnotes. addFootnote and addEndnote are the parts worth reading: each takes
a slice of strings, hands the first to AddFootnote or AddEndnote, and
appends the rest as further paragraphs on the returned note. Output is
add_footnote_endnote.docx.
git clone https://github.com/unidoc/unioffice-examples.git
cd unioffice-examples/document/endnotes_footnotes_insert
go run main.goIf this is your first time using UniOffice, follow the getting started guide to create an API key and set up your development environment.