Skip to content
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
11 changes: 11 additions & 0 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions crates/biome_configuration/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub mod grit;
pub mod html;
pub mod javascript;
pub mod json;
pub mod markdown;
pub mod max_size;
mod overrides;
pub mod vcs;
Expand All @@ -34,6 +35,7 @@ use crate::graphql::{GraphqlFormatterConfiguration, GraphqlLinterConfiguration};
pub use crate::grit::{GritConfiguration, grit_configuration};
use crate::javascript::{JsFormatterConfiguration, JsLinterConfiguration};
use crate::json::{JsonFormatterConfiguration, JsonLinterConfiguration};
pub use crate::markdown::{MarkdownConfiguration, markdown_configuration};
use crate::max_size::MaxSize;
use crate::vcs::{VcsConfiguration, vcs_configuration};
pub use analyzer::{
Expand Down
54 changes: 54 additions & 0 deletions crates/biome_configuration/src/markdown.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
use crate::bool::Bool;
use biome_deserialize_macros::{Deserializable, Merge};
use biome_formatter::{IndentStyle, IndentWidth, LineWidth};
use bpaf::Bpaf;
use serde::{Deserialize, Serialize};

/// Options applied to Markdown files
#[derive(
Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize, Bpaf, Deserializable, Merge,
)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct MarkdownConfiguration {
#[bpaf(external(markdown_formatter_configuration), optional)]
#[serde(skip_serializing_if = "Option::is_none")]
pub formatter: Option<MarkdownFormatterConfiguration>,
}

pub type MarkdownFormatterEnabled = Bool<false>; // Keep it disabled by default while experimental.
pub type MarkdownLinterEnabled = Bool<true>;
pub type MarkdownAssistEnabled = Bool<true>;
pub type MarkdownParseInterpolation = Bool<false>;

/// Options that change how the Markdown formatter behaves
#[derive(
Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize, Bpaf, Deserializable, Merge,
)]
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
#[serde(rename_all = "camelCase", default, deny_unknown_fields)]
pub struct MarkdownFormatterConfiguration {
/// Control the formatter for Markdown (and its super languages) files.
#[bpaf(long("markdown-formatter-enabled"), argument("true|false"), optional)]
#[serde(skip_serializing_if = "Option::is_none")]
pub enabled: Option<MarkdownFormatterEnabled>,

/// The indent style applied to Markdown files.
#[bpaf(
long("markdown-formatter-indent-style"),
argument("tab|space"),
optional
)]
#[serde(skip_serializing_if = "Option::is_none")]
pub indent_style: Option<IndentStyle>,

/// The size of the indentation applied to Markdown files. Defaults to 2.
#[bpaf(long("markdown-formatter-indent-width"), argument("NUMBER"), optional)]
#[serde(skip_serializing_if = "Option::is_none")]
pub indent_width: Option<IndentWidth>,

/// What's the max width of a line applied to Markdown files. Defaults to 80.
#[bpaf(long("markdown-formatter-line-width"), argument("NUMBER"), optional)]
#[serde(skip_serializing_if = "Option::is_none")]
pub line_width: Option<LineWidth>,
}
13 changes: 13 additions & 0 deletions crates/biome_markdown_formatter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,23 @@ biome_formatter = { workspace = true }
biome_markdown_factory = { workspace = true }
biome_markdown_syntax = { workspace = true }
biome_rowan = { workspace = true }
schemars = { workspace = true, optional = true }
serde = { workspace = true, features = ["derive"], optional = true }

[dev-dependencies]
biome_configuration = { workspace = true }
biome_formatter_test = { workspace = true }
biome_fs = { path = "../biome_fs" }
biome_markdown_parser = { workspace = true }
biome_parser = { workspace = true }
biome_service = { path = "../biome_service" }
camino = { workspace = true }
countme = { workspace = true, features = ["enable"] }
tests_macros = { path = "../tests_macros" }

[features]
schema = ["dep:schemars", "serde"]
serde = ["dep:serde"]

[lints]
workspace = true
38 changes: 37 additions & 1 deletion crates/biome_markdown_formatter/src/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use std::rc::Rc;
use std::{fmt, rc::Rc};

use biome_formatter::{
CstFormatContext, FormatContext, FormatOptions, IndentStyle, IndentWidth, LineEnding,
Expand Down Expand Up @@ -62,10 +62,40 @@ impl FormatOptions for MarkdownFormatOptions {
}

impl MarkdownFormatOptions {
pub fn new() -> Self {
Self {
indent_style: IndentStyle::default(),
indent_width: IndentWidth::default(),
line_ending: LineEnding::default(),
line_width: LineWidth::default(),
trailing_newline: TrailingNewline::default(),
}
}

pub fn with_indent_style(mut self, indent_style: IndentStyle) -> Self {
self.indent_style = indent_style;
self
}

pub fn with_indent_width(mut self, indent_width: IndentWidth) -> Self {
self.indent_width = indent_width;
self
}

pub fn with_line_width(mut self, line_width: LineWidth) -> Self {
self.line_width = line_width;
self
}

pub fn with_line_ending(mut self, line_ending: LineEnding) -> Self {
self.line_ending = line_ending;
self
}

pub fn with_trailing_newline(mut self, trailing_newline: TrailingNewline) -> Self {
self.trailing_newline = trailing_newline;
self
}
}

impl MarkdownFormatContext {
Expand Down Expand Up @@ -98,3 +128,9 @@ impl FormatContext for MarkdownFormatContext {
None
}
}

impl fmt::Display for MarkdownFormatOptions {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
std::fmt::Debug::fmt(self, f)
}
Comment thread
tidefield marked this conversation as resolved.
}
39 changes: 39 additions & 0 deletions crates/biome_markdown_formatter/tests/language.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
use biome_formatter_test::TestFormatLanguage;
use biome_fs::BiomePath;
use biome_markdown_formatter::{MarkdownFormatLanguage, context::MarkdownFormatContext};
use biome_markdown_parser::parse_markdown;
use biome_markdown_syntax::MarkdownLanguage;
use biome_parser::AnyParse;
use biome_service::{
settings::{ServiceLanguage, Settings},
workspace::DocumentFileSource,
};

