Repository: Textualize/rich (python)

Issue:
[BUG] Rich markdown printed to console only shows a single link in a column/ table cell
- [x] I've checked [docs](https://rich.readthedocs.io/en/latest/introduction.html) and [closed issues](https://github.com/Textualize/rich/issues?q=is%3Aissue+is%3Aclosed) for possible solutions.
- [x] I can't find my issue in the [FAQ](https://github.com/Textualize/rich/blob/master/FAQ.md).

**Describe the bug**

I use Rich to format a pandas data frame with multiple links in some column to markdown and show it in the terminal. However, when there are more than a single link in a column rich only shows the last one?

```python
from rich.console import Console
from rich.markdown import Markdown

import pandas as pd

md_table = pd.DataFrame(
    {
        "links": ["[page1](https://www.example.com/page1), [page2](https://www.example.com/page2)"]
    }
).to_markdown()

console = Console()
console.print(Markdown(md_table))
```

Output:
```bash
      links  
 ━━━━━━━━━━━ 
  0   page2  
```

Expected
```
      links  
 ━━━━━━━━━━━ 
  0   page1, page2  
```

If I write the markdown to a file I get the expected table with multiple links...

**Platform**

platform="Darwin"
rich==13.5.2


</details>


Pull request description:
Fix markdown table rendering issue with inline styles/links
## Type of changes

- [x] Bug fix
- [ ] New feature
- [ ] Documentation / docstrings
- [x] Tests
- [ ] Other

## Checklist

- [x] I've run the latest [black](https://github.com/psf/black) with default args on new code.
- [x] I've updated CHANGELOG.md and CONTRIBUTORS.md where appropriate.
- [x] I've added tests for new code.
- [x] I accept that @willmcgugan may be pedantic in the code review.

## Description

The table data elements were not interacting well with inline styles (in the rich sense) and the table data element would have its content overridden every time we found another excerpt of text with a different style.
The fix was to do something similar to what `TextElement` does in its method `on_text`, which is to append the new content instead of replacing it.

This fixes #3115.

Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 89843c0a..8e74f4b2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
 The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
+## Unreleased
+
+### Fixed
+
+- Markdown table rendering issue with inline styles and links https://github.com/Textualize/rich/issues/3115
+
 ## [13.5.2] - 2023-08-01
 
 ### Fixed
diff --git a/rich/markdown.py b/rich/markdown.py
index 704da301..86edbfeb 100644
--- a/rich/markdown.py
+++ b/rich/markdown.py
@@ -314,7 +314,7 @@ class TableDataElement(MarkdownElement):
 
     @classmethod
     def create(cls, markdown: "Markdown", token: Token) -> "MarkdownElement":
-        style = str(token.attrs.get("style" "")) or ""
+        style = str(token.attrs.get("style")) or ""
 
         justify: JustifyMethod
         if "text-align:right" in style:
@@ -330,15 +330,13 @@ class TableDataElement(MarkdownElement):
         return cls(justify=justify)
 
     def __init__(self, justify: JustifyMethod) -> None:
-        self.content: TextType = ""
+        self.content: Text = Text("", justify=justify)
         self.justify = justify
 
     def on_text(self, context: "MarkdownContext", text: TextType) -> None:
-        plain = text.plain if isinstance(text, Text) else text
-        style = text.style if isinstance(text, Text) else ""
-        self.content = Text(
-            plain, justify=self.justify, style=context.style_stack.current
-        )
+        text = Text(text) if isinstance(text, str) else text
+        text.stylize(context.current_style)
+        self.content.append_text(text)
 
 
 class ListElement(MarkdownElement):


Test patch:
diff --git a/tests/test_markdown.py b/tests/test_markdown.py
index 1321dcea..08c81736 100644
--- a/tests/test_markdown.py
+++ b/tests/test_markdown.py
@@ -121,7 +121,7 @@ def test_markdown_table():
         """\
 | Year |                      Title                       | Director          |  Box Office (USD) |
 |------|:------------------------------------------------:|:------------------|------------------:|
-| 1982 |            *E.T. the Extra-Terrestrial*            | Steven Spielberg  |    $792.9 million |
+| 1982 |            *E.T. the Extra-Terrestrial*          | Steven Spielberg  |    $792.9 million |
 | 1980 |  Star Wars: Episode V – The Empire Strikes Back  | Irvin Kershner    |    $538.4 million |
 | 1983 |    Star Wars: Episode VI – Return of the Jedi    | Richard Marquand  |    $475.1 million |
 | 1981 |             Raiders of the Lost Ark              | Steven Spielberg  |    $389.9 million |
@@ -129,7 +129,40 @@ def test_markdown_table():
 """
     )
     result = render(markdown)
