quicklatex 0.1.0

A program to help me write LaTeX quickly
Documentation
[![dependency status](https://deps.rs/repo/codeberg/zvavybir/quicklatex/status.svg)](https://deps.rs/repo/codeberg/zvavybir/quicklatex)

# quicklatex
This program was written to enable me to write my lecture notes and
all other stuff related too me studying mathematics in LaTeX.  As
LaTeX is at times to verbose to write as quickly as a lecturer can on
a black board, this program makes some simplification to help me.

`quicklatex` is based on `pdflatex` and acts as a wrapper around it.
Most features are optional, so you can write QLX ("QLX" is my name for
the LaTeX-derived file format this program uses and is short for
"*q*uick *l*ate*x*") that is pretty similar to LaTeX (useful in the
beginning, but in the long term you will presumably want to use
all/most features).  Due to that similarity I'll need to know LaTeX
and I will presume that you do.


# Installation
To install `quicklatex`, please first ensure that `pdflatex` is
installed and available.  Then there are two ways to install
quicklatex:

* Manually:

	```
	git clone https://codeberg.org/zvavybir/quicklatex.git
	cd quicklatex
	cargo build --release
	cp target/release/quicklatex ~/bin
	```

	If you don't want to install it in `~/bin`, just replace the last
    line with the correct one (or remove it to not install it at all).
* Using Rust's package manager `cargo`:

	```
	cargo install quicklatex
	```

# Usage
To use the program just call it with the file name as you would
`pdflatex`:
```
quicklatex [OPTIONS] FILE [COUNT]
```
Explanation:

* Options:
	* `-p` or `--profiling`: Activates profiling.  This prints out the
      time various parts of quicklatex took.  Probably not necessary
      if you're not a `quicklatex` developer.
* File: The file name can be the actual file name or – if the name
  ends in `.tex` – with the `.tex`, `tex`, or `ex` left out (so if you
  have a file `my_notes/math.tex` you could also use
  e.g. `my_notes/math.t`).
* Count: By default (if this argument is not given) `quicklatex` will
  only run `pdflatex` once per invocation, but LaTeX famously needs
  multiple invocations sometimes.  You could do this by manually
  evoking `quicklatex` as you're used to, but this is more convenient
  and only has to convert from QLX to LaTeX once.  `COUNT` needs to be
  a non-negative integer.

The program outputs to the terminal the transformed LaTeX,
`pdflatex`'s output, and – if applicable – all generated warnings very
flashy (the warnings get outputted both at the beginning *and* the
end).


# `quicklatex` for LaTeX
Currently `quicklatex` only supports LaTeX.  It might support Typst at
some point.

## Minor features
There are a couple minor features:

* Auto newlining in math mode.  In environments whose name starts with
  "align" (like `align` and `align*`) double backslashes ("\\\\") are
  automatically added at the end of lines.  You can of course still
  make them manually anywhere (which doesn't interfere with this
  feature) or add an `%` at the end of the line to comment it out.
* `quicklatex` stops processing at the "𝇞" character and silently
  throws away anything afterwards, so if you include one of them in
  your file you have some space to put scibbles/… that you don't want
  `pdflatex` to see (because e.g. there malformed LaTeX or because
  shouldn't end up in the PDF).

## QLR files & custom replacements
Alongside of QLX files (which are the files you write your actual
LaTeX-ish source code in) there are also QLR files (short for
"*q*uick*l*atex *r*eplacement") which are the config files for
`quicklatex`.

The QLR file that is used in a specific case is determined as follows:

* `quicklatex` checks if there is a file with the same name as the
  file that should be built except for the extension `.qlr` and if it
  finds it uses that one.  So if you try to build `my_notes/math.tex`,
  `quicklatex` looks for a file with the name `my_notes/math.qlr`.
* If that fails it tries to use `~/.zvavybir/quicklatex/default.qlr`.
* If that file also doesn't exist, it just uses no file.

The format of the QLR files is pretty restrictive.  On each line there
*must* be *exactly* one command, which consists out of the command
name, a space, and a semicolon seperated list of arguments.  The
arguments itself are arbitrary (as long as they don't contain
newlines, semicola, or malformed escape sequences)
and you can use the following escape sequences there:

* `\\`: A literal backslash.
* `\;`: A semicolon.  These are necessary to distinguish them from
  the argument seperator.
* `\n`: A newline character.
* `\s`: A space character.  Arguments *can* also contain literal
spaces, but that's often not advisable for readability purposes, so
there is this other option.

All commands are run one-after-the-other on the whole file (except
`refkind` ones, as later explained).

There are a bunch of command names, falling in two categories:

* The replacement commands: The base form of a replacement command is
  `replace FROM;TO` with `FROM` and `TO` being arbitrary.  This
  command simply replaces all occurences of `FROM` with `TO` (at once,
  so if `TO` contains `FROM` or similar it's not run again; see
  `_repeated` for that below), no matter whether that looks sensible
  to LaTeX (i.e. it's non-hygienic, which is exactly the thing that
  makes `quicklatex` so useful).  To illustrate this, let's look at
  the following QLR file (instead of the spaces around that "+" we
  could of course also have used the `\s` escape sequence):
  ```
  replace \\frac{a}{;1
  replace b}; + 2
  ```
  This would replace `\frac{a}{b}` to `1 + 2` and `\frac{a}{5 b}` to
  `15 + 2`.

  It is generally advisable to make sure that other replacement rules
  and LaTeX tokenization don't interfere with that rule.  The probably
  most important part of that is that I usually add a space (or more
  precisely a `\s`) at the end of a LaTeX command substitution (so for
  example I want `ð` to be the fraction command, so I use the
  replacement rule `replace ð;\\frac\s`, not `replace ð;\\frac`).

  The following four suffixes can be added to "replace" to make other
  command names with other functionality (these are *arbitrarily*
  combinable and the order doesn't matter, so
  e.g. `replace_noisy_conditionally` and `replace_conditionally_noisy`
  is the same thing):

  * `_noisy`: If such a replacement rule is triggered `quicklatex`
    outputs a big warning at the beginning and end of it's terminal
    output saying which it was.  This is useful to temporarily fix
    typos (e.g. I often mistype `\approx` as `\apporx`, so I have the
    `replace_noisy \\apporx;\\approx` rule).
  * `_repeated`: This runs the replacement many times (until nothing
    would change anymore anyway or a recursion was detected).  I don't
    know why I implemented that because it's only so rarely useful
    that I can't find a single time I used it.
  * `_conditionally`: This command takes a third argument and is only
    then run if this argument is present *anywhere* in the file at the
    time the command is run.  Say we have a file with `abc` in it and
    the QLR file is as follows:
	```
	replace c;xyz
	replace_conditionally a;123a;yz
	```
	The first command yields `abxyz` and the second makes it
    `123abxyz`.  Without the first command it would stay at `abc`,
    despite there being an `a` that could be replaced.
  * `_refkind`: These commands are special because they runs *after
    all non-`refkind` ones* (but still before later `refkind` ones)
    and `replace_refkind FROM;TO` replaces `FROM\ref` (instead of
    `FROM`) with `TO`.  Otherwise though they are normal (especially
    this means that "refkind" can be combined with the other suffixes
    (apart from `_repeated`, which here doesn't do anything) as
    usual).  These are useful if you refer to labels with something
    else than LaTeX's `\ref` command.
* The include commands: The base form of an include command is
  `include FILE` with `FILE` being the file that is included (relative
  paths are evaluated relative to the file that has the `include`
  command).  Since QLR doesn't have variables or similar there is only
  one sensible way that inclusion could work (i.e. the command is
  replaced by the contents of the file (or any equivalent phrasing)),
  so `quicklatex` does that one.

  If you add the `_default` suffix (i.e. use `include_default FILE`),
  `quicklatex` doesn't search relative to the including file, but
  relative to `~/.zvavybir/quicklatex`.  I tend to have one
  `~/.zvavybir/quicklatex/COURSENAME.qlr` file (which contains at
  least the line `include_default default.qlr`[^10]) for each course I
  take and then use `include_default COURSENAME.qlr` in the QLR file
  of each file I'm writing for that course.

## Labels
`quicklatex` automatically checks if labels are in the correct order,
duplicated, or non-existent and removes unused ones.  For the first
point `quicklatex` expects each label to consist out of a consitent
number of numbers (the numbers can be of any sign and can be
fractional) seperated by colons, and warns otherwise.

For the last two points `quicklatex` needs to be able to automatically
figure out which labels exist and which are used.  For this it expects
labels to be declared as `\label{LABEL}` and used as `\ref{LABEL}`.
To not remove labels that are referred to exclusively by LaTeX
commands that aren't `\ref` there are the `_refkind` replacement
commands.  As explained above the rule `replace_refkind FROM;TO`
replaces `FROM\ref` with `TO`.  For example to use custom text in a
reference (i.e. LaTeX command `\hyperref[LABEL]{TEXT}`) I have the
replacement rule `replace_refkind hyper;\\hyperrefzvav` and in a LaTeX
package the command definition
`\newcommand{\hyperrefzvav}[2]{\hyperref[#1]{#2}}`, which I then use
with `hyper\ref{LABEL}{TEXT}`.

Unused labels aren't considered an issue, but wrongly ordered,
duplicated, and non-existent ones are, so `quicklatex` will output a
flashy warning for these.  It might be important to note here though
that some warning obscure others (after all, one warning already means
that's something is out of wack, so it doesn't always even make sense
to say what is supposed to happen otherwise), but if there are issues
you will always get *at least one* warning out (although maybe not the
multiple ones that would be appropriate).

## Short brackets
There are a lot of brackets used in LaTeX and at least for me the
typing required for that (especially for the going back after you have
the closing one) is a bit annoying, so `quicklatex` makes small
brackets easier to type by front-loading all the typing.  To use this
in practice, you type one or two characters specifying the length of
the contents of the brackets, one character for what kind it is, and
the the content.

The following lengths are available (all typed via AltGr+Number on a
normal Linux keyboard layout):

* `¹`: One character.
* `²`: Two characters.
* `³`: Three characters.
* `¼`: Four characters.
* `½`: Five characters.
* `§` + Digit or Letter: As many characters as specified in the digit
  or letter (letters go `a` being 10, `b` being 11, and so forth till
  `z` being 35).

The following bracket kinds are supported:

* ` ` (a space), `c`, `{`, or `}`: Curly brackets.
* `p`, `(`, or `)`: Inserts `ł(` as opening bracket and `¶)` as
  closing bracket.
* `q`, `[`, or `]`: Inserts `ł[` as opening bracket and `¶]` as
  closing bracket.
* `a`, or `|`: Inserts `ł|` as opening bracket and `¶|` as closing
  bracket.
* `i`, or `.`: Inserts `ł.` as opening bracket and `¶|` as closing
  bracket (yes, opening and closing are intentionally different;
  that's not a typo).

Apart from the first they all rely on my replacement rules
`replace ł;\\left\s` and `replace ¶;\\right\s`.  To use any of those
short brackets you will need some rules to deal with "ł" and "¶", even
if you might want to use some other short-form for `\left` and
`\right`.


# Contributing

`quicklatex` can always be improved and new use cases devised, so if
you have an idea, found a bug, or something else please feel free to
[open an issue](https://codeberg.org/zvavybir/quicklatex/issues/new)
or [open a pull request
(PR)](https://codeberg.org/zvavybir/quicklatex/pulls), or contribute
otherwise.


# License
`quicklatex` is licensed under the [GNU Affero General Public
License](https://www.gnu.org/licenses/agpl-3.0.txt) version 3 or any
later.


# General tips for writing LaTeX quickly
I want to end by giving a tip that more generally applies to writing
LaTeX (or anything similar) quickly, even if you don't use
`quicklatex`: Don't insist on "proper" form that isn't *necessary* for
readability, especially if it's annoying to type.  If, for example, I
want to write a half, I'm not writing it `\frac{1}{2}`, but `ð12` (or
`\frac12` in raw LaTeX, without my `replace ð;\\frac\s` rule).
Because I now have nearly three years of experience with reading that,
it's nearly as intuitive as `\frac{1}{2}` or "½".

[^10] In this case (because the including file is already in
`~/.zvavybir/quicklatex` the "_default" suffix would be unnecessary,
but it feels clearer.)