Search code examples
pythonpython-docx

Can you use Python-docx to underline part of a paragraph that is on the same run?


I am new to python and new to programming so please forgive my ignorance.

I am using python-docx to automatically format a document as I need it. In our database application we have a good number of forms that are updated periodically in batches. They all follow pretty much the same format and we are given the newly updated document not formatted for our needs.

So I have a couple questions for what I am trying to do: 1) In each document, there is a number such as 5.1 at the beginning of the document. After the number I need to place a tab and then underline the remainder of the paragraph. I cannot figure out, and maybe it is not possible with the way I am looking at it, but I cannot put a tab in a certain spot or figure out how to underline the remaining of the paragraph because there is only a single run only and I cannot find any way to split a single run into two runs. What i have been able to do is to open the document and use pyautogui to move the number of spaces over to the right using pyautogui.press('right') in a loop after counting how many numbers there are in the 1st paragraph. But that is not preferred i think. I thought that maybe i could insert the text into a string, then split the number from the rest of the words, and then use python-docx to remove the old text and then insert the new text with the different formatting(runs). Is that the best way to do this or are there better ways? This is currently how I am performing this task but it does not allow me to bold. I would like to perform the whole task using python-docx so that i am not as dependent using the gui to make the changes

def JITitleNumberLength():
    doc = docx.Document('1ji.docx')
    p0 = doc.paragraphs[0]
    p0Size = len(p0.text) #finds length of title in paragraph 0
    JI_Title = p0.text
    JI_Title_List = list(JI_Title)
    #print(JI_Title_List[2])
    JI_Index_Length = 0 #Returns the amount of numbers in the title of the Jury Instruction
    counter = 0
    while (counter < p0Size) and True:
        #print(JI_Title_List[counter], ' ', JI_Index_Length)
        if (JI_Title_List[counter] == '1' or
        JI_Title_List[counter] == '2' or
        JI_Title_List[counter] == '3' or
        JI_Title_List[counter] == '4' or
        JI_Title_List[counter] == '5' or
        JI_Title_List[counter] == '6' or
        JI_Title_List[counter] == '7' or
        JI_Title_List[counter] == '8' or
        JI_Title_List[counter] == '9' or
        JI_Title_List[counter] == '0' or
        JI_Title_List[counter] == '.'):
            #print('If Statement True')
            JI_Index_Length = JI_Index_Length + 1
        else:
            #print('False')
            False
        counter = counter + 1
    return JI_Index_Length


def OpenDocumentForAutoGUI():
    os.system("start " + '1ji.docx')
    time.sleep(1) #causes delay to allow document to full open before next command runs

def main():
    TitleNumberLength = int(JITitleNumberLength())
    for i in range(TitleNumberLength):
        pyautogui.press('right')
    pyautogui.press(['delete', 'tab']) #removes space and inserts tab between number and instruction name

2) In the middle of a paragraph, there will be different options given in a format of [option 1] [option 2] [option 3]. I would like to create a content control that would give a drop down option of these three options. No where that i have read has there been something to content controls with docx. Is there any way to do this or just manually doing this with pyautogui the only option i have? Basically my thought is that i would search the paragraphs for the brackets [] and then input them into a content control somehow, and if need be, use pyautogui which i prefer to stay away from if possible.

I havent even begun the code for this part yet, my only thought would be to put each option into a list and then recall from the list after using pyautogui to manually move the mouse to click on the developer tab in word and then select the content control as there is no keyboard shortcut to bring in a content control. I would really prefer not to do this because then the screen resolution plays a big part and only specific screen resolutions would work.


Solution

  • Sorry - I am pretty sure that run-level formatting is the most granular that you can get. It should be trivial to add the code to create a second Run in the paragraph and apply an underline style to it.

    No idea on drop-down list boxes

    Two stylistic tips:

    You can use 'in' and the constant string.digits with a concatenation operator to simplify your very long if statement

    if JI_Title_List[counter] in (string.digits+'.') ....
    

    You can use += to say x = x +; e.g. x+=1 is x = x + 1

    counter += 1
    JI_Index_Length +=1