├── manage ├── resources ├── print-namespace.tex ├── test.zip ├── images │ ├── cast.png │ ├── node.id.png │ ├── tex.sp.png │ ├── node.write.png │ ├── LPeg_alias-01.png │ ├── LPeg_alias-02.png │ ├── Screenshot_CTAN.png │ ├── tex.sp_overload.png │ ├── Screenshot_LuaCATS.png │ ├── node.id_definition.png │ ├── node.id_wrong-type.png │ ├── PreLinebreakFilterCallback.png │ ├── Screenshot_VSCode-extension.png │ ├── PdfColorstockWhatsitNode.data.png │ └── Screenshot_Lua-Addon-Manager.png ├── screencasts │ └── node.new.gif ├── update-lls-addons.sh ├── webpages │ ├── md5.html.lua │ ├── md5.html │ ├── zip.html.lua │ ├── zip.html │ ├── socket.html.lua │ ├── mime.html.lua │ ├── mime.html │ └── socket.html └── namespaces │ └── luametatex_luaonly.md ├── .gitignore ├── stylua.toml ├── search.sh ├── docs ├── Lua-language-servers.md └── Lua-language-servers.tex ├── .vscode ├── settings.json └── snippets.code-snippets ├── Makefile ├── .gitmodules ├── LICENSE ├── utils.lua └── README.md /manage: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | ./manager/.venv/bin/manager --base-path="$(pwd)" "$@" 4 | -------------------------------------------------------------------------------- /resources/print-namespace.tex: -------------------------------------------------------------------------------- 1 | 2 | \directlua{require('resources/print-namespace.lua')()} 3 | \bye 4 | -------------------------------------------------------------------------------- /resources/test.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/test.zip -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/* 2 | tmp_cleaned.lua 3 | tmp.tex 4 | tmp.lua 5 | tmp.txt 6 | test.gz 7 | tmp.log 8 | tmp.pdf 9 | -------------------------------------------------------------------------------- /resources/images/cast.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/cast.png -------------------------------------------------------------------------------- /resources/images/node.id.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/node.id.png -------------------------------------------------------------------------------- /resources/images/tex.sp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/tex.sp.png -------------------------------------------------------------------------------- /resources/images/node.write.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/node.write.png -------------------------------------------------------------------------------- /resources/images/LPeg_alias-01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/LPeg_alias-01.png -------------------------------------------------------------------------------- /resources/images/LPeg_alias-02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/LPeg_alias-02.png -------------------------------------------------------------------------------- /resources/images/Screenshot_CTAN.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/Screenshot_CTAN.png -------------------------------------------------------------------------------- /resources/images/tex.sp_overload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/tex.sp_overload.png -------------------------------------------------------------------------------- /resources/screencasts/node.new.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/screencasts/node.new.gif -------------------------------------------------------------------------------- /resources/images/Screenshot_LuaCATS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/Screenshot_LuaCATS.png -------------------------------------------------------------------------------- /resources/images/node.id_definition.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/node.id_definition.png -------------------------------------------------------------------------------- /resources/images/node.id_wrong-type.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/node.id_wrong-type.png -------------------------------------------------------------------------------- /resources/images/PreLinebreakFilterCallback.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/PreLinebreakFilterCallback.png -------------------------------------------------------------------------------- /resources/images/Screenshot_VSCode-extension.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/Screenshot_VSCode-extension.png -------------------------------------------------------------------------------- /resources/images/PdfColorstockWhatsitNode.data.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/PdfColorstockWhatsitNode.data.png -------------------------------------------------------------------------------- /resources/images/Screenshot_Lua-Addon-Manager.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Josef-Friedrich/LuaTeX_Lua-API/HEAD/resources/images/Screenshot_Lua-Addon-Manager.png -------------------------------------------------------------------------------- /stylua.toml: -------------------------------------------------------------------------------- 1 | syntax = "Lua53" 2 | column_width = 120 3 | line_endings = "Unix" 4 | indent_type = "Spaces" 5 | indent_width = 2 6 | quote_style = "AutoPreferDouble" 7 | call_parentheses = "Always" 8 | collapse_simple_statement = "Never" 9 | space_after_function_names = "Never" 10 | 11 | [sort_requires] 12 | enabled = true 13 | -------------------------------------------------------------------------------- /search.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | # --context=num 4 | # Print num lines of leading and trailing output context. 5 | grep \ 6 | --context=3 \ 7 | --group-separator=----------------------------------------- \ 8 | --recursive \ 9 | --line-number \ 10 | --colour \ 11 | "$*" \ 12 | /usr/local/src/luatex \ 13 | "$HOME/repos/tex/mailing_lists" \ 14 | /usr/local/texlive \ 15 | . 16 | -------------------------------------------------------------------------------- /resources/update-lls-addons.sh: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | 3 | LUA_HOME="${HOME}/repos/lua" 4 | ROOT="${LUA_HOME}/lls_addons" 5 | 6 | rm -rf "${ROOT}" 7 | 8 | git clone --recurse-submodules git@github.com:TeXLuaCATS/LLS-Addons.git "${ROOT}" 9 | 10 | cd "${ROOT}" 11 | 12 | # https://stackoverflow.com/a/7244456 13 | git remote add upstream git@github.com:LuaLS/LLS-Addons.git 14 | git fetch upstream 15 | git checkout main 16 | git rebase upstream/main 17 | git push -u origin main 18 | 19 | UPDATE_BRANCH="update_$(date +%F)" 20 | 21 | git push -d origin update_2025-08-03 22 | 23 | git branch "$UPDATE_BRANCH" 24 | git checkout "$UPDATE_BRANCH" 25 | 26 | ADDONS="\ 27 | lmathx 28 | lpeg 29 | luasocket 30 | luazip 31 | lzlib 32 | md5 33 | slnunicode 34 | tex-lualatex 35 | tex-lualibs 36 | tex-luametatex 37 | tex-luatex\ 38 | " 39 | 40 | _update() { 41 | local ADDON_ROOT="${ROOT}/addons/$1/module" 42 | echo " 43 | ${ADDON_ROOT}" 44 | cd "${ADDON_ROOT}" 45 | git checkout main 46 | git pull 47 | stylua "${ADDON_ROOT}/library" 48 | } 49 | 50 | for ADDON in $ADDONS; do 51 | _update $ADDON 52 | done 53 | 54 | cd "${ROOT}" 55 | 56 | git add -Av 57 | git commit -m "Update TeX related submodules to the latest version" 58 | 59 | git push -u origin "$UPDATE_BRANCH" 60 | -------------------------------------------------------------------------------- /docs/Lua-language-servers.md: -------------------------------------------------------------------------------- 1 | ### Overview of the existing Lua language server 2 | 3 | #### lua-language-server 4 | 5 | The most popular language server, simply named 6 | [lua-language-server](https://github.com/LuaLS/lua-language-server), was 7 | created by a Chinese with the nickname 8 | [*sumneko*](https://github.com/sumneko). In addition to the nickname, 9 | *sumnekos* Github profile also shows 最萌小汐 in Chinese characters, 10 | which means “The cutest Xiaoxi”[^google-translate] or “Xiao Shi, the 11 | most adorable child in the world”[^deepl]. The [first 12 | commit](https://github.com/LuaLS/lua-language-server/commit/3546129c29fbfd7211099a3fbee03a763915ab58) 13 | in the Git repository was made on 7 September 2018. The 14 | *lua-language-server* is written in Lua. In August 2025, the repository 15 | on Gibhub has around 3,800 stars. 16 | 17 | [^google-translate]: https://translate.google.de/?sl=zh-CN&tl=en&text=%E6%9C%80%E8%90%8C%E5%B0%8F%E6%B1%90%20&op=translate 18 | [^deepl]: https://www.deepl.com/en/translator#zh/en-gb/%E6%9C%80%E8%90%8C%E5%B0%8F%E6%B1%90 19 | 20 | ### EmmyLua Analyzer Rust 21 | 22 | A promising language server that is not written in Lua but in Rust is 23 | the [EmmyLua Analyzer 24 | Rust](https://github.com/EmmyLuaLs/emmylua-analyzer-rust). This server 25 | was written by [CppCXY](https://github.com/CppCXY), the developer with 26 | the most commits after sumneko. The new server is advertised in 27 | [several](https://github.com/LuaLS/lua-language-server/issues/2910) 28 | [issues](https://github.com/LuaLS/lua-language-server/issues/3017) in 29 | the sumnekos *lua-language-server* Github repository. 30 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.formatting.provider": "black", 3 | // https://github.com/sumneko/lua-language-server/wiki/Libraries 4 | "Lua.workspace.library": [ 5 | "./TeXLuaCATS/LuaTeX/library", 6 | "${addons}/busted/module/library", 7 | "${3rd}/luassert/library" 8 | ], 9 | "[lua]": { 10 | "editor.defaultFormatter": "JohnnyMorganz.stylua", 11 | "editor.rulers": [80] 12 | }, 13 | "Lua.diagnostics.disable": [ 14 | "duplicate-set-field", 15 | "param-type-mismatch" 16 | ], 17 | "files.exclude": { 18 | "**/_minted*/": true, 19 | "**/*.aux": true, 20 | "**/*.fdb_latexmk": true, 21 | "**/*.fls": true, 22 | "**/*.glo": true, 23 | "**/*.gls": true, 24 | "**/*.hd": true, 25 | "**/*.idx": true, 26 | "**/*.ilg": true, 27 | "**/*.ind": true, 28 | "**/*.log": true, 29 | "**/*.out": true, 30 | "**/*.synctex.gz": true, 31 | "**/*.synctex": true, 32 | "**/*.synctex*": true, 33 | "**/*.tar.gz": false, 34 | "**/*.toc": true 35 | }, 36 | // "latex-workshop.latex.recipes": [ 37 | // { 38 | // "name": "luatex", 39 | // "tools": ["luatex"] 40 | // } 41 | // ], 42 | // "latex-workshop.latex.tools": [ 43 | // { 44 | // "name": "luatex", 45 | // "command": "luatex", 46 | // "args": [ 47 | // "--synctex=1", 48 | // "--interaction=nonstopmode", 49 | // "--file-line-error", 50 | // "%DOC%" 51 | // ], 52 | // "env": {} 53 | // } 54 | // ], 55 | "Lua.workspace.checkThirdParty": false, 56 | "Lua.format.defaultConfig": { 57 | "indent_style": "space", 58 | "indent_size": "2" 59 | }, 60 | "Lua.format.enable": true 61 | } 62 | -------------------------------------------------------------------------------- /docs/Lua-language-servers.tex: -------------------------------------------------------------------------------- 1 | \documentclass{ltxdoc} 2 | \usepackage{standalone} 3 | 4 | \begin{document} 5 | \subsubsection{Overview of the existing Lua language server} 6 | 7 | \paragraph{lua-language-server} 8 | 9 | The most popular language server, simply named 10 | \href{https://github.com/LuaLS/lua-language-server}{lua-language-server 11 | }, was created by a Chinese with the nickname 12 | \href{https://github.com/sumneko}{\emph{sumneko}}. In addition to the 13 | nickname, \emph{sumnekos} Github profile also shows 最萌小汐 in Chinese 14 | characters, which means “The cutest 15 | Xiaoxi”\href{https://translate.google.de/?sl=zh-CN&tl=en&text=\%E6\%9C\%80 16 | \%E8\%90\%8C\%E5\%B0\%8F\%E6\%B1\%90\%20&op=translate}{google-translate} or 17 | “Xiao Shi, the most adorable child in the 18 | world”\href{https://www.deepl.com/en/translator#zh/en-gb/\%E6\%9C\%80\%E8\%9 19 | 0\%8C\%E5\%B0\%8F\%E6\%B1\%90}{deepl}. The 20 | \href{https://github.com/LuaLS/lua-language-server/commit/3546129c29fbf 21 | d7211099a3fbee03a763915ab58}{firstcommit} in the Git repository was 22 | made on 7 September 2018. The \emph{lua-language-server} is written in 23 | Lua. In August 2025, the repository on Gibhub has around 3,800 stars. 24 | 25 | \subsubsection{EmmyLua Analyzer Rust} 26 | 27 | A promising language server that is not written in Lua but in Rust is 28 | the \href{https://github.com/EmmyLuaLs/emmylua-analyzer-rust}{EmmyLua 29 | AnalyzerRust}. This server was written by 30 | \href{https://github.com/CppCXY}{CppCXY}, the developer with the most 31 | commits after sumneko. The new server is advertised in 32 | \href{https://github.com/LuaLS/lua-language-server/issues/2910}{several 33 | } 34 | \href{https://github.com/LuaLS/lua-language-server/issues/3017}{issues} 35 | in the sumnekos \emph{lua-language-server} Github repository. 36 | 37 | \end{document} 38 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | jobname = luatex-type-definitions 2 | texmf = $(HOME)/texmf 3 | texmftex = $(texmf)/tex/luatex 4 | installdir = $(texmftex)/$(jobname) 5 | 6 | .PHONY: all 7 | all: format 8 | 9 | .PHONY: format 10 | format: 11 | ./manage format 12 | 13 | .PHONY: convert 14 | convert: 15 | ./manage convert 16 | 17 | .PHONY: debug 18 | debug: 19 | luatex --luaonly debug.lua 20 | 21 | .PHONY: print_namespace 22 | print_namespace: 23 | luatex resources/print-namespace.tex 24 | 25 | .PHONY: dist 26 | dist: 27 | ./manage dist 28 | 29 | .PHONY: update_lls_addons 30 | update_lls_addons: 31 | resources/update-lls-addons.sh 32 | 33 | .PHONY: submodules 34 | submodules: 35 | ./manage submodules 36 | 37 | .PHONY: submodules_init 38 | submodules_init: 39 | git submodule update --init --recursive --remote 40 | cd manager; make install 41 | 42 | .PHONY: test 43 | test: 44 | ./manage test 45 | 46 | .PHONY: doc 47 | doc: 48 | lualatex --shell-escape $(jobname)-doc.tex 49 | makeindex -s gglo.ist -o $(jobname)-doc.gls $(jobname)-doc.glo 50 | makeindex -s gind.ist -o $(jobname)-doc.ind $(jobname)-doc.idx 51 | lualatex --shell-escape $(jobname)-doc.tex 52 | mkdir -p $(texmf)/doc 53 | cp $(jobname)-doc.pdf $(texmf)/doc/$(jobname).pdf 54 | 55 | .PHONY: ctan 56 | ctan: doc dist_rsync 57 | rm -rf $(jobname) 58 | rm -rf $(jobname).tar.gz 59 | mkdir $(jobname) 60 | ./manage merge luatex 61 | $(HOME)/.cargo/bin/stylua $(jobname) 62 | cp -f README.md $(jobname) 63 | cp -f $(jobname)-doc.tex $(jobname) 64 | cp -f $(jobname)-doc.pdf $(jobname) 65 | tar cvfz $(jobname).tar.gz $(jobname) 66 | # rm -rf $(jobname) 67 | 68 | .PHONY: clean 69 | clean: 70 | git clean -dfX 71 | 72 | .PHONY: download_manuals 73 | download_manuals: 74 | ./manage manuals 75 | 76 | .PHONY: update_manual 77 | update_manual: 78 | wget -O /usr/local/texlive/texmf-dist/doc/luatex/base/luatex.pdf https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/raw/master/manual/luatex.pdf 79 | wget -O /usr/local/texlive/texmf-dist/doc/context/documents/general/manuals/luametatex.pdf https://raw.githubusercontent.com/contextgarden/context/main/doc/context/documents/general/manuals/luametatex.pdf 80 | 81 | LUATEX = ./manage example --print-docstring --subproject luatex 82 | 83 | .PHONY: namespace_luametatex 84 | namespace_luametatex: 85 | $(LUATEX) luametatex/namespace.lua 86 | .PHONY: namespace_luametatex_luaonly 87 | namespace_luametatex_luaonly: 88 | luametatex --luaonly examples/luatex/namespace.lua 89 | 90 | .PHONY: namespace_luatex 91 | namespace_luatex: 92 | $(LUATEX) namespace.lua 93 | 94 | .PHONY: namespace_luatex_luaonly 95 | namespace_luatex_luaonly: 96 | luatex --luaonly examples/luatex/namespace_luaonly.lua 97 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "resources/LuaCATS/upstream/lmathx"] 2 | path = LuaCATS/upstream/lmathx 3 | url = git@github.com:LuaCATS/lmathx.git 4 | [submodule "resources/LuaCATS/upstream/lpeg"] 5 | path = LuaCATS/upstream/lpeg 6 | url = git@github.com:LuaCATS/lpeg.git 7 | [submodule "resources/LuaCATS/upstream/luaharfbuzz"] 8 | path = LuaCATS/upstream/luaharfbuzz 9 | url = git@github.com:LuaCATS/luaharfbuzz.git 10 | [submodule "resources/LuaCATS/upstream/luasocket"] 11 | path = LuaCATS/upstream/luasocket 12 | url = git@github.com:LuaCATS/luasocket.git 13 | [submodule "resources/LuaCATS/upstream/luazip"] 14 | path = LuaCATS/upstream/luazip 15 | url = git@github.com:LuaCATS/luazip.git 16 | [submodule "resources/LuaCATS/upstream/lzlib"] 17 | path = LuaCATS/upstream/lzlib 18 | url = git@github.com:LuaCATS/lzlib.git 19 | [submodule "resources/LuaCATS/upstream/md5"] 20 | path = LuaCATS/upstream/md5 21 | url = git@github.com:LuaCATS/md5.git 22 | [submodule "resources/LuaCATS/upstream/slnunicode"] 23 | path = LuaCATS/upstream/slnunicode 24 | url = git@github.com:LuaCATS/slnunicode.git 25 | [submodule "resources/LuaCATS/downstream/tex-lualatex"] 26 | path = LuaCATS/downstream/tex-lualatex 27 | url = git@github.com:LuaCATS/tex-lualatex.git 28 | [submodule "resources/LuaCATS/downstream/tex-luatex"] 29 | path = LuaCATS/downstream/tex-luatex 30 | url = git@github.com:LuaCATS/tex-luatex.git 31 | [submodule "resources/LuaCATS/downstream/tex-lualibs"] 32 | path = LuaCATS/downstream/tex-lualibs 33 | url = git@github.com:LuaCATS/tex-lualibs.git 34 | [submodule "resources/LuaCATS/downstream/tex-luametatex"] 35 | path = LuaCATS/downstream/tex-luametatex 36 | url = git@github.com:LuaCATS/tex-luametatex.git 37 | [submodule "resources/vscode_extension"] 38 | path = vscode_extension 39 | url = git@github.com:TeXLuaCATS/vscode_extension.git 40 | [submodule "doc-generators/rust"] 41 | path = doc-generators/rust 42 | url = git@github.com:TeXLuaCATS/emmylua-analyzer-rust.git 43 | [submodule "subrepos/Lua-TeX/LuaTeX"] 44 | path = TeXLuaCATS/LuaTeX 45 | url = git@github.com:TeXLuaCATS/LuaTeX.git 46 | [submodule "subrepos/TeXLuaCATS/Lualibs"] 47 | path = TeXLuaCATS/Lualibs 48 | url = git@github.com:TeXLuaCATS/Lualibs.git 49 | [submodule "TeXLuaCATS/LuaLaTeX"] 50 | path = TeXLuaCATS/LuaLaTeX 51 | url = git@github.com:TeXLuaCATS/LuaLaTeX.git 52 | [submodule "TeXLuaCATS/LuaOTFload"] 53 | path = TeXLuaCATS/LuaOTFload 54 | url = git@github.com:TeXLuaCATS/LuaOTFload.git 55 | [submodule "TeXLuaCATS/LuaMetaTeX"] 56 | path = TeXLuaCATS/LuaMetaTeX 57 | url = git@github.com:TeXLuaCATS/LuaMetaTeX.git 58 | [submodule "manager"] 59 | path = manager 60 | url = git@github.com:TeXLuaCATS/manager.git 61 | [submodule "doc-generator"] 62 | path = doc-generator 63 | url = git@github.com:TeXLuaCATS/doc-generator.git 64 | -------------------------------------------------------------------------------- /resources/webpages/md5.html.lua: -------------------------------------------------------------------------------- 1 | --- 2 | ---Cryptographic Library for Lua 5.0 3 | --- 4 | --- 5 | ---This library offers basic cryptographic facilities for Lua 5.0: 6 | ---a hash (digest) function, an a pair crypt/decrypt. 7 | ---(download) 8 | --- 9 | --- 10 | ---Lua API 11 | --- 12 | ---All functions are registered inside a table `md5`. 13 | --- 14 | --- 15 | --- 16 | ---* `md5.sum (message)` 17 | --- 18 | ---Computes the MD5 message-digest of the string `message`. 19 | ---This function takes as input a message of arbitrary length and content 20 | ---and returns as output a 128-bit "fingerprint" (or "message digest") 21 | ---of the input. 22 | ---The output is formated as a binary string with 16 characters. 23 | ---It is conjectured that it is computationally infeasible to produce 24 | ---two messages having the same message digest, or to produce any 25 | ---message having a given pre-specified target message digest. 26 | ---(see 27 | ---RFC 1321) 28 | --- 29 | --- 30 | ---* `md5.sumhexa (message)` 31 | --- 32 | ---Similar to `md5.sum`, 33 | ---but returns its value as a string of 32 hexadecimal digits. 34 | --- 35 | ---* `md5.crypt (message, key [,seed])` 36 | --- 37 | ---Encrypts a string, using MD5 in CFB (Cipher-feedback mode). 38 | ---`message` is an arbitrary binary string to be encrypted. 39 | ---`key` is an arbitrary binary string to be used as a key. 40 | ---`seed` is an arbitrary binary string to be used as a seed; 41 | ---Returns the cyphertext (as a binary string). 42 | --- 43 | --- 44 | ---If no seed is provided, 45 | ---the function uses the result of `os.time()` as a seed. 46 | ---It is recommended that you use different seeds for each message; 47 | ---the seed itself is not private, and should contain no private data, 48 | ---because it goes plain in the beginning of the encrypted message. 49 | --- 50 | --- 51 | ---The length of the cyphertext is the length of the message plus the 52 | ---length of the seed plus one. 53 | --- 54 | --- 55 | ---* `md5.decrypt (message, key)` 56 | --- 57 | ---Decrypts a string. 58 | ---The input `message` must be the result of a previous call 59 | ---to `crypt`. 60 | ---For any `msg`, `key`, 61 | ---and `seed`, we have that 62 | ---``` 63 | --- md5.decrypt(md5.crypt(msg, key, seed), key) == msg 64 | ---``` 65 | --- 66 | --- 67 | ---* `md5.exor (s1, s2)` 68 | --- 69 | ---Does a bit-a-bit exclusive or of strings `s1` and `s2`. 70 | ---Both strings must have the same length, 71 | ---which will be also the length of the resulting string. 72 | --- 73 | --- 74 | --- 75 | --- 76 | --- 77 | ---C API 78 | --- 79 | ---The following functions are declared in `md5.h` 80 | --- 81 | --- 82 | ---* `int luaopen_md5 (lua_State *L);` 83 | --- 84 | ---Opens the library: 85 | ---Registers the above Lua functions in the given state. 86 | --- 87 | --- 88 | ---* `void md5 (const char *message, long len, char *output);` 89 | --- 90 | ---Computes the MD5 message-digest of `message`. 91 | ---`len` is the length of `message`. 92 | ---`output` is a buffer that receives the result; 93 | ---it must have at least 16 bytes (128 bits). 94 | --- 95 | --- 96 | --- 97 | --- 98 | ---INSTALL 99 | --- 100 | ---The following instructions assume that your Lua installation has a dynamic 101 | ---linking facility (function `loadlib`): 102 | --- 103 | --- 104 | --- 105 | ---* Build a shared library (`.so`, `.dll`, etc.) 106 | ---with files `md5.c` and `md5lib.c`. 107 | ---(There is a `makefile` for Linux and similar systems.) 108 | --- 109 | ---* Put the shared library somewhere, 110 | ---and edit file `md5.lua` to point to it. 111 | --- 112 | ---* Put the file `md5.lua` in a directory of your 113 | ---`LUA_PATH`. 114 | --- 115 | --- 116 | --- 117 | --- 118 | ---$Id: md5.html,v 1.4 2003/04/28 16:40:42 roberto Exp $ 119 | --- 120 | --- 121 | --- 122 | --- 123 | --- -------------------------------------------------------------------------------- /resources/webpages/md5.html: -------------------------------------------------------------------------------- 1 | 2 |

