[latex3-commits] [l3svn] r6863 - Defaults referring to other arguments (expandable case) (see #281, fixes #334)

noreply at latex-project.org noreply at latex-project.org
Thu Feb 9 20:21:19 CET 2017


Author: bruno
Date: 2017-02-09 20:21:19 +0100 (Thu, 09 Feb 2017)
New Revision: 6863

Modified:
   trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg
   trunk/l3packages/xparse/testfiles/xparse001.tlg
   trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg
   trunk/l3packages/xparse/testfiles/xparse004.lvt
   trunk/l3packages/xparse/testfiles/xparse004.tlg
   trunk/l3packages/xparse/xparse.dtx
Log:
Defaults referring to other arguments (expandable case) (see #281, fixes #334)


Modified: trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg	2017-02-09 19:21:09 UTC (rev 6862)
+++ trunk/l3packages/xparse/testfiles/xparse001.ptex.tlg	2017-02-09 19:21:19 UTC (rev 6863)
@@ -665,8 +665,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {m}\foo  \foo code
-{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -677,8 +677,8 @@
 . 
 . Redefining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+m}\foo  \foo code
-{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -689,8 +689,8 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {mmm}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -702,9 +702,9 @@
 . 
 . Redefining command \foo with sig. 'om' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {om}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {om}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -715,9 +715,9 @@
 . 
 . Redefining command \foo with sig. '+o+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+o+m}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+o+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -728,8 +728,9 @@
 . 
 . Redefining command \foo with sig. 'sm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {sm}\foo  \foo code
-{\__xparse_expandable_grab_t:w \foo (arg 1) *\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {sm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_t:w \foo (arg 1)
+*\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -740,10 +741,9 @@
 . 
 . Redefining command \foo with sig. 'osm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {osm}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_t:w \foo (arg 2)
-*\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {osm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_t:w \foo (arg 2) *\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2#3->(#1)(#2)(#3).
@@ -775,9 +775,9 @@
 | Expandable commands must have a final mandatory argument (or no arguments at
 | all). You cannot have a terminal optional argument with expandable commands.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {mo}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_D:w \foo (arg 2)
-[]{-NoValue-}}.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {mo}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_D:w \foo
+(arg 2) []}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1).
@@ -822,8 +822,8 @@
 | The arguments for an expandable command must either all be short or all be
 | long. You have tried to mix the two types.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+mmm}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+mmm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -852,9 +852,9 @@
 | The arguments for an expandable command must either all be short or all be
 | long. You have tried to mix the two types.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {o+m}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {o+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -882,9 +882,9 @@
 | Expandable commands must have a final mandatory argument (or no arguments at
 | all). You cannot have a terminal optional argument with expandable commands.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {r()o}\foo  \foo code
-{\__xparse_expandable_grab_R:w \foo (arg 1)
-(){-NoValue-}\__xparse_expandable_grab_D:w \foo (arg 2) []{-NoValue-}}.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {r()o}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_R:w \foo (arg 1)
+()\__xparse_expandable_grab_D:w \foo (arg 2) []}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).

Modified: trunk/l3packages/xparse/testfiles/xparse001.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.tlg	2017-02-09 19:21:09 UTC (rev 6862)
+++ trunk/l3packages/xparse/testfiles/xparse001.tlg	2017-02-09 19:21:19 UTC (rev 6863)
@@ -665,8 +665,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {m}\foo  \foo code
-{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -677,8 +677,8 @@
 . 
 . Redefining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+m}\foo  \foo code
-{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -689,8 +689,8 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {mmm}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -702,9 +702,9 @@
 . 
 . Redefining command \foo with sig. 'om' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {om}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {om}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -715,9 +715,9 @@
 . 
 . Redefining command \foo with sig. '+o+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+o+m}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+o+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -728,8 +728,9 @@
 . 
 . Redefining command \foo with sig. 'sm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {sm}\foo  \foo code
-{\__xparse_expandable_grab_t:w \foo (arg 1) *\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {sm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_t:w \foo (arg 1)
+*\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -740,10 +741,9 @@
 . 
 . Redefining command \foo with sig. 'osm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {osm}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_t:w \foo (arg 2)
-*\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {osm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_t:w \foo (arg 2) *\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2#3->(#1)(#2)(#3).
@@ -775,9 +775,9 @@
 | Expandable commands must have a final mandatory argument (or no arguments at
 | all). You cannot have a terminal optional argument with expandable commands.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {mo}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_D:w \foo (arg 2)
-[]{-NoValue-}}.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {mo}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_D:w \foo
+(arg 2) []}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1).
@@ -822,8 +822,8 @@
 | The arguments for an expandable command must either all be short or all be
 | long. You have tried to mix the two types.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+mmm}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+mmm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -852,9 +852,9 @@
 | The arguments for an expandable command must either all be short or all be
 | long. You have tried to mix the two types.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {o+m}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {o+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -882,9 +882,9 @@
 | Expandable commands must have a final mandatory argument (or no arguments at
 | all). You cannot have a terminal optional argument with expandable commands.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {r()o}\foo  \foo code
-{\__xparse_expandable_grab_R:w \foo (arg 1)
-(){-NoValue-}\__xparse_expandable_grab_D:w \foo (arg 2) []{-NoValue-}}.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {r()o}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_R:w \foo (arg 1)
+()\__xparse_expandable_grab_D:w \foo (arg 2) []}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).

