Prevent newline after clist_map_inline











up vote
5
down vote

favorite
1












I'm trying to automate the creation of some forms, and part of that
effort is automatically creating the correct number of blank rows in a
table-like form. That's led me to the following strange behavior:



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
clistMap{one, two, three}{#1 &\hline}
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


The two tables are typeset differently. I don't understand why.
There's a trailing row after the three rows in the first table. I say
a trailing row, because this following table is typeset the same as
the first.



begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
\
end{tabular}


As one final pair of examples, as minimal as possible, note the same
appearance of the following two tables:



begin{tabular}{|ll|}
clistMap{}{#1 &\hline}
end{tabular}

medskip % So you can see where one table ends and the other begins.

begin{tabular}{|ll|}
\
end{tabular}


How do I get rid of this trailing newline? For bonus points---If you'd
be so kind, future answerers of mine---how would one detect that some
other unexpected control sequences are there? I tried using fancyvrb
commands to do it, and I could never quite get what I wanted; I wasn't
able to detect the \ control sequence, and other characters like
& caused problems. I also tried using the trace package, something
like clistMap expands to around 1000 lines of expanded macros.










share|improve this question
























  • If you use clist_map_function:nN instead it works (don't ask me why, though :)
    – Phelype Oleinik
    Nov 28 at 21:44






  • 3




    you do not have an extra \ to see the effect just use relax or {} or or more or less anything at all after the final hline in your second table.
    – David Carlisle
    Nov 28 at 21:45






  • 2




    clist_map_inline:nn is not expandable and will leave something behind the last hline which create a new line.
    – Ulrike Fischer
    Nov 28 at 21:47






  • 1




    in your first code block you have two tables which have different output, the first has a extra spurious row, but that is not because the l3 code generated an extra \ , add relax before end{tabular} to the second tabular then the two will produce the same output.
    – David Carlisle
    Nov 28 at 22:21






  • 1




    @Beelzebielsk yes anything in that position will start a cell and so a row, an assignment like refstepcounter or just relax (which does nothing) the only things in that position that do not start a new row have to expand to nothing, like @empty
    – David Carlisle
    Nov 28 at 22:30















up vote
5
down vote

favorite
1












I'm trying to automate the creation of some forms, and part of that
effort is automatically creating the correct number of blank rows in a
table-like form. That's led me to the following strange behavior:



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
clistMap{one, two, three}{#1 &\hline}
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


The two tables are typeset differently. I don't understand why.
There's a trailing row after the three rows in the first table. I say
a trailing row, because this following table is typeset the same as
the first.



begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
\
end{tabular}


As one final pair of examples, as minimal as possible, note the same
appearance of the following two tables:



begin{tabular}{|ll|}
clistMap{}{#1 &\hline}
end{tabular}

medskip % So you can see where one table ends and the other begins.

begin{tabular}{|ll|}
\
end{tabular}


How do I get rid of this trailing newline? For bonus points---If you'd
be so kind, future answerers of mine---how would one detect that some
other unexpected control sequences are there? I tried using fancyvrb
commands to do it, and I could never quite get what I wanted; I wasn't
able to detect the \ control sequence, and other characters like
& caused problems. I also tried using the trace package, something
like clistMap expands to around 1000 lines of expanded macros.










share|improve this question
























  • If you use clist_map_function:nN instead it works (don't ask me why, though :)
    – Phelype Oleinik
    Nov 28 at 21:44






  • 3




    you do not have an extra \ to see the effect just use relax or {} or or more or less anything at all after the final hline in your second table.
    – David Carlisle
    Nov 28 at 21:45






  • 2




    clist_map_inline:nn is not expandable and will leave something behind the last hline which create a new line.
    – Ulrike Fischer
    Nov 28 at 21:47






  • 1




    in your first code block you have two tables which have different output, the first has a extra spurious row, but that is not because the l3 code generated an extra \ , add relax before end{tabular} to the second tabular then the two will produce the same output.
    – David Carlisle
    Nov 28 at 22:21






  • 1




    @Beelzebielsk yes anything in that position will start a cell and so a row, an assignment like refstepcounter or just relax (which does nothing) the only things in that position that do not start a new row have to expand to nothing, like @empty
    – David Carlisle
    Nov 28 at 22:30













up vote
5
down vote

favorite
1









up vote
5
down vote

favorite
1






1





I'm trying to automate the creation of some forms, and part of that
effort is automatically creating the correct number of blank rows in a
table-like form. That's led me to the following strange behavior:



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
clistMap{one, two, three}{#1 &\hline}
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


The two tables are typeset differently. I don't understand why.
There's a trailing row after the three rows in the first table. I say
a trailing row, because this following table is typeset the same as
the first.



begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
\
end{tabular}


As one final pair of examples, as minimal as possible, note the same
appearance of the following two tables:



begin{tabular}{|ll|}
clistMap{}{#1 &\hline}
end{tabular}

medskip % So you can see where one table ends and the other begins.

begin{tabular}{|ll|}
\
end{tabular}


How do I get rid of this trailing newline? For bonus points---If you'd
be so kind, future answerers of mine---how would one detect that some
other unexpected control sequences are there? I tried using fancyvrb
commands to do it, and I could never quite get what I wanted; I wasn't
able to detect the \ control sequence, and other characters like
& caused problems. I also tried using the trace package, something
like clistMap expands to around 1000 lines of expanded macros.










share|improve this question















I'm trying to automate the creation of some forms, and part of that
effort is automatically creating the correct number of blank rows in a
table-like form. That's led me to the following strange behavior:



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
clistMap{one, two, three}{#1 &\hline}
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


The two tables are typeset differently. I don't understand why.
There's a trailing row after the three rows in the first table. I say
a trailing row, because this following table is typeset the same as
the first.



begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
\
end{tabular}


As one final pair of examples, as minimal as possible, note the same
appearance of the following two tables:



begin{tabular}{|ll|}
clistMap{}{#1 &\hline}
end{tabular}

medskip % So you can see where one table ends and the other begins.

begin{tabular}{|ll|}
\
end{tabular}


How do I get rid of this trailing newline? For bonus points---If you'd
be so kind, future answerers of mine---how would one detect that some
other unexpected control sequences are there? I tried using fancyvrb
commands to do it, and I could never quite get what I wanted; I wasn't
able to detect the \ control sequence, and other characters like
& caused problems. I also tried using the trace package, something
like clistMap expands to around 1000 lines of expanded macros.







latex3






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 28 at 22:08

























asked Nov 28 at 21:39









Beelzebielsk

306




306












  • If you use clist_map_function:nN instead it works (don't ask me why, though :)
    – Phelype Oleinik
    Nov 28 at 21:44






  • 3




    you do not have an extra \ to see the effect just use relax or {} or or more or less anything at all after the final hline in your second table.
    – David Carlisle
    Nov 28 at 21:45






  • 2




    clist_map_inline:nn is not expandable and will leave something behind the last hline which create a new line.
    – Ulrike Fischer
    Nov 28 at 21:47






  • 1




    in your first code block you have two tables which have different output, the first has a extra spurious row, but that is not because the l3 code generated an extra \ , add relax before end{tabular} to the second tabular then the two will produce the same output.
    – David Carlisle
    Nov 28 at 22:21






  • 1




    @Beelzebielsk yes anything in that position will start a cell and so a row, an assignment like refstepcounter or just relax (which does nothing) the only things in that position that do not start a new row have to expand to nothing, like @empty
    – David Carlisle
    Nov 28 at 22:30


















  • If you use clist_map_function:nN instead it works (don't ask me why, though :)
    – Phelype Oleinik
    Nov 28 at 21:44






  • 3




    you do not have an extra \ to see the effect just use relax or {} or or more or less anything at all after the final hline in your second table.
    – David Carlisle
    Nov 28 at 21:45






  • 2




    clist_map_inline:nn is not expandable and will leave something behind the last hline which create a new line.
    – Ulrike Fischer
    Nov 28 at 21:47






  • 1




    in your first code block you have two tables which have different output, the first has a extra spurious row, but that is not because the l3 code generated an extra \ , add relax before end{tabular} to the second tabular then the two will produce the same output.
    – David Carlisle
    Nov 28 at 22:21






  • 1




    @Beelzebielsk yes anything in that position will start a cell and so a row, an assignment like refstepcounter or just relax (which does nothing) the only things in that position that do not start a new row have to expand to nothing, like @empty
    – David Carlisle
    Nov 28 at 22:30
















If you use clist_map_function:nN instead it works (don't ask me why, though :)
– Phelype Oleinik
Nov 28 at 21:44




If you use clist_map_function:nN instead it works (don't ask me why, though :)
– Phelype Oleinik
Nov 28 at 21:44




3




3




you do not have an extra \ to see the effect just use relax or {} or or more or less anything at all after the final hline in your second table.
– David Carlisle
Nov 28 at 21:45




you do not have an extra \ to see the effect just use relax or {} or or more or less anything at all after the final hline in your second table.
– David Carlisle
Nov 28 at 21:45




2




2




clist_map_inline:nn is not expandable and will leave something behind the last hline which create a new line.
– Ulrike Fischer
Nov 28 at 21:47




clist_map_inline:nn is not expandable and will leave something behind the last hline which create a new line.
– Ulrike Fischer
Nov 28 at 21:47




1




1




in your first code block you have two tables which have different output, the first has a extra spurious row, but that is not because the l3 code generated an extra \ , add relax before end{tabular} to the second tabular then the two will produce the same output.
– David Carlisle
Nov 28 at 22:21




in your first code block you have two tables which have different output, the first has a extra spurious row, but that is not because the l3 code generated an extra \ , add relax before end{tabular} to the second tabular then the two will produce the same output.
– David Carlisle
Nov 28 at 22:21




1




1




@Beelzebielsk yes anything in that position will start a cell and so a row, an assignment like refstepcounter or just relax (which does nothing) the only things in that position that do not start a new row have to expand to nothing, like @empty
– David Carlisle
Nov 28 at 22:30




@Beelzebielsk yes anything in that position will start a cell and so a row, an assignment like refstepcounter or just relax (which does nothing) the only things in that position that do not start a new row have to expand to nothing, like @empty
– David Carlisle
Nov 28 at 22:30










3 Answers
3






active

oldest

votes

















up vote
6
down vote



accepted










You need to use clist_map_function:nN, defining a temporary function:



documentclass{article}

usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{clistMap}{mm}
{
cs_gset:Nn __beelzebielsk_map:n { #2 }
clist_map_function:nN { #1 } __beelzebielsk_map:n
}
ExplSyntaxOff

begin{document}

begin{tabular}{|l|l|}
hline
clistMap{one, two, three}{#1 &\hline}
end{tabular}
qquad
begin{tabular}{|l|l|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}

end{document}


The problem with clist_map_inline:nn is that it leaves TeX in the state where a new cell has already been started when it realizes that the loop has ended.



enter image description here



This is actually what clist_map_inline:nn does: it defines a new “unnamed” function and does clist_map_function:nN with it. However it also has to cover its tracks, particularly for being usable also nested, and for this it uses a counter that has to be stepped down at the end: this is the operation that creates the unwanted additional row.



More explicitly: clist_map_inline:nn { <clist> } { <code> } roughly does



int_incr:Nn <reserved>_int
cs_gset:cn { <reserved> int_eval:n <reserved>_int :n } { <code> }
clist_map_function:nc { <clist> } { <reserved> int_eval:n <reserved>_int :n }
int_decr:Nn <reserved>_int


The function passed to clist_map_function:nc so depends on the nesting level, because the reserved counter is associated to clist mappings. This allows clist_map_inline:nn to contain in its second argument an inner clist_map_inline:nn, which will execute clist_map_function:nc with a different function.



However, the int_decr:Nn <reserved>_int operation will trigger, in your case, TeX starting a new cell. TeX tables are always rebellious beasts. ;-).



With the proposed definition, the operations on counters are skipped; of course you cannot nest clistMap in clistMap.






share|improve this answer























  • Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
    – Beelzebielsk
    Nov 28 at 22:41












  • @Beelzebielsk I added some more explanations
    – egreg
    Nov 28 at 22:54










  • It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
    – Frank Mittelbach
    Nov 30 at 10:51










  • @FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
    – Beelzebielsk
    2 days ago










  • @FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
    – Beelzebielsk
    2 days ago


















up vote
3
down vote













I am sure everyone will forgive my somewhat off-topic answer, and this is just to provide an example illustrating @egreg explanations:



documentclass{article}
usepackage{xinttools}
begin{document}
begin{tabular}{|ll|}
hline
xintFor #1 in {one, two, three}:
{#1 &\hline}
end{tabular}
begin{tabular}{|ll|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


enter image description here



Although xintFor acts non-expandably, it is careful not to do anything "non vanishing by pure expansion" at its end. This allows it to not trigger accidentally a new row. This constraint does however have some limitation effect on the features of xintFor (see the boxed "15.17 xintifForFirst, xintifForLast" comments in xint.pdf).



Notice that the xintFor nests well.



A side remark here is about the strange "gaps" one sees (when magnifying) at the joining of horizontal and vertical lines in both (identical) tabulars: add usepackage{array} to fix that.






share|improve this answer





















  • It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
    – Beelzebielsk
    Nov 30 at 0:44


















up vote
3
down vote













You could make the original function safe in this position by use of noalign



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
noalignbgroupclistMap{one, two, three}{egroup#1 &\hlinenoalignbgroup}egroup
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}





share|improve this answer





















  • Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
    – jfbu
    Nov 30 at 17:10










  • @jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
    – David Carlisle
    Nov 30 at 17:35













Your Answer








StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "85"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f462260%2fprevent-newline-after-clist-map-inline%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
6
down vote



accepted










You need to use clist_map_function:nN, defining a temporary function:



documentclass{article}

usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{clistMap}{mm}
{
cs_gset:Nn __beelzebielsk_map:n { #2 }
clist_map_function:nN { #1 } __beelzebielsk_map:n
}
ExplSyntaxOff

begin{document}

begin{tabular}{|l|l|}
hline
clistMap{one, two, three}{#1 &\hline}
end{tabular}
qquad
begin{tabular}{|l|l|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}

end{document}


The problem with clist_map_inline:nn is that it leaves TeX in the state where a new cell has already been started when it realizes that the loop has ended.



enter image description here



This is actually what clist_map_inline:nn does: it defines a new “unnamed” function and does clist_map_function:nN with it. However it also has to cover its tracks, particularly for being usable also nested, and for this it uses a counter that has to be stepped down at the end: this is the operation that creates the unwanted additional row.



More explicitly: clist_map_inline:nn { <clist> } { <code> } roughly does



int_incr:Nn <reserved>_int
cs_gset:cn { <reserved> int_eval:n <reserved>_int :n } { <code> }
clist_map_function:nc { <clist> } { <reserved> int_eval:n <reserved>_int :n }
int_decr:Nn <reserved>_int


The function passed to clist_map_function:nc so depends on the nesting level, because the reserved counter is associated to clist mappings. This allows clist_map_inline:nn to contain in its second argument an inner clist_map_inline:nn, which will execute clist_map_function:nc with a different function.



However, the int_decr:Nn <reserved>_int operation will trigger, in your case, TeX starting a new cell. TeX tables are always rebellious beasts. ;-).



With the proposed definition, the operations on counters are skipped; of course you cannot nest clistMap in clistMap.






share|improve this answer























  • Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
    – Beelzebielsk
    Nov 28 at 22:41












  • @Beelzebielsk I added some more explanations
    – egreg
    Nov 28 at 22:54










  • It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
    – Frank Mittelbach
    Nov 30 at 10:51










  • @FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
    – Beelzebielsk
    2 days ago










  • @FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
    – Beelzebielsk
    2 days ago















up vote
6
down vote



accepted










You need to use clist_map_function:nN, defining a temporary function:



documentclass{article}

usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{clistMap}{mm}
{
cs_gset:Nn __beelzebielsk_map:n { #2 }
clist_map_function:nN { #1 } __beelzebielsk_map:n
}
ExplSyntaxOff

begin{document}

begin{tabular}{|l|l|}
hline
clistMap{one, two, three}{#1 &\hline}
end{tabular}
qquad
begin{tabular}{|l|l|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}

end{document}


The problem with clist_map_inline:nn is that it leaves TeX in the state where a new cell has already been started when it realizes that the loop has ended.



enter image description here



This is actually what clist_map_inline:nn does: it defines a new “unnamed” function and does clist_map_function:nN with it. However it also has to cover its tracks, particularly for being usable also nested, and for this it uses a counter that has to be stepped down at the end: this is the operation that creates the unwanted additional row.



More explicitly: clist_map_inline:nn { <clist> } { <code> } roughly does



int_incr:Nn <reserved>_int
cs_gset:cn { <reserved> int_eval:n <reserved>_int :n } { <code> }
clist_map_function:nc { <clist> } { <reserved> int_eval:n <reserved>_int :n }
int_decr:Nn <reserved>_int


The function passed to clist_map_function:nc so depends on the nesting level, because the reserved counter is associated to clist mappings. This allows clist_map_inline:nn to contain in its second argument an inner clist_map_inline:nn, which will execute clist_map_function:nc with a different function.



However, the int_decr:Nn <reserved>_int operation will trigger, in your case, TeX starting a new cell. TeX tables are always rebellious beasts. ;-).



With the proposed definition, the operations on counters are skipped; of course you cannot nest clistMap in clistMap.






share|improve this answer























  • Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
    – Beelzebielsk
    Nov 28 at 22:41












  • @Beelzebielsk I added some more explanations
    – egreg
    Nov 28 at 22:54










  • It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
    – Frank Mittelbach
    Nov 30 at 10:51










  • @FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
    – Beelzebielsk
    2 days ago










  • @FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
    – Beelzebielsk
    2 days ago













up vote
6
down vote



accepted







up vote
6
down vote



accepted






You need to use clist_map_function:nN, defining a temporary function:



documentclass{article}

usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{clistMap}{mm}
{
cs_gset:Nn __beelzebielsk_map:n { #2 }
clist_map_function:nN { #1 } __beelzebielsk_map:n
}
ExplSyntaxOff

begin{document}

begin{tabular}{|l|l|}
hline
clistMap{one, two, three}{#1 &\hline}
end{tabular}
qquad
begin{tabular}{|l|l|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}

end{document}


The problem with clist_map_inline:nn is that it leaves TeX in the state where a new cell has already been started when it realizes that the loop has ended.



enter image description here



This is actually what clist_map_inline:nn does: it defines a new “unnamed” function and does clist_map_function:nN with it. However it also has to cover its tracks, particularly for being usable also nested, and for this it uses a counter that has to be stepped down at the end: this is the operation that creates the unwanted additional row.



More explicitly: clist_map_inline:nn { <clist> } { <code> } roughly does



int_incr:Nn <reserved>_int
cs_gset:cn { <reserved> int_eval:n <reserved>_int :n } { <code> }
clist_map_function:nc { <clist> } { <reserved> int_eval:n <reserved>_int :n }
int_decr:Nn <reserved>_int


The function passed to clist_map_function:nc so depends on the nesting level, because the reserved counter is associated to clist mappings. This allows clist_map_inline:nn to contain in its second argument an inner clist_map_inline:nn, which will execute clist_map_function:nc with a different function.



However, the int_decr:Nn <reserved>_int operation will trigger, in your case, TeX starting a new cell. TeX tables are always rebellious beasts. ;-).



With the proposed definition, the operations on counters are skipped; of course you cannot nest clistMap in clistMap.






share|improve this answer














You need to use clist_map_function:nN, defining a temporary function:



documentclass{article}

usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
NewDocumentCommand{clistMap}{mm}
{
cs_gset:Nn __beelzebielsk_map:n { #2 }
clist_map_function:nN { #1 } __beelzebielsk_map:n
}
ExplSyntaxOff

begin{document}

begin{tabular}{|l|l|}
hline
clistMap{one, two, three}{#1 &\hline}
end{tabular}
qquad
begin{tabular}{|l|l|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}

end{document}


The problem with clist_map_inline:nn is that it leaves TeX in the state where a new cell has already been started when it realizes that the loop has ended.



enter image description here



This is actually what clist_map_inline:nn does: it defines a new “unnamed” function and does clist_map_function:nN with it. However it also has to cover its tracks, particularly for being usable also nested, and for this it uses a counter that has to be stepped down at the end: this is the operation that creates the unwanted additional row.



More explicitly: clist_map_inline:nn { <clist> } { <code> } roughly does



int_incr:Nn <reserved>_int
cs_gset:cn { <reserved> int_eval:n <reserved>_int :n } { <code> }
clist_map_function:nc { <clist> } { <reserved> int_eval:n <reserved>_int :n }
int_decr:Nn <reserved>_int


The function passed to clist_map_function:nc so depends on the nesting level, because the reserved counter is associated to clist mappings. This allows clist_map_inline:nn to contain in its second argument an inner clist_map_inline:nn, which will execute clist_map_function:nc with a different function.



However, the int_decr:Nn <reserved>_int operation will trigger, in your case, TeX starting a new cell. TeX tables are always rebellious beasts. ;-).



With the proposed definition, the operations on counters are skipped; of course you cannot nest clistMap in clistMap.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 28 at 22:54

























answered Nov 28 at 21:53









egreg

702k8618733147




702k8618733147












  • Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
    – Beelzebielsk
    Nov 28 at 22:41












  • @Beelzebielsk I added some more explanations
    – egreg
    Nov 28 at 22:54










  • It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
    – Frank Mittelbach
    Nov 30 at 10:51










  • @FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
    – Beelzebielsk
    2 days ago










  • @FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
    – Beelzebielsk
    2 days ago


















  • Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
    – Beelzebielsk
    Nov 28 at 22:41












  • @Beelzebielsk I added some more explanations
    – egreg
    Nov 28 at 22:54










  • It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
    – Frank Mittelbach
    Nov 30 at 10:51










  • @FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
    – Beelzebielsk
    2 days ago










  • @FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
    – Beelzebielsk
    2 days ago
















Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
– Beelzebielsk
Nov 28 at 22:41






Could you explain why there's this difference between clist_map_function:nN and clist_map_inline:nn? There's nothing obvious to me about why one would have to leave a little extra stuff after the loop and the other doesn't. A reference for my familiarity: I've used TeX for several years, and I've read a few chapters of the TeXBook. I still find TeX and all related things extremely obtuse (once I want to start creating things of my own). Overall, not that familiar with the internals, TeX primitives, nor with Latex3.
– Beelzebielsk
Nov 28 at 22:41














@Beelzebielsk I added some more explanations
– egreg
Nov 28 at 22:54




@Beelzebielsk I added some more explanations
– egreg
Nov 28 at 22:54












It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
– Frank Mittelbach
Nov 30 at 10:51




It is an interesting question if that could be avoided somehow in the inline versions (I guess that is the same with all other functions of that nature too). If not it might be something that is worth documenting
– Frank Mittelbach
Nov 30 at 10:51












@FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
– Beelzebielsk
2 days ago




@FrankMittelbach I'm curious as to how you'd document this. I doubt you'd just say, "Careful using it with tables!" since I get the feeling that this detail could affect the display of other things. However, if you just said something more general to the effect of "the inline variant leaves stuff after the last iteration", I wouldn't understand that this could affect table typesetting. I struggle with TeX and LaTeX because the connections between various things is not obvious, and I stumble haphazardly onto those connections by reading books and random stackexchange posts.
– Beelzebielsk
2 days ago












@FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
– Beelzebielsk
2 days ago




@FrankMittelbach To say this another way, if the documentation already said, "The inline variants leave other stuff after the last iteration," I'd have still posted this question.
– Beelzebielsk
2 days ago










up vote
3
down vote













I am sure everyone will forgive my somewhat off-topic answer, and this is just to provide an example illustrating @egreg explanations:



documentclass{article}
usepackage{xinttools}
begin{document}
begin{tabular}{|ll|}
hline
xintFor #1 in {one, two, three}:
{#1 &\hline}
end{tabular}
begin{tabular}{|ll|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


enter image description here



Although xintFor acts non-expandably, it is careful not to do anything "non vanishing by pure expansion" at its end. This allows it to not trigger accidentally a new row. This constraint does however have some limitation effect on the features of xintFor (see the boxed "15.17 xintifForFirst, xintifForLast" comments in xint.pdf).



Notice that the xintFor nests well.



A side remark here is about the strange "gaps" one sees (when magnifying) at the joining of horizontal and vertical lines in both (identical) tabulars: add usepackage{array} to fix that.






share|improve this answer





















  • It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
    – Beelzebielsk
    Nov 30 at 0:44















up vote
3
down vote













I am sure everyone will forgive my somewhat off-topic answer, and this is just to provide an example illustrating @egreg explanations:



documentclass{article}
usepackage{xinttools}
begin{document}
begin{tabular}{|ll|}
hline
xintFor #1 in {one, two, three}:
{#1 &\hline}
end{tabular}
begin{tabular}{|ll|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


enter image description here



Although xintFor acts non-expandably, it is careful not to do anything "non vanishing by pure expansion" at its end. This allows it to not trigger accidentally a new row. This constraint does however have some limitation effect on the features of xintFor (see the boxed "15.17 xintifForFirst, xintifForLast" comments in xint.pdf).



Notice that the xintFor nests well.



A side remark here is about the strange "gaps" one sees (when magnifying) at the joining of horizontal and vertical lines in both (identical) tabulars: add usepackage{array} to fix that.






share|improve this answer





















  • It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
    – Beelzebielsk
    Nov 30 at 0:44













up vote
3
down vote










up vote
3
down vote









I am sure everyone will forgive my somewhat off-topic answer, and this is just to provide an example illustrating @egreg explanations:



documentclass{article}
usepackage{xinttools}
begin{document}
begin{tabular}{|ll|}
hline
xintFor #1 in {one, two, three}:
{#1 &\hline}
end{tabular}
begin{tabular}{|ll|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


enter image description here



Although xintFor acts non-expandably, it is careful not to do anything "non vanishing by pure expansion" at its end. This allows it to not trigger accidentally a new row. This constraint does however have some limitation effect on the features of xintFor (see the boxed "15.17 xintifForFirst, xintifForLast" comments in xint.pdf).



Notice that the xintFor nests well.



A side remark here is about the strange "gaps" one sees (when magnifying) at the joining of horizontal and vertical lines in both (identical) tabulars: add usepackage{array} to fix that.






share|improve this answer












I am sure everyone will forgive my somewhat off-topic answer, and this is just to provide an example illustrating @egreg explanations:



documentclass{article}
usepackage{xinttools}
begin{document}
begin{tabular}{|ll|}
hline
xintFor #1 in {one, two, three}:
{#1 &\hline}
end{tabular}
begin{tabular}{|ll|}
hline
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}


enter image description here



Although xintFor acts non-expandably, it is careful not to do anything "non vanishing by pure expansion" at its end. This allows it to not trigger accidentally a new row. This constraint does however have some limitation effect on the features of xintFor (see the boxed "15.17 xintifForFirst, xintifForLast" comments in xint.pdf).



Notice that the xintFor nests well.



A side remark here is about the strange "gaps" one sees (when magnifying) at the joining of horizontal and vertical lines in both (identical) tabulars: add usepackage{array} to fix that.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 29 at 22:40









jfbu

45.4k65145




45.4k65145












  • It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
    – Beelzebielsk
    Nov 30 at 0:44


















  • It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
    – Beelzebielsk
    Nov 30 at 0:44
















It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
– Beelzebielsk
Nov 30 at 0:44




It's actually not that off-topic. The main goal of this question was to automate the creation of tabular-style forms. This is another method toward that approach. Though, I'm preferring the LaTeX3 stuff.
– Beelzebielsk
Nov 30 at 0:44










up vote
3
down vote













You could make the original function safe in this position by use of noalign



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
noalignbgroupclistMap{one, two, three}{egroup#1 &\hlinenoalignbgroup}egroup
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}





share|improve this answer





















  • Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
    – jfbu
    Nov 30 at 17:10










  • @jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
    – David Carlisle
    Nov 30 at 17:35

















up vote
3
down vote













You could make the original function safe in this position by use of noalign



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
noalignbgroupclistMap{one, two, three}{egroup#1 &\hlinenoalignbgroup}egroup
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}





share|improve this answer





















  • Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
    – jfbu
    Nov 30 at 17:10










  • @jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
    – David Carlisle
    Nov 30 at 17:35















up vote
3
down vote










up vote
3
down vote









You could make the original function safe in this position by use of noalign



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
noalignbgroupclistMap{one, two, three}{egroup#1 &\hlinenoalignbgroup}egroup
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}





share|improve this answer












You could make the original function safe in this position by use of noalign



documentclass{article}
usepackage{expl3}
usepackage{xparse}

ExplSyntaxOn
cs_new_eq:NN clistMap clist_map_inline:nn
ExplSyntaxOff

begin{document}
begin{tabular}{|ll|}
noalignbgroupclistMap{one, two, three}{egroup#1 &\hlinenoalignbgroup}egroup
end{tabular}

begin{tabular}{|ll|}
one &\hline
two &\hline
three &\hline
end{tabular}
end{document}






share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 30 at 14:28









David Carlisle

479k3811121845




479k3811121845












  • Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
    – jfbu
    Nov 30 at 17:10










  • @jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
    – David Carlisle
    Nov 30 at 17:35




















  • Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
    – jfbu
    Nov 30 at 17:10










  • @jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
    – David Carlisle
    Nov 30 at 17:35


















Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
– jfbu
Nov 30 at 17:10




Yes, I noticed that, I was not referring to the actual item being scoped but only to the additional dealings of clist_map_inline:nn in-between (if any) and after the last iteration.
– jfbu
Nov 30 at 17:10












@jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
– David Carlisle
Nov 30 at 17:35






@jfbu ah OK I'd have to check what it's really doing (or you could ask Joseph in chat:-)
– David Carlisle
Nov 30 at 17:35




















draft saved

draft discarded




















































Thanks for contributing an answer to TeX - LaTeX Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f462260%2fprevent-newline-after-clist-map-inline%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

ComboBox Display Member on multiple fields

Is it possible to collect Nectar points via Trainline?