Cryptographic Library for Lua 5.0

3 | 4 |

5 | This library offers basic cryptographic facilities for Lua 5.0: 6 | a hash (digest) function, an a pair crypt/decrypt. 7 | (download) 8 | 9 | 10 |

Lua API

11 | 12 | All functions are registered inside a table md5. 13 | 14 | 75 | 76 | 77 |

C API

78 | 79 | The following functions are declared in md5.h 80 | 97 | 98 |

INSTALL

99 | 100 | The following instructions assume that your Lua installation has a dynamic 101 | linking facility (function loadlib): 102 | 103 | 116 | 117 |


118 | $Id: md5.html,v 1.4 2003/04/28 16:40:42 roberto Exp $ 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /.vscode/snippets.code-snippets: -------------------------------------------------------------------------------- 1 | { 2 | "examples": { 3 | "prefix": [ 4 | "example" 5 | ], 6 | "body": [ 7 | "\n---", 8 | "---__Example:__", 9 | "---", 10 | "---```${1:lua}", 11 | "---$0", 12 | "---```", 13 | "---" 14 | ], 15 | "description": "An code example." 16 | }, 17 | "for-example": { 18 | "prefix": [ 19 | "fexample", 20 | "forexample" 21 | ], 22 | "body": [ 23 | ", for example `$0`." 24 | ], 25 | "description": "Inline code example" 26 | }, 27 | "references": { 28 | "prefix": [ 29 | "reference" 30 | ], 31 | "body": [ 32 | "", 33 | "---", 34 | "---__Reference:__", 35 | "---", 36 | "---* [$2]($1)", 37 | "---$0" 38 | ], 39 | "description": "Reference heading" 40 | }, 41 | "referenceLuaTeXManual": { 42 | "prefix": [ 43 | "manual" 44 | ], 45 | "body": [ 46 | "", 47 | "---* `LuaTeX` manual: ${1:chapter} “${2:title}” page ${3:page}", 48 | "---$0" 49 | ], 50 | "description": "* `LuaTeX` manual: " 51 | }, 52 | "referenceSourceLuaTeXManual": { 53 | "prefix": [ 54 | "source" 55 | ], 56 | "body": [ 57 | "", 58 | "---* Source file of the `LuaTeX` manual: [$2]($1)", 59 | "---$0" 60 | ], 61 | "description": "* Source file of the `LuaTeX` manual" 62 | }, 63 | "link": { 64 | "prefix": [ 65 | "link" 66 | ], 67 | "body": [ 68 | "", 69 | "---* [$2]($1)", 70 | "---$0" 71 | ], 72 | "description": "* item and markdown link" 73 | }, 74 | "referenceC": { 75 | "prefix": [ 76 | "c", 77 | "ccode" 78 | ], 79 | "body": [ 80 | "", 81 | "---", 82 | "---* Corresponding C source code: [$2]($1)", 83 | "---$0" 84 | ], 85 | "description": "* Corresponding C source code: " 86 | }, 87 | "referenceLua": { 88 | "prefix": [ 89 | "l", 90 | "lcode" 91 | ], 92 | "body": [ 93 | "", 94 | "---", 95 | "---* Corresponding Lua source code: [$2]($1)", 96 | "---$0" 97 | ], 98 | "description": "* Corresponding Lua source code: " 99 | }, 100 | "referenceCLines": { 101 | "prefix": [ 102 | "l", 103 | "ccode" 104 | ], 105 | "body": [ 106 | "", 107 | "---", 108 | "---* Corresponding C source code: [luafflib.c#L$1-L$2](https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/blob/f52b099f3e01d53dc03b315e1909245c3d5418d3/source/texk/web2c/luatexdir/luafontloader/src/luafflib.c#L$1-L$2)", 109 | "---$0" 110 | ], 111 | "description": "* Corresponding C source code: only line numbers" 112 | }, 113 | "referenceCpp": { 114 | "prefix": [ 115 | "p", 116 | "cpp" 117 | ], 118 | "body": [ 119 | "", 120 | "---", 121 | "---* cppreference.com: [$2]($1)", 122 | "---$0" 123 | ], 124 | "description": "* cppreference.com" 125 | }, 126 | "referenceHarfBuzz": { 127 | "prefix": [ 128 | "h", 129 | "harf" 130 | ], 131 | "body": [ 132 | "", 133 | "---", 134 | "---* HarfBuzz online documentation: [$2]($1)", 135 | "---$0" 136 | ], 137 | "description": "* HarfBuzz online documentation: " 138 | }, 139 | "referenceWikibooks": { 140 | "prefix": [ 141 | "wikibook" 142 | ], 143 | "body": [ 144 | "", 145 | "---* [Wikibook/TeX](https://en.wikibooks.org/wiki/TeX/$1)", 146 | "---$0" 147 | ], 148 | "description": "Link to Wikibooks / TeX" 149 | }, 150 | "referenceTeXbyTopic": { 151 | "prefix": [ 152 | "texbytopic" 153 | ], 154 | "body": [ 155 | "", 156 | "---* [TeX by Topic, page $1](http://mirrors.ctan.org/info/texbytopic/TeXbyTopic.pdf)", 157 | "---$0" 158 | ], 159 | "description": "Link to CTAN version of TeX by Topic" 160 | }, 161 | "return": { 162 | "prefix": [ 163 | "return" 164 | ], 165 | "body": [ 166 | "", 167 | "---", 168 | "---@return $0" 169 | ], 170 | "description": "@return" 171 | }, 172 | "param": { 173 | "prefix": [ 174 | "param" 175 | ], 176 | "body": [ 177 | "", 178 | "---", 179 | "---@param $0" 180 | ], 181 | "description": "@param" 182 | }, 183 | "see": { 184 | "prefix": [ 185 | "see" 186 | ], 187 | "body": [ 188 | "", 189 | "---", 190 | "---@see $0" 191 | ], 192 | "description": "@see" 193 | }, 194 | "alias": { 195 | "prefix": [ 196 | "alias" 197 | ], 198 | "body": [ 199 | "", 200 | "---", 201 | "---@alias $1 $2 $0" 202 | ], 203 | "description": "@alias" 204 | }, 205 | "type": { 206 | "prefix": [ 207 | "type" 208 | ], 209 | "body": [ 210 | "", 211 | "---", 212 | "---@type $1" 213 | ], 214 | "description": "@alias" 215 | }, 216 | "class": { 217 | "prefix": [ 218 | "class" 219 | ], 220 | "body": [ 221 | "", 222 | "---", 223 | "---@class $1 $0" 224 | ], 225 | "description": "@class" 226 | }, 227 | "as": { 228 | "prefix": [ 229 | "a", 230 | "as" 231 | ], 232 | "body": [ 233 | " --[[@as ]] $1 $0" 234 | ], 235 | "description": "@as" 236 | }, 237 | "direct": { 238 | "prefix": [ 239 | "direct" 240 | ], 241 | "body": [ 242 | "node.direct.$0 = node.$0" 243 | ], 244 | "description": "node.direct.xxx = node.xxx" 245 | }, 246 | "linebreak": { 247 | "prefix": [ 248 | "-" 249 | ], 250 | "body": [ 251 | "", 252 | "---", 253 | "---" 254 | ], 255 | "description": "---" 256 | }, 257 | "inspect": { 258 | "prefix": [ 259 | "i", 260 | "inspect" 261 | ], 262 | "body": [ 263 | "", 264 | "local inspect = require('inspect')", 265 | "print(inspect())", 266 | "local function printi(data) print(inspect(data)) end" 267 | ], 268 | "description": "---" 269 | }, 270 | "man": { 271 | "prefix": [ 272 | "m", 273 | "man" 274 | ], 275 | "body": [ 276 | "", 277 | "---* [man3/$1](https://man7.org/linux/man-pages/man3/$1.3.html)" 278 | ], 279 | "description": "man" 280 | }, 281 | "`code`": { 282 | "body": [ 283 | "`${TM_SELECTED_TEXT:text}`" 284 | ], 285 | "prefix": "code" 286 | } 287 | } 288 | -------------------------------------------------------------------------------- /resources/webpages/zip.html.lua: -------------------------------------------------------------------------------- 1 | --- 3 | --- 4 | --- 5 | --- LuaZip: Reading files inside zip files 6 | --- 7 | --- 8 | --- 9 | --- 10 | --- 11 | --- 12 | --- 13 | --- 14 | --- 15 | --- 16 | --- 17 | --- LuaZip 18 | --- Reading files inside zip files 19 | --- 20 | --- 21 | --- 22 | --- 23 | --- 24 | ---LuaZip 25 | --- 26 | --- * Home 27 | --- 28 | --- * Overview 29 | --- * Status 30 | --- * Download 31 | --- * History 32 | --- * Credits 33 | --- * Contact 34 | --- 35 | --- 36 | --- * Manual 37 | --- 38 | --- * Introduction 39 | --- * Building 40 | --- * Installation 41 | --- * Reference 42 | --- 43 | --- 44 | --- * Examples 45 | --- * Project 46 | --- 47 | --- * Bug Tracker 48 | --- * CVS 49 | --- 50 | --- 51 | --- * License 52 | --- 53 | --- 54 | --- 55 | --- 56 | --- 57 | --- 58 | ---Introduction 59 | --- 60 | ---LuaZip is a lightweight Luaextension library 61 | ---that can be used to read files stored inside zip files. It uses 62 | ---zziplibto do all the hard work. 63 | --- 64 | ---The API exposed to Lua is very simple and very similiar to the usual file handling 65 | ---functions provided by the 66 | ---I/O Lua standard library. 67 | ---In fact, the API is so similar that parts of this manual are extracted from the Lua manual, 68 | ---copyrighted by Tecgraf, PUC-Rio. 69 | --- 70 | ---Building 71 | --- 72 | --- 73 | ---LuaZip could be built to Lua 5.0 or to Lua 5.1. 74 | ---In both cases, the language library and headers files for the target version 75 | ---must be installed properly. 76 | --- 77 | --- 78 | --- 79 | ---LuaZip offers a Makefile and a separate configuration file, 80 | ---`config`, which should be edited to suit your installation 81 | ---before runnig `make`. 82 | ---The file has some definitions like paths to the external libraries, 83 | ---compiler options and the like. 84 | ---One important definition is the version of Lua language, 85 | ---which is not obtained from the installed software. 86 | --- 87 | --- 88 | ---LuaZip compilation depends on 89 | ---zziplib 0.13.49and 90 | ---zlib 1.2.3. 91 | --- 92 | --- 93 | ---Installation 94 | --- 95 | ---The LuaZip compiled binary should be copied to a directory in your 96 | ---C path. 97 | ---Lua 5.0 users should also install Compat-5.1. 98 | --- 99 | --- 100 | ---Reference 101 | --- 102 | --- 103 | --- zip.open (filename) 104 | --- This function opens a zip file and returns a new zip file handle. In case of 105 | --- error it returns nil and an error message. Unlike `io.open`, there is no 106 | --- `mode` parameter, as the only supported mode is "read". 107 | --- 108 | --- zip.openfile (filename [, extensions]]) 109 | --- This function opens a file and returns a file handle. In case of 110 | --- error it returns nil and an error message. Unlike `io.open`, there is no 111 | --- `mode` parameter, as the only supported mode is "read". 112 | --- This function implements a virtual file system based on optionally compressed files. 113 | --- Instead of simply looking for a file at a given path, this function goes recursively up 114 | --- through all path separators ("/") looking for zip files there. If it finds a zip file, 115 | --- this function use the remaining path to open the requested file. 116 | --- The optional parameter extensionsallows the use of file extensions other than .zip 117 | --- during the lookup. It can be a string corresponding to the extension or an indexed table 118 | --- with the lookup extensions sequence. 119 | --- 120 | --- zfile:close () 121 | --- This function closes a zfile opened by `zip.open` 122 | --- 123 | --- zfile:files () 124 | --- Returns an iterator function that returns a new table containing the 125 | --- following information each time it is called: 126 | --- 127 | --- * `filename`: the full path of a file 128 | --- * `compressed_size`: the compressed size of the file in bytes 129 | --- * `uncompressed_size`: the uncompressed size of the file in bytes 130 | --- 131 | --- 132 | --- 133 | --- zfile:open (filename) 134 | --- This function opens a file that is stored inside the zip file opened by `zip.open`. 135 | --- The filename may contain the full path of the file contained inside the zip. The 136 | --- directory separator must be '/'. 137 | --- Unlike `f:open`, there is no `mode` parameter, as the only 138 | --- supported mode is "read". 139 | --- 140 | --- file:read (format1, ...) 141 | --- Reads a `file` according to the given formats, which specify what to read. 142 | --- For each format, the function returns a string with the characters read, or nil if it cannot read 143 | --- data with the specified format. When called without formats, it uses a default format that reads 144 | --- the entire next line (see below). 145 | --- The available formats are: 146 | --- 147 | --- * `"*a"`: reads the whole file, starting at the current position. On end of file, it 148 | --- returns the empty string. 149 | --- * `"*l"`: reads the next line (skipping the end of line), returns nil on end of file. 150 | --- This is the default format. 151 | --- * `number`: reads a string with up to that number of characters, returning nil 152 | --- on end of file. 153 | --- 154 | --- 155 | --- Unlike the standard I/O read, the format `"*n"` is not supported. 156 | --- 157 | --- file:seek ([whence] [, offset]) 158 | --- Sets and gets the file position, measured from the beginning of the file, to the position given 159 | --- by `offset` plus a base specified by the string `whence`, as follows: 160 | --- 161 | --- * `set`: base is position 0 (beginning of the file); 162 | --- * `cur`: base is current position; 163 | --- * `end`: base is end of file; 164 | --- 165 | --- In case of success, function `seek` returns the final file position, measured in bytes 166 | --- from the beginning of the file. If this function fails, it returns nil, plus an error string. 167 | --- The default value for `whence` is `"cur"`, and for `offset` is 0. 168 | --- Therefore, the call `file:seek()` returns the current file position, without changing 169 | --- it; the call `file:seek("set")` sets the position to the beginning of the file (and returns 0); 170 | --- and the call `file:seek("end")` sets the position to the end of the file, and returns its 171 | --- size. 172 | --- 173 | --- file:close () 174 | --- This function closes a file opened by `zfile:open`. 175 | --- 176 | --- file:lines () 177 | --- Returns an iterator function that returns a new line from the file each time it is called. 178 | --- Therefore, the construction 179 | --- ```for line in file:lines() do ... end``` 180 | --- will iterate over all lines of the file. 181 | --- 182 | --- 183 | --- 184 | --- 185 | --- 186 | --- 187 | --- 188 | --- 189 | --- $Id: manual.html,v 1.12 2007-06-18 18:47:05 carregal Exp $ 190 | --- 191 | --- 192 | --- 193 | --- 194 | --- 195 | --- 196 | --- -------------------------------------------------------------------------------- /resources/webpages/zip.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | LuaZip: Reading files inside zip files 6 | 7 | 8 | 9 | 10 | 11 |

12 | 13 |
14 | 17 |
LuaZip
18 |
Reading files inside zip files
19 |
20 | 21 |
22 | 23 | 54 | 55 |
56 | 57 | 58 |

Introduction

59 | 60 |

LuaZip is a lightweight Lua extension library 61 | that can be used to read files stored inside zip files. It uses 62 | zziplib to do all the hard work.

63 | 64 |

The API exposed to Lua is very simple and very similiar to the usual file handling 65 | functions provided by the 66 | I/O Lua standard library. 67 | In fact, the API is so similar that parts of this manual are extracted from the Lua manual, 68 | copyrighted by Tecgraf, PUC-Rio.

69 | 70 |

Building

71 | 72 |

73 | LuaZip could be built to Lua 5.0 or to Lua 5.1. 74 | In both cases, the language library and headers files for the target version 75 | must be installed properly. 76 |

77 | 78 |

79 | LuaZip offers a Makefile and a separate configuration file, 80 | config, which should be edited to suit your installation 81 | before runnig make. 82 | The file has some definitions like paths to the external libraries, 83 | compiler options and the like. 84 | One important definition is the version of Lua language, 85 | which is not obtained from the installed software. 86 |

87 | 88 |

LuaZip compilation depends on 89 | zziplib 0.13.49 and 90 | zlib 1.2.3. 91 |

92 | 93 |

Installation

94 | 95 |

The LuaZip compiled binary should be copied to a directory in your 96 | C path. 97 | Lua 5.0 users should also install Compat-5.1.

98 | 99 | 100 |

Reference

101 | 102 |
103 |
zip.open (filename)
104 |
This function opens a zip file and returns a new zip file handle. In case of 105 | error it returns nil and an error message. Unlike io.open, there is no 106 | mode parameter, as the only supported mode is "read".
107 | 108 |
zip.openfile (filename [, extensions]])
109 |
This function opens a file and returns a file handle. In case of 110 | error it returns nil and an error message. Unlike io.open, there is no 111 | mode parameter, as the only supported mode is "read".
112 | This function implements a virtual file system based on optionally compressed files. 113 | Instead of simply looking for a file at a given path, this function goes recursively up 114 | through all path separators ("/") looking for zip files there. If it finds a zip file, 115 | this function use the remaining path to open the requested file.
116 | The optional parameter extensions allows the use of file extensions other than .zip 117 | during the lookup. It can be a string corresponding to the extension or an indexed table 118 | with the lookup extensions sequence.
119 | 120 |
zfile:close ()
121 |
This function closes a zfile opened by zip.open
122 | 123 |
zfile:files ()
124 |
Returns an iterator function that returns a new table containing the 125 | following information each time it is called: 126 |
    127 |
  • filename: the full path of a file
  • 128 |
  • compressed_size: the compressed size of the file in bytes
  • 129 |
  • uncompressed_size: the uncompressed size of the file in bytes
  • 130 |
131 |
132 | 133 |
zfile:open (filename)
134 |
This function opens a file that is stored inside the zip file opened by zip.open.
135 | The filename may contain the full path of the file contained inside the zip. The 136 | directory separator must be '/'.
137 | Unlike f:open, there is no mode parameter, as the only 138 | supported mode is "read".
139 | 140 |
file:read (format1, ...)
141 |
Reads a file according to the given formats, which specify what to read.
142 | For each format, the function returns a string with the characters read, or nil if it cannot read 143 | data with the specified format. When called without formats, it uses a default format that reads 144 | the entire next line (see below).
145 | The available formats are: 146 |
    147 |
  • "*a": reads the whole file, starting at the current position. On end of file, it 148 | returns the empty string.
  • 149 |
  • "*l": reads the next line (skipping the end of line), returns nil on end of file. 150 | This is the default format.
  • 151 |
  • number: reads a string with up to that number of characters, returning nil 152 | on end of file.
  • 153 |
154 |
155 | Unlike the standard I/O read, the format "*n" is not supported.
156 | 157 |
file:seek ([whence] [, offset])
158 |
Sets and gets the file position, measured from the beginning of the file, to the position given 159 | by offset plus a base specified by the string whence, as follows: 160 |
    161 |
  • set: base is position 0 (beginning of the file);
  • 162 |
  • cur: base is current position;
  • 163 |
  • end: base is end of file;
  • 164 |
165 | In case of success, function seek returns the final file position, measured in bytes 166 | from the beginning of the file. If this function fails, it returns nil, plus an error string. 167 | The default value for whence is "cur", and for offset is 0. 168 | Therefore, the call file:seek() returns the current file position, without changing 169 | it; the call file:seek("set") sets the position to the beginning of the file (and returns 0); 170 | and the call file:seek("end") sets the position to the end of the file, and returns its 171 | size.
172 | 173 |
file:close ()
174 |
This function closes a file opened by zfile:open.
175 | 176 |
file:lines ()
177 |
Returns an iterator function that returns a new line from the file each time it is called. 178 | Therefore, the construction
179 |
for line in file:lines() do ... end
180 | will iterate over all lines of the file.
181 |
182 | 183 |
184 | 185 |
186 | 187 |
188 |

Valid XHTML 1.0!

189 |

$Id: manual.html,v 1.12 2007-06-18 18:47:05 carregal Exp $

