Пример #1
0
        public void TestAddFootnoteRefToParagraph()
        {
            XWPFParagraph p    = docOut.CreateParagraph();
            var           runs = p.Runs;

            Assert.AreEqual(0, runs.Count, "Expected no runs in new paragraph");
            p.AddFootnoteReference(footnote);
            XWPFRun run = p.Runs[0];
            CT_R    ctr = run.GetCTR();

            Assert.IsNotNull(run, "Expected a run");
            CT_FtnEdnRef ref1 = ctr.GetFootnoteReferenceList()[0];

            Assert.IsNotNull(ref1);
            Assert.AreEqual(footnote.Id.ToString(), ref1.id, "Footnote ID and reference ID did not match");
        }
        public void TestFootnoteRender()
        {
            XWPFDocument doc = renderDoc("\\c 1 \\v 1 This is a verse. \\f + \\ft This is a footnote. \\f*");

            // Chapter 1
            Assert.AreEqual("Chapter 1", doc.Paragraphs[0].ParagraphText);
            // Verse 1
            Assert.AreEqual("1", doc.Paragraphs[1].Runs[0].Text);
            // Footnote Reference 1
            CT_FtnEdnRef footnoteRef = (CT_FtnEdnRef)doc.Paragraphs[1].Runs[3].GetCTR().Items[1];

            Assert.AreEqual("1", footnoteRef.id);
            // Footnote Content 1
            XWPFFootnote footnote = doc.GetFootnotes()[0];

            Assert.AreEqual("F1 This is a footnote. ", footnote.Paragraphs[0].ParagraphText);
        }
Пример #3
0
 public XWPFParagraph(CT_P prgrph, IBody part)
 {
     this.paragraph = prgrph;
     this.part      = part;
     this.document  = part.GetXWPFDocument();
     if (this.document == null)
     {
         throw new NullReferenceException();
     }
     this.Runs = new List <XWPFRun>();
     this.BuildRunsInOrderFromXml(this.paragraph.Items);
     foreach (XWPFRun run in this.Runs)
     {
         CT_R ctr = run.GetCTR();
         if (this.document != null)
         {
             foreach (object obj in ctr.Items)
             {
                 if (obj is CT_FtnEdnRef)
                 {
                     CT_FtnEdnRef ctFtnEdnRef = (CT_FtnEdnRef)obj;
                     this.footnoteText.Append("[").Append(ctFtnEdnRef.id).Append(": ");
                     XWPFFootnote xwpfFootnote = this.document.GetFootnoteByID(int.Parse(ctFtnEdnRef.id)) ?? this.document.GetEndnoteByID(int.Parse(ctFtnEdnRef.id));
                     bool         flag         = true;
                     foreach (XWPFParagraph paragraph in (IEnumerable <XWPFParagraph>)xwpfFootnote.Paragraphs)
                     {
                         if (!flag)
                         {
                             this.footnoteText.Append("\n");
                             flag = false;
                         }
                         this.footnoteText.Append(paragraph.GetText());
                     }
                     this.footnoteText.Append("]");
                 }
             }
         }
     }
 }
