9

As per Xparse's new e-type argument (replacement for k-type argument), support for xparse's k_ argument type is no longer available as of TeXLive 2016 and thus have stuck to TeXLive 2015 so far. I have numerous macros that are defined using the older k_ arguments, so wondering if there is an easy patch that I can apply so that I can use the new version of xparse and still have the k_ macros work.

I am willing to discard the k_ and use the new e_ but don't like the idea of changing all the macros at once and then having to debug where things went wrong. If I have a single (patched) version of xparse that supports both argument types, the transition will be a lot easier. Also, in case I run into some issue with TeXLive versions newer than 2015, I need to be able to revert back to TeXLive 2015 until I resolve any issues.

The solution I have below is too cumbersome due to the number of macros involved. Having a patch would allow me to use both as I transition to using the e_ argument types, and only revert to the solution below should I run into issues with newer versions.

References:

MWE

\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}

\makeatletter
    %%  https://tex.stackexchange.com/questions/96570/automatically-determine-which-texlive-version-is-being-used
    \def\getversion{\expandafter\get@version\pdftexbanner\@nil}
    \def\get@version#1201#2)#3\@nil{\def\TeXLiveVersion{201#2}}
\makeatother
\getversion


\ifnum\TeXLiveVersion<2016
    \NewDocumentCommand\MyMacro{k_}{%
        \IfNoValueTF{#1}{%
            \mathbf{A}
        }{%
            A_{\textcolor{red}{#1}}
        }%
    }
\else
    \NewDocumentCommand\MyMacro{e_}{%
      \MyMacroProcess#1%
    }
    \NewDocumentCommand\MyMacroProcess{m}{%
        \IfNoValueTF{#1}{%
            \mathbf{A}
        }{%
            A_{\textcolor{red}{#1}}
        }%
    }
\fi


\begin{document}

With a subscript: $\MyMacro_{\pi}$ 

Without any subscript: $\MyMacro$ 

\end{document}
  • you don't really want to test the version of texlive, rather the version of xparse eg \@ifpackagelater{xparse}{2017/02/10}{this}{that} – David Carlisle Mar 6 '17 at 22:02
  • @DavidCarlisle: Yep, that would be a better test. However, I think the k_ option type was dropped before 2017-02-10. – Peter Grill Mar 6 '17 at 22:06
  • 2
    I realize the feature was marked as experimental, and I don't question the team had the right to drop it. However, a transition period would have been useful. A version of xparse could have been released with both argument types and a warning issued for usages of the k-type. Later, the feature could have been removed completely. – gigabytes Mar 6 '17 at 22:34
  • 1
    @Manuel Yes but the internals have changed (to support # in optional args, for example): see my answer here! – Joseph Wright Mar 7 '17 at 9:26
  • 2
    @gigabytes One issue with any 'transition' period is that people don't update their code until it breaks! – Joseph Wright Mar 7 '17 at 9:27
12
+200

With the current xparse release (2017/12/16), the following will re-add the k-type argument:

\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}

\ExplSyntaxOn

\tl_if_exist:NF \c_novalue_tl
  { \tl_const:Nx \c_novalue_tl { \c__xparse_no_value_tl } }
\cs_if_exist:NF \__xparse_single_char_check:n
  { \cs_set_eq:NN \__xparse_single_char_check:n \__xparse_single_token_check:n }
\cs_if_exist:NF \__xparse_add_type_K:w
  {
    \cs_set_protected:Npn \__xparse_tmp:w #1
      {
        \cs_new_protected:Npn \__xparse_normalize_type_k:w ##1
          { \__xparse_normalize_type_K:w ##1 {#1} }
      }
    \exp_args:No \__xparse_tmp:w { \c_novalue_tl }
    \cs_new_protected:Npn \__xparse_normalize_type_K:w #1#2
      {
        \__xparse_single_char_check:n {#1}
        \quark_if_recursion_tail_stop_do:nn {#2} { \__xparse_bad_arg_spec:wn }
        \tl_put_right:Nn \l__xparse_arg_spec_tl { K #1 {#2} }
        \tl_put_right:Nn \l__xparse_last_delimiters_tl {#1}
        \bool_set_false:N \l__xparse_grab_expandably_bool
        \__xparse_normalize_arg_spec_loop:n
      }
    \cs_new_protected:Npn \__xparse_add_type_K:w #1#2
      {
        \__xparse_flush_m_args:
        \__xparse_add_default:n {#2}
        \__xparse_add_grabber_optional:N K
        \tl_put_right:Nn \l__xparse_signature_tl { #1 }
        \__xparse_prepare_signature:N
      }
    \cs_new_protected:Npn \__xparse_grab_K:w #1#2 \__xparse_run_code:
      {
        \__xparse_grab_K:NnNn #1 {#2}
          \cs_set_protected_nopar:Npn
          { _ignore_spaces }
      }
    \cs_new_protected:Npn \__xparse_grab_K_long:w #1#2 \__xparse_run_code:
      {
        \__xparse_grab_K:NnNn #1 {#2}
          \cs_set_protected:Npn
          { _ignore_spaces }
      }
    \cs_new_protected:Npn \__xparse_grab_K_trailing:w #1#2 \__xparse_run_code:
      {
        \__xparse_grab_K:NnNn #1 {#2}
          \cs_set_protected_nopar:Npn
          { }
      }
    \cs_new_protected:Npn \__xparse_grab_K_long_trailing:w #1#2 \__xparse_run_code:
      {
        \__xparse_grab_K:NnNn #1 {#2}
          \cs_set_protected:Npn
          { }
      }
    \cs_new_protected:Npn \__xparse_grab_K:NnNn #1#2#3#4
      {
        \tl_set:Nn \l__xparse_signature_tl {#2}
        \exp_after:wN #3 \l__xparse_fn_tl ##1
          {
            \__xparse_add_arg:n {##1}
          }
        \use:c { peek_meaning_remove #4 :NTF } #1
          { \l__xparse_fn_tl }
          {
            \__xparse_add_arg:o \c_novalue_tl
          }
      }
  }
\ExplSyntaxOff
%
\NewDocumentCommand\MyMacro{k_}{%
  \IfNoValueTF{#1}{%
      \mathbf{A}%
  }{%
      A_{\textcolor{red}{#1}}%
  }%
}


\begin{document}

With a subscript: $\MyMacro_{\pi}$ 

Without any subscript: $\MyMacro$ 

\end{document}

I have raised the transition question with the team, and will either update the answer here on the next release (if required) or arrange for k-type to have some (limited) transitional support. Note though that this entire area is still very much in flux!

  • I am waiting for the e type paramater to be taken off the experimental tag before replacing the older k_ and t_ arg types that I have used in numerous macros. – Peter Grill Dec 29 '17 at 10:28
  • @PeterGrill That may never happen: the whole point of xparse is to allow some experimentation. What I can say is we won't be going back to k. – Joseph Wright Dec 29 '17 at 10:38
  • @PeterGrill We have a whole question of what to do with the non-LaTeX2e-like ideas: they work but do they encourage the wrong approaches (see the g-type for example). – Joseph Wright Dec 29 '17 at 10:39
  • So, I guess I might as well stick to the k_ type then. – Peter Grill Dec 29 '17 at 18:48
  • I agree with the g type macro possible leasing to problems. But, I actually found a good use of the g type parameter. When I add a new mandatory parameter to a macro, I initalyy use the g type so that I can easliy detect older uses of it until I get around to updating all uses of the macro. Then chnage the g to an m. – Peter Grill Dec 29 '17 at 18:48
4

For the simple case where it is used with a single token e and k are more or less the same so if you just make \IfNoValue a little less fussy abut the difference between {-NoValue-} and -NoValue- then you can alias k to e if it's not already defined so your MWE drops down to:

enter image description here

\documentclass{article}
\usepackage{xparse}
\usepackage{xcolor}

\makeatletter
\ExplSyntaxOn
\ifx\__xparse_normalize_type_k:w\undefined
  \def\__xparse_normalize_type_k:w{\__xparse_normalize_type_e:w}
  \let\xIfNoValueTF\IfNoValueTF
  \def\IfNoValueTF#1{\expandafter\xIfNoValueTF\expandafter{\@car#1.\@nil}}
\fi
\ExplSyntaxOff


    \NewDocumentCommand\MyMacro{k_}{%
        \IfNoValueTF{#1}{%
            \mathbf{A}%
        }{%
            A_{\textcolor{red}{#1}}%
        }%
    }

\begin{document}

With a subscript: $\MyMacro_{\pi}$ 

Without any subscript: $\MyMacro$ 

\end{document}
  • Clearly Joseph's answer is the more complete fix but I'll leave this one here for the "one line" case which might be easier to understand than the full k implementation. (But you should accept Joseph's answer:-) – David Carlisle Mar 7 '17 at 9:35
  • FYI, This works fine in the MWE, but it did not work in my actual use case. I guess my usage must be more than just the basic case. – Peter Grill Mar 20 '17 at 5:58

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.