190 |
191 | 192 |
193 | 194 | 195 | 196 | -------------------------------------------------------------------------------- /resources/webpages/socket.html.lua: -------------------------------------------------------------------------------- 1 | --- 3 | --- 4 | --- 5 | --- 6 | --- 7 | --- 8 | ---LuaSocket: The socket namespace 9 | --- 10 | --- 11 | --- 12 | --- 13 | --- 14 | --- 15 | --- 16 | --- 17 | --- 18 | --- 19 | --- 20 | --- 21 | --- 22 | --- 23 | ---Network support for the Lua language 24 | --- 25 | --- 26 | --- 27 | ---home· 28 | ---download· 29 | ---installation· 30 | ---introduction· 31 | ---reference 32 | --- 33 | --- 34 | --- 35 | --- 36 | --- 37 | --- 38 | --- 39 | ---The socket namespace 40 | --- 41 | --- 42 | ---The `socket` namespace contains the core functionality of LuaSocket. 43 | --- 44 | --- 45 | --- 46 | ---To obtain the `socket` namespace, run: 47 | --- 48 | --- 49 | ---``` 50 | ----- loads the socket module 51 | ---local socket = require("socket") 52 | ---``` 53 | --- 54 | --- 55 | --- 56 | --- 57 | ---socket.headers.canonic 58 | --- 59 | ---The `socket.headers.canonic` table 60 | ---is used by the HTTP and SMTP modules to translate from 61 | ---lowercase field names back into their canonic 62 | ---capitalization. When a lowercase field name exists as a key 63 | ---in this table, the associated value is substituted in 64 | ---whenever the field name is sent out. 65 | --- 66 | --- 67 | --- 68 | ---You can obtain the `headers` namespace if case run-time 69 | ---modifications are required by running: 70 | --- 71 | --- 72 | ---``` 73 | ----- loads the headers module 74 | ---local headers = require("headers") 75 | ---``` 76 | --- 77 | --- 78 | --- 79 | --- 80 | --- 81 | ---socket.bind(address, port [, backlog]) 82 | --- 83 | --- 84 | --- 85 | ---This function is a shortcut that creates and returns a TCP server object 86 | ---bound to a local `address` and `port`, ready to 87 | ---accept client connections. Optionally, 88 | ---user can also specify the `backlog` argument to the 89 | ---`listen`method (defaults to 32). 90 | --- 91 | --- 92 | --- 93 | ---Note: The server object returned will have the option "`reuseaddr`" 94 | ---set to `true`. 95 | --- 96 | --- 97 | --- 98 | --- 99 | --- 100 | ---socket.connect[46](address, port [, locaddr] [, locport] [, family]) 101 | --- 102 | --- 103 | --- 104 | ---This function is a shortcut that creates and returns a TCP client object 105 | ---connected to a remote `address` at a given `port`. Optionally, 106 | ---the user can also specify the local address and port to bind 107 | ---(`locaddr` and `locport`), or restrict the socket family 108 | ---to "`inet`" or "`inet6`". 109 | ---Without specifying `family` to `connect`, whether a tcp or tcp6 110 | ---connection is created depends on your system configuration. Two variations 111 | ---of connect are defined as simple helper functions that restrict the 112 | ---`family`, `socket.connect4` and `socket.connect6`. 113 | --- 114 | --- 115 | --- 116 | --- 117 | --- 118 | ---socket._DEBUG 119 | --- 120 | --- 121 | --- 122 | ---This constant is set to `true` if the library was compiled 123 | ---with debug support. 124 | --- 125 | --- 126 | --- 127 | --- 128 | --- 129 | ---socket._DATAGRAMSIZE 130 | --- 131 | --- 132 | --- 133 | ---Default datagram size used by calls to 134 | ---`receive`and 135 | ---`receivefrom`. 136 | ---(Unless changed in compile time, the value is 8192.) 137 | --- 138 | --- 139 | --- 140 | --- 141 | --- 142 | ---socket.gettime() 143 | --- 144 | --- 145 | --- 146 | ---Returns the UNIX time in seconds. You should subtract the values returned by this function 147 | ---to get meaningful values. 148 | --- 149 | --- 150 | ---``` 151 | ---t = socket.gettime() 152 | ----- do stuff 153 | ---print(socket.gettime() - t .. " seconds elapsed") 154 | ---``` 155 | --- 156 | --- 157 | --- 158 | --- 159 | ---socket.newtry(finalizer) 160 | --- 161 | --- 162 | --- 163 | ---Creates and returns a clean 164 | ---`try` 165 | ---function that allows for cleanup before the exception 166 | ---is raised. 167 | --- 168 | --- 169 | --- 170 | ---`Finalizer` is a function that will be called before 171 | ---`try` throws the exception. 172 | --- 173 | --- 174 | --- 175 | ---The function returns your customized `try` function. 176 | --- 177 | --- 178 | --- 179 | ---Note: This idea saved a lotof work with the 180 | ---implementation of protocols in LuaSocket: 181 | --- 182 | --- 183 | ---``` 184 | ---foo = socket.protect(function() 185 | --- -- connect somewhere 186 | --- local c = socket.try(socket.connect("somewhere", 42)) 187 | --- -- create a try function that closes 'c' on error 188 | --- local try = socket.newtry(function() c:close() end) 189 | --- -- do everything reassured c will be closed 190 | --- try(c:send("hello there?\r\n")) 191 | --- local answer = try(c:receive()) 192 | --- ... 193 | --- try(c:send("good bye\r\n")) 194 | --- c:close() 195 | ---end) 196 | ---``` 197 | --- 198 | --- 199 | --- 200 | --- 201 | --- 202 | ---socket.protect(func) 203 | --- 204 | --- 205 | --- 206 | ---Converts a function that throws exceptions into a safe function. This 207 | ---function only catches exceptions thrown by the `try` 208 | ---and `newtry`functions. It does not catch normal 209 | ---Lua errors. 210 | --- 211 | --- 212 | --- 213 | ---`Func` is a function that calls 214 | ---`try`(or `assert`, or `error`) 215 | ---to throw exceptions. 216 | --- 217 | --- 218 | --- 219 | ---Returns an equivalent function that instead of throwing exceptions in case of 220 | ---a failed `try`call, returns `nil` 221 | ---followed by an error message. 222 | --- 223 | --- 224 | --- 225 | --- 226 | --- 227 | ---socket.select(recvt, sendt [, timeout]) 228 | --- 229 | --- 230 | --- 231 | ---Waits for a number of sockets to change status. 232 | --- 233 | --- 234 | --- 235 | ---`Recvt` is an array with the sockets to test for characters 236 | ---available for reading. Sockets in the `sendt` array are watched to 237 | ---see if it is OK to immediately write on them. `Timeout` is the 238 | ---maximum amount of time (in seconds) to wait for a change in status. A 239 | ---`nil`, negative or omitted `timeout` value allows the 240 | ---function to block indefinitely. `Recvt` and `sendt` can also 241 | ---be empty tables or `nil`. Non-socket values (or values with 242 | ---non-numeric indices) in the arrays will be silently ignored. 243 | --- 244 | --- 245 | ---The function returns a list with the sockets ready for 246 | ---reading, a list with the sockets ready for writing and an error message. 247 | ---The error message is "`timeout`" if a timeout 248 | ---condition was met, "`select failed`" if the call 249 | ---to `select` failed, and 250 | ---`nil` otherwise. The returned tables are 251 | ---doubly keyed both by integers and also by the sockets 252 | ---themselves, to simplify the test if a specific socket has 253 | ---changed status. 254 | --- 255 | --- 256 | --- 257 | ---Note:`select` can monitor a limited number 258 | ---of sockets, as defined by the constant 259 | ---`socket._SETSIZE`. This 260 | ---number may be as high as 1024 or as low as 64 by default, 261 | ---depending on the system. It is usually possible to change this 262 | ---at compile time. Invoking `select` with a larger 263 | ---number of sockets will raise an error. 264 | --- 265 | --- 266 | --- 267 | ---Important note: a known bug in WinSock causes `select` to fail 268 | ---on non-blocking TCP sockets. The function may return a socket as 269 | ---writable even though the socket is notready for sending. 270 | --- 271 | --- 272 | --- 273 | ---Another important note: calling select with a server socket in the receive parameter before a call to accept does notguarantee 274 | ---`accept`will return immediately. 275 | ---Use the `settimeout` 276 | ---method or `accept` might block forever. 277 | --- 278 | --- 279 | --- 280 | ---Yet another note: If you close a socket and pass 281 | ---it to `select`, it will be ignored. 282 | --- 283 | --- 284 | --- 285 | ---Using select with non-socket objects: Any object that implements `getfd` and `dirty` can be used with `select`, allowing objects from other libraries to be used within a `socket.select` driven loop. 286 | --- 287 | --- 288 | --- 289 | --- 290 | --- 291 | ---socket._SETSIZE 292 | --- 293 | --- 294 | --- 295 | ---The maximum number of sockets that the `select`function can handle. 297 | --- 298 | --- 299 | --- 300 | --- 301 | --- 302 | --- 303 | ---socket.sink(mode, socket) 304 | --- 305 | --- 306 | --- 307 | ---Creates an 308 | ---LTN12 309 | ---sink from a stream socket object. 310 | --- 311 | --- 312 | --- 313 | ---`Mode` defines the behavior of the sink. The following 314 | ---options are available: 315 | --- 316 | --- 317 | ---* `"http-chunked"`: sends data through socket after applying the 318 | ---chunked transfer coding, closing the socket when done; 319 | ---* `"close-when-done"`: sends all received data through the 320 | ---socket, closing the socket when done; 321 | ---* `"keep-open"`: sends all received data through the 322 | ---socket, leaving it open when done. 323 | --- 324 | --- 325 | ---`Socket` is the stream socket object used to send the data. 326 | --- 327 | --- 328 | --- 329 | ---The function returns a sink with the appropriate behavior. 330 | --- 331 | --- 332 | --- 333 | --- 334 | --- 335 | ---socket.skip(d [, ret1, ret2... retN]) 336 | --- 337 | --- 338 | --- 339 | ---Drops a number of arguments and returns the remaining. 340 | --- 341 | --- 342 | --- 343 | ---`D` is the number of arguments to drop. `Ret1` to 344 | ---`retN` are the arguments. 345 | --- 346 | --- 347 | --- 348 | ---The function returns `retd+1` to `retN`. 349 | --- 350 | --- 351 | --- 352 | ---Note: This function is useful to avoid creation of dummy variables: 353 | --- 354 | --- 355 | ---``` 356 | ----- get the status code and separator from SMTP server reply 357 | ---local code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)")) 358 | ---``` 359 | --- 360 | --- 361 | --- 362 | --- 363 | ---socket.sleep(time) 364 | --- 365 | --- 366 | --- 367 | ---Freezes the program execution during a given amount of time. 368 | --- 369 | --- 370 | --- 371 | ---`Time` is the number of seconds to sleep for. If 372 | ---`time` is negative, the function returns immediately. 373 | --- 374 | --- 375 | --- 376 | --- 377 | --- 378 | ---socket.source(mode, socket [, length]) 379 | --- 380 | --- 381 | --- 382 | ---Creates an 383 | ---LTN12 384 | ---source from a stream socket object. 385 | --- 386 | --- 387 | --- 388 | ---`Mode` defines the behavior of the source. The following 389 | ---options are available: 390 | --- 391 | --- 392 | ---* `"http-chunked"`: receives data from socket and removes the 393 | ---chunked transfer codingbefore returning the data; 394 | ---* `"by-length"`: receives a fixed number of bytes from the 395 | ---socket. This mode requires the extra argument `length`; 396 | ---* `"until-closed"`: receives data from a socket until the other 397 | ---side closes the connection. 398 | --- 399 | --- 400 | ---`Socket` is the stream socket object used to receive the data. 401 | --- 402 | --- 403 | --- 404 | ---The function returns a source with the appropriate behavior. 405 | --- 406 | --- 407 | --- 408 | --- 409 | --- 410 | ---socket._SOCKETINVALID 411 | --- 412 | --- 413 | --- 414 | ---The OS value for an invalid socket. This can be used with 415 | ---`tcp:getfd`and `tcp:setfd`methods. 416 | --- 417 | --- 418 | --- 419 | --- 420 | --- 421 | ---socket.try(ret1[, ret2... retN]) 422 | --- 423 | --- 424 | --- 425 | ---Throws an exception in case `ret1` is falsy, using 426 | ---`ret2` as the error message. The exception is supposed to be caught 427 | ---by a `protect`ed function only. 428 | --- 429 | --- 430 | --- 431 | ---`Ret1` to `retN` can be arbitrary 432 | ---arguments, but are usually the return values of a function call 433 | ---nested with `try`. 434 | --- 435 | --- 436 | --- 437 | ---The function returns `ret`1to `ret`Nif 438 | ---`ret`1is not `nil` or `false`. 439 | ---Otherwise, it calls `error` passing `ret`2wrapped 440 | ---in a table with metatable used by `protect`to 441 | ---distinguish exceptions from runtime errors. 442 | --- 443 | --- 444 | ---``` 445 | ----- connects or throws an exception with the appropriate error message 446 | ---c = socket.try(socket.connect("localhost", 80)) 447 | ---``` 448 | --- 449 | --- 450 | --- 451 | --- 452 | ---socket._VERSION 453 | --- 454 | --- 455 | --- 456 | ---This constant has a string describing the current LuaSocket version. 457 | --- 458 | --- 459 | --- 460 | --- 461 | --- 462 | --- 463 | --- 464 | --- 465 | ---home· 466 | ---download· 467 | ---installation· 468 | ---introduction· 469 | ---reference 470 | --- 471 | --- 472 | --- 473 | ---Last modified by Diego Nehab on 474 | ---Thu Apr 20 00:25:54 EDT 2006 475 | --- 476 | --- 477 | --- 478 | --- 479 | --- 480 | --- 481 | --- 482 | --- -------------------------------------------------------------------------------- /resources/webpages/mime.html.lua: -------------------------------------------------------------------------------- 1 | --- 3 | --- 4 | --- 5 | --- 6 | --- 7 | --- 8 | ---LuaSocket: MIME module 9 | --- 10 | --- 11 | --- 12 | --- 13 | --- 14 | --- 15 | --- 16 | --- 17 | --- 18 | --- 19 | --- 20 | --- 21 | --- 22 | --- 23 | ---Network support for the Lua language 24 | --- 25 | --- 26 | --- 27 | ---home· 28 | ---download· 29 | ---installation· 30 | ---introduction· 31 | ---reference 32 | --- 33 | --- 34 | --- 35 | --- 36 | --- 37 | --- 38 | --- 39 | ---MIME 40 | --- 41 | --- 42 | ---The `mime` namespace offers filters that apply and remove common 43 | ---content transfer encodings, such as Base64 and Quoted-Printable. 44 | ---It also provides functions to break text into lines and change 45 | ---the end-of-line convention. 46 | ---MIME is described mainly in 47 | ---RFC 2045, 48 | ---2046, 49 | ---2047, 50 | ---2048, and 51 | ---2049. 52 | --- 53 | --- 54 | --- 55 | ---All functionality provided by the MIME module 56 | ---follows the ideas presented in 57 | --- 58 | ---LTN012, Filters sources and sinks. 59 | --- 60 | --- 61 | --- 62 | ---To obtain the `mime` namespace, run: 63 | --- 64 | --- 65 | ---``` 66 | ----- loads the MIME module and everything it requires 67 | ---local mime = require("mime") 68 | ---``` 69 | --- 70 | --- 71 | --- 72 | --- 73 | ---High-level filters 74 | --- 75 | --- 76 | --- 77 | --- 78 | --- 79 | ---mime.decode("base64") 80 | ---mime.decode("quoted-printable") 81 | --- 82 | --- 83 | --- 84 | ---Returns a filter that decodes data from a given transfer content 85 | ---encoding. 86 | --- 87 | --- 88 | --- 89 | --- 90 | --- 91 | ---mime.encode("base64") 92 | ---mime.encode("quoted-printable" [, mode]) 93 | --- 94 | --- 95 | --- 96 | ---Returns a filter that encodes data according to a given transfer content 97 | ---encoding. 98 | --- 99 | --- 100 | --- 101 | ---In the Quoted-Printable case, the user can specify whether the data is 102 | ---textual or binary, by passing the `mode` strings "`text`" or 103 | ---"`binary`". `Mode` defaults to "`text`". 104 | --- 105 | --- 106 | --- 107 | ---Although both transfer content encodings specify a limit for the line 108 | ---length, the encoding filters do notbreak text into lines (for 109 | ---added flexibility). 110 | ---Below is a filter that converts binary data to the Base64 transfer content 111 | ---encoding and breaks it into lines of the correct size. 112 | --- 113 | --- 114 | ---``` 115 | ---base64 = ltn12.filter.chain( 116 | --- mime.encode("base64"), 117 | --- mime.wrap("base64") 118 | ---) 119 | ---``` 120 | --- 121 | --- 122 | ---Note: Text data hasto be converted to canonic form 123 | ---beforebeing encoded. 124 | --- 125 | --- 126 | ---``` 127 | ---base64 = ltn12.filter.chain( 128 | --- mime.normalize(), 129 | --- mime.encode("base64"), 130 | --- mime.wrap("base64") 131 | ---) 132 | ---``` 133 | --- 134 | --- 135 | --- 136 | --- 137 | ---mime.normalize([marker]) 138 | --- 139 | --- 140 | --- 141 | ---Converts most common end-of-line markers to a specific given marker. 142 | --- 143 | --- 144 | --- 145 | ---`Marker` is the new marker. It defaults to CRLF, the canonic 146 | ---end-of-line marker defined by the MIME standard. 147 | --- 148 | --- 149 | --- 150 | ---The function returns a filter that performs the conversion. 151 | --- 152 | --- 153 | --- 154 | ---Note: There is no perfect solution to this problem. Different end-of-line 155 | ---markers are an evil that will probably plague developers forever. 156 | ---This function, however, will work perfectly for text created with any of 157 | ---the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF), 158 | ---or the DOS (CRLF) conventions. Even if the data has mixed end-of-line 159 | ---markers, the function will still work well, although it doesn't 160 | ---guarantee that the number of empty lines will be correct. 161 | --- 162 | --- 163 | --- 164 | --- 165 | --- 166 | ---mime.stuff() 167 | --- 168 | --- 169 | --- 170 | ---Creates and returns a filter that performs stuffing of SMTP messages. 171 | --- 172 | --- 173 | --- 174 | ---Note: The `smtp.send`function 175 | ---uses this filter automatically. You don't need to chain it with your 176 | ---source, or apply it to your message body. 177 | --- 178 | --- 179 | --- 180 | --- 181 | --- 182 | ---mime.wrap("text" [, length]) 183 | ---mime.wrap("base64") 184 | ---mime.wrap("quoted-printable") 185 | --- 186 | --- 187 | --- 188 | ---Returns a filter that breaks data into lines. 189 | --- 190 | --- 191 | --- 192 | ---The "`text`" line-wrap filter simply breaks text into lines by 193 | ---inserting CRLF end-of-line markers at appropriate positions. 194 | ---`Length` defaults 76. 195 | ---The "`base64`" line-wrap filter works just like the default 196 | ---"`text`" line-wrap filter with default length. 197 | ---The function can also wrap "`quoted-printable`" lines, taking care 198 | ---not to break lines in the middle of an escaped character. In that case, the 199 | ---line length is fixed at 76. 200 | --- 201 | --- 202 | --- 203 | ---For example, to create an encoding filter for the Quoted-Printable transfer content encoding of text data, do the following: 204 | --- 205 | --- 206 | ---``` 207 | ---qp = ltn12.filter.chain( 208 | --- mime.normalize(), 209 | --- mime.encode("quoted-printable"), 210 | --- mime.wrap("quoted-printable") 211 | ---) 212 | ---``` 213 | --- 214 | --- 215 | ---Note: To break into lines with a different end-of-line convention, apply 216 | ---a normalization filter after the line break filter. 217 | --- 218 | --- 219 | --- 220 | --- 221 | ---Low-level filters 222 | --- 223 | --- 224 | --- 225 | --- 226 | ---A, B = mime.b64(C [, D]) 227 | --- 228 | --- 229 | --- 230 | ---Low-level filter to perform Base64 encoding. 231 | --- 232 | --- 233 | --- 234 | ---`A` is the encoded version of the largest prefix of 235 | ---`C..D` 236 | ---that can be encoded unambiguously. `B` has the remaining bytes of 237 | ---`C..D`, beforeencoding. 238 | ---If `D` is `nil`, `A` is padded with 239 | ---the encoding of the remaining bytes of `C`. 240 | --- 241 | --- 242 | --- 243 | ---Note: The simplest use of this function is to encode a string into it's 244 | ---Base64 transfer content encoding. Notice the extra parenthesis around the 245 | ---call to `mime.b64`, to discard the second return value. 246 | --- 247 | --- 248 | ---``` 249 | ---print((mime.b64("diego:password"))) 250 | -----> ZGllZ286cGFzc3dvcmQ= 251 | ---``` 252 | --- 253 | --- 254 | --- 255 | ---A, n = mime.dot(m [, B]) 256 | --- 257 | --- 258 | --- 259 | ---Low-level filter to perform SMTP stuffing and enable transmission of 260 | ---messages containing the sequence "CRLF.CRLF". 261 | --- 262 | --- 263 | --- 264 | ---`A` is the stuffed version of `B`. '`n`' gives the 265 | ---number of characters from the sequence CRLF seen in the end of `B`. 266 | ---'`m`' should tell the same, but for the previous chunk. 267 | --- 268 | --- 269 | ---Note: The message body is defined to begin with 270 | ---an implicit CRLF. Therefore, to stuff a message correctly, the 271 | ---first `m` should have the value 2. 272 | --- 273 | --- 274 | ---``` 275 | ---print((string.gsub(mime.dot(2, ".\r\nStuffing the message.\r\n.\r\n."), "\r\n", "\\n"))) 276 | -----> ..\nStuffing the message.\n..\n.. 277 | ---``` 278 | --- 279 | --- 280 | ---Note: The `smtp.send`function 281 | ---uses this filter automatically. You don't need to 282 | ---apply it again. 283 | --- 284 | --- 285 | --- 286 | --- 287 | --- 288 | ---A, B = mime.eol(C [, D, marker]) 289 | --- 290 | --- 291 | --- 292 | ---Low-level filter to perform end-of-line marker translation. 293 | ---For each chunk, the function needs to know if the last character of the 294 | ---previous chunk could be part of an end-of-line marker or not. This is the 295 | ---context the function receives besides the chunk. An updated version of 296 | ---the context is returned after each new chunk. 297 | --- 298 | --- 299 | --- 300 | ---`A` is the translated version of `D`. `C` is the 301 | ---ASCII value of the last character of the previous chunk, if it was a 302 | ---candidate for line break, or 0 otherwise. 303 | ---`B` is the same as `C`, but for the current 304 | ---chunk. `Marker` gives the new end-of-line marker and defaults to CRLF. 305 | --- 306 | --- 307 | ---``` 308 | ----- translates the end-of-line marker to UNIX 309 | ---unix = mime.eol(0, dos, "\n") 310 | ---``` 311 | --- 312 | --- 313 | --- 314 | --- 315 | ---A, B = mime.qp(C [, D, marker]) 316 | --- 317 | --- 318 | --- 319 | ---Low-level filter to perform Quoted-Printable encoding. 320 | --- 321 | --- 322 | --- 323 | ---`A` is the encoded version of the largest prefix of 324 | ---`C..D` 325 | ---that can be encoded unambiguously. `B` has the remaining bytes of 326 | ---`C..D`, beforeencoding. 327 | ---If `D` is `nil`, `A` is padded with 328 | ---the encoding of the remaining bytes of `C`. 329 | ---Throughout encoding, occurrences of CRLF are replaced by the 330 | ---`marker`, which itself defaults to CRLF. 331 | --- 332 | --- 333 | --- 334 | ---Note: The simplest use of this function is to encode a string into it's 335 | ---Quoted-Printable transfer content encoding. 336 | ---Notice the extra parenthesis around the call to `mime.qp`, to discard the second return value. 337 | --- 338 | --- 339 | ---``` 340 | ---print((mime.qp("ma��"))) 341 | -----> ma=E7=E3= 342 | ---``` 343 | --- 344 | --- 345 | --- 346 | --- 347 | ---A, m = mime.qpwrp(n [, B, length]) 348 | --- 349 | --- 350 | --- 351 | ---Low-level filter to break Quoted-Printable text into lines. 352 | --- 353 | --- 354 | --- 355 | ---`A` is a copy of `B`, broken into lines of at most 356 | ---`length` bytes (defaults to 76). 357 | ---'`n`' should tell how many bytes are left for the first 358 | ---line of `B` and '`m`' returns the number of bytes 359 | ---left in the last line of `A`. 360 | --- 361 | --- 362 | --- 363 | ---Note: Besides breaking text into lines, this function makes sure the line 364 | ---breaks don't fall in the middle of an escaped character combination. Also, 365 | ---this function only breaks lines that are bigger than `length` bytes. 366 | --- 367 | --- 368 | --- 369 | --- 370 | --- 371 | ---A, B = mime.unb64(C [, D]) 372 | --- 373 | --- 374 | --- 375 | ---Low-level filter to perform Base64 decoding. 376 | --- 377 | --- 378 | --- 379 | ---`A` is the decoded version of the largest prefix of 380 | ---`C..D` 381 | ---that can be decoded unambiguously. `B` has the remaining bytes of 382 | ---`C..D`, beforedecoding. 383 | ---If `D` is `nil`, `A` is the empty string 384 | ---and `B` returns whatever couldn't be decoded. 385 | --- 386 | --- 387 | --- 388 | ---Note: The simplest use of this function is to decode a string from it's 389 | ---Base64 transfer content encoding. 390 | ---Notice the extra parenthesis around the call to `mime.unqp`, to discard the second return value. 391 | --- 392 | --- 393 | ---``` 394 | ---print((mime.unb64("ZGllZ286cGFzc3dvcmQ="))) 395 | -----> diego:password 396 | ---``` 397 | --- 398 | --- 399 | --- 400 | --- 401 | ---A, B = mime.unqp(C [, D]) 402 | --- 403 | --- 404 | --- 405 | ---Low-level filter to remove the Quoted-Printable transfer content encoding 406 | ---from data. 407 | --- 408 | --- 409 | --- 410 | ---`A` is the decoded version of the largest prefix of 411 | ---`C..D` 412 | ---that can be decoded unambiguously. `B` has the remaining bytes of 413 | ---`C..D`, beforedecoding. 414 | ---If `D` is `nil`, `A` is augmented with 415 | ---the encoding of the remaining bytes of `C`. 416 | --- 417 | --- 418 | --- 419 | ---Note: The simplest use of this function is to decode a string from it's 420 | ---Quoted-Printable transfer content encoding. 421 | ---Notice the extra parenthesis around the call to `mime.unqp`, to discard the second return value. 422 | --- 423 | --- 424 | ---``` 425 | ---print((mime.qp("ma=E7=E3="))) 426 | -----> ma�� 427 | ---``` 428 | --- 429 | --- 430 | --- 431 | --- 432 | ---A, m = mime.wrp(n [, B, length]) 433 | --- 434 | --- 435 | --- 436 | ---Low-level filter to break text into lines with CRLF marker. 437 | ---Text is assumed to be in the `normalize`form. 438 | --- 439 | --- 440 | --- 441 | ---`A` is a copy of `B`, broken into lines of at most 442 | ---`length` bytes (defaults to 76). 443 | ---'`n`' should tell how many bytes are left for the first 444 | ---line of `B` and '`m`' returns the number of bytes 445 | ---left in the last line of `A`. 446 | --- 447 | --- 448 | --- 449 | ---Note: This function only breaks lines that are bigger than 450 | ---`length` bytes. The resulting line length does not include the CRLF 451 | ---marker. 452 | --- 453 | --- 454 | --- 455 | --- 456 | --- 457 | --- 458 | --- 459 | --- 460 | --- 461 | ---home· 462 | ---download· 463 | ---installation· 464 | ---introduction· 465 | ---reference 466 | --- 467 | --- 468 | --- 469 | ---Last modified by Diego Nehab on 470 | ---Fri Mar 4 15:19:17 BRT 2016 471 | --- 472 | --- 473 | --- 474 | --- 475 | --- 476 | --- 477 | --- 478 | --- -------------------------------------------------------------------------------- /resources/webpages/mime.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | LuaSocket: MIME module 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 23 | 25 |
21 | LuaSocket 22 |
Network support for the Lua language 24 |
26 |

