(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 + 12. 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.pdf4. ELpeg1.lua
To be written! See: (find-show2 "LUA/ELpeg1.lua")