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); }
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("]"); } } } } }
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; } }
/** * 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()); }
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("]"); } } } } }
/** * 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()); }