Add prepending text for specific headers (h1, h2, h3)
diff --git a/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.test.tsx b/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.test.tsx
index b3bd3f0a688a..745271b16d87 100644
--- a/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.test.tsx
+++ b/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.test.tsx
@@ -188,4 +188,43 @@ describe("Heading", () => {
     expect(wrapper.find("h1").text()).toEqual("hello")
     expect(wrapper.find("StyledStreamlitMarkdown")).toHaveLength(0)
   })
+
+  it("does not render ol block", () => {
+    const props = getHeadingProps({ body: "1) hello" })
+    const wrapper = mount(<Heading {...props} />)
+    expect(wrapper.find("h1").text()).toEqual("1) hello")
+    expect(wrapper.find("ol")).toHaveLength(0)
+  })
+
+  it("does not render ul block", () => {
+    const props = getHeadingProps({ body: "* hello" })
+    const wrapper = mount(<Heading {...props} />)
+    expect(wrapper.find("h1").text()).toEqual("* hello")
+    expect(wrapper.find("ul")).toHaveLength(0)
+  })
+
+  it("does not render blockquote with >", () => {
+    const props = getHeadingProps({ body: ">hello" })
+    const wrapper = mount(<Heading {...props} />)
+    expect(wrapper.find("h1").text()).toEqual(">hello")
+    expect(wrapper.find("blockquote")).toHaveLength(0)
+  })
+
+  it("does not render tables", () => {
+    const props = getHeadingProps({
+      body: `| Syntax | Description |
+    | ----------- | ----------- |
+    | Header      | Title       |
+    | Paragraph   | Text        |`,
+    })
+    const wrapper = mount(<Heading {...props} />)
+    expect(wrapper.find("h1").text()).toEqual(`| Syntax | Description |`)
+    expect(wrapper.find("StyledStreamlitMarkdown").text()).toEqual(
+      `| ----------- | ----------- |
+| Header      | Title       |
+| Paragraph   | Text        |
+`
+    )
+    expect(wrapper.find("table")).toHaveLength(0)
+  })
 })
diff --git a/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.tsx b/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.tsx
index 69a11ed3fb1c..6799fcffb409 100644
--- a/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.tsx
+++ b/frontend/src/components/shared/StreamlitMarkdown/StreamlitMarkdown.tsx
@@ -303,6 +303,24 @@ export function LinkWithTargetBlank(props: LinkProps): ReactElement {
   )
 }
 
+function makeMarkdownHeading(tag: string, markdown: string): string {
+  switch (tag.toLowerCase()) {
+    // willhuang1997: TODO: could be refactored to Enums
+    case "h1": {
+      return `# ${markdown}`
+    }
+    case "h2": {
+      return `## ${markdown}`
+    }
+    case "h3": {
+      return `### ${markdown}`
+    }
+    default: {
+      throw new Error(`Unrecognized tag for header: ${tag}`)
+    }
+  }
+}
+
 export function Heading(props: HeadingProtoProps): ReactElement {
   const { width } = props
   const { tag, anchor, body } = props.element
@@ -315,7 +333,7 @@ export function Heading(props: HeadingProtoProps): ReactElement {
     <div className="stMarkdown" style={{ width }}>
       <HeadingWithAnchor tag={tag} anchor={anchor}>
         <RenderedMarkdown
-          source={heading}
+          source={makeMarkdownHeading(tag, heading)}
           allowHTML={false}
           // this is purely an inline string
           overrideComponents={{

<!--
Before contributing (PLEASE READ!)

⚠️ If your contribution is more than a few lines of code, then prior to starting to code on it please post in the issue saying you want to volunteer, then wait for a positive response. And if there is no issue for it yet, create it first.

This helps make sure:

  1. Two people aren't working on the same thing
  2. This is something Streamlit's maintainers believe should be implemented/fixed
  3. Any API, UI, or deeper architectural changes that need to be implemented have been fully thought through by Streamlit's maintainers
  4. Your time is well spent!

More information in our wiki: https://github.com/streamlit/streamlit/wiki/Contributing
-->

## 📚 Context

Currently, I broke StreamlitMarkdown by refactoring Heading to its own component. This was done because we removed the "#" that was prepended by the backend. However, we are readding them on the frontend. I tried adding the `ReactMarkdown` prop `allowedElements` and `disallowedElements` in two separate testing scenarios and they both seem to not work. 
`allowedElements` just did not print anything.
`disallowedElements` printed things but when it was introduced to disallowedElements such as `li`, it just didn't show anything.
- What kind of change does this PR introduce?

  - [x] Bugfix
  - [ ] Feature
  - [ ] Refactoring
  - [ ] Other, please describe:

## 🧠 Description of Changes
Adding a method that prepends a # or ## or ### based on the tag. 
- _Add bullet points summarizing your changes here_

  - [ ] This is a breaking API change
  - [x] This is a visible (user-facing) change

**Revised:**
<img width="1175" alt="Screen Shot 2022-09-09 at 3 36 12 PM" src="https://user-images.githubusercontent.com/16749069/189454729-6529066e-60b9-40c7-bb0e-82aca1cd3638.png">

_Insert screenshot of your updated UI/code here_

**Current:**
<img width="973" alt="Screen Shot 2022-09-09 at 3 36 24 PM" src="https://user-images.githubusercontent.com/16749069/189454752-c806f7a2-ca4c-43ca-a178-14220c649bfd.png">

_Insert screenshot of existing UI/code here_

## 🧪 Testing Done

- [x] Screenshots included
- [x] Added/Updated unit tests
- [ ] Added/Updated e2e tests

## 🌐 References

_Does this depend on other work, documents, or tickets?_

- **Issue**: Closes #5329 

---

**Contribution License Agreement**

By submitting this pull request you agree that all contributions to this project are made under the Apache 2.0 license.
