Skip to content

Commit

Permalink
https://github.com/jackdewinter/pymarkdown/issues/813
Browse files Browse the repository at this point in the history
  • Loading branch information
jackdewinter committed Dec 22, 2023
1 parent a80ae0c commit 7adb3ff
Show file tree
Hide file tree
Showing 6 changed files with 213 additions and 10 deletions.
2 changes: 2 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ for a version 1.0 release in early 2
- Extension: Strikethrough
- [Issue 805](https://github.com/jackdewinter/pymarkdown/issues/805)
- Extension: Task List Items
- [Issie 813](https://github.com/jackdewinter/pymarkdown/issues/813)
- Rule MD019 - Added fix options
- [Issue 814](https://github.com/jackdewinter/pymarkdown/issues/814)
- Rule MD021 - Added fix options
- [Issue 816](https://github.com/jackdewinter/pymarkdown/issues/816)
Expand Down
9 changes: 9 additions & 0 deletions docs/rules/rule_md019.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
| `md019` |
| `no-multiple-space-atx` |

| Autofix Available |
| --- |
| Yes |

## Summary

Multiple spaces are present after hash character on Atx Heading.
Expand Down Expand Up @@ -73,3 +77,8 @@ this rule was developed to ignore any leading spaces. The rationale is
that if leading spaces before Atx Heading elements are not desired, there
should only be one rule's configuration that needs to be set to
enforce that.

## Fix Description

Any instances of 1+ space characters within a normal AtxHeading are replaced with
a single space character.
8 changes: 4 additions & 4 deletions publish/coverage.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
"projectName": "pymarkdown",
"reportSource": "pytest",
"branchLevel": {
"totalMeasured": 4513,
"totalCovered": 4513
"totalMeasured": 4515,
"totalCovered": 4515
},
"lineLevel": {
"totalMeasured": 18589,
"totalCovered": 18589
"totalMeasured": 18594,
"totalCovered": 18594
}
}

2 changes: 1 addition & 1 deletion publish/test-results.json
Original file line number Diff line number Diff line change
Expand Up @@ -1260,7 +1260,7 @@
},
{
"name": "test.rules.test_md019",
"totalTests": 5,
"totalTests": 9,
"failedTests": 0,
"errorTests": 0,
"skippedTests": 0,
Expand Down
25 changes: 20 additions & 5 deletions pymarkdown/plugins/rule_md_019.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Optional, cast

from pymarkdown.general.parser_helper import ParserHelper
from pymarkdown.plugin_manager.plugin_details import PluginDetails
from pymarkdown.plugin_manager.plugin_details import PluginDetailsV2
from pymarkdown.plugin_manager.plugin_scan_context import PluginScanContext
from pymarkdown.plugin_manager.rule_plugin import RulePlugin
from pymarkdown.tokens.atx_heading_markdown_token import AtxHeadingMarkdownToken
Expand All @@ -23,18 +23,18 @@ def __init__(self) -> None:
super().__init__()
self.__atx_heading_token: Optional[MarkdownToken] = None

def get_details(self) -> PluginDetails:
def get_details(self) -> PluginDetailsV2:
"""
Get the details for the plugin.
"""
return PluginDetails(
return PluginDetailsV2(
plugin_name="no-multiple-space-atx",
plugin_id="MD019",
plugin_enabled_by_default=True,
plugin_description="Multiple spaces are present after hash character on Atx Heading.",
plugin_version="0.5.0",
plugin_interface_version=1,
plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md019.md",
plugin_supports_fix=True,
)

def starting_new_file(self) -> None:
Expand All @@ -43,6 +43,21 @@ def starting_new_file(self) -> None:
"""
self.__atx_heading_token = None

def __report(
self, context: PluginScanContext, text_token: TextMarkdownToken
) -> None:
assert self.__atx_heading_token is not None
if context.in_fix_mode:
self.register_fix_token_request(
context,
text_token,
"next_token",
"extracted_whitespace",
" ",
)
else:
self.report_next_token_error(context, self.__atx_heading_token)

def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None:
"""
Event that a new token is being processed.
Expand All @@ -59,4 +74,4 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None:
text_token.extracted_whitespace
)
if self.__atx_heading_token and len(resolved_extracted_whitespace) > 1:
self.report_next_token_error(context, self.__atx_heading_token)
self.__report(context, text_token)
177 changes: 177 additions & 0 deletions test/rules/test_md019.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,14 @@
"""
import os
from test.markdown_scanner import MarkdownScanner
from test.utils import assert_file_is_as_expected, copy_to_temp_file

import pytest

# pylint: disable=too-many-lines

source_path = os.path.join("test", "resources", "rules", "md019") + os.sep


@pytest.mark.rules
def test_md019_good_single_spacing():
Expand Down Expand Up @@ -74,6 +77,47 @@ def test_md019_bad_multiple_spacing():
)


@pytest.mark.rules
def test_md019_bad_multiple_spacing_fix():
"""
Test to make sure this rule does not trigger with a document that
contains Atx Headings with multiple spaces before text.
"""

# Arrange
scanner = MarkdownScanner()
with copy_to_temp_file(source_path + "multiple_spacing.md") as temp_source_path:
original_file_contents = """# Heading 1
## Heading 2
"""
assert_file_is_as_expected(temp_source_path, original_file_contents)

supplied_arguments = [
"-x-fix",
"scan",
temp_source_path,
]

expected_return_code = 3
expected_output = f"Fixed: {temp_source_path}"
expected_error = ""

expected_file_contents = """# Heading 1
## Heading 2
"""

# Act
execute_results = scanner.invoke_main(arguments=supplied_arguments)

# Assert
execute_results.assert_results(
expected_output, expected_error, expected_return_code
)
assert_file_is_as_expected(temp_source_path, expected_file_contents)


def test_md019_bad_multiple_spacing_with_inline():
"""
Test to make sure this rule does not trigger with a document that
Expand Down Expand Up @@ -109,6 +153,49 @@ def test_md019_bad_multiple_spacing_with_inline():
)


@pytest.mark.rules
def test_md019_bad_multiple_spacing_with_inline_fix():
"""
Test to make sure this rule does not trigger with a document that
contains Atx Headings with multiple spaces before text.
"""

# Arrange
scanner = MarkdownScanner()
with copy_to_temp_file(
source_path + "multiple_spacing_with_inline.md"
) as temp_source_path:
original_file_contents = """# Heading *number* 1
## Heading *number* 2
"""
assert_file_is_as_expected(temp_source_path, original_file_contents)

supplied_arguments = [
"-x-fix",
"scan",
temp_source_path,
]

expected_return_code = 3
expected_output = f"Fixed: {temp_source_path}"
expected_error = ""

expected_file_contents = """# Heading *number* 1
## Heading *number* 2
"""

# Act
execute_results = scanner.invoke_main(arguments=supplied_arguments)

# Assert
execute_results.assert_results(
expected_output, expected_error, expected_return_code
)
assert_file_is_as_expected(temp_source_path, expected_file_contents)


def test_md019_bad_multiple_spacing_with_indent():
"""
Test to make sure this rule does not trigger with a document that
Expand Down Expand Up @@ -146,6 +233,51 @@ def test_md019_bad_multiple_spacing_with_indent():
)


@pytest.mark.rules
def test_md019_bad_multiple_spacing_with_indent_fix():
"""
Test to make sure this rule does not trigger with a document that
contains Atx Headings with multiple spaces before text.
"""

# Arrange
scanner = MarkdownScanner()
with copy_to_temp_file(
source_path + "multiple_spacing_with_indent.md"
) as temp_source_path:
original_file_contents = """ # Heading 1
## Heading 2
"""
assert_file_is_as_expected(temp_source_path, original_file_contents)

supplied_arguments = [
"--disable-rules",
"md023",
"-x-fix",
"scan",
temp_source_path,
]

expected_return_code = 3
expected_output = f"Fixed: {temp_source_path}"
expected_error = ""

expected_file_contents = """ # Heading 1
## Heading 2
"""

# Act
execute_results = scanner.invoke_main(arguments=supplied_arguments)

# Assert
execute_results.assert_results(
expected_output, expected_error, expected_return_code
)
assert_file_is_as_expected(temp_source_path, expected_file_contents)


def test_md019_bad_single_space_single_tab():
"""
Test to make sure this rule does trigger with a document that
Expand Down Expand Up @@ -180,3 +312,48 @@ def test_md019_bad_single_space_single_tab():
execute_results.assert_results(
expected_output, expected_error, expected_return_code
)


@pytest.mark.rules
def test_md019_bad_single_space_single_tab_fix():
"""
Test to make sure this rule does not trigger with a document that
contains Atx Headings with multiple spaces before text.
"""

# Arrange
scanner = MarkdownScanner()
with copy_to_temp_file(
source_path + "single_space_single_tab.md"
) as temp_source_path:
original_file_contents = """# \tHeading 1
## \tHeading 2
"""
assert_file_is_as_expected(temp_source_path, original_file_contents)

supplied_arguments = [
"--disable-rules",
"md010",
"-x-fix",
"scan",
temp_source_path,
]

expected_return_code = 3
expected_output = f"Fixed: {temp_source_path}"
expected_error = ""

expected_file_contents = """# Heading 1
## Heading 2
"""

# Act
execute_results = scanner.invoke_main(arguments=supplied_arguments)

# Assert
execute_results.assert_results(
expected_output, expected_error, expected_return_code
)
assert_file_is_as_expected(temp_source_path, expected_file_contents)

0 comments on commit 7adb3ff

Please sign in to comment.