-    expected = "\n                                                                                               \n \x1b[1m \x1b[0m\x1b[1mYear\x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1m                    Title                     \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mDirector        \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mBox Office (USD)\x1b[0m\x1b[1m \x1b[0m \n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ \n  1982   \x1b[3m          E.T. the Extra-Terrestrial          \x1b[0m   Steven Spielberg     $792.9 million  \n  1980   Star Wars: Episode V – The Empire Strikes Back   Irvin Kershner       $538.4 million  \n  1983     Star Wars: Episode VI – Return of the Jedi     Richard Marquand     $475.1 million  \n  1981              Raiders of the Lost Ark               Steven Spielberg     $389.9 million  \n  1984        Indiana Jones and the Temple of Doom        Steven Spielberg     $333.1 million  \n                                                                                               \n"
+    expected = "\n                                                                                               \n \x1b[1m \x1b[0m\x1b[1mYear\x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1m                    Title                     \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mDirector        \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mBox Office (USD)\x1b[0m\x1b[1m \x1b[0m \n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ \n  1982             \x1b[3mE.T. the Extra-Terrestrial\x1b[0m             Steven Spielberg     $792.9 million  \n  1980   Star Wars: Episode V – The Empire Strikes Back   Irvin Kershner       $538.4 million  \n  1983     Star Wars: Episode VI – Return of the Jedi     Richard Marquand     $475.1 million  \n  1981              Raiders of the Lost Ark               Steven Spielberg     $389.9 million  \n  1984        Indiana Jones and the Temple of Doom        Steven Spielberg     $333.1 million  \n                                                                                               \n"
+    assert result == expected
+
+
+def test_inline_styles_in_table():
+    """Regression test for https://github.com/Textualize/rich/issues/3115"""
+    markdown = Markdown(
+        """\
+| Year | This **column** displays _the_ movie _title_ ~~description~~ | Director          |  Box Office (USD) |
+|------|:----------------------------------------------------------:|:------------------|------------------:|
+| 1982 | *E.T. the Extra-Terrestrial* ([Wikipedia article](https://en.wikipedia.org/wiki/E.T._the_Extra-Terrestrial)) | Steven Spielberg  |    $792.9 million |
+| 1980 |  Star Wars: Episode V – The *Empire* **Strikes** ~~Back~~  | Irvin Kershner    |    $538.4 million |
+"""
+    )
+    result = render(markdown)
+    expected = "\n                                                                                                 \n \x1b[1m \x1b[0m\x1b[1mYear\x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mThis \x1b[0m\x1b[1mcolumn\x1b[0m\x1b[1m displays \x1b[0m\x1b[1;3mthe\x1b[0m\x1b[1m movie \x1b[0m\x1b[1;3mtitle\x1b[0m\x1b[1m \x1b[0m\x1b[1;9mdescription\x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mDirector        \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1mBox Office (USD)\x1b[0m\x1b[1m \x1b[0m \n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ \n  1982    \x1b[3mE.T. the Extra-Terrestrial\x1b[0m (\x1b]8;id=0;foo\x1b\\\x1b[4;34mWikipedia article\x1b[0m\x1b]8;;\x1b\\)    Steven Spielberg     $792.9 million  \n  1980    Star Wars: Episode V – The \x1b[3mEmpire\x1b[0m \x1b[1mStrikes\x1b[0m \x1b[9mBack\x1b[0m    Irvin Kershner       $538.4 million  \n                                                                                                 \n"
+    assert result == expected
+
+
+def test_inline_styles_with_justification():
+    """Regression test for https://github.com/Textualize/rich/issues/3115
+
+    In particular, this tests the interaction between the change that was made to fix
+    #3115 and column text justification.
+    """
+    markdown = Markdown(
+        """\
+| left | center | right |
+| :- | :-: | -: |
+| This is a long row | because it contains | a fairly long sentence. |
+| a*b* _c_ ~~d~~ e | a*b* _c_ ~~d~~ e | a*b* _c_ ~~d~~ e |"""
+    )
+    result = render(markdown)
+    expected = "\n                                                                      \n \x1b[1m \x1b[0m\x1b[1mleft              \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1m      center       \x1b[0m\x1b[1m \x1b[0m \x1b[1m \x1b[0m\x1b[1m                  right\x1b[0m\x1b[1m \x1b[0m \n ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ \n  This is a long row   because it contains   a fairly long sentence.  \n  a\x1b[3mb\x1b[0m \x1b[3mc\x1b[0m \x1b[9md\x1b[0m e                  a\x1b[3mb\x1b[0m \x1b[3mc\x1b[0m \x1b[9md\x1b[0m e                        a\x1b[3mb\x1b[0m \x1b[3mc\x1b[0m \x1b[9md\x1b[0m e  \n                                                                      \n"
     assert result == expected