[PATCH 7/9] StringList.get_indented(): Support indention by tabs

"Jarret \"Jax\" Renker via Docutils-develop" <[email protected]>
Newsgroups gmane.text.docutils.devel
Message-ID <b6_ZUwrAeN6f6MrahsPZamRKwG11Wc8AmrL9XEzQCIWkKK7AGhmHKci5SpQ_3XLv2nESiB3kpt_quLOdRCTDYAUZT3CGohWzqogq04MEPEY=@proton.me>
Support calculating indention with tabs, e.g. 1 tab = 8 spaces.
---
 docutils/docutils/statemachine.py | 16 +++++++++++-----
 1 file changed, 11 insertions(+), 5 deletions(-)

diff --git a/docutils/docutils/statemachine.py b/docutils/docutils/statemachine.py
index c1f07b57e..681563d19 100644
--- a/docutils/docutils/statemachine.py
+++ b/docutils/docutils/statemachine.py
@@ -1358,7 +1358,7 @@ def get_text_block(self, start, flush_left=False):
         return self[start:end]
 
     def get_indented(self, start=0, until_blank=False, strip_indent=True,
-                     block_indent=None, first_indent=None):
+                     block_indent=None, first_indent=None, tab_width=8):
         """
         Extract and return a StringList of indented lines of text.
 
@@ -1367,12 +1367,17 @@ def get_indented(self, start=0, until_blank=False, strip_indent=True,
         `strip_indent` is false), and return them. All lines up to but not
         including the first unindented line will be returned.
 
+        The indention is calculated for the logical text position.  That is
+        a tab character is `tab_width` spaces wide instead of 1.
+        See `logical_rslice()` for details.
+
         :Parameters:
           - `start`: The index of the first line to examine.
           - `until_blank`: Stop collecting at the first blank line if true.
           - `strip_indent`: Strip common leading indent if true (default).
           - `block_indent`: The indent of the entire block, if known.
           - `first_indent`: The indent of the first line, if known.
+          - `tab_width`: tab stop positions "1 tab = `tab_width` spaces"
 
         :Return:
           - a StringList of indented lines with minimum indent removed;
@@ -1388,7 +1393,7 @@ def get_indented(self, start=0, until_blank=False, strip_indent=True,
         last = len(self.data)
         while end < last:
             line = self.data[end]
-            if line and (line[0] != ' '
+            if line and ((line[0] not in ' \t')
                          or (block_indent is not None
                              and line[:block_indent].strip())):
                 # Line not indented or insufficiently indented.
@@ -1402,7 +1407,8 @@ def get_indented(self, start=0, until_blank=False, strip_indent=True,
                     blank_finish = 1
                     break
             elif block_indent is None:
-                line_indent = len(line) - len(stripped)
+                indent_chars = line[:-len(stripped)]
+                line_indent = len(indent_chars.expandtabs(tab_width))
                 if indent is None:
                     indent = line_indent
                 else:
@@ -1412,9 +1418,9 @@ def get_indented(self, start=0, until_blank=False, strip_indent=True,
             blank_finish = 1            # block ends at end of lines
         block = self[start:end]
         if first_indent is not None and block:
-            block.data[0] = block.data[0][first_indent:]
+            block.data[0] = logical_rslice(block.data[0], first_indent, tab_width)
         if indent and strip_indent:
-            block.trim_left(indent, start=(first_indent is not None))
+            block.trim_left(indent, start=(first_indent is not None), tab_width=tab_width)
         return block, indent or 0, blank_finish
 
     def get_2D_block(self, top, left, bottom, right, strip_indent=True):
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.