Пример #4
0
        public XWPFParagraph(CT_P prgrph, IBody part)
        {
            this.paragraph = prgrph;
            this.part      = part;

            this.document = part.GetXWPFDocument();

            if (document == null)
            {
                throw new NullReferenceException();
            }
            // Build up the character runs
            runs = new List <XWPFRun>();

            BuildRunsInOrderFromXml(paragraph.Items);
            // Look for bits associated with the runs
            foreach (XWPFRun run in runs)
            {
                CT_R r = run.GetCTR();
                if (document != null)
                {
                    for (int i = 0; i < r.Items.Count; i++)
                    {
                        object o = r.Items[i];
                        if (o is CT_FtnEdnRef)
                        {
                            CT_FtnEdnRef ftn = (CT_FtnEdnRef)o;
                            footnoteText.Append("[").Append(ftn.id).Append(": ");

                            XWPFFootnote footnote = null;

                            if (r.ItemsElementName.Count > i && r.ItemsElementName[i] == RunItemsChoiceType.endnoteReference)
                            {
                                footnote = document.GetEndnoteByID(int.Parse(ftn.id));
                                if (footnote == null)
                                {
                                    footnote = document.GetFootnoteByID(int.Parse(ftn.id));
                                }
                            }
                            else
                            {
                                footnote = document.GetFootnoteByID(int.Parse(ftn.id));
                                if (footnote == null)
                                {
                                    footnote = document.GetEndnoteByID(int.Parse(ftn.id));
                                }
                            }

                            if (footnote != null)
                            {
                                bool first = true;
                                foreach (XWPFParagraph p in footnote.Paragraphs)
                                {
                                    if (!first)
                                    {
                                        footnoteText.Append("\n");
                                        first = false;
                                    }
                                    footnoteText.Append(p.Text);
                                }
                            }

                            footnoteText.Append("]");
                        }
                    }
                }
            }

            // Get all our child nodes in order, and process them
            //  into XWPFRuns where we can

            /*XmlCursor c = paragraph.NewCursor();
             * c.SelectPath("child::*");
             * while (c.ToNextSelection()) {
             * XmlObject o = c.Object;
             * if(o is CT_R) {
             *    Runs.Add(new XWPFRun((CT_R)o, this));
             * }
             * if(o is CT_Hyperlink) {
             *    CT_Hyperlink link = (CT_Hyperlink)o;
             *    foreach(CTR r in link.RList) {
             *       Runs.Add(new XWPFHyperlinkRun(link, r, this));
             *    }
             * }
             * if(o is CT_SdtRun) {
             *    CT_SdtContentRun run = ((CT_SdtRun)o).SdtContent;
             *    foreach(CTR r in Run.RList) {
             *       Runs.Add(new XWPFRun(r, this));
             *    }
             * }
             * if(o is CT_RunTrackChange) {
             *    foreach(CTR r in ((CT_RunTrackChange)o).RList) {
             *       Runs.Add(new XWPFRun(r, this));
             *    }
             * }
             * if(o is CT_SimpleField) {
             *    foreach(CTR r in ((CT_SimpleField)o).RList) {
             *       Runs.Add(new XWPFRun(r, this));
             *    }
             * }
             * }*/
        }
        private void RenderMarker(Marker input, StyleConfig styles, XWPFParagraph parentParagraph = null)
        {
            // Keep track of the previous marker
            previousMarker = thisMarker;
            thisMarker     = input;

            StyleConfig markerStyle = (StyleConfig)styles.Clone();

            switch (input)
            {
            case PMarker _:

                XWPFParagraph paragraph = parentParagraph;
                // If the previous marker was a chapter marker, don't create a new paragraph.
                if (!(previousMarker is CMarker _))
                {
                    XWPFParagraph newParagraph = newDoc.CreateParagraph(markerStyle, configDocx);
                    newParagraph.SetBidi(configDocx.rightToLeft);
                    newParagraph.Alignment      = configDocx.textAlign;
                    newParagraph.SpacingBetween = configDocx.lineSpacing;
                    newParagraph.SpacingAfter   = 200;
                    paragraph = newParagraph;
                }

                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, paragraph);
                }
                break;

            case CLMarker clMarker:
                if (beforeFirstChapter)
                {
                    // A CL before the first chapter means that we should use
                    // this string instead of the word "Chapter".
                    chapterLabel = clMarker.Label;
                }
                break;

            case CMarker cMarker:

                if (beforeFirstChapter)
                {
                    // We found the first chapter, so set the flag to false.
                    beforeFirstChapter = false;
                }
                else
                {
                    if (configDocx.separateChapters)
                    {
                        // Add page break between chapters.
                        newDoc.CreateParagraph().CreateRun().AddBreak(BreakType.PAGE);
                    }
                }

                createBookHeaders(previousBookHeader);

                XWPFParagraph newChapter = newDoc.CreateParagraph(markerStyle, configDocx);
                newChapter.SetBidi(configDocx.rightToLeft);
                newChapter.Alignment      = configDocx.textAlign;
                newChapter.SpacingBetween = configDocx.lineSpacing;
                newChapter.SpacingBefore  = 200;
                newChapter.SpacingAfter   = 200;
                XWPFRun chapterMarker = newChapter.CreateRun(markerStyle);
                setRTL(chapterMarker);
                string simpleNumber = cMarker.Number.ToString();
                if (cMarker.CustomChapterLabel != simpleNumber)
                {
                    // Use the custom label for this section, e.g. "Psalm One" instead of "Chapter 1"
                    currentChapterLabel = cMarker.CustomChapterLabel;
                }
                else
                {
                    // Use the default chapter text for this section, e.g. "Chapter 1"
                    currentChapterLabel = chapterLabel + " " + simpleNumber;
                }
                chapterMarker.SetText(currentChapterLabel);
                chapterMarker.FontSize = (int)(configDocx.fontSize * 1.5);

                XWPFParagraph chapterVerses = newDoc.CreateParagraph(markerStyle, configDocx);
                chapterVerses.SetBidi(configDocx.rightToLeft);
                chapterVerses.Alignment      = configDocx.textAlign;
                chapterVerses.SpacingBetween = configDocx.lineSpacing;
                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, chapterVerses);
                }

                RenderCrossReferences(markerStyle);

                break;

            case VMarker vMarker:

                // If there is no parent paragraph, then we're maybe
                // missing a chapter marker prior to this verse.  Let's
                // create a stub parent paragraph so we can keep rendering.
                if (parentParagraph == null)
                {
                    parentParagraph = newDoc.CreateParagraph(markerStyle, configDocx);
                    parentParagraph.SetBidi(configDocx.rightToLeft);
                    parentParagraph.Alignment      = configDocx.textAlign;
                    parentParagraph.SpacingBetween = configDocx.lineSpacing;
                    parentParagraph.SpacingAfter   = 200;
                }

                if (configDocx.separateVerses)
                {
                    XWPFRun newLine = parentParagraph.CreateRun();
                    newLine.AddBreak(BreakType.TEXTWRAPPING);
                }

                markerStyle.fontSize = configDocx.fontSize;
                XWPFRun verseMarker = parentParagraph.CreateRun(markerStyle);
                setRTL(verseMarker);
                verseMarker.SetText(vMarker.VerseCharacter);
                verseMarker.Subscript = VerticalAlign.SUPERSCRIPT;
                AppendSpace(parentParagraph);

                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                if (parentParagraph.Text.EndsWith(" ") == false)
                {
                    AppendSpace(parentParagraph);
                }
                break;

            case QMarker qMarker:
                markerStyle.fontSize = configDocx.fontSize;
                XWPFParagraph poetryParagraph = newDoc.CreateParagraph(markerStyle, configDocx);
                poetryParagraph.SetBidi(configDocx.rightToLeft);
                poetryParagraph.Alignment        = configDocx.textAlign;
                poetryParagraph.SpacingBetween   = configDocx.lineSpacing;
                poetryParagraph.IndentationLeft += qMarker.Depth * 500;
                poetryParagraph.SpacingAfter     = 200;

                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, poetryParagraph);
                }
                break;

            case MMarker mMarker:
                break;

            case TextBlock textBlock:
                markerStyle.fontSize = configDocx.fontSize;
                XWPFRun blockText = parentParagraph.CreateRun(markerStyle);
                setRTL(blockText);
                blockText.SetText(textBlock.Text);
                break;

            case BDMarker bdMarker:
                markerStyle.isBold = true;
                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                break;

            case HMarker hMarker:

                // Add section header for previous book, if any
                // (section page headers are set at the final paragraph of the section)
                if (previousBookHeader != null)
                {
                    // Create new section and page header
                    createBookHeaders(previousBookHeader);
                    // Print page break
                    XWPFParagraph sectionParagraph = newDoc.CreateParagraph();
                    sectionParagraph.SetBidi(configDocx.rightToLeft);
                    sectionParagraph.Alignment = configDocx.textAlign;
                    sectionParagraph.CreateRun().AddBreak(BreakType.PAGE);
                }
                previousBookHeader = hMarker.HeaderText;

                // Write body header text
                markerStyle.fontSize = (configDocx.fontSize * 2);
                XWPFParagraph newHeader = newDoc.CreateParagraph(markerStyle, configDocx);
                newHeader.Style = "Heading1";     // for TOC pagination

                newHeader.SetBidi(configDocx.rightToLeft);
                newHeader.SpacingAfter = 200;
                XWPFRun headerTitle = newHeader.CreateRun(markerStyle);
                setRTL(headerTitle);
                headerTitle.SetText(hMarker.HeaderText);

                break;

            case FMarker fMarker:
                string footnoteId;
                footnoteId = nextFootnoteNum.ToString();
                nextFootnoteNum++;

                CT_FtnEdn footnote = new CT_FtnEdn();
                footnote.id   = footnoteId;
                footnote.type = ST_FtnEdn.normal;
                StyleConfig footnoteMarkerStyle = (StyleConfig)styles.Clone();
                footnoteMarkerStyle.fontSize = 12;
                CT_P          footnoteParagraph  = footnote.AddNewP();
                XWPFParagraph xFootnoteParagraph = new XWPFParagraph(footnoteParagraph, parentParagraph.Body);
                xFootnoteParagraph.SetBidi(configDocx.rightToLeft);
                footnoteParagraph.AddNewR().AddNewT().Value = "F" + footnoteId.ToString() + " ";
                foreach (Marker marker in fMarker.Contents)
                {
                    RenderMarker(marker, footnoteMarkerStyle, xFootnoteParagraph);
                }
                parentParagraph.Document.AddFootnote(footnote);

                XWPFRun footnoteReferenceRun = parentParagraph.CreateRun();
                setRTL(footnoteReferenceRun);
                CT_RPr rpr = footnoteReferenceRun.GetCTR().AddNewRPr();
                rpr.rStyle     = new CT_String();
                rpr.rStyle.val = "FootnoteReference";
                CT_FtnEdnRef footnoteReference = new CT_FtnEdnRef();
                footnoteReference.id        = footnoteId;
                footnoteReference.isEndnote = false;
                footnoteReferenceRun.SetUnderline(UnderlinePatterns.Single);
                footnoteReferenceRun.AppendText("F");
                footnoteReferenceRun.GetCTR().Items.Add(footnoteReference);
                break;

            case FPMarker fPMarker:
                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                break;

            case FTMarker fTMarker:

                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                break;

            case FRMarker fRMarker:
                markerStyle.isBold = true;
                XWPFRun VerseReference = parentParagraph.CreateRun(markerStyle);
                setRTL(VerseReference);
                VerseReference.SetText(fRMarker.VerseReference);
                break;

            case FKMarker fKMarker:
                XWPFRun FootNoteKeyword = parentParagraph.CreateRun(markerStyle);
                setRTL(FootNoteKeyword);
                FootNoteKeyword.SetText($" {fKMarker.FootNoteKeyword.ToUpper()}: ");
                break;

            case FQMarker fQMarker:
            case FQAMarker fQAMarker:
                markerStyle.isItalics = true;
                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                break;

            // Cross References
            case XMarker xMarker:
                string crossId;
                switch (xMarker.CrossRefCaller)
                {
                case "-":
                    crossId = "";
                    break;

                case "+":
                    crossId = $"{CrossRefMarkers.Count + 1}";
                    break;

                default:
                    crossId = xMarker.CrossRefCaller;
                    break;
                }
                XWPFRun crossRefMarker = parentParagraph.CreateRun(markerStyle);
                setRTL(crossRefMarker);
                crossRefMarker.SetText(crossId);
                crossRefMarker.Subscript = VerticalAlign.SUPERSCRIPT;

                CrossRefMarkers[crossId] = xMarker;
                break;

            case XOMarker xOMarker:
                markerStyle.isBold = true;
                XWPFRun CrossVerseReference = parentParagraph.CreateRun(markerStyle);
                setRTL(CrossVerseReference);
                CrossVerseReference.SetText($" {xOMarker.OriginRef} ");
                break;

            case XTMarker xTMarker:
                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                break;

            case XQMarker xQMarker:
                markerStyle.isItalics = true;
                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, parentParagraph);
                }
                break;

            // Table Markers
            case TableBlock table:
                XWPFTable tableContainer = newDoc.CreateTable();

                // Clear Borders
                tableContainer.SetBottomBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "#FFFFFFF");
                tableContainer.SetLeftBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "#FFFFFFF");
                tableContainer.SetRightBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "#FFFFFFF");
                tableContainer.SetTopBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "#FFFFFFF");
                // Clear Inside Borders
                tableContainer.SetInsideHBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "#FFFFFFF");
                tableContainer.SetInsideVBorder(XWPFTable.XWPFBorderType.NONE, 0, 0, "#FFFFFFF");

                foreach (Marker marker in input.Contents)
                {
                    getRenderedRows(marker, markerStyle, tableContainer);
                }
                break;

            case BMarker bMarker:
                XWPFRun newLineBreak = parentParagraph.CreateRun();
                setRTL(newLineBreak);
                newLineBreak.AddBreak(BreakType.TEXTWRAPPING);
                break;

            case IDMarker _:
                // This is the start of a new book.
                beforeFirstChapter  = true;
                chapterLabel        = chapterLabelDefault;
                currentChapterLabel = "";
                break;

            case IPMarker _:
                XWPFParagraph introParagraph = parentParagraph;
                // If the previous marker was a chapter marker, don't create a new paragraph.
                if (!(previousMarker is CMarker _))
                {
                    XWPFParagraph newParagraph = newDoc.CreateParagraph(markerStyle, configDocx);
                    newParagraph.SetBidi(configDocx.rightToLeft);
                    newParagraph.Alignment      = configDocx.textAlign;
                    newParagraph.SpacingBetween = configDocx.lineSpacing;
                    newParagraph.SpacingAfter   = 200;
                    introParagraph = newParagraph;
                }

                foreach (Marker marker in input.Contents)
                {
                    RenderMarker(marker, markerStyle, introParagraph);
                }
                break;

            case XEndMarker _:
            case FEndMarker _:
            case IDEMarker _:
            case VPMarker _:
            case VPEndMarker _:
                break;

            default:
                UnrenderableMarkers.Add(input.Identifier);
                break;
            }
        }
