(Re)generate: (find-show2-intro)
Source code: (find-efunction 'find-show2-intro)
More intros: (find-eev-quick-intro)
(find-eev-intro)
(find-eepitch-intro)
This buffer is _temporary_ and _editable_.
It is meant as both a tutorial and a sandbox.
1. Introduction
My presentation at the EmacsConf2023 was titled "REPLs in
strange places: Lua, LaTeX, LPeg, LPegRex, TikZ". My page about
it is here,
http://anggtwu.net/emacsconf2023.html
and its two videos are here:
Info: (find-1stclassvideo-links "eev2023repls")
(find-1stclassvideo-links "eev2023replsb")
Play: (find-eev2023replsvideo "0:00")
(find-eev2023replsbvideo "0:00")
Subs: (find-eev2023replslsubs "0:00")
(find-eev2023replsblsubs "0:00")
http://anggtwu.net/emacsconf2023-repls.html
http://anggtwu.net/emacsconf2023-repls-b.html
The presentation was about a family of small Lua programs that
were all built on top of these two libraries:
http://anggtwu.net/LUA/Show2.lua.html
http://anggtwu.net/LUA/ELpeg1.lua.html
(find-angg "LUA/Show2.lua")
(find-angg "LUA/ELpeg1.lua")
where Show2.lua is the module that lets us generate LaTeX code
from REPLs and that displays the resulting PDFs using a 3-window
setting like this one,
___________________________
| | |
| | [t]arget |
| the file | buffer |
| being |_______________|
| [e]dited | |
| (a .lua) | [v]iew the |
| | resulting PDF |
|___________|_______________|
and ELpeg1 is the module that lets us create parsers in REPLs. In
most cases these parsers return abstract syntax trees (ASTs),
that are displayed in a format like this one:
Stmt__.________________.
| | |
if Expr__._____. Stmt
| | | |
Id Optr Num StmtList_______.
| | | | |
x > 9 Stmt__.__. Stmt__.__.
| | | | | |
Id = Expr Id = Expr__._____.
| | | | | |
x Num y Id Optr Num
| | | |
0 y + 1
2. Dependencies
Here we install some system-wide packages.
The first part - pdf-tools - should work everywhere.
The other part is different for each OS and distro.
2.1. Pdf-tools
** Make sure that you have pdf-tools installed in Emacs.
** This part should work in all OSs (except Windows).
** Note: some of the sexps below take a long time - many seconds!
**
** See: (find-melpa-links)
** (find-epackage-links 'pdf-tools)
**
* (package-initialize)
* (add-to-list 'package-archives '("melpa" . "https://melpa.org/packages/"))
* (package-refresh-contents)
* (package-install 'pdf-tools)
** (find-epackage 'pdf-tools)
2.2. Debian
** Make sure that we have the Debian packages that we need.
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
sudo apt-get install build-essential
sudo apt-get install lua5.1 lua5.1-doc lua5.1-dev
sudo apt-get install lua5.2 lua5.2-doc lua5.2-dev
sudo apt-get install lua-lpeg lua-lpeg-dev
sudo apt-get install texlive-latex-extra
** This will be used to build lpeglabel
* (setenv "LUA52DIR" "/usr/include/lua5.2")
** Define links to some manuals
* (code-brappend "lua51manual" "file:///usr/share/doc/lua5.1-doc/doc/manual.html")
* (code-brappend "lua52manual" "file:///usr/share/doc/lua5.2-doc/manual.html")
* (code-brappend "lpegmanual" "file:///usr/share/doc/lua-lpeg-dev/lpeg.html")
* (code-brappend "lpegremanual" "file:///usr/share/doc/lua-lpeg-dev/re.html")
** Tests: (find-lua51manual)
** (find-lua52manual)
** (find-lpegmanual)
** (find-lpegremanual)
2.3. Arch Linux
** Make sure that we have the Pacman packages that we need.
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
sudo pacman -S base-devel
sudo pacman -S lua51 lua51-lpeg
sudo pacman -S lua52 lua52-lpeg
sudo pacman -S texlive-latexextra
** This will be used to build lpeglabel
* (setenv "LUA52DIR" "/usr/include/lua5.2")
** Define links to some manuals
* (code-brappend "lua51manual" "file:///usr/share/doc/lua51/manual.html")
* (code-brappend "lua52manual" "https://www.lua.org/manual/5.2/manual.html")
* (code-brappend "lpegmanual" "http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html")
* (code-brappend "lpegremanual" "http://www.inf.puc-rio.br/~roberto/lpeg/re.html")
** Tests: (find-lua51manual)
** (find-lua52manual)
** (find-lpegmanual)
** (find-lpegremanual)
2.4. MacOS (MacPorts)
** Make sure that we have the MacPorts packages that we need.
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
sudo port install lua-lpeg lua51-lpeg lua52-lpeg
sudo port install texlive-latex-extra
** This will be used to build lpeglabel
* (setenv "LUA52DIR" "/opt/local/include/lua5.2")
** Define links to some manuals
* (code-brappend "lua51manual" "file:///opt/local/share/doc/lua51/html/manual.html")
* (code-brappend "lua52manual" "file:///opt/local/share/doc/lua52/html/manual.html")
* (code-brappend "lpegmanual" "http://www.inf.puc-rio.br/~roberto/lpeg/lpeg.html")
* (code-brappend "lpegremanual" "http://www.inf.puc-rio.br/~roberto/lpeg/re.html")
** Tests: (find-lua51manual)
** (find-lua52manual)
** (find-lpegmanual)
** (find-lpegremanual)
3. Installation (on /tmp/)
** Clone the git repository with Show2.lua and friends.
** See: https://github.com/edrx/show2-elpeg1#introduction
* (eepitch-shell)
* (eepitch-kill)
* (eepitch-shell)
rm -Rfv /tmp/show2-elpeg1/
mkdir /tmp/show2-elpeg1/
cd /tmp/show2-elpeg1/
git clone https://github.com/edrx/show2-elpeg1 .
** Clone the git repositories of lpegrex and lpeglabel
** inside /tmp/show2-elpeg1/. Notes:
** 1) lpegrex depends on lpeglabel
** 2) lpeglabel needs to be compiled
** 3) lpeglabel doesn't work on Lua5.1, so we use Lua5.2
** 4) the (lua)rocks for lpegrex and lpeglabel don't work
** 5) I only use lpegrex in a few examples, and for comparisons
rm -Rfv /tmp/show2-elpeg1/lpeglabel
rm -Rfv /tmp/show2-elpeg1/lpegrex
cd /tmp/show2-elpeg1/
git clone https://github.com/sqmedeiros/lpeglabel
git clone https://github.com/edubart/lpegrex
cd /tmp/show2-elpeg1/lpeglabel/
make LUADIR=/usr/include/lua5.2 2>&1 | tee om
** Define links to some directories and manuals
* (code-c-d "show2" "/tmp/show2-elpeg1/" :anchor)
* (code-brappend "lua51manual" "file:///usr/share/doc/lua5.1-doc/doc/manual.html")
* (code-brappend "lua52manual" "file:///usr/share/doc/lua5.2-doc/manual.html")
* (code-brappend "lpegmanual" "file:///usr/share/doc/lua-lpeg-dev/lpeg.html")
* (code-brappend "lpegremanual" "file:///usr/share/doc/lua-lpeg-dev/re.html")
** Tests: (find-show2file "")
** (find-show2 "LUA/")
** (find-show2 "LUA/Show2.lua" "introduction")
** (find-show2 "LUA/lua50init.lua")
** (find-lua51manual)
** (find-lua52manual)
** (find-lpegmanual)
** (find-lpegremanual)
** Make some ennvironment variables point to /tmp/show2-elpeg1/
* (setenv "SHOW2LUADIR" "/tmp/show2-elpeg1/LUA")
* (setenv "SHOW2LATEXDIR" "/tmp/show2-elpeg1/LATEX")
* (setenv "LUA_INIT" "@/tmp/show2-elpeg1/LUA/lua50init.lua")
* (setenv "LUA_PATH" "/tmp/show2-elpeg1/LUA/?.lua;;")
** In show2-elpeg1 the Path.addLUAtopath() below is defined as a no-op.
** See: (find-show2 "LUA/lua50init.lua" "Path.addLUAtopath")
** Test if the init file and "require" both work.
** See: (find-show2 "LUA/Tos2.lua")
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
PP({10,20,"30",d=40})
Path.addLUAtopath()
= Path.from "path"
require "Tos2"
PPC(Tos.__index)
** Test lpegrex: first test (boring).
** Hint: no errors good, errors bad.
* (eepitch-lua52)
* (eepitch-kill)
* (eepitch-lua52)
Path.prepend("path", "/tmp/show2-elpeg1/lpeglabel/?.lua")
Path.prepend("cpath", "/tmp/show2-elpeg1/lpeglabel/?.so")
Path.prepend("path", "/tmp/show2-elpeg1/lpegrex/?.lua")
require "lpegrex"
require "tests/csv-test"
arg = {"/home/edrx/usrc/lpegrex/examples/lua-ast.lua"}
require "examples/lua-ast"
** Test lpegrex: check if loadlpegrex works
* (eepitch-lua52)
* (eepitch-kill)
* (eepitch-lua52)
loadlpegrex "/tmp/show2-elpeg1"
Path.addLUAtopath()
require "Tos2"
PPC(lpegrex)
3. Show2.lua
Remember that Show2.lua uses a 3-window setting like this:
___________________________
| | |
| | [t]arget |
| the file | buffer |
| being |_______________|
| [e]dited | |
| (a .lua) | [v]iew the |
| | resulting PDF |
|___________|_______________|
Both Show2.lua and Emacs need to configured to use the same PDF
file. This is done by running lines like these ones with <f8>s:
* (show2-use "{dir}/{stem}.{ext}")
* (show2-use "/tmp/show2-elpeg1/LATEX/Show2.tex")
* (show2-use "$SHOW2LATEXDIR/Show2.tex")
* (show2-use "$SHOW2LATEXDIR/")
* (show2-use "/tmp/Show2.tex")
* (show2-use "/tmp/")
`show2-use' displays all the details of what it does in the
window at the right, and when we run a `show2-use' in a red star
line it also displays some information in the echo area. The
communication with Lua is done by setting two environment
variables - SHOW2DIR and SHOW2STEM - but the details are not
important now.
Let's see how that works in practice.
3.1. A minimal example
This is a minimal example of how to use Show2.lua:
* (show2-use "/tmp/Show2.tex")
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
loadshow2()
body = [[ HELLO ]]
= body:show()
* (etv)
The `(show2-use ...)' in the beginning makes Show2.lua and Emacs
use the directory "/tmp/" and the files "/tmp/Show2.tex" and
"/tmp/Show2.pdf"; it also displays some explanations in the
right window. The
= body:show()
runs lualatex on "/tmp/Show2.tex" and then prints either
Show: /tmp/Show2.tex => ?
or:
Show: /tmp/Show2.tex => Success!
and the "* (etv)" at the end displays the resulting PDF in the
lower right window. To keep the code simple the `(etv)' doesn't
wait for the PDF to be produced; after typing an <f8> in the line
with the
= body:show()
you will have to wait until it prints a result -
"...Success!!!" or "...?" - and only then type an <f8> on the
line with the "* (etv)".
Try to run the "minimal example" at the beginning of this
section with <f8>s. Don't forget to wait after the ":show()"!
3.2. An example with extra lines
Try to run the example below with <f8>s - and don't forget to
wait a bit after the ":show()":
* (show2-use "/tmp/Show2.tex")
* (eepitch-lua51)
* (eepitch-kill)
* (eepitch-lua51)
loadshow2()
body = [[ \HELLO ]]
body = [[ HELLO ]]
= body:show00 {scale=4}
= body:show0 {scale=4}
= body:show {scale=4}
* (etv)
= Show.log
= Show.bigstr
The two "body = ..." lines let you choose between "HELLO",
that is valid LaTeX code, and "\HELLO", that will yield an
error. Choosing is explained here:
(find-elisp-intro "5. Variables")
(find-elisp-intro "5. Variables" "choosing the right order")
The "{scale=4}" is a Lua table with options for ":show". The
lines with ":show00" and ":show0" can be used to inspect the
first steps of what the ":show" would do: the ":show00" just
applies the options in the "{scale=4}" on the "body", and the
":show0" does that and returns the contents of (what would be)
the full .tex file.
The ":show" saves the log of running lualatex in Show.log and
saves the contexts of the .tex file in Show.bigstr. Try to run
the block above again, but now run the
body = [[ \HELLO ]]
and skip the:
body = [[ HELLO ]]
Now the ":show" will return a "?" indicating an error, and
the "* (etv)" will fail. You can use the "= Show.log" and the
"= Show.bigstr" to see the exact error message and the LaTeX
code that caused it.
3.3. ParseTree2.lua
Now try to run the example in this test block:
(find-show2 "LUA/ParseTree2.lua" "ParseTree-tests")
You should get something very similar to example that I used at
the beginning and at the end of my presentation at the
EmacsConf2023:
(find-eev2023replsvideo "0:00")
(find-eev2023replslsubs "0:00")
(find-eev2023replsvideo "56:58")
(find-eev2023replslsubs "56:58")
3.4. Dednat6
Some of the test blocks in this directory
(find-show2 "LUA/")
need to save their .tex files in a specific directory - this one,
(find-show2 "LATEX/")
(find-fline "$SHOW2LATEXDIR/")
because their .tex files need to load files that are there. Try
to run this test block:
(find-show2 "LUA/Verbatim3.lua" "dednat6-tests")
The line with the ":show0()" in the test block shows the
contents of the .tex file. You will see that it contains several
lines that start with "\input" and some lines that load
Dednat6, that is explained here:
(find-eev2023replsvideo "20:52")
(find-eev2023replslsubs "20:52")
http://anggtwu.net/dednat6/tug-slides.pdf
4. ELpeg1.lua
To be written! See:
(find-show2 "LUA/ELpeg1.lua")