Repository: domluna/JuliaFormatter.jl
Pull request #570 (2022-04-27 18:40:57)

Allow for .qmd extension and {julia} code blocks.
- a `.qmd` file extension, used by [Quarto](https://quarto.org), is similar to `.jmd` except that Julia code blocks are flagged as `{julia}`, not just `julia`
- this PR allows for both these extensions - #569
- added test

domluna: LGTM - running tests

anything else to add @dmbates  ?
dmbates: I should add a test or @palday will feel that his training of me has failed. 
dmbates: I think this is ready to go new.
domluna: alright looks good!

Patch:
diff --git a/src/JuliaFormatter.jl b/src/JuliaFormatter.jl
index c33bd9bf..1751a7c5 100644
--- a/src/JuliaFormatter.jl
+++ b/src/JuliaFormatter.jl
@@ -602,7 +602,7 @@ end
         format_options...,
     )::Bool
 
-Formats the contents of `filename` assuming it's a `.jl`, `.md` or `.jmd` file.
+Formats the contents of `filename` assuming it's a `.jl`, `.md`, `.jmd` or `.qmd` file.
 
 ## File Options
 
@@ -643,7 +643,7 @@ function format_file(
 )::Bool
     path, ext = splitext(filename)
     shebang_pattern = r"^#!\s*/.*\bjulia[0-9.-]*\b"
-    formatted_str = if ext == ".md" || ext == ".jmd"
+    formatted_str = if match(r"^\.[jq]*md$", ext) ≠ nothing
         format_markdown || return true
         verbose && println("Formatting $filename")
         str = String(read(filename))
@@ -653,7 +653,7 @@ function format_file(
         str = String(read(filename))
         format_text(str; format_options...)
     else
-        error("$filename must be a Julia (.jl) or Markdown (.md or .jmd) source file")
+        error("$filename must be a Julia (.jl) or Markdown (.md, .jmd or .qmd) source file")
     end
     formatted_str = replace(formatted_str, r"\n*$" => "\n")
     already_formatted = (formatted_str == str)
@@ -727,7 +727,7 @@ function format(paths; options...)::Bool
                     _, ext = splitext(file)
                     full_path = joinpath(root, file)
                     formatted_file &
-                    if ext in (".jl", ".md", ".jmd") &&
+                    if ext in (".jl", ".md", ".jmd", ".qmd") &&
                        !(".git" in split(full_path, Base.Filesystem.path_separator))
                         dir = abspath(root)
                         opts = if (config = find_config_file(dir)) !== nothing
diff --git a/src/styles/default/pretty.jl b/src/styles/default/pretty.jl
index 99bf7ddd..93560a6a 100644
--- a/src/styles/default/pretty.jl
+++ b/src/styles/default/pretty.jl
@@ -238,7 +238,8 @@ block_modifier(rule::FormatRule) =
         if startswith(language, "@example") ||
            startswith(language, "@repl") ||
            startswith(language, "@eval") ||
-           startswith(language, "julia")
+           startswith(language, "julia") ||
+           startswith(language, "{julia}")
             block.literal = format_text(code, rule)
         elseif startswith(language, "jldoctest")
             block.literal = if occursin(r"^julia> "m, code)


Test patch:
diff --git a/test/config.jl b/test/config.jl
index 22be3db9..c474adb5 100644
--- a/test/config.jl
+++ b/test/config.jl
@@ -270,6 +270,62 @@
         end
     end
 
+    @testset "qmd formatting" begin
+        config2 = """
+        indent = 2
+        format_markdown = true
+        """
+
+        before = """
+        ---
+        title: Test file
+        author: JuliaFormatter
+        ---
+
+        # hello world
+
+        ```{julia}
+        begin body end
+        ```
+        - a
+        -             b
+        """
+        after2 = """
+        ---
+        title: Test file
+        author: JuliaFormatter
+        ---
+
+        # hello world
+
+        ```{julia}
+        begin
+          body
+        end
+        ```
+
+          - a
+          -             b
+        """
+        # test formatting a Quarto markdown file
+        # test_basic_quartomarkdown_format
+        # ├─ .JuliaFormatter.toml (config2)
+        # └─ file.qmd (before -> after2)
+        sandbox_dir = joinpath(tempdir(), "test_basic_quartomarkdown_format")
+        mkdir(sandbox_dir)
+        try
+            config_path = joinpath(sandbox_dir, CONFIG_FILE_NAME)
+            md_path = joinpath(sandbox_dir, "file.qmd")
+            open(io -> write(io, config2), config_path, "w")
+            open(io -> write(io, before), md_path, "w")
+
+            @test format(md_path) == false
+            @test read(md_path, String) == after2
+        finally
+            rm(sandbox_dir; recursive = true)
+        end
+    end
+
     @testset "trailing_comma = nothing" begin
         config_trailing_comma_nothing = """
         trailing_comma = "nothing"