This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
This repository was archived by the owner on Aug 29, 2025. It is now read-only.

Issue 596 - Add Markdown presentation - #606

Merged
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns
Jan 7, 2020
Merged

Issue 596 - Add Markdown presentation#606
Marc-Andre-Rivet merged 49 commits into
devfrom
596-markdowns

Conversation

@Marc-Andre-Rivet

@Marc-Andre-RivetMarc-Andre-Rivet commented Sep 30, 2019

Copy link
Copy Markdown
Contributor

Fixes#596

  • check virtualized performance

  • virtualized behavior (varying row height -- breaks assumptions, this will be dealt outside the scope of this PR as this behavior is not caused by MD)

  • varying row height with fixed columns (Using DataTable row_selectable and row_deletable with fixed columns results in mismatched row heights #649)

  • navigation through and from markdown cell

  • define copy/paste behavior (?!)

  • define filter behavior -- for now filters will behave the same way for markdown cells as for any other text cells (the value filtered on is the actual value in the df) -- expect at least one visual/sanity test for the filter behavior (guard rail)

  • define sort behavior (supporting/using displayed values is out of scope) -- for now sort will behave the same way for markdown cells as for any other text cells (the value sorted on is the actual value in the df) -- expect at least one visual/sanity test for the sort behavior (guard rail)

  • visual tests -- cover as much of md syntax as possible

  • behavior on non-text input value + test (e.g. number, boolean values, how does ReMarkable behave)

  • markdown image resize (test, docs)

  • more tests

  • docs (will be done in https://github.com/plotly/dash-docs/pull/733)

  • Test: Default highlight.js included with table does not assign itself to window.hljs

  • Test: Loading external highlight.js will take precedence on the table's version

- change reset css to allow markdown styling
Comment threadsrc/dash-table/components/CellMarkdown/index.tsx
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from fe1cab8 to 9972df4CompareDecember 3, 2019 16:13
This preserves alignment for code and lists.
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 5 times, most recently from b69da8a to e7f63fbCompareDecember 3, 2019 20:06

@Marc-Andre-RivetMarc-Andre-Rivet left a comment

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Navigation works well when the user single clicks on the cell, on a double click the focus goes back to the page's body and navigation inside the table becomes impossible

  2. Seeing quite a few percy diffs for fixed columns / rows test cases

Very nice visual tests 😄

}

export default class CellMarkdown extends PureComponent<IProps> {
private static md: Remarkable = new Remarkable();

@Marc-Andre-RivetMarc-Andre-RivetDec 5, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've been thinking that maybe we can include the configuration for highlight.js usage, externalize the resource and expect special code block users to include the highlight.js they want as a resource from https://highlightjs.org/download/ ?! Either that or (1) not support it at all or (2) asyncing the resource -- in which case React.Suspense won't do and we'll have to handle it through state on CellMarkdown. This is mostly about completeness.. we should not load JS by default as it will involve a very special use case.

 private static md: Remarkable = new Remarkable({
highlight: (value: string, language: string) => {
const hljs: any = (window as any).hljs;
if (!hljs) {
return '';
}
if (language && hljs.getLanguage(language)) {
try {
return hljs.highlight(language, value).value;
} catch (_) { }
}
try {
return hljs.highlightAuto(value).value;
} catch (_) { }
return '';
}
});

I don't think we should flat out not support highlighting and I don't think this will ever be enough of a priority on its own to be fixed later, if possible I think I'd rather get it in w/ async and wrap it up.

Comment thread@Types/modules.d.ts
highlightjs.registerLanguage('xml', xml);
highlightjs.registerLanguage('yaml', yaml);

export default highlightjs;

@Marc-Andre-RivetMarc-Andre-RivetDec 17, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since this is now our own cherry-picked version of Highlight.js would rather see this somewhere inside of /src, even if it's just /src/third-party/Highlight.js or some variation.


declare class Remarkable {
constructor();
constructor(options?: any);

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


declare interface RemarkableCtor {
new(): Remarkable;
new(options?: any): Remarkable;

@Marc-Andre-RivetMarc-Andre-RivetDec 19, 2019

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that with @types/Remarkable added, all of the remarkable definitions becomes redundant.

Comment thread@Types/modules.d.ts
Comment threadtslint.json Outdated
"cypress/**",
"inst/**",
"node_modules/**",
"third-party/**",

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is now redundant

@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 4 times, most recently from 234fe22 to fc63409CompareDecember 20, 2019 20:43
@shammamah-zz
shammamah-zzforce-pushed the 596-markdowns branch 2 times, most recently from 86f0485 to a2af831CompareDecember 23, 2019 20:52
@Marc-Andre-Rivet

Marc-Andre-Rivet commented Jan 7, 2020

Copy link
Copy Markdown
ContributorAuthor

@shammamah Testing navigation with:

import dash
from dash_html_components import Div
from dash_table import DataTable
app = dash.Dash(__name__)
data=[
dict(a=1, b='''```javascript
return 20;```
'''),
dict(a=1, b='''```js
console.log(\'pouet\');
'''),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```'),
dict(a=1, b='```js console.log(\'pouet\'); ```')
]
app.layout = Div([
DataTable(
columns=[
dict(name='a', id='a', editable=True),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
DataTable(
columns=[
dict(name='a', id='a'),
dict(name='b', id='b', type='text', presentation='markdown')
],
data=data,
editable=False
),
])
app.run_server(debug=True)

Notice that for both tables it's possible to click/select a markdown cell and keyboard/navigate within the markdown column as expected. The top table, with editable=True, does not behave correctly after keyboard/navigate from column a to b. Notice that it's now impossible to keyboard/navigate. Does not apply to the read-only table.

@Marc-Andre-Rivet
Marc-Andre-Rivet merged commit bbe12fe into devJan 7, 2020
@Marc-Andre-Rivet
Marc-Andre-Rivet deleted the 596-markdowns branch January 7, 2020 20:20
@muzamalrana

Copy link
Copy Markdown

hi Can anyone help me here ? I am totally stuck. Trying to embedd image from link into dash table cell. Following is the code snippet.
html.Div([dt.DataTable(id='my-data',
columns=[
{"id": 'artist_image', "name": "artist_image", "presentation": "markdown"},
{"id": 'song_artist', "name": "song_artist"},
{"id": 'monthly_listeners', "name": "monthly_listeners"},
{"id": 'artist_followers', "name": "artist_followers"},
{"id": 'artist_popularity', "name": "artist_popularity"}]
,style_as_list_view=True,
filter_action="native",
sort_action="native",
sort_mode="multi",
column_selectable="single",
style_data_conditional=[
{
'if': {'row_index': 'odd'},
'backgroundColor': '#000000'
}
],
style_cell={'textAlign': 'center','padding': '5px','backgroundColor':'#00FF00',
'color':'white'},
style_header={
'backgroundColor': '#202020',
'fontWeight': 'bold','color':'white'
})],className='ten columns')])],className='row')], style=tab_style, selected_style=tab_selected_style)
@app.callback(
dash.dependencies.Output('my-data','data'),
[dash.dependencies.Input('my-graph1', 'clickData'),
dash.dependencies.Input('my_dropdown1', 'value'),
dash.dependencies.Input('radio_buttons', 'value'),
dash.dependencies.Input('my_dropdown3', 'value')]
)
def update_graph(click_data,dropdown,radio_button,dropdown3):
try:
genre1=click_data['points'][0]['customdata'][1]
except:
genre1='pop'
artist_data1=sm.artist_dataFrame(songs,artist,click_data,dropdown,radio_button)
print(artist_data1.head(1))
artist_data1=artist_data1[['artist_image','song_artist','monthly_listeners','artist_followers','artist_popularity','date_x']]
artist_data1['date_x']=pd.to_datetime(artist_data1['date_x'])
artist_data1=artist_data1[artist_data1['date_x']==artist_data1['date_x'].max()]
artist_data1=artist_data1.sort_values(by=radio_button,ascending=False).reset_index(drop=True)
artist_data1=artist_data1.drop(['date_x'],axis=1)
if dropdown3==0 or dropdown3=='All':
artist_data1=artist_data1
else:
artist_data1=artist_data1.head(dropdown3)
artist_data1['artist_image']=[html.Img(src=i) for i in artist_data1['artist_image']]
return artist_data1.to_dict('records')

Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Allow for Markdown formatting in table cells

3 participants

@Marc-Andre-Rivet@muzamalrana@chriddyp