Пример #6
0
        /**
         * Returns the string version of the text, with tabs and
         *  carriage returns in place of their xml equivalents.
         */
        public override String ToString()
        {
            StringBuilder text = new StringBuilder();

            for (int i = 0; i < run.Items.Count; i++)
            {
                object o = run.Items[i];
                if (o is CT_Text)
                {
                    if (!(run.ItemsElementName[i] == RunItemsChoiceType.instrText))
                    {
                        text.Append(((CT_Text)o).Value);
                    }
                }

                if (o is CT_PTab)
                {
                    text.Append("\t");
                }
                if (o is CT_Br)
                {
                    text.Append("\n");
                }
                if (o is CT_Empty)
                {
                    // Some inline text elements Get returned not as
                    //  themselves, but as CTEmpty, owing to some odd
                    //  defInitions around line 5642 of the XSDs
                    // This bit works around it, and replicates the above
                    //  rules for that case
                    if (run.ItemsElementName[i] == RunItemsChoiceType.tab)
                    {
                        text.Append("\t");
                    }
                    if (run.ItemsElementName[i] == RunItemsChoiceType.br)
                    {
                        text.Append("\n");
                    }
                    if (run.ItemsElementName[i] == RunItemsChoiceType.cr)
                    {
                        text.Append("\n");
                    }
                }

                if (o is CT_FtnEdnRef)
                {
                    CT_FtnEdnRef ftn         = (CT_FtnEdnRef)o;
                    String       footnoteRef = ftn.DomNode.LocalName.Equals("footnoteReference") ?
                                               "[footnoteRef:" + ftn.id + "]" : "[endnoteRef:" + ftn.id + "]";
                    text.Append(footnoteRef);
                }
            }

            // Any picture text?
            if (pictureText != null && pictureText.Length > 0)
            {
                text.Append("\n").Append(pictureText);
            }

            return(text.ToString());
        }
