]> granicus.if.org Git - python/commitdiff
Code by Mark Hammond to format paragraphs embedded in comments.
authorGuido van Rossum <guido@python.org>
Thu, 10 Jun 1999 17:48:02 +0000 (17:48 +0000)
committerGuido van Rossum <guido@python.org>
Thu, 10 Jun 1999 17:48:02 +0000 (17:48 +0000)
Read the comments (which I reformatted using the new feature :-)
for some limitations.

Tools/idle/FormatParagraph.py

index e17f54c51e613bdb3b79b68c5e758ff22df52e72..6d2d47573f5f5b96c70490fae06edc129370f77e 100644 (file)
@@ -1,5 +1,19 @@
 # Extension to format a paragraph
 
+# Does basic, standard text formatting, and also understands Python
+# comment blocks.  Thus, for editing Python source code, this
+# extension is really only suitable for reformatting these comment
+# blocks or triple-quoted strings.
+
+# Known problems with comment reformatting:
+# * If there is a selection marked, and the first line of the
+#   selection is not complete, the block will probably not be detected
+#   as comments, and will have the normal "text formatting" rules
+#   applied.
+# * If a comment block has leading whitespace that mixes tabs and
+#   spaces, they will not be considered part of the same block.
+# * Fancy comments, like this bulleted list, arent handled :-)
+
 import string
 import re
 
@@ -24,16 +38,37 @@ class FormatParagraph:
 
     def format_paragraph_event(self, event):
         text = self.editwin.text
-        try:
-            first = text.index("sel.first")
-            last = text.index("sel.last")
-        except TclError:
-            first = last = None
+        first, last = self.editwin.get_selection_index()
         if first and last:
             data = text.get(first, last)
+            comment_header = ''
         else:
-            first, last, data = find_paragraph(text, text.index("insert"))
-        newdata = reformat_paragraph(data)
+            first, last, comment_header, data = \
+                    find_paragraph(text, text.index("insert"))
+        if comment_header:
+            # Reformat the comment lines - convert to text sans header.
+            lines = string.split(data, "\n")
+            lines = map(lambda st, l=len(comment_header): st[l:], lines)
+            data = string.join(lines, "\n")
+            # Reformat to 70 chars or a 20 char width, whichever is greater.
+            format_width = max(70-len(comment_header), 20)
+            newdata = reformat_paragraph(data, format_width)
+            # re-split and re-insert the comment header.
+            newdata = string.split(newdata, "\n")
+            # If the block ends in a \n, we dont want the comment
+            # prefix inserted after it. (Im not sure it makes sense to
+            # reformat a comment block that isnt made of complete
+            # lines, but whatever!)  Can't think of a clean soltution,
+            # so we hack away
+            block_suffix = ""
+            if not newdata[-1]:
+                block_suffix = "\n"
+                newdata = newdata[:-1]
+            builder = lambda item, prefix=comment_header: prefix+item
+            newdata = string.join(map(builder, newdata), '\n') + block_suffix
+        else:
+            # Just a normal text format
+            newdata = reformat_paragraph(data)
         text.tag_remove("sel", "1.0", "end")
         if newdata != data:
             text.mark_set("insert", first)
@@ -52,18 +87,23 @@ def find_paragraph(text, mark):
         lineno = lineno + 1
         line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
     first_lineno = lineno
-    while not is_all_white(line):
+    comment_header = get_comment_header(line)
+    comment_header_len = len(comment_header)
+    while get_comment_header(line)==comment_header and \
+              not is_all_white(line[comment_header_len:]):
         lineno = lineno + 1
         line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
     last = "%d.0" % lineno
     # Search back to beginning of paragraph
     lineno = first_lineno - 1
     line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
-    while lineno > 0 and not is_all_white(line):
+    while lineno > 0 and \
+              get_comment_header(line)==comment_header and \
+              not is_all_white(line[comment_header_len:]):
         lineno = lineno - 1
         line = text.get("%d.0" % lineno, "%d.0 lineend" % lineno)
     first = "%d.0" % (lineno+1)
-    return first, last, text.get(first, last)
+    return first, last, comment_header, text.get(first, last)
 
 def reformat_paragraph(data, limit=70):
     lines = string.split(data, "\n")
@@ -105,3 +145,8 @@ def is_all_white(line):
 
 def get_indent(line):
     return re.match(r"^(\s*)", line).group()
+
+def get_comment_header(line):
+    m = re.match(r"^(\s*#*)", line)
+    if m is None: return ""
+    return m.group(1)