# DprintMarkdownFormatter Usage Guide for LLMs
This guide helps LLMs understand how to use the DprintMarkdownFormatter package effectively.
## Package Overview
DprintMarkdownFormatter is a fast, configurable markdown formatter for Elixir that uses Rust's `dprint-plugin-markdown` via NIFs. It provides:
- High-performance markdown formatting
- Mix format integration for .md files
- Module attribute formatting (@moduledoc, @doc, etc.)
- Sigil support (~M)
- Extensive configuration options
## Quick Start
### Installation
Add to `mix.exs`:
```elixir
def deps do
[
{:dprint_markdown_formatter, "~> 0.5.1"}
]
end
```
## Configuration
### Global Configuration (mix.exs)
```elixir
def project do
[
# ... other config
dprint_markdown_formatter: [
line_width: 100,
text_wrap: :never,
emphasis_kind: :underscores,
format_module_attributes: true
]
]
end
```
### Configuration Options
| Option | Default | Values | Description |
|--------|---------|--------|-------------|
| `:line_width` | `80` | positive integer | Maximum line width |
| `:text_wrap` | `:always` | `:always`, `:never`, `:maintain` | Text wrapping behavior |
| `:emphasis_kind` | `:asterisks` | `:asterisks`, `:underscores` | Emphasis style (*text* vs _text_) |
| `:strong_kind` | `:asterisks` | `:asterisks`, `:underscores` | Strong text style (**text** vs __text__) |
| `:unordered_list_kind` | `:dashes` | `:dashes`, `:asterisks` | List style (- vs *) |
| `:new_line_kind` | `:auto` | `:auto`, `:lf`, `:crlf` | Line ending type |
| `:format_module_attributes` | `nil` | `nil`, `true`, `false`, `[atom()]` | Module attribute formatting |
**Note**: Configuration values can be atoms (`:never`) or strings (`"never"`). Atoms are preferred.
## Usage Patterns
### 1. Mix Format Integration
Add to `.formatter.exs`:
```elixir
[
plugins: [DprintMarkdownFormatter],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}", "*.{md,markdown}"]
]
```
This enables automatic formatting of `.md` and `.markdown` files when running `mix format`.
### 2. Sigil Usage
```elixir
import DprintMarkdownFormatter.Sigil
# Sigil content gets formatted by mix format
markdown = ~M"""
# API Documentation
This is **bold** text with extra spaces.
* Poorly formatted list
"""
```
### 3. Module Attribute Formatting
Enable in `mix.exs`:
```elixir
dprint_markdown_formatter: [
format_module_attributes: true # Format default attributes
]
```
This formats markdown in `@moduledoc`, `@doc`, `@typedoc`, `@shortdoc`, and `@deprecated`.
Custom attributes:
```elixir
dprint_markdown_formatter: [
format_module_attributes: [:moduledoc, :doc, :custom_doc]
]
```
## Module Attribute Formatting
### Setup Requirements
1. Add plugin to `.formatter.exs`:
```elixir
[
plugins: [DprintMarkdownFormatter],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}", "*.{md,markdown}"]
]
```
2. Configure in `mix.exs`:
```elixir
dprint_markdown_formatter: [
format_module_attributes: true
]
```
3. Run `mix format` on your `.ex` files
### How It Works
Before formatting:
```elixir
defmodule MyModule do
@moduledoc """
This is messy markdown.
* Poorly formatted list
* Another item
"""
@doc """
Function docs with extra spaces.
"""
def my_function, do: :ok
end
```
After `mix format`:
```elixir
defmodule MyModule do
@moduledoc """
This is messy markdown.
- Properly formatted list
- Another item
"""
@doc """
Function docs with extra spaces.
"""
def my_function, do: :ok
end
```
## Common Use Cases
### 1. CI/CD Integration
```bash
# Check if markdown files are properly formatted
mix format --check-formatted
```
### 2. Custom Formatting Workflows
Use `mix format` with specific file patterns:
```bash
# Format all markdown files
mix format "**/*.md"
# Format specific directories
mix format "docs/**/*.{md,markdown}"
```
## Troubleshooting
### Module Attributes Not Being Formatted
**Check these steps in order:**
1. **Plugin configuration**: Ensure `.formatter.exs` has:
```elixir
[
plugins: [DprintMarkdownFormatter],
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}", "*.{md,markdown}"]
]
```
2. **Module attribute configuration**: Ensure `mix.exs` has:
```elixir
dprint_markdown_formatter: [
format_module_attributes: true # or custom list
]
```
3. **Run on .ex files**: Module attributes are formatted when you run `mix format` on `.ex` files, not `.md` files.
4. **Check attribute names**: Default formatting only applies to `:moduledoc`, `:doc`, `:typedoc`, `:shortdoc`, `:deprecated`.
### Compilation Issues
If you see Rust compilation errors, force precompiled binaries:
```bash
export RUSTLER_PRECOMPILED_FORCE_BUILD=false
mix deps.get
mix compile
```
### Configuration Not Taking Effect
- **Global config**: Must be in `mix.exs` under `dprint_markdown_formatter` key
- **Per-call config**: Passed as second argument to `format/2`
- **Mix format**: Uses global config from `mix.exs`
### Performance Considerations
- **Large files**: The formatter is optimized for performance but very large files (>1MB) may take time
- **Batch processing**: For many files, consider parallel processing with `Task.async_stream/2`
- **Caching**: The formatter is deterministic - same input always produces same output
## Advanced Usage
### Custom Attribute Formatting
```elixir
# Format specific attributes only
dprint_markdown_formatter: [
format_module_attributes: [
:moduledoc,
:doc,
:api_doc, # custom attribute
:example_doc # custom attribute
]
]
```
### Complex Configuration
```elixir
dprint_markdown_formatter: [
line_width: 120,
text_wrap: :never,
emphasis_kind: :underscores,
strong_kind: :underscores,
unordered_list_kind: :asterisks,
format_module_attributes: [
:moduledoc,
:doc,
:typedoc,
:spec_doc,
:example_doc
]
]
```
### Integration with Other Tools
Use `mix format` in your build tools and CI:
```bash
# In your build scripts
mix format --check-formatted
# Format before generating docs
mix format && mix docs
```
## Best Practices
1. **Use atoms for config values**: `:never` instead of `"never"`
2. **Set reasonable line widths**: 80-120 characters work well
3. **Consider text wrapping**: `:maintain` preserves existing line breaks
4. **Test configuration**: Start with defaults, then customize
5. **Use in CI**: Add `mix format --check-formatted` to ensure consistent formatting
6. **Document custom attributes**: If using custom module attributes, document them for your team
## Performance Tips
- The formatter is very fast due to Rust implementation
- For large batches of files, use `Task.async_stream/2` for parallel processing
- Configuration parsing is cached, so repeated calls with same options are efficient
- Empty or very small strings are handled efficiently with early returns