Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

https://github.com/jackdewinter/pymarkdown/issues/964 #965

Merged
merged 2 commits into from
Jan 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
- inconsistent splitting of whitespace caused some issues
- went through all strip() calls and ensured that they have the
specific type of whitespace identified and documented
- [Issue 964](https://github.com/jackdewinter/pymarkdown/issues/964)
- final fix states needed verification and fixing of any issues
- uncovered and fixed issues in Md007, Md019, and Md029

### Changed

Expand Down
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": 4785,
"totalCovered": 4785
"totalMeasured": 4795,
"totalCovered": 4795
},
"lineLevel": {
"totalMeasured": 19327,
"totalCovered": 19327
"totalMeasured": 19341,
"totalCovered": 19341
}
}

6 changes: 4 additions & 2 deletions publish/pylint_suppression.json
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,9 @@
"too-many-arguments": 6
},
"pymarkdown/plugins/rule_md_028.py": {},
"pymarkdown/plugins/rule_md_029.py": {},
"pymarkdown/plugins/rule_md_029.py": {
"too-many-arguments": 1
},
"pymarkdown/plugins/rule_md_030.py": {
"too-many-instance-attributes": 1
},
Expand Down Expand Up @@ -493,7 +495,7 @@
"too-many-instance-attributes": 24,
"too-many-public-methods": 4,
"too-few-public-methods": 39,
"too-many-arguments": 226,
"too-many-arguments": 227,
"too-many-locals": 38,
"chained-comparison": 1,
"too-many-boolean-expressions": 2,
Expand Down
6 changes: 3 additions & 3 deletions publish/test-results.json
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@
},
{
"name": "test.gfm.test_markdown_list_blocks",
"totalTests": 135,
"totalTests": 137,
"failedTests": 0,
"errorTests": 0,
"skippedTests": 4,
Expand Down Expand Up @@ -1140,7 +1140,7 @@
},
{
"name": "test.rules.test_md005",
"totalTests": 88,
"totalTests": 94,
"failedTests": 0,
"errorTests": 0,
"skippedTests": 2,
Expand All @@ -1156,7 +1156,7 @@
},
{
"name": "test.rules.test_md007",
"totalTests": 62,
"totalTests": 68,
"failedTests": 0,
"errorTests": 0,
"skippedTests": 0,
Expand Down
37 changes: 32 additions & 5 deletions pymarkdown/plugins/rule_md_007.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def get_details(self) -> PluginDetailsV2:
plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md007.md",
plugin_configuration="indent,start_indented",
plugin_supports_fix=True,
plugin_fix_level=3,
)

@classmethod
Expand Down Expand Up @@ -165,25 +166,51 @@ def __check_apply_fix(
calculated_column_number: int,
) -> None:
list_token = cast(ListStartMarkdownToken, token)

# column_delta is the space before the list start and follow_space_delta
# is the space following the list start, before the list text commences.
column_delta = adjusted_column_number - calculated_column_number
whitespace_length = len(list_token.extracted_whitespace)
assert whitespace_length >= column_delta
follow_space_delta = (list_token.indent_level - list_token.column_number) - 1
jackdewinter marked this conversation as resolved.
Show resolved Hide resolved

assert len(list_token.extracted_whitespace) >= column_delta
adjusted_whitespace = list_token.extracted_whitespace[:-column_delta]

self.register_fix_token_request(
context,
token,
"next_token",
"extracted_whitespace",
adjusted_whitespace,
)
if token.is_new_list_item:
self.register_fix_token_request(
context,
token,
"next_token",
"indent_level",
list_token.indent_level - column_delta - follow_space_delta,
)
if not token.is_new_list_item:
self.register_fix_token_request(
context,
token,
"next_token",
"indent_level",
list_token.indent_level - column_delta,
"column_number",
list_token.column_number - column_delta,
)
if list_token.leading_spaces:
new_spaces = []
total_delta = column_delta + follow_space_delta
for i in list_token.leading_spaces.split("\n"):
if len(i) >= list_token.indent_level:
i = i[:-total_delta]
new_spaces.append(i)
self.register_fix_token_request(
context,
list_token,
"next_token",
"leading_spaces",
"\n".join(new_spaces),
)

def __check(self, context: PluginScanContext, token: MarkdownToken) -> None:
# print(f"{token}".replace(ParserHelper.newline_character, "\\n"))
Expand Down
14 changes: 12 additions & 2 deletions pymarkdown/plugins/rule_md_019.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from typing import Optional, cast

from pymarkdown.general.parser_helper import ParserHelper
from pymarkdown.general.tab_helper import TabHelper
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
Expand All @@ -21,7 +22,7 @@ class RuleMd019(RulePlugin):

def __init__(self) -> None:
super().__init__()
self.__atx_heading_token: Optional[MarkdownToken] = None
self.__atx_heading_token: Optional[AtxHeadingMarkdownToken] = None

