Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
jackdewinter authored Dec 27, 2023
1 parent 41dbbac commit 03d3842
Show file tree
Hide file tree
Showing 8 changed files with 1,135 additions and 23 deletions.
4 changes: 3 additions & 1 deletion changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
## Unversioned - In Main, Not Released

This release is going to focus on getting the feature list complete
for a version 1.0 release in early 2
for a version 1.0 release in early 2024.

### Added

Expand All @@ -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
- [Issue 809](https://github.com/jackdewinter/pymarkdown/issues/809)
- Rule MD007 - Added fix options
- [Issie 813](https://github.com/jackdewinter/pymarkdown/issues/813)
- Rule MD019 - Added fix options
- [Issue 814](https://github.com/jackdewinter/pymarkdown/issues/814)
Expand Down
38 changes: 38 additions & 0 deletions docs/rules/rule_md007.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
| `md007` |
| `ul-indent` |

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

## Summary

Unordered list indentation.
Expand Down Expand Up @@ -115,3 +119,37 @@ on the following sample:
+ sublist
+ sublist
```

## Fix Description

Any unordered list item elements and their new list item elements are examined
to make sure that they start with a multiple of the specified `indent`. If an
unordered list is started within a block quote or ordered list item, the base indent
within that element is calculated. If not in either of those two elements, the
base indent is `0`. The number of containing unordered list item elements or list
depth is calculated.

A simple calculation is made to determine the ideal ident: the base indent plus
the `indent` value multiplied by the list depth minus `1`. If that value
differs from the actual indent, the list item start element or the new list item
element is adjusted to start at that calculated location.

Therefore, for the above example:

```Markdown
1. ordered indent
* unordered indent
```

the base indent is `3` and the list depth is `1`. Therefore `3 + (1-1)*2` equals
`3`, adjusting the unordered list start to have an indent of 3:

```Markdown
1. ordered indent
* unordered indent
```

The same calculation happens for a new list item for that list, arriving at the same
list depth, and therefore the same calculated indent. For any nested lists, the
list depth is increased accordingly, resulting in indents of `5`, `7`, `9`, and
so on.
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": 4515,
"totalCovered": 4515
"totalMeasured": 4525,
"totalCovered": 4525
},
"lineLevel": {
"totalMeasured": 18594,
"totalCovered": 18594
"totalMeasured": 18617,
"totalCovered": 18617
}
}

2 changes: 1 addition & 1 deletion publish/test-results.json
Original file line number Diff line number Diff line change
Expand Up @@ -1156,7 +1156,7 @@
},
{
"name": "test.rules.test_md007",
"totalTests": 33,
"totalTests": 54,
"failedTests": 0,
"errorTests": 0,
"skippedTests": 0,
Expand Down
67 changes: 50 additions & 17 deletions pymarkdown/plugins/rule_md_007.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
from typing import Tuple, 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.plugins.utils.container_token_manager import ContainerTokenManager
Expand All @@ -26,19 +26,19 @@ def __init__(self) -> None:
self.__start_indented = False
self.__container_manager = ContainerTokenManager()

def get_details(self) -> PluginDetails:
def get_details(self) -> PluginDetailsV2:
"""
Get the details for the plugin.
"""
return PluginDetails(
return PluginDetailsV2(
plugin_name="ul-indent",
plugin_id="MD007",
plugin_enabled_by_default=True,
plugin_description="Unordered list indentation",
plugin_version="0.5.0",
plugin_interface_version=1,
plugin_url="https://github.com/jackdewinter/pymarkdown/blob/main/docs/rules/rule_md007.md",
plugin_configuration="indent,start_indented",
plugin_supports_fix=True,
)

@classmethod
Expand Down Expand Up @@ -157,6 +157,34 @@ def __calculate_base_column(self) -> Tuple[int, int, int]:
stack_index -= 1
return container_base_column, block_quote_base, list_depth

def __check_apply_fix(
self,
context: PluginScanContext,
token: MarkdownToken,
adjusted_column_number: int,
calculated_column_number: int,
) -> None:
list_token = cast(ListStartMarkdownToken, token)
column_delta = adjusted_column_number - calculated_column_number
whitespace_length = len(list_token.extracted_whitespace)
assert whitespace_length >= 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,
)

def __check(self, context: PluginScanContext, token: MarkdownToken) -> None:
# print(f"{token}".replace(ParserHelper.newline_character, "\\n"))
# print(f"{self.__container_token_stack}".replace(ParserHelper.newline_character, "\\n"))
Expand All @@ -183,16 +211,21 @@ def __check(self, context: PluginScanContext, token: MarkdownToken) -> None:
calculated_column_number = list_depth * self.__indent_basis
# print(f"adjusted_column_number={adjusted_column_number}, calculated_column_number=" + \
# f"{calculated_column_number},block_quote_base={block_quote_base}")
if adjusted_column_number != calculated_column_number:
# print(f"container_base_column={container_base_column}")
if block_quote_base:
container_base_column -= block_quote_base
elif container_base_column:
container_base_column += 1
extra_error_information = (
f"Expected: {calculated_column_number+container_base_column}, "
+ f"Actual={adjusted_column_number+container_base_column}"
)
self.report_next_token_error(
context, token, extra_error_information=extra_error_information
)
if adjusted_column_number > calculated_column_number:
if context.in_fix_mode:
self.__check_apply_fix(
context, token, adjusted_column_number, calculated_column_number
)
else:
# print(f"container_base_column={container_base_column}")
if block_quote_base:
container_base_column -= block_quote_base
elif container_base_column:
container_base_column += 1
extra_error_information = (
f"Expected: {calculated_column_number+container_base_column}, "
+ f"Actual={adjusted_column_number+container_base_column}"
)
self.report_next_token_error(
context, token, extra_error_information=extra_error_information
)
8 changes: 8 additions & 0 deletions pymarkdown/tokens/list_start_markdown_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,14 @@ def _modify_token(self, field_name: str, field_value: Union[str, int]) -> bool:
self.__list_start_content = field_value
self.__compose_extra_data_field()
return True
if field_name == "extracted_whitespace" and isinstance(field_value, str):
self.__extracted_whitespace = field_value
self.__compose_extra_data_field()
return True
# if field_name == "indent_level" and isinstance(field_value, int):
# self.__indent_level = field_value
# self.__compose_extra_data_field()
# return True
return False


Expand Down
8 changes: 8 additions & 0 deletions pymarkdown/tokens/new_list_item_markdown_token.py
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,14 @@ def _modify_token(self, field_name: str, field_value: Union[str, int]) -> bool:
self.__list_start_content = field_value
self.__compose_extra_data_field()
return True
if field_name == "extracted_whitespace" and isinstance(field_value, str):
self.__extracted_whitespace = field_value
self.__compose_extra_data_field()
return True
if field_name == "indent_level" and isinstance(field_value, int):
self.__indent_level = field_value
self.__compose_extra_data_field()
return True
return False

def __compose_extra_data_field(self) -> str:
Expand Down
Loading

0 comments on commit 03d3842

Please sign in to comment.