I'm writing a template which uses the report class and customizes the typesetting with several packages. I'm defining some data in a separate user-data.tex file which is loaded just after documentclass:
\def\thesis{Master} %<PhD> or <Master>
\def\thesistitle{The title of the thesis}
\def\author{AName AFirst ASecond}
\def\authormail{aname@univ.edu}
\def\school{Master and Doctoral School}
\def\date{City, month year}
\def\logo-university{univ.pdf}
Those variables/constants are used to provide two different titlepages, to be included in the footer with titlesec, or used by the user at any time.
Is it ok to do it like that (using just \def)? Or should I use \global, \newcommand... or any other ? Would you place them in any other format rather than plain tex?
After the comments, I changed to \newcommand* and renamed some of the macros:
\newcommand*\thesis{Master} %<PhD> or <Master>
\newcommand*\thesistitle{The title of the thesis}
\newcommand*\authors{AName AFirst ASecond}
\newcommand*\authorsmail{aname@univ.edu}
\newcommand*\school{Master and Doctoral School}
\newcommand*\titledate{City, month year}
\newcommand*\university{univ.pdf}
After the answer by @Andrew, I'm using
\providecommand*\@school{No SCHOOL defined}
\newcommand*\School[1]{\renewcommand*\@school{#1}}
just in the beginning of the package, to let the user either define \newcommand*\@school{Something} before loading it, or \School{Something} after doing so.
As @barbara guessed, I moved the template to a *.sty which I'm loading as a package:
mypkg.sty
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypkg}
%If not previously defined, default value applied
\providecommand*{\@mythesis}{No THESIS TYPE defined}
\providecommand*{\@myauthor}{No AUTHOR defined}
%Command to modify the field at any point after this
\newcommand*\MyThesis[1]{\renewcommand*\@mythesis{#1}}
\newcommand*\MyAuthor[1]{\renewcommand*\@myauthor{#1}}
%Command to access the field
\newcommand*\showDF[1]{\csname @#1\endcsname}
%The content may be supplied in a separate file with \Thesis
\@input{data.dat}
\endinput
main.tex
\documentclass[a4paper,titlepage,11pt,twoside,openright]{report}
% A field may defined before loading the package
\makeatletter
\newcommand\@mythesis{My title before loading}
\makeatother
%If it not defined, the package does it
\usepackage{mypkg}
\begin{document}
% The variable may be directly accessed
\makeatletter\@mythesis\makeatother
% The content may be rewritten
\MyThesis{PhD}
% Reading with the provided command
\showDF{mythesis}
\showDF{myauthor}
\end{document}
It works. The user can define the content prior to loading the package, or either in a separate file or at any point after doing so with a 'helper command'. However, I'd like to:
-Use a command to automatically define the commands associated to a field. New question here.
-Give the user the ability to give the field as an option when loading the package. I tried with xkeyval:
\define@key{fam}{thesis}[Master]{\Thesis{#1}}
\ProcessOptionsX<fam>
changing the loading in the main file to:
\usepackage[thesis=PhD]{mypkg}
The above code works, except for the fields which have more than a word, since the spaces between them are removed. How can I make it work with, i.e. \usepackage[title=A title with several words]{mypkg}. I tried with {A title with several words} and "A title with several words" but It doesn't work.
Using the approach in this answer, I have now this 'factory' function to create all the commands at once:
\usepackage{etoolbox}
\newcommand\forcsvlistargs[2]{ \expandafter\providecommand\csname \detokenize{#1}aux\endcsname[1]{
\csname \detokenize{#1}\endcsname##1\relax}
\forcsvlist{\csname \detokenize{#1}aux\endcsname}{#2}
}
\newcommand\newDF[2]{ \expandafter\providecommand\csname th#1\endcsname{No \MakeUppercase{#2} defined}
\expandafter\newcommand\csname TH#2\endcsname[1]{\expandafter\renewcommand\csname th#1\endcsname{##1}} }
\forcsvlistargs{newDF}{{{typ}{type}}, {{date}{date}}, {{tit}{title}}, {{sch}{school}},
{{aut}{author}}, {{eaut}{eauthor}} }
\logo-universitywould be better with a different name. – barbara beeton Sep 23 '14 at 20:34\defis that you don't get warned about overwriting existing commands eg\authorand\date– David Carlisle Sep 23 '14 at 21:10\newcommandsbefore your file is loaded. If so, I'd use\providecommand. Otherwise they have to use\renewcommandafter the file is loaded. – Peter Grill Sep 24 '14 at 05:50\catcode-=11\def\logo-university\includegraphics{logo}` ;-) oh the markup fails, but you get the point – 1010011010 Sep 24 '14 at 20:02@sign, and is thus an "internal" command, it might be useful to point out that the "template" file will be named either*.clsor*.sty, and accessed by\documentclassor\usepackage. otherwise, additional measures are needed to avoid unwanted error messages. – barbara beeton Sep 24 '14 at 20:10\showDFto let the user have easy acces to the fields. Did you mean that? I suppose I could just remove the@, but I think it's better to use it, since it will prevent the user from overwritting just with\def. BTW, I added a MWE exposing the usage as a package. – umarcor Sep 25 '14 at 00:23