Modified: trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg	2017-02-09 19:21:09 UTC (rev 6862)
+++ trunk/l3packages/xparse/testfiles/xparse001.uptex.tlg	2017-02-09 19:21:19 UTC (rev 6863)
@@ -665,8 +665,8 @@
 . 
 . Defining command \foo with sig. 'm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {m}\foo  \foo code
-{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -677,8 +677,8 @@
 . 
 . Redefining command \foo with sig. '+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+m}\foo  \foo code
-{\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1->(#1).
@@ -689,8 +689,8 @@
 . 
 . Redefining command \foo with sig. 'mmm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {mmm}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=macro:->\__xparse_start_expandable:nNNNn {mmm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -702,9 +702,9 @@
 . 
 . Redefining command \foo with sig. 'om' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {om}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {om}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -715,9 +715,9 @@
 . 
 . Redefining command \foo with sig. '+o+m' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+o+m}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+o+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -728,8 +728,9 @@
 . 
 . Redefining command \foo with sig. 'sm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {sm}\foo  \foo code
-{\__xparse_expandable_grab_t:w \foo (arg 1) *\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {sm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_t:w \foo (arg 1)
+*\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -740,10 +741,9 @@
 . 
 . Redefining command \foo with sig. 'osm' on line ....
 .................................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {osm}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_t:w \foo (arg 2)
-*\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {osm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_t:w \foo (arg 2) *\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2#3->(#1)(#2)(#3).
@@ -775,9 +775,9 @@
 | Expandable commands must have a final mandatory argument (or no arguments at
 | all). You cannot have a terminal optional argument with expandable commands.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {mo}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_D:w \foo (arg 2)
-[]{-NoValue-}}.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {mo}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_D:w \foo
+(arg 2) []}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1).
@@ -822,8 +822,8 @@
 | The arguments for an expandable command must either all be short or all be
 | long. You have tried to mix the two types.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {+mmm}\foo  \foo code
-{\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
+> \foo=macro:->\__xparse_start_expandable:nNNNn {+mmm}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_m:w \__xparse_expandable_grab_m:w
 \__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
@@ -852,9 +852,9 @@
 | The arguments for an expandable command must either all be short or all be
 | long. You have tried to mix the two types.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {o+m}\foo  \foo code
-{\__xparse_expandable_grab_D:w \foo (arg 1)
-[]{-NoValue-}\__xparse_expandable_grab_m:w }.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {o+m}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_D:w \foo (arg 1)
+[]\__xparse_expandable_grab_m:w }.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).
@@ -882,9 +882,9 @@
 | Expandable commands must have a final mandatory argument (or no arguments at
 | all). You cannot have a terminal optional argument with expandable commands.
 |...............................................
-> \foo=macro:->\__xparse_start_expandable:nNNn {r()o}\foo  \foo code
-{\__xparse_expandable_grab_R:w \foo (arg 1)
-(){-NoValue-}\__xparse_expandable_grab_D:w \foo (arg 2) []{-NoValue-}}.
+> \foo=macro:->\__xparse_start_expandable:nNNNn {r()o}\foo  \foo code \foo
+defaults {\__xparse_expandable_grab_R:w \foo (arg 1)
+()\__xparse_expandable_grab_D:w \foo (arg 2) []}.
 <recently read> }
 l. ...}
 > \foo code=\long macro:#1#2->(#1)(#2).

