## LATEX-L@LISTSERV.UNI-HEIDELBERG.DE

#### View:

 Message: [ First | Previous | Next | Last ] By Topic: [ First | Previous | Next | Last ] By Author: [ First | Previous | Next | Last ] Font: Proportional Font

Subject:

Re: safer quarks

From:

Date:

Sat, 7 May 2011 07:04:37 +0100

Content-Type:

text/plain

Parts/Attachments:

 text/plain (111 lines)
 On 07/05/2011 04:42, Bruno Le Floch wrote: > if I understand correctly, quarks are meant to work in cases like > > \def\foo{#1} > \ifx\foo\quark ... \else ... \fi > > This requires quarks to be defined as expanding to themselves. > Or it requires to distinguish between a quark and a token list containing > that quark. > > I personally don't use quarks as anything else than delimiters, so any > definition is fine, but I guess that property of quarks is used in > constructions > like > > \tl_set:Nn \foo {#1} > \quark_if_recursion_tail_stop:N \foo > > or > > \prop_get:NnN \foo {key} \bar > \quark_if_no_value:NTF \bar { } { } > > This could be solved by altering quark tests, perhaps...? This has all been discussed before, of course, but I think there is some merit in looking again at it. I think we have two quarks that are tested in this way: \q_no_value and \q_nil. So I did some testing using the siunitx manual. With the definitions \cs_set_nopar:Npn \q_no_value \q_no_value { \q_no_value } \tl_const:Nn \c_q_no_value_tl { \q_no_value } \prg_set_conditional:Npnn \quark_if_no_value:N #1 { p , T , F , TF }   {      \if_meaning:w \q_no_value #1       \prg_return_true:      \else:        \if_meaning:w \c_q_no_value_tl #1         \prg_return_true:        \else:          \prg_return_false:        \fi:      \fi:   } \cs_set_nopar:Npn \q_no_nil \q_no_nil { \q_no_nil } \tl_const:Nn \c_q_nil_tl { \q_nil } \prg_set_conditional:Npnn \quark_if_nil:N #1 { p , T , F , TF }   {      \if_meaning:w \q_nil #1       \prg_return_true:      \else:        \if_meaning:w \c_q_nil_tl #1         \prg_return_true:        \else:          \prg_return_false:        \fi:      \fi:   } I get very little change in compile time on my laptop (which admittedly is a fast system): the .dtx takes about 13 seconds with the current definitions and with the modified ones above. More importantly, they does not break anything. (Delimiting the macro with itself will of course be valid if there are two adjacent quarks, but should 'unwind' to an error on full expansion.) There is also a need to alter: \tl_const:Nn \c_q_recursion_tail_tl { \q_recursion_tail } \cs_set:Npn \quark_if_recursion_tail_stop:N #1   {     \if_meaning:w #1 \q_recursion_tail       \exp_after:wN \use_none_delimit_by_q_recursion_stop:w     \else:       \if_meaning:w #1 \c_q_recursion_tail_tl         \exp_after:wN \exp_after:wN \exp_after:wN           \use_none_delimit_by_q_recursion_stop:w       \fi:     \fi:   } \cs_set:Npn \quark_if_recursion_tail_stop_do:Nn #1#2   {     \if_meaning:w #1 \q_recursion_tail       \exp_after:wN \use_i_delimit_by_q_recursion_stop:nw     \else:       \if_meaning:w #1 \c_q_recursion_tail_tl         \exp_after:wN \exp_after:wN \exp_after:wN           \use_i_delimit_by_q_recursion_stop:nw       \else:         \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n       \fi:     \fi:       {#2}   } as these are needed by map_variable implementations (and perhaps in other places). Now, I think that this is not such a bad idea: the infinite loop problem is one I suspect most of us have never been too keen on (it certainly causes me headaches from time to time). In the test file, the proposed change breaks the trivial 'print the definition stuff', obviously, but also   \quark_if_nil:oTF \q_nil \TRUE \FALSE which leaves me the question 'Do we really need this?' That I know of, we've never used the fact that a single quark expansion leaves the quark unchanged. Joseph