The Inbox: Collections-eem.732.mcz

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

The Inbox: Collections-eem.732.mcz

commits-2
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: '&nbsp;&nbsp;&nbsp;&nbsp;']
+ 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!


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Collections-eem.732.mcz

Eliot Miranda-2
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:
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: '&nbsp;&nbsp;&nbsp;&nbsp;']
+                       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


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Collections-eem.732.mcz

Tobias Pape

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: '&nbsp;&nbsp;&nbsp;&nbsp;']
> +                       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
>


Reply | Threaded
Open this post in threaded view
|

Re: The Inbox: Collections-eem.732.mcz

Eliot Miranda-2


On Wed, Feb 8, 2017 at 12:47 PM, Tobias Pape <[hidden email]> wrote:

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? :)

Here's a screen shot of a workspace from which I used the inbox version of copyHtml to produce the blog post.





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 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 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.

I disagree.  All that is needed is to use <pre></pre> correctly.
 

Btw: there's also an TextIndent attribute that we could leverage.

Perhaps.
 

Best regards
        -Tobias


BTW, Marcel, if one uses TAB or SHIFT-TAB to change the indentation of colored text, the operation strips the colouration :-(
 
>
> 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: '&nbsp;&nbsp;&nbsp;&nbsp;']
> +                       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
>





--
_,,,^..^,,,_
best, Eliot