diff options
author | Norbert Preining <norbert@preining.info> | 2022-09-26 03:03:51 +0000 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2022-09-26 03:03:51 +0000 |
commit | 3416c5679e9cfa1ebba2296ecf401319a9f1cfe6 (patch) | |
tree | f451ec530b29856ea00420cb41b85943ade67d10 /macros/latex/contrib/jobname-suffix | |
parent | ce8083552e0d948bf495e72d5c4d2680b505c90b (diff) |
CTAN sync 202209260303
Diffstat (limited to 'macros/latex/contrib/jobname-suffix')
-rw-r--r-- | macros/latex/contrib/jobname-suffix/README.md | 25 | ||||
-rw-r--r-- | macros/latex/contrib/jobname-suffix/jobname-suffix.pdf | bin | 0 -> 437856 bytes | |||
-rw-r--r-- | macros/latex/contrib/jobname-suffix/jobname-suffix.sty | 134 | ||||
-rw-r--r-- | macros/latex/contrib/jobname-suffix/jobname-suffix.tex | 229 |
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 Binary files differnew file mode 100644 index 0000000000..6693efda38 --- /dev/null +++ b/macros/latex/contrib/jobname-suffix/jobname-suffix.pdf 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} |