Skip to main content

An mdformat plugin for space control: EditorConfig indentation, tight lists, frontmatter spacing, and wikilinks.

Project description

mdformat-space-control

Build Status PyPI version

An 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)
  • 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
  • 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

pip install mdformat-space-control

Or with pipx for command-line usage:

pipx install mdformat
pipx inject mdformat mdformat-space-control

Usage

After installation, mdformat will automatically use this plugin:

mdformat your-file.md

EditorConfig Support

Create an .editorconfig file in your project:

# .editorconfig
root = true

[*.md]
indent_style = space
indent_size = 4

Nested lists will use the configured indentation:

Before:

- Item 1
  - Nested item
- Item 2

After (with 4-space indent):

- Item 1
    - Nested item
- Item 2

Tight List Formatting

Lists with single-paragraph items are automatically formatted as tight lists:

Before:

- Item 1

- Item 2

- Item 3

After:

- Item 1
- Item 2
- Item 3

Multi-paragraph items preserve loose formatting:

- First item with multiple paragraphs

  Second paragraph of first item

- Second item

Frontmatter Spacing

When used with mdformat-frontmatter, this plugin removes blank lines between the frontmatter closing delimiter and the first content block:

Before:

---
title: My Document
---


# Introduction

After:

---
title: My Document
---
# Introduction

Install both plugins for this feature:

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:

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)

Wikilink Preservation

Obsidian-style wikilinks are preserved during formatting:

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:

[![[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:

This is a paragraph with
a soft line break in the source.

After:

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

This plugin is tested to work alongside:

For formatting files in an Obsidian vault, the recommended install is:

pip install mdformat-space-control mdformat-frontmatter mdformat-gfm

Note: Wikilink support is built-in; mdformat-wikilink is not needed.

Development

# 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.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mdformat_space_control-0.3.2.tar.gz (20.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mdformat_space_control-0.3.2-py3-none-any.whl (10.9 kB view details)

Uploaded Python 3

File details

Details for the file mdformat_space_control-0.3.2.tar.gz.

File metadata

  • Download URL: mdformat_space_control-0.3.2.tar.gz
  • Upload date:
  • Size: 20.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.12

File hashes

Hashes for mdformat_space_control-0.3.2.tar.gz
Algorithm Hash digest
SHA256 c7f8ac4b8f9a962aefce401fef6260779bc0752fd1b3ac6af446a37adb4d61ee
MD5 1406203d9b761ece369883f460e2215d
BLAKE2b-256 4712ce1b087354c79d966c3f3027293cb641240e53d013b38983b85b2d45e6bb

See more details on using hashes here.

File details

Details for the file mdformat_space_control-0.3.2-py3-none-any.whl.

File metadata

File hashes

Hashes for mdformat_space_control-0.3.2-py3-none-any.whl
Algorithm Hash digest
SHA256 baa2b133f95622729c5e609934a5090665838680573fcde54c548153008c6393
MD5 7692a4def2f6e6a33d0bbc5ddbdd71a2
BLAKE2b-256 ca346c824b5d0f089224322feac91964a7b1797ac89544eaf3c8a108206d60b1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page