669 |idx1 "{ Class:SmallInteger }" |
669 |idx1 "{ Class:SmallInteger }" |
670 idx2 "{ Class:SmallInteger }" |
670 idx2 "{ Class:SmallInteger }" |
671 totalLength "{ Class:SmallInteger }" |
671 totalLength "{ Class:SmallInteger }" |
672 pos "{ Class:SmallInteger }" |
672 pos "{ Class:SmallInteger }" |
673 newString lineString spaces idx nTabs sepCnt |
673 newString lineString spaces idx nTabs sepCnt |
674 any16Bit stringClass| |
674 any16Bit stringClass needEmphasis| |
675 |
675 |
676 " |
676 " |
677 first accumulate the size of the string, to avoid |
677 first accumulate the size of the string, to avoid |
678 countless reallocations. If tabs are compressed, |
678 countless reallocations. If tabs are compressed, |
679 the size computed is not exact, but gives an upper bound ... |
679 the size computed is not exact, but gives an upper bound ... |
680 On the fly, look if a 16bit string is needed. |
680 On the fly, look if a 16bit string is needed. |
681 " |
681 " |
682 any16Bit := false. |
682 any16Bit := needEmphasis := false. |
683 stringClass := String. |
683 stringClass := String. |
684 |
684 |
685 totalLength := 0. |
685 totalLength := 0. |
686 sepCnt := sepCharacter notNil ifTrue:[1] ifFalse:[0]. |
686 sepCnt := sepCharacter notNil ifTrue:[1] ifFalse:[0]. |
687 |
687 |
688 idx1 := firstLine. |
688 idx1 := firstLine. |
689 idx2 := lastLine. |
689 idx2 := lastLine. |
690 idx1 to:idx2 do:[:lineIndex | |
690 idx1 to:idx2 do:[:lineIndex | |
691 lineString := self at:lineIndex. |
691 lineString := self at:lineIndex. |
692 |
692 |
693 lineString isNil ifTrue:[ |
693 lineString isNil ifTrue:[ |
694 totalLength := totalLength + sepCnt |
694 totalLength := totalLength + sepCnt |
695 ] ifFalse: [ |
695 ] ifFalse: [ |
696 (lineString bitsPerCharacter == 16) ifTrue:[ |
696 lineString hasChangeOfEmphasis ifTrue:[ |
697 any16Bit := true. |
697 needEmphasis := true |
698 stringClass := lineString class |
698 ]. |
699 ]. |
699 (lineString bitsPerCharacter == 16) ifTrue:[ |
700 totalLength := totalLength + lineString size + sepCnt |
700 any16Bit := true. |
701 ]. |
701 stringClass := lineString class |
|
702 ]. |
|
703 totalLength := totalLength + lineString size + sepCnt |
|
704 ]. |
702 ]. |
705 ]. |
703 endCharacter isNil ifTrue:[ |
706 endCharacter isNil ifTrue:[ |
704 totalLength := totalLength - 1 |
707 totalLength := totalLength - 1 |
705 ]. |
708 ]. |
706 spaces := ' '. |
709 spaces := ' '. |
707 newString := stringClass new:totalLength. |
710 newString := stringClass new:totalLength. |
|
711 needEmphasis ifTrue:[ |
|
712 newString := Text string:newString |
|
713 ]. |
708 |
714 |
709 " |
715 " |
710 now, replace ... |
716 now, replace ... |
711 " |
717 " |
712 pos := 1. |
718 pos := 1. |
713 idx1 to:idx2 do:[:lineIndex | |
719 idx1 to:idx2 do:[:lineIndex | |
714 |thisLen| |
720 |thisLen| |
715 |
721 |
716 lineString := self at:lineIndex. |
722 lineString := self at:lineIndex. |
717 thisLen := lineString size. |
723 thisLen := lineString size. |
718 thisLen ~~ 0 ifTrue:[ |
724 thisLen ~~ 0 ifTrue:[ |
719 compressTabs ifTrue:[ |
725 compressTabs ifTrue:[ |
720 " |
726 " |
721 mhmh: could use withTabs from String-class here, |
727 mhmh: could use withTabs from String-class here, |
722 but we should avoid creating too many temporary strings |
728 but we should avoid creating too many temporary strings |
723 (especially, since this method is typically used when converting |
729 (especially, since this method is typically used when converting |
724 big texts such as when saving in the filebrowser ...). |
730 big texts such as when saving in the filebrowser ...). |
725 Therefore, we convert tabs inline here doing a direct replace |
731 Therefore, we convert tabs inline here doing a direct replace |
726 in newString." |
732 in newString." |
727 |
733 |
728 idx := lineString findFirst:[:c | (c ~~ Character space)]. |
734 idx := lineString findFirst:[:c | (c ~~ Character space)]. |
729 nTabs := (idx-1) // 8. |
735 nTabs := (idx-1) // 8. |
730 nTabs ~~ 0 ifTrue:[ |
736 nTabs ~~ 0 ifTrue:[ |
731 "any tabs" |
737 "any tabs" |
732 newString atAll:(pos to:pos+nTabs-1) put:(Character tab). |
738 newString atAll:(pos to:pos+nTabs-1) put:(Character tab). |
733 pos := pos + nTabs. |
739 pos := pos + nTabs. |
734 newString replaceFrom:pos with:lineString startingAt:(nTabs * 8 + 1). |
740 newString replaceFrom:pos with:lineString startingAt:(nTabs * 8 + 1). |
735 pos := pos + thisLen - (nTabs * 8). |
741 pos := pos + thisLen - (nTabs * 8). |
736 ] ifFalse:[ |
742 ] ifFalse:[ |
737 newString replaceFrom:pos with:lineString. |
743 newString replaceFrom:pos with:lineString. |
738 pos := pos + thisLen |
744 pos := pos + thisLen |
739 ]. |
745 ]. |
740 ] ifFalse:[ |
746 ] ifFalse:[ |
741 newString replaceFrom:pos with:lineString. |
747 newString replaceFrom:pos with:lineString. |
742 pos := pos + thisLen |
748 pos := pos + thisLen |
743 ] |
749 ] |
744 ]. |
750 ]. |
745 (sepCharacter notNil |
751 (sepCharacter notNil |
746 and:[lineIndex ~~ lastLine]) ifTrue:[ |
752 and:[lineIndex ~~ lastLine]) ifTrue:[ |
747 newString at:pos put:sepCharacter. |
753 newString at:pos put:sepCharacter. |
748 pos := pos + 1 |
754 pos := pos + 1 |
749 ] ifFalse:[ |
755 ] ifFalse:[ |
750 endCharacter notNil ifTrue:[ |
756 endCharacter notNil ifTrue:[ |
751 newString at:pos put:endCharacter. |
757 newString at:pos put:endCharacter. |
752 pos := pos + 1 |
758 pos := pos + 1 |
753 ] |
759 ] |
754 ] |
760 ] |
755 ]. |
761 ]. |
756 |
762 |
757 " |
763 " |
758 in case of tab compression, the result has to be |
764 in case of tab compression, the result has to be |
759 cut to size ... sorry |
765 cut to size ... sorry |
760 " |
766 " |
761 pos ~~ totalLength ifTrue:[ |
767 pos ~~ totalLength ifTrue:[ |
762 ^ newString copyTo:(pos - 1) |
768 ^ newString copyTo:(pos - 1) |
763 ]. |
769 ]. |
764 ^ newString |
770 ^ newString |
765 |
771 |
766 " |
772 " |
767 creating entries for searchpath: |
773 creating entries for searchpath: |
768 |
774 |
769 #('foo' 'bar' 'baz' '/foo/bar') |
775 #('foo' 'bar' 'baz' '/foo/bar') |
770 asStringWith:$: from:1 to:4 compressTabs:false final:nil |
776 asStringWith:$: |
|
777 from:1 to:4 |
|
778 compressTabs:false |
|
779 final:nil |
771 |
780 |
772 with trailing colon: |
781 with trailing colon: |
773 |
782 |
774 #('foo' 'bar' 'baz' '/foo/bar') |
783 #('foo' 'bar' 'baz' '/foo/bar') |
775 asStringWith:$: from:1 to:4 compressTabs:false final:$: |
784 asStringWith:$: |
|
785 from:1 to:4 |
|
786 compressTabs:false |
|
787 final:$: |
776 |
788 |
777 concatenating all elements: |
789 concatenating all elements: |
778 |
790 |
779 #('foo' 'bar' 'baz') |
791 #('foo' 'bar' 'baz') |
780 asStringWith:nil from:1 to:3 compressTabs:false final:nil |
792 asStringWith:nil |
|
793 from:1 to:3 |
|
794 compressTabs:false |
|
795 final:nil |
781 |
796 |
782 creating a string from a collection of lines: |
797 creating a string from a collection of lines: |
783 |
798 |
784 #('foo' 'bar' 'baz') |
799 #('foo' 'bar' 'baz') |
785 asStringWith:(Character cr) from:1 to:3 compressTabs:false final:(Character cr) |
800 asStringWith:(Character cr) |
786 " |
801 from:1 to:3 |
787 |
802 compressTabs:false |
788 "Modified: 23.2.1996 / 15:28:55 / cg" |
803 final:(Character cr) |
|
804 |
|
805 creating a text from a collection of mixed texts and strings: |
|
806 |
|
807 (Array |
|
808 with:'foo' |
|
809 with:('bar' asText allBold) |
|
810 with:'baz' |
|
811 with:('baz2' asText emphasizeAllWith:#italic) |
|
812 ) |
|
813 asStringWith:(Character cr) |
|
814 from:1 to:4 |
|
815 compressTabs:false |
|
816 final:(Character cr) |
|
817 " |
|
818 |
|
819 "Modified: 14.5.1996 / 16:37:12 / cg" |
789 ! |
820 ! |
790 |
821 |
791 asStringWithCRs |
822 asStringWithCRs |
792 "return a string generated by concatenating my elements |
823 "return a string generated by concatenating my elements |
793 (which must be strings or nil) and embedding cr characters in between. |
824 (which must be strings or nil) and embedding cr characters in between. |