[DONE] Seeking: a Rich Text display

Objective: Display of moderately-formatted help text, or other instructional text. You’re reading a positive example right now.

Should handle

  • relative font sizing (for titles and headings)
  • bold, italic, underline
  • proportional and monospaced fonts
  • superscript and subscript (e.g., for minor math effects)
  • numbered and unnumbered lists
  • word wrap

Raw format may be a subset of XHTML, XML, Markdown, ReStructuredText (such as used to build Python’s documentation), etc… Strictly limited, for good security and performance.

While this could be done, in principle, via a Canvas, that would require a fair bit of code, to respect margins et al. It would probably be better to translate into HTML, thus leveraging the browser’s built-in display features.

15 Likes

Would love to see this too

+1

I would also find this useful to save time vs writing it manually.

UPDATED - uses an API to convert - should have most tags in there.

EDIT - ok , the API is not very reliable either, but you get the point :slight_smile:

Ok, a simple proof of concept …

https://anvil.works/ide#clone:DB7P3J5H66WTW5RN=MSR52MBDCQSOWGOUFVY2CCF6

You drop the custom component onto your form just like a label, then call :

self.<customcomponentname>.text="Hello *everybody*"

Only supports asterisk for now, but you can see the principle.

Is that broadly what everyone meant? If so I might have a bash at getting it to parse the whole markdown bit.

If not, then …oops :slight_smile:

1 Like

I think it’d be awesome to just have some component that lets me insert actual HTML. I know that’s a big escape hatch to have right in the toolbox, but I’m not really sure how I should do <p>Hello <b>World</b></p> in Anvil right now, let alone something like colouring certain letters in a string (in HTML I’d just do <span style='color:red'> or whatever).

Thank you immensely! I hope to look closer at this later.

A long time ago I had plans to use ReStructured Text. It made sense to me, since an RST-to-HTML converter, docutils, is already available on the server, and RST is Python’s standard for documentation.

Eventually, RST’s extension mechanism could be leveraged for specifying data-entry widgets, e.g., for direct insertion into the running text. Does Markdown have such a mechanism?

You’re right, direct insertion of HTML is a potential minefield. This is why I think that using a markup language is on the right track. Even if malformed, it can still be displayed as-is, and still look semi-reasonable.

1 Like

I just did a test for a project I’m working on, and if you put the mistune.py file from https://github.com/lepture/mistune into a server module running Python 3, you can use it from other server modules to convert Markdown to HTML.

I have a custom HTML form whose HTML property is set to the result of that conversion, and then that custom form gets embedded into another form so that the Markdown result is only part of the final form that gets displayed.

It’d be nice if a Markdown library were added to the available server modules, but until then this is a way to do the conversion for display purposes.

mistune.py will not run in the client due to its reliance on the inspect module, which isn’t available in Skulpt.

1 Like

We’ve just installed mistune in the Server Module environment. So you can now convert Markdown to HTML without needing to copy-paste the mistune module into Anvil.

https://anvil.works/ide#clone:YQWUZQFCP5A5IQ2H=27BCTY6GFMHGHSK53UEYVDIB

5 Likes

I’ve since switched to using BBCode, which worked better for customizing for my app. Can we also get the BBCode module installed on the server? https://pypi.org/project/bbcode/

Thanks for installing mistune in the server module environment. I will definitely use it.

But… it would be even better if Label had a markdown property, so there would be no need for a round trip and I could do:

label_1.markdown = True
label_1.text = 'Hello :earth_americas:!'

and see:

Hello :earth_americas:!

3 Likes

@shaun do you happen to know if there is a way to achieve syntax highlighting so

```python
print(“help”)
```

becomes

print("help")

If we had the module pygments we could have something like the following so we could get syntax highlighting.

text="""```python\nprint("help")\n```"""
import mistune
from pygments import highlight
from pygments.lexers import get_lexer_by_name
from pygments.formatters import html
class HighlightRenderer(mistune.Renderer):
    def block_code(self, code, lang):
        if not lang:
            return '\n<pre><code>%s</code></pre>\n' % \
                mistune.escape(code)
        lexer = get_lexer_by_name(lang, stripall=True)
        formatter = html.HtmlFormatter()
        return highlight(code, lexer, formatter)
renderer = HighlightRenderer()
markdown = mistune.Markdown(renderer=renderer)
print(markdown(text))

output:

<div class="highlight"><pre><span></span><span class="k">print</span><span class="p">(</span><span class="s2">&quot;help&quot;</span><span class="p">)</span>
</pre></div>

We’ll get pygments and bbcode installed soon.

If you want to do the syntax highlighting in the browser, you could consider highlight.js. You can include it from a CDN like so:

<link rel="stylesheet"
      href="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.13.1/build/styles/default.min.css">
<script src="//cdn.jsdelivr.net/gh/highlightjs/cdn-release@9.13.1/build/highlight.min.js"></script>

Then do something like this:


$('div.code').each(function(i, block) {
  hljs.highlightBlock(block);
});

to enact the highlighting. Obviously you could wrap this in a JavaScript function and call_js every time you want to refresh the highlighting. So in my Skulpt example, you could put the code in an Anvil TextArea (instead of an HTML textarea) and call_js to the highlighting function from the change event handler.

4 Likes

Amazingly helpful!! Thanks Shaun.

Pygments and bbcode are both installed :slight_smile:

5 Likes

Quill is great JS library that does rich text (thanks to @joinlook for finding it)

(We fixed the error he mentioned, here it is in action:)

Here’s all the JS you need to run it:

<!-- Initialize Quill editor -->
<script>
  var quill = new Quill('#editor-container', {
  modules: {
    toolbar: [
      [{ header: [1, 2, false] }],
      ['bold', 'italic', 'underline'],
      ['image', 'code-block']
    ]
  },
  placeholder: 'Compose an epic...',
  theme: 'snow'  // or 'bubble'
});
</script>

Here’s a clone link for that app:

https://anvil.works/build#clone:PN36FXDXJF4YXIUO=Q4SFH4UYMYMGX3GWDSLL4FSH

4 Likes

so simple.

a good king he!

1 Like

Here is an example of converting the quill delta representation into HTML that can be perhaps sent in an email.

https://anonymish.anvil.app

https://anvil.works/build#clone:4WZ3DTRQGVHDWZIM=KKU7WQABSU4C5BF3GD675D3D

2 Likes

Something changed and this is no longer able to read the html contents from the rich text editor. If you open the clone link you can see what happens. The error returned is:

ExternalError: ReferenceError: WrappedPythonValue is not defined at [email_drafter, line 15]

I noticed this because in my real project which I use the text editor, it suddenly stopped working. It used to work and nothing changed in the clone link, so do you think this a jquery issue, an anvil issue, or a quill issue?

Sorry about that - thanks for the heads-up. Now fixed.

1 Like