27 | home · 28 | download · 29 | installation · 30 | introduction · 31 | reference 32 |

33 |
34 |
35 |
36 | 37 | 38 | 39 |

MIME

40 | 41 |

42 | The mime namespace offers filters that apply and remove common 43 | content transfer encodings, such as Base64 and Quoted-Printable. 44 | It also provides functions to break text into lines and change 45 | the end-of-line convention. 46 | MIME is described mainly in 47 | RFC 2045, 48 | 2046, 49 | 2047, 50 | 2048, and 51 | 2049. 52 |

53 | 54 |

55 | All functionality provided by the MIME module 56 | follows the ideas presented in 57 | 58 | LTN012, Filters sources and sinks. 59 |

60 | 61 |

62 | To obtain the mime namespace, run: 63 |

64 | 65 |
 66 | -- loads the MIME module and everything it requires
 67 | local mime = require("mime")
 68 | 
69 | 70 | 71 | 72 | 73 |

High-level filters

74 | 75 | 76 | 77 | 78 |

79 | mime.decode("base64")
80 | mime.decode("quoted-printable") 81 |

82 | 83 |

84 | Returns a filter that decodes data from a given transfer content 85 | encoding. 86 |

87 | 88 | 89 | 90 |

91 | mime.encode("base64")
92 | mime.encode("quoted-printable" [, mode]) 93 |

94 | 95 |

96 | Returns a filter that encodes data according to a given transfer content 97 | encoding. 98 |

99 | 100 |

101 | In the Quoted-Printable case, the user can specify whether the data is 102 | textual or binary, by passing the mode strings "text" or 103 | "binary". Mode defaults to "text". 104 |

105 | 106 |

107 | Although both transfer content encodings specify a limit for the line 108 | length, the encoding filters do not break text into lines (for 109 | added flexibility). 110 | Below is a filter that converts binary data to the Base64 transfer content 111 | encoding and breaks it into lines of the correct size. 112 |

113 | 114 |
115 | base64 = ltn12.filter.chain(
116 |   mime.encode("base64"),
117 |   mime.wrap("base64")
118 | )
119 | 
120 | 121 |

122 | Note: Text data has to be converted to canonic form 123 | before being encoded. 124 |

125 | 126 |
127 | base64 = ltn12.filter.chain(
128 |   mime.normalize(),
129 |   mime.encode("base64"),
130 |   mime.wrap("base64")
131 | )
132 | 
133 | 134 | 135 | 136 |

137 | mime.normalize([marker]) 138 |

139 | 140 |

141 | Converts most common end-of-line markers to a specific given marker. 142 |

143 | 144 |

145 | Marker is the new marker. It defaults to CRLF, the canonic 146 | end-of-line marker defined by the MIME standard. 147 |

148 | 149 |

150 | The function returns a filter that performs the conversion. 151 |

152 | 153 |

154 | Note: There is no perfect solution to this problem. Different end-of-line 155 | markers are an evil that will probably plague developers forever. 156 | This function, however, will work perfectly for text created with any of 157 | the most common end-of-line markers, i.e. the Mac OS (CR), the Unix (LF), 158 | or the DOS (CRLF) conventions. Even if the data has mixed end-of-line 159 | markers, the function will still work well, although it doesn't 160 | guarantee that the number of empty lines will be correct. 161 |

162 | 163 | 164 | 165 |

166 | mime.stuff()
167 |

168 | 169 |

170 | Creates and returns a filter that performs stuffing of SMTP messages. 171 |

172 | 173 |

174 | Note: The smtp.send function 175 | uses this filter automatically. You don't need to chain it with your 176 | source, or apply it to your message body. 177 |

178 | 179 | 180 | 181 |

182 | mime.wrap("text" [, length])
183 | mime.wrap("base64")
184 | mime.wrap("quoted-printable") 185 |

186 | 187 |

188 | Returns a filter that breaks data into lines. 189 |

190 | 191 |

192 | The "text" line-wrap filter simply breaks text into lines by 193 | inserting CRLF end-of-line markers at appropriate positions. 194 | Length defaults 76. 195 | The "base64" line-wrap filter works just like the default 196 | "text" line-wrap filter with default length. 197 | The function can also wrap "quoted-printable" lines, taking care 198 | not to break lines in the middle of an escaped character. In that case, the 199 | line length is fixed at 76. 200 |

201 | 202 |

203 | For example, to create an encoding filter for the Quoted-Printable transfer content encoding of text data, do the following: 204 |

205 | 206 |
207 | qp = ltn12.filter.chain(
208 |   mime.normalize(),
209 |   mime.encode("quoted-printable"),
210 |   mime.wrap("quoted-printable")
211 | )
212 | 
213 | 214 |

215 | Note: To break into lines with a different end-of-line convention, apply 216 | a normalization filter after the line break filter. 217 |

218 | 219 | 220 | 221 |

Low-level filters

222 | 223 | 224 | 225 |

226 | A, B = mime.b64(C [, D]) 227 |

228 | 229 |

230 | Low-level filter to perform Base64 encoding. 231 |

232 | 233 |

234 | A is the encoded version of the largest prefix of 235 | C..D 236 | that can be encoded unambiguously. B has the remaining bytes of 237 | C..D, before encoding. 238 | If D is nil, A is padded with 239 | the encoding of the remaining bytes of C. 240 |

241 | 242 |

243 | Note: The simplest use of this function is to encode a string into it's 244 | Base64 transfer content encoding. Notice the extra parenthesis around the 245 | call to mime.b64, to discard the second return value. 246 |

247 | 248 |
249 | print((mime.b64("diego:password")))
250 | --> ZGllZ286cGFzc3dvcmQ=
251 | 
252 | 253 | 254 |

255 | A, n = mime.dot(m [, B]) 256 |

257 | 258 |

259 | Low-level filter to perform SMTP stuffing and enable transmission of 260 | messages containing the sequence "CRLF.CRLF". 261 |

262 | 263 |

264 | A is the stuffed version of B. 'n' gives the 265 | number of characters from the sequence CRLF seen in the end of B. 266 | 'm' should tell the same, but for the previous chunk. 267 |

268 | 269 |

Note: The message body is defined to begin with 270 | an implicit CRLF. Therefore, to stuff a message correctly, the 271 | first m should have the value 2. 272 |

273 | 274 |
275 | print((string.gsub(mime.dot(2, ".\r\nStuffing the message.\r\n.\r\n."), "\r\n", "\\n")))
276 | --> ..\nStuffing the message.\n..\n..
277 | 
278 | 279 |

280 | Note: The smtp.send function 281 | uses this filter automatically. You don't need to 282 | apply it again. 283 |

284 | 285 | 286 | 287 |

288 | A, B = mime.eol(C [, D, marker]) 289 |

290 | 291 |

292 | Low-level filter to perform end-of-line marker translation. 293 | For each chunk, the function needs to know if the last character of the 294 | previous chunk could be part of an end-of-line marker or not. This is the 295 | context the function receives besides the chunk. An updated version of 296 | the context is returned after each new chunk. 297 |

298 | 299 |

300 | A is the translated version of D. C is the 301 | ASCII value of the last character of the previous chunk, if it was a 302 | candidate for line break, or 0 otherwise. 303 | B is the same as C, but for the current 304 | chunk. Marker gives the new end-of-line marker and defaults to CRLF. 305 |

306 | 307 |
308 | -- translates the end-of-line marker to UNIX
309 | unix = mime.eol(0, dos, "\n")
310 | 
311 | 312 | 313 | 314 |

315 | A, B = mime.qp(C [, D, marker]) 316 |

317 | 318 |

319 | Low-level filter to perform Quoted-Printable encoding. 320 |

321 | 322 |

323 | A is the encoded version of the largest prefix of 324 | C..D 325 | that can be encoded unambiguously. B has the remaining bytes of 326 | C..D, before encoding. 327 | If D is nil, A is padded with 328 | the encoding of the remaining bytes of C. 329 | Throughout encoding, occurrences of CRLF are replaced by the 330 | marker, which itself defaults to CRLF. 331 |

332 | 333 |

334 | Note: The simplest use of this function is to encode a string into it's 335 | Quoted-Printable transfer content encoding. 336 | Notice the extra parenthesis around the call to mime.qp, to discard the second return value. 337 |

338 | 339 |
340 | print((mime.qp("ma��")))
341 | --> ma=E7=E3=
342 | 
343 | 344 | 345 | 346 |

347 | A, m = mime.qpwrp(n [, B, length]) 348 |

349 | 350 |

351 | Low-level filter to break Quoted-Printable text into lines. 352 |

353 | 354 |

355 | A is a copy of B, broken into lines of at most 356 | length bytes (defaults to 76). 357 | 'n' should tell how many bytes are left for the first 358 | line of B and 'm' returns the number of bytes 359 | left in the last line of A. 360 |

361 | 362 |

363 | Note: Besides breaking text into lines, this function makes sure the line 364 | breaks don't fall in the middle of an escaped character combination. Also, 365 | this function only breaks lines that are bigger than length bytes. 366 |

367 | 368 | 369 | 370 |

371 | A, B = mime.unb64(C [, D]) 372 |

373 | 374 |

375 | Low-level filter to perform Base64 decoding. 376 |

377 | 378 |

379 | A is the decoded version of the largest prefix of 380 | C..D 381 | that can be decoded unambiguously. B has the remaining bytes of 382 | C..D, before decoding. 383 | If D is nil, A is the empty string 384 | and B returns whatever couldn't be decoded. 385 |

386 | 387 |

388 | Note: The simplest use of this function is to decode a string from it's 389 | Base64 transfer content encoding. 390 | Notice the extra parenthesis around the call to mime.unqp, to discard the second return value. 391 |

392 | 393 |
394 | print((mime.unb64("ZGllZ286cGFzc3dvcmQ=")))
395 | --> diego:password
396 | 
397 | 398 | 399 | 400 |

401 | A, B = mime.unqp(C [, D]) 402 |

403 | 404 |

405 | Low-level filter to remove the Quoted-Printable transfer content encoding 406 | from data. 407 |

408 | 409 |

410 | A is the decoded version of the largest prefix of 411 | C..D 412 | that can be decoded unambiguously. B has the remaining bytes of 413 | C..D, before decoding. 414 | If D is nil, A is augmented with 415 | the encoding of the remaining bytes of C. 416 |

417 | 418 |

419 | Note: The simplest use of this function is to decode a string from it's 420 | Quoted-Printable transfer content encoding. 421 | Notice the extra parenthesis around the call to mime.unqp, to discard the second return value. 422 |

423 | 424 |
425 | print((mime.qp("ma=E7=E3=")))
426 | --> ma��
427 | 
428 | 429 | 430 | 431 |

432 | A, m = mime.wrp(n [, B, length]) 433 |

434 | 435 |

436 | Low-level filter to break text into lines with CRLF marker. 437 | Text is assumed to be in the normalize form. 438 |

439 | 440 |

441 | A is a copy of B, broken into lines of at most 442 | length bytes (defaults to 76). 443 | 'n' should tell how many bytes are left for the first 444 | line of B and 'm' returns the number of bytes 445 | left in the last line of A. 446 |

447 | 448 |

449 | Note: This function only breaks lines that are bigger than 450 | length bytes. The resulting line length does not include the CRLF 451 | marker. 452 |

453 | 454 | 455 | 456 | 457 | 475 | 476 | 477 | 478 | -------------------------------------------------------------------------------- /resources/webpages/socket.html: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | LuaSocket: The socket namespace 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |
19 | 20 | 23 | 25 |
21 | LuaSocket 22 |
Network support for the Lua language 24 |
26 |

27 | home · 28 | download · 29 | installation · 30 | introduction · 31 | reference 32 |

33 |
34 |
35 |
36 | 37 | 38 | 39 |

The socket namespace

40 | 41 |

42 | The socket namespace contains the core functionality of LuaSocket. 43 |

44 | 45 |

46 | To obtain the socket namespace, run: 47 |

48 | 49 |
 50 | -- loads the socket module
 51 | local socket = require("socket")
 52 | 
53 | 54 | 55 | 56 |

57 | socket.headers.canonic

58 | 59 |

The socket.headers.canonic table 60 | is used by the HTTP and SMTP modules to translate from 61 | lowercase field names back into their canonic 62 | capitalization. When a lowercase field name exists as a key 63 | in this table, the associated value is substituted in 64 | whenever the field name is sent out. 65 |

66 | 67 |

68 | You can obtain the headers namespace if case run-time 69 | modifications are required by running: 70 |

71 | 72 |
 73 | -- loads the headers module
 74 | local headers = require("headers")
 75 | 
76 | 77 | 78 | 79 | 80 |

81 | socket.bind(address, port [, backlog]) 82 |

83 | 84 |

85 | This function is a shortcut that creates and returns a TCP server object 86 | bound to a local address and port, ready to 87 | accept client connections. Optionally, 88 | user can also specify the backlog argument to the 89 | listen method (defaults to 32). 90 |

91 | 92 |

93 | Note: The server object returned will have the option "reuseaddr" 94 | set to true. 95 |

96 | 97 | 98 | 99 |

100 | socket.connect[46](address, port [, locaddr] [, locport] [, family]) 101 |

102 | 103 |

104 | This function is a shortcut that creates and returns a TCP client object 105 | connected to a remote address at a given port. Optionally, 106 | the user can also specify the local address and port to bind 107 | (locaddr and locport), or restrict the socket family 108 | to "inet" or "inet6". 109 | Without specifying family to connect, whether a tcp or tcp6 110 | connection is created depends on your system configuration. Two variations 111 | of connect are defined as simple helper functions that restrict the 112 | family, socket.connect4 and socket.connect6. 113 |

114 | 115 | 116 | 117 |

118 | socket._DEBUG 119 |

120 | 121 |

122 | This constant is set to true if the library was compiled 123 | with debug support. 124 |

125 | 126 | 127 | 128 |

129 | socket._DATAGRAMSIZE 130 |

131 | 132 |

133 | Default datagram size used by calls to 134 | receive and 135 | receivefrom. 136 | (Unless changed in compile time, the value is 8192.) 137 |

138 | 139 | 140 | 141 |

142 | socket.gettime() 143 |

144 | 145 |

146 | Returns the UNIX time in seconds. You should subtract the values returned by this function 147 | to get meaningful values. 148 |

149 | 150 |
151 | t = socket.gettime()
152 | -- do stuff
153 | print(socket.gettime() - t .. " seconds elapsed")
154 | 
155 | 156 | 157 | 158 |

159 | socket.newtry(finalizer) 160 |

161 | 162 |

163 | Creates and returns a clean 164 | try 165 | function that allows for cleanup before the exception 166 | is raised. 167 |

168 | 169 |

170 | Finalizer is a function that will be called before 171 | try throws the exception. 172 |

173 | 174 |

175 | The function returns your customized try function. 176 |

177 | 178 |

179 | Note: This idea saved a lot of work with the 180 | implementation of protocols in LuaSocket: 181 |

182 | 183 |
184 | foo = socket.protect(function()
185 |     -- connect somewhere
186 |     local c = socket.try(socket.connect("somewhere", 42))
187 |     -- create a try function that closes 'c' on error
188 |     local try = socket.newtry(function() c:close() end)
189 |     -- do everything reassured c will be closed
190 |     try(c:send("hello there?\r\n"))
191 |     local answer = try(c:receive())
192 |     ...
193 |     try(c:send("good bye\r\n"))
194 |     c:close()
195 | end)
196 | 
197 | 198 | 199 | 200 | 201 |

202 | socket.protect(func) 203 |

204 | 205 |

206 | Converts a function that throws exceptions into a safe function. This 207 | function only catches exceptions thrown by the try 208 | and newtry functions. It does not catch normal 209 | Lua errors. 210 |

211 | 212 |

213 | Func is a function that calls 214 | try (or assert, or error) 215 | to throw exceptions. 216 |

217 | 218 |

219 | Returns an equivalent function that instead of throwing exceptions in case of 220 | a failed try call, returns nil 221 | followed by an error message. 222 |

223 | 224 | 225 | 226 |

227 | socket.select(recvt, sendt [, timeout]) 228 |

229 | 230 |

231 | Waits for a number of sockets to change status. 232 |

233 | 234 |

235 | Recvt is an array with the sockets to test for characters 236 | available for reading. Sockets in the sendt array are watched to 237 | see if it is OK to immediately write on them. Timeout is the 238 | maximum amount of time (in seconds) to wait for a change in status. A 239 | nil, negative or omitted timeout value allows the 240 | function to block indefinitely. Recvt and sendt can also 241 | be empty tables or nil. Non-socket values (or values with 242 | non-numeric indices) in the arrays will be silently ignored. 243 |

244 | 245 |

The function returns a list with the sockets ready for 246 | reading, a list with the sockets ready for writing and an error message. 247 | The error message is "timeout" if a timeout 248 | condition was met, "select failed" if the call 249 | to select failed, and 250 | nil otherwise. The returned tables are 251 | doubly keyed both by integers and also by the sockets 252 | themselves, to simplify the test if a specific socket has 253 | changed status. 254 |

255 | 256 |

257 | Note: select can monitor a limited number 258 | of sockets, as defined by the constant 259 | socket._SETSIZE. This 260 | number may be as high as 1024 or as low as 64 by default, 261 | depending on the system. It is usually possible to change this 262 | at compile time. Invoking select with a larger 263 | number of sockets will raise an error. 264 |

265 | 266 |

267 | Important note: a known bug in WinSock causes select to fail 268 | on non-blocking TCP sockets. The function may return a socket as 269 | writable even though the socket is not ready for sending. 270 |

271 | 272 |

273 | Another important note: calling select with a server socket in the receive parameter before a call to accept does not guarantee 274 | accept will return immediately. 275 | Use the settimeout 276 | method or accept might block forever. 277 |

278 | 279 |

280 | Yet another note: If you close a socket and pass 281 | it to select, it will be ignored. 282 |

283 | 284 |

285 | Using select with non-socket objects: Any object that implements getfd and dirty can be used with select, allowing objects from other libraries to be used within a socket.select driven loop. 286 |

287 | 288 | 289 | 290 |

291 | socket._SETSIZE 292 |

293 | 294 |

295 | The maximum number of sockets that the select function can handle. 297 |

298 | 299 | 300 | 301 | 302 |

303 | socket.sink(mode, socket) 304 |

305 | 306 |

307 | Creates an 308 | LTN12 309 | sink from a stream socket object. 310 |

311 | 312 |

313 | Mode defines the behavior of the sink. The following 314 | options are available: 315 |

316 | 324 |

325 | Socket is the stream socket object used to send the data. 326 |

327 | 328 |

329 | The function returns a sink with the appropriate behavior. 330 |

331 | 332 | 333 | 334 |

335 | socket.skip(d [, ret1, ret2 ... retN]) 336 |

337 | 338 |

339 | Drops a number of arguments and returns the remaining. 340 |

341 | 342 |

343 | D is the number of arguments to drop. Ret1 to 344 | retN are the arguments. 345 |

346 | 347 |

348 | The function returns retd+1 to retN. 349 |

350 | 351 |

352 | Note: This function is useful to avoid creation of dummy variables: 353 |

354 | 355 |
356 | -- get the status code and separator from SMTP server reply
357 | local code, sep = socket.skip(2, string.find(line, "^(%d%d%d)(.?)"))
358 | 
359 | 360 | 361 | 362 |

363 | socket.sleep(time) 364 |

