Nicolas Cellier uploaded a new version of Collections to project The Trunk:
http://source.squeak.org/trunk/Collections-nice.192.mcz ==================== Summary ==================== Name: Collections-nice.192 Author: nice Time: 16 November 2009, 1:25:56 am UUID: ea8893b0-c42d-134b-8752-3d9ac395b62d Ancestors: Collections-nice.191 Some changes for handling cr/lf/crlf line delimiters in String =============== Diff against Collections-nice.191 =============== Item was changed: ----- Method: String>>lineCorrespondingToIndex: (in category 'accessing') ----- lineCorrespondingToIndex: anIndex + "Answer a string containing the line at the given character position." - "Answer a string containing the line at the given character position. 1/15/96 sw: Inefficient first stab at this" + self lineIndicesDo: [:start :endWithoutDelimiters :end | + anIndex <= end ifTrue: [^self copyFrom: start to: endWithoutDelimiters]]. + ^''! - | cr aChar answer | - cr := Character cr. - answer := ''. - 1 to: self size do: - [:i | - aChar := self at: i. - aChar = cr - ifTrue: - [i > anIndex - ifTrue: - [^ answer] - ifFalse: - [answer := '']] - ifFalse: - [answer := answer copyWith: aChar]]. - ^ answer! Item was changed: ----- Method: String>>indentationIfBlank: (in category 'paragraph support') ----- indentationIfBlank: aBlock "Answer the number of leading tabs in the receiver. If there are no visible characters, pass the number of tabs to aBlock and return its value." + | reader leadingTabs lastSeparator tab ch | - | reader leadingTabs lastSeparator cr tab ch | - cr := Character cr. tab := Character tab. reader := ReadStream on: self. leadingTabs := 0. [reader atEnd not and: [(ch := reader next) = tab]] whileTrue: [leadingTabs := leadingTabs + 1]. + lastSeparator := leadingTabs. + [reader atEnd not and: [ch isSeparator and: [(CSLineEnders includes: ch) not]]] - lastSeparator := leadingTabs + 1. - [reader atEnd not and: [ch isSeparator and: [ch ~= cr]]] whileTrue: [lastSeparator := lastSeparator + 1. ch := reader next]. + (lastSeparator >= self size or: [CSLineEnders includes: ch]) - lastSeparator = self size | (ch = cr) ifTrue: [^aBlock value: leadingTabs]. + ^ leadingTabs! - ^ leadingTabs. - ! Item was changed: ----- Method: String>>lineNumber: (in category 'accessing') ----- lineNumber: anIndex + "Answer a string containing the characters in the given line number." - "Answer a string containing the characters in the given line number. 5/10/96 sw" - - | crString pos finalPos | - crString := String with: Character cr. - pos := 0. - 1 to: anIndex - 1 do: - [:i | pos := self findString: crString startingAt: pos + 1. - pos = 0 ifTrue: [^ nil]]. - finalPos := self findString: crString startingAt: pos + 1. - finalPos = 0 ifTrue: [finalPos := self size + 1]. - ^ self copyFrom: pos + 1 to: finalPos - 1 + | lineCount | + lineCount := 0. + self lineIndicesDo: [:start :endWithoutDelimiters :end | + (lineCount := lineCount + 1) = anIndex ifTrue: [^self copyFrom: start to: endWithoutDelimiters]]. + ^nil! - " - 'Fred - the - Bear' lineNumber: 3 - "! Item was added: + ----- Method: SequenceableCollection>>lastIndexOfAnyOf:startingAt:ifAbsent: (in category 'accessing') ----- + lastIndexOfAnyOf: aCollection startingAt: lastIndex ifAbsent: exceptionBlock + "Answer the index of the last occurence of anElement within the + receiver. If the receiver does not contain anElement, answer the + result of evaluating the argument, exceptionBlock." + + lastIndex to: 1 by: -1 do: + [:index | + (aCollection includes: (self at: index)) ifTrue: [^ index]]. + ^ exceptionBlock value! Item was changed: ----- Method: String>>linesDo: (in category 'accessing') ----- linesDo: aBlock + "Execute aBlock with each line in this string. The terminating line delimiters CR, LF or CRLF pairs are not included in what is passed to aBlock" - "execute aBlock with each line in this string. The terminating CR's are not included in what is passed to aBlock" - | start end | - start := 1. - [ start <= self size ] whileTrue: [ - end := self indexOf: Character cr startingAt: start ifAbsent: [ self size + 1 ]. - end := end - 1. + self lineIndicesDo: [:start :endWithoutDelimiters :end | + aBlock value: (self copyFrom: start to: endWithoutDelimiters)]! - aBlock value: (self copyFrom: start to: end). - start := end + 2. ].! Item was changed: ----- Method: String>>lineCount (in category 'accessing') ----- lineCount + "Answer the number of lines represented by the receiver, where every line delimiter CR, LF or CRLF pair adds one line." - "Answer the number of lines represented by the receiver, where every cr adds one line. 5/10/96 sw" + | lineCount | + lineCount := 0. + self lineIndicesDo: [:start :endWithoutDelimiters :end | + lineCount := lineCount + 1]. + ^lineCount! - | cr count | - cr := Character cr. - count := 1 min: self size.. - 1 to: self size do: - [:i | (self at: i) = cr ifTrue: [count := count + 1]]. - ^ count - - " - 'Fred - the - Bear' lineCount - "! Item was added: + ----- Method: String>>lineIndicesDo: (in category 'accessing') ----- + lineIndicesDo: aBlock + "execute aBlock with 3 arguments for each line: + - start index of line + - end index of line without line delimiter + - end index of line including line delimiter(s) CR, LF or CRLF" + + | start end endWithoutDelimiters | + start := 1. + [ start <= self size ] whileTrue: [ + end := self indexOfAnyOf: CSLineEnders startingAt: start ifAbsent: [ self size + 1 ]. + endWithoutDelimiters := end - 1. + (end < self size + and: [(self at: end + 1) = Character lf + and: [(self at: end) = Character cr]]) + ifTrue: [end := end + 1]. + aBlock value: start value: endWithoutDelimiters value: end. + start := end + 1]! |
Free forum by Nabble | Edit this page |