Help hyperlink

Good morning - I’ve got a question for you. I’m using aspose.world dll, and i’d like to have an hyperlink on a specific position within my document. I’ve tried to use the DocumentBuilder.InsertHyperlink method, but unfortunately this method only adds the object at the top of my document. How can i have my link on a specific position?
This message was posted using Aspose.Live 2 Forum

Hello

Thanks for your request. I think in this case you can put a bookmark to your document at place where you would like to see the hyperlink. From the code you can use documentBuilder.MoveToBookmark(“BookMarkName”) and insert Hyperlink there.
Hope this helps.
Best regards,

Thank you for the reply. I try this solution!

Best regards
Ivan

No changes, i put this code:

builder.StartBookmark("FineBookmark")
builder.EndBookmark("FineBookmark")
builder.MoveToBookmark("FineBookmark")
builder.InsertHyperlink(Me.PTag2New, "http://www.google.com", False)

but the hyperlink was write on top yet.

Hello

Thanks for your request. Could you please attach your input and expected output document here for testing? I will investigate it on my side and provide you more information.
Best regards,

Yes of course, this is the test document.
I would that the program will replace a web link instead the tag #number#, here and not at the top of the document

Hi
Thank you for additional information. I create a simple code example that demonstrates the technique how to achieve what you need:

Document doc = new Document("C:\\Temp\\test.doc");
doc.Range.Replace(new Regex(@"#number#"), new ReplaceEvaluatorFindAndInsertHyperlink(@"http:\\aspose.com"), false);
doc.Save("C:\\Temp\\out.doc");
private class ReplaceEvaluatorFindAndInsertHyperlink: IReplacingCallback
{
    public ReplaceEvaluatorFindAndInsertHyperlink(string text)
    {
        mText = text;
    }
    ///
    /// This method is called by the Aspose.Words find and replace engine for each match.
    /// This method replaces the match string, even if it spans multiple runs.
    ///
    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 removing.
        ArrayList runs = new ArrayList();
        // 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(currentNode);
            remainingLength = 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(currentNode);
        }
        // Create Document Buidler aond insert text
        DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Document);
        builder.MoveTo((Run) runs[runs.Count - 1]);
        builder.Font.StyleIdentifier = StyleIdentifier.Hyperlink;
        builder.InsertHyperlink(mText, mText, false);
        // Now remove all runs in the sequence.
        foreach(Run run in runs)
        run.Remove();
        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.Skip;
    }
    ///
    /// Splits text of the specified run into two runs.
    /// Inserts the new run just after the specified run.
    ///
    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run) run.Clone(true);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring(0, position);
        run.ParentNode.InsertAfter(afterRun, run);
        return afterRun;
    }
    private string mText;
}

Hope this helps.
Best regards,

Hi,

I couldn’t understand very well how that piece of code works, but it does work! I spent some time translating that piece of code to vb.net (now I’m using that language), and now it works as expected. Thanks for your useful advice!!!

Ivan

Hi Ivan,
It’s great that it’s working. In the future if you require any code from the forums translated to VB.NET for you please ask us, we will be gladd to assist.
Thanks,

Hi,

today when I do some test I find a issue. The code above insert an hyperlink but not in the correct mode.
If I need to insert an Hyperlink with “engine” as text and “www.google.com” as link it insert:

file:///C:\www.google.it

What Did I do wrong?

Hello

Thanks for your inquiry. I have changed the code little bit. Please see the code bellow:

Document doc = new Document("C:\\Temp\\in.doc");
doc.Range.Replace(new Regex(@"#number#"), new ReplaceEvaluatorFindAndInsertHyperlink("engine", @"http:\\google.com.ua"), false);
doc.Save("C:\\Temp\\out.doc");
private class ReplaceEvaluatorFindAndInsertHyperlink: IReplacingCallback
{
    public ReplaceEvaluatorFindAndInsertHyperlink(string text, string link)
    {
        mText = text;
        mLink = link;
    }
    ///
    /// This method is called by the Aspose.Words find and replace engine for each match.
    /// This method replaces the match string, even if it spans multiple runs.
    ///
    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 removing.
        ArrayList runs = new ArrayList();
        // 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(currentNode);
            remainingLength = 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(currentNode);
        }
        // Create Document Buidler aond insert text
        DocumentBuilder builder = new DocumentBuilder(e.MatchNode.Document as Document);
        builder.MoveTo((Run) runs[runs.Count - 1]);
        builder.Font.StyleIdentifier = StyleIdentifier.Hyperlink;
        builder.InsertHyperlink(mText, mLink, false);
        // Now remove all runs in the sequence.
        foreach(Run run in runs)
        run.Remove();
        // Signal to the replace engine to do nothing because we have already done all what we wanted.
        return ReplaceAction.Skip;
    }
    ///
    /// Splits text of the specified run into two runs.
    /// Inserts the new run just after the specified run.
    ///
    private static Run SplitRun(Run run, int position)
    {
        Run afterRun = (Run) run.Clone(true);
        afterRun.Text = run.Text.Substring(position);
        run.Text = run.Text.Substring(0, position);
        run.ParentNode.InsertAfter(afterRun, run);
        return afterRun;
    }
    private string mText;
    private string mLink;
}

Best regards,

Hi Andrey,

this was what I did after your first reply, I edited the code exactly like you write now but the result is:

“engine” as text and "file:///C:\http://www.google.com" as link

Ivan

EDIT: the problem wasn’t in the code, the problem was that in test i writed "http://www.google.com" and not "http://www.google.com", is a word fault.

Thank you!

Ivan

Hello

Thanks for your request. I cannot reproduce the problem on my side using the code from my previous post and the latest version of Aspose.Words (9.7.0) for testing.
You can download the latest version from here:
https://releases.aspose.com/words/net
Could you please try using the latest version of Aspose.Words and let me know how it goes on your side.
Also please see the attached input and output documents.
Best regards,