uf90: Unicode mathematical notation for portable Fortran
uf90 lets you write mathematical Unicode identifiers in Fortran projects.
It translates *.f90u files into ordinary ASCII *.f90 files, which are then
compiled by fpm and your existing Fortran compiler.
The project is at an early stage (0.1.x). It is a source-to-source translator,
not a compiler or a Fortran language extension.
Quick start with fpm
Install the version published on PyPI with
pipx:
pipx install uf90
If your shell cannot find uf90 or fpm-uf90 after installation, run
pipx ensurepath and open a new terminal.
The installation provides both the uf90 command and the fpm-uf90 plugin.
With fpm and fpm-uf90 available on PATH, run the plugin from a project
containing an fpm.toml file:
fpm uf90 build
fpm uf90 run
fpm uf90 test
The plugin finds *.f90u files in the project, updates their corresponding
*.f90 files, and forwards the command to fpm. Additional arguments are
forwarded as well:
fpm uf90 build --profile release
In practice, this:
fpm uf90 build
is equivalent to:
uf90 sync
fpm build
Minimal example
Write source files in the directories recognized by fpm, using the .f90u
extension. This example rotates the point (x₀, y₀) by an angle θ and stores
the result in (x₁, y₁):
! app/main.f90u
program rotation
implicit none
real :: π, θ
real :: x₀, y₀, x₁, y₁
π = acos(-1.0)
θ = π / 4.0
x₀ = 1.0
y₀ = 0.0
x₁ = cos(θ) * x₀ - sin(θ) * y₀
y₁ = sin(θ) * x₀ + cos(θ) * y₀
print *, x₁, y₁
end program rotation
Running fpm uf90 run generates:
! app/main.f90
program rotation
implicit none
real :: uc_pi, uc_theta
real :: x_0, y_0, x_1, y_1
uc_pi = acos(-1.0)
uc_theta = uc_pi / 4.0
x_0 = 1.0
y_0 = 0.0
x_1 = cos(uc_theta) * x_0 - sin(uc_theta) * y_0
y_1 = sin(uc_theta) * x_0 + cos(uc_theta) * y_0
print *, x_1, y_1
end program rotation
Strings and comments are preserved. The .f90 file is generated output; edit
the corresponding .f90u source instead.
Supported notation
- Greek letters:
α→uc_alpha,Δt→uc_deltat; - numeric subscripts:
T₁₀₀→T_100; - alphanumeric subscripts:
Eₙ→E_n,Aᵢⱼ→A_ij; - superscripts:
c²→c_p2.
With uf90-ls, type a LaTeX-style Greek name such as \alpha or \Delta and
accept the completion to insert α or Δ. This works in both VS Code and
Neovim; the generated Neovim setup also maps Ctrl+Space to manual completion.
Unicode does not provide subscript forms for every letter. The current set
includes ₐ ₑ ₕ ᵢ ⱼ ₖ ₗ ₘ ₙ ₒ ₚ ᵣ ₛ ₜ ᵤ ᵥ ₓ, ₔ, digits, and the Greek forms
ᵦ ᵧ ᵨ ᵩ ᵪ.
Commands without fpm
For direct use or integration with other workflows:
uf90 sync [directory]
uf90 check [directory]
uf90 translate source.f90u [-o source.f90]
uf90 fortls-config [directory]
uf90 editor-config {vscode,neovim} [-o file]
uf90 sync uses .uf90-manifest.json as an incremental cache. uf90 check
does not modify files and returns a non-zero status when generated output needs
to be updated.
Editors
The experimental 0.2 uf90-ls proxy lets fortls analyze generated .f90
files while editors continue displaying .f90u. Setup guides are available
for VS Code
and Neovim.
The design document
tracks the architecture, acceptance criteria, and remaining scope.
From a 0.2 development checkout, install the proxy and its tested fortls in one
isolated environment with pipx install --force --editable '.[lsp]'. Then use
uf90 editor-config vscode or uf90 editor-config neovim to generate a ready
configuration.
Project status and scope
The current version is intended for experimenting with the notation in fpm
projects and for finding translation cases that are not covered yet. The
interface and mappings may change while the project remains below version
1.0.
uf90 currently:
- translates identifiers without changing text inside strings and comments;
- generates ASCII Fortran that continues through the regular
fpmworkflow; - runs automated tests on Linux, macOS, and Windows with Python 3.10 through 3.14.
It does not validate program semantics, replace the Fortran compiler, or depend on LLVM or MLIR.
Examples and development
The examples directory
contains six progressive fpm projects. To run them from a repository clone:
python3 -m pip install -e '.[test]'
python3 -m pytest
python3 examples/run_all.py
The maintainer release procedure is documented in
docs/RELEASING.md.
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 uf90-0.2.0.tar.gz.
File metadata
- Download URL: uf90-0.2.0.tar.gz
- Upload date:
- Size: 55.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
901aaa59312425927e62facf264d9ede8c13b675761947f38ece967d08fcbe2c
|
|
| MD5 |
7e15c19ecd1fc47c2be8007a464ff05e
|
|
| BLAKE2b-256 |
7cf6c8d2b39364415ab245e0dd19cd77cb3c826e2373c401aacc70cea6d13769
|
Provenance
The following attestation bundles were made for uf90-0.2.0.tar.gz:
Publisher:
publish.yml on nnardoto/uf90
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uf90-0.2.0.tar.gz -
Subject digest:
901aaa59312425927e62facf264d9ede8c13b675761947f38ece967d08fcbe2c - Sigstore transparency entry: 2403445924
- Sigstore integration time:
-
Permalink:
nnardoto/uf90@5ace23e0c6fb0f9b69bec65d7767296c1f91160e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/nnardoto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5ace23e0c6fb0f9b69bec65d7767296c1f91160e -
Trigger Event:
release
-
Statement type:
File details
Details for the file uf90-0.2.0-py3-none-any.whl.
File metadata
- Download URL: uf90-0.2.0-py3-none-any.whl
- Upload date:
- Size: 24.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bc5b1142e2ed79c337adee71cb55d6eac0227499c1190c8bedef19795248407d
|
|
| MD5 |
d279028e160c34843391e8d894f223f9
|
|
| BLAKE2b-256 |
600b18ad8d41307efa9de8f3a6d2a51bca8f9d27362263cb7f1036ff2a96c8f5
|
Provenance
The following attestation bundles were made for uf90-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on nnardoto/uf90
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
uf90-0.2.0-py3-none-any.whl -
Subject digest:
bc5b1142e2ed79c337adee71cb55d6eac0227499c1190c8bedef19795248407d - Sigstore transparency entry: 2403446005
- Sigstore integration time:
-
Permalink:
nnardoto/uf90@5ace23e0c6fb0f9b69bec65d7767296c1f91160e -
Branch / Tag:
refs/tags/v0.2.0 - Owner: https://github.com/nnardoto
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@5ace23e0c6fb0f9b69bec65d7767296c1f91160e -
Trigger Event:
release
-
Statement type: