Eliot Miranda uploaded a new version of Collections to project The Inbox:
http://source.squeak.org/inbox/Collections-eem.732.mcz ==================== Summary ==================== Name: Collections-eem.732 Author: eem Time: 8 February 2017, 10:55:41.894202 am UUID: c2c7f1c4-f586-4872-b2c7-6fb7f9cd6527 Ancestors: Collections-dtl.731 Modify HtmlReadWriter to enclose indented text within <pre></pre> to preserve formatting of, for example, code. =============== Diff against Collections-dtl.731 =============== Item was added: + ----- Method: HtmlReadWriter>>linesWithAttributesIn:do: (in category 'writing') ----- + linesWithAttributesIn: aText do: aBlock + "Evauate aBlock with a string and the emphasis for that string, guaranteeing + that if the string contains a line break, it occurs at the end of the line." + aText runs withStartStopAndValueDo: + [:start :stop :attributes | | att idx startIdx | + startIdx := start. + [att := aText attributesAt: startIdx. + idx := aText string indexOf: Character cr from: startIdx to: stop ifAbsent: stop. + aBlock value: (aText string copyFrom: startIdx to: idx) value: att. + idx < stop] + whileTrue: + [startIdx := idx + 1]]! Item was changed: ----- Method: HtmlReadWriter>>nextPutText: (in category 'accessing') ----- nextPutText: aText + | atStartOfLine inIndent cr | + atStartOfLine := true. + inIndent := false. + cr := Character cr. + self linesWithAttributesIn: aText do: + [:string :attributes | | indented | + atStartOfLine ifTrue: + [indented := string first == Character tab. + indented ~~ inIndent ifTrue: + [stream nextPutAll: (indented ifTrue: ['<pre>'] ifFalse: ['</pre>']). + inIndent := indented]]. + attributes do: [:each | self writeStartTagFor: each]. + inIndent + ifTrue: [self writePresentationContent: string] + ifFalse: [self writeContent: string]. + attributes reverseDo: [:each | self writeEndTagFor: each]. + atStartOfLine := string last == cr]. + inIndent ifTrue: + [stream nextPutAll: '</pre>']! - - aText runs - withStartStopAndValueDo: [:start :stop :attributes | - | att str | - att := aText attributesAt: start. - str := aText string copyFrom: start to: stop. - - att do: [:each | self writeStartTagFor: each]. - self writeContent: str. - att reverse do: [:each | self writeEndTagFor: each]]! Item was added: + ----- Method: HtmlReadWriter>>writePresentationContent: (in category 'writing') ----- + writePresentationContent: aString + + aString do: [:char | + char = Character tab + ifTrue: [stream nextPutAll: ' '] + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) + ifNil: [stream nextPut: char] + ifNotNil: [:escapeSequence | + stream + nextPut: $&; + nextPutAll: escapeSequence; + nextPut: $;]]]! Item was added: + ----- Method: SequenceableCollection>>indexOf:from:to:ifAbsent: (in category 'accessing') ----- + indexOf: anElement from: start to: end ifAbsent: exceptionBlock + "Answer the index of the first occurence of anElement from start to stop + within the receiver. If the receiver does not contain anElement in the, + range answer the result of evaluating the argument, exceptionBlock." + + start to: end do: + [:index | + (self at: index) = anElement ifTrue: [^index]]. + ^exceptionBlock value! |
Hi All, I'd really like this to be in trunk. I've just written a blog post in a Workspace using this code (http://www.mirandabanda.org/cogblog/2017/02/07/smalltalk-scanning-and-shcontrol-structures/) and it turns creating a blog post into a simple copyHtml paste operation from a workspace to (in my case) WordPress. So any reviewers? On Wed, Feb 8, 2017 at 10:55 AM, <[hidden email]> wrote: Eliot Miranda uploaded a new version of Collections to project The Inbox: _,,,^..^,,,_ best, Eliot |
On 08.02.2017, at 19:59, Eliot Miranda <[hidden email]> wrote: > Hi All, > > I'd really like this to be in trunk. I've just written a blog post in a Workspace using this code (http://www.mirandabanda.org/cogblog/2017/02/07/smalltalk-scanning-and-shcontrol-structures/) and it turns creating a blog post into a simple copyHtml paste operation from a workspace to (in my case) WordPress. So any reviewers? Care to explain it a litte bit? :) It looks a bit complicated to my eyes. Also, do you really want <pre>? (http://stackoverflow.com/questions/4611591/code-vs-pre-vs-samp-for-inline-and-block-code-snippets#4611735) The HtmlReadWriter seems to (up until now) pretty directly map text attributes to html attributes. You seem to want to differentiate code from non-code, so what about having a do-it attribute, that does exactly that? Because now, there's also no back-reading of such html into a Text object, wich I find unfortunate. I think, the readwriter should be able to read what it has written. I know, it's a mere convenience thing, but still, its very procedural, and seeing #~~ in high-level code is strange to my eyes… What would be really cool is to - mark the code as do-it - have the do-it present itself as <code> or <pre> on Html. Btw: there's also an TextIndent attribute that we could leverage. Best regards -Tobias > > On Wed, Feb 8, 2017 at 10:55 AM, <[hidden email]> wrote: > Eliot Miranda uploaded a new version of Collections to project The Inbox: > http://source.squeak.org/inbox/Collections-eem.732.mcz > > ==================== Summary ==================== > > Name: Collections-eem.732 > Author: eem > Time: 8 February 2017, 10:55:41.894202 am > UUID: c2c7f1c4-f586-4872-b2c7-6fb7f9cd6527 > Ancestors: Collections-dtl.731 > > Modify HtmlReadWriter to enclose indented text within <pre></pre> to preserve formatting of, for example, code. > > =============== Diff against Collections-dtl.731 =============== > > Item was added: > + ----- Method: HtmlReadWriter>>linesWithAttributesIn:do: (in category 'writing') ----- > + linesWithAttributesIn: aText do: aBlock > + "Evauate aBlock with a string and the emphasis for that string, guaranteeing > + that if the string contains a line break, it occurs at the end of the line." > + aText runs withStartStopAndValueDo: > + [:start :stop :attributes | | att idx startIdx | > + startIdx := start. > + [att := aText attributesAt: startIdx. > + idx := aText string indexOf: Character cr from: startIdx to: stop ifAbsent: stop. > + aBlock value: (aText string copyFrom: startIdx to: idx) value: att. > + idx < stop] > + whileTrue: > + [startIdx := idx + 1]]! > > Item was changed: > ----- Method: HtmlReadWriter>>nextPutText: (in category 'accessing') ----- > nextPutText: aText > + | atStartOfLine inIndent cr | > + atStartOfLine := true. > + inIndent := false. > + cr := Character cr. > + self linesWithAttributesIn: aText do: > + [:string :attributes | | indented | > + atStartOfLine ifTrue: > + [indented := string first == Character tab. > + indented ~~ inIndent ifTrue: > + [stream nextPutAll: (indented ifTrue: ['<pre>'] ifFalse: ['</pre>']). > + inIndent := indented]]. > + attributes do: [:each | self writeStartTagFor: each]. > + inIndent > + ifTrue: [self writePresentationContent: string] > + ifFalse: [self writeContent: string]. > + attributes reverseDo: [:each | self writeEndTagFor: each]. > + atStartOfLine := string last == cr]. > + inIndent ifTrue: > + [stream nextPutAll: '</pre>']! > - > - aText runs > - withStartStopAndValueDo: [:start :stop :attributes | > - | att str | > - att := aText attributesAt: start. > - str := aText string copyFrom: start to: stop. > - > - att do: [:each | self writeStartTagFor: each]. > - self writeContent: str. > - att reverse do: [:each | self writeEndTagFor: each]]! > > Item was added: > + ----- Method: HtmlReadWriter>>writePresentationContent: (in category 'writing') ----- > + writePresentationContent: aString > + > + aString do: [:char | > + char = Character tab > + ifTrue: [stream nextPutAll: ' '] > + ifFalse: [(String htmlEntities keyAtValue: char ifAbsent: []) > + ifNil: [stream nextPut: char] > + ifNotNil: [:escapeSequence | > + stream > + nextPut: $&; > + nextPutAll: escapeSequence; > + nextPut: $;]]]! > > Item was added: > + ----- Method: SequenceableCollection>>indexOf:from:to:ifAbsent: (in category 'accessing') ----- > + indexOf: anElement from: start to: end ifAbsent: exceptionBlock > + "Answer the index of the first occurence of anElement from start to stop > + within the receiver. If the receiver does not contain anElement in the, > + range answer the result of evaluating the argument, exceptionBlock." > + > + start to: end do: > + [:index | > + (self at: index) = anElement ifTrue: [^index]]. > + ^exceptionBlock value! > > > > > > -- > _,,,^..^,,,_ > best, Eliot > |
On Wed, Feb 8, 2017 at 12:47 PM, Tobias Pape <[hidden email]> wrote:
Here's a screen shot of a workspace from which I used the inbox version of copyHtml to produce the blog post. Compare it against http://www.mirandabanda.org/cogblog/2017/02/07/smalltalk-scanning-and-shcontrol-structures/; it's a pretty good mapping. It looks a bit complicated to my eyes. The thing to note is that normal text isn't indented, and presentation text is. HTML rendering in browsers doesn't preserve indentation if one uses <blockquote>, but does if one uses <pre>. Using <code> preserves indentation but can include ugly sidebars. So <pre></pre> is definitely the tag to use to include indented text. Indented text may /not/ be code, but we clearly want it to be indented correctly. Basically, all the change does is enclose a run of indented lines in <pre></pre>, which will preserve indentation and not introduce unwanted artifacts such as included using the <code> tag, so this should be uncontroversial. Do do this, scanning of the text needs to be modified to spot indentations at the beginning of lines. To do that I introduce HtmlReadWriter>>#linesWithAttributesIn:do: to sit above RunArray>>withStartStopAndValueDo: and ensure that the block argument to linesWithAttributesIn:do: is only ever supplied with strings that, if they contain a carriage return, have the carriage return at the end. This makes it easy for HtmlReadWriter>>#nextPutText: to spot f it is at the beginning of a line, and therefore to know if it is processing a line within a run of indented text. So here's the method: nextPutText: aText | atStartOfLine inIndent cr | atStartOfLine := true. inIndent := false. cr := Character cr. self linesWithAttributesIn: aText do: [:subString :attributes | | indented | atStartOfLine ifTrue: [indented := subString first == Character tab. indented ~~ inIndent ifTrue: [stream nextPutAll: (indented ifTrue: ['<pre>'] ifFalse: ['</pre>']). inIndent := indented]]. attributes do: [:each | self writeStartTagFor: each]. inIndent ifTrue: [self writePresentationContent: subString] ifFalse: [self writeContent: subString]. attributes reverseDo: [:each | self writeEndTagFor: each]. atStartOfLine := subString last == cr]. inIndent ifTrue: [stream nextPutAll: '</pre>'] So if atStartOfLine, we need to check for indentation (line begins with a tab). If at this pint there is a change from non-indenting to indenting, or vice verse, we need to add either a <pre> or a </pre> tag. While processing indented text we shouldn't map carriage return to <br> because that will give us a double line feed, and so if indenting we process using writePresentationContent: which is the same as writeContent: except for the carriage return -> <br> processing. The block spots being atStartOfLine by looking at the last character of the string, which linesWithAttributesIn:do: guarantees is the only place a carriage return will occur in the block. Finally at the end of the method if indenting we close off the indentation by generating the matching </pre>. The HtmlReadWriter seems to (up until now) pretty directly map text attributes to html attributes. But because it does't enclose indented text in <pre></pre> it causes browsers to screw up indented text, and requires lots of painful hand editing to correct. I fixed copyHtml to avoid this. You seem to want to differentiate code from non-code, so what about having a do-it attribute, that does exactly that? Not really. I just want to preserve indentation. Code is merely one kind of text for which indentation is important. But indented lists are valid also. I don't think one should be introducing markup into the Workspace. Instead I think copyHtml should be trying to construct HTML that is visually equivalent to the source text. My modifications achieve that. I don't like the idea of adding a do-it attribute. I don't see the need. The modifications I introduce do it automatically. Compare the workspace above with my blog post. Because now, there's also no back-reading of such html into a Text object, wich I find unfortunate. I disagree. All that is needed is to use <pre></pre> correctly.
Perhaps.
BTW, Marcel, if one uses TAB or SHIFT-TAB to change the indentation of colored text, the operation strips the colouration :-(
_,,,^..^,,,_ best, Eliot |
Free forum by Nabble | Edit this page |