title: How to update table of contents in docx-file with python on linux?
body: <p>I've got a problem with <strong>updating</strong> table of contents in docx-file, generated by <em>python-docx</em> on Linux. Generally, it is not difficult to <strong>create</strong> TOC (Thanks for this answer <a href="https://stackoverflow.com/a/48622274/9472173">https://stackoverflow.com/a/48622274/9472173</a> and this thread <a href="https://github.com/python-openxml/python-docx/issues/36" rel="nofollow noreferrer">https://github.com/python-openxml/python-docx/issues/36</a>)</p>
  
  <pre><code>from docx.oxml.ns import qn
  from docx.oxml import OxmlElement
  
  paragraph = self.document.add_paragraph()
  run = paragraph.add_run()
  fldChar = OxmlElement('w:fldChar')  # creates a new element
  fldChar.set(qn('w:fldCharType'), 'begin')  # sets attribute on element
  instrText = OxmlElement('w:instrText')
  instrText.set(qn('xml:space'), 'preserve')  # sets attribute on element
  instrText.text = 'TOC \o "1-3" \h \z \u'   # change 1-3 depending on heading levels you need
  
  fldChar2 = OxmlElement('w:fldChar')
  fldChar2.set(qn('w:fldCharType'), 'separate')
  fldChar3 = OxmlElement('w:t')
  fldChar3.text = "Right-click to update field."
  fldChar2.append(fldChar3)
  
  fldChar4 = OxmlElement('w:fldChar')
  fldChar4.set(qn('w:fldCharType'), 'end')
  
  r_element = run._r
  r_element.append(fldChar)
  r_element.append(instrText)
  r_element.append(fldChar2)
  r_element.append(fldChar4)
  p_element = paragraph._p
  </code></pre>
  
  <p>But later to make TOC visible it requires to update fields. Mentioned bellow solution involves update it <strong>manually</strong> (right-click on TOC hint and choose 'update fields'). For the <strong>automatic</strong> updating, I've found the following solution with word application simulation (thanks to this answer <a href="https://stackoverflow.com/a/34818909/9472173">https://stackoverflow.com/a/34818909/9472173</a>)</p>
  
  <pre><code>import win32com.client
  import inspect, os
  
  def update_toc(docx_file):
      word = win32com.client.DispatchEx("Word.Application")
      doc = word.Documents.Open(docx_file)
      doc.TablesOfContents(1).Update()
      doc.Close(SaveChanges=True)
      word.Quit()
  
  def main():
      script_dir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
      file_name = 'doc_with_toc.docx'
      file_path = os.path.join(script_dir, file_name)
      update_toc(file_path)
  
  if __name__ == "__main__":
      main()
  </code></pre>
  
  <p>It pretty works on Windows, but obviously not on Linux. Have someone any ideas about how to provide the same functionality on Linux. The only one suggestion I have is to use local URLs (anchors) to every heading, but I am not sure is it possible with <em>python-docx</em>, also I'm not very strong with these <em>openxml</em> features. I will very appreciate any help.</p>