summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/gitver/gitver.sty
blob: c2649c3d9766e374a05be53cf37f6bbc277be5d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
% gitVer
% 
% (c) Charles Baynham 2022
%
% License: LaTeX Project Public License 1.3c
%
% This package will get a description of the current git version of this
% document and store it in a command "\gitVer". If memoir is installed, it
% will also add this to the document headers unless the option "noheader" is
% passed.
% 
% It also defines a command "\versionBox{}" which outputs a box containing the
% version and date of compilation
%
% For this to work, you must have git installed and available on the command
% line, and latex must be running in "shell escape" mode.
%

\NeedsTeXFormat{LaTeX2e}
\def\@gitVerPkgName{gitver}
\ProvidesPackage{\@gitVerPkgName}
  [2022/07/16 v1.4 Access current git version and optionally add it to document headers]

\RequirePackage{hyperref}
\RequirePackage{catchfile}
\RequirePackage{pdftexcmds}
\RequirePackage{datetime2}
\RequirePackage{ifthen}
\RequirePackage{xparse}

% Define a command to get environmental variables
% Thanks to egreg at https://tex.stackexchange.com/questions/62010/can-i-access-system-environment-variables-from-latex-for-instance-home
\ExplSyntaxOn
\NewDocumentCommand{\getenv}{om}
 {
  \sys_get_shell:nnN { kpsewhich ~ --var-value ~ #2 } { } \l_tmpa_tl %
  \tl_trim_spaces:N \l_tmpa_tl %
  \IfNoValueTF { #1 } %
   {%
    \tl_use:N \l_tmpa_tl%
   }%
   {%
    \tl_set_eq:NN #1 \l_tmpa_tl%
   }%
 }
\ExplSyntaxOff

% Support lualatex by reinstating the \write18 command
\RequirePackage{ifluatex}
\ifluatex
	\RequirePackage{shellesc}
\fi

%%% Package options %%%

%% 'noheader' option
\newif\if@gitver@noheader
\@gitver@noheaderfalse
\DeclareOption{noheader}{
	\@gitver@noheadertrue
	\PackageInfo{\@gitVerPkgName}{Header info disabled}%
}
%
%% 'nopdfinfo' option
\newif\if@gitver@pdfsubect
\@gitver@pdfsubecttrue
\DeclareOption{nopdfinfo}{
	\@gitver@pdfsubectfalse
	\PackageInfo{\@gitVerPkgName}{Metadata info disabled}%
}
%
\ProcessOptions\relax

%%% End package options %%%

% Define some ifs
\newif\if@gitver@ready
\newif\if@gitver@success

% https://tex.stackexchange.com/questions/88614/how-do-you-detect-restricted-write18-support

\ifcase\pdf@shellescape
  \@gitver@readyfalse%
  \or
  \@gitver@readytrue%
  \or
  \@gitver@readyfalse%
 \fi

\if@gitver@ready
	\PackageInfo{\@gitVerPkgName}{Shell escape enabled}%
%
	% Get current git version
	% Note: this command requires (a) git installed and (b) shell escape in latex enabled
	\immediate\write18{ git describe --match nopenopenope --always --long --dirty --abbrev=6 > \jobname_desc.aux }
%
	% Extract this into a new variable, gitVer
	\@gitver@successfalse
	\IfFileExists{\jobname_desc.aux}{
		% Read the file into \gitVer
		\CatchFileDef{\gitVer}{\jobname_desc.aux}{\endlinechar=-1}

		% Check if the macro \gitVer is empty: this is its definition if the file had no contents
		\def\@gitver@emptyfile{}

		\ifx\gitVer\@gitver@emptyfile%
			\PackageWarning{\@gitVerPkgName}{Git output is empty: is this folder a git repo? Make sure that this directory has had "git init" called in it, has at least one commit, and that git is installed.}
		\else
			\@gitver@successtrue
		\fi
	}

	\if@gitver@success
	\else
	    % Look for "CLSI" environmental variable: this stands for Common Latex Service
        % Interface, and is set to "1" in web builders like Overleaf.com
        \getenv[\CLSI]{CLSI}
        % Check if CLSI == 1 (see https://tex.stackexchange.com/a/306500)
        \ifnum1=0\CLSI\relax 
            \PackageWarning{\@gitVerPkgName}{Running on a Common Latex Service %
                Interface without Git: writing version as "CLSI"}%
		    \def\gitVer{CLSI}
        \else 
            \PackageError{\@gitVerPkgName}{Git command failed: writing as "unknown"}{%
                Calling git failed, and your system did not identify itself as a 
                Common Latex Service Interface (e.g. overleaf.com). Make sure that git
                is installed and that this file is in a repository which has at least
                one commit. 
            }%
		    \def\gitVer{unknown}
        \fi
	\fi
%
	% Make a box containing the date and version
	\newcommand{\versionBox}{\fbox{Manuscript version: \textit{\#\gitVer} - \DTMnow{} }}
%
	% If we're using memoir, put the tag into into the header
%
	\@ifclassloaded{memoir}%
	  {%
	  	\PackageInfo{\@gitVerPkgName}{Memoir detected}%
	  	\if@gitver@noheader%
		\else%
			% Add the git version and the date/time to the header / footer
			\PackageInfo{\@gitVerPkgName}{Adding git info to header}%
			\makeoddfoot{Ruled}{\versionBox}{}{\thepage}
			\makeevenfoot{Ruled}{\thepage}{}{\versionBox}
			\makeevenhead {Ruled}{\scshape\leftmark}{}{\textit{\#\gitVer}}
			\makeoddhead {Ruled}{\textit{\#\gitVer}}{}{\rightmark}
		\fi%
	}{%
		% If we're not using memoir, but we are using fancyhdr, also add to the header
		\@ifpackageloaded{fancyhdr}
		{%
			\if@gitver@noheader%
			\else%
				\fancyfoot[L]{\versionBox}
				\fancyfoot[C]{}
				\fancyfoot[R]{\thepage}
			\fi
		}{%
			% No memoir or fancyhdr
			\if@gitver@noheader%
			\else%
				\PackageWarning{\@gitVerPkgName}{Not changing the document headers because you're not using "memoir" or "fancyhdr" package. Pass "noheader" to suppress this warning, or use one of these classes / packages.}
			\fi
		}
	}%

	\if@gitver@pdfsubect%
		\PackageInfo{\@gitVerPkgName}{Setting pdf subject metadata}%
		% Put it into the metadata too
		\hypersetup{
			pdfsubject={Version \#\gitVer{}}
		}%
	\fi%
\else
	\PackageError{\@gitVerPkgName}{Shell escape not enabled}{Latex failed to write a file. This is probably because shell-escape mode is disabled: you must turn this on!}

	\def\versionBox{???}
	\def\gitVer{unknown}
\fi