https://github.com/jdmonaco/mdformat-space-control
An mdformat plugin that tightens list, separates them with empty lines, and applies EditorConfig indentation settings.
https://github.com/jdmonaco/mdformat-space-control
mdformat
Last synced: 4 months ago
JSON representation
An mdformat plugin that tightens list, separates them with empty lines, and applies EditorConfig indentation settings.
- Host: GitHub
- URL: https://github.com/jdmonaco/mdformat-space-control
- Owner: jdmonaco
- License: mit
- Created: 2025-12-07T12:55:12.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-02-02T02:04:11.000Z (5 months ago)
- Last Synced: 2026-02-02T11:36:40.260Z (5 months ago)
- Topics: mdformat
- Language: Python
- Homepage:
- Size: 94.7 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# mdformat-space-control
[![Build Status][ci-badge]][ci-link]
[![PyPI version][pypi-badge]][pypi-link]
An [mdformat](https://github.com/executablebooks/mdformat) plugin that provides unified control over Markdown spacing:
- **EditorConfig support**: Configure list indentation via `.editorconfig` files
- **Tight list formatting**: Automatically removes unnecessary blank lines between list items
- **Frontmatter spacing**: Normalizes spacing after YAML frontmatter (works with [mdformat-frontmatter](https://github.com/butler54/mdformat-frontmatter))
- **Consecutive blank line normalization**: Limits runs of 3+ empty lines to a maximum of 2
- **Trailing whitespace removal**: Strips trailing whitespace outside code blocks
- **Escaped link repair**: Fixes malformed multi-line links from web-clipped content
- **Smart dash conversion**: Converts `--` to en-dash (–) and `---` to em-dash (—), preserving code blocks and inline code
- **Wikilink preservation**: Handles Obsidian-style `[[links]]`, `[[links|aliases]]`, `[[page#heading]]`, `[[page#^blockid]]`, and `![[embeds]]`
- **Explicit line breaks**: Converts soft breaks to hard breaks (`\` + newline) so source line breaks render visually in all Markdown renderers
## Installation
```bash
pip install mdformat-space-control
```
Or with [pipx](https://pipx.pypa.io/) for command-line usage:
```bash
pipx install mdformat
pipx inject mdformat mdformat-space-control
```
## Usage
After installation, mdformat will automatically use this plugin:
```bash
mdformat your-file.md
```
### EditorConfig Support
Create an `.editorconfig` file in your project:
```ini
# .editorconfig
root = true
[*.md]
indent_style = space
indent_size = 4
```
Nested lists will use the configured indentation:
**Before:**
```markdown
- Item 1
- Nested item
- Item 2
```
**After (with 4-space indent):**
```markdown
- Item 1
- Nested item
- Item 2
```
### Tight List Formatting
Lists with single-paragraph items are automatically formatted as tight lists:
**Before:**
```markdown
- Item 1
- Item 2
- Item 3
```
**After:**
```markdown
- Item 1
- Item 2
- Item 3
```
Multi-paragraph items preserve loose formatting:
```markdown
- First item with multiple paragraphs
Second paragraph of first item
- Second item
```
### Frontmatter Spacing
When used with [mdformat-frontmatter](https://github.com/butler54/mdformat-frontmatter), this plugin removes blank lines between the frontmatter closing delimiter and the first content block:
**Before:**
```markdown
---
title: My Document
---
# Introduction
```
**After:**
```markdown
---
title: My Document
---
# Introduction
```
Install both plugins for this feature:
```bash
pip install mdformat-space-control mdformat-frontmatter
```
### EditorConfig Properties
| Property | Status | Notes |
|----------|--------|-------|
| `indent_style` | Supported | `space` or `tab` for list indentation |
| `indent_size` | Supported | Number of spaces per indent level |
| `tab_width` | Supported | Used when `indent_size = tab` |
### Python API
When using the Python API, you can set the file context for EditorConfig lookup:
```python
import mdformat
from mdformat_space_control import set_current_file
set_current_file("/path/to/your/file.md")
try:
result = mdformat.text(markdown_text, extensions={"space_control"})
finally:
set_current_file(None)
```
### Smart Dash Conversion
Markdown dash sequences are automatically converted to their Unicode equivalents:
- `--` → en-dash (–, U+2013)
- `---` → em-dash (—, U+2014)
**Before:**
```markdown
The result---unexpected as it was---changed everything.
Pages 10--20 of the report.
```
**After:**
```markdown
The result—unexpected as it was—changed everything.
Pages 10–20 of the report.
```
Dashes are preserved inside fenced code blocks and inline code spans. Thematic breaks (`---`) and frontmatter delimiters are not affected. Sequences of 4+ dashes are left unchanged.
### Wikilink Preservation
Obsidian-style wikilinks are preserved during formatting:
```markdown
Link to [[another note]] or [[note|with alias]].
Embed an image: ![[photo.jpg]]
Link to heading: [[note#section]]
Block reference: [[note#^blockid]]
```
Wikilinks inside markdown link text are correctly handled without duplication:
```markdown
[![[image.jpg]]](http://example.com)
```
### Explicit Line Breaks
Soft breaks (plain newlines within paragraphs) are converted to hard breaks (backslash + newline). This makes source line breaks explicit so they render visually regardless of the Markdown renderer's line-break strictness setting. The conversion applies to paragraphs, list items, and blockquotes.
**Before:**
```markdown
This is a paragraph with
a soft line break in the source.
```
**After:**
```markdown
This is a paragraph with\
a hard line break in the output.
```
> **Note:** Without a GFM table parser, markdown-it treats pipe tables as paragraphs
> containing soft breaks, which causes backslashes to appear at the end of table rows.
> Install `mdformat-gfm` to enable proper table parsing and avoid this issue
> (see [Compatible Plugins](#compatible-plugins)).
## Compatible Plugins
This plugin is tested to work alongside:
- [mdformat-frontmatter](https://github.com/butler54/mdformat-frontmatter) - YAML frontmatter parsing
- [mdformat-simple-breaks](https://github.com/csala/mdformat-simple-breaks) - Normalizes thematic breaks to `---`
- [mdformat-gfm](https://github.com/hukkin/mdformat-gfm) - GFM table parsing (prevents hard breaks from being inserted into pipe table rows)
For formatting files in an **Obsidian vault**, the recommended install is:
```bash
pip install mdformat-space-control mdformat-frontmatter mdformat-gfm
```
Note: Wikilink support is built-in; `mdformat-wikilink` is not needed.
## Development
```bash
# Install dependencies
uv sync
# Run tests
uv run python -m pytest
# Run with coverage
uv run python -m pytest --cov=mdformat_space_control
```
## License
MIT - see LICENSE file for details.
[ci-badge]: https://github.com/jdmonaco/mdformat-space-control/actions/workflows/tests.yml/badge.svg?branch=main
[ci-link]: https://github.com/jdmonaco/mdformat-space-control/actions/workflows/tests.yml
[pypi-badge]: https://img.shields.io/pypi/v/mdformat-space-control.svg
[pypi-link]: https://pypi.org/project/mdformat-space-control