title: line number spacing in text widget Tkinter
body: <p>I am adding line number feature to the text widget by following Bryan Oakley's code <a href="https://stackoverflow.com/questions/16369470/tkinter-adding-line-number-to-text-widget/16375233#16375233">here</a>. I am inserting my own XML file in that text box. That file is listed below:</p>
  
  <p>myFile.xml</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8" standalone="no" ?&gt;
  
  &lt;p1:sample1 xmlns:p1="http://www.example.org/eHorizon"&gt;
  
     &lt;p1:time nTimestamp="5"&gt;
        &lt;p1:location hours = "1" path = '1'&gt;
           &lt;p1:feature color="6" type="a"&gt;560&lt;/p1:feature&gt;
           &lt;p1:feature color="2" type="a"&gt;564&lt;/p1:feature&gt;
           &lt;p1:feature color="3" type="b"&gt;570&lt;/p1:feature&gt;
           &lt;p1:feature color="4" type="c"&gt;570&lt;/p1:feature&gt;
        &lt;/p1:location&gt;
     &lt;/p1:time&gt;
  
     &lt;p1:time nTimestamp="6"&gt;
        &lt;p1:location hours = "1" path = '1'&gt;
           &lt;p1:feature color="2" type="a"&gt;564&lt;/p1:feature&gt;
           &lt;p1:feature color="3" type="b"&gt;570&lt;/p1:feature&gt;
           &lt;p1:feature color="4" type="c"&gt;570&lt;/p1:feature&gt;
        &lt;/p1:location&gt;
     &lt;/p1:time&gt;
  
  &lt;/p1:sample1&gt;
  </code></pre>
  
  <p>myCode.py</p>
  
  <pre><code>import Tkinter as tk
  
  class TextLineNumbers(tk.Canvas):
      def __init__(self, *args, **kwargs):
          tk.Canvas.__init__(self, *args, **kwargs)
          self.textwidget = None
  
      def attach(self, text_widget):
          self.textwidget = text_widget
  
      def redraw(self, *args):
          '''redraw line numbers'''
          self.delete("all")
  
          i = self.textwidget.index("@0,0")
          while True :
              dline= self.textwidget.dlineinfo(i)
              if dline is None: break
              y = dline[1]
              linenum = str(i).split(".")[0]
              self.create_text(2,y,anchor="nw", text=linenum)
              i = self.textwidget.index("%s+1line" % i)
  
  class CustomText(tk.Text):
      def __init__(self, *args, **kwargs):
          tk.Text.__init__(self, *args, **kwargs)
  
          self.tk.eval('''
              proc widget_proxy {widget widget_command args} {
  
                  # call the real tk widget command with the real args
                  set result [uplevel [linsert $args 0 $widget_command]]
  
                  # generate the event for certain types of commands
                  if {([lindex $args 0] in {insert replace delete}) ||
                      ([lrange $args 0 2] == {mark set insert}) || 
                      ([lrange $args 0 1] == {xview moveto}) ||
                      ([lrange $args 0 1] == {xview scroll}) ||
                      ([lrange $args 0 1] == {yview moveto}) ||
                      ([lrange $args 0 1] == {yview scroll})} {
  
                      event generate  $widget &lt;&lt;Change&gt;&gt; -when tail
                  }
  
                  # return the result from the real widget command
                  return $result
              }
              ''')
          self.tk.eval('''
              rename {widget} _{widget}
              interp alias {{}} ::{widget} {{}} widget_proxy {widget} _{widget}
          '''.format(widget=str(self)))
  
  class Example(tk.Frame):
      def __init__(self, *args, **kwargs):
          tk.Frame.__init__(self, *args, **kwargs)
          self.text = CustomText(self)
          self.vsb = tk.Scrollbar(orient="vertical", command=self.text.yview)
          self.text.configure(yscrollcommand=self.vsb.set)
          self.text.tag_configure("bigfont", font=("Helvetica", "24", "bold"))
          self.linenumbers = TextLineNumbers(self, width=30)
          self.linenumbers.attach(self.text)
  
          self.vsb.pack(side="right", fill="y")
          self.linenumbers.pack(side="left", fill="y")
          self.text.pack(side="right", fill="both", expand=True)
  
          self.text.bind("&lt;&lt;Change&gt;&gt;", self._on_change)
          self.text.bind("&lt;Configure&gt;", self._on_change)
          file = open('C:/your/file/location/myFile.xml')
          self.text.insert("end", file.read())
  
  
      def _on_change(self, event):
          self.linenumbers.redraw()
  
  if __name__ == "__main__":
      root = tk.Tk()
      Example(root).pack(side="top", fill="both", expand=True)
      root.mainloop()
  </code></pre>
  
  <p><strong>What I want:</strong></p>
  
  <p>The result generated on running code looks like this:</p>
  
  <p><a href="https://i.stack.imgur.com/9xGvh.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/9xGvh.png" alt="enter image description here"></a></p>
  
  <p>I have edited this pic using ms-paint to show red markings. Numbering of lines in red is what I want. As it can be seen that numbering on canvas also includes space, I want to modify code in such a manner that there are no line numbers on empty or white spaces.</p>
  
  <p>So there are two objectives I want to achieve:</p>
  
  <p>1). Follow line numbering in a way numbers marked in red are given.</p>
  
  <p>2). After this changes are made if possible I also want to extract the line number from canvas for any given string for that text widget.   </p>
  
  <p><strong>What I tried</strong></p>
  
  <p>I am trying to compare two files and introduce empty lines on places where there are missing points. Before I proceed I need to implement an algorithm which can exclude empty white space from allotting line numbers (which happens with most of the editors). So far I am playing around but cannot find how can I implement this in code above. </p>