def get_details(self) -> PluginDetailsV2:
"""
Expand Down Expand Up @@ -65,13 +66,22 @@ def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None:
if token.is_atx_heading:
atx_token = cast(AtxHeadingMarkdownToken, token)
if not atx_token.remove_trailing_count:
self.__atx_heading_token = token
self.__atx_heading_token = atx_token
elif token.is_paragraph_end:
self.__atx_heading_token = None
elif token.is_text:
text_token = cast(TextMarkdownToken, token)
resolved_extracted_whitespace = ParserHelper.remove_all_from_text(
text_token.extracted_whitespace
)
if self.__atx_heading_token and "\t" in resolved_extracted_whitespace:
start_index = (
self.__atx_heading_token.column_number
- 1
+ self.__atx_heading_token.hash_count
)
resolved_extracted_whitespace = TabHelper.detabify_string(
resolved_extracted_whitespace, start_index
)
if self.__atx_heading_token and len(resolved_extracted_whitespace) > 1:
self.__report(context, text_token)
98 changes: 58 additions & 40 deletions pymarkdown/plugins/rule_md_029.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ def __match_first_item(
self, context: PluginScanContext, token: MarkdownToken
) -> Tuple[Optional[str], Optional[int]]:
list_token = cast(ListStartMarkdownToken, token)
list_style: Optional[str] = self.__style
last_known_number: Optional[int] = int(list_token.list_start_content)
last_known_number: int = int(list_token.list_start_content)
jackdewinter marked this conversation as resolved.
Show resolved Hide resolved

list_style: str = self.__style
if list_style == RuleMd029.__one_or_ordered_style and last_known_number != 1:
list_style = RuleMd029.__ordered_style

Expand All @@ -109,27 +109,12 @@ def __match_first_item(
elif list_style == RuleMd029.__zero_style:
is_valid = last_known_number == 0
# print(f"list_style={list_style},last_known_number={last_known_number},is_valid={is_valid}")
if not is_valid:
assert list_style is not None
style, expected_number = self.__calculate_match_info(
list_style, True, last_known_number
)
extra_error_information = f"Expected: {expected_number}; Actual: {last_known_number}; Style: {style}"
if context.in_fix_mode:
self.register_fix_token_request(
context,
token,
"next_token",
"list_start_content",
str(expected_number),
)
last_known_number = expected_number
else:
self.report_next_token_error(
context, token, extra_error_information=extra_error_information
)
list_style, last_known_number = (None, None)
return list_style, last_known_number
if is_valid:
return list_style, last_known_number

return self.__report_invalid(
context, list_token, True, list_style, last_known_number, None
)

def __match_non_first_items(
self,
Expand All @@ -140,7 +125,8 @@ def __match_non_first_items(
) -> Tuple[Optional[str], Optional[int]]:
if list_style:
list_token = cast(ListStartMarkdownToken, token)
new_number: Optional[int] = int(list_token.list_start_content)
new_number: int = int(list_token.list_start_content)

# print(f"list_style={list_style},last_known_number={last_known_number},new_number={new_number}")
if list_style == RuleMd029.__one_or_ordered_style:
list_style = (
Expand All @@ -159,28 +145,60 @@ def __match_non_first_items(
assert last_known_number is not None
is_valid = new_number == last_known_number + 1
if not is_valid:
style, expected_number = self.__calculate_match_info(
list_style, False, last_known_number
)
extra_error_information = (
f"Expected: {expected_number}; Actual: {new_number}; Style: {style}"
return self.__report_invalid(
context,
list_token,
False,
list_style,
last_known_number,
new_number,
)
if context.in_fix_mode:
last_known_number = new_number
return list_style, last_known_number

# pylint: disable=too-many-arguments
def __report_invalid(
self,
context: PluginScanContext,
token: ListStartMarkdownToken,
initial_match: bool,
list_style: str,
last_known_number: Optional[int],
new_number: Optional[int],
) -> Tuple[Optional[str], Optional[int]]:
style, expected_number = self.__calculate_match_info(
list_style, initial_match, last_known_number
)
actual_number = last_known_number if new_number is None else new_number
extra_error_information = (
f"Expected: {expected_number}; Actual: {actual_number}; Style: {style}"
)
if context.in_fix_mode:
self.register_fix_token_request(
context,
token,
"next_token",
"list_start_content",
str(expected_number),
)
if not initial_match and new_number is not None:
expected_number_as_string = str(expected_number)
new_number_as_string = str(new_number)
if delta := len(expected_number_as_string) - len(new_number_as_string):
self.register_fix_token_request(
context,
token,
"next_token",
"list_start_content",
str(expected_number),
)
new_number = expected_number
else:
self.report_next_token_error(
context, token, extra_error_information=extra_error_information
"indent_level",
token.indent_level + delta,
)
list_style, new_number = (None, None)
last_known_number = new_number
return list_style, last_known_number
return list_style, expected_number
self.report_next_token_error(
context, token, extra_error_information=extra_error_information
)
return (None, None)

# pylint: enable=too-many-arguments

def next_token(self, context: PluginScanContext, token: MarkdownToken) -> None:
"""
Expand Down
Loading