365 | 366 |

367 | Freezes the program execution during a given amount of time. 368 |

369 | 370 |

371 | Time is the number of seconds to sleep for. If 372 | time is negative, the function returns immediately. 373 |

374 | 375 | 376 | 377 |

378 | socket.source(mode, socket [, length]) 379 |

380 | 381 |

382 | Creates an 383 | LTN12 384 | source from a stream socket object. 385 |

386 | 387 |

388 | Mode defines the behavior of the source. The following 389 | options are available: 390 |

391 | 399 |

400 | Socket is the stream socket object used to receive the data. 401 |

402 | 403 |

404 | The function returns a source with the appropriate behavior. 405 |

406 | 407 | 408 | 409 |

410 | socket._SOCKETINVALID 411 |

412 | 413 |

414 | The OS value for an invalid socket. This can be used with 415 | tcp:getfd and tcp:setfd methods. 416 |

417 | 418 | 419 | 420 |

421 | socket.try(ret1 [, ret2 ... retN]) 422 |

423 | 424 |

425 | Throws an exception in case ret1 is falsy, using 426 | ret2 as the error message. The exception is supposed to be caught 427 | by a protected function only. 428 |

429 | 430 |

431 | Ret1 to retN can be arbitrary 432 | arguments, but are usually the return values of a function call 433 | nested with try. 434 |

435 | 436 |

437 | The function returns ret1 to retN if 438 | ret1 is not nil or false. 439 | Otherwise, it calls error passing ret2 wrapped 440 | in a table with metatable used by protect to 441 | distinguish exceptions from runtime errors. 442 |

443 | 444 |
445 | -- connects or throws an exception with the appropriate error message
446 | c = socket.try(socket.connect("localhost", 80))
447 | 
448 | 449 | 450 | 451 |

452 | socket._VERSION 453 |

454 | 455 |

456 | This constant has a string describing the current LuaSocket version. 457 |

