https://github.com/dhanushka2001/citeorder
Simple command-line tool to relabel Footnotes in Markdown files in numerical order. Program and integration testing written in C. Builds for Windows, macOS, and Linux.
https://github.com/dhanushka2001/citeorder
c citations cli command-line command-line-tool footnotes integration-testing markdown
Last synced: 3 months ago
JSON representation
Simple command-line tool to relabel Footnotes in Markdown files in numerical order. Program and integration testing written in C. Builds for Windows, macOS, and Linux.
- Host: GitHub
- URL: https://github.com/dhanushka2001/citeorder
- Owner: dhanushka2001
- License: gpl-3.0
- Created: 2025-09-23T22:18:32.000Z (7 months ago)
- Default Branch: main
- Last Pushed: 2026-01-13T10:05:23.000Z (3 months ago)
- Last Synced: 2026-01-13T11:55:34.639Z (3 months ago)
- Topics: c, citations, cli, command-line, command-line-tool, footnotes, integration-testing, markdown
- Language: C
- Homepage:
- Size: 123 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 2
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

# citeorder
[](https://github.com/dhanushka2001/citeorder/actions/workflows/main.yml)
[](https://github.com/dhanushka2001/citeorder/releases)
[](https://github.com/dhanushka2001/citeorder/blob/main/LICENSE)
[](https://github.com/dhanushka2001/citeorder/commits/main/)
[](https://github.com/dhanushka2001/citeorder/releases)
[](https://github.com/dhanushka2001/citeorder/stargazers)
[](https://github.com/dhanushka2001/citeorder/releases)
[](https://github.com/dhanushka2001/citeorder/releases)
[](https://github.com/dhanushka2001/citeorder/releases)
[](https://github.com/dhanushka2001/citeorder/releases)


Simple command-line tool to correctly reorder Footnotes in Markdown files.
## Motivation
Markdown processors that support footnotes (e.g. [GitHub’s Markdown engine](https://github.com/github/cmark-gfm), which implements the [GitHub Flavored Markdown](https://github.github.com/gfm) spec) automatically reorder footnotes when converting ``.md`` files to HTML. However, ``citeorder`` fixes the ordering in the ``.md`` file itself, making it neater and easier to manage lots of footnotes. Especially useful when needing to add new footnotes in the middle of a long ``.md`` file and not having to spend ages reordering every in-text and full-entry footnote manually (🥲).
In-text footnotes (``"Alice here",[^1]``) and full-entry footnotes (``[^1]: Alice``) are a many-to-one relationship. ``citeorder`` assumes the connections are correct, and relabels them according to the order in which the **in-text footnotes** appear.
## How to use
1. Download the precompiled executable from the latest [release](https://github.com/dhanushka2001/citeorder/releases).
Installation via Homebrew (macOS/Ubuntu):
```bash
brew install dhanushka2001/citeorder/citeorder
```
Installation via the [AUR](https://aur.archlinux.org/packages/citeorder) (Arch):
```bash
yay -S citeorder
```
Or clone the repo and compile source code
If you want to compile the source code yourself, clone the repo and compile ``citeorder.c``:
```console
git clone https://github.com/dhanushka2001/citeorder
```
```console
gcc -Wall citeorder.c -o citeorder
```
2. To run, simply enter into the terminal:
```console
citeorder input.md
```
where ``input.md`` is the Markdown file whose Footnotes you want reordered. ``citeorder`` will keep the original file as is and output the changes to a new file, ``input-fixed.md``.
To allow relaxed quote handling, do:
```console
citeorder -q input.md
```
For more info and options, run:
```console
citeorder -h
```
## Example
``example.md``:
```md
"Alice says hi".[^1]
[^1]: Alice
"Bob is here".[^7] "I'm Charlie",[^4] "Daniel!",[^5] here.
[^4]: Charlie
[^3]: Gary
[^5]: Daniel
[^7]: Bob
Is "Ethan"[^8] here?
[^8]: Ethan
"Bob and Charlie here again"[^7][^4]
[^6]: Fred
```
Running:
```console
citeorder example.md
```
will produce ``example-fixed.md``:
```md
"Alice says hi".[^1]
[^1]: Alice
"Bob is here".[^2] "I'm Charlie",[^3] "Daniel!",[^4] here.
[^2]: Bob
[^3]: Charlie
[^4]: Daniel
[^6]: Gary
Is "Ethan"[^5] here?
[^5]: Ethan
"Bob and Charlie here again"[^2][^3]
[^7]: Fred
```
## Cases handled
* No changes needed.
* Stacked in-text footnotes, e.g. ``"hello",[^3][^1][^5]`` → ``"hello",[^1][^2][^3]``.
* Single punctuation (or none) after end quote, e.g. ``"A"[^3] "B",[^2] "C".[^6] "D"![^5]`` → ``"A"[^1] "B",[^2] "C".[^3] "D"![^4]``.
* Improper quote, e.g. ``"hello[^1]``, ``"hello",,[^1]``, ``hello"[^1]``, ``"hello" [^1]`` produces an error message like: ``ERROR: in-text citation [^1] not properly quoted (line 5)``. Can ignore this error with the ``-r``/``--relaxed-quotes`` flag.
* Full-entry footnotes with no matching in-text footnotes simply get bubbled to the end of the ordering.
* In-text footnotes with no matching full-entry footnote produce an error message like: ``ERROR: in-text citation [^2] without full-entry (line 3)``.
* Duplicate full-entry footnotes, e.g.
```md
[^4]: Alice
[^4]: Bob
```
produces an error message like: ``ERROR: duplicate [^4] full-entry citations (line 7 and 8)``.
* Footnotes inside inline code (``"A"[^1]``) and fenced code blocks:
```md
"A"[^1]
[^1]: A
[^2]: B
```
are ignored.
* Footnote labels with letters/symbols are supported, and will be relabeled accordingly, e.g. ``"A"[^6b]`` → ``"A"[^1]``.
* Spaces in the in-text or full-entry footnotes. Spaces outside the label for in-text footnotes, e.g. ``"A"[^ Alice ]`` are accepted by Markdown processors, and ``citeorder`` will convert that to ``"A"[^1]``. However, for full-entry footnotes, e.g. ``[^ 4b ]: Alice``, it is not accepted, and in ``citeorder`` it will produce an error message like: ``ERROR: [^ 4b ] full-entry citation contains a space (line 3)``. For both in-text and full-entry footnotes, spaces **in** the label itself, e.g. ``"A"[^4 b]``, ``[^4 b]: Alice``, are not accepted, and in ``citeorder`` you will get an error message.
* In-text or full-entry footnote missing a label, e.g. ``"A"[^]``, will produce an error message like: ``ERROR: in-text citation [^] missing label (line 7)``.
* Multiline quote:
```md
"T"[^4]
"This quote takes
up multiple lines
but is still valid",[^3]
"H",[^6]
[^4]: T
[^6]: H
[^3]: Multiline quote
```
becomes:
```md
"T"[^1]
"This quote takes
up multiple lines
but is still valid",[^2]
"H",[^3]
[^1]: T
[^2]: Multiline quote
[^3]: H
```
* Duplicate full-entry footnotes, e.g.
```md
"A"[^dupe], "B"[^dupe]
[^dupe]: A
[^dupe]: B
"C"[^dupe]
[^dupe]: C
"D"[^1]
[^1]: D
```
can be auto-incremented using the ``-d``/``--relaxed-duplicates`` flag (must be only ONE duplicate footnote label, and must have an equal number of full-entry and in-text duplicates):
```md
"A"[^1], "B"[^2]
[^1]: A
[^2]: B
"C"[^3]
[^3]: C
"D"[^4]
[^4]: D
```