Created
June 27, 2012 15:55
-
-
Save zr-tex8r/3005011 to your computer and use it in GitHub Desktop.
To create (expandable) getter in "OOP in LaTeX" with the PGF oo module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
% | |
% bxpgfooacc.sty | |
% | |
%% package declaration | |
\NeedsTeXFormat{LaTeX2e} | |
\ProvidesPackage{bxpgfooacc}[2012/06/30] | |
%% preparation | |
\def\bxqpu@pkgname{bxpgfooacc} | |
\def\bxqpu@error{\PackageError\bxqpu@pkgname} | |
% | |
\RequirePackage{pgf} | |
\usepgfmodule{oo} | |
% | |
\endlinechar=-1 % | |
%--------------------------------------- | |
%% patch to \pgfooclass | |
% This makes \property equivalent to \bxqpu@declareproperty | |
% in the body of \pgfooclass. | |
\begingroup | |
\toks@\expandafter{\pgfooclass{#1}{#2}} | |
\edef\bxqpu@next{ | |
\gdef\noexpand\pgfooclass##1##2{ | |
\noexpand\bxqpu@pgfooclass@pre@patch | |
\the\toks@ | |
\noexpand\bxqpu@pgfooclass@post@patch | |
} | |
} | |
\bxqpu@next | |
\endgroup | |
\def\bxqpu@pgfooclass@pre@patch{ | |
\let\bxqpu@origaccessor\accessor | |
\let\accessor\bxqpu@declareaccessor | |
} | |
\def\bxqpu@pgfooclass@post@patch{ | |
\let\accessor\bxqpu@origaccessor | |
} | |
%--------------------------------------- | |
%% unique tokens | |
\def\bxqpu@end{\bxqpu@end@} | |
\def\bxqpu@mark{\bxqpu@mark@} | |
\def\bxqpu@empty{\bxqpu@empty@} | |
%%<*> \accessor <attr-name>; | |
% Declares accessors for the attribute <attr-name>. There are | |
% two accessor methods: | |
% - a method <attr-name>([<value>]) | |
% It sets <attr-name> to the full expansion of <value> if | |
% <value> is present (expanded setter); otherwise expands to | |
% the current value of <attr-name> (getter). | |
% - a method <attr-name>*(<value>) | |
% It sets <attr-name> to <value> without expansion (unexpanded | |
% setter). | |
\def\bxqpu@declareaccessor#1;{ | |
\bxqpu@declare@accessors{#1} | |
} | |
%% \bxqpu@get@prop@name{<text>} | |
% [Now this macro is never used.] | |
% Finds the property name from <text> and sets it to \bxqpu@prop@name; | |
% where <text> has the form <prop-name>[=<value>]. | |
\def\bxqpu@next#1{% here #1 is a space | |
\def\bxqpu@get@prop@name##1{ | |
\bxqpu@get@prop@name@a##1=\bxqpu@end | |
} | |
\def\bxqpu@get@prop@name@a##1=##2\bxqpu@end{ | |
\bxqpu@get@prop@name@b##1\bxqpu@mark#1\bxqpu@mark\bxqpu@end{##1} | |
} | |
\def\bxqpu@get@prop@name@b##1#1\bxqpu@mark##2\bxqpu@end##3{ | |
\ifx\bxqpu@empty##2\bxqpu@empty | |
\def\bxqpu@prop@name{##3} | |
\else \def\bxqpu@prop@name{##1} | |
\fi | |
} | |
} | |
\bxqpu@next{ } | |
%% \bxqpu@declare@accessors{<prop-name>} | |
% Declares the two accessor methods. | |
\def\bxqpu@declare@accessors#1{ | |
\bxqpu@declare@int@method#1(##1){ | |
\bxqpu@accessor{#1}{##1} | |
} | |
\bxqpu@declare@int@method#1*(##1){ | |
\bxqpu@nxsetter{#1}{##1} | |
} | |
} | |
%% \bxqpu@accessor | |
% The subproc of the method <prop-name>(). | |
\def\bxqpu@accessor#1#2#3{ | |
\ifx\bxqpu@empty#2\bxqpu@empty | |
\expandafter\@firstoftwo | |
\else \expandafter\@secondoftwo | |
\fi{ | |
\csname pgfooX#3@#1\endcsname | |
}{ | |
\expandafter\edef\csname pgfooX#3@#1\endcsname{#2} | |
} | |
} | |
%% \bxqpu@nxsetter | |
% The subproc of the method <prop-name>*(). | |
\def\bxqpu@nxsetter#1#2#3{ | |
\expandafter\def\csname pgfooX#3@#1\endcsname{#2} | |
} | |
%--------------------------------------- | |
%%<*> \bxqpu@declare@int@method <method>(<arg-list>){<body>} | |
% Declares a method that has expandability. The method call | |
% \handler.<method>(<arg-list>) | |
% expands to | |
% <body>{<obj-id>} (with parameters substituted) | |
% Note that \this will not work in methods of this type. | |
\def\bxqpu@declare@int@method#1({ | |
\expandafter\let\csname bxqpu@fxm/\pgfoo@classname/#1\endcsname=t\relax | |
\method#1( | |
} | |
%% Redefines \pgfoo@caller. | |
\let\bxqpu@pgfoo@caller=\pgfoo@caller | |
\def\bxqpu@mod@caller#1.{ | |
\expandafter\bxqpu@mod@caller@a\number#1. | |
} | |
\def\bxqpu@mod@caller@a#1.#2({ | |
\expandafter\ifx\csname bxqpu@fxm/\csname | |
pgfooX#1@class\endcsname/#2\endcsname\relax | |
\expandafter\bxqpu@pgfoo@caller | |
\else \expandafter\bxqpu@mod@caller@b | |
\fi #1.#2( | |
} | |
\def\bxqpu@mod@caller@b#1.#2(#3){ | |
% calls the method-macro without setting \pgfoothis@count | |
\csname pgfooY\csname pgfooX#1@class\endcsname.#2\endcsname({#3}){#1} | |
} | |
\let\pgfoo@caller=\bxqpu@mod@caller | |
\let\pgfoo@orig@caller=\bxqpu@mod@caller | |
%--------------------------------------- | |
% all done | |
\endlinechar=13 % | |
% EOF |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
\documentclass{article} | |
\usepackage{pgf}\usepgfmodule{oo} | |
\usepackage{bxpgfooacc} | |
\endlinechar=-1 % | |
\pgfooclass{pair}{ | |
\attribute first; | |
\accessor first; | |
\attribute second; | |
\accessor second; | |
\method pair(#1,#2){ | |
\pgfooset{first}{#1} | |
\pgfooset{second}{#2} | |
} | |
\method form(){ | |
[\pgfoovalueof{first},\pgfoovalueof{second}] | |
} | |
} | |
\endlinechar=13 % | |
\begin{document} | |
\pgfoonew\pairA=new pair(99,6)% | |
\pairA.form() | |
\pairA.first({\pairA.second()})% assigns expanded value | |
\pairA.second*(\seven)% assigns unexpanded value \seven (undefined) | |
\def\seven{7}% | |
\pairA.form() %==> [6,7] : second is \seven, which expands to 7 | |
\newcount\result % let's do arithmetic | |
\result=\pairA.first()\relax | |
\multiply\result by \pairA.second()\relax | |
\the\result %==> 42 : 6 times 7 | |
\end{document} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment