StringCollection.st
changeset 160 5dae57a490bd
parent 97 b876f90648aa
child 203 3d88fa870de0
--- a/StringCollection.st	Mon Oct 10 01:29:28 1994 +0100
+++ b/StringCollection.st	Mon Oct 10 01:53:52 1994 +0100
@@ -1,6 +1,6 @@
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
-              All Rights Reserved
+	      All Rights Reserved
 
  This software is furnished under a license and may be used
  only in accordance with the terms of that license and with the
@@ -19,9 +19,9 @@
 
 Text comment:'
 COPYRIGHT (c) 1989 by Claus Gittinger
-              All Rights Reserved
+	      All Rights Reserved
 
-$Header: /cvs/stx/stx/libbasic/StringCollection.st,v 1.8 1994-08-05 01:07:14 claus Exp $
+$Header: /cvs/stx/stx/libbasic/StringCollection.st,v 1.9 1994-10-10 00:53:50 claus Exp $
 '!
 
 !Text class methodsFor:'documentation'!
@@ -29,7 +29,7 @@
 copyright
 "
  COPYRIGHT (c) 1989 by Claus Gittinger
-              All Rights Reserved
+	      All Rights Reserved
 
  This software is furnished under a license and may be used
  only in accordance with the terms of that license and with the
@@ -42,19 +42,21 @@
 
 version
 "
-$Header: /cvs/stx/stx/libbasic/StringCollection.st,v 1.8 1994-08-05 01:07:14 claus Exp $
+$Header: /cvs/stx/stx/libbasic/StringCollection.st,v 1.9 1994-10-10 00:53:50 claus Exp $
 "
 !
 
 documentation
 "
-    text is an array of lines which are strings.
-    This class is temporary (a historic leftover) - it may change or
-    even vanish in the future. Use OrderedCollections or other standard
-    classes to represent collections of strings.
+    Text is an array of lines which are strings.
+    WARNING:
+        This class is temporary (a historic leftover) - it may change or
+        even vanish in the future. Use OrderedCollections or other standard
+        classes to represent collections of strings.
 
     Also, Text is a very bad name - there is something totally different 
     also named Text in ST-80 ...
+
     So, even if kept, it will be definitely be renamed to something like
     StringCollection in one of the next versions.
 "
@@ -78,7 +80,7 @@
     size := anArray size.
     newText := self new:size.
     1 to:size do:[:line |
-        newText at:line put:(anArray at:line)
+	newText at:line put:(anArray at:line)
     ].
     ^ newText
 ! !
@@ -94,7 +96,7 @@
     oldSize := tally.
     super grow:newSize.
     (oldSize < newSize) ifTrue:[
-        contentsArray from:(oldSize + 1) to:newSize put:''
+	contentsArray from:(oldSize + 1) to:newSize put:''
     ]
 !
 
@@ -115,59 +117,77 @@
 asString
     "return myself as a string with embedded cr's"
 
-    |totalLength "{ Class:SmallInteger }"
-     pos         "{ Class:SmallInteger }"
-     newString |
-
-    totalLength := 0.
-    self do:[:lineString |
-        lineString isNil ifTrue:[
-            totalLength := totalLength + 1
-        ] ifFalse: [
-            totalLength := totalLength + lineString size + 1
-        ].
-        0
-    ].
-    newString := String new:totalLength.
-    pos := 1.
-    self do:[:lineString |
-        lineString isNil ifFalse:[
-            newString replaceFrom:pos with:lineString.
-            pos := pos + (lineString size)
-        ].
-        newString at:pos put:(Character cr).
-        pos := pos + 1
-    ].
-    ^ newString
+    ^ self asStringFrom:1 to:(self size)
 !
 
 asStringFrom:firstLine to:lastLine
     "return part of myself as a string with embedded cr's"
 
+    ^ self asStringFrom:firstLine to:lastLine compressTabs:false
+!
+
+asStringFrom:firstLine to:lastLine compressTabs:compressTabs
+    "return part of myself as a string with embedded cr's.
+     If the argument compressTabs is true, leading spaces are converted
+     to tab-characters (8col tabs)"
+
     |totalLength "{ Class:SmallInteger }"
      pos         "{ Class:SmallInteger }"
