GLMFormatedPresentation>>format bug?

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

GLMFormatedPresentation>>format bug?

alistairgrant
Hi All,

I'm currently porting my personal documentation system from Python /
Django to Pharo and am trying to display formatted text in a new pane in
the inspector.  If I execute something like:

| text |

text := 'Hello World' asText.
text addAttribute: TextColor green from: 1 to: 6.
text

in a playground using "Do it and go", the text is displayed correctly
(with formatting).

If I add a method in the object I want to inspect:

gtInspectIn: composite
        <gtInspectorPresentationOrder: 30>

        ^ composite text
                title: 'Meme';
                display: [self asText].

the formatting disappears.

I'm able to "fix" the problem by changing:

GLMFormatedPresentation>>format
        ^ format ifNil: [ format := #asString ]

to:

GLMFormatedPresentation>>format
        ^ format ifNil: [ format := #asText ]

Is someone more knowledgable about Glamour able to confirm that this is
really a bug?  If so, I'll submit a formal bug report on fogbugz.  (If
there's a better solution, that would be great too).

Thanks!
Alistair

Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

Andrei Chis
Hi Alistair,

Try something like this. Now 100% sure it will work.

gtInspectIn: composite
        <gtInspectorPresentationOrder: 30>

        ^ composite text
                title: 'Meme';
                format: [self asText].

The display block should return the object to be displayed, which is this case is self.

Cheers,
Andrei


On Sun, May 15, 2016 at 11:58 PM, Alistair Grant <[hidden email]> wrote:
Hi All,

I'm currently porting my personal documentation system from Python /
Django to Pharo and am trying to display formatted text in a new pane in
the inspector.  If I execute something like:

| text |

text := 'Hello World' asText.
text addAttribute: TextColor green from: 1 to: 6.
text

in a playground using "Do it and go", the text is displayed correctly
(with formatting).

If I add a method in the object I want to inspect:

gtInspectIn: composite
        <gtInspectorPresentationOrder: 30>

        ^ composite text
                title: 'Meme';
                display: [self asText].

the formatting disappears.

I'm able to "fix" the problem by changing:

GLMFormatedPresentation>>format
        ^ format ifNil: [ format := #asString ]

to:

GLMFormatedPresentation>>format
        ^ format ifNil: [ format := #asText ]

Is someone more knowledgable about Glamour able to confirm that this is
really a bug?  If so, I'll submit a formal bug report on fogbugz.  (If
there's a better solution, that would be great too).

Thanks!
Alistair


Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

alistairgrant
Hi Andrei,

On Mon, May 16, 2016 at 12:08:01AM +0200, Andrei Chis wrote:

> Hi Alistair,
>
> Try something like this. Now 100% sure it will work.
>
> gtInspectIn: composite
>         <gtInspectorPresentationOrder: 30>
>
>         ^ composite text
>                 title: 'Meme';
>                 format: [self asText].
>
> The display block should return the object to be displayed, which is this case
> is self.

Yep, that fixes the problem!  Thanks for your reply.

Cheers,
Alistair

Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

Ben Coman
On Mon, May 16, 2016 at 6:28 AM, Alistair Grant <[hidden email]> wrote:

> Hi Andrei,
>
> On Mon, May 16, 2016 at 12:08:01AM +0200, Andrei Chis wrote:
>> Hi Alistair,
>>
>> Try something like this. Now 100% sure it will work.
>>
>> gtInspectIn: composite
>>         <gtInspectorPresentationOrder: 30>
>>
>>         ^ composite text
>>                 title: 'Meme';
>>                 format: [self asText].
>>
>> The display block should return the object to be displayed, which is this case
>> is self.
>
> Yep, that fixes the problem!  Thanks for your reply.

Just curious if this also works...

         ^ composite text
                 title: 'Meme';
                 format: #asText

cheers -ben

Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

Tudor Girba-2
Hi,

On May 16, 2016, at 1:00 AM, Ben Coman <[hidden email]> wrote:

On Mon, May 16, 2016 at 6:28 AM, Alistair Grant <[hidden email]> wrote:
Hi Andrei,

On Mon, May 16, 2016 at 12:08:01AM +0200, Andrei Chis wrote:
Hi Alistair,

Try something like this. Now 100% sure it will work.

gtInspectIn: composite
       <gtInspectorPresentationOrder: 30>

       ^ composite text
               title: 'Meme';
               format: [self asText].

The display block should return the object to be displayed, which is this case
is self.

Yep, that fixes the problem!  Thanks for your reply.

Just curious if this also works...

        ^ composite text
                title: 'Meme';
                format: #asText

It works because the format block takes an optional argument with the input entity. However, the semantics are not going to be quite the same. In isolation, the behavior will be identical. However, the difference comes when you try to reuse a presentation. 

Let’s look at an example. This is how an AST node displays the source:

RBProgramNode>>gtInspectorSourceCodeIn: composite
<gtInspectorPresentationOrder: 30> 
^ composite pharoMethod 
title: 'Source code’;
display: [ self source ];
...

Like this, the block closure can simply delegate to the corresponding ast node to display the source:

BlockClosure>>gtInspectorSourceCodeIn: composite 
<gtInspectorPresentationOrder: 40>
self sourceNode gtInspectorSourceCodeIn: composite

And a keymap object which holds a block in an action instance variable, can simply delegate to the block closure object to display the source:

KMKeymap>>gtInspectorSourceCodeIn: composite
<gtInspectorPresentationOrder: 30> 
^ self action gtInspectorSourceCodeIn: composite


If the ProgramNode definition would have been implemented like:
display: [ :each | each source ]

then when inspecting the block object, we would have gotten the block object as each, and not the AST node.

Does this explanation make sense?

Cheers,
Doru



cheers -ben

--
www.tudorgirba.com
www.feenk.com

"Some battles are better lost than fought."




Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

alistairgrant
On Mon, May 16, 2016 at 05:42:54AM +0200, Tudor Girba wrote:

> Hi,
>
>
>     On May 16, 2016, at 1:00 AM, Ben Coman <[hidden email]> wrote:
>
>     On Mon, May 16, 2016 at 6:28 AM, Alistair Grant <[hidden email]>
>     wrote:
>
>         Hi Andrei,
>
>         On Mon, May 16, 2016 at 12:08:01AM +0200, Andrei Chis wrote:
>
>             Hi Alistair,
>
>             Try something like this. Now 100% sure it will work.
>
>             gtInspectIn: composite
>                    <gtInspectorPresentationOrder: 30>
>
>                    ^ composite text
>                            title: 'Meme';
>                            format: [self asText].
>
>             The display block should return the object to be displayed, which
>             is this case
>             is self.
>
>
>         Yep, that fixes the problem!  Thanks for your reply.
>
>
>     Just curious if this also works...
>
>             ^ composite text
>                     title: 'Meme';
>                     format: #asText

This also works, and looking at the definition of #format I'm guessing
that this is closer to the original intended usage (see below)?


> It works because the format block takes an optional argument with the input
> entity. However, the semantics are not going to be quite the same. In
> isolation, the behavior will be identical. However, the difference comes when
> you try to reuse a presentation.
>
> Let’s look at an example. This is how an AST node displays the source:
>
> RBProgramNode>>gtInspectorSourceCodeIn: composite
> <gtInspectorPresentationOrder: 30>
> ^ composite pharoMethod
> title: 'Source code’;
> display: [ self source ];
> ...
>
> Like this, the block closure can simply delegate to the corresponding ast node
> to display the source:
>
> BlockClosure>>gtInspectorSourceCodeIn: composite
> <gtInspectorPresentationOrder: 40>
> self sourceNode gtInspectorSourceCodeIn: composite
>
> And a keymap object which holds a block in an action instance variable, can
> simply delegate to the block closure object to display the source:
>
> KMKeymap>>gtInspectorSourceCodeIn: composite
> <gtInspectorPresentationOrder: 30>
> ^ self action gtInspectorSourceCodeIn: composite
>
>
> If the ProgramNode definition would have been implemented like:
> display: [ :each | each source ]
>
> then when inspecting the block object, we would have gotten the block object as
> each, and not the AST node.
>
> Does this explanation make sense?

So using this code is going to be more flexible than

    ^ composite text
        title: 'Meme';
        format: [self asText]

since the format object isn't supplied the optional arguments.

Thanks,
Alistair

Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

Tudor Girba-2
Hi,

> On May 16, 2016, at 7:59 AM, Alistair Grant <[hidden email]> wrote:
>
> On Mon, May 16, 2016 at 05:42:54AM +0200, Tudor Girba wrote:
>> Hi,
>>
>>
>>    On May 16, 2016, at 1:00 AM, Ben Coman <[hidden email]> wrote:
>>
>>    On Mon, May 16, 2016 at 6:28 AM, Alistair Grant <[hidden email]>
>>    wrote:
>>
>>        Hi Andrei,
>>
>>        On Mon, May 16, 2016 at 12:08:01AM +0200, Andrei Chis wrote:
>>
>>            Hi Alistair,
>>
>>            Try something like this. Now 100% sure it will work.
>>
>>            gtInspectIn: composite
>>                   <gtInspectorPresentationOrder: 30>
>>
>>                   ^ composite text
>>                           title: 'Meme';
>>                           format: [self asText].
>>
>>            The display block should return the object to be displayed, which
>>            is this case
>>            is self.
>>
>>
>>        Yep, that fixes the problem!  Thanks for your reply.
>>
>>
>>    Just curious if this also works...
>>
>>            ^ composite text
>>                    title: 'Meme';
>>                    format: #asText
>
> This also works, and looking at the definition of #format I'm guessing
> that this is closer to the original intended usage (see below)?
>
>
>> It works because the format block takes an optional argument with the input
>> entity. However, the semantics are not going to be quite the same. In
>> isolation, the behavior will be identical. However, the difference comes when
>> you try to reuse a presentation.
>>
>> Let’s look at an example. This is how an AST node displays the source:
>>
>> RBProgramNode>>gtInspectorSourceCodeIn: composite
>> <gtInspectorPresentationOrder: 30>
>> ^ composite pharoMethod
>> title: 'Source code’;
>> display: [ self source ];
>> ...
>>
>> Like this, the block closure can simply delegate to the corresponding ast node
>> to display the source:
>>
>> BlockClosure>>gtInspectorSourceCodeIn: composite
>> <gtInspectorPresentationOrder: 40>
>> self sourceNode gtInspectorSourceCodeIn: composite
>>
>> And a keymap object which holds a block in an action instance variable, can
>> simply delegate to the block closure object to display the source:
>>
>> KMKeymap>>gtInspectorSourceCodeIn: composite
>> <gtInspectorPresentationOrder: 30>
>> ^ self action gtInspectorSourceCodeIn: composite
>>
>>
>> If the ProgramNode definition would have been implemented like:
>> display: [ :each | each source ]
>>
>> then when inspecting the block object, we would have gotten the block object as
>> each, and not the AST node.
>>
>> Does this explanation make sense?
>
> So using this code is going to be more flexible than
>
>    ^ composite text
>        title: 'Meme';
>        format: [self asText]
>
> since the format object isn't supplied the optional arguments.

Actually, the less flexible approach is:
        format: [ :each | each source ]

Given that you define the extension directly in the class of the object you want to inspect, you essentially always want to apply the transformations on self, regardless of the “each” block argument. In this way, you can reuse this presentation in other objects through delegation like I mentioned above.

In any case, I am happy to hear that you want to extend you object. Could you let us know the use case?

Cheers,
Tudor


> Thanks,
> Alistair

--
www.tudorgirba.com
www.feenk.com

"Some battles are better lost than fought."





Reply | Threaded
Open this post in threaded view
|

Re: GLMFormatedPresentation>>format bug?

alistairgrant
Hi Tudor,

On Wed, May 18, 2016 at 09:26:51AM +0200, Tudor Girba wrote:

> Hi,
>
> > On May 16, 2016, at 7:59 AM, Alistair Grant <[hidden email]> wrote:
> >
> > On Mon, May 16, 2016 at 05:42:54AM +0200, Tudor Girba wrote:
> >
> >  ...
> >> It works because the format block takes an optional argument with the input
> >> entity. However, the semantics are not going to be quite the same. In
> >> isolation, the behavior will be identical. However, the difference comes when
> >> you try to reuse a presentation.
> >>
> >> Let’s look at an example. This is how an AST node displays the source:
> >>
> >> RBProgramNode>>gtInspectorSourceCodeIn: composite
> >> <gtInspectorPresentationOrder: 30>
> >> ^ composite pharoMethod
> >> title: 'Source code’;
> >> display: [ self source ];
> >> ...
> >>
> >> Like this, the block closure can simply delegate to the corresponding ast node
> >> to display the source:
> >>
> >> BlockClosure>>gtInspectorSourceCodeIn: composite
> >> <gtInspectorPresentationOrder: 40>
> >> self sourceNode gtInspectorSourceCodeIn: composite
> >>
> >> And a keymap object which holds a block in an action instance variable, can
> >> simply delegate to the block closure object to display the source:
> >>
> >> KMKeymap>>gtInspectorSourceCodeIn: composite
> >> <gtInspectorPresentationOrder: 30>
> >> ^ self action gtInspectorSourceCodeIn: composite
> >>
> >>
> >> If the ProgramNode definition would have been implemented like:
> >> display: [ :each | each source ]
> >>
> >> then when inspecting the block object, we would have gotten the block object as
> >> each, and not the AST node.
> >>
> >> Does this explanation make sense?
> >
> > So using this code is going to be more flexible than
> >
> >    ^ composite text
> >        title: 'Meme';
> >        format: [self asText]
> >
> > since the format object isn't supplied the optional arguments.
>
> Actually, the less flexible approach is:
> format: [ :each | each source ]
>
> Given that you define the extension directly in the class of the object you want to inspect, you essentially always want to apply the transformations on self, regardless of the “each” block argument. In this way, you can reuse this presentation in other objects through delegation like I mentioned above.
>
> In any case, I am happy to hear that you want to extend you object. Could you let us know the use case?

I'm porting my personal note taking system that I originally developed
in Python / Django about 5 years ago to Pharo.

The main entity is what I call a "meme", which simply has a name, label
and description.  Any number of attachments may be added, e.g. URLs,
links to external files, internally managed files, etc.  Meme's are
related to each other as parents / children or peers.

The approach I'm taking is to be able to view each of the objects in the
standard Pharo inspectors, so for a meme its' name, label and
description are displayed as formatted text with clickable links (thus
the question that started this thread), relations to other memes are
displayed in a RTMondrian force graph (at the moment).

Being able to inspect the objects obviously helps with the debugging and
gives the system a live / exploratory feel.  Once that is working, I'll
start on a more custom interface which will be more practical for actual
note taking.

Does that answer your question?

Cheers,
Alistair