Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I am trying to code a macro that adds xkeyval arguments contained in a macro to a list of default xkeyval arguments.

The following minimal example explains better what I want to do.

\documentclass{article}

\usepackage{xkeyval}

\makeatletter

\define@cmdkey{f}[c@]{a}[a]{}
\define@cmdkey{f}[c@]{b}[b]{}
\define@cmdkey{f}[c@]{c}[c]{}
\newcommand{\dispKeys}[2][toMakeItMoreComplex]{
  \setkeys{f}{a,b,c,#2}
  c@a = \c@a{} \\
  c@b = \c@b{} \\
  c@c = \c@c{} \\
}

\makeatother

\newcommand{\prefilled}[2][toMakeItMoreComplex]{
 \dispKeys[#1]{a=prefilled, #2}
}

\begin{document}

\dispKeys{a=test}

\def\dummy{dummy}
\prefilled[\dummy]{}

\prefilled[\dummy]{b=other}

\def\otherArgs{c}
\prefilled[\dummy]{b=other, \otherArgs}

\def\otherArgs{c=another}
\prefilled[\dummy]{b=other, \otherArgs}

\end{document}

Should generate the output:

c@a = test
c@b = b
c@c = c
c@a = prefilled
c@b = b
c@c = c
c@a = prefilled
c@b = other
c@c = c
c@a = prefilled
c@b = other
c@c = c
c@a = prefilled
c@b = other
c@c = another

However, the last call \prefilled[\dummy]{b=other, \otherArgs} generates an error as it interpret the whole content of \otherArgs as a key name.

I tried using \expandafter (which I do not really know how to use) in different places in \prefilled[\dummy]{b=other, \otherArgs} without success. {b=other, \otherArgs} is not taken as argument and I get:

c@a = prefilled
c@b = b
c@c = c
b=other, c=another

How do I modify the call \prefilled[\dummy]{b=other, \otherArgs} or the definition of \prefilled for it to work? The real case is more complex than this minimal example (it involves includegraphics and lengths) but hopefully I will be able to adapt a potential solution.

share|improve this question
    
I do something similar in adjustbox if \adjustboxset is used: bitbucket.org/martin_scharrer/adjustbox/src/47332dea3c9f/… –  Martin Scharrer May 13 '12 at 10:52
    
You can pass something like {b=other, \otherArgs} because the = and , inside \otherArgs are then hidden. Expanding everything with \edef like egreg showed is one solution against this, but will prevent to have general code in the key values. You could allow to pass one macro as an extra argument which is the expanded. I have trouble seeing your real use case from your example. Why would someone pass \otherArgs instead of the real key=value pairs? Is this done by the user or internally by some of your macros?? –  Martin Scharrer May 13 '12 at 12:29
    
I am coding a user macro IMGS formating a set of images (IMGS{f1, f2, ...}). IMGS call includegraphics with a set of predefined (keepasp..., ...) or computed (width, ...) arguments. Optionally the user can give additional arguments for specific imges (IMGS{f1, [angle=90]f2, f3}). I use xstring to parse the argument of IMGS and multido to call includegraphics for every image. I am able to get the file in \f... and the argument in \args. I now want to call (via one more level of indirection thru a macro \img) \includegraphics[keepaspectratio, width=\computedWidth, ..., \args]{\f...} –  Gus May 13 '12 at 13:59
    
In this case use \expandafter with an auxiliary macro as shown in my answer. –  Martin Scharrer May 13 '12 at 14:07
add comment

3 Answers 3

up vote 4 down vote accepted

You have to expand the option list buried in \otherArgs before \setkeys sees that macro: remember that \setkeys doesn't perform expansion.

\newcommand{\prefilled}[2][toMakeItMoreComplex]{%
 \begingroup\edef\x{\endgroup\noexpand\dispKeys[#1]{a=prefilled,#2}}\x
}

As Martin remarks, this bears some risks, as the expansion is complete, so the values given to keys should not contain things that don't survive expansion (typical examples are \textbf and such). Alternatively, use \protected@edef instead of \edef.

The \begingroup and \endgroup ensure that the meaning given to \x will be forgotten instantly when \x is expanded.

share|improve this answer
    
Yes, but this has the drawback that all keys and values are expanded. However, this seems to be the only possibility if the OP wants to allow any form of combinations of direct key=value pairs and ones inside macros. –  Martin Scharrer May 13 '12 at 11:21
    
Thanks, it works pretty well on the minimal case study. I will now try to adapt it on my real case. Just to make sure, the \expandafter[#1]{a=prefilled,#2} protect the whole block [#1] or only [? Also, what's the role of the \begingroup and \endgroup, why wouldn't it work without them? –  Gus May 13 '12 at 11:43
    
@egreg: Please what does the \expandafter in \expandafter[#1] do, given the \edef? This solution (with \edef) isn't applicable for general use. My preferred approach is a walk through the key-value pairs and one-step expanding each pair that requires expansion. Of course, the solution will be longer. I can develop and post it only if the OP thinks it will be useful to him. –  Ahmed Musa May 13 '12 at 14:59
    
@AhmedMusa Thanks for noting: it was a "copy-paste" error. –  egreg May 13 '12 at 15:29
add comment

If \otherArgs is actually added by some internal code, not by the user directly, you can expand it first and add the expanded code at the right position using an auxiliary macro as shown by \withotherargs and \@withotherargs below. If the \otherArgs comes from the user instead you can provide a second argument to pass such a macro.

\documentclass{article}

\usepackage{xkeyval}

\makeatletter

\define@cmdkey{f}[c@]{a}[a]{}
\define@cmdkey{f}[c@]{b}[b]{}
\define@cmdkey{f}[c@]{c}[c]{}
\newcommand{\dispKeys}[2][toMakeItMoreComplex]{%
  \setkeys{f}{a,b,c,#2}%
  c@a = \c@a{} \\
  c@b = \c@b{} \\
  c@c = \c@c{} \\
}

\makeatother

\newcommand{\prefilled}[2][toMakeItMoreComplex]{%
 \dispKeys[#1]{a=prefilled, #2}%
}

\makeatletter
\newcommand\withotherargs[2][]{%
    \expandafter\@withotherargs\expandafter{\otherArgs}{#1}{#2}%
}
\def\@withotherargs#1#2#3{%
    \prefilled[#2]{#3,#1}%
}
\makeatother

\begin{document}

\dispKeys{a=test}

\def\dummy{dummy}
\prefilled[\dummy]{}

\prefilled[\dummy]{b=other}

\def\otherArgs{c}
\prefilled[\dummy]{b=other, \otherArgs}

\def\otherArgs{c=another}
%\prefilled[\dummy]{b=other, \otherArgs}
\withotherargs[\dummy]{b=other}

\end{document}
share|improve this answer
add comment

A more universal and robust solution turned out to be cheaper than I had thought. I choose to normalize the key-value set because without first normalizing the list the scheme of pre-expanding each keyname will not always work. This is because the \expandafter may simply act on a blank space. Normalization also deals with active commas and equal signs. Top-level expansion of keynames is safe because it is unlikely that an active character will lead any keyname.

You can use the option expandkeyname in \documentclass or \usepackage to globally turn on 'expand keyname'. Also, in case anyone rightly fears global assignments, it is possible to use the commands \ExpandKeynameInSetkeys and \NoExpandKeynameInSetkeys to locally turn expandkeyname on and off. You can also use the command \expandnamekeys and similar commands to enter, remove or delete keys whose names should be expanded once or twice at \setkeys.

After extracting the file content keyvalx.sty, move it to the right location in your TeX repository.

Aside: I often hear that one of the drawbacks of xkeyval package is that it can't be loaded before \documentclass. The following keyvalx package patches xkeyval so that keyvalx can be loaded before \documentclass. It postpones what xkeyval likes to do with \@classoptionslist until \documentclass is seen/invoked.

\begin{filecontents}{keyvalx.sty}
\NeedsTeXFormat{LaTeX2e}[2011/06/27]
\ProvidesPackage{keyvalx}[2012/05/13 v0.0.1 Patches for xkeyval package (AM)]
\RequirePackage{catoptions}
\ifdefTF\XKeyValLoaded{}{\input xkeyval }
\edef\XKV@restorecatcodes{%
  \catcode`\noexpand\@\the\catcode`\@\relax
  \catcode`\noexpand\=\the\catcode`\=\relax
  \catcode`\noexpand\,\the\catcode`\,\relax
  \catcode`\noexpand\:\the\catcode`\:\relax
  \let\noexpand\XKV@restorecatcodes\relax
}
\catcode`\@11\relax
\catcode`\=12\relax
\catcode`\,12\relax
\catcode`\:12\relax
\let\XKV@doxs\relax
\def\XKV@warn#1{\PackageWarning{xkeyval}{#1}}
\def\XKV@err#1{\PackageError{xkeyval}{#1}\@ehd}
\cptnewvariables{if}[XKV@]{expandkeyname}[false]
\cptnewvariables{if}[XKV]{forbreak}[false]
\new@def*\XKVifcond#1\fi{%
  #1\relax\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
}
\newletcs\XKVforbreak\XKVforbreaktrue
% \XKVfor[<parser>]<list>\do{<1-parameter-callback>}
% Star (*) implies <listcmd> in place of <list>
\robust@def*\XKVfor{\cpt@teststopt\XKV@for,}
\robust@def*\XKV@for[#1]#2\do#3{%
  \global\advance\XKV@depth by1
  \csn@def{XKV@fordo@\romannumeral\XKV@depth}##1#1{%
    \XKV@for@a#1\XKVfor{XKV@fordo@\romannumeral\XKV@depth}{##1}{#3}%
  }%
  \XKVforbreakfalse
  \begingroup % for \XKV@tempa
  \cpt@stchoose{cpt@st}{#2}\XKV@tempa\XKVfor
  \cpt@sttrue\cpt@csvnormalize[#1]\XKV@tempa
  \expandafter\endgroup
  \csname XKV@fordo@\romannumeral\XKV@depth\expandafter\endcsname
  \XKV@tempa#1\XKVfor#1%
  \global\advance\XKV@depth by-1
}
% \XKVtfor<list>\do{<callback>}
\robust@def*\XKVtfor{\cpt@testst\XKV@tfor}
\robust@def*\XKV@tfor#1\do#2{%
  \global\advance\XKV@depth by1
  \csn@def{XKV@tfordo@\romannumeral\XKV@depth}##1{%
    \XKV@for@a{}\XKVtfor{XKV@tfordo@\romannumeral\XKV@depth}{##1}{#2}%
  }%
  \XKVforbreakfalse
  \begingroup
  \cpt@stchoose{cpt@st}{#1}\XKV@tempa\XKVtfor
  \expandafter\endgroup
  \csname XKV@tfordo@\romannumeral\XKV@depth\expandafter\endcsname
  \XKV@tempa\XKVtfor
  \global\advance\XKV@depth by-1
}
\robust@def*\XKV@for@a#1#2#3#4#5{%
  \csname i\ifx#2#4\else i\fi ofii\endcsname{%
    % In case it was set true by the last item:
    \XKVforbreakfalse
  }{%
    \csname i\ifXKVforbreak\else i\fi ofii\endcsname{%
      \XKVforbreakfalse
      \begingroup
      \defpass\reserved@a##1#2#1{\endgroup
        \edef\XKV@remainder{\unexpanded{##1}}%
      }%
    }{%
      #5\relax\csname#3\endcsname
    }%
  }%
}
% \XKVforwhile[<parser>]<list><holder-cmd><if-cond>\fi{<callback>}
% Star (*) -> <listcmd> in place of <list>
\robust@def*\XKVforwhile{\cpt@teststopt\XKV@forwhile,}
\robust@def\XKV@forwhile[#1]#2#3#4\fi#5{%
  \XKVifcond#4\fi{%
    \edef#3{\ifboolTF{cpt@st}\expandcsonce\unexpanded{#2}}%
    \XKVfor*[#1]#3\do{%
      \edef#3{\unexpanded{##1}}%
      \XKVifcond#4\fi{#5}\XKVforbreak
    }%
  }{}%
}
\robust@redef*\XKV@whilist{\XKVforwhile*}
\robust@def*\XKV@normalizelist#1#2{%
  \ifcsnullTF#2{}{%
    \usename{\ifcase#1csv\else kv\fi @@normalize}*#2%
  }%
}
\robust@redef\XKV@sp@deflist#1#2{%
  \edef#1{\unexpanded{#2}}%
  \XKV@normalizelist{0}#1%
}
\robust@redef*\XKV@checksanitizea#1#2{%
  \XKV@ch@cksanitize{#1}#2=%
  \edef#2{\unexpanded{#1}}%
  \ifboolTF{in@}{}{\XKV@ch@cksanitize{#1}#2,}%
  \ifboolTF{in@}{\XKV@normalizelist{1}#2}{}%
}
\robust@redef*\XKV@checksanitizeb#1#2{%
  \XKV@ch@cksanitize{#1}#2,%
  \edef#2{\unexpanded{#1}}%
  \ifboolTF{in@}{\XKV@normalizelist{0}#2}%
}
% Save/add to 'expand name keys':
\robust@def*\expandnamekeys{\XKV@stfalse\XKV@testoptb\XKV@expandnamekeys}
\robust@def*\gexpandnamekeys{\XKV@sttrue\XKV@testoptb\XKV@expandnamekeys}
\robust@def*\XKV@expandnamekeys#1{%
  \ifdefFT{XKV@\XKV@header expandname}{%
    \XKV@checksanitizeb{#1}\XKV@tempa
    \ifXKV@st\expandafter\global\fi
    \csn@edef{XKV@\XKV@header expandname}{\expandcsonce\XKV@tempa}%
  }{%
    \aftercsname\XKV@merge{XKV@\XKV@header expandname}{#1}\XKV@getsg
  }%
}
% Remove from 'expand name keys' list:
\robust@def*\remexpandnamekeys{\XKV@stfalse\XKV@testoptb\XKV@remexpandnamekeys}
\robust@def*\gremexpandnamekeys{\XKV@sttrue\XKV@testoptb\XKV@remexpandnamekeys}
\robust@def*\XKV@remexpandnamekeys#1{%
  \ifdefFT{XKV@\XKV@header expandname}{%
    \XKV@err{No 'expandname keys' defined for family `\XKV@header'}%
  }{%
    \aftercsname\XKV@delete{XKV@\XKV@header expandname}{#1}\XKV@getsg
  }%
}
% Delete entire 'expand name keys' list:
\robust@def*\delexpandnamekeys{\XKV@stfalse\XKV@testoptb\XKV@delexpandnamekeys}
\robust@def*\gdelexpandnamekeys{\XKV@sttrue\XKV@testoptb\XKV@delexpandnamekeys}
\robust@def*\XKV@delexpandnamekeys{%
  \ifdefFT{XKV@\XKV@header expandname}{%
    \XKV@err{No 'expandname keys' defined for family `\XKV@header'}%
  }{%
    \ifXKV@st\expandafter\global\fi
    \undefcsn{XKV@\XKV@header expandname}%
  }%
}
\robust@def*\XKV@checkexpandname#1{%
  \ifboolTF{XKV@expandkeyname}{%
    \expandafter
  }{%
    \XKV@ch@ckexpandname{#1}%
  }%
}
\robust@def*\XKV@ch@ckexpandname#1{%
  \begingroup
  \def\XKV@exponce{01}%
  \def\XKV@exptwice{01}%
  \def\XKV@tempc##1{%
    \ifcsndefFT{XKV@\XKV@prefix ##1@expandname}{}{%
      \expandcsnonce{XKV@\XKV@prefix ##1@expandname}%
    }%
  }%
  \XKVfor*\XKV@fams\do{%
    \expandafter\XKV@g@tkeyname#1=\@nil\XKV@tempa
    \xifinsetTF{,\expandcsonce\XKV@tempa,}{,\XKV@tempc{##1},}{%
      \def\XKV@exponce{00}%
      \XKVforbreak
    }{%
      \expandafter\expandafter\expandafter
      \XKV@g@tkeyname#1=\@nil\XKV@tempa
      \xifinsetTF{,\expandcstwice\XKV@tempa,}{,\XKV@tempc{##1},}{%
        \def\XKV@exptwice{00}%
        \XKVforbreak
      }{}%
    }%
  }%
  \ifswitchTF{XKV@exponce}{%
    \endgroup\expandafter
  }{%
    \ifswitchTF{XKV@exptwice}{%
      \endgroup\expandafter\expandafter\expandafter
    }{%
      \endgroup
    }%
  }%
}
\robust@redef\XKV@setkeys[#1]#2{%
  \edef\XKV@userkeys{\unexpanded{#2}}%
  \XKV@normalizelist{1}\XKV@userkeys
  \let\XKV@naa\@empty
  \XKVfor*\XKV@userkeys\do{%
    \XKV@checkexpandname{##1}%
    \XKV@g@tkeyname##1=\@nil\XKV@tempa
    \XKV@addtolist@x\XKV@naa\XKV@tempa
  }%
  \ifnum\XKV@depth=\z@\let\XKV@rm\@empty\fi
  \XKV@usepresetkeys{#1}{preseth}%
  \expandafter\XKV@s@tkeys\expandafter{\XKV@userkeys}{#1}%
  \XKV@usepresetkeys{#1}{presett}%
  \let\CurrentOption\@empty
}
\robust@redef\XKV@s@tkeys#1#2{%
  \edef\XKV@na{\unexpanded{#2}}%
  \XKV@normalizelist{0}\XKV@na
  \XKVfor#1\do{%
    \edef\CurrentOption{\unexpanded{##1}}%
    \XKV@checkexpandname{##1}%
    \XKV@s@tk@ys##1==\@nil
  }%
}

\XKVforwhile*\@filelist\XKV@tempa\ifx\XKV@documentclass\@undefined\fi{%
  \filename@parse\XKV@tempa
  \ifxTF\filename@ext\@clsextension{%
    \ifcsndefFT{opt@\filename@area\filename@base.\filename@ext}{}{%
      \edef\XKV@documentclass{\filename@area\filename@base.\filename@ext}%
    }%
  }{}%
}
\robust@def*\XKV@filterclassoptions{%
  \XKV@sgfalse
  \ifx\@classoptionslist\@undefined\else
    \ifx\@classoptionslist\relax\else\XKV@sgtrue\fi
  \fi
  \ifXKV@sg
    \let\XKV@filterclassoptions\relax
    \let\XKV@classoptionslist\@classoptionslist
    \def\@classoptionslist{}%
    \XKVfor*\XKV@classoptionslist\do{%
      \ifinsetTF={##1}{}{%
        \edef\@classoptionslist{%
          \@classoptionslist\ifx\@classoptionslist\@empty\else,\fi
          \unexpanded{##1}%
        }%
      }%
    }%
  \fi
}
\ifdefTF\XKV@documentclass{%
  \XKV@filterclassoptions
}{%
  \let\XKV@documentclass\@empty
  \let\XKV@classoptionslist\@empty
  \edef\@popfilename{\expandcsonce\@popfilename\XKV@filterclassoptions}%
}
\robust@redef*\XKV@testopte#1{%
  \XKV@ifstar{\XKV@sttrue\XKV@t@stopte#1}{\XKV@stfalse\XKV@t@stopte#1}%
}
\robust@redef*\XKV@t@stopte#1{\@testopt{\XKV@t@st@pte#1}{KV}}
\robust@redef*\XKV@t@st@pte#1[#2]{%
  \XKV@makepf{#2}%
  \@ifnextchar<{\XKV@@t@st@pte#1}%
    {\XKV@@t@st@pte#1<\@currname.\@currext>}%
}
\robust@redef*\XKV@@t@st@pte#1<#2>{%
  \XKV@sp@deflist\XKV@fams{#2}%
  \@testopt#1{}%
}
\robust@redef*\DeclareOptionX{%
  \let\@fileswith@pti@ns\@badrequireerror
  \XKV@ifstar\XKV@dox\XKV@d@x
}
\robust@redef\XKV@dox#1{\XKV@toks{#1}\edef\XKV@doxs{\the\XKV@toks}}
\robust@redef*\XKV@d@x{\@testopt\XKV@@d@x{KV}}
\robust@redef*\XKV@@d@x[#1]{%
  \@ifnextchar<{\XKV@@@d@x[#1]}{\XKV@@@d@x[#1]<\@currname.\@currext>}%
}
\robust@redef*\XKV@@@d@x[#1]<#2>#3{\@testopt{\define@key[#1]{#2}{#3}}{}}
\robust@redef*\ExecuteOptionsX{\XKV@stfalse\XKV@plfalse\XKV@t@stopte\XKV@setkeys}
\robust@redef*\ProcessOptionsX{\XKV@plfalse\XKV@testopte\XKV@pox}
\robust@redef*\XKV@pox[#1]{%
  \XKV@normalizelist{1}\XKV@classoptionslist
  \let\XKV@tempa\@empty
  \XKV@inpoxtrue
  \let\@fileswith@pti@ns\@badrequireerror
  \edef\XKV@testclass{\@currname.\@currext}%
  \ifxTF\XKV@testclass\XKV@documentclass{%
    \let\@unusedoptionlist\XKV@classoptionslist
    \ifdefFT{ver@xkvltxp.sty}{}{%
      \@onelevel@sanitize\@unusedoptionlist
    }%
  }{%
    \ifboolTF{XKV@st}{%
      \ifcsnullTF\XKV@classoptionslist{}{%
        \XKVfor*\XKV@classoptionslist\do{%
          % When 'xkvltxp' or 'catoptions' is loaded, options aren't expanded:
          \XKV@checkexpandname{##1}%
          \XKV@g@tkeyname##1=\@nil\CurrentOption
          \XKV@key@if@ndefined{\CurrentOption}{}{%
            \expandafter\XKV@useoption\expandafter{\CurrentOption}%
            \XKV@addtolist@n\XKV@tempa{##1}%
          }%
        }%
      }%
    }{}%
  }%
  \aftercsname{\XKV@addtolist@o\XKV@tempa}{opt@\@currname.\@currext}%
  \cptexpandargonce{\XKV@setkeys[#1]}\XKV@tempa
  \let\XKV@doxs\relax\let\XKV@rm\@empty
  \XKV@inpoxfalse
  \let\@fileswith@pti@ns\@@fileswith@pti@ns
  \AtEndOfPackage{\let\@unprocessedoptions\relax}%
}
\robust@redef*\XKV@useoption#1{%
  \def\XKV@resa{#1}%
  \ifdefFT{ver@xkvltxp.sty}{}{%
    \@onelevel@sanitize\XKV@resa
  }%
  \@expandtwoargs\@removeelement{\XKV@resa}%
    {\@unusedoptionlist}\@unusedoptionlist
}
\define@boolkey[KV]{keyvalx}[XKV@]{expandkeyname}[true]{}
\robust@def*\ExpandKeynameInSetkeys{%
  \setkeys[KV]{keyvalx}{expandkeyname=true}%
}
\robust@def*\NoExpandKeynameInSetkeys{%
  \setkeys[KV]{keyvalx}{expandkeyname=false}%
}
\DeclareOptionX*{%
  \PackageWarning{keyvalx}{Unknown option '\CurrentOption' ignored}%
}
\ExecuteOptionsX[KV]<keyvalx>{expandkeyname=false}
\ProcessOptionsX*[KV]<keyvalx>\relax
\XKV@restorecatcodes
\endinput 
\end{filecontents}

% Your example document:
\documentclass%[expandkeyname]
  {article}
\usepackage%[expandkeyname]
  {keyvalx}
\makeatletter
\define@cmdkey{gus}[c@]{a}[a]{}
\define@cmdkey{gus}[c@]{b}[b]{}
\define@cmdkey{gus}[c@]{c}[c]{}
\newcommand{\dispKeys}[2][toMakeItMoreComplex]{%
  \setkeys{gus}{a,b,c,#2}%
  c@a = \c@a{} \\
  c@b = \c@b{} \\
  c@c = \c@c{} \\
}
\makeatother

\newcommand{\prefilled}[2][toMakeItMoreComplex]{%
  \dispKeys[#1]{a=prefilled,#2}%
}

\begin{document}
\setkeys{gus}{a,b}

\def\dummy{dummy}
\prefilled[\dummy]{}
\prefilled[\dummy]{b=other}

\def\otherArgs{c}
%\ExpandKeynameInSetkeys
% Enter key 'c' as 'expand name key':
\expandnamekeys{gus}{c}
\prefilled[\dummy]{b=other,\otherArgs}

\def\otherArgs{c=another}
\prefilled[\dummy]{b=other, \otherArgs}
%\NoExpandKeynameInSetkeys
\end{document}
share|improve this answer
    
It seems to be a nice generic solution. I have done a quick fix for now. When I cleanup the macros I will definitely test this solution with the others. Thanks a lot. –  Gus May 13 '12 at 18:18
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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