Пример #7
0
        public XWPFParagraph(CT_P prgrph, IBody part)
        {
            this.paragraph = prgrph;
            this.part      = part;

            this.document = part.GetXWPFDocument();

            if (document == null)
            {
                throw new NullReferenceException();
            }
            // Build up the character runs
            runs  = new List <XWPFRun>();
            iRuns = new List <IRunElement>();

            BuildRunsInOrderFromXml(paragraph.Items);
            // Look for bits associated with the runs
            foreach (XWPFRun run in runs)
            {
                CT_R r = run.GetCTR();
                if (document != null)
                {
                    for (int i = 0; i < r.Items.Count; i++)
                    {
                        object o = r.Items[i];
                        if (o is CT_FtnEdnRef)
                        {
                            CT_FtnEdnRef ftn = (CT_FtnEdnRef)o;
                            footnoteText.Append("[").Append(ftn.id).Append(": ");

                            XWPFFootnote footnote = null;

                            if (r.ItemsElementName.Count > i && r.ItemsElementName[i] == RunItemsChoiceType.endnoteReference)
                            {
                                footnote = document.GetEndnoteByID(int.Parse(ftn.id));
                                if (footnote == null)
                                {
                                    footnote = document.GetFootnoteByID(int.Parse(ftn.id));
                                }
                            }
                            else
                            {
                                footnote = document.GetFootnoteByID(int.Parse(ftn.id));
                                if (footnote == null)
                                {
                                    footnote = document.GetEndnoteByID(int.Parse(ftn.id));
                                }
                            }

                            if (footnote != null)
                            {
                                bool first = true;
                                foreach (XWPFParagraph p in footnote.Paragraphs)
                                {
                                    if (!first)
                                    {
                                        footnoteText.Append("\n");
                                        first = false;
                                    }
                                    footnoteText.Append(p.Text);
                                }
                            }

                            footnoteText.Append("]");
                        }
                    }
                }
            }
        }
