Packages
makeup_patch
0.1.0
Diff and patch lexer for the Makeup syntax highlighter. Provides syntax highlighting for unified, context and normal diffs in ExDoc and any other tool using Makeup.
Current section
Files
Jump to
Current section
Files
makeup_patch
README.md
README.md
# MakeupDiff
A [Makeup](https://hex.pm/packages/makeup) lexer for diffs and patches.
Diffs are a line-oriented format, so — unlike a lexer for a programming
language — this one classifies whole lines rather than individual syntactic
atoms.
## Supported dialects
- **Unified diffs** (`diff -u`, `git diff`, `hg diff`, `svn diff`), including
`@@ -old,count +new,count @@ section` hunk headers and the `@@@ ... @@@`
headers produced by combined (merge) diffs.
- **Context diffs** (`diff -c`): the `*** old` / `--- new` banner pair, the
`***************` hunk separator, the `*** 1,5 ****` and `--- 1,7 ----`
range lines, and the `!` change marker.
- **Normal diffs** (`diff` with no flags): `1,5c1,7` / `3d2` / `0a1` command
lines and the `<` / `>` content markers.
- **Git extended headers**: `diff --git`, `index`, `old mode`, `new mode`,
`new file mode`, `deleted file mode`, `copy from` / `copy to`,
`rename from` / `rename to`, `similarity index`, `dissimilarity index`,
`Binary files ... differ`, `GIT binary patch`.
- **Subversion / CVS scaffolding**: `Index: path`, the `====...` rule,
`Property changes on:`, `RCS file:`, `retrieving revision`.
- **`git format-patch` mail preambles**: the mbox `From <sha> Mon Sep 17`
line plus the usual `From:` / `Date:` / `Subject:` / MIME headers.
- The `\ No newline at end of file` marker.
## Token mapping
| Construct | Token type |
| --- | --- |
| added lines (`+`, `>`) | `:generic_inserted` |
| removed lines (`-`, `<`) | `:generic_deleted` |
| changed lines in context diffs (`!`) | `:generic_strong` |
| hunk headers, range lines, file banners | `:generic_subheading` |
| repository-level metadata (`diff --git`, `index`, ...) | `:generic_heading` |
| section hint trailing a unified hunk header | `:name_function` |
| mail headers of a `git format-patch` preamble | `:comment_preproc` |
| `\ No newline at end of file` | `:comment_special` |
| context lines and anything unrecognised | `:text` |
## Ambiguity of `---` and `+++`
A line starting with `---` is either the *old file* banner of a unified diff
or the removal of a line whose content begins with `--`; the same holds for
`+++`. The tokenizer emits a provisional token for both and resolves it in
the postprocessing pass from the surrounding lines:
- a `---` immediately followed by a `+++` is a banner pair;
- a `---` right after a repository-level heading, or at the very start of the
input, is a banner;
- everything else is ordinary added/removed content.
So a literal `---` inside a hunk — right after an `@@` header, say — is
correctly highlighted as a deleted line rather than as a file banner.
## Installation
Add `makeup_patch` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[
{:makeup_patch, "~> 0.1"}
]
end
```
The lexer will be automatically registered in Makeup for the language names
`"diff"`, `"udiff"` and `"patch"`, and for the file extensions `.diff` and
`.patch`.
## Usage
Once installed, ExDoc and any other tool using Makeup will automatically
syntax-highlight diff code blocks (tagged with `diff` as the language).
You can also use it directly:
```elixir
alias Makeup.Lexers.DiffLexer
DiffLexer.lex("""
--- a/lib/app.ex
+++ b/lib/app.ex
@@ -1,3 +1,3 @@ defmodule App do
def hello do
- :world
+ :diff
end
""")
```
The lexer round-trips: for any input, `input |> DiffLexer.lex() |>
Makeup.Lexer.unlex()` returns the original string.
## License
MIT—see [LICENSE](https://github.com/am-kantox/makeup_patch/blob/main/LICENSE) for details.