Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/atreyagaurav/litex-mode
LiTeX mode for emacs; A minor mode to convert valid lisp expressions to LaTeX
https://github.com/atreyagaurav/litex-mode
emacs latex lisp
Last synced: 2 months ago
JSON representation
LiTeX mode for emacs; A minor mode to convert valid lisp expressions to LaTeX
- Host: GitHub
- URL: https://github.com/atreyagaurav/litex-mode
- Owner: Atreyagaurav
- License: gpl-3.0
- Created: 2022-02-06T23:55:12.000Z (almost 3 years ago)
- Default Branch: main
- Last Pushed: 2023-02-27T20:00:17.000Z (almost 2 years ago)
- Last Synced: 2023-03-05T09:52:50.586Z (almost 2 years ago)
- Topics: emacs, latex, lisp
- Language: Emacs Lisp
- Homepage:
- Size: 311 KB
- Stars: 43
- Watchers: 3
- Forks: 4
- Open Issues: 2
-
Metadata Files:
- Readme: README.org
- License: LICENSE
Awesome Lists containing this project
README
[[https://melpa.org/#/litex-mode][file:https://melpa.org/packages/litex-mode-badge.svg]]
[[https://stable.melpa.org/#/litex-mode][file:https://stable.melpa.org/packages/litex-mode-badge.svg]]* LiTeX mode
This is a minor mode to convert valid elisp/lisp expressions to latex.This is useful for emacs users because emacs allows lisp code to be directly evaluated inside any buffer, which means no need to have any code blocks. But since lisp expressions aren't popular we can't expect to put them in reports, so to overcome that I wrote this mode with the help of my friend [[https://gist.github.com/bpanthi977][Bibek Panthi]].
The beginning of this mode, and previous codes are here:
- [[https://emacs.stackexchange.com/questions/70358/how-can-i-convert-a-lisp-expression-to-a-latex-math-expression/70360?noredirect=1#comment113158_70360][Stackexchange Question]]
- [[https://gist.github.com/bpanthi977/4b8ece0eeff3bc05bb82275a23cbb56d][Bibek's gist]]
- [[https://github.com/Atreyagaurav/emacs-modules][My previous calculation template mode and first few versions of LiTeX]]For example if you look at this image you can see how just 1 lines of lisp expression can be converted to the final result of several lines of mathematical expression without even having to do any of the calculation.
[[./images/litex.png]]
Not only can it convert lisp expressions to latex, it can also, give intermediate solution steps. Perfect for doing homeworks (as that's what I made it for) :P
* Table of contents :TOC:
- [[#litex-mode][LiTeX mode]]
- [[#how-to-use][How to Use]]
- [[#installation][Installation]]
- [[#usage][Usage]]
- [[#keybindings][Keybindings]]
- [[#setting-keybindings-for-individual-functions][Setting keybindings for individual functions]]
- [[#setting-the-whole-litex-provided-keybindings-to-a-prefix-key][Setting the whole litex provided keybindings to a prefix key]]
- [[#complete-setup-using-use-package][Complete setup using use-package]]
- [[#known-problems][Known Problems:]]
- [[#tips-and-tricks][Tips and Tricks]]
- [[#including-units][Including Units]]
- [[#using-case-sensitive-symbols][Using case sensitive symbols]]
- [[#slime-integration][Slime integration]]
- [[#using-litex-variables-in-your-normal-calculations][Using LiTeX variables in your normal calculations]]
- [[#using-greek-letters][Using Greek letters]]
- [[#explanation-for-functions][Explanation for functions]]
- [[#litex-format-region-last][litex-format-region-last]]
- [[#litex-format-region][litex-format-region]]
- [[#litex-eval-and-replace][litex-eval-and-replace]]
- [[#litex-eval-and-insert][litex-eval-and-insert]]
- [[#litex-sexp-to-latex-exp][litex-sexp-to-latex-exp]]
- [[#litex-sexp-solve-all-steps][litex-sexp-solve-all-steps]]
- [[#litex-increment-number][litex-increment-number]]
- [[#litex-exp-to-latex][litex-exp-to-latex]]
- [[#litex-exp-in-latex-math][litex-exp-in-latex-math]]
- [[#litex-sexp-solve-all-steps-equation][litex-sexp-solve-all-steps-equation]]
- [[#litex-sexp-solve-all-steps-eqnarray][litex-sexp-solve-all-steps-eqnarray]]
- [[#customization][Customization]]
- [[#contributing][Contributing]]* How to Use
Here is a [[https://youtu.be/esEf63gSSPg][demo video]] describing the features of LiTeX mode.
For Text descriptions refer sections below for details on what each function does, and the meaning of custom variables.
You can also access it all from texinfo file provided with the package.
* Installation
You can install it through melpa with ~M-x package-install litex-mode ~.Or you can clone this github repo and load it using path.
Configuration section shows how you can add the load path using ~use-package~.
* Usage
Using ~use-package~ you can do:#+begin_src emacs-lisp :tangle yes
(use-package litex-mode
;; :load-path "/path/to/litex-mode/"
:commands litex-mode
:hook text-mode)
#+end_srcPlease look through the Keybindings, Functions, Variables, Known problems and the Tips and Tricks to get 100% out of this package.
* Keybindings
By default LiTeX-mode doesn't provide any keybindings, but it does have a variable containing bindings for the interactive functions that you can use.** Setting keybindings for individual functions
You can use ~local-set-key~ to bind individual functions to a key binding.
#+begin_src emacs-lisp :tangle yes
(local-set-key (kbd "×") 'litex-insert-or-replace-x)
#+end_src** Setting the whole litex provided keybindings to a prefix key
You can set a prefix key (~C-e~ for me here) like in this example, which makes it so you can for example use ~litex-format-region-last~ using ~C-e f~ using the following in your config. In some cases you might have to unset key ~C-e~ because it's used to goto end of line, I'm replacing that because I don't use it (as ~End~ key does the same).
#+begin_src emacs-lisp :tangle yes
(local-set-key (kbd "C-e") litex-key-map)
#+end_srcContents of litex-key-map are below.
#+begin_src emacs-lisp :tangle yes
(define-key litex-key-map (kbd "F") 'litex-format-region)
(define-key litex-key-map (kbd "f") 'litex-format-region-last)
(define-key litex-key-map (kbd "E") 'litex-eval-and-replace)
(define-key litex-key-map (kbd "e") 'litex-eval-and-insert)
(define-key litex-key-map (kbd "s") 'litex-sexp-to-latex-exp)
(define-key litex-key-map (kbd "S") 'litex-sexp-solve-all-steps)
(define-key litex-key-map (kbd "+") 'litex-increment-number)
(define-key litex-key-map (kbd "l") 'litex-exp-to-latex)
(define-key litex-key-map (kbd "m") 'litex-exp-in-latex-math)
(define-key litex-key-map (kbd "A") 'litex-sexp-solve-all-steps-equation)
(define-key litex-key-map (kbd "a") 'litex-sexp-solve-all-steps-eqnarray)
#+end_src** Complete setup using use-package
This is the complete setup using use-package, if you installed from melpa. If you installed by cloning the repo, uncomment and provide the load path.
#+begin_src emacs-lisp :tangle yes
(use-package litex-mode
;; :load-path "/path/to/litex-mode/"
:commands litex-mode
:hook text-mode
:config
(local-set-key (kbd "C-e") litex-key-map)
(local-set-key (kbd "×") 'litex-insert-or-replace-x))
#+end_src* Known Problems:
elisp uses integer calculations so ~(/ 1 2)~ is evaluated to 0, be careful of such pitfalls. For now ~(/ 1.0 2)~ is evaluated as ~0.5~, so I'd recommend using floats when you need floats.This problem doesn't exist if you use slime integration. But slime will evaluate =(/ 1 2)= as =1/2= so expect that to be the final answer.
* Tips and Tricks
** Including Units
LiTeX mode now supports unit conversion and formatting using the =[[https://github.com/Atreyagaurav/units-mode][units-mode]]= which in turn uses gnu units.The formatting is like below, the functions are from =units-mode= package.
- =(units-convert-simple (/ 1 2) "m" "ft") ⇒ \unit[\frac{1}{2}]{m}=
- =(units-ignore 5 "ft") ⇒ \unit[5]{ft}=It also formats correctly on step by step solve, for example:
- =(setq L (units-convert-simple (+ 1 2) "m" "ft"))=
#+begin_src latex
\begin{align*}
L& = \unit[1 + 2]{m}\\
& = \unit[3]{m}\\
& = \unit[9.843]{ft}
\end{align*}
#+end_src- =(setq l (units-ignore 24 "in"))=
#+begin_src latex
\begin{align*}
l& = \unit[24]{in}
\end{align*}
#+end_src*Note that the =\unit= latex command is from [[https://mirrors.mit.edu/CTAN/macros/latex/contrib/units/units.pdf][=units= package]], so you have to include it in your preamble.*
If you're using slime for evaluation, you need to load the units functions in slime too. The functions are available in units-mode's github named =clisp/units.lisp=.
For =sbcl= you can put the contents in =clisp/units.lisp= to =~/.sbclrc= so it's evaluated in sbcl/slime startup.
** Using case sensitive symbols
Inside emacs the symbols are read without case sensitivity, so if you define and variable names ~ABCD~, it'll replace the variable named ~abcd~. To avoid that, specially if you have formula with both lowercase and uppercase symbols you can use this customization.#+begin_src emacs-lisp :tangle yes
(setq readtable-case :preserve)
#+end_srcNOTE: Currently it only works for elisp, and not for slime integration, I'm searching for a solution with slime.
** Slime integration
If you want to do the calculations in your favorite lisp dilect instead of doing it in elisp, or polluting the emacs environment with your variables, or mistakenly messing something up. You can start a slime process with ~slime~ and use that process to evaluate everything.You Only need to set this configuration variable true:
#+begin_src emacs-lisp :tangle yes
(setq litex-use-slime-for-eval t)
#+end_src** Using LiTeX variables in your normal calculations
You can use the function =litex-eval= to evaluate expressions for you. If you don't have slime integration then normal evaluation will work, but this will handle both cases for you.For example:
#+begin_src emacs-lisp :tangle yes
(defun calc-Q (a b c)
(litex-eval `(+ (* C-1 ,b) (* C-2 ,a) (* C-3 ,c))))
#+end_src
Here, the function calc-Q can be called from elisp, so you can put it in the org table formula, while internally it uses the variables =C-1= to =C-3= from your slime instance.** Using Greek letters
Someone who writes in LaTeX will definitely want to include greek letters, so you can use greek letters multiple ways in LiTeX.*** By double escaping the backslash
You can use double escape to escape the backslash so you'll get the variable correct. For example: ~(setq \\alpha 2)~ ⇒ ~\alpha = 2~*** Using Unicode:
You can input unicode greek letters like α,β,γ...,Σ...,Ω, and they'll be rendered fine by LaTeX. For example: ~(setq α 2)~ ⇒ ~α = 2~. Which is the default behavior.If you want to use them to input, but still want to use LaTeX equivalent command then you can set ~litex-make-unicode-to-latex~ to true, that'll convert the unicode to LaTeX command. For example: ~(setq α 2)~ ⇒ ~{\alpha} = 2~.
#+begin_src emacs-lisp :tangle yes
(setq litex-make-unicode-to-latex t)
#+end_srcAs for how to type unicode directly, you can use Compose key in Linux machines, and there is also TeX input method in emacs that lets you do that. If you type ~C-u C-\ TeX ~ for TeX input method then when you type ~\alpha~ emacs will convert it into unicode ~α~.
*** Using conversion from their names
By default you can use variables names like ~alpha~ without having it any effect, for example: ~(setq alpha 2)~ ⇒ ~alpha = 2~ but if you set the variable ~litex-make-name-to-latex-glyph~ true then you can just convert normal greek character's names to LaTeX symbols.
Like: ~(setq alpha 2)~ ⇒ ~{\alpha} = 2~#+begin_src emacs-lisp :tangle yes
(setq litex-make-name-to-latex-glyph t)
#+end_srcWhen you have more than one letters, in this use case you have to separate them with ~.~, for example:
~(setq Delta.alpha 2)~ ⇒ ~{\Delta}{\alpha} = 2~This is so that the letters inside other words won't be converted automatically. As you can see ~.~ is only used for initial separation of words so you can use it to make the bounds where you want greek letters:
~(setq Delta./.alpha 2)~ ⇒ ~{\Delta}/{\alpha} = 2~* Explanation for functions
** litex-format-region-last
Formats the selection based on variable ~litex-format-string~.For example: ~2.3434343~ ⇒ ~2.34~ (when ~litex-format-string~ is ~.2f~)
** litex-format-region
Same as ~litex-format-region-last~ but asks for the format, it also sets the ~litex-format-string~ variable.*NOTE*: Doesn't work well with multiple-cursors, so first use this once, then use the ~litex-format-region-last~ on the multiple cursors.
** litex-eval-and-replace
Evals the last sexp and replaces it with the evaluation value.** litex-eval-and-insert
Evals the last sexp and inserts the evaluation value after that.The value and sexp are separated by ~litex-steps-join-string~ which is "= " by default.
** litex-sexp-to-latex-exp
Converts valid lisp sexp to latex Expression:For example: ~(+ 2 3 (* 6 x))~ ⇒ ~2 + 3 + 6 x~
** litex-sexp-solve-all-steps
Solves lisp sexp steps by steps:For example:
~(setq x 5)~ ⇒ ~x = 5~ then ~(setq y (+ 2 3 (* 6 x)))~ ⇒ ~y = (+ 2 3 (* 6 x)) = (+ 2 3 (* 6 5)) = (+ 2 3 30) = 35~** litex-increment-number
Increments the number.~some/url/to/chapter-2~ ⇒ ~some/url/to/chapter-3~
** litex-exp-to-latex
Converts exponential term to latex format.~1.23e-34~ ⇒ ~1.23 \times 10^{-34}~
** litex-exp-in-latex-math
Encloses the selection in latex inline math.~1.23e-34~ ⇒ ~\(1.23e-34\)~
** litex-sexp-solve-all-steps-equation
Same as ~litex-sexp-solve-all-steps~ but puts them in equation environment.For example: ~(setq y (+ 2 3 (* 6 x)))~ ⇒
#+begin_example
\begin{equation}
y= 2 + 3 + 6 x = 2 + 3 + 6 \times 5 = 2 + 3 + 30 = 35
\end{equation}
#+end_example** litex-sexp-solve-all-steps-eqnarray
Same as ~litex-sexp-solve-all-steps~ but puts them in eqnarray* environment.For example: ~(setq y (+ 2 3 (* 6 x)))~ ⇒
#+begin_example
\begin{eqnarray*}
y &=& 2 + 3 + 6 x \\
&=& 2 + 3 + 6 \times 5 \\
&=& 2 + 3 + 30\\
&=& 35
\end{eqnarray*}
#+end_example* Customization
There are lots of variables that define how each of these functions behave.| Variable Name | Default Value | What it does |
|---------------------------------------+------------------------+-----------------------------------------------------------------------------------------|
| litex-latex-functions | '(sin cos tan) | Lisp functions that have their own latex commands. |
| litex-make-hyphenated-to-subscript | t | Whether to make the hyphenated variables subscript or not. |
| litex-latex-always-enclose? | nil | Enclose latex converted to paran all the time. |
| litex-format-float-string | "%.3f" | Format string to be used by floats. |
| litex-format-float-upper-limit | 1e4 | Upper limit of what number is formatted as float. |
| litex-format-float-lower-limit | 1e-2 | Lower limit of what number is formatted as float. |
| litex-format-float-trim-decimal | nil | Trim zeros after decimal if all decimals are zeros. |
| litex-steps-join-string | "= " | String used for joining strings in steps of a solution. |
| litex-steps-end-string | " " | String used at the end of each strings in steps of a solution. |
| litex-math-inline-start | "\\(" | Opening syntax for math inline environment. |
| litex-math-inline-end | "\\)" | Closing syntax for math inline environment. |
| litex-math-equation-start | "\\begin{equation}\n" | Opening syntax for math equation environment. |
| litex-math-equation-end | "\n\\end{equation}\n" | Closing syntax for math equation environment. |
| litex-math-steps-equation-join-string | "= " | Value of `litex-steps-join-string' to be used in equation environment. |
| litex-math-steps-equation-end-string | " " | Value of `litex-steps-end-string' to be used in equation environment. |
| litex-math-eqnarray-start | "\\begin{eqnarray*}\n" | Opening syntax for math eqnarray environment. |
| litex-math-eqnarray-end | "\n\\end{eqnarray*}\n" | Closing syntax for math eqnarray environment. |
| litex-math-steps-eqnarray-join-string | " &=& " | Value of `litex-steps-join-string' to be used in eqnarray environment. |
| litex-math-steps-eqnarray-end-string | "\\\\\n" | Value of `litex-steps-end-string' to be used in eqnarray environment. |
| litex-math-align-start | "\\begin{align*}\n" | Opening syntax for math align environment. |
| litex-math-align-end | "\n\\end{align*}\n" | Closing syntax for math align environment. |
| litex-math-steps-align-join-string | "& = " | Value of `litex-steps-join-string' to be used in align environment. |
| litex-math-steps-align-end-string | "\\\\\n" | Value of `litex-steps-end-string' to be used in align environment. |
| litex-make-unicode-to-latex | nil | Convert unicode to LaTeX equivalent (eg. α -> \alpha) |
| litex-make-name-to-latex-glyph | nil | Convert variables with the same name as a glyph to a LaTeX glyph (eg. alpha -> \alpha). |
| litex-use-slime-for-eval | nil | Whether to use slime process for evalulation or not. You need to start slime yourself. |
| litex-greek-unicode-latex-alist | | Alist of greek unicode symbols and their LaTeX counterparts. |* Contributing
Since this package is new, I'd appreciate contributions on few things:- Finding bugs and reporting them in github issues.
- There are many tests to be written for the functions.
- Many functions that might have special syntax in LaTeX yet to be written. For example ~1+~, ~defun~ were added later (it only started with 4 operators), similar could be done for many more.
- Fixing some glitches with the current functions.
- Maybe some symbolic calculations using ~calc-eval~ if it has variables that are not yet defined.
- I'm thinking of making an org babel implementation where it'll generate the equations that we can include in latex export.