Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tech] Consider enabling html in markdown components #675

Open
huong-li-nguyen opened this issue Sep 3, 2024 · 1 comment
Open

[Tech] Consider enabling html in markdown components #675

huong-li-nguyen opened this issue Sep 3, 2024 · 1 comment
Assignees
Labels
Feature Request 🤓 Issue contains a feature request

Comments

@huong-li-nguyen
Copy link
Contributor

huong-li-nguyen commented Sep 3, 2024

I'll outline my thoughts here for us to discuss properly:

With the new header and footer arguments being enabled, we want to allow users to add more information to their charts. Currently, doing everything in pure Markdown feels cumbersome because many tasks are either impossible or not straightforward to implement. Here are some limitations where enabling HTML would be beneficial:

1. Customising fonts (e.g. apply coloring, apply different font-sizes, etc)

Markdown does not support text coloring: Markdown Font Color

However, I believe text coloring is an essential feature that HTML could easily solve. Here are some visual examples of why I'd like to be able to color fonts within Markdown. It's mainly to emphasize a narrative within the visualization or even replace a legend. Remember, AgGrid and DataTable do not come with an embedded color scale legend natively if you apply cell coloring. With AgGrid, there's a workaround by installing a third-party library, but I haven't explored a solution for DataTable yet. Enabling font colors in the footer could easily address this without requiring another library or a hacky solution. I also often see colors used in subtitles to emphasize certain data points.

Screenshot 2024-09-03 at 10 04 44:

Screenshot 2024-09-03 at 10 04 51

While coloring is the most crucial argument for me, other considerations include applying custom font families, sizes, text alignments etc, which are either only possible via HTML or just simpler to do.

2. Apply CSS styling

This one is normally simpler to do in HTML as you can provide classNames or inline styles directly, which is simpler to do for CSS beginners. However, as soon as someone wants to style something with pure markdown - it is possible, but they have to know CSS selectors really well. They have to know the hierarchies and have to know how to selectively target elements in their hierarchy (p, h1, h2, img) if they do not want to apply it to all.

For me either of this works, but I am wondering how intuitive this actually is for CSS beginners and whether they even need more sophisticated styling. Or if we can assume that people who would like more sophisticated styling are automatically familiar with CSS?

3. Embedding interactive elements (e.g. buttons)

This actually seems fine in both markdown and HTML. For example, to create a button that proceeds to a link when clicked, use the following format:

[![Get it on SERVICE](https://gist.github.com/cxmeel/0dbc95191f239b631c3874f4ccf114e2/raw/SERVICE.svg)](https://example.com/...)

However, positioning it and styling it properly requires point 2) applying CSS via selectors.

@antonymilne
Copy link
Contributor

Very interesting topic! Enabling HTML is indeed a possible solution here but I would also like us to investigate an alternative solution(s) that go something like:

  • extend markdown to apply a restricted set of useful things in a markdown-type syntax, e.g. just to apply a class name to something like (and then do all styling through CSS)
  • use BBCode which enables e.g. color tag possible Python packages: 1 2

The advantages of this would be:

  • it's more consistent/declarative/simple like markdown rather than using HTML syntax
  • it potentially enables things that aren't at all possible in HTML (e.g. solving get_asset_url problem explained below)
  • it could handle untrusted user input more safely than enabling all HTML

The disadvantages are:

  • it's much much more work than just enabling HTML
  • it basically enables a subset of HTML so is less powerful and so might need to be continually extended

In addition to the things you mention above, here's some things I thought before we might like to do in HTML/some extension of markdown:

  • some way of inserting Google materials icon directly just using icon string, e.g. <icon_name>. Note if we enable some way of specifying a classname that renders as <span class="..."> then that's sufficient
  • some way to handle the get_asset_url problem

A very rough dump of notes I made before

Something else I wondered about before and we might like to consider in future is whether we could extend markdown syntax to make it easier for people to do things that might be common in VizX but are not so easy to do in pure markdown. A bit like this way of specifying a form. Let’s wait and see what people try to do with the cards and then see if there’s common difficulties that we might be able to resolve.

I can confirm that dcc.Markdown only supports commonmark and not Github flavoured markdown (GFM), and so our docstring is correct. Actually I wonder if at some point we should make our own custom dcc.Markdown that enables GFM - this would be very easy because react-markdown is very nicely designed to be extensible, and there’s a remark-gfm plugin. There’s actually lots of plugins that could be useful for us, e.g. remark-images would make it easier for someone who doesn't know markdown to put in an image. It would be nice to have autolinks like in GFM also. Links: 1 2 3

Look at GFM (specification GitHub Flavored Markdown Spec) for allowing HTML also. See https://community.plotly.com/t/how-to-use-dcc-link-in-dcc-markdown-for-high-performance-links/66781
Commonmark: CommonMark Spec

Could parse markdown using miyuchina/mistletoe: A fast, extensible and spec-compliant Markdown parser in pure Python. and then edit in Python rather than making custom markdown plugin.

https://community.plotly.com/t/dash-mistletoe-a-customizable-markdown-parser/70456

I really like the idea! I used the same approach for writing the dash-extensions docs. It works well for documentation, and other text-heavy report-like apps.

Also very interestingL: https://pypi.org/project/dash-down/

The get_asset_url problem

Same problem applies to get_relative_url and any other similar also.

If you provide an image in Markdown inside Card.text this is actually very tricky to do correctly because the correct code would use dash.get_asset_url("/images/blah.png"), and so you currently *have* to do the incorrect thing and just hardcode in the path as assets/images/blah.png. This is how our examples and docs suggest you do it, and it's the best we can do for now but is not a perfect solution e.g. it will break if you specify a custom assets_external_url in Vizro() or host somewhere that is not at the root, e.g. at http://www.website.com/many_dashboards/dashboard_1`. This would probably also be an issue on databricks and through jupyter-server-proxy and anywhere else where a requests_pathname_prefix.

Note this can’t be solved just by writing get_asset_url into the Markdown code using f-string in Python, because you define vm.Card before Dash is instantiated, so get_asset_url doesn’t work!

It will take a long time before anyone discovers this is a problem so I’m happy to ignore it for now. Since it’s not such an easy one to fix, and there are ok workarounds for the user. In reality, the current situation won't cause any problems apart from in some deployment scenarios, and even then you could fix it manually without too much difficulty.

Maybe solve through Markdown extension or relying on environment variable to get paths in deployment? Or just saying your Dash instantiation must go first and you need to use Python specification rather than YAML.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature Request 🤓 Issue contains a feature request
Projects
None yet
Development

No branches or pull requests

3 participants