An uncompromising Fortran formatter, inspired by Black
Project description
An uncompromising Fortran formatter, inspired by Black.
"So it goes." — Kurt Vonnegut, Slaughterhouse-Five
Sable enforces one consistent style for modern free-form Fortran, so you can focus on code instead of formatting.
Installation
pip install sable-fortran
Usage
# Format a file or directory in place
sable my_module.f90
sable src/
# Check formatting without changing files (exit 1 if changes are needed)
sable --check src/
# Preview changes as a unified diff
sable --diff src/
# Check + diff together (non-zero if any file would change)
sable --check --diff src/
# Migration mode: only low-risk whitespace/layout changes
sable --safe src/
# Format piped input (Sable reads stdin when no files are passed)
cat code.f90 | sable
# Optional: label stdin input in diagnostics
cat code.f90 | sable --stdin-filename my_module.f90
Directory scans include .f90, .F90, .f95, .F95, .f03, .F03, .f08,
and .F08 files.
What Sable changes
- Normalizes keyword/operator style (
INTEGER->integer,.EQ.->==,endif->end ifby default). - Applies consistent spacing and indentation.
- Wraps long lines deterministically (including one-argument-per-line layouts).
- Canonicalizes declarations (
::, stable attribute order). - Preserves directives and formatting-off regions (
! sable: off/on). - Guarantees idempotent output with exactly one trailing newline.
! Before
IF(A .EQ. B)THEN
CALL compute(alpha_input,beta_input,gamma_input,result_output)
ENDIF
! After
if (A == B) then
call compute( &
alpha_input, &
beta_input, &
gamma_input, &
result_output &
)
end if
Formatting rules (quick reference)
| Old | New |
|---|---|
.EQ. |
== |
.NE. |
/= |
.LT. |
< |
.LE. |
<= |
.GT. |
> |
.GE. |
>= |
- Keywords are lower-case by default (
--keyword-case upperto change). - Names are preserved exactly as written.
- End keywords use spaced forms by default (
end if,end do; configurable). .AND.,.OR.,.NOT.,.EQV.,.NEQV.are preserved.- One space around most binary operators; no spaces around
%or**. - No spaces inside parens/brackets.
- Two spaces before inline comments (
x = 1 ! note). - Default indent is 3 spaces (
--indent-widthto change). - Long lines wrap with
&using deterministic split rules (--line-length). - Multi-statement lines split into one statement per line.
Configuration
Sable intentionally exposes few options:
| Flag | Default | Description |
|---|---|---|
--line-length, -l |
100 |
Max line length |
--indent-width, -i |
3 |
Spaces per indent level |
--keyword-case |
lower |
lower or upper |
--end-keyword-form |
spaced |
spaced or compact |
--no-normalize-operators |
off | Keep old-style relational operators |
--safe |
off | Migration mode; skip non-safe syntax/canonicalization rewrites |
--quiet |
off | Suppress non-error status output |
Name
Sable is heraldic for black — a nod to Black, the Python formatter that inspired this project.
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sable_fortran-0.1.5.tar.gz.
File metadata
- Download URL: sable_fortran-0.1.5.tar.gz
- Upload date:
- Size: 43.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc2bb2af34fa3fc66cb15809e3c7e5622c3aa956bb0829ede1719c75d73a741b
|
|
| MD5 |
66dc65ec82fc2e56d8d551626edbf212
|
|
| BLAKE2b-256 |
cd724a6a7ab0e6c7bafdc701c7a27c4c1eaaa47555e2dad7900ede5bc69c49cd
|
Provenance
The following attestation bundles were made for sable_fortran-0.1.5.tar.gz:
Publisher:
publish.yml on eirik-kjonstad/sable
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sable_fortran-0.1.5.tar.gz -
Subject digest:
bc2bb2af34fa3fc66cb15809e3c7e5622c3aa956bb0829ede1719c75d73a741b - Sigstore transparency entry: 1013763527
- Sigstore integration time:
-
Permalink:
eirik-kjonstad/sable@07483e89edb1439350b344eae97dd159026932f5 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/eirik-kjonstad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@07483e89edb1439350b344eae97dd159026932f5 -
Trigger Event:
release
-
Statement type:
File details
Details for the file sable_fortran-0.1.5-py3-none-any.whl.
File metadata
- Download URL: sable_fortran-0.1.5-py3-none-any.whl
- Upload date:
- Size: 30.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
defc28912870e4bf0ece831344eb765d33a5dff9edc18026a80a672ed1ef7756
|
|
| MD5 |
d7449ebcfb60b6a9eefbec5fa2c5c408
|
|
| BLAKE2b-256 |
337863bf3e1df7f7f0b493c3fec80c9fa39670505f32fc7f46f1163468c5156c
|
Provenance
The following attestation bundles were made for sable_fortran-0.1.5-py3-none-any.whl:
Publisher:
publish.yml on eirik-kjonstad/sable
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
sable_fortran-0.1.5-py3-none-any.whl -
Subject digest:
defc28912870e4bf0ece831344eb765d33a5dff9edc18026a80a672ed1ef7756 - Sigstore transparency entry: 1013763572
- Sigstore integration time:
-
Permalink:
eirik-kjonstad/sable@07483e89edb1439350b344eae97dd159026932f5 -
Branch / Tag:
refs/tags/v0.1.5 - Owner: https://github.com/eirik-kjonstad
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@07483e89edb1439350b344eae97dd159026932f5 -
Trigger Event:
release
-
Statement type: