Derive from IReplacingCallback in python not possible

Hi there,

I just found out through another thread, that with license that we’ve bought (Aspose.Words for Python) we cannot use IReplacingCallback due to limitations in the Python version.

https://docs.aspose.com/words/python-net/python-notes/

I mainly chose the python version back then when we purchased, because we’re more familiar with python, but did not foresee the necessity to use said callback.

Is there any chance we could exchange our license for the .NET version? As far is I can tell, they’re the same price.

All the best,
Timo

@tjmaul You are right, unfortunately, Aspose.Words for Python does not allow using callbacks yet.

We have opened the following new ticket(s) in our internal issue tracking system and will deliver their fixes according to the terms mentioned in Free Support Policies.

Issue ID(s): WORDSPYTHON-3

You can obtain Paid Support Services if you need support on a priority basis, along with the direct access to our Paid Support management team.

But I think you can achieve what you need without IReplacingCallback. For example, the following code demonstrates how to replace placeholder with an image

phrase_match = "ReplaceMe"
img = "C:\\temp\\test.png"

doc = aw.Document("C:\\Temp\\in.docx")
builder = aw.DocumentBuilder(doc)

# replace the phrase with itself to make it to be represented as a single Run.
doc.range.replace(phrase_match, phrase_match)

# Insert an image after the phrase
for r in doc.get_child_nodes(aw.NodeType.RUN, True):
    run = r.as_run()
    if phrase_match == run.text:
        # put an empty run after the matched Run
        dummy = run.parent_node.insert_after(aw.Run(doc), run)
        builder.move_to(dummy)
        builder.insert_image(img)
        run.text = ""

# Save the document
doc.save("C:\\Temp\\out.docx")

Is there any chance we could exchange our license for the .NET version? As far is I can tell, they’re the same price.

You can contact our sales team in order to exchange the license. You can contact them in Aspose.Purchase forum:
https://forum.aspose.com/c/purchase/6
Here in this forum we can help you with technical questions.

Thank you for your quick response @alexey.noskov! In our case we’d like to search for a regular expression, so that’s probably somewhat harder to do. I posted a topic in the Aspose.Purchase Forum, so let’s see how that goes.

But a follow up question on your code: Suppose I matched a run, how can i determine in which section of the document this run is?

To elaborate this a bit more: In legal contracts it is common to structure them like this

1. Some paragraph 
1.1 Some more legal text
    i) Some bullet that belongs to section 1.1
    ii) Some bullet that also belongs to section 1.1
    iii) Some bullet with a KEYWORD that i'm looking for.

So if I found “KEYWORD”, how can I deduct it’s section hierarchy so I end up with “1.1iii)”

@tjmaul To you mean list items when say sections? If possible, could you please attach your actual input document here for our reference? This will help us to better understand your requirements and provide you a solution.

Hi @alexey.noskov
Sorry, I should have been clearer:

I attached a sample contract that is in both english and german. As an example, search for “any transaction with the Acquirer”, for which you’ll find one single result on page 12.

Note, that this paragraph starts with a). Above that, there is 6.2.

My goal is to end up with the string "6.2.a)" given the serach term "any transaction with the Acquirer", because that where it is located.

I tried to traverse up the node tree and find section indices, but I’m having trouble translating that to the numbering format and getting this to work in general.

Thank you for your help!

GESSI-Exit-Muster-SPA.docx (185.4 KB)

@tjmaul Thank you for additional information. However, structure of your document is quite hard to analyze because data is in table and list items do not belong to the same list, so it is hard to determine the “parent” list item. The following code returns the required values:

doc = aw.Document("C:\\Temp\\in.docx")
# Updale list labels to make them accessible through Paragraph.list_label property.
doc.update_list_labels()

# replace the phrase with itself to make it to be represented as a single Run.
phrase_match = "any transaction with the Acquirer"
doc.range.replace(phrase_match, phrase_match)

# Insert an image after the phrase
for r in doc.get_child_nodes(aw.NodeType.RUN, True):
    run = r.as_run()
    if phrase_match == run.text:
        # Get the parent paragraph of the matched run.
        p = run.get_ancestor(aw.NodeType.PARAGRAPH).as_paragraph()
        if p.is_list_item :
            print(p.list_label.label_string) # print the current paragraph list label
        # get the parent list item
        parent_list_item = p.previous_pre_order(doc)
        while parent_list_item != None :
            if parent_list_item.node_type == aw.NodeType.PARAGRAPH:
                parent_list_item = parent_list_item.as_paragraph()
                if parent_list_item.is_list_item and parent_list_item.list_label.label_string != p.list_label.label_string:
                    break
            parent_list_item = parent_list_item.previous_pre_order(doc)

        if parent_list_item != None :
            print(parent_list_item.list_label.label_string) # print the parent list label

but unfortunately, it will not work for all possible cases.