diff --git a/py/examples/markdown.py b/py/examples/markdown.py
index dc4a6cb38d1..94d59cd73ab 100644
--- a/py/examples/markdown.py
+++ b/py/examples/markdown.py
@@ -14,6 +14,8 @@
___
The **quick** __brown__ *fox* **_jumped_ over** the ~~lazy~~ _dog_.
+This is superscript and this is subscript!
+
Block quote:
> The quick brown fox jumped over the lazy dog.
@@ -37,12 +39,6 @@
- First nested list item
- Second nested list item
-
-
-Ignore \*markdown\* formatting.
-
-This framework is made by [h2o.ai](https://h2o.ai)
-
Image:
![Monty Python](https://upload.wikimedia.org/wikipedia/en/c/cb/Flyingcircus_2.jpg)
@@ -61,8 +57,7 @@
Inline code:
-Use `git status` to list all new or modified files that haven't yet been committed.
-
+Use `ui.markdown_card` to start creating your own markdown content!
Code block:
@@ -81,17 +76,13 @@ async def serve(q: Q):
await q.page.save()
```
-This is superscript and this is subscript!
+
-Linking
---------------------
+Ignore \*markdown\* formatting.
-Search with [Google][1],
-[Yahoo][2] or [MSN][3].
+Linking:
- [1]: http://google.com/ "Google"
- [2]: http://search.yahoo.com/ "Yahoo Search"
- [3]: http://search.msn.com/ "MSN Search"
+This framework is made by [h2o.ai](https://h2o.ai)
'''
@app('/demo')
diff --git a/ui/src/markdown.tsx b/ui/src/markdown.tsx
index f908988335a..ea1a9f7d671 100644
--- a/ui/src/markdown.tsx
+++ b/ui/src/markdown.tsx
@@ -51,8 +51,8 @@ const
}
},
})
-const highlightSyntax = async (str: S, language: S, codeBlockId: S) => {
- const codeBlock = document.getElementById(codeBlockId)
+const highlightSyntax = async (str: S, language: S, codeElementId: S) => {
+ const codeBlock = document.getElementById(codeElementId)
if (!codeBlock) return ''
if (language) {
try {
@@ -81,21 +81,23 @@ const highlightSyntax = async (str: S, language: S, codeBlockId: S) => {
return highlightedCode
}
-export const Markdown = ({ source, compact = true }: { source: S, compact?: B }) => {
+export const Markdown = ({ source, name, compact = true }: { source: S, name: S, compact?: B }) => {
const
prevHighlights = React.useRef([]), // Prevent flicker during streaming.
codeBlockIdx = React.useRef(0), // MarkdownIt parses code blocks sequentially, which is a problem for streaming.
markdown = React.useMemo(() => MarkdownIt({
html: true, linkify: true, typographer: true, highlight: (str, lang) => {
const codeBlockId = codeBlockIdx.current.toString()
+ // Use the unique html element id to avoid conflicts when multiple markdown cards are rendered on the same page.
+ const codeElementId = `${name}-${codeBlockId}`
if (prevHighlights.current.length === codeBlockIdx.current) prevHighlights.current.push('')
// HACK: MarkdownIt does not support async rules.
// https://github.com/markdown-it/markdown-it/blob/master/docs/development.md#i-need-async-rule-how-to-do-it
- setTimeout(async () => prevHighlights.current[+codeBlockId] = await highlightSyntax(str, lang, codeBlockId), 0)
+ setTimeout(async () => prevHighlights.current[+codeBlockId] = await highlightSyntax(str, lang, codeElementId), 0)
// TODO: Sanitize the HTML.
- const ret = `${prevHighlights.current[codeBlockIdx.current] || str}
`
+ const ret = `${prevHighlights.current[codeBlockIdx.current] || str}
`
codeBlockIdx.current++
return ret
}
@@ -163,7 +165,7 @@ export const
)