11

a user-defined class:

\ProvidesClass{preview}[2012/12/15 v 0.01 class for creating a tight PSTricks diagram]
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\ProcessOptions\relax
\LoadClass[]{article}
\RequirePackage{pstricks}
\RequirePackage[tightpage,active]{preview}
\PreviewEnvironment{pspicture}
\endinput

consumer's input file:

\documentclass[PreviewBorder=12pt]{preview}% the option will set \PreviewBorder=12pt.

\begin{document}
\begin{pspicture}[showgrid=true](-2,-2)(2,2)
\end{pspicture}
\end{document}

How to write a class that accepts an optional key-value pair to set PreviewBorder as shown in the code snippet? Note: Its default value of the key is 0pt.


The reason I don't accept the existing answer:

Because the default value does not work as expected. Please make a try the following code and see there is still a thin white padding (CSS terminology) around the red rectangle.

\begin{filecontents}{preview.cls}
\ProvidesClass{preview}[2012/12/15 v 0.01 class for creating a tight PSTricks
diagram]
\RequirePackage{scrbase}
\DefineFamily{preview}
\DefineFamilyMember{preview}
\DefineFamilyKey{preview}{PreviewBorder}[0pt]{%
  \if@atdocument% before or after \begin{document}?
    \expandafter\@firstofone% after \begin{document} do it just now
  \else
    \expandafter\AtEndOfClass% \PreviewBorder first defined after loading
                            % preview package!
  \fi{\setlength{\PreviewBorder}{#1}}%
}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\FamilyProcessOptions{preview}
\LoadClass{article}
\RequirePackage{pstricks}
\RequirePackage[tightpage,active]{preview}
\PreviewEnvironment{pspicture}
\endinput
\end{filecontents}

%\documentclass{preview}%default value 0pt does not work!
\documentclass[PreviewBorder=0pt]{preview}% works as expected.

\begin{document}
\begin{pspicture}(-2,-2)(2,2)
\psframe[linecolor=red](-2,-2)(2,2)
\end{pspicture}

\end{document}

In other words, I want both

\documentclass{preview}

and

\documentclass[PreviewBorder=0pt]{preview}

to produce the same result without border.

5
+50

You need to differential between an initial value (set even if the key is never used) and a default value (used if the key is given with no value). In your example you seem to want an initial value rather than a default. There are several packages which can do what you want: I'd probably use kvoptions for this relatively simple case.

\begin{filecontents}{preview.cls}
\ProvidesClass{preview}[2012/12/15 v 0.01 class for creating a tight PSTricks
diagram]
\RequirePackage{kvoptions}
\DeclareStringOption[0 pt]{PreviewBorder}
\ProcessKeyvalOptions*
\LoadClass{article}
\RequirePackage{pstricks}
\RequirePackage[tightpage,active]{preview}
\PreviewEnvironment{pspicture}
\AtEndOfClass{\setlength{\PreviewBorder}{\preview@PreviewBorder}}
%\AtEndOfClass{\showthe\PreviewBorder}
\end{filecontents}

\documentclass{preview}%default value 0pt does not work!
%\documentclass[PreviewBorder=0pt]{preview}% works as expected.

\begin{document}
    \begin{pspicture}(-2,-2)(2,2)
    \psframe[linecolor=red](-2,-2)(2,2)
    \end{pspicture}
\end{document}

You'll see that I've only set the length once: there does not seem to be a need to set it otherwise.

|improve this answer|||||
  • Please uncomment the first \documentclass and comment the second one. Do you get the expected result? I don't. – kiss my armpit Dec 20 '11 at 19:57
  • @CounterTerrorist Oops, a typo: I had the option name wrong. I've edited to correct this. I do get the same result for both cases. – Joseph Wright Dec 20 '11 at 20:12
  • I've also added an optional \showthe line which you can use to see that the value for the border is the same in both cases. – Joseph Wright Dec 20 '11 at 20:13
  • Unfortunately, nothing changes. I don't get a tight output without border when uncommenting the first one. – kiss my armpit Dec 20 '11 at 20:14
  • @CounterTerrorist Are you deleting your preview.cls file between runs, as it will only be generated if it is not there. To check, try changing the version number and make sure in the log file that this also changes. If that fails, could you send me the two .tex files and matching logs: joseph.wright@morningstar2.co.uk? – Joseph Wright Dec 20 '11 at 20:20
5

Here is a small example using scrbase:

\begin{filecontents}{preview.cls}
\ProvidesClass{preview}[2012/12/15 v 0.01 class for creating a tight PSTricks
diagram]
\RequirePackage{scrbase}
\DefineFamily{preview}
\DefineFamilyMember{preview}
\DefineFamilyKey{preview}{PreviewBorder}[0pt]{%
  \if@atdocument% before or after \begin{document}?
    \expandafter\@firstofone% after \begin{document} do it just now
  \else
    \expandafter\AtEndOfClass% \PreviewBorder first defined after loading
                            % preview package!
  \fi{\setlength{\PreviewBorder}{#1}}%
}
\DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}}
\FamilyProcessOptions{preview}
\LoadClass{article}
\RequirePackage{pstricks}
\RequirePackage[tightpage,active]{preview}
\PreviewEnvironment{pspicture}
\endinput
\end{filecontents}

\documentclass[PreviewBorder=12pt,twoside]{preview}

\begin{document}
\begin{pspicture}[showgrid=true](-2,-2)(2,2)
\end{pspicture}

And you may even change the value inside the document:

\FamilyOptions{preview}{PreviewBorder=5cm}
\begin{pspicture}[showgrid=true](-2,-2)(2,2)
\end{pspicture}

\end{document}

I've done so, because you may find a lot of information about using all the other packages, but seldom something about using scrbase.

|improve this answer|||||
  • 2
    You would split the code into two blocks and remove the filecontents environment. Using it just to have one example file is more confusing for some users than helpful. – Martin Scharrer Dec 15 '11 at 10:45
  • @Schweinebacke: Please see my last update. The optional default value does not work when I ignore it. – kiss my armpit Dec 15 '11 at 16:08
2

I don't know where you are using your \PreviewBorder length, but here is what I would do.

\RequirePackage{xkeyval}
\newlength{\preview@border}
\setlength{\preview@border}{0pt}
\DeclareOptionX{PreviewBorder}[0pt]{\setlength{\preview@border}{#1}
\ProcessOptionsX

Use the length \preview@border in your code later. Note that the default value is set in the \setlength macro. The [0pt] used in the option declaration is just the value to give if the user specifies the key with no value.

  • \usepackage{preview} results in a border of 0pt.
  • \usepackage[PreviewBorder]{preview} results in a border of 0pt.
  • \usepackage[PreviewBorder=10pt]{preview} results in a border of 10pt.

Edit. Here is the working example. Thanks for the correction. The class:

\ProvidesClass{p}
\LoadClass{article}
\RequirePackage{xkeyval}
\newlength{\preview@border}
\setlength{\preview@border}{0pt}
\DeclareOptionX{PreviewBorder}[0pt]{\setlength{\preview@border}{#1}}
\ProcessOptionsX

\def\myborder{\the\preview@border}

now, use the class 'p' The LaTeX file:

\documentclass[PreviewBorder=10pt]{p}
\begin{document}
The border is \myborder

\end{document}
|improve this answer|||||

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.