Skip to content
Closed
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
14 changes: 13 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions crates/ruff_markdown/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ ruff_workspace = { workspace = true }

insta = { workspace = true }
regex = { workspace = true }
fancy-regex = "0.17.0"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we usually add dependencies at the workspace level and then use { workspace = true } in the crates, but I could be wrong.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's common practice yeah.


[lints]
workspace = true
31 changes: 17 additions & 14 deletions crates/ruff_markdown/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::{path::Path, sync::LazyLock};

use regex::Regex;
use fancy_regex::Regex;
use ruff_python_ast::PySourceType;
use ruff_python_formatter::format_module_source;
use ruff_python_trivia::textwrap::{dedent, indent};
Expand All @@ -20,13 +20,13 @@ static MARKDOWN_CODE_BLOCK: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(
r"(?imsx)
(?<before>
^(?<indent>\ *)```[^\S\r\n]*
(?<lang>(?:python|py|python3|py3|pyi)?)
^(?<indent>\ *)(?<fence>```+|~~~+)[^\S\r\n]*
(?<language>(?:python|py|python3|py3|pyi)?)
(?:\ .*?)?\n
)
(?<code>.*?)
(?<after>
^\ *```[^\S\r\n]*$
^\ *\k<fence>[^\S\r\n]*$
)
",
)
Expand All @@ -43,10 +43,14 @@ pub fn format_code_blocks(
let mut last_match = 0;

for capture in MARKDOWN_CODE_BLOCK.captures_iter(source) {
let (_, [before, code_indent, language, code, after]) = capture.extract();

let py_source_type = PySourceType::from_extension(language);
let unformatted_code = dedent(code);
let Ok(capture) = capture else {
continue;
};
let language = capture.name("language").expect("no language");
let code = capture.name("code").expect("no code");

let py_source_type = PySourceType::from_extension(language.as_str());
let unformatted_code = dedent(code.as_str());
let options = settings.to_format_options(py_source_type, &unformatted_code, path);

// Using `Printed::into_code` requires adding `ruff_formatter` as a direct dependency, and I suspect that Rust can optimize the closure away regardless.
Expand All @@ -57,15 +61,14 @@ pub fn format_code_blocks(
if let Ok(formatted_code) = formatted_code {
if formatted_code.len() != unformatted_code.len() || formatted_code != *unformatted_code
{
let m = capture.get_match();
formatted.push_str(&source[last_match..m.start()]);
let code_indent = capture.name("indent").expect("no indent").as_str();

formatted.push_str(&source[last_match..code.start()]);

let indented_code = indent(&formatted_code, code_indent);
// otherwise I need to deal with a result from write!
#[expect(clippy::format_push_string)]
formatted.push_str(&format!("{before}{indented_code}{after}"));
formatted.push_str(&indented_code);

last_match = m.end();
last_match = code.end();
changed = true;
}
}
Expand Down
Loading