summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/jobname-suffix
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-09-26 03:03:51 +0000
committerNorbert Preining <norbert@preining.info>2022-09-26 03:03:51 +0000
commit3416c5679e9cfa1ebba2296ecf401319a9f1cfe6 (patch)
treef451ec530b29856ea00420cb41b85943ade67d10 /macros/latex/contrib/jobname-suffix
parentce8083552e0d948bf495e72d5c4d2680b505c90b (diff)
CTAN sync 202209260303
Diffstat (limited to 'macros/latex/contrib/jobname-suffix')
-rw-r--r--macros/latex/contrib/jobname-suffix/README.md25
-rw-r--r--macros/latex/contrib/jobname-suffix/jobname-suffix.pdfbin0 -> 437856 bytes
-rw-r--r--macros/latex/contrib/jobname-suffix/jobname-suffix.sty134
-rw-r--r--macros/latex/contrib/jobname-suffix/jobname-suffix.tex229
4 files changed, 388 insertions, 0 deletions
diff --git a/macros/latex/contrib/jobname-suffix/README.md b/macros/latex/contrib/jobname-suffix/README.md
new file mode 100644
index 0000000000..8e35de3524
--- /dev/null
+++ b/macros/latex/contrib/jobname-suffix/README.md
@@ -0,0 +1,25 @@
+# jobname-suffix
+LaTeX package to achieve different outputs based on the filename
+
+### Compiling
+
+#### Running tests
+
+Run tests with
+
+```bash
+l3build check
+```
+
+To override a test's output (for example if you changed the test), run
+
+```bash
+l3build save jobname-suffix-001
+```
+
+## Missing `l3build`
+
+If your system does not have `l3build` installed into the system path,
+you may need to access it directly. For example, on my system it is located
+at `/usr/share/texmf-dist/scripts/l3build/l3build.lua` and can be
+directly invoked.
diff --git a/macros/latex/contrib/jobname-suffix/jobname-suffix.pdf b/macros/latex/contrib/jobname-suffix/jobname-suffix.pdf
new file mode 100644
index 0000000000..6693efda38
--- /dev/null
+++ b/macros/latex/contrib/jobname-suffix/jobname-suffix.pdf
Binary files differ
diff --git a/macros/latex/contrib/jobname-suffix/jobname-suffix.sty b/macros/latex/contrib/jobname-suffix/jobname-suffix.sty
new file mode 100644
index 0000000000..d57014ff96
--- /dev/null
+++ b/macros/latex/contrib/jobname-suffix/jobname-suffix.sty
@@ -0,0 +1,134 @@
+\NeedsTeXFormat{LaTeX2e}[1994/06/01]
+\ProvidesExplPackage{jobname-suffix}{2022/09/17}{1.0}{Compile differently based on the filename}
+
+\RequirePackage{expl3}
+\ExplSyntaxOn
+
+%
+% Variants
+%
+\cs_generate_variant:Nn \str_set:Nn {Ne}
+\cs_generate_variant:Nn \str_if_eq:nnTF {nfTF}
+
+%
+% Messages
+%
+\msg_new:nnn {jobname-suffix} {initial-data} {
+ \\
+ (jobname-suffix)\ \ \ Found~jobname~~`#1'~~with~suffix~~`#2'
+ \\
+}
+\msg_new:nnn {jobname-suffix} {override} {
+ \\
+ (jobname-suffix)\ \ \ Overriding~suffix~with~`#1'
+ \\
+}
+\msg_new:nnn {jobname-suffix} {test} {
+ \\
+ (jobname-suffix)\ \ \ Testing~`#1'~==~`#2'
+ \\
+}
+\msg_new:nnn {jobname-suffix} {condition} {
+ \\
+ (jobname-suffix)\ \ \ Condition~is~`#1'
+ \\
+}
+
+
+
+
+
+\str_new:N \g__suffix_str
+\str_new:N \g__jobname_str
+\str_new:N \g__split_char_str
+\str_set:Nn \g__split_char_str {-}
+\seq_new:N \l__suffix_list_seq
+\str_new:N \l__suffix_list_str
+
+
+
+
+
+\int_new:N \l__slice_pos_int
+% Slice #1 at the char indicated by #2 and store the result in #3
+\cs_new_protected:Nn \__slice_at_char:NNN {
+ \int_set:Nn \l__slice_pos_int {1}
+ \str_map_inline:Nn #1 {
+ \int_incr:N \l__slice_pos_int
+ \str_if_eq:VnTF {#2} {##1} {
+ \str_map_break:
+ }{}
+ }
+ \str_set:Nx #3 {\str_range:Nnn #1 {\l__slice_pos_int}{\c_max_int}}
+}
+
+
+% If the string starts with a quote, trim it off.
+\cs_new:Nn \__trim_quotes:N {
+ \str_if_eq:nfTF {"} { \str_range:Nnn #1 {1}{1}} {
+ \str_range:Nnn #1 {2}{-1+\str_count:N #1}
+ }{
+ #1
+ }
+}
+
+% The jobname will be surrounded by quotes if there are any spaces in it,
+% so we first trim it if needed.
+\str_set:Nx \g__jobname_str { \__trim_quotes:N \c_sys_jobname_str }
+% Find the suffix string. The result will be stored in the last argument
+\__slice_at_char:NNN \g__jobname_str \g__split_char_str \g__suffix_str
+
+\msg_term:nnxx {jobname-suffix} {initial-data} {\g__jobname_str} {\g__suffix_str}
+
+%
+% User-facing commands and environments
+%
+
+% Optional arg is a comma-separate list of suffixes. If any of the listed
+% suffixes match the jobname's suffix, the true contiditon is executed. Otherwise
+% the false condition is executed.
+\NewDocumentCommand{\IfSuffixTF}{ o +m +m }{
+ %\msg_term:nnxx {jobname-suffix} {test} {#1} {\g__suffix_str}
+
+ \IfNoValueTF {#1} {
+ %\msg_term:nnx {jobname-suffix} {condition} {FALSE}
+ #3
+ }{
+ % We want to do string-based comparisons, so we must first
+ % cast our argument list as a string (otherwise, \seq_* operations
+ % won't work properly).
+ \str_set:Nn \l__suffix_list_str {#1}
+ \seq_set_split:NnV \l__suffix_list_seq {,} {\l__suffix_list_str}
+
+ \seq_if_in:NVTF \l__suffix_list_seq {\g__suffix_str} {
+ %\msg_term:nnx {jobname-suffix} {condition} {TRUE}
+ #2
+ } {
+ %\msg_term:nnx {jobname-suffix} {condition} {FALSE}
+ #3
+ }
+ }
+}
+
+\NewDocumentCommand{\IfSuffixT}{ o +m }{
+ \IfSuffixTF[#1]{#2}{}
+}
+
+\NewDocumentCommand{\IfSuffixF}{ o +m }{
+ \IfSuffixTF[#1]{}{#2}
+}
+
+\NewDocumentEnvironment{IfSuffix}{ o +b }{
+ \IfSuffixT[#1]{#2}
+}{}
+
+\NewDocumentCommand{\OverrideSuffix}{ m }{
+ \str_set:Nn \g__suffix_str {#1}
+ \msg_term:nnx {jobname-suffix} {override} {\g__suffix_str}
+}
+\NewExpandableDocumentCommand{\JobnameSuffix}{}{
+ \str_use:N \g__suffix_str
+}
+
+
+\ExplSyntaxOff
diff --git a/macros/latex/contrib/jobname-suffix/jobname-suffix.tex b/macros/latex/contrib/jobname-suffix/jobname-suffix.tex
new file mode 100644
index 0000000000..0ae054b602
--- /dev/null
+++ b/macros/latex/contrib/jobname-suffix/jobname-suffix.tex
@@ -0,0 +1,229 @@
+%% pig.dtx
+%% Copyright 2022 Jason Siefken
+%
+% This work may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This work has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this work is Jason Siefken
+%
+% This work consists of the files jobname-suffix.sty and docs/jobname-suffix.tex
+\documentclass{l3doc}
+\usepackage{listings,xcolor}
+
+\lstdefinestyle{mystyle}{
+ language=[LaTeX]{TeX},
+ texcsstyle=*\color{blue},
+ commentstyle={\color{green!50!black}\itshape},
+ basicstyle=\ttfamily,
+ moretexcs={IfSuffixT,IfSuffixF,IfSuffixTF,OverrideSuffix,JobnameSuffix,solution}, % user command highlight
+ frame=single,
+}
+\lstset{style=mystyle}
+
+\title{%
+ \pkg{jobname-suffix}\\
+ Compile different content based on the file name%
+}
+
+\author{%
+ Jason Siefken%
+ \thanks{%
+ Please file an issues/comments to \url{https://github.com/siefkenj/jobname-suffix/issues}
+ }
+}
+
+\date{Released \today}
+
+\NewDocumentCommand{\fileshow}{m}{%
+\par
+\noindent\begin{minipage}{\linewidth}
+ \noindent\texttt{\itshape #1:}
+ \vspace{-1cm}
+\end{minipage}
+}
+
+\begin{document}
+ \maketitle
+
+ \tableofcontents
+
+ \begin{abstract}
+ \pkg{jobname-suffix} allows one to compile a document differently depending
+ on the document's file name (internally called the \texttt{jobname} in \TeX).
+ This allows one to have one source file and multiple links to this source file (either
+ as symbolic links, or as different files referencing the original via an \cs{input}
+ command) that are each compile differently. For example, an exam might have an
+ \file{exam-student.tex} and an \file{exam-instructor.tex} which both reference the
+ same source code but where the instructor version includes solutions and the student
+ version does not.
+ \end{abstract}
+
+ \begin{documentation}
+
+ \section{Introduction}
+ \pkg{jobname-suffix} by default allows you to reference the part of a file name (technically the \cs{jobname})
+ that comes after the first ``\texttt{-}'' character and use that information to control what \LaTeX{} produces.
+
+ Consider the following example: you have three files \file{exam.tex}, \file{exam-student.tex}, and \file{exam-instructor.tex}.
+ The files \file{exam-student.tex} and \file{exam-instructor.tex} are either symbolic links to \file{exam.tex} (if your operating
+ system supports symbolic links) or use \cs{input}\Arg{exam.tex file path} to include the contents of \file{exam.tex}.
+
+ \fileshow{exam-student.tex \textnormal{and} exam-instructor.tex}
+ \begin{lstlisting}
+\input{exam.tex}
+ \end{lstlisting}
+
+ \fileshow{exam.tex}
+ \begin{lstlisting}
+\documentclass{article}
+\usepackage{jobname-suffix}
+
+\newcommand{\solution}[1]{#1}
+\IfSuffixT[instructor]{
+ % Instructors get solutions emboldened
+ \renewcommand{\solution}[1]{\textbf{#1}}
+}
+\IfSuffixT[student]{
+ % Students don't see solutions at all
+ \renewcommand{\solution}[1]{}
+}
+
+\begin{document}
+ \begin{enumerate}
+ \item First question
+ \solution{First answer}
+
+ \item Second question
+ \solution{Second answer}
+ \end{enumerate}
+\end{document}
+ \end{lstlisting}
+
+ \noindent Then, compiling via
+
+ \noindent\texttt{> lualatex exam-instructor.tex}
+
+ \noindent\texttt{> lualatex exam-student.tex}
+
+ \noindent will produce two pdfs: one with solutions and one without.
+
+ \section{Usage}
+ \subsection{Variables}
+
+ \begin{variable}{\JobnameSuffix}
+ The computed suffix of the filename (\cs{jobname}). This is normally the part of the file name after the first ``\texttt{-}''
+ character and before the file extension. For example,
+ \file{file-a.tex} has a \cs{JobnameSuffix} of ``\texttt{a}'',
+ \file{file-a-b.tex} has a \cs{JobnameSuffix} of ``\texttt{a-b}'',
+ and \file{file.tex} has a \cs{JobnameSuffix} of consisting of the empty string.
+ \end{variable}
+
+ \subsection{Commands}
+ \begin{function}{\IfSuffixTF, \IfSuffixT, \IfSuffixF}
+ \begin{syntax}
+ \cs{IfSuffixTF}\oarg{suffixes}\marg{true condition}\marg{false condition}
+ \cs{IfSuffixT}\oarg{suffixes}\marg{true condition}
+ \cs{IfSuffixF}\oarg{suffixes}\marg{false condition}
+ \end{syntax}
+ The argument \meta{suffixes} is a comma-separated list of all suffixes you wish to test against.
+ \end{function}
+
+ \begin{function}{\OverrideSuffix}
+ \begin{syntax}
+ \cs{OverrideSuffix}\marg{suffix}
+ \end{syntax}
+ Override \cs{JobnameSuffix} to be the suffix specified by \meta{suffix} instead.
+ \end{function}
+
+ \subsection{Environments}
+
+ \DescribeEnv{IfSuffix}
+ The \env{IfSuffix} environment accepts an optional argument \oarg{suffixes} and will display its contents (unmodified)
+ if \cs{JobnameSuffix} is among the comma-separated list \meta{suffixes}. Unfortunately this environment cannot contain
+ \env{verbatim} contents.
+
+ \section{Compiling}
+
+ \pkg{jobname-suffix} works by reading the \cs{jobname} macro that is part of standard \TeX. By default, this is
+ set to the file name without the file extension. You can affect the jobname in one of two ways:
+ \begin{enumerate}
+ \item The name of your file.
+ \item By supplying the \texttt{-jobname} option during compilation. For example, the following two
+ commands would both result in compiling with a \cs{jobname} of \texttt{exam-student}.
+
+ \noindent\texttt{> lualatex -jobname exam-instructor exam.tex}
+
+ \noindent\texttt{> lualatex exam-instructor.tex}
+ \end{enumerate}
+
+ \section{Tips}
+
+ \begin{itemize}
+ \item
+ For performance reasons, it is best to \cs{IfSuffixTF} to define/redefine commands in your document preamble
+ rather than to use them in your document body/macro bodies. For example, do
+
+\begin{lstlisting}
+\documentclass{article}
+\usepackage{jobname-suffix}
+
+\newcommand{\solution}[1]{#1}
+\IfSuffixT[instructor]{
+ % Instructors get solutions emboldened
+ \renewcommand{\solution}[1]{\textbf{#1}}
+}
+
+\begin{document}
+ \solution{Some Text}
+\end{document}
+\end{lstlisting}
+
+instead of
+
+\begin{lstlisting}
+\documentclass{article}
+\usepackage{jobname-suffix}
+
+\newcommand{\solution}[1]{%
+ \IfSuffixTF[instructor]{%
+ % Instructors get solutions emboldened
+ \textbf{#1}%
+ }{%
+ #1%
+ }
+}
+
+\begin{document}
+ \solution{Some Text}
+\end{document}
+\end{lstlisting}
+
+ \item
+ To match the case when you have ``no suffix'' (i.e., when the suffix is the empty string because ``\texttt{-}'' did not appear in
+ the filename), use \cs{IfSuffix[]} with an empty argument list\footnote{
+ If you omit the optional argument, \cs{IfSuffixT} will never be true (not even if \cs{JobnameSuffix} is the empty string).
+ }.
+ \end{itemize}
+
+
+ \section{Installation}
+
+ For manual installation, the package is available from
+ \href{http://ctan.org/pkg/jobname-suffix}{{CTAN}}.
+
+ The package requires \LaTeX3 support as provided in the \pkg{l3kernel} and
+ \pkg{l3packages} bundles. Both of these are included in \TeX{} Live and
+ MiK\TeX{}, or are again available in ready-to-install form from {CTAN}.
+
+ \end{documentation}
+
+
+ \PrintIndex
+\end{document}