Skip to content

Instantly share code, notes, and snippets.

@zr-tex8r
Created June 27, 2012 15:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zr-tex8r/3005011 to your computer and use it in GitHub Desktop.
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
%
% 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
\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