Wie lädt man benutzerdefinierten Inhalt zur Verwendung in einer Vorlage?

Wie lädt man benutzerdefinierten Inhalt zur Verwendung in einer Vorlage?

Ich schreibe eine Vorlage, die die reportKlasse verwendet und den Schriftsatz mit mehreren Paketen anpasst. Ich definiere einige Daten in einer separaten user-data.texDatei, die direkt danach geladen wird 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}

Diese Variablen/Konstanten werden verwendet, um zwei unterschiedliche Titelseiten bereitzustellen, die in die Fußzeile eingefügt titlesecoder jederzeit vom Benutzer verwendet werden können.

Ist es in Ordnung, es so zu machen (nur zu verwenden \def)? Oder sollte ich \global, \newcommand… oder ein anderes verwenden? Würden Sie sie in einem anderen Format als dem einfachen verwenden tex?


\newcommand*Nach den Kommentaren habe ich einige der Makros geändert und umbenannt:

\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}

Nach der Antwort von @Andrew verwende ich

\providecommand*\@school{No SCHOOL defined}
\newcommand*\School[1]{\renewcommand*\@school{#1}}

direkt am Anfang des Pakets, damit der Benutzer \newcommand*\@school{Something}es entweder vor dem Laden oder \School{Something}danach definieren kann.


Wie @barbara vermutet hat, habe ich die Vorlage dorthin verschoben, *.stywo ich sie als Paket lade:

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}

Es funktioniert. Der Benutzer kann den Inhalt vor dem Laden des Pakets definieren, entweder in einer separaten Datei oder zu jedem beliebigen Zeitpunkt danach mit einem „Hilfsbefehl“. Ich möchte jedoch:

-Verwenden Sie einen Befehl, um die einem Feld zugeordneten Befehle automatisch zu definieren. Neue FrageHier.

- Geben Sie dem Benutzer die Möglichkeit, das Feld beim Laden des Pakets als Option anzugeben. Ich habe es mit Folgendem versucht xkeyval:

\define@key{fam}{thesis}[Master]{\Thesis{#1}}
\ProcessOptionsX<fam>

Ändern der Belastung in der Hauptdatei in:

\usepackage[thesis=PhD]{mypkg}

Der obige Code funktioniert, außer bei den Feldern, die mehr als ein Wort enthalten, da die Leerzeichen zwischen ihnen entfernt werden. Wie kann ich es mit z. B. zum Laufen bringen? \usepackage[title=A title with several words]{mypkg}Ich habe es mit {A title with several words}und versucht "A title with several words", aber es funktioniert nicht.

Es kann nicht gemacht werden


Mit dem Ansatz inDasAntwort: Ich habe jetzt diese „Factory“-Funktion, um alle Befehle auf einmal zu erstellen:

\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}} }

Antwort1

Ich habe einige (interne) Klassen, die so etwas tun. Ich definiere zunächst einen Befehl wie:

\newcommand\School[1]{\def\@school{#1}}

damit der „Benutzer“ \School{My wonderful school}die Standardeinstellungen überschreiben kann. Intern verwendet die Klasse es, \@schoolwenn der Name der Schule gedruckt werden muss.

Als nächstes lasse ich die Klasse, wenn dies sinnvoll ist, einen sinnvollen Standard für die Schule festlegen, indem ich eine Zeile wie

\School{My Wonderful School}

in der Klasse. Tatsächlich ist es wahrscheinlich die bessere Form,

\providescommand\@school{My Wonderful School}

obwohl die Verwendung des „Hilfsbefehls“ meiner Meinung nach klarer ist.

Ein Ort, an dem ich dies verwende, sind Tutorial-Arbeitsblätter, bei denen viele dieser Variablen von etwas anderem abhängen. Für diese Fälle definiere ich eine Option für die Klasse, um alle diese Variablen auf einmal festzulegen. Der „Benutzer“ beginnt seine Datei also mit

\documentclass[somecourse,solutions]{mytutorials}

und dann mytutorials.clshabe ich drinnen

\DeclareOption{somecourse}{
  \CourseName{An exciting counrse}
  \Semester{Semester 2}
  \CourseNumber{Math 987123}
}
\DeclareOption{solutions}{
    ...
}

Um alle Optionen zu verarbeiten, benötigen Sie etwas wie:

\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions

Dadurch kann ich aufspringen article.clsund Optionen übergeben, die in meiner Datei nicht definiert sind.

Schließlich möchten Sie je nach Anwendungsfall möglicherweise automatisch einen Satz von Standardwerten aus einer Datei im aktuellen Verzeichnis laden. Wenn Sie \includeoder verwenden \input, treten Probleme auf, wenn die Datei nicht vorhanden ist. Stattdessen können Sie \@inputin Ihrer Klassendatei Folgendes verwenden:

\@input{defaults.dat}

Dadurch wird die Datei „defaults.dat“ geladen, wenn sie existiert, und andernfalls wird nichts unternommen. Diese Datei wird so wie sie ist eingebunden, daher ist die Verwendung dieses Tricks gefährlich, denn wenn die Datei Müll enthält, geht alles kaputt. Um die Fälle abzudecken, in denen diese Datei nicht existiert, müssen Sie natürlich sinnvolle Standardwerte festlegen.

(Übrigens kann es für Ihre eigenen internen Variablen wirklich nicht schaden, sie zu verwenden \def– und es ist auch einfacher. Natürlich sollten Sie zuerst sicherstellen, dass Sie nichts anderes überschreiben!)

verwandte Informationen