
我正在編寫一個模板,它使用該類別report
並使用多個套件自訂排版。我在一個單獨的user-data.tex
文件中定義一些數據,該文件在之後加載documentclass
:
\def\thesis{Master} %<PhD> or <Master>
\def\thesistitle{The title of the thesis}
\def\author{AName AFirst ASecond}
\def\authormail{[email protected]}
\def\school{Master and Doctoral School}
\def\date{City, month year}
\def\logo-university{univ.pdf}
這些變數/常數用於提供兩個不同的標題頁,包含在頁腳中titlesec
,或由使用者隨時使用。
這樣做可以嗎(僅使用\def
)?還是我應該使用\global
,\newcommand
...或任何其他?你會把它們放在任何其他格式而不是普通格式嗎tex
?
評論後,我更改並重\newcommand*
命名了一些巨集:
\newcommand*\thesis{Master} %<PhD> or <Master>
\newcommand*\thesistitle{The title of the thesis}
\newcommand*\authors{AName AFirst ASecond}
\newcommand*\authorsmail{[email protected]}
\newcommand*\school{Master and Doctoral School}
\newcommand*\titledate{City, month year}
\newcommand*\university{univ.pdf}
在@Andrew回答之後,我正在使用
\providecommand*\@school{No SCHOOL defined}
\newcommand*\School[1]{\renewcommand*\@school{#1}}
就在套件的開頭,讓使用者\newcommand*\@school{Something}
在載入之前或\School{Something}
之後進行定義。
正如@barbara 猜測的那樣,我將模板移動到了*.sty
作為包加載的位置:
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
主文件
\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}
有用。使用者可以在載入套件之前定義內容,或在單獨的檔案中定義內容,或在使用「幫助命令」之後的任何時間定義內容。不過,我想:
- 使用命令自動定義與欄位關聯的命令。新問題這裡。
- 使用戶能夠在載入套件時將該欄位作為選項提供。我嘗試過xkeyval
:
\define@key{fam}{thesis}[Master]{\Thesis{#1}}
\ProcessOptionsX<fam>
將主文件中的載入更改為:
\usepackage[thesis=PhD]{mypkg}
上面的程式碼有效,除了具有多個單字的欄位之外,因為它們之間的空格被刪除了。我怎樣才能讓它工作,即\usepackage[title=A title with several words]{mypkg}
.我嘗試使用{A title with several words}
and"A title with several words"
但它不起作用。
使用該方法這回答,我現在有這個“工廠”功能來一次創建所有命令:
\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}} }
答案1
我有一些(內部)課程可以做這樣的事情。我所做的是先定義一個命令,例如:
\newcommand\School[1]{\def\@school{#1}}
以便“用戶”可以用來\School{My wonderful school}
覆蓋預設值。在內部,類別\@school
在需要列印學校名稱時使用。
接下來,如果這是合理的,我讓班級為學校設定一個合理的預設值,方法如下:
\School{My Wonderful School}
在課堂裡。事實上,使用它可能是更好的形式
\providescommand\@school{My Wonderful School}
雖然我認為使用“helper command”更清晰。
我使用它的一個地方是教程表,其中許多變數恰好依賴其他東西。對於這些情況,我為類別定義了一個選項,用於一次設定所有這些變數。所以“用戶”開始他們的文件
\documentclass[somecourse,solutions]{mytutorials}
然後裡面mytutorials.cls
我有
\DeclareOption{somecourse}{
\CourseName{An exciting counrse}
\Semester{Semester 2}
\CourseNumber{Math 987123}
}
\DeclareOption{solutions}{
...
}
要處理所有選項,您需要類似以下內容:
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions
這允許我搭載article.cls
並傳遞文件中未定義的選項。
最後,根據您的用例,您可能希望自動從目前目錄中的檔案載入一組預設值。如果您使用\include
或 ,\input
那麼當文件不存在時您會遇到問題。相反,您可以\@input
在類文件中使用:
\@input{defaults.dat}
這將載入檔案“defaults.dat”(如果存在),否則不執行任何操作。該文件將按原樣包含,因此使用此技巧存在危險,因為如果文件包含垃圾,則所有內容都會損壞。當然,為了涵蓋該文件不存在的情況,您需要設定合理的預設值。
(順便說一句,對於您自己的內部變數來說,使用確實沒有什麼壞處\def
——而且也更容易。當然,您應該首先確保您沒有覆蓋其他任何內容!)