Page MenuHomePhabricator

efl.text_markup
Closed, ResolvedPublic

Description

|interface Efl.Text_Markup @beta
|├ (P) markup
bu5hm4n created this task.May 3 2019, 11:14 AM
bu5hm4n triaged this task as TODO priority.
zmike moved this task from Backlog to Trivial on the efl: api board.Jun 12 2019, 7:38 AM

Same as efl.text, seems okay?

What kind of markup do we actually use? Is this documented anywhere?

Maybe we can add a markup_type property which is an enum to support multiple types?
Although that means we need to keep the original markup around in case the property is changed later and we need to re-interpret the markup string.
Probably a better approach is a set_markup method with a type parameter besides the actual markup text, instead of a plain markup property.
If the type parameter has a default value then we do not add any complexity for the user (for languages supporting default parameters).

Dunno how to read that

What kind of markup do we actually use? Is this documented anywhere?

@segfaultxavi
I think that tags (=formats) which can be used with EFL markup text are listed up in evas_textblock_legacy.h.
(I'm not sure whether this is something you want to know)

Maybe we can add a markup_type property which is an enum to support multiple types?
Although that means we need to keep the original markup around in case the property is changed later and we need to re-interpret the markup string.
Probably a better approach is a set_markup method with a type parameter besides the actual markup text, instead of a plain markup property.
If the type parameter has a default value then we do not add any complexity for the user (for languages supporting default parameters).

I'm wonderting what you mean with "markup_type". I don't know whether there can be multiple types for this feature.
What I only know is that there are only utf8 and markup which need to be covered by efl.canvas.text.
(Please let me know if I'm wrong)

I was thinking that maybe we could future-proof the API by specifying the type of markup the user is providing (EFL markup, Markdown, Flavored Markdown, Github Markdown... there¡'s hundreds of types!).
Right now this type would be an enum with only one possible value (EFL Markup), but in the future it could be extended.

Anyway, this does not seem urgent right now, and there's other ways to allow other types in the future, so just ignore my comment (for the record, here are some ideas: Add another property like github_markdown, or allow a special EFL-markup code at the beginning of the string indicating the type, something like <markdown_type=github>).

Thanks for the link to evas_textblock_legacy.h, that will be helpful!

zmike added a comment.Aug 29 2019, 7:09 AM

Is this good or what

Isn't this being completely revamped by @tasn ?

zmike added a comment.Sep 25 2019, 7:37 AM

Will this interface with the same property still exist at that point? If so, this can become stable now.

tasn added a comment.Sep 25 2019, 12:47 PM

No it won't. Not this name and not sure about the same property.

zmike moved this task from Trivial to Needs experts on the efl: api board.

This is should be ready to stabilize, any comments ?

The comments above say this is going to be replaced, so why are we talking now about its stabilization ?

The comments above say this is going to be replaced, so why are we talking now about its stabilization ?

Efl.Text.Content can not exist because efl.text already released and stabilized and we can not break it, comments are all over the place :)
https://phab.enlightenment.org/T8297#144289

Comments are not here, and the last comment says this is going to be replaced, that's why there is my comment. But thanks for sharing the link.

Comments are not here, and the last comment says this is going to be replaced, that's why there is my comment. But thanks for sharing the link.

It is challenging to keep track of all tasks and comments.

The comments above say this is going to be replaced, so why are we talking now about its stabilization ?

So this is ok now why we will not remove this?

This seems ok for me :)

If there would be no objects, I'll located this to "stabilized".

@ali.alzyod can you summarize for me what are the plans for markup support? It is unclear to me if this class should be removed and how will users provide markup if this is class is removed.

@ali.alzyod can you summarize for me what are the plans for markup support? It is unclear to me if this class should be removed and how will users provide markup if this is class is removed.

This is not class, it is interface, and we do not plan to remove it

OK, let me try again:
@ali.alzyod can you summarize for me what are the plans for markup support? It is unclear to me what will replace this interface and how will users provide markup if this class is replaced.

ali.alzyod added a comment.EditedDec 30 2019, 7:51 AM

This interface will not be removed or replaced. (why you keep refer to it as a class)

For Markup user can provide it as string.

but in the future far far far away in a galaxy far far away, we will have an object called AttributedString with this object user can create markups programmatically and this object will have
AttributedString.ToString() which will return string same as markup string we have now.

This interface will be :

interface Efl.Text_Markup @beta
├ (P) markup
├ (P) attributed_String (or markup_Object)

@segfaultxavi @ali.alzyod

I think there have been some miscommunications.

@segfaultxavi
Are you wondering "Why this MARKUP interface should be existed" and "Could it be involved to another class or interface" ?
As @ali.alzyod said, the meaning of "replace this interface" in your comment seems a big ambiguous.

@ali.alzyod
While checking the discussion here, I'm wondering whether this interface should be existed uniquely or can be involved to another interface.

ali.alzyod added a comment.EditedDec 30 2019, 11:01 PM

@woohyun
First I think of adding this class only property into efl.text interface.
but from what I understand from @zmike and @tasn, there are classes do not understand makeup because they are built internally from Canvas_Text not Canvas_Textblock (like Ui.Button).
So we can not combine it with efl.text interface, and I cannot see another better place for it, other than its own interface.

@ali.alzyod
Oh. I understand your point. The thing is that it can be implemented by other none-text classes.

@segfaultxavi
Do you think above @ali.alzyod 's opinion can be an answer on your question ?

OK, I understand why this interface cannot be merged to Efl.Text. Thanks for that.

Still, 6 months ago (here T7858#138241) I suggested some future-proofing measures.
Then @tasn said that this interface was going to be totally revamped (meaning fully modified, here T7858#141112).
And then, some months later, we're talking about stabilizing it as it is.

That's why I am asking what are the plans for this interface, and this has not been answered yet.
Are we following @tasn's RFC? Can we consider my suggestions?

I am not a fan of the current Efl.Text_Markup logic as it is pretty much impossible for the application to leverage it for a custom type. I would really prefer a logic where we can set a class/object that is in charge of interpreting the markup language string and convert it back and forth to native text API when a user call markup set on an object. This way all the markup language of the world can be easily supported and efl doesn't need to do it itself. Currently, it is not the direction we are taking. The reason why having a converter class/object is nicer than to require the creation of complete new class for an application, is that it divide intent clearly and reduce application work needed in just providing that conversion logic.

@cedric
Thanks for sharing your idea.
Is it something different from "efl_text_markup_util" class ?
Or, would it be sufficient to create classes (for different markup languages) which are similar with "efl_text_markup_util" ?

@segfaultxavi
Sorry for not catching your original question (and I had not known well about the meaning of "revamp".
I have tried to trace the history of markup.

And, I found T8215 which was assigned to me (but not implemented).

Relating this task, below class is defined in "/devs/tasn/ifaces".

class @beta Efl2.Text.Serializer.Markup extends Efl.Object implements Efl2.Text.Serializer.Interface {
   [[Markup creation object                                                     
                                                                                
       See https://phab.enlightenment.org/T8306                                 
   ]]                                                                           
   methods {                                                                    
      @property singelton @static {                                             
         values {                                                               
              singleton: Efl2.Text.Serializer.Markup; [[The singleton instance]]
         }                                                                      
      }                                                                         
   }                                                                            
                                                                                
   implements {                                                                 
       Efl2.Text.Serializer.Interface.insert;                                   
       Efl2.Text.Serializer.Interface.range_get;                                
   }                                                                            
}

And, as @ali.alzyod said in T8306, above "insert" and "range_get" have already been in Cursor class (T8454),
So, I don't think the above class is needed to current design.
Except this one, I could not find any point which needs to be "revamped".

@ali.alzyod
If I missed something about the original plan, could you let me know about it ?

cedric added a comment.Jan 3 2020, 5:59 PM

@cedric
Thanks for sharing your idea.
Is it something different from "efl_text_markup_util" class ?

No, this class is only for EFL markup language to text as a string. There is no integration with any text widget.

Or, would it be sufficient to create classes (for different markup languages) which are similar with "efl_text_markup_util" ?

This class is not connected to any widget and does not have the ability to do so as the API is not about integration, but just conversion to plain text.

ali.alzyod added a comment.EditedJan 5 2020, 12:29 AM

@woohyun @segfaultxavi
Last discussion related to this task with @tasn was in T8362

Efl2.Text.Content.Markup needs to be renamed.
Because of the former point, Efl2.Text.Content.Markup is now inconsistently named. It should be renamed to something else, maybe Efl.Text_Markup?

So removing this interface was not an option from start, it was renaming.
We did not add Efl2.Text.Serializer.Markup, because it is more convenient to use cursor object for such functionality.

@cedric
I am not catching exactly your comments, Are you referring to internal implementation or API exposed to users ?

EFl markup is a special kind of markup, and I think we should keep its internal support. new markups that we would like to support can be implemented be converting them into EFL markup and vice-versa (where it have no dependencies on Widgets).

Future plan for Markup :
What we are planing about in the future, Is to introduce anew object called AttributedText,
1- This object is capable of representing String with attributes attached to it.
2- This object has no dependencies on text widgets or cursors.
And currently, we do not see any blocking implementation for this feature.

@cedric
I am not catching exactly your comments, Are you referring to internal implementation or API exposed to users ?

API exposed to users

EFl markup is a special kind of markup, and I think we should keep its internal support. new markups that we would like to support can be implemented be converting them into EFL markup and vice-versa (where it have no dependencies on Widgets).

I do not like this path for two reason.

  1. It is a slow path. You first convert to EFL markup, emit it, parse it, convert to destination markup, free the EFL markup. While if you were tied to the widget API, you would directly just walk the text and generate the destination markup right away.
  2. It is a painful to use solution. Instead of getting the markup language you would want in your app, you end up with having to do additional step everywhere you use it.

Future plan for Markup :
What we are planing about in the future, Is to introduce anew object called AttributedText,
1- This object is capable of representing String with attributes attached to it.
2- This object has no dependencies on text widgets or cursors.
And currently, we do not see any blocking implementation for this feature.

I understand your plan and why you are taking it, I do think it is not going to lead to a nice and simple API to use. It would be nicer in my opinion if the Markup Generator code was split in its own class and that we could easily replace it. This way someone instantiating an text object, will just set the Markup Generator they want (Or even write their own) and every use of markup on that object would do what they want right away. No cumbersome additional step. It was my understanding that @tasn plan was to go in that direction and I am a bit sad that we are going back to a suboptimal solution.

ali.alzyod added a comment.EditedJan 5 2020, 11:37 PM

@cedric
I am not catching exactly your comments, Are you referring to internal implementation or API exposed to users ?

API exposed to users

Can you please show me what you expect to expose to the user?

EFl markup is a special kind of markup, and I think we should keep its internal support. new markups that we would like to support can be implemented be converting them into EFL markup and vice-versa (where it have no dependencies on Widgets).

I do not like this path for two reason.

  1. It is a slow path. You first convert to EFL markup, emit it, parse it, convert to destination markup, free the EFL markup. While if you were tied to the widget API, you would directly just walk the text and generate the destination markup right away.

at least some part of markup parsing will be kept internal,
for example:
1- how can we support font size variation like <font_size=20px>, internally EFL should be able to do so,
2- Introduce new attributes like list or table in the text ? EFL internally should be able to understand and draw these attributes and tags

  1. It is a painful to use solution. Instead of getting the markup language you would want in your app, you end up with having to do additional step everywhere you use it.

I still do not get it, efl_text_markup_set(tb, <font_size=20>Hello World</font_size>); where is this extra step?
Now I think I understand your comment, If user want to support rtf for example, because of such cases I feel Efl.AttributedString is the best solution for such support, just build two converter From/To and thats it.
By the way, we are planning 2020 to partially support HTML/CSS and expose this functionality to users.
But currently user can use Efl.TextFormatter to create annotated string from whatever markup language he want.

Future plan for Markup :
What we are planing about in the future, Is to introduce anew object called AttributedText,
1- This object is capable of representing String with attributes attached to it.
2- This object has no dependencies on text widgets or cursors.
And currently, we do not see any blocking implementation for this feature.

I understand your plan and why you are taking it, I do think it is not going to lead to a nice and simple API to use.

Almost all toolkits have such feature, Spans in android NSAttributedString in Cocoa, TextBuffer in GTK , QTextDocument in QT.
This is very common to deal with text and rich text without the need for Text Widget(single threaded ).

It would be nicer in my opinion if the Markup Generator code was split in its own class and that we could easily replace it.

I am missing something here, what you are referring to is internal class right?

This way someone instantiating an text object, will just set the Markup Generator they want (Or even write their own) and every use of markup on that object would do what they want right away. No cumbersome additional step. It was my understanding that @tasn plan was to go in that direction and I am a bit sad that we are going back to a suboptimal solution.

User will attach the generator to the widget? Currently, user can create his own parser with Efl.TextFormatter class, (but I hate that is now dependent on Text Widget to work).
In the future when we have Efl.AttributeString user can create his own parser for convert from/to Efl.AttributeString. which acts the same as Efl.TextFormatter but without any kind of dependency on TextWidget.
The only thing we need to do is to make Efl.AttributeString work efficiently with Text Widgets (no delay spent on parsing and it can be immutable to reduce memory usage)

@cedric
I am not catching exactly your comments, Are you referring to internal implementation or API exposed to users ?

API exposed to users

Can you please show me what you expect to expose to the user?

Well, something like: efl_text_markup_generator_set(widget, markdown_generator); and after that all call to a markup_get function on that widget would return a markdown markup text.

EFl markup is a special kind of markup, and I think we should keep its internal support. new markups that we would like to support can be implemented be converting them into EFL markup and vice-versa (where it have no dependencies on Widgets).

I do not like this path for two reason.

  1. It is a slow path. You first convert to EFL markup, emit it, parse it, convert to destination markup, free the EFL markup. While if you were tied to the widget API, you would directly just walk the text and generate the destination markup right away.

at least some part of markup parsing will be kept internal,
for example:
1- how can we support font size variation like <font_size=20px>, internally EFL should be able to do so,
2- Introduce new attributes like list or table in the text ? EFL internally should be able to understand and draw these attributes and tags

  1. It is a painful to use solution. Instead of getting the markup language you would want in your app, you end up with having to do additional step everywhere you use it.

I still do not get it, efl_text_markup_set(tb, <font_size=20>Hello World</font_size>); where is this extra step?

There isn't many people in the world who have their text represented in EFL markup format. Most of the world use other format, like markdown in the above example. The extra step is going from their format to EFL format.

Now I think I understand your comment, If user want to support rtf for example, because of such cases I feel Efl.AttributedString is the best solution for such support, just build two converter From/To and thats it.
By the way, we are planning 2020 to partially support HTML/CSS and expose this functionality to users.

That is a lot of work, but nice to hear about it. Depending on what you intend to support, you might need to have a higher level widget logic than just the string logic of a text widget.

But currently user can use Efl.TextFormatter to create annotated string from whatever markup language he want.

Yes, this is part of the infrastructure that a MarkupGenerator class would use indeed.

Future plan for Markup :
What we are planing about in the future, Is to introduce anew object called AttributedText,
1- This object is capable of representing String with attributes attached to it.
2- This object has no dependencies on text widgets or cursors.
And currently, we do not see any blocking implementation for this feature.

I understand your plan and why you are taking it, I do think it is not going to lead to a nice and simple API to use.

Almost all toolkits have such feature, Spans in android NSAttributedString in Cocoa, TextBuffer in GTK , QTextDocument in QT.
This is very common to deal with text and rich text without the need for Text Widget(single threaded ).

Everyone doing something doesn't justify it. If you want to have an non visual interface which support both cursor and markup API, I am completely fine with that idea too. But it is orthogonal to the discussion here I think.

It would be nicer in my opinion if the Markup Generator code was split in its own class and that we could easily replace it.

I am missing something here, what you are referring to is internal class right?

No, the MarkupGenerator interface would be public and anyone can implement their own. Allowing for any application to support any markup language they want transparently.

This way someone instantiating an text object, will just set the Markup Generator they want (Or even write their own) and every use of markup on that object would do what they want right away. No cumbersome additional step. It was my understanding that @tasn plan was to go in that direction and I am a bit sad that we are going back to a suboptimal solution.

User will attach the generator to the widget? Currently, user can create his own parser with Efl.TextFormatter class, (but I hate that is now dependent on Text Widget to work).

What is the problem with depending on TextWidget?

In the future when we have Efl.AttributeString user can create his own parser for convert from/to Efl.AttributeString. which acts the same as Efl.TextFormatter but without any kind of dependency on TextWidget.
The only thing we need to do is to make Efl.AttributeString work efficiently with Text Widgets (no delay spent on parsing and it can be immutable to reduce memory usage)

Is Efl.AttributeString basically going to be an Efl.TextBuffer that has all the same interface of an Efl.TextWidget, except it doesn't do any rendering and it proxy an existing widget to be efficient? I am quite not sure I understand your idea here correctly.

ali.alzyod added a comment.EditedJan 6 2020, 12:17 PM

@cedric
I am not catching exactly your comments, Are you referring to internal implementation or API exposed to users ?

API exposed to users

Can you please show me what you expect to expose to the user?

Well, something like: efl_text_markup_generator_set(widget, markdown_generator); and after that all call to a markup_get function on that widget would return a markdown markup text.

Now I understand it,

  • With current implementation and design we do not block adding Markup Generator in the future, now we support EflMarkup, in the future, we can add a generator set functionality and set it by default into EflMarkup generator.

EFl markup is a special kind of markup, and I think we should keep its internal support. new markups that we would like to support can be implemented be converting them into EFL markup and vice-versa (where it have no dependencies on Widgets).

I do not like this path for two reason.

  1. It is a slow path. You first convert to EFL markup, emit it, parse it, convert to destination markup, free the EFL markup. While if you were tied to the widget API, you would directly just walk the text and generate the destination markup right away.

at least some part of markup parsing will be kept internal,
for example:
1- how can we support font size variation like <font_size=20px>, internally EFL should be able to do so,
2- Introduce new attributes like list or table in the text ? EFL internally should be able to understand and draw these attributes and tags

  1. It is a painful to use solution. Instead of getting the markup language you would want in your app, you end up with having to do additional step everywhere you use it.

I still do not get it, efl_text_markup_set(tb, <font_size=20>Hello World</font_size>); where is this extra step?

There isn't many people in the world who have their text represented in EFL markup format. Most of the world use other format, like markdown in the above example. The extra step is going from their format to EFL format.

That is why we want to start partially supporting HTML and CSS

Now I think I understand your comment, If user want to support rtf for example, because of such cases I feel Efl.AttributedString is the best solution for such support, just build two converter From/To and thats it.
By the way, we are planning 2020 to partially support HTML/CSS and expose this functionality to users.

That is a lot of work, but nice to hear about it. Depending on what you intend to support, you might need to have a higher level widget logic than just the string logic of a text widget.

Yes it is a lot of work, but we can start with partial support, and with each release, we extend this support little by little.

But currently user can use Efl.TextFormatter to create annotated string from whatever markup language he want.

Yes, this is part of the infrastructure that a MarkupGenerator class would use indeed.

Yes it is, but what I meant was that EflMarkup needs to be supported by default, and internally EFL can understand it.

Future plan for Markup :
What we are planing about in the future, Is to introduce anew object called AttributedText,
1- This object is capable of representing String with attributes attached to it.
2- This object has no dependencies on text widgets or cursors.
And currently, we do not see any blocking implementation for this feature.

I understand your plan and why you are taking it, I do think it is not going to lead to a nice and simple API to use.

Almost all toolkits have such feature, Spans in android NSAttributedString in Cocoa, TextBuffer in GTK , QTextDocument in QT.
This is very common to deal with text and rich text without the need for Text Widget(single threaded ).

Everyone doing something doesn't justify it. If you want to have an non visual interface which support both cursor and markup API, I am completely fine with that idea too. But it is orthogonal to the discussion here I think.

supporting cursor and markup API is dependent either this new attributedText is EO object or not (maybe higher level class can support them which depend on attributed string), we did not decide yet.
And I think the common thing between this work and Markup Generator, is to allow users to create generator using this class, which is much easy in my opinion instead of missing up things (without guidance it is hard to create generators), markup language (not only markup) can be RTF or non xml, so converting is not that simple, each rich text format can have its own logic which is hard thing to implement directly on widget,

It would be nicer in my opinion if the Markup Generator code was split in its own class and that we could easily replace it.

I am missing something here, what you are referring to is internal class right?

No, the MarkupGenerator interface would be public and anyone can implement their own. Allowing for any application to support any markup language they want transparently.

Even now user can support it externally, and as I mention early current design does not block this feature (we can now assume the gennerator is by default EflMarkupGenerator)

This way someone instantiating an text object, will just set the Markup Generator they want (Or even write their own) and every use of markup on that object would do what they want right away. No cumbersome additional step. It was my understanding that @tasn plan was to go in that direction and I am a bit sad that we are going back to a suboptimal solution.

User will attach the generator to the widget? Currently, user can create his own parser with Efl.TextFormatter class, (but I hate that is now dependent on Text Widget to work).

What is the problem with depending on TextWidget?

Any Text Related process will need TextWidget and this is not necessary, for example (dummy example), if you want to process multiple files(written in EFL markup format), and replace text word "font" with the word "HELLO", we will need to upload file into widger then get the text the replace the word, the save widget content into file the upload other file, (we can not do it in parallel by the way because widget works on main thread only), I know it is a dummy example but it shows exactly the bottle nick of depending on widgets for text processing.

In the future when we have Efl.AttributeString user can create his own parser for convert from/to Efl.AttributeString. which acts the same as Efl.TextFormatter but without any kind of dependency on TextWidget.
The only thing we need to do is to make Efl.AttributeString work efficiently with Text Widgets (no delay spent on parsing and it can be immutable to reduce memory usage)

Is Efl.AttributeString basically going to be an Efl.TextBuffer that has all the same interface of an Efl.TextWidget, except it doesn't do any rendering and it proxy an existing widget to be efficient? I am quite not sure I understand your idea here correctly.

No it should not, maybe Higher level class can do that like EflDocument, currently Efl.AttributeString plan is plainText with a list of ranges and attributes to these ranges.

I am now a bit lost on HOW you plan to implement this, but I wanted to say that I still think that supporting multiple markup formats is important.
If I am not mistaken, @cedric's idea of a markup generator class only requires adding a markup_generator property to the Efl.Markup interface, which defaults to EFL Markup. Correct?
In this case, it can be added later on, and I am happy with this approach.

cedric added a comment.Jan 7 2020, 9:53 AM

I am also happy with the plan to add a markup_generator later on to support multiple markup language.

Ok !!

Then, everyone here likes the current definition. Am I right ? :)

Thanks :) Move to "stablized".

woohyun moved this task from Evaluating to Stabilized on the efl: api board.Jan 8 2020, 8:16 PM