diff options
| author | Elie Roux <elie.roux@telecom-bretagne.eu> | 2009-04-17 11:46:44 +0200 | 
|---|---|---|
| committer | Elie Roux <elie.roux@telecom-bretagne.eu> | 2009-04-17 11:46:44 +0200 | 
| commit | 17ff8d11d679d6e241537d8ad3cdf35e4fc21589 (patch) | |
| tree | 88ace697a9084bfc44d11e1bb21a9df692f5634c | |
| parent | 14ab4ed94ba4a81c8357b5717db10d7e6299ae35 (diff) | |
| download | lualibs-17ff8d11d679d6e241537d8ad3cdf35e4fc21589.tar.gz | |
cleanup and documentation of luaextra
| -rw-r--r-- | luaextra.dtx (renamed from luaextra.lua) | 493 | 
1 files changed, 426 insertions, 67 deletions
diff --git a/luaextra.lua b/luaextra.dtx index e292d70..7a55d76 100644 --- a/luaextra.lua +++ b/luaextra.dtx @@ -1,41 +1,181 @@ +% \iffalse meta-comment +% +% Copyright (C) 2009 by PRAGMA ADE / ConTeXt Development Team +% +% See ConTeXt's mreadme.pdf for the license. +% +% This work consists of the main source file luaextra.dtx +% and the derived file luaextra.lua. +% +% Unpacking and documentation: +%    pdftex luaextra.dtx +% +%    The class ltxdoc loads the configuration file ltxdoc.cfg +%    if available. Here you can specify further options, e.g. +%    use A4 as paper format: +%       \PassOptionsToClass{a4paper}{article} +% +% +% +%<*ignore> +\begingroup + +\input docstrip.tex +\Msg{************************************************************************} +\Msg{* Installation} +\Msg{* Package: luaextra 2009/03/19 v0.91 Lua additional functions.} +\Msg{************************************************************************} + +\keepsilent +\askforoverwritefalse + +\let\MetaPrefix\relax + +\preamble +This is a generated file. + +Copyright (C) 2009 by PRAGMA ADE / ConTeXt Development Team + +See ConTeXt's mreadme.pdf for the license. + +This work consists of the main source file luaextra.dtx +and the derived file luaextra.lua. + +\endpreamble + +\let\MetaPrefix\DoubleperCent + +\generate{% +  \file{luaextra.drv}{\from{luaextra.dtx}{driver}}% +} + +% The following hacks are to generate a lua file with lua comments starting by -- instead of %% + +\def\MetaPrefix{-- } + +\def\luapostamble{% +  \MetaPrefix^^J% +  \MetaPrefix\space End of File `\outFileName'.% +} + +\def\currentpostamble{\luapostamble}% + +\generate{% +  \usedir{luatex/lua/luaextra}% +  \file{luaextra.lua}{\from{luaextra.dtx}{lua}}% +} + +\obeyspaces +\Msg{************************************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the following} +\Msg{* files into a directory searched by TeX:} +\Msg{*} +\Msg{*     luaextra.lua} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*} +\Msg{************************************************************************} + +\endgroup +%</ignore> +% \iffalse +%<driver> +%<driver>\NeedsTeXFormat{LaTeX2e} +%<driver>\ProvidesPackage{luaextra.sty} +%<driver>  [2009/04/15 v0.91 Lua additional functions.] +%<driver> +% \fi +%<*driver> +\documentclass{ltxdoc} +\EnableCrossrefs +\CodelineIndex +\begin{document} +  \DocInput{luaextra.dtx}% +\end{document} +%</driver> +% \fi +% \CheckSum{0} +% +% \CharacterTable +%  {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z +%   Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z +%   Digits        \0\1\2\3\4\5\6\7\8\9 +%   Exclamation   \!     Double quote  \"     Hash (number) \# +%   Dollar        \$     Percent       \%     Ampersand     \& +%   Acute accent  \'     Left paren    \(     Right paren   \) +%   Asterisk      \*     Plus          \+     Comma         \, +%   Minus         \-     Point         \.     Solidus       \/ +%   Colon         \:     Semicolon     \;     Less than     \< +%   Equals        \=     Greater than  \>     Question mark \? +%   Commercial at \@     Left bracket  \[     Backslash     \\ +%   Right bracket \]     Circumflex    \^     Underscore    \_ +%   Grave accent  \`     Left brace    \{     Vertical bar  \| +%   Right brace   \}     Tilde         \~} +% +% \GetFileInfo{luaextra.drv} +% +% \title{The \textsf{luaextra} package} +% \date{2009/04/15 v0.91} +% \author{Elie Roux \\ \texttt{elie.roux@telecom-bretagne.eu}} +% +% \maketitle +% +% \begin{abstract} +% Additional lua functions taken from the libs of Con\TeX t. +% \end{abstract} +% +% \section{Overview} +% +% Lua is a very minimal language, and it does not have a lot of built-in functions. Some functions will certainly be needed by a lot of packages. Instead of making each of them implement these functions, the aim of this file is to provide a minimal set of functions. All functions are taken from Con\TeX t libraries. +% +% There are some differences with the Con\TeX t funtions though, especially on names: for example the \texttt{file.*} funtions are renamed in \texttt{fpath.*}. It seems more logical as they deal with file paths, not files. Also the \texttt{file.is\_readable} and \texttt{file.is\_writable} are renamed \texttt{lfs.is\_readable} and \texttt{lfs.is\_writable}. +% +% If you use a function you think is missing in this file, please tell the maintainer. +% +% \texttt{Warning:} Even if the names will certainly remain the same, some implementations may differ, and some functions might appear or dissapear. As Lua\TeX\ is not stable, this file is not neither. +% +% All functions are described in this document, but the one of the functions you'll use most will certainly be \texttt{table.serialize} (also named \texttt{table.tostring}) that takes a table and returns an intented string describing the table. It describes the table so that Lua\TeX\ can read it again as a table. You can do a lot of things with this functions, like printing a table for debugging, or saving a table into a file. Functions are also converted into bytecode to be saved. +% +% \section{\texttt{luaextra.lua}} +% +% \iffalse +%<*lua> +% \fi +% +%    \begin{macrocode}  local module = {      name          = "luaextra", -    version       = 0.9, -    date          = "2009/03/19", -    description   = "Additions to the default lua library.", +    version       = 0.91, +    date          = "2009/04/15", +    description   = "Lua additional functions.",      author        = "Hans Hagen, PRAGMA-ADE, Hasselt NL & Elie Roux",      copyright     = "PRAGMA ADE / ConTeXt Development Team", -    license       = "GPLv2", +    license       = "See ConTeXt's mreadme.pdf for the license",  }  luatextra.provides_module(module) -string.chr_to_esc = { -    ["%"] = "%%", -    ["."] = "%.", ["*"] = "%*", -    ["+"] = "%+", ["-"] = "%-", -    ["^"] = "%^", ["$"] = "%$", -    ["["] = "%[", ["]"] = "%]", -    ["("] = "%(", [")"] = "%)", -    ["{"] = "%{", ["}"] = "%}" -} - -function string:esc() -- variant 2 -    return (self:gsub("(.)",string.chr_to_esc)) -end - -function string:count(pattern) -    local n = 0 -    for _ in self:gmatch(pattern) do -        n = n + 1 -    end -    return n -end +%    \end{macrocode} +% +% \begin{macro}{string:stripspaces} +% +% A function to strip the spaces at the beginning and at the end of a string. +% +%    \begin{macrocode}  function string:stripspaces()      return (self:gsub("^%s*(.-)%s*$", "%1"))  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{string.is boolean} +% +% If the argument is a string describing a boolean, this function returns the boolean, otherwise it retuns nil. +% +%    \begin{macrocode} +  function string.is_boolean(str)      if type(str) == "string" then          if str == "true" or str == "yes" or str == "on" or str == "t" then @@ -47,13 +187,37 @@ function string.is_boolean(str)      return nil  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{string.is number} +% +% Returns true if the argument string is a number. +% +%    \begin{macrocode} +  function string.is_number(str)      return str:find("^[%-%+]?[%d]-%.?[%d+]$") == 1  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{lpeg.space and lpeg.newline} +% +% Two small helpers for \texttt{lpeg}, that will certainly be widely used: spaces and newlines. +% +%    \begin{macrocode} +  lpeg.space    = lpeg.S(" \t\f\v")  lpeg.newline  = lpeg.P("\r\n") + lpeg.P("\r") +lpeg.P("\n") +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.fastcopy} +% +% A function copying a table fastly. +% +%    \begin{macrocode} +  if not table.fastcopy then do      local type, pairs, getmetatable, setmetatable = type, pairs, getmetatable, setmetatable @@ -82,6 +246,14 @@ if not table.fastcopy then do  end end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.copy} +% +% A function copying a table in more cases than fastcopy, for example when a key is a table. +% +%    \begin{macrocode} +  if not table.copy then do      local type, pairs, getmetatable, setmetatable = type, pairs, getmetatable, setmetatable @@ -119,6 +291,14 @@ if not table.copy then do  end end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.serialize} +% +% A bunch of functions leading to \texttt{table.serialize}. +% +%    \begin{macrocode} +  function table.sortedkeys(tab)      local srt, kind = { }, 0 -- 0=unknown 1=string, 2=number 3=mixed      for key,_ in pairs(tab) do @@ -368,6 +548,14 @@ do  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.tohash} +% +% Returning a table with all values of the argument table as keys, and \texttt{false} as values. This is what we will call a hash. +% +%    \begin{macrocode} +  function table.tohash(t)      local h = { }      for _, v in pairs(t) do -- no ipairs here @@ -376,6 +564,14 @@ function table.tohash(t)      return h  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.fromhash} +% +% Returning a table built from a hash, with simple integer keys. +% +%    \begin{macrocode} +  function table.fromhash(t)      local h = { }      for k, v in pairs(t) do -- no ipairs here @@ -384,6 +580,14 @@ function table.fromhash(t)      return h  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.contains value} +% +% A function returning true if the value \texttt{val} is in the table \texttt{t}. +% +%    \begin{macrocode} +  function table.contains_value(t, val)      if t then          for k, v in pairs(t) do @@ -395,6 +599,14 @@ function table.contains_value(t, val)      return false  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.contains key} +% +% A function returning true if the key \texttt{key} is in the table \texttt{t} +% +%    \begin{macrocode} +  function table.contains_key(t, key)      if t then          for k, v in pairs(t) do @@ -406,6 +618,14 @@ function table.contains_key(t, key)      return false  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.value position} +% +% A function returning the position of a value in a table. This will be important to be able to remove a value. +% +%    \begin{macrocode} +  function table.value_position(t, val)      if t then          local i=1 @@ -419,6 +639,14 @@ function table.value_position(t, val)      return 0  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.key position} +% +% A function returning the position of a key in a table. +% +%    \begin{macrocode} +  function table.key_position(t, key)      if t then          local i=1 @@ -429,60 +657,79 @@ function table.key_position(t, key)              i = i+1          end      end -    return 0 +    return -1  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.remove value} +% +% Removes the first occurence of a value from a table. +% +%    \begin{macrocode} +  function table.remove_value(t, v) -    table.remove(t, table.value_position(t,v)) +    local p = table.value_position(t,v) +    if p ~= -1 then +        table.remove(t, table.value_position(t,v)) +    end  end -function table.remove_key(t, k) -    table.remove(t, table.key_position(t,k)) -end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.remove key} +% +% Removing a key from a table. +% +%    \begin{macrocode} -function table.reverse_hash(h) -    local r = { } -    for k,v in next, h do -        r[v] = string.lower(string.gsub(k," ","")) +function table.remove_key(t, k) +    local p = table.key_position(t,k) +    if p ~= -1 then +        table.remove(t, table.key_position(t,k))      end -    return r  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{table.is empty} +% +% Returns true if a table is empty. +% +%    \begin{macrocode} +  function table.is_empty(t)      return not t or not next(t)  end -function io.loaddata(filename) -    local f = io.open(filename,'rb') -    if f then -        local data = f:read('*all') -        f:close() -        return data -    else -        return nil -    end -end - -function io.savedata(filename,data,joiner) -    local f = io.open(filename, "wb") -    if f then -        if type(data) == "table" then -            f:write(table.join(data,joiner or "")) -        elseif type(data) == "function" then -            data(f) -        else -            f:write(data) -        end -        f:close() -    end -end +%    \end{macrocode} +% +%  \texttt{fpath} will contain all the file path manipulation functions. Some functions certainly need a little update or cleanup... +% +%    \begin{macrocode}  fpath = { } +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.removesuffix} +% +% A function to remove the suffix (extention) of a filename. +% +%    \begin{macrocode} +  function fpath.removesuffix(filename)      return filename:gsub("%.[%a%d]+$", "")  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.addsuffix} +% +% A function adding a suffix to a filename, except if it already has one. +% +%    \begin{macrocode} +  function fpath.addsuffix(filename, suffix)      if not filename:find("%.[%a%d]+$") then          return filename .. "." .. suffix @@ -491,6 +738,14 @@ function fpath.addsuffix(filename, suffix)      end  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.replacesuffix} +% +% A function replacing a suffix by a new one. +% +%    \begin{macrocode} +  function fpath.replacesuffix(filename, suffix)      if not filename:find("%.[%a%d]+$") then          return filename .. "." .. suffix @@ -499,10 +754,26 @@ function fpath.replacesuffix(filename, suffix)      end  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.dirname} +% +% A function returning the directory of a file path. +% +%    \begin{macrocode} +  function fpath.dirname(name)      return name:match("^(.+)[/\\].-$") or ""  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.basename} +% +% A function returning the basename (the name of the file, without the directories) of a file path. +% +%    \begin{macrocode} +  function fpath.basename(fname)      if not fname then          return nil @@ -510,17 +781,37 @@ function fpath.basename(fname)      return fname:match("^.+[/\\](.-)$") or fname  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.nameonly} +% +% Returning the basename of a file without the suffix. +% +%    \begin{macrocode} +  function fpath.nameonly(name)      return ((name:match("^.+[/\\](.-)$") or name):gsub("%..*$",""))  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.suffix} +% +% Returns the suffix of a file name. +% +%    \begin{macrocode} +  function fpath.suffix(name)      return name:match("^.+%.([^/\\]-)$") or  ""  end -function fpath.stripsuffix(name) -    return (name:gsub("%.[%a%d]+$","")) -end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.join} +% +% A function joining any number of arguments into a complete path. +% +%    \begin{macrocode}  function fpath.join(...)      local pth = table.concat({...},"/") @@ -536,6 +827,14 @@ function fpath.join(...)      return (pth:gsub("//+","/"))  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.split} +% +% A function returning a table with all directories from a filename. +% +%    \begin{macrocode} +  function fpath.split(str)      local t = { }      str = str:gsub("\\", "/") @@ -549,10 +848,26 @@ function fpath.split(str)      return t  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.normalize sep} +% +% A function to change directory separators to canonical ones (\texttt{/}). +% +%    \begin{macrocode} +  function fpath.normalize_sep(str)      return str:gsub("\\", "/")  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{fpath.localize sep} +% +% A function changing directory separators into local ones (\texttt{/} on Unix, |\| on Windows). +% +%    \begin{macrocode} +  function fpath.localize_sep(str)      if os.type == 'windows' or type == 'msdos' then          return str:gsub("/", "\\") @@ -561,11 +876,13 @@ function fpath.localize_sep(str)      end  end -function fpath.join(tab) -    return table.concat(tab,io.pathseparator) -- can have trailing // -end - --- should be made with lfs.attributes +%    \end{macrocode} +% +% \end{macro}\begin{macro}{lfs.is writable} +% +% Returns true if a file is writable. This function and the following ones are a bit too expensive, they should be made with |lfs.attributes|. +% +%    \begin{macrocode}  function lfs.is_writable(name)      local f = io.open(name, 'w') @@ -577,6 +894,14 @@ function lfs.is_writable(name)      end  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{lfs.is readable} +% +% Returns true if a file is readable. +% +%    \begin{macrocode} +  function lfs.is_readable(name)      local f = io.open(name,'r')      if f then @@ -587,20 +912,54 @@ function lfs.is_readable(name)      end  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{math.round} +% +% Returns the closest integer. +% +%    \begin{macrocode} +  if not math.round then      function math.round(x)          return math.floor(x + 0.5)      end  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{math.div} +% +% Returns the quotient of the euclidian division of n by m. +% +%    \begin{macrocode} +  if not math.div then      function math.div(n,m)          return floor(n/m)      end  end +%    \end{macrocode} +% +% \end{macro}\begin{macro}{math.mod} +% +% Returns the remainder of the euclidian division of n by m. +% +%    \begin{macrocode} +  if not math.mod then      function math.mod(n,m)          return n % m      end  end + +%    \end{macrocode} +% +% \end{macro} +% +% \iffalse +%</lua> +% \fi +% \Finale +\endinput  | 