458 | 459 | 460 | 461 | 479 | 480 | 481 | 482 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /utils.lua: -------------------------------------------------------------------------------- 1 | ---This file is intended as a library for the various example files. 2 | local inspect = (function() 3 | --- https://raw.githubusercontent.com/kikito/inspect.lua/refs/heads/master/inspect.lua 4 | local _tl_compat 5 | if (tonumber((_VERSION or ""):match("[%d.]*$")) or 0) < 5.3 then 6 | local p, m = pcall(require, "compat53.module") 7 | if p then 8 | _tl_compat = m 9 | end 10 | end 11 | local math = _tl_compat and _tl_compat.math or math 12 | local string = _tl_compat and _tl_compat.string or string 13 | local table = _tl_compat and _tl_compat.table or table 14 | local inspect = { Options = {} } 15 | 16 | inspect._VERSION = "inspect.lua 3.1.0" 17 | inspect._URL = "http://github.com/kikito/inspect.lua" 18 | inspect._DESCRIPTION = "human-readable representations of tables" 19 | inspect._LICENSE = [[ 20 | MIT LICENSE 21 | 22 | Copyright (c) 2022 Enrique García Cota 23 | 24 | Permission is hereby granted, free of charge, to any person obtaining a 25 | copy of this software and associated documentation files (the 26 | "Software"), to deal in the Software without restriction, including 27 | without limitation the rights to use, copy, modify, merge, publish, 28 | distribute, sublicense, and/or sell copies of the Software, and to 29 | permit persons to whom the Software is furnished to do so, subject to 30 | the following conditions: 31 | 32 | The above copyright notice and this permission notice shall be included 33 | in all copies or substantial portions of the Software. 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 36 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 37 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 38 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 39 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 40 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 41 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 42 | ]] 43 | inspect.KEY = setmetatable({}, { 44 | __tostring = function() 45 | return "inspect.KEY" 46 | end, 47 | }) 48 | inspect.METATABLE = setmetatable({}, { 49 | __tostring = function() 50 | return "inspect.METATABLE" 51 | end, 52 | }) 53 | 54 | local tostring = tostring 55 | local rep = string.rep 56 | local match = string.match 57 | local char = string.char 58 | local gsub = string.gsub 59 | local fmt = string.format 60 | 61 | local _rawget 62 | if rawget then 63 | _rawget = rawget 64 | else 65 | _rawget = function(t, k) 66 | return t[k] 67 | end 68 | end 69 | 70 | local function rawpairs(t) 71 | return next, t, nil 72 | end 73 | 74 | local function smartQuote(str) 75 | if match(str, '"') and not match(str, "'") then 76 | return "'" .. str .. "'" 77 | end 78 | return '"' .. gsub(str, '"', '\\"') .. '"' 79 | end 80 | 81 | local shortControlCharEscapes = { 82 | ["\a"] = "\\a", 83 | ["\b"] = "\\b", 84 | ["\f"] = "\\f", 85 | ["\n"] = "\\n", 86 | ["\r"] = "\\r", 87 | ["\t"] = "\\t", 88 | ["\v"] = "\\v", 89 | ["\127"] = "\\127", 90 | } 91 | local longControlCharEscapes = { ["\127"] = "\127" } 92 | for i = 0, 31 do 93 | local ch = char(i) 94 | if not shortControlCharEscapes[ch] then 95 | shortControlCharEscapes[ch] = "\\" .. i 96 | longControlCharEscapes[ch] = fmt("\\%03d", i) 97 | end 98 | end 99 | 100 | local function escape(str) 101 | return (gsub(gsub(gsub(str, "\\", "\\\\"), "(%c)%f[0-9]", longControlCharEscapes), "%c", shortControlCharEscapes)) 102 | end 103 | 104 | local luaKeywords = { 105 | ["and"] = true, 106 | ["break"] = true, 107 | ["do"] = true, 108 | ["else"] = true, 109 | ["elseif"] = true, 110 | ["end"] = true, 111 | ["false"] = true, 112 | ["for"] = true, 113 | ["function"] = true, 114 | ["goto"] = true, 115 | ["if"] = true, 116 | ["in"] = true, 117 | ["local"] = true, 118 | ["nil"] = true, 119 | ["not"] = true, 120 | ["or"] = true, 121 | ["repeat"] = true, 122 | ["return"] = true, 123 | ["then"] = true, 124 | ["true"] = true, 125 | ["until"] = true, 126 | ["while"] = true, 127 | } 128 | 129 | local function isIdentifier(str) 130 | return type(str) == "string" and not not str:match("^[_%a][_%a%d]*$") and not luaKeywords[str] 131 | end 132 | 133 | local flr = math.floor 134 | local function isSequenceKey(k, sequenceLength) 135 | return type(k) == "number" and flr(k) == k and 1 <= k and k <= sequenceLength 136 | end 137 | 138 | local defaultTypeOrders = { 139 | ["number"] = 1, 140 | ["boolean"] = 2, 141 | ["string"] = 3, 142 | ["table"] = 4, 143 | ["function"] = 5, 144 | ["userdata"] = 6, 145 | ["thread"] = 7, 146 | } 147 | 148 | local function sortKeys(a, b) 149 | local ta, tb = type(a), type(b) 150 | 151 | if ta == tb and (ta == "string" or ta == "number") then 152 | return a < b 153 | end 154 | 155 | local dta = defaultTypeOrders[ta] or 100 156 | local dtb = defaultTypeOrders[tb] or 100 157 | 158 | return dta == dtb and ta < tb or dta < dtb 159 | end 160 | 161 | local function getKeys(t) 162 | local seqLen = 1 163 | while _rawget(t, seqLen) ~= nil do 164 | seqLen = seqLen + 1 165 | end 166 | seqLen = seqLen - 1 167 | 168 | local keys, keysLen = {}, 0 169 | for k in rawpairs(t) do 170 | if not isSequenceKey(k, seqLen) then 171 | keysLen = keysLen + 1 172 | keys[keysLen] = k 173 | end 174 | end 175 | table.sort(keys, sortKeys) 176 | return keys, keysLen, seqLen 177 | end 178 | 179 | local function countCycles(x, cycles) 180 | if type(x) == "table" then 181 | if cycles[x] then 182 | cycles[x] = cycles[x] + 1 183 | else 184 | cycles[x] = 1 185 | for k, v in rawpairs(x) do 186 | countCycles(k, cycles) 187 | countCycles(v, cycles) 188 | end 189 | countCycles(getmetatable(x), cycles) 190 | end 191 | end 192 | end 193 | 194 | local function makePath(path, a, b) 195 | local newPath = {} 196 | local len = #path 197 | for i = 1, len do 198 | newPath[i] = path[i] 199 | end 200 | 201 | newPath[len + 1] = a 202 | newPath[len + 2] = b 203 | 204 | return newPath 205 | end 206 | 207 | local function processRecursive(process, item, path, visited) 208 | if item == nil then 209 | return nil 210 | end 211 | if visited[item] then 212 | return visited[item] 213 | end 214 | 215 | local processed = process(item, path) 216 | if type(processed) == "table" then 217 | local processedCopy = {} 218 | visited[item] = processedCopy 219 | local processedKey 220 | 221 | for k, v in rawpairs(processed) do 222 | processedKey = processRecursive(process, k, makePath(path, k, inspect.KEY), visited) 223 | if processedKey ~= nil then 224 | processedCopy[processedKey] = processRecursive(process, v, makePath(path, processedKey), visited) 225 | end 226 | end 227 | 228 | local mt = processRecursive(process, getmetatable(processed), makePath(path, inspect.METATABLE), visited) 229 | if type(mt) ~= "table" then 230 | mt = nil 231 | end 232 | setmetatable(processedCopy, mt) 233 | processed = processedCopy 234 | end 235 | return processed 236 | end 237 | 238 | local function puts(buf, str) 239 | buf.n = buf.n + 1 240 | buf[buf.n] = str 241 | end 242 | 243 | local Inspector = {} 244 | 245 | local Inspector_mt = { __index = Inspector } 246 | 247 | local function tabify(inspector) 248 | puts(inspector.buf, inspector.newline .. rep(inspector.indent, inspector.level)) 249 | end 250 | 251 | function Inspector:getId(v) 252 | local id = self.ids[v] 253 | local ids = self.ids 254 | if not id then 255 | local tv = type(v) 256 | id = (ids[tv] or 0) + 1 257 | ids[v], ids[tv] = id, id 258 | end 259 | return tostring(id) 260 | end 261 | 262 | function Inspector:putValue(v) 263 | local buf = self.buf 264 | local tv = type(v) 265 | if tv == "string" then 266 | puts(buf, smartQuote(escape(v))) 267 | elseif tv == "number" or tv == "boolean" or tv == "nil" or tv == "cdata" or tv == "ctype" then 268 | puts(buf, tostring(v)) 269 | elseif tv == "table" and not self.ids[v] then 270 | local t = v 271 | 272 | if t == inspect.KEY or t == inspect.METATABLE then 273 | puts(buf, tostring(t)) 274 | elseif self.level >= self.depth then 275 | puts(buf, "{...}") 276 | else 277 | if self.cycles[t] > 1 then 278 | puts(buf, fmt("<%d>", self:getId(t))) 279 | end 280 | 281 | local keys, keysLen, seqLen = getKeys(t) 282 | 283 | puts(buf, "{") 284 | self.level = self.level + 1 285 | 286 | for i = 1, seqLen + keysLen do 287 | if i > 1 then 288 | puts(buf, ",") 289 | end 290 | if i <= seqLen then 291 | puts(buf, " ") 292 | self:putValue(t[i]) 293 | else 294 | local k = keys[i - seqLen] 295 | tabify(self) 296 | if isIdentifier(k) then 297 | puts(buf, k) 298 | else 299 | puts(buf, "[") 300 | self:putValue(k) 301 | puts(buf, "]") 302 | end 303 | puts(buf, " = ") 304 | self:putValue(t[k]) 305 | end 306 | end 307 | 308 | local mt = getmetatable(t) 309 | if type(mt) == "table" then 310 | if seqLen + keysLen > 0 then 311 | puts(buf, ",") 312 | end 313 | tabify(self) 314 | puts(buf, " = ") 315 | self:putValue(mt) 316 | end 317 | 318 | self.level = self.level - 1 319 | 320 | if keysLen > 0 or type(mt) == "table" then 321 | tabify(self) 322 | elseif seqLen > 0 then 323 | puts(buf, " ") 324 | end 325 | 326 | puts(buf, "}") 327 | end 328 | else 329 | puts(buf, fmt("<%s %d>", tv, self:getId(v))) 330 | end 331 | end 332 | 333 | function inspect.inspect(root, options) 334 | options = options or {} 335 | 336 | local depth = options.depth or math.huge 337 | local newline = options.newline or "\n" 338 | local indent = options.indent or " " 339 | local process = options.process 340 | 341 | if process then 342 | root = processRecursive(process, root, {}, {}) 343 | end 344 | 345 | local cycles = {} 346 | countCycles(root, cycles) 347 | 348 | local inspector = setmetatable({ 349 | buf = { n = 0 }, 350 | ids = {}, 351 | cycles = cycles, 352 | depth = depth, 353 | level = 0, 354 | newline = newline, 355 | indent = indent, 356 | }, Inspector_mt) 357 | 358 | inspector:putValue(root) 359 | 360 | return table.concat(inspector.buf) 361 | end 362 | 363 | setmetatable(inspect, { 364 | __call = function(_, root, options) 365 | return inspect.inspect(root, options) 366 | end, 367 | }) 368 | 369 | return inspect 370 | end)() 371 | 372 | --- 373 | ---__ANSI color codes:__ 374 | --- 375 | ---* `0`: Reset 376 | ---* `30`: Black 377 | ---* `31`: Red 378 | ---* `32`: Green 379 | ---* `33`: Yellow 380 | ---* `34`: Blue 381 | ---* `35`: Purple 382 | ---* `36`: Cyan 383 | ---* `37`: White 384 | ---@param color_code integer 385 | local function format_ansi_color_code(color_code) 386 | return string.char(27) .. "[" .. tostring(color_code) .. "m" 387 | end 388 | 389 | --- 390 | ---__ANSI color codes:__ 391 | --- 392 | ---* `0`: Reset 393 | ---* `30`: Black 394 | ---* `31`: Red 395 | ---* `32`: Green 396 | ---* `33`: Yellow 397 | ---* `34`: Blue 398 | ---* `35`: Purple 399 | ---* `36`: Cyan 400 | ---* `37`: White 401 | --- 402 | ---@param color_code integer 403 | ---@param text unknown 404 | ---@param skip_colorize? boolean 405 | --- 406 | ---@return string 407 | local function colorize(color_code, text, skip_colorize) 408 | if skip_colorize then 409 | return text 410 | end 411 | return format_ansi_color_code(color_code) .. tostring(text) .. format_ansi_color_code(0) 412 | end 413 | 414 | ---Print the inspected version of the value 415 | local function pinspect(value) 416 | print(inspect(value)) 417 | end 418 | 419 | --- 420 | ---@param names string[] 421 | local function convert_string_array_to_alias_union(names) 422 | for index, name in ipairs(names) do 423 | print("---|`" .. name .. "`") 424 | end 425 | end 426 | 427 | --- 428 | ---Returns the file extension from a given file path. 429 | --- 430 | ---@param path string: The file path to extract the extension from. 431 | --- 432 | ---@return string|nil: The file extension (including the dot), or nil if no extension is found. 433 | local function get_file_extension(path) 434 | return path:match("^.+(%..+)$") 435 | end 436 | 437 | --- 438 | ---https://stackoverflow.com/a/49405922 439 | --- 440 | ---@param path string The path of a directory 441 | --- 442 | ---@return fun(...): string, LuaFileSystem.Attributes 443 | local function list_files_recursively(path) 444 | assert(path and path ~= "", "Please pass directory parameter") 445 | if string.sub(path, -1) == "/" then 446 | path = string.sub(path, 1, -2) 447 | end 448 | 449 | --- 450 | ---@param dir string 451 | local function yieldtree(dir) 452 | for entry in lfs.dir(dir) do 453 | if entry ~= "." and entry ~= ".." then 454 | local new_entry = dir .. "/" .. entry 455 | local attr = lfs.attributes(new_entry) 456 | coroutine.yield(new_entry, attr) 457 | if attr.mode == "directory" then 458 | yieldtree(new_entry) 459 | end 460 | end 461 | end 462 | end 463 | 464 | return coroutine.wrap(function() 465 | yieldtree(path) 466 | end) 467 | end 468 | 469 | local namespace = (function() 470 | ---https://stackoverflow.com/a/29246308 471 | --- 472 | ---@param fun function 473 | ---@return string 474 | local function get_function_args(fun) 475 | local args = {} 476 | local hook = debug.gethook() 477 | 478 | local arg_hook = function(...) 479 | local info = debug.getinfo(3) 480 | if "pcall" ~= info.name then 481 | return 482 | end 483 | 484 | for i = 1, math.huge do 485 | local name, value = debug.getlocal(2, i) 486 | if "(*temporary)" == name then 487 | debug.sethook(hook) 488 | error("") 489 | return 490 | end 491 | table.insert(args, name) 492 | end 493 | end 494 | 495 | debug.sethook(arg_hook, "c") 496 | pcall(fun) 497 | 498 | return table.concat(args, ", ") 499 | end 500 | 501 | --- 502 | ---@param s string 503 | ---@param ... any 504 | local function printf(s, ...) 505 | print(string.format(s, ...)) 506 | end 507 | 508 | --- 509 | ---@param t table 510 | ---@return table 511 | local function sort_keys(t) 512 | local keys = {} 513 | for k in pairs(t) do 514 | table.insert(keys, k) 515 | end 516 | table.sort(keys) 517 | return keys 518 | end 519 | 520 | --- 521 | ---@param lib_name string 522 | ---@param lib table 523 | ---@param as_lua? boolean # Print as Lua code, not as Markdown 524 | local function print_lib_members(lib_name, lib, as_lua) 525 | if as_lua == nil then 526 | as_lua = false 527 | end 528 | local member_names = sort_keys(lib) 529 | for _, member in ipairs(member_names) do 530 | local member_type = type(lib[member]) 531 | if not as_lua then 532 | if member_type == "table" and member ~= "__index" and member ~= "_M" then 533 | printf("- *`%s.%s` (%s)*", lib_name, member, member_type) 534 | print_lib_members(lib_name .. "." .. member, lib[member], as_lua) 535 | elseif member_type == "function" then 536 | printf("- __`%s.%s` (%s)__", lib_name, member, member_type) 537 | else 538 | printf("- `%s.%s` (%s)", lib_name, member, member_type) 539 | end 540 | else 541 | if member_type == "function" then 542 | local args = get_function_args(lib[member]) 543 | printf("function %s.%s(%s) end", lib_name, member, args) 544 | end 545 | end 546 | end 547 | end 548 | 549 | local lua_std = { 550 | _G = true, 551 | arg = true, 552 | boolean = true, 553 | coroutine = true, 554 | debug = true, 555 | io = true, 556 | math = true, 557 | number = true, 558 | os = true, 559 | package = true, 560 | string = true, 561 | table = true, 562 | utf8 = true, 563 | } 564 | 565 | local function print_global_namespace() 566 | local env = _ENV 567 | local lib_names = sort_keys(env) 568 | for _, lib_name in ipairs(lib_names) do 569 | if not lua_std[lib_name] then 570 | local lib = env[lib_name] 571 | if type(lib) == "table" then 572 | printf("\n### %s\n", lib_name) 573 | print_lib_members(lib_name, env[lib_name]) 574 | end 575 | end 576 | end 577 | end 578 | 579 | return print_global_namespace 580 | end)() 581 | 582 | ---@class NodeTypeInfo 583 | ---@field id NodeTypeName 584 | ---@field subtype? WhatsitTypeName 585 | ---@field subtypes? table 586 | ---@field fields? table 587 | 588 | --- 589 | ---@param id NodeTypeName 590 | ---@param subtype? WhatsitTypeName 591 | ---@return NodeTypeInfo 592 | local function get_node_info(id, subtype) 593 | --- 594 | ---Some luatex lua functions return an array table with a 0 index for the first element. 595 | --- 596 | ---inspect prints out: 597 | --- 598 | ---```lua 599 | ---{ "line", "box", 600 | --- [0] = "unknown" 601 | ---} 602 | ---``` 603 | --- 604 | ---@param tbl? table 605 | local function reindex_array(tbl) 606 | if not tbl then 607 | return 608 | end 609 | local new = {} 610 | for i = -3, 100 do 611 | if tbl[i] then 612 | table.insert(new, tbl[i] .. " (" .. i .. ")") 613 | end 614 | end 615 | return new 616 | end 617 | 618 | local function render_numberic(number) 619 | return " (" .. tostring(number) .. ")" 620 | end 621 | 622 | ---@type NodeTypeInfo 623 | local info = { 624 | id = id .. render_numberic(node.id(id)), 625 | } 626 | if subtype ~= nil then 627 | info.subtype = subtype .. render_numberic(node.subtype(subtype)) 628 | info.fields = reindex_array(node.fields(node.id(id), node.subtype(subtype))) 629 | else 630 | info.subtypes = reindex_array(node.subtypes(id)) 631 | info.fields = reindex_array(node.fields(node.id(id))) 632 | end 633 | return info 634 | end 635 | 636 | local assertions = (function() 637 | --- 638 | ---@param actual unknown 639 | ---@param expected unknown 640 | ---@param compare fun(actual: unknown, expected: unknown): boolean 641 | local function report_diff(compare, actual, expected) 642 | if not compare(actual, expected) then 643 | print("actual:", inspect(actual)) 644 | print("expected:", inspect(expected)) 645 | assert(false) 646 | else 647 | print(colorize(31, inspect(actual))) 648 | end 649 | end 650 | 651 | ---@param actual unknown 652 | ---@param expected unknown 653 | --- 654 | ---@return boolean 655 | local function compare_equality(actual, expected) 656 | return actual == expected 657 | end 658 | 659 | ---@param actual unknown 660 | --- 661 | ---@return boolean 662 | local function compare_truthy(actual) 663 | if actual then 664 | return true 665 | end 666 | return false 667 | end 668 | 669 | ---@param a number 670 | ---@param b number 671 | ---@param epsilon number 672 | --- 673 | ---@return boolean 674 | local function compare_numbers(a, b, epsilon) 675 | epsilon = epsilon or 1e-6 676 | return a == b or math.abs(a - b) < epsilon 677 | end 678 | 679 | --- 680 | ---Deeply compare two objects. 681 | --- 682 | ---Source: [gist.github.com/sapphyrus/fd9aeb871e3ce966cc4b0b969f62f539](https://gist.github.com/sapphyrus/fd9aeb871e3ce966cc4b0b969f62f539?permalink_comment_id=4563041#gistcomment-4563041) 683 | --- 684 | ---@param o1 unknown # An object of any type. 685 | ---@param o2 unknown # An object of any type. 686 | ---@param ignore_mt? boolean # Ignore the metatable. 687 | --- 688 | ---@return boolean # `true`, if the two specified objects are deeply equal. 689 | local function compare_tables(o1, o2, ignore_mt) 690 | -- same object 691 | if o1 == o2 then 692 | return true 693 | end 694 | 695 | local o1Type = type(o1) 696 | local o2Type = type(o2) 697 | --- different type 698 | if o1Type ~= o2Type then 699 | return false 700 | end 701 | --- same type but not table, already compared above 702 | if o1Type ~= "table" then 703 | return false 704 | end 705 | 706 | -- use metatable method 707 | if not ignore_mt then 708 | local mt1 = getmetatable(o1) 709 | if mt1 and mt1.__eq then 710 | -- compare using built in method 711 | return o1 == o2 712 | end 713 | end 714 | 715 | -- iterate over o1 716 | for key1, value1 in pairs(o1) do 717 | local value2 = o2[key1] 718 | if value2 == nil or compare_tables(value1, value2, ignore_mt) == false then 719 | return false 720 | end 721 | end 722 | 723 | --- check keys in o2 but missing from o1 724 | for key2, _ in pairs(o2) do 725 | if o1[key2] == nil then 726 | return false 727 | end 728 | end 729 | return true 730 | end 731 | 732 | return { 733 | ---@param actual unknown 734 | ---@param expected unknown 735 | equals = function(actual, expected) 736 | report_diff(compare_equality, actual, expected) 737 | end, 738 | 739 | ---@param actual unknown 740 | is_nil = function(actual) 741 | report_diff(compare_equality, actual, nil) 742 | end, 743 | 744 | ---@param actual unknown 745 | is_true = function(actual) 746 | report_diff(compare_equality, actual, true) 747 | end, 748 | 749 | ---@param actual unknown 750 | is_truthy = function(actual) 751 | report_diff(compare_truthy, actual, true) 752 | end, 753 | 754 | ---@param actual unknown 755 | is_false = function(actual) 756 | report_diff(compare_equality, actual, false) 757 | end, 758 | 759 | ---@param actual unknown 760 | ---@param expected "nil"|"number"|"string"|"boolean"|"table"|"function"|"thread"|"userdata" 761 | is_type = function(actual, expected) 762 | report_diff(compare_equality, type(actual), expected) 763 | end, 764 | 765 | ---@param actual unknown 766 | ---@param expected unknown 767 | numbers = function(actual, expected) 768 | report_diff(compare_numbers, actual, expected) 769 | end, 770 | 771 | ---@param actual unknown 772 | ---@param expected unknown 773 | same = function(actual, expected) 774 | report_diff(compare_tables, actual, expected) 775 | end, 776 | 777 | ---@param id NodeTypeName 778 | ---@param subtype? WhatsitTypeName 779 | ---@param expected unknown 780 | node_type = function(id, subtype, expected) 781 | local info = get_node_info(id, subtype) 782 | report_diff(compare_tables, info, expected) 783 | end, 784 | } 785 | end)() 786 | 787 | return { 788 | pinspect = pinspect, 789 | assert = assertions, 790 | print_global_namespace = namespace, 791 | convert_string_array_to_alias_union = convert_string_array_to_alias_union, 792 | list_files_recursively = list_files_recursively, 793 | get_file_extension = get_file_extension, 794 | } 795 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # LuaTeX Lua API 2 | 3 | Type definitions for the Lua API of `LuaTeX` and related projects. 4 | 5 | ![](resources/screencasts/node.new.gif) 6 | 7 | [LuaTeX](https://www.luatex.org) has a very large [Lua](https://www.lua.org) 8 | API. This project tries to make this API accessible in the text editor 9 | of your choice. This is made possible by the 10 | [lua-language-server](https://github.com/LuaLS/lua-language-server) - a 11 | server that implements the [Language Server Protocol 12 | (LSP)](https://en.wikipedia.org/wiki/Language_Server_Protocol) for the 13 | `Lua` language. Features such as code completion, syntax highlighting 14 | and marking of warnings and errors, should therefore not only be 15 | possible in [Visual Studio Code](https://code.visualstudio.com), but in 16 | a [large number of 17 | editors](https://langserver.org/#implementations-client) that support 18 | the `LSP`. 19 | 20 | ## Subprojects 21 | 22 | * [lualatex](https://github.com/TeXLuaCATS/LuaLaTeX) 23 | * [lualibs](https://github.com/TeXLuaCATS/Lualibs) 24 | * [luametatex](https://github.com/TeXLuaCATS/LuaMetaTeX) 25 | * [luaotfload](https://github.com/TeXLuaCATS/LuaOTFload) 26 | * [luatex](https://github.com/TeXLuaCATS/LuaTeX) 27 | 28 | ## Distribution ... 29 | 30 | ## via CTAN 31 | 32 | ![](resources/images/Screenshot_CTAN.png) 33 | 34 | The type definitions are published on 35 | [CTAN](https://www.ctan.org/pkg/luatex-type-definitions) as a single 36 | file to avoid cluttering the CTAN directory with many individual Lua 37 | files. Since this one file is just under 1.5 MB in size, a configuration 38 | must be made so that the language server can load the file. The 39 | following configuration example sets the preload file size to a maximum 40 | of 5000 kB. 41 | 42 | ```json 43 | { 44 | "Lua.workspace.preloadFileSize": 5000, 45 | } 46 | ``` 47 | 48 | There are several ways to include type definitions in a project. 49 | The easiest way is to copy the file into the project folder. 50 | Or you can use the configuration `Lua.workspace.library`: 51 | 52 | ```json 53 | { 54 | "Lua.workspace.library": ["/path/to/luatex-type-definitions.lua"] 55 | } 56 | ``` 57 | 58 | ### via Visual Studio Code Extension 59 | 60 | [![](resources/images/Screenshot_VSCode-extension.png)](https://marketplace.visualstudio.com/items?itemName=JosefFriedrich.luatex) 61 | 62 | [Visual Studio Code LuaTeX Extension](https://github.com/TeXLuaCATS/vscode_extension) 63 | 64 | ### via LuaCATS git respositories 65 | 66 | ![](resources/images/Screenshot_LuaCATS.png) 67 | 68 | [LuaCATS](https://github.com/LuaCATS) is a [Github](https://github.com) 69 | organisation and stands for *“Lua Comment And Type System”*. This 70 | organization provides a place for community projects to live. These 71 | projects are [addons](https://luals.github.io/wiki/addons/) for popular 72 | libraries/frameworks. 73 | The repositories in this organization are used by 74 | [LLS-Addons](https://github.com/LuaLS/LLS-Addons), a repository that is used by the [addon 75 | manager](https://luals.github.io/wiki/addons/#addon-manager) of the [VS 76 | Code 77 | extension](https://marketplace.visualstudio.com/items?itemName=sumneko.lua) 78 | for the [Lua Language Server](https://github.com/LuaLS/lua-language-server). 79 | 80 | #### All related LuaCATS repositories 81 | 82 | This repositories in LuaCATS are related to this project: 83 | 84 | * [lmathx](https://github.com/LuaCATS/lmathx) 85 | * [lpeg](https://github.com/LuaCATS/lpeg) 86 | * [luafilesystem](https://github.com/LuaCATS/luafilesystem) 87 | * [luaharfbuzz](https://github.com/LuaCATS/luaharfbuzz) 88 | * [luasocket](https://github.com/LuaCATS/luasocket) 89 | * [luazip](https://github.com/LuaCATS/luazip) 90 | * [lzlib](https://github.com/LuaCATS/lzlib) 91 | * [md5](https://github.com/LuaCATS/md5) 92 | * [slnunicode](https://github.com/LuaCATS/slnunicode) 93 | * [tex-lualatex](https://github.com/LuaCATS/tex-lualatex) 94 | * [tex-lualibs](https://github.com/LuaCATS/tex-lualibs) 95 | * [tex-luametatex](https://github.com/LuaCATS/tex-luametatex) 96 | * [tex-luatex](https://github.com/LuaCATS/tex-luatex) 97 | 98 | #### Upstream LuaCATS repositories 99 | 100 | The following repositories are *upstream* projects. This means: The type 101 | definitions are developed in a LuaCATS repository and *pulled* in by 102 | this project. 103 | 104 | * [LuaCATS: lmathx](https://github.com/LuaCATS/lmathx) 105 | → [library/luametatex/lmathx.lua](https://github.com/TeXLuaCATS/LuaMetaTeX/blob/main/library/xmath.lua) 106 | * [LuaCATS: lpeg](https://github.com/LuaCATS/lpeg) 107 | → [TeXLuaCATS/LuaTeX/lpeg.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/lpeg.lua) 108 | * [LuaCATS: luaharfbuzz](https://github.com/LuaCATS/luaharfbuzz) 109 | → [TeXLuaCATS/LuaTeX/luaharfbuzz.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/luaharfbuzz.lua) 110 | * [LuaCATS: luasocket](https://github.com/LuaCATS/luasocket) 111 | → [TeXLuaCATS/LuaTeX/socket.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/socket.lua) 112 | → [TeXLuaCATS/LuaTeX/mime.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/mime.lua) 113 | * [LuaCATS: luazip](https://github.com/LuaCATS/luazip) 114 | → [TeXLuaCATS/LuaTeX/zip.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/zip.lua) 115 | * [LuaCATS: lzlib](https://github.com/LuaCATS/lzlib) 116 | → [TeXLuaCATS/LuaTeX/zlib.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/zlib.lua) 117 | * [LuaCATS: md5](https://github.com/LuaCATS/md5) 118 | → [TeXLuaCATS/LuaTeX/md5.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/md5.lua) 119 | * [LuaCATS: slnunicode](https://github.com/LuaCATS/slnunicode) 120 | → [TeXLuaCATS/LuaTeX/unicode.lua](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/unicode.lua) 121 | 122 | #### Downstream LuaCATS repositories 123 | 124 | The following repositories are *downstream* projects. This means: The 125 | type definitions are developed in this project. They are then *pushed* 126 | into a LuaCATS repository. 127 | 128 | * [LuaCATS: tex-lualatex](https://github.com/LuaCATS/tex-lualatex) 129 | ← [TeXLuaCATS/LuaLaTeX](https://github.com/TeXLuaCATS/LuaLaTeX) 130 | * [LuaCATS: tex-luatex](https://github.com/LuaCATS/tex-luatex) 131 | ← [TeXLuaCATS/LuaTeX](https://github.com/TeXLuaCATS/LuaTeX) 132 | * [LuaCATS: tex-lualibs](https://github.com/LuaCATS/tex-lualibs) 133 | ← [TeXLuaCATS/Lualibs](https://github.com/TeXLuaCATS/Lualibs) 134 | * [LuaCATS: tex-luametatex](https://github.com/LuaCATS/tex-luametatex) 135 | ← [TeXLuaCATS/LuaMetaTeX](https://github.com/TeXLuaCATS/LuaMetaTeX) 136 | 137 | ## Directory structure of the repository 138 | 139 | In the subfolder `library` are files named after the global libraries 140 | they document. For example, the `library/tex.lua` file contains the 141 | documentation for the `tex` library. These *Lua* files don’t contain 142 | real *Lua* code. They consist only of function bodies and empty 143 | tables. The main focus is in the docstrings. 144 | 145 | The API documentation is written in a [well documented annotation 146 | format](https://luals.github.io/wiki/annotations/). 147 | This format is based on the [EmmyLua](https://emmylua.github.io) 148 | format. Unfortunately, the *Lua* community has not yet been able to 149 | agree on a standarized annotation format. Many *Lua* project are 150 | documented in the [LDoc](https://github.com/lunarmodules/LDoc) format. 151 | However, the differences between these formats are marginal. 152 | 153 | ### Directory `library` 154 | 155 | The actual definitions are located in the directory `library`. This 156 | directory is divided into further subdirectories. In the folder `luatex` 157 | you will find the definitions that the engine *LuaTeX* provides. The 158 | folder `lualibs` documents the extension library of the same name. If 159 | you use `lualatex`, you may be interested in the folder of the same 160 | name. 161 | 162 | ### Directory `resources` 163 | 164 | The folder `resources` contains *TeX* manuals and *HTML* online 165 | documentation converted into *Lua* docstrings. 166 | 167 | ### Directory `examples` 168 | 169 | The `example` folder contains *TeX* and *Lua* files for demonstrating 170 | and testing the documented Lua API. 171 | 172 | ## Current version 173 | 174 | 2025/07/24 v0.2.0 175 | 176 | ## License 177 | 178 | Copyright (C) 2022-2025 by Josef Friedrich 179 | ------------------------------------------------------------------------ 180 | 181 | This program is free software: you can redistribute it and/or modify it 182 | under the terms of the GNU General Public License as published by the 183 | Free Software Foundation, either version 2 of the License, or (at your 184 | option) any later version. 185 | 186 | This program is distributed in the hope that it will be useful, but 187 | WITHOUT ANY WARRANTY; without even the implied warranty of 188 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 189 | Public License for more details. 190 | 191 | You should have received a copy of the GNU General Public License along 192 | with this program. If not, see . 193 | 194 | ### About the license selection 195 | 196 | The same license was used for the type definitions as for LuaTeX (GPLv2). 197 | The MIT license is used for the external upstream projects. 198 | 199 | ### GPLv2 copyright notice for every file 200 | 201 | Only two hyphens are used here, rather than three, so that the copyright notice 202 | does not end up in the rendered documentation. 203 | 204 | ```lua 205 | -- ----------------------------------------------------------------------------- 206 | -- Copyright (C) 2022-2025 by Josef Friedrich 207 | -- ----------------------------------------------------------------------------- 208 | -- 209 | -- This program is free software: you can redistribute it and/or modify it 210 | -- under the terms of the GNU General Public License as published by the 211 | -- Free Software Foundation, either version 2 of the License, or (at your 212 | -- option) any later version. 213 | -- 214 | -- This program is distributed in the hope that it will be useful, but 215 | -- WITHOUT ANY WARRANTY; without even the implied warranty of 216 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General 217 | -- Public License for more details. 218 | -- 219 | -- You should have received a copy of the GNU General Public License along 220 | -- with this program. If not, see . 221 | -- 222 | -- ----------------------------------------------------------------------------- 223 | 224 | ``` 225 | 226 | ### MIT copyright notice for every file 227 | 228 | ```lua 229 | -- ----------------------------------------------------------------------------- 230 | -- Copyright (c) 2023-2025 by Josef Friedrich 231 | -- ----------------------------------------------------------------------------- 232 | -- 233 | -- MIT License 234 | -- 235 | -- Permission is hereby granted, free of charge, to any person obtaining a copy 236 | -- of this software and associated documentation files (the "Software"), to deal 237 | -- in the Software without restriction, including without limitation the rights 238 | -- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 239 | -- copies of the Software, and to permit persons to whom the Software is 240 | -- furnished to do so, subject to the following conditions: 241 | -- 242 | -- The above copyright notice and this permission notice shall be included in 243 | -- all copies or substantial portions of the Software. 244 | -- 245 | -- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 246 | -- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 247 | -- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 248 | -- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 249 | -- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 250 | -- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 251 | -- SOFTWARE. 252 | -- 253 | -- ----------------------------------------------------------------------------- 254 | 255 | ``` 256 | 257 | ## Installation / Setup for Visual Studio Code 258 | 259 | Install [Visual Studio Code](https://code.visualstudio.com/) and the 260 | [lua-language-server](https://marketplace.visualstudio.com/items?itemName=sumneko.lua). 261 | 262 | 263 | ``` 264 | git clone https://github.com/TeXLuaCATS/LuaTeX.git 265 | ``` 266 | 267 | `.vscode/settings.json`: 268 | 269 | ```json 270 | { 271 | "Lua.workspace.library": [ 272 | "/library" 273 | ] 274 | } 275 | ``` 276 | 277 | ## How to contribute 278 | 279 | The preferred method of contributing to the project is via Github pull 280 | requests. You can also email patches to josef@friedrich.rocks. 281 | It is ok if you only document the data types of the input parameters. 282 | 283 | Use imperative mood for the first line: https://peps.python.org/pep-0257/ 284 | 285 | `Please contribute!` messages 286 | 287 | Default message: 288 | 289 | ```lua 290 | ---😱 [Types](https://github.com/TeXLuaCATS/LuaTeX/blob/main/library/pdf.lua) incomplete or incorrect? 🙏 [Please contribute!](https://github.com/TeXLuaCATS/LuaTeX/pulls) 291 | ``` 292 | 293 | No documentation at all: 294 | 295 | ```lua 296 | --- 297 | ---Warning! Undocumented code!

298 | ---TODO: Please contribute 299 | ---https://github.com/TeXLuaCATS/meta#how-to-contribute 300 | ``` 301 | 302 | ### Minimal example of `tex.sp()` 303 | 304 | ```lua 305 | --- 306 | ---@param s string 307 | function tex.sp(s) end 308 | ``` 309 | 310 | ### Less minimal example of `tex.sp()` 311 | 312 | ```lua 313 | --- 314 | ---@param s string 315 | --- 316 | ---@return integer 317 | function tex.sp(s) end 318 | ``` 319 | 320 | Or if you have more time you can also expand the documentation to this 321 | level: 322 | 323 | ### Prime example of `tex.sp()` 324 | 325 | ```lua 326 | ---@meta 327 | 328 | tex = {} 329 | 330 | --- 331 | ---Convert a string `s` that represents an explicit 332 | ---dimension into an integer number of scaled points. 333 | --- 334 | ---For parsing the string, the same scanning and conversion rules are used that 335 | ---*LuaTeX* would use if it was scanning a dimension specifier in its *TeX*-like 336 | ---input language (this includes generating errors for bad values), expect for the 337 | ---following: 338 | --- 339 | ---* only explicit values are allowed, control sequences are not handled 340 | ---* infinite dimension units (`fil...`) are forbidden 341 | ---* `mu` units do not generate an error (but may not be useful either) 342 | --- 343 | ---__Example:__ 344 | --- 345 | ---```lua 346 | ---local scaled_points = tex.sp('1cm') 347 | ---print(scaled_points) -- 1864679 348 | ---``` 349 | --- 350 | ---__Reference:__ 351 | --- 352 | ---* `LuaTeX` manual: 10.3.15.5 `sp` page 204 353 | ---* Source file of the `LuaTeX` manual: [luatex-tex.tex#L1386-L1413](https://gitlab.lisn.upsaclay.fr/texlive/luatex/-/blob/f52b099f3e01d53dc03b315e1909245c3d5418d3/manual/luatex-tex.tex#L1386-L1413) 354 | --- 355 | ---@param s string # A string to convert into scaled points. 356 | --- 357 | ---@return integer # The dimension in the scaled points format. 358 | function tex.sp(s) end 359 | ``` 360 | 361 | The docstring above is rendered as follows in Visual Studio Code: 362 | 363 | ![](resources/images/tex.sp.png) 364 | 365 | A Python script called [manager](https://github.com/TeXLuaCATS/manager) 366 | was used to convert the source files. 367 | 368 | ### Navigation table `_N` 369 | 370 | Some Lua files contain a table named `_N`. `_N` stands for *navigation*. 371 | With the help of this table and the outline view of the editor, it is 372 | easier to navigate through the documentation. The name is inspired by 373 | the global Lua table `_G`. Many parts of the documentation, such as the 374 | definition of the various `Node` classes, are not shown in the outline. 375 | In the released version, this navigation table is removed using the 376 | `manage.py` management script. 377 | 378 | ```lua 379 | -- The `_N` table makes it easier to navigate through the type definitions with 380 | -- the help of the outline: 381 | -- https://github.com/TeXLuaCATS/meta?tab=readme-ov-file#navigation-table-_n 382 | _N = {} 383 | ``` 384 | 385 | The different node types are defined as classes. Since this class 386 | definition takes place entirely in the comments, it is not displayed in 387 | the outline. 388 | 389 | ```lua 390 | _N.hlist = 0 391 | 392 | ---@class HlistNode: ListNode 393 | 394 | _N.vlist = 1 395 | 396 | ---@class VlistNode: ListNode 397 | ``` 398 | 399 | The following example refers to section “8.7.2 is_node” on page 149 in 400 | the LuaTeX documentation. 401 | 402 | ```lua 403 | _N._8_7_2_is_node = "page 149" 404 | ``` 405 | 406 | ### Documentation of function overloading 407 | 408 | `LuaTeX` makes extensive use of function overloading. The following 409 | example is taken from the `LuaTeX` manual: 410 | 411 | ``` 412 | w, h, d = 413 | node.dimensions( n) 414 | w, h, d = 415 | node.dimensions( n, dir) 416 | w, h, d = 417 | node.dimensions( n, t) 418 | w, h, d = 419 | node.dimensions( n, t, dir) 420 | w, h, d = 421 | node.dimensions( glue_set, glue_sign, glue_order, n) 422 | w, h, d = 423 | node.dimensions( glue_set, glue_sign, glue_order, n, dir) 424 | w, h, d = 425 | node.dimensions( glue_set, glue_sign, glue_order, n, t) 426 | w, h, d = 427 | node.dimensions( glue_set, glue_sign, glue_order, n, t, dir) 428 | ``` 429 | 430 | This can easily be done by documenting the function with the same name 431 | but different signatures multiple times. 432 | 433 | [Issue for further improvement of the function loading](https://github.com/LuaLS/lua-language-server/issues/1456) 434 | 435 | Function overloading in `tex.sp()` 436 | 437 | ![](resources/images/tex.sp_overload.png) 438 | 439 | ### Documentation of nodes 440 | 441 | A node (object) can be described by the `@class` annotation and provided 442 | with some documentation about its attributes using `@field`. There is a base class `Node` for all node type classes. 443 | 444 | ```lua 445 | --- 446 | ---A node that comprise actual typesetting commands. A few fields are 447 | ---present in all nodes regardless of their type, these are: 448 | --- 449 | ---@class Node 450 | ---@field next Node|nil # the next node in a list, or nil 451 | ---@field prev Node|nil # That prev field is always present, but only initialized on explicit request ... 452 | ``` 453 | 454 | The `KernNode` class for example inherits from `Node` and represents 455 | a kern node. 456 | 457 | ```lua 458 | --- 459 | ---The `kern` command creates such nodes but for instance the font and math 460 | ---machinery can also add them. 461 | --- 462 | ---@class KernNode: Node 463 | ---@field subtype KernNodeSubtype 464 | ---@field kern integer # Fixed horizontal or vertical advance (in scaled points) 465 | ``` 466 | 467 | ```lua 468 | ---@alias KernNodeSubtype 469 | ---|0 # fontkern 470 | ---|1 # userkern 471 | ---|2 # accentkern 472 | ---|3 # italiccorrection 473 | ``` 474 | 475 | The `@cast` annotation forces a unspecific node to a distinct node type. 476 | 477 | ```lua 478 | while n do 479 | if n.id == node.id('kern') then 480 | ---@cast n KernNode 481 | print(n.kern) 482 | end 483 | n = n.next 484 | end 485 | ``` 486 | 487 | Use `--[[@as ]]` to force a node type onto an expression. 488 | 489 | ```lua 490 | local kern = node.new('kern') --[[@as KernNode]] 491 | ``` 492 | 493 | ![](resources/images/cast.png) 494 | 495 | 496 | ### Documentation of callback functions 497 | 498 | How a callback function is documented is shown using the 499 | `pre_linebreak_filter` as an example. 500 | 501 | #### @alias `PreLinebreakFilterGroupCode` 502 | 503 | ```lua 504 | --- 505 | ---The string called `groupcode` identifies the nodelist's context within 506 | ---*TeX*'s processing. The range of possibilities is given in the table below, but 507 | ---not all of those can actually appear in `pre_linebreak_filter`, some are 508 | ---for the `hpack_filter` and `vpack_filter` callbacks that will be 509 | ---explained in the next two paragraphs. 510 | ---@alias PreLinebreakFilterGroupCode 511 | ---|'' # main vertical list 512 | ---|'hbox' # hbox` in horizontal mode 513 | ---|'adjusted_hbox' #hbox` in vertical mode 514 | ---|'vbox' # vbox` 515 | ---|'vtop' # vtop' # 516 | ---|'align' # halign` or `valign` 517 | ---|'disc' # discretionaries 518 | ---|'insert' # packaging an insert 519 | ---|'vcenter' # vcenter` 520 | ---|'local_box' # localleftbox` or `localrightbox` 521 | ---|'split_off' # top of a `vsplit` 522 | ---|'split_keep' # remainder of a `vsplit` 523 | ---|'align_set' # alignment cell 524 | ---|'fin_row' # alignment row 525 | ``` 526 | 527 | #### @alias `NodeCallbackReturn` 528 | 529 | 530 | ```lua 531 | --- 532 | ---As for all the callbacks that deal with nodes, the return value can be one of 533 | ---three things: 534 | --- 535 | ---* boolean `true` signals successful processing 536 | ---* `` signals that the “head” node should be replaced by the 537 | --- returned node 538 | ---* boolean `false` signals that the “head” node list should be 539 | --- ignored and flushed from memory 540 | ---@alias NodeCallbackReturn true|false|Node 541 | ``` 542 | 543 | #### @alias `PreLinebreakFilter` 544 | 545 | ```lua 546 | --- 547 | ---# `pre_linebreak_filter` callback 548 | --- 549 | ---This callback is called just before *LuaTeX* starts converting a list of nodes 550 | ---into a stack of `hbox`es, after the addition of `parfillskip`. 551 | --- 552 | ---```lua 553 | ------@type PreLinebreakFilter 554 | ---function(head, groupcode) 555 | --- --- true|false|node 556 | --- return true 557 | ---end 558 | ---``` 559 | --- 560 | ---This callback does not replace any internal code. 561 | ---@alias PreLinebreakFilter fun(head: Node, groupcode: PreLinebreakFilterGroupCode): NodeCallbackReturn 562 | ``` 563 | 564 | Annotation your custom callback function with `@type`. 565 | 566 | ```lua 567 | ---@type PreLinebreakFilter 568 | local function visit_nodes(head, group) 569 | return true 570 | end 571 | 572 | luatexbase.add_to_callback('pre_linebreak_filter', visit_nodes, 'visit nodes') 573 | ``` 574 | 575 | ![](resources/images/PreLinebreakFilterCallback.png) 576 | 577 | Quick info `node.id(type)` 578 | 579 | ![](resources/images/node.id.png) 580 | 581 | Type error in `node.id(type)` 582 | 583 | ![](https://raw.githubusercontent.com/TeXLuaCATS/meta/main/resources/images/node.id_wrong-type.png) 584 | 585 | `node.id(type)` type definition 586 | 587 | ![](https://raw.githubusercontent.com/TeXLuaCATS/meta/main/resources/images/node.id_definition.png) 588 | 589 | Quick info `node.write(n)` 590 | 591 | ![](https://raw.githubusercontent.com/TeXLuaCATS/meta/main/resources/images/node.write.png) 592 | 593 | Documentation for the field `data` of the `pdf_colorstack` node: 594 | 595 | ![](https://raw.githubusercontent.com/TeXLuaCATS/meta/main/resources/images/PdfColorstockWhatsitNode.data.png) 596 | 597 | ## Documentation 598 | 599 | * [LuaTeX Repo](https://gitlab.lisn.upsaclay.fr/texlive/luatex/) [LuaTeX Mirror](https://github.com/TeX-Live/texlive-source/tree/trunk/texk/web2c/luatexdir) 600 | * [pdfTeX Mirror](https://github.com/TeX-Live/texlive-source/tree/trunk/texk/web2c/pdftexdir) 601 | 602 | ## Howtos 603 | 604 | * [Custom libraries](https://github.com/LuaLS/lua-language-server/wiki/Libraries#custom) 605 | * [@meta annotation](https://github.com/LuaLS/lua-language-server/wiki/Annotations#meta) 606 | 607 | ## Other type definition / stub repos: 608 | 609 | * [Template of the Lua interface itself](https://github.com/LuaLS/lua-language-server/tree/master/meta/template) 610 | * [In the lua-language-server included 3rd party libraries](https://github.com/LuaLS/lua-language-server/tree/master/meta/3rd) 611 | * [FiveM Lua Stubs](https://github.com/j-mie/fivem_lua_stubs) 612 | 613 | ## Annotation 614 | 615 | ### @meta 616 | 617 | Do not put the `@meta` tag in the docstrings for a global table, because 618 | EmmaLua Rust will not render the docstrings for this global table. 619 | 620 | Marks a file as "meta", meaning it is used for definitions and not for 621 | its functional Lua code. It is used internally by the language server 622 | for defining the [built-in Lua 623 | libraries](https://github.com/LuaLS/lua-language-server/tree/master/meta/template). 624 | If you are writing your own [definition files](https://luals.github.io/wiki/definition-files/), 625 | you will probably want to include this annotation in them. If you 626 | specify a name, it will only be able to be required by the given name. 627 | Giving the name `_` will make it unable to be required. Files with the 628 | `@meta` tag in them behave a little different: 629 | 630 | - Completion will not display context in a meta file 631 | - Hovering a `require` of a meta file will show `[meta]` instead of its absolute path 632 | - `Find Reference` ignores meta files 633 | 634 | **Syntax** 635 | 636 | `---@meta [name]` 637 | 638 | **Examples** 639 | 640 | Mark Meta File 641 | 642 | ```Lua 643 | ---@meta [name] 644 | ``` 645 | [^luals-meta] 646 | 647 | [^luals-meta]: https://github.com/LuaLS/LuaLS.github.io/blob/f87938ff71a9322ac2bdcbac2164ad2da7e394f0/src/content/wiki/annotations.mdx?plain=1#L731-L752 648 | 649 | ## HTML doc generator 650 | 651 | The [EmmyLua Analyzer 652 | Rust](https://github.com/EmmyLuaLs/emmylua-analyzer-rust) provides a 653 | [documentation generation tool](https://github.com/EmmyLuaLs/emmylua-analyzer-rust/tree/main/crates/emmylua_doc_cli). 654 | This tool generates Markdown files which can be parsed by [mkdocs](https://www.mkdocs.org). 655 | 656 | ```yml 657 | site_name: LuaTeX Lua API type definitions 658 | 659 | theme: 660 | name: material 661 | font: 662 | text: Roboto 663 | code: Roboto Mono 664 | search: true 665 | features: 666 | - quick-links 667 | - navigation 668 | - search 669 | - toc 670 | - fullscreen 671 | - bookmarks 672 | - tabs 673 | - code 674 | - edit-on-github 675 | - language-selector 676 | - code 677 | - cover 678 | - footer 679 | - social-share 680 | - theme-switcher 681 | 682 | markdown_extensions: 683 | - pymdownx.highlight: 684 | anchor_linenums: true 685 | line_spans: __span 686 | pygments_lang_class: true 687 | - pymdownx.inlinehilite 688 | - pymdownx.snippets 689 | - pymdownx.superfences 690 | ``` 691 | 692 | ## References 693 | 694 | ```lua 695 | --- 696 | ---__Reference:__ 697 | --- 698 | ---* Source file of the `LuaTeX` manual: []() 699 | --- 700 | ``` 701 | 702 | ## Global namespaces 703 | 704 | The Makefile provides targets for printing the global namespace 705 | available on the specific engines. The Makefile uses some Lua functions 706 | to output all functions and tables of the global namespace that can be 707 | found in 708 | [utils.lua](https://github.com/TeXLuaCATS/meta/blob/main/utils.lua). 709 | 710 | To print the [LuaTeX global namespace](https://github.com/TeXLuaCATS/LuaTeX/blob/main/resources/namespace.md): 711 | 712 | ``` 713 | make print_namespace 714 | ``` 715 | 716 | To print the [LuaMetaTeX global namespace](https://github.com/TeXLuaCATS/meta/blob/main/resources/namespaces/luametatex_luaonly.md): 717 | 718 | ``` 719 | make namespace_luametatex 720 | ``` 721 | -------------------------------------------------------------------------------- /resources/namespaces/luametatex_luaonly.md: -------------------------------------------------------------------------------- 1 | ### aes 2 | 3 | - __`aes.decode` (function)__ 4 | - __`aes.encode` (function)__ 5 | - __`aes.random` (function)__ 6 | 7 | ### basexx 8 | 9 | - __`basexx.decode16` (function)__ 10 | - __`basexx.decode64` (function)__ 11 | - __`basexx.decode85` (function)__ 12 | - __`basexx.decodeLZW` (function)__ 13 | - __`basexx.decodeRL` (function)__ 14 | - __`basexx.encode16` (function)__ 15 | - __`basexx.encode64` (function)__ 16 | - __`basexx.encode85` (function)__ 17 | - __`basexx.encodeLZW` (function)__ 18 | - __`basexx.encodeRL` (function)__ 19 | 20 | ### fio 21 | 22 | - __`fio.getposition` (function)__ 23 | - __`fio.read2dot14` (function)__ 24 | - __`fio.readbytes` (function)__ 25 | - __`fio.readbytetable` (function)__ 26 | - __`fio.readcardinal1` (function)__ 27 | - __`fio.readcardinal1le` (function)__ 28 | - __`fio.readcardinal2` (function)__ 29 | - __`fio.readcardinal2le` (function)__ 30 | - __`fio.readcardinal3` (function)__ 31 | - __`fio.readcardinal3le` (function)__ 32 | - __`fio.readcardinal4` (function)__ 33 | - __`fio.readcardinal4le` (function)__ 34 | - __`fio.readcardinaltable` (function)__ 35 | - __`fio.readcline` (function)__ 36 | - __`fio.readcstring` (function)__ 37 | - __`fio.readfixed2` (function)__ 38 | - __`fio.readfixed4` (function)__ 39 | - __`fio.readinteger1` (function)__ 40 | - __`fio.readinteger1le` (function)__ 41 | - __`fio.readinteger2` (function)__ 42 | - __`fio.readinteger2le` (function)__ 43 | - __`fio.readinteger3` (function)__ 44 | - __`fio.readinteger3le` (function)__ 45 | - __`fio.readinteger4` (function)__ 46 | - __`fio.readinteger4le` (function)__ 47 | - __`fio.readintegertable` (function)__ 48 | - __`fio.setposition` (function)__ 49 | - __`fio.skipposition` (function)__ 50 | - __`fio.writecardinal1` (function)__ 51 | - __`fio.writecardinal1le` (function)__ 52 | - __`fio.writecardinal2` (function)__ 53 | - __`fio.writecardinal2le` (function)__ 54 | - __`fio.writecardinal3` (function)__ 55 | - __`fio.writecardinal3le` (function)__ 56 | - __`fio.writecardinal4` (function)__ 57 | - __`fio.writecardinal4le` (function)__ 58 | 59 | ### lfs 60 | 61 | - __`lfs.attributes` (function)__ 62 | - __`lfs.chdir` (function)__ 63 | - __`lfs.currentdir` (function)__ 64 | - __`lfs.dir` (function)__ 65 | - __`lfs.isdir` (function)__ 66 | - __`lfs.isfile` (function)__ 67 | - __`lfs.isreadabledir` (function)__ 68 | - __`lfs.isreadablefile` (function)__ 69 | - __`lfs.iswriteabledir` (function)__ 70 | - __`lfs.iswriteablefile` (function)__ 71 | - __`lfs.link` (function)__ 72 | - __`lfs.mkdir` (function)__ 73 | - __`lfs.rmdir` (function)__ 74 | - __`lfs.setexecutable` (function)__ 75 | - __`lfs.symlink` (function)__ 76 | - __`lfs.symlinktarget` (function)__ 77 | - __`lfs.touch` (function)__ 78 | 79 | ### lpeg 80 | 81 | - __`lpeg.B` (function)__ 82 | - __`lpeg.C` (function)__ 83 | - __`lpeg.Carg` (function)__ 84 | - __`lpeg.Cb` (function)__ 85 | - __`lpeg.Cc` (function)__ 86 | - __`lpeg.Cf` (function)__ 87 | - __`lpeg.Cg` (function)__ 88 | - __`lpeg.Cmt` (function)__ 89 | - __`lpeg.Cp` (function)__ 90 | - __`lpeg.Cs` (function)__ 91 | - __`lpeg.Ct` (function)__ 92 | - __`lpeg.P` (function)__ 93 | - __`lpeg.R` (function)__ 94 | - __`lpeg.S` (function)__ 95 | - __`lpeg.V` (function)__ 96 | - __`lpeg.locale` (function)__ 97 | - __`lpeg.match` (function)__ 98 | - __`lpeg.pcode` (function)__ 99 | - __`lpeg.ptree` (function)__ 100 | - __`lpeg.setmaxstack` (function)__ 101 | - __`lpeg.type` (function)__ 102 | - __`lpeg.utfR` (function)__ 103 | - `lpeg.version` (string) 104 | 105 | ### lua 106 | 107 | - __`lua.addnibble` (function)__ 108 | - __`lua.comparekeys` (function)__ 109 | - __`lua.getallkeys` (function)__ 110 | - __`lua.getcheckedkeys` (function)__ 111 | - __`lua.getcurrenttime` (function)__ 112 | - __`lua.getexitcode` (function)__ 113 | - __`lua.getnibble` (function)__ 114 | - __`lua.getnumerickeys` (function)__ 115 | - __`lua.getpreciseseconds` (function)__ 116 | - __`lua.getpreciseticks` (function)__ 117 | - __`lua.getruntime` (function)__ 118 | - __`lua.getstacktop` (function)__ 119 | - __`lua.getstartupfile` (function)__ 120 | - __`lua.getstringkeys` (function)__ 121 | - __`lua.getversion` (function)__ 122 | - __`lua.newindex` (function)__ 123 | - __`lua.newtable` (function)__ 124 | - __`lua.setexitcode` (function)__ 125 | - __`lua.setnibble` (function)__ 126 | - `lua.startupfile` (string) 127 | - __`lua.subnibble` (function)__ 128 | - `lua.version` (string) 129 | 130 | ### luac 131 | 132 | - __`luac.print` (function)__ 133 | 134 | ### md5 135 | 136 | - __`md5.HEX` (function)__ 137 | - __`md5.hex` (function)__ 138 | - __`md5.sum` (function)__ 139 | 140 | ### mime 141 | 142 | - `mime._VERSION` (string) 143 | - __`mime.b64` (function)__ 144 | - __`mime.dot` (function)__ 145 | - __`mime.eol` (function)__ 146 | - __`mime.qp` (function)__ 147 | - __`mime.qpwrp` (function)__ 148 | - __`mime.unb64` (function)__ 149 | - __`mime.unqp` (function)__ 150 | - __`mime.wrp` (function)__ 151 | 152 | ### mplib 153 | 154 | - __`mplib.execute` (function)__ 155 | - __`mplib.expandtex` (function)__ 156 | - __`mplib.fillbytemap` (function)__ 157 | - __`mplib.finish` (function)__ 158 | - __`mplib.getbytemap` (function)__ 159 | - __`mplib.getbytemapdata` (function)__ 160 | - __`mplib.getcallbackstate` (function)__ 161 | - __`mplib.getcodes` (function)__ 162 | - __`mplib.getcolormodels` (function)__ 163 | - __`mplib.getfields` (function)__ 164 | - __`mplib.gethashentries` (function)__ 165 | - __`mplib.gethashentry` (function)__ 166 | - __`mplib.getinternalactions` (function)__ 167 | - __`mplib.getknotstates` (function)__ 168 | - __`mplib.getlastaddtype` (function)__ 169 | - __`mplib.getlogtargets` (function)__ 170 | - __`mplib.getobjecttypes` (function)__ 171 | - __`mplib.getresultstatus` (function)__ 172 | - __`mplib.getscantypes` (function)__ 173 | - __`mplib.getstates` (function)__ 174 | - __`mplib.getstatistics` (function)__ 175 | - __`mplib.getstatus` (function)__ 176 | - __`mplib.gettolerance` (function)__ 177 | - __`mplib.gettype` (function)__ 178 | - __`mplib.gettypes` (function)__ 179 | - __`mplib.injectboolean` (function)__ 180 | - __`mplib.injectcmykcolor` (function)__ 181 | - __`mplib.injectcolor` (function)__ 182 | - __`mplib.injectinteger` (function)__ 183 | - __`mplib.injectnumber` (function)__ 184 | - __`mplib.injectnumeric` (function)__ 185 | - __`mplib.injectpair` (function)__ 186 | - __`mplib.injectpath` (function)__ 187 | - __`mplib.injectstring` (function)__ 188 | - __`mplib.injecttransform` (function)__ 189 | - __`mplib.injectvector` (function)__ 190 | - __`mplib.injectvectors` (function)__ 191 | - __`mplib.injectwhatever` (function)__ 192 | - __`mplib.new` (function)__ 193 | - __`mplib.newbytemap` (function)__ 194 | - __`mplib.peninfo` (function)__ 195 | - __`mplib.scanboolean` (function)__ 196 | - __`mplib.scancmykcolor` (function)__ 197 | - __`mplib.scancolor` (function)__ 198 | - __`mplib.scanexpression` (function)__ 199 | - __`mplib.scaninteger` (function)__ 200 | - __`mplib.scannext` (function)__ 201 | - __`mplib.scannumber` (function)__ 202 | - __`mplib.scannumeric` (function)__ 203 | - __`mplib.scanpair` (function)__ 204 | - __`mplib.scanpath` (function)__ 205 | - __`mplib.scanpen` (function)__ 206 | - __`mplib.scanproperty` (function)__ 207 | - __`mplib.scanstring` (function)__ 208 | - __`mplib.scansymbol` (function)__ 209 | - __`mplib.scantoken` (function)__ 210 | - __`mplib.scantransform` (function)__ 211 | - __`mplib.setbytemap` (function)__ 212 | - __`mplib.settolerance` (function)__ 213 | - __`mplib.showcontext` (function)__ 214 | - __`mplib.skiptoken` (function)__ 215 | - __`mplib.solvepath` (function)__ 216 | - __`mplib.version` (function)__ 217 | 218 | ### optional 219 | 220 | - *`optional.curl` (table)* 221 | - __`optional.curl.escape` (function)__ 222 | - __`optional.curl.fetch` (function)__ 223 | - __`optional.curl.getversion` (function)__ 224 | - __`optional.curl.initialize` (function)__ 225 | - __`optional.curl.unescape` (function)__ 226 | - *`optional.foreign` (table)* 227 | - __`optional.foreign.abivalues` (function)__ 228 | - __`optional.foreign.getbuffer` (function)__ 229 | - __`optional.foreign.initialize` (function)__ 230 | - __`optional.foreign.load` (function)__ 231 | - __`optional.foreign.newbuffer` (function)__ 232 | - __`optional.foreign.totable` (function)__ 233 | - __`optional.foreign.types` (function)__ 234 | - *`optional.ghostscript` (table)* 235 | - __`optional.ghostscript.execute` (function)__ 236 | - __`optional.ghostscript.initialize` (function)__ 237 | - *`optional.graphicsmagick` (table)* 238 | - __`optional.graphicsmagick.execute` (function)__ 239 | - __`optional.graphicsmagick.getnoisetypes` (function)__ 240 | - __`optional.graphicsmagick.initialize` (function)__ 241 | - *`optional.hb` (table)* 242 | - __`optional.hb.getshapers` (function)__ 243 | - __`optional.hb.getversion` (function)__ 244 | - __`optional.hb.initialize` (function)__ 245 | - __`optional.hb.loadfont` (function)__ 246 | - __`optional.hb.shapestring` (function)__ 247 | - *`optional.imagemagick` (table)* 248 | - __`optional.imagemagick.execute` (function)__ 249 | - __`optional.imagemagick.initialize` (function)__ 250 | - *`optional.kpse` (table)* 251 | - __`optional.kpse.expand_braces` (function)__ 252 | - __`optional.kpse.expand_path` (function)__ 253 | - __`optional.kpse.expand_var` (function)__ 254 | - __`optional.kpse.find_file` (function)__ 255 | - __`optional.kpse.find_files` (function)__ 256 | - __`optional.kpse.get_file_types` (function)__ 257 | - __`optional.kpse.initialize` (function)__ 258 | - __`optional.kpse.readable_file` (function)__ 259 | - __`optional.kpse.set_program_name` (function)__ 260 | - __`optional.kpse.var_value` (function)__ 261 | - *`optional.library` (table)* 262 | - __`optional.library.load` (function)__ 263 | - *`optional.lz4` (table)* 264 | - __`optional.lz4.compress` (function)__ 265 | - __`optional.lz4.decompresssize` (function)__ 266 | - __`optional.lz4.framecompress` (function)__ 267 | - __`optional.lz4.framedecompress` (function)__ 268 | - __`optional.lz4.initialize` (function)__ 269 | - *`optional.lzma` (table)* 270 | - __`optional.lzma.compress` (function)__ 271 | - __`optional.lzma.decompress` (function)__ 272 | - __`optional.lzma.initialize` (function)__ 273 | - *`optional.lzo` (table)* 274 | - __`optional.lzo.compress` (function)__ 275 | - __`optional.lzo.decompresssize` (function)__ 276 | - __`optional.lzo.initialize` (function)__ 277 | - *`optional.mujs` (table)* 278 | - __`optional.mujs.dofile` (function)__ 279 | - __`optional.mujs.execute` (function)__ 280 | - __`optional.mujs.initialize` (function)__ 281 | - __`optional.mujs.reset` (function)__ 282 | - __`optional.mujs.setclosefile` (function)__ 283 | - __`optional.mujs.setconsole` (function)__ 284 | - __`optional.mujs.setfindfile` (function)__ 285 | - __`optional.mujs.setopenfile` (function)__ 286 | - __`optional.mujs.setreadfile` (function)__ 287 | - __`optional.mujs.setseekfile` (function)__ 288 | - *`optional.mysql` (table)* 289 | - __`optional.mysql.close` (function)__ 290 | - __`optional.mysql.execute` (function)__ 291 | - __`optional.mysql.getmessage` (function)__ 292 | - __`optional.mysql.initialize` (function)__ 293 | - __`optional.mysql.open` (function)__ 294 | - *`optional.openssl` (table)* 295 | - __`optional.openssl.getversion` (function)__ 296 | - __`optional.openssl.initialize` (function)__ 297 | - __`optional.openssl.sign` (function)__ 298 | - __`optional.openssl.verify` (function)__ 299 | - *`optional.postgress` (table)* 300 | - __`optional.postgress.close` (function)__ 301 | - __`optional.postgress.execute` (function)__ 302 | - __`optional.postgress.getmessage` (function)__ 303 | - __`optional.postgress.initialize` (function)__ 304 | - __`optional.postgress.open` (function)__ 305 | - *`optional.sqlite` (table)* 306 | - __`optional.sqlite.close` (function)__ 307 | - __`optional.sqlite.execute` (function)__ 308 | - __`optional.sqlite.getmessage` (function)__ 309 | - __`optional.sqlite.initialize` (function)__ 310 | - __`optional.sqlite.open` (function)__ 311 | - *`optional.zint` (table)* 312 | - __`optional.zint.execute` (function)__ 313 | - __`optional.zint.initialize` (function)__ 314 | - *`optional.zstd` (table)* 315 | - __`optional.zstd.compress` (function)__ 316 | - __`optional.zstd.decompress` (function)__ 317 | - __`optional.zstd.initialize` (function)__ 318 | 319 | ### pdfdecode 320 | 321 | 322 | ### pdfe 323 | 324 | - __`pdfe.arraytotable` (function)__ 325 | - __`pdfe.close` (function)__ 326 | - __`pdfe.closestream` (function)__ 327 | - __`pdfe.dictionarytotable` (function)__ 328 | - __`pdfe.getarray` (function)__ 329 | - __`pdfe.getboolean` (function)__ 330 | - __`pdfe.getbox` (function)__ 331 | - __`pdfe.getcatalog` (function)__ 332 | - __`pdfe.getdictionary` (function)__ 333 | - __`pdfe.getencodingvalues` (function)__ 334 | - __`pdfe.getfieldtypes` (function)__ 335 | - __`pdfe.getfromarray` (function)__ 336 | - __`pdfe.getfromdictionary` (function)__ 337 | - __`pdfe.getfromobject` (function)__ 338 | - __`pdfe.getfromreference` (function)__ 339 | - __`pdfe.getfromstream` (function)__ 340 | - __`pdfe.getinfo` (function)__ 341 | - __`pdfe.getinteger` (function)__ 342 | - __`pdfe.getmemoryusage` (function)__ 343 | - __`pdfe.getname` (function)__ 344 | - __`pdfe.getnofobjects` (function)__ 345 | - __`pdfe.getnofpages` (function)__ 346 | - __`pdfe.getnumber` (function)__ 347 | - __`pdfe.getobjectrange` (function)__ 348 | - __`pdfe.getpage` (function)__ 349 | - __`pdfe.getpages` (function)__ 350 | - __`pdfe.getpermissions` (function)__ 351 | - __`pdfe.getsize` (function)__ 352 | - __`pdfe.getstatus` (function)__ 353 | - __`pdfe.getstatusvalues` (function)__ 354 | - __`pdfe.getstream` (function)__ 355 | - __`pdfe.getstring` (function)__ 356 | - __`pdfe.gettrailer` (function)__ 357 | - __`pdfe.getversion` (function)__ 358 | - __`pdfe.new` (function)__ 359 | - __`pdfe.open` (function)__ 360 | - __`pdfe.openfile` (function)__ 361 | - __`pdfe.openstream` (function)__ 362 | - __`pdfe.pagestotable` (function)__ 363 | - __`pdfe.readfromstream` (function)__ 364 | - __`pdfe.readwholestream` (function)__ 365 | - __`pdfe.type` (function)__ 366 | - __`pdfe.unencrypt` (function)__ 367 | 368 | ### pngdecode 369 | 370 | - __`pngdecode.applyfilter` (function)__ 371 | - __`pngdecode.expand` (function)__ 372 | - __`pngdecode.interlace` (function)__ 373 | - __`pngdecode.makemask` (function)__ 374 | - __`pngdecode.splitmask` (function)__ 375 | - __`pngdecode.tocmyk` (function)__ 376 | - __`pngdecode.tomask` (function)__ 377 | 378 | ### posit 379 | 380 | - __`posit.NaN` (function)__ 381 | - __`posit.NaR` (function)__ 382 | - __`posit.__add` (function)__ 383 | - __`posit.__band` (function)__ 384 | - __`posit.__bor` (function)__ 385 | - __`posit.__bxor` (function)__ 386 | - __`posit.__div` (function)__ 387 | - __`posit.__eq` (function)__ 388 | - `posit.__index` (table) 389 | - __`posit.__le` (function)__ 390 | - __`posit.__lt` (function)__ 391 | - __`posit.__mul` (function)__ 392 | - `posit.__name` (string) 393 | - __`posit.__pow` (function)__ 394 | - __`posit.__shl` (function)__ 395 | - __`posit.__shr` (function)__ 396 | - __`posit.__sub` (function)__ 397 | - __`posit.__tostring` (function)__ 398 | - __`posit.__unm` (function)__ 399 | - __`posit.abs` (function)__ 400 | - __`posit.acos` (function)__ 401 | - __`posit.asin` (function)__ 402 | - __`posit.atan` (function)__ 403 | - __`posit.band` (function)__ 404 | - __`posit.bor` (function)__ 405 | - __`posit.bxor` (function)__ 406 | - __`posit.ceil` (function)__ 407 | - __`posit.conj` (function)__ 408 | - __`posit.copy` (function)__ 409 | - __`posit.cos` (function)__ 410 | - __`posit.exp` (function)__ 411 | - __`posit.exp2` (function)__ 412 | - __`posit.expand` (function)__ 413 | - __`posit.floor` (function)__ 414 | - __`posit.frombyte` (function)__ 415 | - __`posit.fromchar` (function)__ 416 | - __`posit.fromposit` (function)__ 417 | - __`posit.integer` (function)__ 418 | - __`posit.log` (function)__ 419 | - __`posit.log10` (function)__ 420 | - __`posit.log1p` (function)__ 421 | - __`posit.log2` (function)__ 422 | - __`posit.logb` (function)__ 423 | - __`posit.max` (function)__ 424 | - __`posit.min` (function)__ 425 | - __`posit.modf` (function)__ 426 | - __`posit.new` (function)__ 427 | - __`posit.pow` (function)__ 428 | - __`posit.rotate` (function)__ 429 | - __`posit.round` (function)__ 430 | - __`posit.rounded` (function)__ 431 | - __`posit.shift` (function)__ 432 | - __`posit.sin` (function)__ 433 | - __`posit.sqrt` (function)__ 434 | - __`posit.tan` (function)__ 435 | - __`posit.tobyte` (function)__ 436 | - __`posit.tochar` (function)__ 437 | - __`posit.tonumber` (function)__ 438 | - __`posit.toposit` (function)__ 439 | - __`posit.tostring` (function)__ 440 | 441 | ### potrace 442 | 443 | - __`potrace.free` (function)__ 444 | - __`potrace.getnewfields` (function)__ 445 | - __`potrace.getpolicyvalues` (function)__ 446 | - __`potrace.getprocessfields` (function)__ 447 | - __`potrace.new` (function)__ 448 | - __`potrace.process` (function)__ 449 | - __`potrace.totable` (function)__ 450 | 451 | ### qrcodegen 452 | 453 | - __`qrcodegen.generate` (function)__ 454 | 455 | ### serial 456 | 457 | - __`serial.__gc` (function)__ 458 | - `serial.__index` (table) 459 | - `serial.__name` (string) 460 | - __`serial.__tostring` (function)__ 461 | - __`serial.close` (function)__ 462 | - __`serial.open` (function)__ 463 | - __`serial.send` (function)__ 464 | - __`serial.tostring` (function)__ 465 | - __`serial.write` (function)__ 466 | 467 | ### sha2 468 | 469 | - __`sha2.HEX256` (function)__ 470 | - __`sha2.HEX384` (function)__ 471 | - __`sha2.HEX512` (function)__ 472 | - __`sha2.digest256` (function)__ 473 | - __`sha2.digest384` (function)__ 474 | - __`sha2.digest512` (function)__ 475 | - __`sha2.hex256` (function)__ 476 | - __`sha2.hex384` (function)__ 477 | - __`sha2.hex512` (function)__ 478 | - __`sha2.sum256` (function)__ 479 | - __`sha2.sum384` (function)__ 480 | - __`sha2.sum512` (function)__ 481 | 482 | ### sio 483 | 484 | - __`sio.read2dot14` (function)__ 485 | - __`sio.readbytes` (function)__ 486 | - __`sio.readbytetable` (function)__ 487 | - __`sio.readcardinal1` (function)__ 488 | - __`sio.readcardinal1le` (function)__ 489 | - __`sio.readcardinal2` (function)__ 490 | - __`sio.readcardinal2le` (function)__ 491 | - __`sio.readcardinal3` (function)__ 492 | - __`sio.readcardinal3le` (function)__ 493 | - __`sio.readcardinal4` (function)__ 494 | - __`sio.readcardinal4le` (function)__ 495 | - __`sio.readcardinaltable` (function)__ 496 | - __`sio.readcline` (function)__ 497 | - __`sio.readcstring` (function)__ 498 | - __`sio.readfixed2` (function)__ 499 | - __`sio.readfixed4` (function)__ 500 | - __`sio.readinteger1` (function)__ 501 | - __`sio.readinteger1le` (function)__ 502 | - __`sio.readinteger2` (function)__ 503 | - __`sio.readinteger2le` (function)__ 504 | - __`sio.readinteger3` (function)__ 505 | - __`sio.readinteger3le` (function)__ 506 | - __`sio.readinteger4` (function)__ 507 | - __`sio.readinteger4le` (function)__ 508 | - __`sio.readintegertable` (function)__ 509 | - __`sio.tocardinal1` (function)__ 510 | - __`sio.tocardinal1le` (function)__ 511 | - __`sio.tocardinal2` (function)__ 512 | - __`sio.tocardinal2le` (function)__ 513 | - __`sio.tocardinal3` (function)__ 514 | - __`sio.tocardinal3le` (function)__ 515 | - __`sio.tocardinal4` (function)__ 516 | - __`sio.tocardinal4le` (function)__ 517 | 518 | ### socket 519 | 520 | - `socket._SETSIZE` (number) 521 | - `socket._SOCKETINVALID` (number) 522 | - `socket._VERSION` (string) 523 | - __`socket.__unload` (function)__ 524 | - __`socket.connect` (function)__ 525 | - *`socket.dns` (table)* 526 | - __`socket.dns.getaddrinfo` (function)__ 527 | - __`socket.dns.gethostname` (function)__ 528 | - __`socket.dns.getnameinfo` (function)__ 529 | - __`socket.dns.tohostname` (function)__ 530 | - __`socket.dns.toip` (function)__ 531 | - __`socket.gettime` (function)__ 532 | - __`socket.newtry` (function)__ 533 | - __`socket.protect` (function)__ 534 | - __`socket.select` (function)__ 535 | - __`socket.skip` (function)__ 536 | - __`socket.sleep` (function)__ 537 | - __`socket.tcp` (function)__ 538 | - __`socket.tcp4` (function)__ 539 | - __`socket.tcp6` (function)__ 540 | 541 | ### sparse 542 | 543 | - __`sparse.concat` (function)__ 544 | - __`sparse.get` (function)__ 545 | - __`sparse.max` (function)__ 546 | - __`sparse.min` (function)__ 547 | - __`sparse.new` (function)__ 548 | - __`sparse.range` (function)__ 549 | - __`sparse.restore` (function)__ 550 | - __`sparse.set` (function)__ 551 | - __`sparse.traverse` (function)__ 552 | - __`sparse.wipe` (function)__ 553 | 554 | ### status 555 | 556 | - __`status.list` (function)__ 557 | 558 | ### texconfig 559 | 560 | 561 | ### texio 562 | 563 | - __`texio.write` (function)__ 564 | - __`texio.write_nl` (function)__ 565 | - __`texio.writenl` (function)__ 566 | - __`texio.writeselector` (function)__ 567 | - __`texio.writeselectorlf` (function)__ 568 | - __`texio.writeselectornl` (function)__ 569 | 570 | ### vector 571 | 572 | - __`vector.add` (function)__ 573 | - __`vector.append` (function)__ 574 | - __`vector.ceiling` (function)__ 575 | - __`vector.concat` (function)__ 576 | - *`vector.contour` (table)* 577 | - __`vector.contour.average` (function)__ 578 | - __`vector.contour.checkoverlap` (function)__ 579 | - __`vector.contour.collectoverlap` (function)__ 580 | - __`vector.contour.getarea` (function)__ 581 | - __`vector.contour.getmesh` (function)__ 582 | - __`vector.contour.sort` (function)__ 583 | - __`vector.contour.triangulate` (function)__ 584 | - __`vector.copy` (function)__ 585 | - __`vector.crossproduct` (function)__ 586 | - __`vector.delete` (function)__ 587 | - __`vector.determinant` (function)__ 588 | - __`vector.div` (function)__ 589 | - __`vector.equal` (function)__ 590 | - __`vector.exchange` (function)__ 591 | - __`vector.floor` (function)__ 592 | - __`vector.get` (function)__ 593 | - __`vector.getdimensions` (function)__ 594 | - __`vector.getepsilon` (function)__ 595 | - __`vector.getrc` (function)__ 596 | - __`vector.getrow` (function)__ 597 | - __`vector.getstacking` (function)__ 598 | - __`vector.gettype` (function)__ 599 | - __`vector.homogenize` (function)__ 600 | - __`vector.identity` (function)__ 601 | - __`vector.inner` (function)__ 602 | - __`vector.insert` (function)__ 603 | - __`vector.inverse` (function)__ 604 | - __`vector.ismesh` (function)__ 605 | - __`vector.issingular` (function)__ 606 | - __`vector.isvector` (function)__ 607 | - __`vector.iszero` (function)__ 608 | - *`vector.mesh` (table)* 609 | - __`vector.mesh.get` (function)__ 610 | - __`vector.mesh.getdimensions` (function)__ 611 | - __`vector.mesh.ismesh` (function)__ 612 | - __`vector.mesh.new` (function)__ 613 | - __`vector.mesh.set` (function)__ 614 | - __`vector.mesh.tostring` (function)__ 615 | - __`vector.mesh.totable` (function)__ 616 | - __`vector.mesh.type` (function)__ 617 | - __`vector.mul` (function)__ 618 | - __`vector.negate` (function)__ 619 | - __`vector.new` (function)__ 620 | - __`vector.normalize` (function)__ 621 | - __`vector.onecolumn` (function)__ 622 | - __`vector.onerow` (function)__ 623 | - __`vector.product` (function)__ 624 | - __`vector.remove` (function)__ 625 | - __`vector.replace` (function)__ 626 | - __`vector.round` (function)__ 627 | - __`vector.rowechelon` (function)__ 628 | - __`vector.set` (function)__ 629 | - __`vector.setnext` (function)__ 630 | - __`vector.setrc` (function)__ 631 | - __`vector.setstacking` (function)__ 632 | - __`vector.slice` (function)__ 633 | - __`vector.sub` (function)__ 634 | - __`vector.swap` (function)__ 635 | - __`vector.tostring` (function)__ 636 | - __`vector.totable` (function)__ 637 | - __`vector.transpose` (function)__ 638 | - __`vector.truncate` (function)__ 639 | - __`vector.type` (function)__ 640 | 641 | ### xcomplex 642 | 643 | - __`xcomplex.I` (function)__ 644 | - __`xcomplex.__add` (function)__ 645 | - __`xcomplex.__div` (function)__ 646 | - __`xcomplex.__eq` (function)__ 647 | - `xcomplex.__index` (table) 648 | - __`xcomplex.__mul` (function)__ 649 | - `xcomplex.__name` (string) 650 | - __`xcomplex.__pow` (function)__ 651 | - __`xcomplex.__sub` (function)__ 652 | - __`xcomplex.__tostring` (function)__ 653 | - __`xcomplex.__unm` (function)__ 654 | - __`xcomplex.abs` (function)__ 655 | - __`xcomplex.acos` (function)__ 656 | - __`xcomplex.acosh` (function)__ 657 | - __`xcomplex.arg` (function)__ 658 | - __`xcomplex.asin` (function)__ 659 | - __`xcomplex.asinh` (function)__ 660 | - __`xcomplex.atan` (function)__ 661 | - __`xcomplex.atanh` (function)__ 662 | - __`xcomplex.conj` (function)__ 663 | - __`xcomplex.cos` (function)__ 664 | - __`xcomplex.cosh` (function)__ 665 | - __`xcomplex.dawson` (function)__ 666 | - __`xcomplex.erf` (function)__ 667 | - __`xcomplex.erfc` (function)__ 668 | - __`xcomplex.erfcx` (function)__ 669 | - __`xcomplex.erfi` (function)__ 670 | - __`xcomplex.exp` (function)__ 671 | - __`xcomplex.i` (function)__ 672 | - __`xcomplex.imag` (function)__ 673 | - __`xcomplex.log` (function)__ 674 | - __`xcomplex.new` (function)__ 675 | - __`xcomplex.pow` (function)__ 676 | - __`xcomplex.proj` (function)__ 677 | - __`xcomplex.real` (function)__ 678 | - __`xcomplex.sin` (function)__ 679 | - __`xcomplex.sinh` (function)__ 680 | - __`xcomplex.sqrt` (function)__ 681 | - __`xcomplex.tan` (function)__ 682 | - __`xcomplex.tanh` (function)__ 683 | - __`xcomplex.topair` (function)__ 684 | - __`xcomplex.tostring` (function)__ 685 | - __`xcomplex.totable` (function)__ 686 | - __`xcomplex.voigt` (function)__ 687 | - __`xcomplex.voigt_hwhm` (function)__ 688 | 689 | ### xdecimal 690 | 691 | - __`xdecimal.__add` (function)__ 692 | - __`xdecimal.__band` (function)__ 693 | - __`xdecimal.__bor` (function)__ 694 | - __`xdecimal.__bxor` (function)__ 695 | - __`xdecimal.__div` (function)__ 696 | - __`xdecimal.__eq` (function)__ 697 | - __`xdecimal.__idiv` (function)__ 698 | - `xdecimal.__index` (table) 699 | - __`xdecimal.__le` (function)__ 700 | - __`xdecimal.__lt` (function)__ 701 | - __`xdecimal.__mod` (function)__ 702 | - __`xdecimal.__mul` (function)__ 703 | - `xdecimal.__name` (string) 704 | - __`xdecimal.__pow` (function)__ 705 | - __`xdecimal.__shl` (function)__ 706 | - __`xdecimal.__shr` (function)__ 707 | - __`xdecimal.__sub` (function)__ 708 | - __`xdecimal.__tostring` (function)__ 709 | - __`xdecimal.__unm` (function)__ 710 | - __`xdecimal.abs` (function)__ 711 | - __`xdecimal.band` (function)__ 712 | - __`xdecimal.bor` (function)__ 713 | - __`xdecimal.bxor` (function)__ 714 | - __`xdecimal.conj` (function)__ 715 | - __`xdecimal.copy` (function)__ 716 | - __`xdecimal.exp` (function)__ 717 | - __`xdecimal.getprecision` (function)__ 718 | - __`xdecimal.ln` (function)__ 719 | - __`xdecimal.log` (function)__ 720 | - __`xdecimal.max` (function)__ 721 | - __`xdecimal.min` (function)__ 722 | - __`xdecimal.minus` (function)__ 723 | - __`xdecimal.new` (function)__ 724 | - __`xdecimal.plus` (function)__ 725 | - __`xdecimal.pow` (function)__ 726 | - __`xdecimal.rotate` (function)__ 727 | - __`xdecimal.setprecision` (function)__ 728 | - __`xdecimal.shift` (function)__ 729 | - __`xdecimal.sqrt` (function)__ 730 | - __`xdecimal.toengstring` (function)__ 731 | - __`xdecimal.tonumber` (function)__ 732 | - __`xdecimal.tostring` (function)__ 733 | - __`xdecimal.trim` (function)__ 734 | 735 | ### xmath 736 | 737 | - __`xmath.acos` (function)__ 738 | - __`xmath.acosh` (function)__ 739 | - __`xmath.asin` (function)__ 740 | - __`xmath.asinh` (function)__ 741 | - __`xmath.atan` (function)__ 742 | - __`xmath.atan2` (function)__ 743 | - __`xmath.atanh` (function)__ 744 | - __`xmath.cbrt` (function)__ 745 | - __`xmath.ceil` (function)__ 746 | - __`xmath.copysign` (function)__ 747 | - __`xmath.cos` (function)__ 748 | - __`xmath.cosh` (function)__ 749 | - __`xmath.deg` (function)__ 750 | - __`xmath.erf` (function)__ 751 | - __`xmath.erfc` (function)__ 752 | - __`xmath.exp` (function)__ 753 | - __`xmath.exp2` (function)__ 754 | - __`xmath.expm1` (function)__ 755 | - __`xmath.fabs` (function)__ 756 | - __`xmath.fdim` (function)__ 757 | - __`xmath.floor` (function)__ 758 | - __`xmath.fma` (function)__ 759 | - __`xmath.fmax` (function)__ 760 | - __`xmath.fmin` (function)__ 761 | - __`xmath.fmod` (function)__ 762 | - __`xmath.frexp` (function)__ 763 | - __`xmath.gamma` (function)__ 764 | - __`xmath.hypot` (function)__ 765 | - `xmath.inf` (number) 766 | - __`xmath.isfinite` (function)__ 767 | - __`xmath.isinf` (function)__ 768 | - __`xmath.isnan` (function)__ 769 | - __`xmath.isnormal` (function)__ 770 | - __`xmath.j0` (function)__ 771 | - __`xmath.j1` (function)__ 772 | - __`xmath.jn` (function)__ 773 | - __`xmath.ldexp` (function)__ 774 | - __`xmath.lgamma` (function)__ 775 | - __`xmath.log` (function)__ 776 | - __`xmath.log10` (function)__ 777 | - __`xmath.log1p` (function)__ 778 | - __`xmath.log2` (function)__ 779 | - __`xmath.logb` (function)__ 780 | - __`xmath.modf` (function)__ 781 | - `xmath.nan` (number) 782 | - __`xmath.nearbyint` (function)__ 783 | - __`xmath.nextafter` (function)__ 784 | - `xmath.pi` (number) 785 | - __`xmath.pow` (function)__ 786 | - __`xmath.rad` (function)__ 787 | - __`xmath.remainder` (function)__ 788 | - __`xmath.remquo` (function)__ 789 | - __`xmath.round` (function)__ 790 | - __`xmath.scalbn` (function)__ 791 | - __`xmath.sin` (function)__ 792 | - __`xmath.sinh` (function)__ 793 | - __`xmath.sqrt` (function)__ 794 | - __`xmath.tan` (function)__ 795 | - __`xmath.tanh` (function)__ 796 | - __`xmath.tgamma` (function)__ 797 | - __`xmath.trunc` (function)__ 798 | - __`xmath.y0` (function)__ 799 | - __`xmath.y1` (function)__ 800 | - __`xmath.yn` (function)__ 801 | 802 | ### xzip 803 | 804 | - __`xzip.adler32` (function)__ 805 | - __`xzip.compress` (function)__ 806 | - __`xzip.compresssize` (function)__ 807 | - __`xzip.crc32` (function)__ 808 | - __`xzip.decompress` (function)__ 809 | - __`xzip.decompresssize` (function)__ 810 | --------------------------------------------------------------------------------