#[derive(Default)]
pub struct MarkdownTestFormatLanguage {}

impl TestFormatLanguage for MarkdownTestFormatLanguage {
type ServiceLanguage = MarkdownLanguage;
type Context = MarkdownFormatContext;
type FormatLanguage = MarkdownFormatLanguage;

fn parse(&self, text: &str) -> AnyParse {
parse_markdown(text).into()
}

fn to_format_language(
&self,
settings: &Settings,
file_source: &DocumentFileSource,
) -> Self::FormatLanguage {
let language_settings = &settings.languages.markdown.formatter;
let options = Self::ServiceLanguage::resolve_format_options(
&settings.formatter,
&settings.override_settings,
language_settings,
&BiomePath::new(""),
file_source,
);
MarkdownFormatLanguage::new(options)
}
}
29 changes: 29 additions & 0 deletions crates/biome_markdown_formatter/tests/prettier_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use biome_formatter::{IndentStyle, IndentWidth};
use biome_formatter_test::test_prettier_snapshot::{PrettierSnapshot, PrettierTestFile};
use biome_markdown_formatter::{MarkdownFormatLanguage, context::MarkdownFormatOptions};
use camino::Utf8Path;
use std::env;

mod language {
include!("language.rs");
}

tests_macros::gen_tests! {"tests/specs/prettier/markdown/**/*.{md}", crate::test_snapshot, ""}

fn test_snapshot(input: &'static str, _: &str, _: &str, _: &str) {
countme::enable(true);

let root_path = Utf8Path::new(concat!(
env!("CARGO_MANIFEST_DIR"),
"/tests/specs/prettier/"
));

let test_file = PrettierTestFile::new(input, root_path);
let options = MarkdownFormatOptions::default()
.with_indent_style(IndentStyle::Space)
.with_indent_width(IndentWidth::default());
let language = language::MarkdownTestFormatLanguage::default();
let snapshot = PrettierSnapshot::new(test_file, language, MarkdownFormatLanguage::new(options));

snapshot.test()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
---
source: crates/biome_formatter_test/src/snapshot_builder.rs
info: markdown/blockquote/code.md
---
# Input

```md
> NOTE: To use `unobtrusive`, `unobtrusive/import`, `unobtrusive/react`, and `unobtrusive/flowtype` together, your eslint config would look like this:
>```json
>{
> "extends": [
> "unobtrusive",
> "unobtrusive/import",
> "unobtrusive/react",
> "unobtrusive/flowtype"
> ],
> "env": {
> "browser": true
> }
>}
>```

```


# Prettier differences

```diff
--- Prettier
+++ Biome
@@ -1,7 +1,6 @@
> NOTE: To use `unobtrusive`, `unobtrusive/import`, `unobtrusive/react`, and `unobtrusive/flowtype` together, your eslint config would look like this:
->
-> ```json
-> {
+>```json
+>{
> "extends": [
> "unobtrusive",
> "unobtrusive/import",
@@ -11,5 +10,5 @@
> "env": {
> "browser": true
> }
-> }
-> ```
+>}
+>```
```

# Output

```md
> NOTE: To use `unobtrusive`, `unobtrusive/import`, `unobtrusive/react`, and `unobtrusive/flowtype` together, your eslint config would look like this:
>```json
>{
> "extends": [
> "unobtrusive",
> "unobtrusive/import",
> "unobtrusive/react",
> "unobtrusive/flowtype"
> ],
> "env": {
> "browser": true
> }
>}
>```
```

# Errors
```
code.md:2:2 parse ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

× Unterminated fenced code block, expected closing triple backticks (```).

1 │ > NOTE: To use `unobtrusive`, `unobtrusive/import`, `unobtrusive/react`, and `unobtrusive/flowtype` together, your eslint config would look like this:
> 2 │ >```json
│ ^^^
3 │ >{
4 │ > "extends": [

i code block started here

1 │ > NOTE: To use `unobtrusive`, `unobtrusive/import`, `unobtrusive/react`, and `unobtrusive/flowtype` together, your eslint config would look like this:
> 2 │ >```json
│ ^^^
3 │ >{
4 │ > "extends": [

i Add closing triple backticks (```) at the start of a new line.


```

# Lines exceeding max width of 80 characters
```
1: > NOTE: To use `unobtrusive`, `unobtrusive/import`, `unobtrusive/react`, and `unobtrusive/flowtype` together, your eslint config would look like this:
```
Loading