Inserting a footnote marker in the middle of a paragraph

Hi,

I need to insert a footnote in the middle of a paragraph to have something looking like this:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis venenatis1, eros sed ullamcorper varius, odio diam sollicitudin purus, in
ultricies.

Right now, I’m using the following code which adds the footnote marker at the end of the paragraph:

footnote = new Footnote( doc, FootnoteType.Footnote );
footnote.Paragraphs.Add( new Paragraph( doc ) );
footnote.FirstParagraph.Runs.Add( new Run( doc, “some text” );
para.AppendChild( footnote );

Result:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis venenatis, eros sed ullamcorper varius, odio diam sollicitudin purus, in
ultricies.1

Is there a way to do this via Aspose.Words?

Hi,

Thanks for your inquiry. Could you please attach the following Word documents here for reference?

Input document: The document you want to insert Footnote in.
Target document: The document showing the desired behaviour. You can manually create it using Microsoft Word. I just need to learn as to how you want your final document to be generated like.

I will then investigate the problem on my side and provide you code to achieve this.

Best regards,

Hi,

Here are the documents.

Please note that the “Input document” is constructed on-the-fly based on paragraphs available in a database.

Some paragraphs may contain footnotes (like the 3rd one in the sample) which use the following format “<NOTE:Some text>”. This tag should be replaced by a footnote containing “Some text”.

At the time of posting my question, I created the whole document “manually” but after reading other posts and digging deeper in the help, I switched to the document builder which greatly facilitate the work (first project using Aspose.Words :slight_smile: ). I can now insert the footnote where I need using text splitting / the Write and InsertFootnote functions.

Anyway, is there another way to specify the position of the footnote in a paragraph?

Hi,

Thanks for the additional information. Please try running the following code to achieve what you’re looking for:

Document doc = new
Document(@“C:\Temp\Input+document.doc”);
doc.Range.Replace(new Regex(""), new ReplaceHandler(), false);
doc.Save(@"C:\Temp\out.doc");
private class ReplaceHandler : IReplacingCallback
{
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        Footnote footnote = new Footnote(e.MatchNode.Document, FootnoteType.Footnote);
        e.MatchNode.ParentNode.InsertBefore(footnote, e.MatchNode);

        footnote.Paragraphs.Add(new Paragraph(e.MatchNode.Document));
        footnote.FirstParagraph.Runs.Add(new Run(e.MatchNode.Document, "This is a test footnote."));

        return ReplaceAction.Replace;
    }
}

I hope, this helps.

Best regards,

Hi,

Thanks for the code and your help. It helped in another situation I had to handle.

For the footnote I sticked to the DocumentBuilder solution since the its content is variable and the implemented solution is working fine now (although I may review it at a later time).

Hi,


Sure, in case you have further inquires or need any help, please let us know.

Best regards,

A post was split to a new topic: How can we change the font size of footnote using Aspose.Words

@awais.hafeez: I want to perform same operation.
Can you please explain me how this required behavior achieved using ReplaceHandler?

Thanks
Snehal

@snehalghute The following code demonstrates how to insert a footnote after the word "test" in the document using IReplacingCallback:

Document doc = new Document(@"C:\Temp\in.docx");

// The following code will insert footnote at "test" word in the document.
FindReplaceOptions opt = new FindReplaceOptions();
opt.ReplacingCallback = new ReplaceEvaluatorFindAndInsertFootnote();
doc.Range.Replace("test", "", opt);

doc.Save(@"C:\Temp\out.docx");
internal class ReplaceEvaluatorFindAndInsertFootnote : IReplacingCallback
{
    /// <summary>
    /// This method is called by the Aspose.Words find and replace engine for each match.
    /// </summary>
    ReplaceAction IReplacingCallback.Replacing(ReplacingArgs e)
    {
        // This is a Run node that contains either the beginning or the complete match.
        Node currentNode = e.MatchNode;

        // The first (and may be the only) run can contain text before the match, 
        // in this case it is necessary to split the run.
        if (e.MatchOffset > 0)
            currentNode = SplitRun((Run)currentNode, e.MatchOffset);

        // This array is used to store all nodes of the match for further deleting.
        List<Run> runs = new List<Run>();

        // Find all runs that contain parts of the match string.
        int remainingLength = e.Match.Value.Length;
        while (
            remainingLength > 0 &&
            currentNode != null &&
            currentNode.GetText().Length <= remainingLength)
        {
            runs.Add((Run)currentNode);
            remainingLength -= currentNode.GetText().Length;

            // Select the next Run node.
            // Have to loop because there could be other nodes such as BookmarkStart etc.
            do
            {
                currentNode = currentNode.NextSibling;
            } while (currentNode != null && currentNode.NodeType != NodeType.Run);
        }

        // Split the last run that contains the match if there is any text left.
        if (currentNode != null && remainingLength > 0)
        {
            SplitRun((Run)currentNode, remainingLength);
            runs.Add((Run)currentNode);
        }

        // Create DocumentBuilder to insert a field.
        DocumentBuilder builder = new DocumentBuilder((Document)e.MatchNode.Document);
        // Move builder to the first run.
        builder.MoveTo(runs[0]);
        // Insert footnote
        Aspose.Words.Notes.Footnote note = builder.InsertFootnote(Aspose.Words.Notes.FootnoteType.Footnote, "This is footnote text");
        // Move footnote after the matched text.
        Run lastRun = runs[runs.Count - 1];
        lastRun.ParentNode.InsertAfter(note, lastRun);

        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.Skip;
    }

    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run)run.Clone(true);
        run.ParentNode.InsertAfter(afterRun, run);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring((0), (0) + (position));
        return afterRun;
    }
}

Please see our documentation to learn more about footnotes and find/replace functionality:
https://docs.aspose.com/words/net/working-with-footnote-and-endnote/
https://docs.aspose.com/words/net/find-and-replace/