Modified: trunk/l3packages/xparse/testfiles/xparse004.lvt
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse004.lvt	2017-02-09 19:21:09 UTC (rev 6862)
+++ trunk/l3packages/xparse/testfiles/xparse004.lvt	2017-02-09 19:21:19 UTC (rev 6863)
@@ -264,6 +264,33 @@
     \foo ^{\B} _{\A} +{\D} {\E}
   }
 
+\DeclareExpandableDocumentCommand { \foobar }
+  { D<>{##} t* m R(){##} }
+  { \TYPE { #1 | #2 | #3 | #4 } }
+\TESTEXP { Test~#~in~expandable~argument~specification }
+  {
+    \foobar <1>{#}\relax\NEWLINE
+    \foobar *{#}(2#)\NEWLINE
+    \foobar {#}(2#)\NEWLINE
+    \foobar <1>*{#}(2#)\NEWLINE
+  }
+
+\DeclareExpandableDocumentCommand { \foobar }
+  { D<>{#2} O{#4#1} m O{#3#5} m }
+  { \TYPE { \exp_not:n { #1 | #2 | #3 | #4 | #5 } } }
+\DeclareExpandableDocumentCommand {\baz}
+  { O{#2} O{#3} O{#4} O{#5} O{#6} O{#7} O{#8} O{#9} m }
+  { \TYPE { \exp_not:n {#1} } }
+\TESTEXP { Refer~to~other~args~(expandable) }
+  {
+    \foobar <\A>{\C}{\E}     \NEWLINE
+    \foobar {\C}{\E}         \NEWLINE
+    \foobar {\C}[\D]{\E}     \NEWLINE
+    \foobar [\B]{\C}{\E}     \NEWLINE
+    \foobar <\A>[\B]{\C}{\E} \NEWLINE
+    \baz{\A}
+  }
+
 \TEST { Bad~arguments }
   {
     \DeclareDocumentCommand { \foo } { {abc} {def} } { }
@@ -304,4 +331,11 @@
     \foo ^{a}____ \foo _a_abc_ \foo *_a_
   }
 
+\DeclareDocumentCommand { \foo } { O{\par} m } { \TYPE { |#1|#2| } }
+\TESTEXP { par~in~default~of~short~expandable }
+  {
+    \foo{a} \NEWLINE
+    \foo[a]{b} \NEWLINE
+  }
+
 \END

Modified: trunk/l3packages/xparse/testfiles/xparse004.tlg
===================================================================
--- trunk/l3packages/xparse/testfiles/xparse004.tlg	2017-02-09 19:21:09 UTC (rev 6862)
+++ trunk/l3packages/xparse/testfiles/xparse004.tlg	2017-02-09 19:21:19 UTC (rev 6863)
@@ -1118,12 +1118,74 @@
 {{\C }{-NoValue-}}{\A }|{\C }{-NoValue-}|\E 
 {\A }{\B }|{{\A }{\B }}{\D }|\E 
 ============================================================
+.................................................
+. LaTeX info: "xparse/define-command"
+. 
+. Defining command \foobar with sig. 'D<>{####}t*mR(){####}' on line ....
+.................................................
 ============================================================
-TEST 14: Bad arguments
+TEST 14: Test ## in expandable argument specification
 ============================================================
+! Undefined control sequence.
+<argument> \LaTeX3 error: 
+                           Failed to find required argument starting with '('.
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+1|\BooleanFalse |##|##{\relax }
+##|\BooleanTrue |##|2##
+##|\BooleanFalse |##|2##
+1|\BooleanTrue |##|2##
+============================================================
 .................................................
+. LaTeX info: "xparse/redefine-command"
+. 
+. Redefining command \foobar with sig. 'D<>{##2}O{##4##1}mO{##3##5}m' on line
+. 280.
+.................................................
+.................................................
 . LaTeX info: "xparse/define-command"
 . 
+. Defining command \baz with sig.
+. 'O{##2}O{##3}O{##4}O{##5}O{##6}O{##7}O{##8}O{##9}m' on line ....
+.................................................
+============================================================
+TEST 15: Refer to other args (expandable)
+============================================================
+! Undefined control sequence.
+<argument> \LaTeX3 error: 
+                           Unresolved circular dependency in default values ...
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+! Undefined control sequence.
+<argument> \LaTeX3 error: 
+                           Unresolved circular dependency in default values ...
+l. ...  }
+The control sequence at the end of the top line
+of your error message was never \def'ed. If you have
+misspelled it (e.g., `\hobx'), type `I' and the correct
+spelling (e.g., `I\hbox'). Otherwise just continue,
+and I'll forget about whatever was undefined.
+\A |\C \E \A |\C |\C \E |\E 
+\C \E \C \E \C \E \C \E -NoValue--NoValue-|\C \E \C \E \C \E \C \E \C \E -NoValue-|\C |\C \E |\E 
+\D \D \D \D \D -NoValue-|\D \D \D \D \D -NoValue-|\C |\D |\E 
+\B |\B |\C |\C \E |\E 
+\A |\B |\C |\C \E |\E 
+\A 
+============================================================
+============================================================
+TEST 16: Bad arguments
+============================================================
+.................................................
+. LaTeX info: "xparse/define-command"
+. 
 . Defining command \foo with sig. '{abc}{def}' on line ....
 .................................................
 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
@@ -1271,7 +1333,7 @@
 undefined
 ============================================================
 ============================================================
-TEST 15: Optional+mandatory with same delimiter
+TEST 17: Optional+mandatory with same delimiter
 ============================================================
 .................................................
 . LaTeX info: "xparse/define-command"
@@ -1408,3 +1470,14 @@
 |{a}{-NoValue-}|\BooleanFalse |abc|
 |{-NoValue-}{-NoValue-}|\BooleanTrue |a|
 ============================================================
+.................................................
+. LaTeX info: "xparse/define-command"
+. 
+. Defining command \foo with sig. 'O{\par }m' on line ....
+.................................................
+============================================================
+TEST 18: par in default of short expandable
+============================================================
+\foo {a}
+\foo [a]{b}
+============================================================

Modified: trunk/l3packages/xparse/xparse.dtx
===================================================================
--- trunk/l3packages/xparse/xparse.dtx	2017-02-09 19:21:09 UTC (rev 6862)
+++ trunk/l3packages/xparse/xparse.dtx	2017-02-09 19:21:19 UTC (rev 6863)
@@ -349,9 +349,6 @@
 %   \margins [1cm] {a} [2cm] {b}  % => {(1cm,a,2cm,b)}
 % \end{verbatim}
 %
-% Currently, referring to other arguments in default values is not
-% supported for expandable commands.
-%
 % Users should note that support for default arguments referring to
 % other arguments is somewhat experimental. Feedback is therefore very
 % welcome on the \texttt{LaTeX-L} mailing list.
@@ -1091,12 +1088,23 @@
     \cs_generate_from_arg_count:cNnn
       { \l_@@_function_tl \c_space_tl code }
       \cs_set:Npn \l_@@_current_arg_int {#3}
+    \bool_if:NT \l_@@_defaults_bool
+      {
+        \use:x
+          {
+            \cs_generate_from_arg_count:cNnn
+              { \l_@@_function_tl \c_space_tl defaults }
+              \cs_set:Npn \l_@@_current_arg_int
+              { \exp_not:o \l_@@_defaults_tl }
+          }
+      }
     \cs_set_nopar:Npx #1
       {
-        \exp_not:N \@@_start_expandable:nNNn
+        \exp_not:N \@@_start_expandable:nNNNn
           { \exp_not:n {#2} }
           \exp_not:c { \l_@@_function_tl \c_space_tl }
           \exp_not:c { \l_@@_function_tl \c_space_tl code }
+          \exp_not:c { \l_@@_function_tl \c_space_tl defaults }
           { \exp_not:o \l_@@_signature_tl }
       }
     \bool_if:NTF \l_@@_all_long_bool
@@ -1170,18 +1178,6 @@
 %
 % \subsection{Structure of \pkg{xparse} commands}
 %
-% \begin{macro}{\@@_start_expandable:nNNn}
-%   This is called for all expandable commands.  |#4| is the signature,
-%   responsible for grabbing arguments.  |#3| is the code to run.
-%   |#2|~is a function (named after the command) that grabs a single
-%   argument in the input stream.  The argument specification |#1| is
-%   unused but used by diagnostic functions.
-%    \begin{macrocode}
-\cs_new:Npn \@@_start_expandable:nNNn #1#2#3#4
-  { #4 \@@_grab_expandable_end:wN #3 \q_@@ #2 }
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_start:nNNnnn}
 %   This sets up a few variables to minimize the boilerplate code
 %   included in all \pkg{xparse}-defined commands.  It then runs the
@@ -1346,6 +1342,77 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\@@_start_expandable:nNNNn}
+%   This is called for all expandable commands.  |#5| is the signature,
+%   responsible for grabbing arguments.  |#4| is used to determine
+%   default values.  |#3| is the code to run.
+%   |#2|~is a function (named after the command) that grabs a single
+%   argument in the input stream.  The argument specification |#1| is
+%   unused but used by diagnostic functions.
+%    \begin{macrocode}
+\cs_new:Npn \@@_start_expandable:nNNNn #1#2#3#4#5
+  { #5 \@@_end_expandable:NNw #4 #3 \q_@@ #2 }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_end_expandable:NNw}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_aux:w,
+%   \@@_end_expandable_aux:nNNN, \@@_end_expandable_defaults:nnnNNn}
+% \begin{macro}[EXP,aux]{\@@_end_expandable_defaults:nnw,
+%   \@@_end_expandable_defaults:nw}
+%   Followed by a function |#1| to determine default values, the code
+%   |#2|, arguments that have been grabbed, then \cs{q_@@} and a generic
+%   grabber.  The idea to find default values is similar to the
+%   non-expandable case but we cannot define an auxiliary function, so
+%   at every step in the loop we need to go through all arguments
+%   searching for which ones started out as |-NoValue-| and replacing
+%   these by the newly computed values.  In fact we need to keep track
+%   of three versions of all arguments: the original version, the
+%   previous version with default values, and the currently built
+%   version (first argument of \cs{@@_end_expandable_defaults:nnnNNn}).
+%    \begin{macrocode}
+\cs_new:Npn \@@_end_expandable:NNw #1#2
+  { \@@_end_expandable_aux:w #1#2 \prg_do_nothing: }
+\cs_new:Npn \@@_end_expandable_aux:w #1#2#3 \q_@@ #4
+  { \exp_args:No \@@_end_expandable_aux:nNNN {#3} #1 #2 #4 }
+\cs_new:Npn \@@_end_expandable_aux:nNNN #1#2#3#4
+  {
+    \cs_if_exist:NF #2 { \exp_after:wN \use_iv:nnnn }
+    \@@_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
+      { } { } { } { } { } { } { } { } { } { }
+      {
+        \__msg_kernel_expandable_error:nnn
+          { xparse } { loop-in-defaults } {#4}
+        \use_iv:nnnn
+      }
+    \q_stop
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nnnNNn #1#2#3#4#5#6
+  {
+    #6
+    \str_if_eq:nnTF {#1} {#2}
+      { \use_i_delimit_by_q_stop:nw { #5 #1 } }
+      {
+        \exp_args:No \@@_tl_mapthread_function:nnN
+          { #4 #1 } {#3}
+          \@@_end_expandable_defaults:nnw
+        \@@_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5
+      }
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nnw #1#2
+  {
+    \@@_if_no_value:nTF {#2}
+      { \exp_args:No \@@_end_expandable_defaults:nw { \use_none:n #1 } }
+      { \@@_end_expandable_defaults:nw {#2} }
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nw
+    #1#2 \@@_end_expandable_defaults:nnnNNn #3
+  { #2 \@@_end_expandable_defaults:nnnNNn { #3 {#1} } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \subsection{Normalizing the argument specifications}
 %
 % \begin{macro}{\@@_normalize_arg_spec:n}
@@ -1961,6 +2028,7 @@
 %   that default value (it may involve other arguments).  Defaults are
 %   always stored with a leading |.| except for \texttt{E}-type
 %   arguments, to distinguish them.
+%   This is also used by expandable functions.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_default:n #1
   {
@@ -1998,26 +2066,27 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_add_expandable_type_D:w}
-% \begin{macro}{\@@_add_expandable_type_D_aux:NNn}
-% \begin{macro}{\@@_add_expandable_type_D_aux:Nn}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NN}
+% \begin{macro}{\@@_add_expandable_type_D_aux:N}
 %   The set up for \texttt{d}- and \texttt{D}-type arguments is the same,
 %   and involves constructing a rather complex auxiliary which is used
 %   repeatedly when grabbing. There is an auxiliary here so that the
 %   \texttt{R}-type can share code readily.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_D:w #1#2
+\cs_new_protected:Npn \@@_add_expandable_type_D:w #1#2#3
   {
+    \@@_add_default:n {#3}
     \tl_if_eq:nnTF {#1} {#2}
       {
         \@@_add_expandable_grabber_optional:n { D_alt }
-        \@@_add_expandable_type_D_aux:Nn #1
+        \@@_add_expandable_type_D_aux:N #1
       }
       {
         \@@_add_expandable_grabber_optional:n { D }
-        \@@_add_expandable_type_D_aux:NNn #1#2
+        \@@_add_expandable_type_D_aux:NN #1#2
       }
   }
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNn #1#2#3
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2
   {
     \bool_if:NTF \l_@@_all_long_bool
       { \cs_set:cpx }
@@ -2027,7 +2096,7 @@
     \tl_put_right:Nx \l_@@_signature_tl
       {
         \exp_not:c  { \l_@@_expandable_aux_name_tl }
-        \exp_not:n { #1 #2 {#3} }
+        \exp_not:n { #1 #2 }
       }
     \bool_set_false:N \l_@@_long_bool
     \@@_prepare_signature:N
@@ -2037,7 +2106,7 @@
 %  contrast to the non-expandable route, the grabber here has to act
 %  differently for this case.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:Nn #1#2
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:N #1
   {
     \bool_if:NTF \l_@@_all_long_bool
       { \cs_set:cpx }
@@ -2047,7 +2116,7 @@
     \tl_put_right:Nx \l_@@_signature_tl
       {
         \exp_not:c  { \l_@@_expandable_aux_name_tl }
-        \exp_not:n { #1 {#2} }
+        \exp_not:n {#1}
       }
     \bool_set_false:N \l_@@_long_bool
     \@@_prepare_signature:N
@@ -2065,6 +2134,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_expandable_type_m:w
   {
+    \@@_add_default:
     \int_incr:N \l_@@_m_args_int
     \@@_add_expandable_grabber_mandatory:n { m }
     \bool_set_false:N \l_@@_long_bool
@@ -2077,16 +2147,17 @@
 %   The \texttt{R}-type is very similar to the \texttt{D}-type
 %   argument, and so the same internals are used.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_R:w #1#2
+\cs_new_protected:Npn \@@_add_expandable_type_R:w #1#2#3
   {
+    \@@_add_default:n {#3}
     \tl_if_eq:nnTF {#1} {#2}
       {
         \@@_add_expandable_grabber_mandatory:n { R_alt }
-        \@@_add_expandable_type_D_aux:Nn #1
+        \@@_add_expandable_type_D_aux:N #1
       }
       {
         \@@_add_expandable_grabber_mandatory:n { R }
-        \@@_add_expandable_type_D_aux:NNn #1#2
+        \@@_add_expandable_type_D_aux:NN #1#2
       }
   }
 %    \end{macrocode}
@@ -2096,6 +2167,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_add_expandable_type_t:w #1
   {
+    \@@_add_default:
     \@@_add_expandable_grabber_optional:n { t }
     \bool_if:NTF \l_@@_all_long_bool
       { \cs_set:cpn }
@@ -2945,7 +3017,7 @@
 % \subsection{Grabbing arguments expandably}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_D:w}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNnwN}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNn}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:NNNwNnnn}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:Nw}
 % \begin{macro}[EXP, aux]{\@@_expandable_grab_D:nnNNNwN}
@@ -2954,25 +3026,24 @@
 %   it.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_D:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_D:NNNnwNn #1 \q_@@ #2 } }
+  { #2 { \@@_expandable_grab_D:NNNwNn #1 \q_@@ #2 } }
 %    \end{macrocode}
-%   We then wish to test whether |#7|, which we just grabbed, is exactly |#2|.
+%   We then wish to test whether |#6|, which we just grabbed, is exactly |#2|.
 %   Expand the only grabber function we have, |#1|, once: the two strings below
-%   are equal if and only if |#7| matches |#2| exactly.\footnote{It is obvious
-%   that if \texttt{\#7} matches \texttt{\#2} then the strings are equal. We
+%   are equal if and only if |#6| matches |#2| exactly.\footnote{It is obvious
+%   that if \texttt{\#6} matches \texttt{\#2} then the strings are equal. We
 %   must check the converse. The right-hand-side of \cs{str_if_eq:onTF} does
 %   not end with \texttt{\#3}, implying that the grabber function took
 %   everything as its arguments. The first brace group can only be empty if
-%   \texttt{\#7} starts with \texttt{\#2}, otherwise the brace group preceding
-%   \texttt{\#7} would not vanish. The third brace group is empty, thus the
+%   \texttt{\#6} starts with \texttt{\#2}, otherwise the brace group preceding
+%   \texttt{\#6} would not vanish. The third brace group is empty, thus the
 %   \cs{q_@@} that was used by our grabber \texttt{\#1} must be the one
-%   that we inserted (not some token in \texttt{\#7}), hence the second brace
-%   group contains the end of \texttt{\#7} followed by \texttt{\#2}. Since this
+%   that we inserted (not some token in \texttt{\#6}), hence the second brace
+%   group contains the end of \texttt{\#6} followed by \texttt{\#2}. Since this
 %   is \texttt{\#2} on the right-hand-side, and no brace can be lost there,
-%   \texttt{\#7} must contain nothing else than its leading \texttt{\#2}.} If
-%   |#7| does not match |#2|, then the optional argument is missing, we use the
-%   default |#4|, and put back the argument |#7| in the input stream.
-%   %^^A There is probably a bug similar to the non-expandable O{\par} bug.
+%   \texttt{\#6} must contain nothing else than its leading \texttt{\#2}.} If
+%   |#6| does not match |#2|, then the optional argument is missing, we use the
+%   default |-NoValue-|, and put back the argument |#6| in the input stream.
 %
 %   If it does match, then interesting things need to be done. We will grab the
 %   argument piece by piece, with the following pattern:
@@ -2994,19 +3065,24 @@
 %   \meta{piece 2}. We stop grabbing arguments once the \meta{piece 2} contains
 %   no opening delimiter any more, hence the balance is reached, and the final
 %   argument is \meta{piece 1} \meta{piece 2}.
+%   The indirection via \cs{@@_tmp:w} allows to insert |-NoValue-| expanded.
 %    \begin{macrocode}
-\cs_new:Npn \@@_expandable_grab_D:NNNnwNn #1#2#3#4#5 \q_@@ #6#7
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } { } #7 #2 \q_@@ #3 }
-      { { } {#2} { } }
+    \cs_new:Npn \@@_expandable_grab_D:NNNwNn ##1##2##3##4 \q_@@ ##5##6
       {
-        #1
-          { \@@_expandable_grab_D:NNNwNnnn #1#2#3#5 \q_@@ #6 }
-          \q_nil { } #2 \ERROR \q_@@ \ERROR
+        \str_if_eq:onTF
+          { ##1 { } { } ##6 ##2 \q_@@ ##3 }
+          { { } {##2} { } }
+          {
+            ##1
+              { \@@_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q_@@ ##5 }
+              \q_nil { } ##2 \ERROR \q_@@ \ERROR
+          }
+          { ##4 {#1} \q_@@ ##5 {##6} }
       }
-      { #5 {#4} \q_@@ #6 {#7} }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
 %   At this stage, |#6| is \cs{q_nil} \Arg{piece 1} \meta{more for piece 1},
 %   and we want to concatenate all that, removing \cs{q_nil}, and keeping the
@@ -3065,26 +3141,30 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_D_alt:w}
-% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNnwNn}
-% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nw}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNwNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nwn}
 %   When the delimiters are identical, nesting is not possible and a simplified
 %   approach is used. The test concept here is the same as for the case where
 %   the delimiters are different.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_D_alt:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_D_alt:NNnwNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_D_alt:NNnwNn #1#2#3#4 \q_@@ #5#6
+  { #2 { \@@_expandable_grab_D_alt:NNwNn #1 \q_@@ #2 } }
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } #6 #2 #2 }
-      { { } #2 }
+    \cs_new:Npn \@@_expandable_grab_D_alt:NNwNn ##1##2##3 \q_@@ ##4##5
       {
-        #1
-          { \@@_expandable_grab_D_alt:Nwn #5 #4 \q_@@ }
-          #6 \ERROR
+        \str_if_eq:onTF
+          { ##1 { } ##5 ##2 ##2 }
+          { { } ##2 }
+          {
+            ##1
+              { \@@_expandable_grab_D_alt:Nwn ##4 ##3 \q_@@ }
+              ##5 \ERROR
+          }
+          { ##3 {#1} \q_@@ ##4 {##5} }
       }
-      { #4 {#3} \q_@@ #5 {#6} }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 \cs_new:Npn \@@_expandable_grab_D_alt:Nwn #1#2 \q_@@ #3
   {
     \tl_if_blank:oTF { \use_none:n #3 }
@@ -3117,56 +3197,64 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_R:w}
-% \begin{macro}[EXP, aux]{\@@_expandable_grab_R_aux:NNwn}
+% \begin{macro}[EXP, aux]{\@@_expandable_grab_R_aux:NNNwNn}
 %   Much the same as for the \texttt{D}-type argument, with only the lead-off
 %   function varying.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_R:w #1 \q_@@ #2
-  { #2 { \@@_expandable_grab_R_aux:NNNnwNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_R_aux:NNNnwNn #1#2#3#4#5 \q_@@ #6#7
+  { #2 { \@@_expandable_grab_R_aux:NNNwNn #1 \q_@@ #2 } }
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } { } #7 #2 \q_@@ #3 }
-      { { } {#2} { } }
+    \cs_new:Npn \@@_expandable_grab_R_aux:NNNwNn ##1##2##3##4 \q_@@ ##5##6
       {
-        #1
-          { \@@_expandable_grab_D:NNNwNnnn #1#2#3#5 \q_@@ #6 }
-          \q_nil { } #2 \ERROR \q_@@ \ERROR
+        \str_if_eq:onTF
+          { ##1 { } { } ##6 ##2 \q_@@ ##3 }
+          { { } {##2} { } }
+          {
+            ##1
+              { \@@_expandable_grab_D:NNNwNnnn ##1##2##3##4 \q_@@ ##5 }
+              \q_nil { } ##2 \ERROR \q_@@ \ERROR
+          }
+          {
+            \__msg_kernel_expandable_error:nnn
+              { xparse } { missing-required } {##2}
+            ##4 {#1} \q_@@ ##5 {##6}
+          }
       }
-      {
-        \__msg_kernel_expandable_error:nnn
-          { xparse } { missing-required } {#2}
-        #5 {#4} \q_@@ #6 {#7}
-      }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_expandable_grab_R_alt:w}
-% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNnwNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNwNn}
 %   When the delimiters are identical, nesting is not possible and a simplified
 %   approach is used. The test concept here is the same as for the case where
 %   the delimiters are different.
 %    \begin{macrocode}
 \cs_new:Npn \@@_expandable_grab_R_alt:w #1 \q_@@ #2
   { #2 { \@@_expandable_grab_R_alt_aux:NNnwNn #1 \q_@@ #2 } }
-\cs_new:Npn \@@_expandable_grab_R_alt_aux:NNnwNn #1#2#3#4 \q_@@ #5#6
+\cs_set_protected:Npn \@@_tmp:w #1
   {
-    \str_if_eq:onTF
-      { #1 { } #6 #2 #2 }
-      { { } #2 }
+    \cs_new:Npn \@@_expandable_grab_R_alt_aux:NNwNn ##1##2##3 \q_@@ ##4##5
       {
-        #1
-          { \@@_expandable_grab_D_alt:Nwn #5 #4 \q_@@ }
-          #6 \ERROR
+        \str_if_eq:onTF
+          { ##1 { } ##5 ##2 ##2 }
+          { { } ##2 }
+          {
+            ##1
+              { \@@_expandable_grab_D_alt:Nwn ##4 ##3 \q_@@ }
+              ##5 \ERROR
+          }
+          {
+            \__msg_kernel_expandable_error:nnn
+              { xparse } { missing-required } {##2}
+            ##3 {#1} \q_@@ ##4 {##5}
+          }
       }
-      {
-        \__msg_kernel_expandable_error:nnn
-          { xparse } { missing-required } {#2}
-        #4 {#3} \q_@@ #5 {#6}
-      }
   }
+\exp_args:No \@@_tmp:w { \c_@@_no_value_tl }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -3198,14 +3286,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[EXP]{\@@_grab_expandable_end:wN}
-%   For the end of the grabbing sequence: get rid of the generic grabber and
-%   insert the code function followed by its arguments.
-%    \begin{macrocode}
-\cs_new:Npn \@@_grab_expandable_end:wN #1 \q_@@ #2 {#1}
-%    \end{macrocode}
-% \end{macro}
-%
 % \subsection{Argument processors}
 %
 % \begin{macro}{\@@_bool_reverse:N}
@@ -3551,7 +3631,7 @@
 %   To determine whether the command is an \pkg{xparse} command check
 %   that its |arg_spec| is empty (this also excludes non-macros) and
 %   that its |replacement_spec| starts with either \cs{@@_start:nNNnnn}
-%   (non-expandable command) or \cs{@@_start_expandable:nNNn}
+%   (non-expandable command) or \cs{@@_start_expandable:nNNNn}
 %   (expandable command).
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_cmd_if_xparse:NTF #1
@@ -3566,7 +3646,7 @@
       }
       {
         { \token_to_str:N \@@_start:nNNnnn } { }
-        { \token_to_str:N \@@_start_expandable:nNNn } { }
+        { \token_to_str:N \@@_start_expandable:nNNNn } { }
       }
   }
 \cs_new:Npn \@@_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}



More information about the latex3-commits mailing list