diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml
index 41240f8..000c0b2 100644
--- a/.github/workflows/python-app.yml
+++ b/.github/workflows/python-app.yml
@@ -16,14 +16,14 @@ jobs:
steps:
- uses: actions/checkout@v2
- - name: Set up Python 3.6
+ - name: Set up Python 3.8
uses: actions/setup-python@v2
with:
- python-version: 3.6
+ python-version: 3.8
- name: Install dependencies
run: |
python -m pip install --upgrade pip
- pip install flake8==2.5.4 pytest
+ pip install flake8==3.8.4 pytest
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
- name: Lint with flake8
run: |
diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml
index 1a03a7b..9e3a349 100644
--- a/.github/workflows/python-publish.yml
+++ b/.github/workflows/python-publish.yml
@@ -17,7 +17,7 @@ jobs:
- name: Set up Python
uses: actions/setup-python@v2
with:
- python-version: '3.x'
+ python-version: '3.8'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
diff --git a/README.rst b/README.rst
index 4d21411..1e245c1 100644
--- a/README.rst
+++ b/README.rst
@@ -75,6 +75,18 @@ bullets
lists are nested. Otherwise, the bullet will alternate based on nesting
level. Defaults to ``'*+-'``.
+strong_em_symbol
+ In markdown, both ``*`` and ``_`` are used to encode **strong** or
+ *emphasized* texts. Either of these symbols can be chosen by the options
+ ``ASTERISK`` (default) or ``UNDERSCORE`` respectively.
+
+newline_style
+ Defines the style of marking linebreaks (``
``) in markdown. The default
+ value ``SPACES`` of this option will adopt the usual two spaces and a newline,
+ while ``BACKSLASH`` will convert a linebreak to ``\\n`` (a backslash an a
+ newline). While the latter convention is non-standard, it is commonly
+ preferred and supported by a lot of interpreters.
+
Options may be specified as kwargs to the ``markdownify`` function, or as a
nested ``Options`` class in ``MarkdownConverter`` subclasses.
diff --git a/markdownify/__init__.py b/markdownify/__init__.py
index 8200ca7..0b2a620 100644
--- a/markdownify/__init__.py
+++ b/markdownify/__init__.py
@@ -15,6 +15,14 @@ ATX_CLOSED = 'atx_closed'
UNDERLINED = 'underlined'
SETEXT = UNDERLINED
+# Newline style
+SPACES = 'spaces'
+BACKSLASH = 'backslash'
+
+# Strong and emphasis style
+ASTERISK = '*'
+UNDERSCORE = '_'
+
def escape(text):
if not text:
@@ -46,6 +54,8 @@ class MarkdownConverter(object):
autolinks = True
heading_style = UNDERLINED
bullets = '*+-' # An iterable of bullet types.
+ strong_em_symbol = ASTERISK
+ newline_style = SPACES
class Options(DefaultOptions):
pass
@@ -148,25 +158,29 @@ class MarkdownConverter(object):
if convert_as_inline:
return text
- return '\n' + line_beginning_re.sub('> ', text) if text else ''
+ return '\n' + (line_beginning_re.sub('> ', text) + '\n\n') if text else ''
def convert_br(self, el, text, convert_as_inline):
if convert_as_inline:
return ""
- return ' \n'
+ if self.options['newline_style'].lower() == BACKSLASH:
+ return '\\\n'
+ else:
+ return ' \n'
def convert_em(self, el, text, convert_as_inline):
+ em_tag = self.options['strong_em_symbol']
prefix, suffix, text = chomp(text)
if not text:
return ''
- return '%s*%s*%s' % (prefix, text, suffix)
+ return '%s%s%s%s%s' % (prefix, em_tag, text, em_tag, suffix)
def convert_hn(self, n, el, text, convert_as_inline):
if convert_as_inline:
return text
- style = self.options['heading_style']
+ style = self.options['heading_style'].lower()
text = text.rstrip()
if style == UNDERLINED and n <= 2:
line = '=' if n == 1 else '-'
@@ -222,10 +236,11 @@ class MarkdownConverter(object):
return '%s\n\n' % text if text else ''
def convert_strong(self, el, text, convert_as_inline):
+ strong_tag = 2 * self.options['strong_em_symbol']
prefix, suffix, text = chomp(text)
if not text:
return ''
- return '%s**%s**%s' % (prefix, text, suffix)
+ return '%s%s%s%s%s' % (prefix, strong_tag, text, strong_tag, suffix)
def convert_img(self, el, text, convert_as_inline):
alt = el.attrs.get('alt', None) or ''
diff --git a/setup.py b/setup.py
index ec7dea2..db71182 100644
--- a/setup.py
+++ b/setup.py
@@ -10,7 +10,7 @@ read = lambda filepath: codecs.open(filepath, 'r', 'utf-8').read()
pkgmeta = {
'__title__': 'markdownify',
'__author__': 'Matthew Tretter',
- '__version__': '0.6.1',
+ '__version__': '0.6.6',
}
@@ -50,7 +50,7 @@ class LintCommand(Command):
yield "%s.py" % filename
def run(self):
- from flake8.engine import get_style_guide
+ from flake8.api.legacy import get_style_guide
flake8_style = get_style_guide(config_file='setup.cfg')
paths = self.distribution_files()
report = flake8_style.check_files(paths)
@@ -70,13 +70,13 @@ setup(
zip_safe=False,
include_package_data=True,
setup_requires=[
- 'flake8',
+ 'flake8>=3.8,<4',
],
tests_require=[
- 'pytest',
+ 'pytest>=6.2,<7',
],
install_requires=[
- 'beautifulsoup4', 'six'
+ 'beautifulsoup4>=4.9,<5', 'six>=1.15,<2'
],
classifiers=[
'Environment :: Web Environment',
@@ -87,6 +87,9 @@ setup(
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
+ 'Programming Language :: Python :: 3.6',
+ 'Programming Language :: Python :: 3.7',
+ 'Programming Language :: Python :: 3.8',
'Topic :: Utilities'
],
cmdclass={
diff --git a/tests/test_conversions.py b/tests/test_conversions.py
index bf09506..6dcf9a6 100644
--- a/tests/test_conversions.py
+++ b/tests/test_conversions.py
@@ -1,4 +1,4 @@
-from markdownify import markdownify as md, ATX, ATX_CLOSED
+from markdownify import markdownify as md, ATX, ATX_CLOSED, BACKSLASH, UNDERSCORE
import re
@@ -145,12 +145,16 @@ def test_b_spaces():
def test_blockquote():
- assert md('
Hello').strip() == '> Hello' + assert md('
Hello') == '\n> Hello\n\n' + + +def test_blockquote_with_paragraph(): + assert md('
Hello
handsome
') == '\n> Hello\n\nhandsome\n\n' def test_nested_blockquote(): - text = md('And she was like').strip() - assert text == '> And she was like \n> > Hello' + text = md('Hello
And she was like') + assert text == '\n> And she was like \n> > Hello\n> \n> \n\n' def test_br(): @@ -292,3 +296,14 @@ def test_table(): assert md(table) == '| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |' assert md(table_head_body) == '| Firstname | Lastname | Age |\n| --- | --- | --- |\n| Jill | Smith | 50 |\n| Eve | Jackson | 94 |' assert md(table_missing_text) == '| | Lastname | Age |\n| --- | --- | --- |\n| Jill | | 50 |\n| Eve | Jackson | 94 |' + + +def test_strong_em_symbol(): + assert md('Hello', strong_em_symbol=UNDERSCORE) == '__Hello__' + assert md('Hello', strong_em_symbol=UNDERSCORE) == '__Hello__' + assert md('Hello', strong_em_symbol=UNDERSCORE) == '_Hello_' + assert md('Hello', strong_em_symbol=UNDERSCORE) == '_Hello_' + + +def test_newline_style(): + assert md('aHello