ruff/scripts/_mdformat_utils.py
Auguste Lalande a5f41e8d63
Add a formatting step using mdformat as part of generate_mkdocs.py (#10484)
## Summary

The purpose of this change is mainly to address one of the issues
outlined in #10427. Namely, some lists in the docs were not rendering
properly when preceded by a text block without a newline character. This
PR adds `mdformat` as a final step to the rule documentation script, so
that any missing newlines will be added.

NB: The default behavior of `mdformat` is to escape markdown special
characters found in text such as `<`. This resulted in some misformatted
docs. To address this I implemented an ad-hoc mdformat plugin to
override the behavior. This may be considered a bit 'hacky', but I think
it's a good solution. Nevertheless, if someone has a better idea, let me
know.

## Test Plan

This change is hard to test systematically, however, I tried my best to
look at the before and after diffs to ensure no unwanted changes were
made to the docs.
2024-03-21 00:37:40 +00:00

44 lines
1.4 KiB
Python

from __future__ import annotations
from typing import TYPE_CHECKING
import mdformat
if TYPE_CHECKING:
import argparse
from markdown_it import MarkdownIt
from mdformat.renderer import RenderContext, RenderTreeNode
class NoEscapeTextPlugin:
r"""Overrides the default text formatting behavior of mdformat.
By default mdformat will escape any markdown special character found in a
text block, e.g., <. Some of these characters are found in our
documentation, and when escaped (i.e. \<) will be rendered incorrectly by
mkdocs, i.e., the backslash will appear in the render. Because our only
purpose in using mdformat is to manage the line-breaks, it makes sense to
override its text formatting behavior.
"""
def __init__(self: NoEscapeTextPlugin) -> None:
self.POSTPROCESSORS = {"text": NoEscapeTextPlugin.text}
self.RENDERERS = {}
@staticmethod
def add_cli_options(parser: argparse.ArgumentParser) -> None:
pass
@staticmethod
def update_mdit(mdit: MarkdownIt) -> None:
pass
@staticmethod
def text(_text: str, node: RenderTreeNode, _context: RenderContext) -> str:
return node.content
def add_no_escape_text_plugin() -> None:
"""Add NoEscapeTextPlugin to the list of mdformat extensions."""
mdformat.plugins.PARSER_EXTENSIONS["no-escape-text"] = NoEscapeTextPlugin()