-     newString lineString|
+     newString lineString spaces idx nTabs cutOff|
 
+    "
+     first accumulate the size of the string, to avoid
+     countless reallocations. The size is not exact, but gives
+     an upper bound ...
+    "
     totalLength := 0.
     firstLine to:lastLine do:[:lineIndex |
-        lineString := self at:lineIndex.
-        lineString isNil ifTrue:[
-            totalLength := totalLength + 1
-        ] ifFalse: [
-            totalLength := totalLength + lineString size + 1
-        ].
-        0
+	lineString := self at:lineIndex.
+	lineString isNil ifTrue:[
+	    totalLength := totalLength + 1
+	] ifFalse: [
+	    totalLength := totalLength + lineString size + 1
+	].
+	0
     ].
+
+    spaces := '        '.
     newString := String new:totalLength.
     pos := 1.
     firstLine to:lastLine do:[:lineIndex |
-        lineString := self at:lineIndex.
-        lineString isNil ifFalse:[
-            newString replaceFrom:pos with:lineString.
-            pos := pos + (lineString size)
-        ].
-        newString at:pos put:(Character cr).
-        pos := pos + 1
+	lineString := self at:lineIndex.
+	lineString isNil ifFalse:[
+	    compressTabs ifTrue:[
+		"
+		 mhmh: could use withTabs from String-class here,
+		 but we should avoid creating too many temporary strings
+		 (especially, since this method is typically used when converting
+		 big texts such as when saving in the filebrowser ...).
+		 Therefore, we convert tabs inline here doing a direct replace
+		 in newString."
+
+		idx := lineString findFirst:[:c | (c ~~ Character space)].
+		nTabs := (idx-1) // 8.
+		nTabs ~~ 0 ifTrue:[
+		    "any tabs"
+		    newString atAll:(pos to:pos+nTabs-1) put:(Character tab).
+		    pos := pos + nTabs.
+		    newString replaceFrom:pos with:lineString startingAt:(nTabs * 8 + 1).
+		    pos := pos + lineString size - (nTabs * 8).
+		] ifFalse:[
+		    newString replaceFrom:pos with:lineString.
+		    pos := pos + (lineString size)
+		].
+	    ] ifFalse:[
+		newString replaceFrom:pos with:lineString.
+		pos := pos + (lineString size)
+	    ]
+	].
+	newString at:pos put:(Character cr).
+	pos := pos + 1
+    ].
+    pos ~~ totalLength ifTrue:[
+	^ newString copyTo:(pos - 1)
     ].
     ^ newString
 !
@@ -184,19 +204,19 @@
     self grow:numberOfLines.
     start := 1.
     1 to:numberOfLines do:[:lineNr |
-        stop := aString indexOf:(Character cr) startingAt:start.
-        stop == 0 ifTrue:[
-            stop := aString size
-        ] ifFalse: [
-            stop := stop - 1.
-        ].
+	stop := aString indexOf:(Character cr) startingAt:start.
+	stop == 0 ifTrue:[
+	    stop := aString size
+	] ifFalse: [
+	    stop := stop - 1.
+	].
 
-        (stop < start) ifTrue: [
-            self at:lineNr put:(String new:0)
-        ] ifFalse: [
-            self at:lineNr put:(aString copyFrom:start to:stop)
-        ].
-        start := stop + 2
+	(stop < start) ifTrue: [
+	    self at:lineNr put:(String new:0)
+	] ifFalse: [
+	    self at:lineNr put:(aString copyFrom:start to:stop)
+	].
+	start := stop + 2
     ]
 !
 
@@ -219,10 +239,10 @@
 
     index := 1.
     [index <= self size] whileTrue:[
-        ((self at:index) startsWith:aString) ifTrue:[
-            ^ index
-        ].
-        index := index + 1
+	((self at:index) startsWith:aString) ifTrue:[
+	    ^ index
+	].
+	index := index + 1
     ].
     ^ 0
 ! !