Skip to content

Commit

Permalink
Switch to Lua implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
alexpovel committed Oct 29, 2020
1 parent 9c0943c commit 6d0cd7e
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 77 deletions.
55 changes: 0 additions & 55 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,53 +19,6 @@ default:
# only:
# - tags

# Define some stages so to get rid of 'Test' as default:
stages:
- prepare
- build

insert_git_metadata:
stage: prepare
script:
# Declare associative (-A) array with predefined GitLab CI variables.
# The keys correspond to the command names found in the LaTeX code:
- |
declare -A GITINFO=(
[GitRefName]=$CI_COMMIT_REF_NAME
[GitShortSHA]=$CI_COMMIT_SHORT_SHA
)
# Iterate over array and replace the LaTeX commands,
# e.g. \newcommand*{\GitRefName}{n.a.},
# with
# e.g. \newcommand*{\GitRefName}{v1.00}.
# Use double quotes to enable variable expansion.
# Employ and use capture group \1 to replace current LaTeX command
# (given by key in array) by corresponding value for that key.
# Run on all class files (cls) found. Only do it once (no global option to sed),
# for safety: the relevant \newcommand should only occur once.
# Checking with `grep` is simpler/clearer than using sed's `q` option.
- |
for k in "${!GITINFO[@]}"
do
grep --silent "${k}" *.cls || \
{ \
echo "Failed to find (and therefore replace) '${k}'." && \
exit 1; \
};
sed --in-place "s~\(newcommand\*{\\\\$k}\){.*}~\1{${GITINFO[$k]}}~" *.cls
done
# Hand the processed *.cls file(s) to the next stage:
artifacts:
# Overrides default
paths:
# Hand over the modified file, otherwise the depending stage only gets the
# default non-modified one.
- "*.cls"
needs: []
# This *shouldn't* fail, but failure is not catastrophic:
allow_failure: true

build_latex:
stage: build
script:
Expand All @@ -77,10 +30,6 @@ build_latex:
# Configure latexmk tool using '.latexmkrc' in project root.
# After the run, display the relevant rules (for debugging).
- latexmk --rules
needs:
- job: insert_git_metadata
# Also get that job's artifacts (like what `dependencies` used to do):
artifacts: true

build_pandoc:
stage: build
Expand All @@ -95,7 +44,3 @@ build_pandoc:
--metadata=date:$(date --iso-8601) \
--output=${README_BASENAME}.pdf \
${README_BASENAME}.md
# Despite being in a later stage, specifying that this particular jobs 'needs'
# no other job allows it run immediately, leading to concurrent running of stages
# which would otherwise run serially, speeding up the pipeline
needs: []
19 changes: 2 additions & 17 deletions chapters/frontmatter/colophon.tex
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,6 @@
\thispagestyle{empty}
\vspace*{\fill}

% Use URL as wrapper to escape special chars in tags, mainly underscores like "Fix_It"
% \urlstyle takes rm, tt etc.
% https://tex.stackexchange.com/a/20891/120853
\DeclareUrlCommand{\EscWrapper}{\urlstyle{tt}}

\begingroup% Keep changes local to this group
\hypersetup{hidelinks}
\color{g2}
Expand All @@ -35,18 +30,8 @@
\\
\TransCompiledOn{} & \textbf{\DTMnow{}}\\
\addlinespace
% Expand Argument first, else we print \GitRefName etc. literally.
% Then wrap into special command to escape chars (like underscores):
Git Ref.\ Name &
\texttt{\textbf{%
\expandafter\EscWrapper\expandafter{\GitRefName}%
}}
\\
Git Short SHA &
\texttt{%
\expandafter\EscWrapper\expandafter{\GitShortSHA}%
}
\\
Git Version & \texttt{\textbf{\GitRefName{}}} \\
Git Hash & \texttt{\GitShortSHA{}} \\
\addlinespace
Engine & \prettybanner{}\\
\LaTeX{} Version & \hologo{\fmtname} (\fmtversion)\\
Expand Down
13 changes: 8 additions & 5 deletions cookbook.cls
Original file line number Diff line number Diff line change
Expand Up @@ -351,11 +351,14 @@
% https://tex.stackexchange.com/a/350583/120853
\StrSubstitute{\shortbanner}{\detokenize{LuaTeX}}{\hologo{LuaTeX}}[\prettybanner]

% These are inserted into the PDF metadata.
% In the build process, the defaults should be replaced by the respective,
% current values (see gitlab-ci.yml / your CI script for this)
\newcommand*{\GitRefName}{n.a.}
\newcommand*{\GitShortSHA}{n.a.}
% Generate some control sequences which contain metadata, which can be inserted e.g.
% into the PDF metadata (e.g. to have the exact git commit SHA of a build).
% Do not use Lua code in `\directlua`, way too annoying with all the escaping (see:
% https://www.overleaf.com/learn/latex/Articles/An_Introduction_to_LuaTeX_(Part_2):_Understanding_%5Cdirectlua
% ). Just execute an outside, proper file.
\directlua{%
dofile("lua/envvar_newcommands.lua")
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
Expand Down
47 changes: 47 additions & 0 deletions lua/envvar_newcommands.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
--[[
The following import is not required since in LuaTeX's `\directlua` environment,
`token` is already available. However, this is nice to keep linters from complaining
about an undefined variable.
--]]
local token = require("token")

--[[
Trying to incorporate dynamic values into certain newcommand macros. Their
contents are set at build-time according to environment variables. This is useful
for automatic workflows in CI environments. See also:
https://tex.stackexchange.com/a/1739/120853.
An alternative to using environment variables are command line arguments:
https://tex.stackexchange.com/a/18813/120853
However, this seems more error-prone and requires more steps, e.g. piping arguments
to `lualatex` through `latexmk` first, etc.
The previous approach was to `sed` for certain `newcommand` definitions in an
additional CI job. This was much more error-prone (bash scripting) and less
easily expanded than the below approach.
LuaTeX provides excellent access to TeX, making this implementation much easier.
--]]

local missing = "n.a."

-- Environment variables as used e.g. in GitLab CI:
local macros_to_envvars = {
GitRefName = "CI_COMMIT_REF_NAME",
GitShortSHA = "CI_COMMIT_SHORT_SHA",
}

for macro_name, env_var in pairs(macros_to_envvars) do
local content = os.getenv(env_var)
if content == nil then
content = missing
end
--[[
The `content` can contain unprintable characters, like underscores in git branch
names. Towards this end, use detokenize in the macro itself, which will make all
characters printable (assigns category code 12). Use `\string` to escape the
backslashes so they make it into the Lua interpreter intact. See also:
https://www.overleaf.com/learn/latex/Articles/An_Introduction_to_LuaTeX_(Part_2):_Understanding_%5Cdirectlua
--]]
local escaped_content = "\\detokenize{"..content.."}"

-- Set a macro, like `\newcommand`, see also: https://tex.stackexchange.com/a/450892/120853
token.set_macro(macro_name, escaped_content)
end

0 comments on commit 6d0cd7e

Please sign in to comment.