Пример #8
0
        /**
         * Returns the string version of the text, with tabs and
         *  carriage returns in place of their xml equivalents.
         */
        public override String ToString()
        {
            StringBuilder text = new StringBuilder();

            for (int i = 0; i < run.Items.Count; i++)
            {
                object o = run.Items[i];
                if (o is CT_Text)
                {
                    if (!(run.ItemsElementName[i] == RunItemsChoiceType.instrText))
                    {
                        text.Append(((CT_Text)o).Value);
                    }
                }
                // Complex type evaluation (currently only for extraction of check boxes)
                if (o is CT_FldChar)
                {
                    CT_FldChar ctfldChar = ((CT_FldChar)o);
                    if (ctfldChar.fldCharType == ST_FldCharType.begin)
                    {
                        if (ctfldChar.ffData != null)
                        {
                            foreach (CT_FFCheckBox checkBox in ctfldChar.ffData.GetCheckBoxList())
                            {
                                if ([email protected] == true)
                                {
                                    text.Append("|X|");
                                }
                                else
                                {
                                    text.Append("|_|");
                                }
                            }
                        }
                    }
                }
                if (o is CT_PTab)
                {
                    text.Append("\t");
                }
                if (o is CT_Br)
                {
                    text.Append("\n");
                }
                if (o is CT_Empty)
                {
                    // Some inline text elements Get returned not as
                    //  themselves, but as CTEmpty, owing to some odd
                    //  defInitions around line 5642 of the XSDs
                    // This bit works around it, and replicates the above
                    //  rules for that case
                    if (run.ItemsElementName[i] == RunItemsChoiceType.tab)
                    {
                        text.Append("\t");
                    }
                    if (run.ItemsElementName[i] == RunItemsChoiceType.br)
                    {
                        text.Append("\n");
                    }
                    if (run.ItemsElementName[i] == RunItemsChoiceType.cr)
                    {
                        text.Append("\n");
                    }
                }

                if (o is CT_FtnEdnRef)
                {
                    CT_FtnEdnRef ftn         = (CT_FtnEdnRef)o;
                    String       footnoteRef = ftn.DomNode.LocalName.Equals("footnoteReference") ?
                                               "[footnoteRef:" + ftn.id + "]" : "[endnoteRef:" + ftn.id + "]";
                    text.Append(footnoteRef);
                }
            }

            // Any picture text?
            if (pictureText != null && pictureText.Length > 0)
            {
                text.Append("\n").Append(pictureText);
            }

            return(text.ToString());
        }