# Subclassing racket/gui editor%

**URL:** <https://racket.discourse.group/t/subclassing-racket-gui-editor/1058>\
**Category:** Questions & Answers\
**Tags:** gui\
**Created:** [June 4, 2022, 9:10pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058 "2022-06-04T21:10:58Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [June 4, 2022, 9:10pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/1 "2022-06-04T21:10:58Z")

</div>

I want to create a version of the text% editor that can reflow text around images. This is for a simple HTML renderer. I'm looking for advice on how to approach this because it seems like the implementation of racket/gui is going to make it difficult.

Ideally, I'd like to just create a new subclass of editor% alongside text% and pasteboard%, but I don't think this will work for a number of reasons. For one, editor-canvas% assumes that editor%s are either text% or pasteboard%. It is also hard to determine what exactly I'd need to do in a new editor% to satisfy editor-canvas%.

Subclassing text% and changing how it handles text flow is another option but the way that the editor classes have a super class in the wx layer makes it difficult to subclass them. For example, the main text% inherits from another class in the wx layer also called text%. The behavior I want to change is mostly implemented in the wx layer, so if I subclassed the text% in that layer I would also have to re-implement all the text% code in the main layer.

I'm not that experienced with Racket's class system, so perhaps there is a viable approach that I'm just not aware of. Any advice is appreciated!

---

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [June 9, 2022, 8:57pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/2 "2022-06-09T20:57:26Z")

</div>

Is it possible to `require` the wx layer from application code? I'm looking at the definition of `editor-canvas%` in mrcanvas.rkt and it requires wx.rkt, wxcanvas.rkt, mrwindow.rkt, etc. using filenames. Is any of this stuff available in a module I can `require` from my application code?

EDIT: perhaps I'm over complicating and it is possible to do what I need by just subclassing `canvas%` and creating something similar to `editor-canvas%` that also includes some `editor%`-like functionality. I'm just reluctant to start writing a bunch of code only to realize later that what I want to achieve isn't possible. If I can insert snips and render them the way I want to in the `dc%` provided by `get-dc`, I should be ok though, right?

---

<div class="post-metadata">

**Author:** ![alexh](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/alexh/32/315_2.png) [@alexh](https://racket.discourse.group/u/alexh)\
**Post date:** [June 9, 2022, 10:42pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/3 "2022-06-09T22:42:48Z")

</div>

> [@jjsimpso](#):
>
> I want to create a version of the text% editor that can reflow text around images. This is for a simple HTML renderer. I'm looking for advice on how to approach this because it seems like the implementation of racket/gui is going to make it difficult.

From my little experience with the editor classes, I don't think they are designed to be able to extend the text re-flowing behavior and, as far as I know they don't already support that. To do what you want you will need to modify these classes inside the `racket/gui` library, or write your own HTML renderer from scratch using `canvas%`. Both of these alternatives would require a lot of work.

On the other hand, if you relax the "simple HTML renderer" requirement to not flow text around images, you can look at this blog post on how to implement one on top of `text%`. The code can be used almost directly, singe Greg's markown parser already produces HTML like expressions:

> **[Markdown View using the Racket editor%](https://alex-hhh.github.io/2020/05/markdown-view.html)**
>
> The Racket text% editor class can be used to display multi line text with formatting, such as fonts and colors; it is however, somewhat difficult to set it up and use its formatting capabilities. This blog post shows how to build a text view which...

Hope this helps,  
Alex.

---

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [June 10, 2022, 1:40am UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/4 "2022-06-10T01:40:01Z")

</div>

Thank you for the response. It is good to at least confirm my current understanding.

For my use case I'm only interested in rendering HTML 3.2 and earlier and I don't care about things like css or perfect accuracy. So this at least limits my scope a bit. I already have a [basic implementation](https://github.com/jjsimpso/molasses/blob/main/src/html.rkt) using `html-parsing` and `text%`, but I knew at some point I'd have to handle text flow around images plus implement tables, etc. I also considered a _really ugly_ hack where I have a custom snip with an image and some text and manually flow the text around it with the snip's draw function. The was an interesting experiment but I don't think it is a practical solution. I might be able to implement tables with a custom snip though.

Working within racket/gui is something I've also considered, but I think it may be easier to create a new class rather than try to modify `text%`. `text%` has a lot of complexity that I don't need for my use case. If I can muster the energy I may attempt working off of `canvas%`.

I didn't originally intend to take this as far as I already have, but now I'm finding it hard to let it go!

---

<div class="post-metadata">

**Author:** ![soegaard](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/soegaard/32/19_2.png) [@soegaard](https://racket.discourse.group/u/soegaard)\
**Post date:** [June 10, 2022, 4:10pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/5 "2022-06-10T16:10:41Z")

</div>

FWIW you can require `mrcanvas.rkt` like this:

> (require mred/private/mrcanvas)

I am not sure that's the way to go though.

Out of curiosity - have you looked at the how the old `browser` library did it?  
It was used to display help pages directly in DrRacket (Well, DrScheme at the time).  
[Disclaimer: I have never looked at the code of `browser`]

[https://docs.racket-lang.org/browser/index.html](https://docs.racket-lang.org/browser/index.html)

---

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [June 10, 2022, 6:44pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/6 "2022-06-10T18:44:22Z")

</div>

> [@soegaard](#):
>
> FWIW you can require `mrcanvas.rkt` like this:  
> (require mred/private/mrcanvas)

Thanks for this. I'm not sure this is the way to go either, but I like having the option.

I did look at `browser` when I began investigating this and I borrowed some ideas from there. But I don't believe it handles text flow or any of the more complicated things like tables. I haven't tried using the browser code directly, but I think what I have written so far is probably more capable. I'd be happy to be proven wrong about this though!

---

<div class="post-metadata">

**Author:** ![greghendershott](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/greghendershott/32/98_2.png) [@greghendershott](https://racket.discourse.group/u/greghendershott)\
**Post date:** [June 11, 2022, 12:45pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/7 "2022-06-11T12:45:13Z")

</div>

Keep in mind the `private/*` convention means you'd be using private implementation stuff. The author could change it and break your use, someday.

(OTOH that might not matter much; depends on what you want to do with your own project, eventually.)

---

<div class="post-metadata">

**Author:** ![jjsimpso](https://yyz2.discourse-cdn.com/free1/user_avatar/racket.discourse.group/jjsimpso/32/602_2.png) [@jjsimpso](https://racket.discourse.group/u/jjsimpso)\
**Post date:** [December 11, 2023, 7:08pm UTC](https://racket.discourse.group/t/subclassing-racket-gui-editor/1058/8 "2023-12-11T19:08:34Z")

</div>

It has been over a year, but i wanted to follow up and post the solution I finally arrived at. I subclassed `canvas%` and created a new canvas that handles text flow. In a sense, my new class `layout-canvas%` is a combination of `editor%` and `editor-canvas%`.

`layout-canvas%` has modes for non-wrapped text, word wrapping, and a layout mode that implements the alignment and text flow. It supports snips and strings with an attached style. I'm currently working on a table snip. There are still lots of bugs and missing features, but it is coming along nicely.

The project I'm using this in is:

> **[GitHub - jjsimpso/molasses: Browser for the slow internet (gopher and gemini)](https://github.com/jjsimpso/molasses)**
>
> Browser for the slow internet (gopher and gemini). Contribute to jjsimpso/molasses development by creating an account on GitHub.

Here's a screen shot of some html:

 ![Screenshot from 2023-12-09 11-43-34](https://global.discourse-cdn.com/free1/uploads/racket/original/2X/0/02cb52d0c07c3d2ca274634b821d7415064a4dd0.png)
