Skip to content

Commit

Permalink
Introduce longtabu example
Browse files Browse the repository at this point in the history
With some juicy (and equally useless) Lua code
  • Loading branch information
alexpovel committed Feb 17, 2021
1 parent d766fb6 commit 9e89214
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 0 deletions.
45 changes: 45 additions & 0 deletions chapters/backmatter.tex
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,51 @@ \section{More appendix}

\Blindtext

\section{Unprocessed data}
\label{ch:appendix_table}

This is also a good place to put unprocessed data, like \cref{tab:random_long}.

% All following long tables will have the following setting, which could make sense for
% the appendix.
\AtBeginEnvironment{longtabu}{\footnotesize}{}{}

\begin{longtabu}{%
% ATTENTION: the `tabu` package is unmaintained and a bunch of stuff doesn't work.
% See also https://github.com/tabu-issues-for-future-maintainer/tabu.
% Pretty bad situation but works okay enough, and we already use `tabu`/`longtable`
% anyway for the glossaries in `glossaries-extra`.
%
@{}% Remove superfluous left horizontal space
% NOTE: `X[c]{S}` columns, like in the `tabu` docs, do not really work, see also
% https://tex.stackexchange.com/q/70279/120853
S% `S` expects what `\num` would: a number
s% `s` expects what `\si` would: a unit
X[2, l]% double the width factor when computing automatic widths
X[1, l, $]% Dollar sign breaks my editor's syntax highlighting
@{}% Remove superfluous right horizontal space
}%
\caption[A \texttt{longtable} from the \ctanpackage{tabu} package]{
A \texttt{longtable} from the \ctanpackage{tabu} package.
It can break across pages but still have a caption.
The \ctanpackage{tabu} package allows automatic width scaling:
the table is as wide as the text automatically (which sometimes looks bad).
There are also automatic numbers (note the horizontal decimal point alignment), units (also from \ctanpackage{siunitx}, not \ctanpackage{tabu}) and math columns.
Note how the table rows are generated automatically and randomly, using Lua%
\label{tab:random_long}%
}\\
\toprule
Magnitude & Unit & Double-width text & \text{Math column} \\
\midrule
118.135 & \nano\meter & Foo & f-x=h\\
% The following rows look just like that but are generated:
\directlua{%
N_ROWS = 75
dofile("lib/lua/generate_random_table_rows.lua")
}
\bottomrule
\end{longtabu}
\chapter{Another appendix chapter}
More stuff can go into the next appendix chapter, for example algorithms and code.
Expand Down
4 changes: 4 additions & 0 deletions chapters/mainmatter/floats.tex
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,10 @@ \subsubsection{Large Floats}
\end{table}%
\end{landscape}

\paragraph{Very long tables}

See \cref{tab:random_long} in \cref{ch:appendix_table} for an example of a very large table (which does not float).

\subsubsection{Table Style}

In general, use the least ink possible to get your point across.
Expand Down
77 changes: 77 additions & 0 deletions lib/lua/generate_random_table_rows.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
--[[
The following import is not required since in LuaTeX's `\directlua` environment,
`texio` etc. is already available. However, this is nice to keep linters from
complaining about an undefined variable.
--]]
local texio = require("texio")
local tex = require("tex")

PREFIXES = {"", "kilo", "milli", "giga", "nano"}

UNITS = {"meter", "degreeCelsius", "kelvin", "gram", "bar", "pascal", "newton", "candela", "ampere", "ohm", "volt",
"watt"}

TEXTS = {"This is a longer text that will probably span multiple lines in the table because it is overly wide.",
"Hello World", "A", "B", "C", "Foo", "Bar", "Baz", "Yeet"}

MATH_OPS = {"+", "-", "/", "^"}
MATH_SYMBOLS = {"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", "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"}

-- Seed with `os.time()` for true randomness; keep a constant seed for
-- reproducibility:
RANDOM_SEED = RANDOM_SEED or os.time()
math.randomseed(RANDOM_SEED)

local function choice(table)
-- Imitating Python's `random.choice` to pick a random element from a table.
return table[math.random(#table)]
end

local function random_int(n_digits)
-- Returns a random integer with the specified number of digits
if n_digits < 1 then
-- `min` can be `0 <= min <= 1` from e.g. 10^(0 - 1), which cannot be fed to
-- `math.random` properly, so return early here.
return 0
end

local min = 10 ^ (n_digits - 1) -- e.g. 2 -> 10
local max = (10 ^ n_digits) - 1 -- e.g. 2 -> 100 - 1 -> 99
return math.random(min, max)
end

local function latex_table_row()
local max_n_digits_left, max_n_digits_right = 3, 3
local n_digits_left = math.random(0, max_n_digits_left)
local n_digits_right = math.random(0, max_n_digits_right)
local left, right = random_int(n_digits_left), random_int(n_digits_right)
-- We could do some super cool bit logic to achieve the desired floating decimal
-- points but I'm not smart enough, so cast to string like a monkey.
local number = left .. "." .. right

local prefix = choice(PREFIXES)
if prefix ~= "" then
-- Do not allow `\\` to pass, aka prefix is empty string
prefix = "\\" .. prefix
end
local unit = "\\" .. choice(UNITS)

local text = choice(TEXTS)

local math = choice(MATH_SYMBOLS) .. choice(MATH_OPS) .. choice(MATH_SYMBOLS) .. "=" .. choice(MATH_SYMBOLS)

local row_eol = "\\\\"
local column_sep = " & "
local row = table.concat({number, prefix .. unit, text, math}, column_sep) .. row_eol
texio.write_nl("Generated new table row: " .. row)
return row
end

-- See if defined, else fallback to default:
N_ROWS = N_ROWS or 75

for _ = 1, N_ROWS do
tex.print(latex_table_row())
end

0 comments on commit 9e89214

Please sign in to comment.