task: metadata: install: pip install -e .[dev]
patch: diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index b67c32b..cab4f36 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -369,6 +369,12 @@ class MarkdownConverter(object):
     def convert_table(self, el, text, convert_as_inline):
         return '\n\n' + text + '\n'
 
+    def convert_caption(self, el, text, convert_as_inline):
+        return text + '\n'
+
+    def convert_figcaption(self, el, text, convert_as_inline):
+        return '\n\n' + text + '\n\n'
+
     def convert_td(self, el, text, convert_as_inline):
         return ' ' + text.strip().replace("\n", " ") + ' |'
 

problem_statement: Blank lines are missing around figure and table captions
For `<table>` elements, a newline is missing between the `<caption>` element and the first `|` (pipe) character in the table structure:

```
from markdownify import markdownify as md
md('TEXT<table><caption>Caption</caption><tr><td>CELL</td></tr></tbody></table>')  # > 'TEXT\n\nCaption| CELL |\n\n'
#                                                                                               ^^^^^^^^
```

For `<figure>` elements, blank lines are missing around `<figcaption>` elements at the top or bottom of the figure:

```
from markdownify import markdownify as md
md('TEXT<figure><figcaption>Caption</figcaption><span>SPAN</span></figure>')  # > 'TEXTCaptionSPAN'
#                                                                                     ^^^^^^^^^
md('<figure><span>SPAN</span><figcaption>Caption</figcaption></figure>TEXT')  # > 'SPANCaptionTEXT'
#                                                                                     ^^^^^^^^^
```

These tests use inline text content and no newlines to test the worst-case output scenario (no extra newlines in input propagating to output).
repo: matthewwithanm/python-markdownify
test_cmd: pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
test_patch: diff --git a/tests/test_conversions.py b/tests/test_conversions.py
index ae56837..1e685f3 100644
--- a/tests/test_conversions.py
+++ b/tests/test_conversions.py
@@ -74,6 +74,11 @@ def test_br():
     assert md('a<br />b<br />c', newline_style=BACKSLASH) == 'a\\\nb\\\nc'
 
 
+def test_caption():
+    assert md('TEXT<figure><figcaption>Caption</figcaption><span>SPAN</span></figure>') == 'TEXT\n\nCaption\n\nSPAN'
+    assert md('<figure><span>SPAN</span><figcaption>Caption</figcaption></figure>TEXT') == 'SPAN\n\nCaption\n\nTEXT'
+
+
 def test_code():
     inline_tests('code', '`')
     assert md('<code>*this_should_not_escape*</code>') == '`*this_should_not_escape*`'
diff --git a/tests/test_tables.py b/tests/test_tables.py
index ebbb146..9be876d 100644
--- a/tests/test_tables.py
+++ b/tests/test_tables.py
@@ -201,6 +201,14 @@ table_body = """<table>
     </tbody>
 </table>"""
 
+table_with_caption = """TEXT<table><caption>Caption</caption>
+    <tbody><tr><td>Firstname</td>
+            <td>Lastname</td>
+            <td>Age</td>
+        </tr>
+    </tbody>
+</table>"""
+
 
 def test_table():
     assert md(table) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
@@ -213,3 +221,4 @@ def test_table():
     assert md(table_missing_text) == '\n\n|  | Lastname | Age |\n| --- | --- | --- |\n| Jill |  | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_missing_head) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
     assert md(table_body) == '\n\n| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |\n\n'
+    assert md(table_with_caption) == 'TEXT\n\nCaption\n| Firstname | Lastname | Age |\n\n'