mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(formatter_markdown): honor range ignore inside directives (#28164)
Fixes #28154 Range ignore is supported only at the top level. Prettier does not support directives, so the contents of `:::` end up at the top level and the range works there. We parse `:::` as a container directive, so its contents were not top-level and the range was ignored. This PR treats a `:::` directive with no blockquote / list item / footnote above it as top-level. Supporting ranges everywhere is possible, but it has concerns such as indentation drift in verbatim output. So this starts small.
This commit is contained in:
1 parent
3e7f0f5b73
commit
23d23d69ae
4 files changed
+102
-8
No files matched your search
@@ -31,8 +31,18 @@ pub enum Parent {
|
||||
loose: bool,
|
||||
after_checkbox: bool,
|
||||
},
|
||||
/// Blockquote or container directive.
|
||||
Container,
|
||||
/// Blockquote, footnote definition or container directive.
|
||||
/// `top_level`: no prefix / indent above (a directive at the root, or in such a directive).
|
||||
Container {
|
||||
top_level: bool,
|
||||
},
|
||||
}
|
||||
|
||||
impl Parent {
|
||||
/// No prefix / indent above: the root, or a `top_level` container.
|
||||
const fn is_top_level(self) -> bool {
|
||||
matches!(self, Self::Root | Self::Container { top_level: true })
|
||||
}
|
||||
}
|
||||
|
||||
/// Emits sibling blocks with a blank line between them, except where one line break is the rule
|
||||
@@ -53,8 +63,9 @@ pub fn write_blocks<'a>(
|
||||
}
|
||||
|
||||
// `<!-- prettier-ignore-start -->` ... `<!-- prettier-ignore-end -->`: the range is source text.
|
||||
// Only at the document root; nested, the comments are plain HTML.
|
||||
if parent == Parent::Root
|
||||
// Only at the document root and in directives with no prefix / indent above them
|
||||
// (top-level for Prettier, which has no directives); nested elsewhere, the comments are plain HTML.
|
||||
if parent.is_top_level()
|
||||
&& let Some(end) = ignore_range_end(blocks, index, f)
|
||||
{
|
||||
let source = f.context().source_text();
|
||||
@@ -221,7 +232,7 @@ pub fn write_block<'a>(
|
||||
Block::Paragraph(p) => {
|
||||
let parent = inline::InlineParent {
|
||||
paragraph: true,
|
||||
first_in_container: parent == Parent::Container && index == 0,
|
||||
first_in_container: matches!(parent, Parent::Container { .. }) && index == 0,
|
||||
first_in_document: front_matter_risk(parent, siblings, index, f),
|
||||
after_checkbox: matches!(parent, Parent::ListItem { after_checkbox: true, .. }),
|
||||
..inline::InlineParent::default()
|
||||
@@ -255,7 +266,8 @@ pub fn write_block<'a>(
|
||||
write_verbatim(d.opening, f);
|
||||
if !d.children.is_empty() {
|
||||
super::write_gap(after_opening, f);
|
||||
write_blocks(&d.children, Parent::Container, f);
|
||||
let inner = Parent::Container { top_level: parent.is_top_level() };
|
||||
write_blocks(&d.children, inner, f);
|
||||
}
|
||||
if let Some(closing) = d.closing {
|
||||
super::write_gap(before_closing, f);
|
||||
@@ -331,7 +343,7 @@ fn write_footnote_definition<'a>(
|
||||
) {
|
||||
write!(f, [token("[^"), text(f.context().slice(def.label)), token("]:")]);
|
||||
let children = &def.children;
|
||||
let parent = Parent::Container;
|
||||
let parent = Parent::Container { top_level: false };
|
||||
let first = format_with(|f| write_block(&children[0], children, 0, parent, f)).memoized();
|
||||
let on_label_line = matches!(children.as_slice(), [Block::Paragraph(_)])
|
||||
&& f.options().prose_wrap != ProseWrap::Always
|
||||
|
||||
@@ -15,7 +15,9 @@ pub fn write_blockquote<'a>(quote: &'a Blockquote<'a>, f: &mut MarkdownFormatter
|
||||
write!(f, ">");
|
||||
return;
|
||||
}
|
||||
let body = format_with(|f| block::write_blocks("e.children, block::Parent::Container, f));
|
||||
let body = format_with(|f| {
|
||||
block::write_blocks("e.children, block::Parent::Container { top_level: false }, f);
|
||||
});
|
||||
// The prefixed column is the root that verbatim continuation lines return to
|
||||
write!(f, ["> ", prefix_align(&"> ", &mark_as_root(&body))]);
|
||||
}
|
||||
@@ -11,3 +11,22 @@
|
||||
|
||||
<!-- prettier-ignore -->
|
||||
* also kept
|
||||
|
||||
::: details X
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| a | b |
|
||||
| - | - |
|
||||
* kept
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
:::
|
||||
|
||||
> ::: details Y
|
||||
>
|
||||
> <!-- prettier-ignore-start -->
|
||||
> | a | b |
|
||||
> | - | - |
|
||||
> <!-- prettier-ignore-end -->
|
||||
>
|
||||
> :::
|
||||
@@ -16,6 +16,25 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
<!-- prettier-ignore -->
|
||||
* also kept
|
||||
|
||||
::: details X
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| a | b |
|
||||
| - | - |
|
||||
* kept
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
:::
|
||||
|
||||
> ::: details Y
|
||||
>
|
||||
> <!-- prettier-ignore-start -->
|
||||
> | a | b |
|
||||
> | - | - |
|
||||
> <!-- prettier-ignore-end -->
|
||||
>
|
||||
> :::
|
||||
|
||||
==================== Output ====================
|
||||
------------------
|
||||
{ printWidth: 80 }
|
||||
@@ -34,6 +53,27 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
<!-- prettier-ignore -->
|
||||
* also kept
|
||||
|
||||
::: details X
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| a | b |
|
||||
| - | - |
|
||||
* kept
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
:::
|
||||
|
||||
> ::: details Y
|
||||
>
|
||||
> <!-- prettier-ignore-start -->
|
||||
>
|
||||
> | a | b |
|
||||
> | --- | --- |
|
||||
>
|
||||
> <!-- prettier-ignore-end -->
|
||||
>
|
||||
> :::
|
||||
|
||||
-------------------
|
||||
{ printWidth: 100 }
|
||||
-------------------
|
||||
@@ -51,4 +91,25 @@ source: crates/oxc_formatter_markdown/tests/fixtures/mod.rs
|
||||
<!-- prettier-ignore -->
|
||||
* also kept
|
||||
|
||||
::: details X
|
||||
|
||||
<!-- prettier-ignore-start -->
|
||||
| a | b |
|
||||
| - | - |
|
||||
* kept
|
||||
<!-- prettier-ignore-end -->
|
||||
|
||||
:::
|
||||
|
||||
> ::: details Y
|
||||
>
|
||||
> <!-- prettier-ignore-start -->
|
||||
>
|
||||
> | a | b |
|
||||
> | --- | --- |
|
||||
>
|
||||
> <!-- prettier-ignore-end -->
|
||||
>
|
||||
> :::
|
||||
|
||||
===================== End =====================
|
||||
Reference in new issue
Block a user