Macro inserted via everypar in obeylines context doesn't see some commandsWhen to use LetLtxMacro?Obeylines and gappto from etoolbox
about to retire but not retired yet, employed but not working any more
Duplicate instruments in unison in an orchestra
Movie where people enter a church but find they can't leave, not in English
How is linear momentum conserved in case of a freely falling body?
Limitations with dynamical systems vs. PDEs?
Where can/should I, as a high schooler, publish a paper regarding the derivation of a formula?
How can I download a file through 2 SSH connections?
Papers on arXiv solving the same problem at the same time
What should come first—characters or plot?
Does Yeshayahu 43:10b / 43:13a imply HaShem was created?
How to gently end involvement with an online community?
Is gzip atomic?
Why are non-collision-resistant hash functions considered insecure for signing self-generated information
Anyone else seeing white rings in the Undead parish?
“T” in subscript in formulas
Does this VCO produce a sine wave or square wave
Hangman game in Python - need feedback on the quality of code
Can RMSE and MAE have the same value?
Very slow boot time and poor perfomance
When one problem is added to the previous one
Evaluated vs. unevaluated Association
Is first Ubuntu user root?
What are the occurences of total war in the Native Americans?
Why do banks “park” their money at the European Central Bank?
Macro inserted via everypar in obeylines context doesn't see some commands
When to use LetLtxMacro?Obeylines and gappto from etoolbox
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty margin-bottom:0;
I have the following code which works as expected except, as noted in the code, when a macro begins a line of the xltabular
being built:
documentclassarticle
usepackage[papersize=5.5in,8.5in,margin=0.6in,bottom=0.7in]geometry
usepackagearray
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
deftabline#1~%
xapptotabbodyunexpanded#1\hline~
makeatletter
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
offinterlineskip
everypar=tabline
obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hline
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
et dolore
magna aliqua.
Ut enim ad
explain
Note: verb+bfseries+ by itself is ignored. verb+textbfSee Note+ produces verb+Extra fi+ error.
endlistit
enddocument
Using leavevmodebfseries See Note
produces the expected output. Why is this necessary?
What am I missing?
tex-core everypar obeylines
add a comment |
I have the following code which works as expected except, as noted in the code, when a macro begins a line of the xltabular
being built:
documentclassarticle
usepackage[papersize=5.5in,8.5in,margin=0.6in,bottom=0.7in]geometry
usepackagearray
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
deftabline#1~%
xapptotabbodyunexpanded#1\hline~
makeatletter
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
offinterlineskip
everypar=tabline
obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hline
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
et dolore
magna aliqua.
Ut enim ad
explain
Note: verb+bfseries+ by itself is ignored. verb+textbfSee Note+ produces verb+Extra fi+ error.
endlistit
enddocument
Using leavevmodebfseries See Note
produces the expected output. Why is this necessary?
What am I missing?
tex-core everypar obeylines
add a comment |
I have the following code which works as expected except, as noted in the code, when a macro begins a line of the xltabular
being built:
documentclassarticle
usepackage[papersize=5.5in,8.5in,margin=0.6in,bottom=0.7in]geometry
usepackagearray
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
deftabline#1~%
xapptotabbodyunexpanded#1\hline~
makeatletter
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
offinterlineskip
everypar=tabline
obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hline
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
et dolore
magna aliqua.
Ut enim ad
explain
Note: verb+bfseries+ by itself is ignored. verb+textbfSee Note+ produces verb+Extra fi+ error.
endlistit
enddocument
Using leavevmodebfseries See Note
produces the expected output. Why is this necessary?
What am I missing?
tex-core everypar obeylines
I have the following code which works as expected except, as noted in the code, when a macro begins a line of the xltabular
being built:
documentclassarticle
usepackage[papersize=5.5in,8.5in,margin=0.6in,bottom=0.7in]geometry
usepackagearray
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
deftabline#1~%
xapptotabbodyunexpanded#1\hline~
makeatletter
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
offinterlineskip
everypar=tabline
obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hline
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
et dolore
magna aliqua.
Ut enim ad
explain
Note: verb+bfseries+ by itself is ignored. verb+textbfSee Note+ produces verb+Extra fi+ error.
endlistit
enddocument
Using leavevmodebfseries See Note
produces the expected output. Why is this necessary?
What am I missing?
tex-core everypar obeylines
tex-core everypar obeylines
edited 7 hours ago
frougon
8,3901 gold badge13 silver badges26 bronze badges
8,3901 gold badge13 silver badges26 bronze badges
asked 10 hours ago
sgmoyesgmoye
4,3241 gold badge13 silver badges30 bronze badges
4,3241 gold badge13 silver badges30 bronze badges
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
Diagnosis
The problem is that the lines of your tabbody
are collected by the tabline
macro, which is inserted by everypar
. However, the everypar
tokens are only inserted when a paragraph starts, and bfseries
used in vertical mode doesn't cause TeX to start a paragraph (i.e., to switch to horizontal mode). So, when one of the special lines designed to be read by tabline
starts with bfseries
, TeX is still in vertical mode when it finds the bfseries
(this is right after an end-of-line has been turned into par
). It expands it, and only later when a 〈horizontal command〉1 causes a switch to horizontal mode, it inserts tabline
which will collect the rest of the line. But when this happens, it is too late, the bfseries
has already been fully expanded and digested, it is not grabbed as part of the #1
by the inserted tabline
.
Example: suppose that TeX is collecting these lines:
tempor incididunt
bfseries See Note
tempor incididunt
is the first argument of the tabline
macro that was inserted by means of everypar
when the paragraph was started with the t
from tempor incididunt
(t
is a 〈letter〉 and therefore a 〈horizontal command〉; when TeX finds it in vertical mode, it switches to horizontal mode to start a new paragraph). So, the expansion of this tabline
consumed tempor incididunt•
from the input stream, where •
represents an active end-of-line character (it is active because obeylines
was used above). After these tokens have been removed from the input stream, the replacement text of tabline
is inserted, with tempor incididunt
substituted for #1
:
xapptotabbodyunexpandedtempor incididunt\hline•
Once xappto
has been fully processed, TeX finds the • that was just inserted, which has been made let
-equivalent to par
by obeylines
:
obeylines:
macro:->catcode `^^Mactive let ^^Mpar
Therefore, when this • token is digested, TeX ends the paragraph and switches to vertical mode. The next token from the input stream is bfseries
. This is a macro, therefore it is expanded. I pass on the details of its expansion (protectbfseries
where the second bfseries
has a space at the end of its name, etc.). What is important is that this bfseries
doesn't start a new paragraph (its expansion doesn't contain any 〈horizontal command〉). This only happens when TeX digests the S
from See Note
, i.e., after bfseries
has been fully processed. At this point, TeX switches to horizontal mode because the S
is a 〈horizontal command〉; it inserts the indentation box (invisible here because parindent
is 0pt
), then the tokens stored in everypar
, in your case a single tabline
, and resumes normal processing of the input stream. The just-inserted tabline
token is expanded, this grabs See Note
as the first argument (you see, bfseries
isn't present in this argument, it is already behind us), consumes the active end-of-line character that follows (because it is part of the 〈parameter text〉 of the macro), then the replacement text is inserted with See Note
substituted for #1
:
xapptotabbodyunexpandedSee Note\hline•
(note that this xappto
call doesn't append the bfseries
to tabbody
, it has definitely been lost for tabbody
) and the process goes on, as we just explained.
Proposed solution
I propose not to rely on everypar
. Rather, we can make the end-of-line character active in the innermost group of your listit
environment definition and redefine the active end-of-line character to be let
-equal to tabline
(see my listit@obeylines
macro). This way, every end-of-line character in the special portion becomes equivalent to a tabline
token and is expanded right before the next line. This way, its #1
grabs everything until the following end-of-line, and thus no command is lost.
This method even allows you to have par
tokens among the text that is collected in tabbody
(see Paragraph break here:par But...
in the example below). Of course, it requires a means to stop the special collection process. Given your example, I decided that a line starting with explain
marks the end of this process (cf. listit@checknext
). Of course, one could use a different end marker if you wish.
documentclassarticle
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
makeatletter
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
longdeftabline#1~%
xapptotabbodyunexpanded#1\hline%
futureletnextlistit@checknext
newcommand*listit@obeylinescatcode`~=active let~=tabline
newcommand*listit@checknext%
ifxnextexplain
letnext=relax
else
letnext=tabline
fi
next
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
listit@obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hlinenoalignvskip 4pt%
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
textbfSee Note
magna aliqua.
Paragraph break here:par But we remain in the same ``line.''
explain
Note: verb+bfseries+ is not ignored anymore. You can easily see that
verb+textbfSee Note+ works fine too.
endlistit
enddocument
Footnote
- Such as a 〈letter〉, 〈otherchar〉 or
unhbox
coming from the expansion ofleavevmode
, among other possibilities (cf. TeXbook p. 283).
add a comment |
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',
autoActivateHeartbeat: false,
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f505682%2fmacro-inserted-via-everypar-in-obeylines-context-doesnt-see-some-commands%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Diagnosis
The problem is that the lines of your tabbody
are collected by the tabline
macro, which is inserted by everypar
. However, the everypar
tokens are only inserted when a paragraph starts, and bfseries
used in vertical mode doesn't cause TeX to start a paragraph (i.e., to switch to horizontal mode). So, when one of the special lines designed to be read by tabline
starts with bfseries
, TeX is still in vertical mode when it finds the bfseries
(this is right after an end-of-line has been turned into par
). It expands it, and only later when a 〈horizontal command〉1 causes a switch to horizontal mode, it inserts tabline
which will collect the rest of the line. But when this happens, it is too late, the bfseries
has already been fully expanded and digested, it is not grabbed as part of the #1
by the inserted tabline
.
Example: suppose that TeX is collecting these lines:
tempor incididunt
bfseries See Note
tempor incididunt
is the first argument of the tabline
macro that was inserted by means of everypar
when the paragraph was started with the t
from tempor incididunt
(t
is a 〈letter〉 and therefore a 〈horizontal command〉; when TeX finds it in vertical mode, it switches to horizontal mode to start a new paragraph). So, the expansion of this tabline
consumed tempor incididunt•
from the input stream, where •
represents an active end-of-line character (it is active because obeylines
was used above). After these tokens have been removed from the input stream, the replacement text of tabline
is inserted, with tempor incididunt
substituted for #1
:
xapptotabbodyunexpandedtempor incididunt\hline•
Once xappto
has been fully processed, TeX finds the • that was just inserted, which has been made let
-equivalent to par
by obeylines
:
obeylines:
macro:->catcode `^^Mactive let ^^Mpar
Therefore, when this • token is digested, TeX ends the paragraph and switches to vertical mode. The next token from the input stream is bfseries
. This is a macro, therefore it is expanded. I pass on the details of its expansion (protectbfseries
where the second bfseries
has a space at the end of its name, etc.). What is important is that this bfseries
doesn't start a new paragraph (its expansion doesn't contain any 〈horizontal command〉). This only happens when TeX digests the S
from See Note
, i.e., after bfseries
has been fully processed. At this point, TeX switches to horizontal mode because the S
is a 〈horizontal command〉; it inserts the indentation box (invisible here because parindent
is 0pt
), then the tokens stored in everypar
, in your case a single tabline
, and resumes normal processing of the input stream. The just-inserted tabline
token is expanded, this grabs See Note
as the first argument (you see, bfseries
isn't present in this argument, it is already behind us), consumes the active end-of-line character that follows (because it is part of the 〈parameter text〉 of the macro), then the replacement text is inserted with See Note
substituted for #1
:
xapptotabbodyunexpandedSee Note\hline•
(note that this xappto
call doesn't append the bfseries
to tabbody
, it has definitely been lost for tabbody
) and the process goes on, as we just explained.
Proposed solution
I propose not to rely on everypar
. Rather, we can make the end-of-line character active in the innermost group of your listit
environment definition and redefine the active end-of-line character to be let
-equal to tabline
(see my listit@obeylines
macro). This way, every end-of-line character in the special portion becomes equivalent to a tabline
token and is expanded right before the next line. This way, its #1
grabs everything until the following end-of-line, and thus no command is lost.
This method even allows you to have par
tokens among the text that is collected in tabbody
(see Paragraph break here:par But...
in the example below). Of course, it requires a means to stop the special collection process. Given your example, I decided that a line starting with explain
marks the end of this process (cf. listit@checknext
). Of course, one could use a different end marker if you wish.
documentclassarticle
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
makeatletter
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
longdeftabline#1~%
xapptotabbodyunexpanded#1\hline%
futureletnextlistit@checknext
newcommand*listit@obeylinescatcode`~=active let~=tabline
newcommand*listit@checknext%
ifxnextexplain
letnext=relax
else
letnext=tabline
fi
next
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
listit@obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hlinenoalignvskip 4pt%
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
textbfSee Note
magna aliqua.
Paragraph break here:par But we remain in the same ``line.''
explain
Note: verb+bfseries+ is not ignored anymore. You can easily see that
verb+textbfSee Note+ works fine too.
endlistit
enddocument
Footnote
- Such as a 〈letter〉, 〈otherchar〉 or
unhbox
coming from the expansion ofleavevmode
, among other possibilities (cf. TeXbook p. 283).
add a comment |
Diagnosis
The problem is that the lines of your tabbody
are collected by the tabline
macro, which is inserted by everypar
. However, the everypar
tokens are only inserted when a paragraph starts, and bfseries
used in vertical mode doesn't cause TeX to start a paragraph (i.e., to switch to horizontal mode). So, when one of the special lines designed to be read by tabline
starts with bfseries
, TeX is still in vertical mode when it finds the bfseries
(this is right after an end-of-line has been turned into par
). It expands it, and only later when a 〈horizontal command〉1 causes a switch to horizontal mode, it inserts tabline
which will collect the rest of the line. But when this happens, it is too late, the bfseries
has already been fully expanded and digested, it is not grabbed as part of the #1
by the inserted tabline
.
Example: suppose that TeX is collecting these lines:
tempor incididunt
bfseries See Note
tempor incididunt
is the first argument of the tabline
macro that was inserted by means of everypar
when the paragraph was started with the t
from tempor incididunt
(t
is a 〈letter〉 and therefore a 〈horizontal command〉; when TeX finds it in vertical mode, it switches to horizontal mode to start a new paragraph). So, the expansion of this tabline
consumed tempor incididunt•
from the input stream, where •
represents an active end-of-line character (it is active because obeylines
was used above). After these tokens have been removed from the input stream, the replacement text of tabline
is inserted, with tempor incididunt
substituted for #1
:
xapptotabbodyunexpandedtempor incididunt\hline•
Once xappto
has been fully processed, TeX finds the • that was just inserted, which has been made let
-equivalent to par
by obeylines
:
obeylines:
macro:->catcode `^^Mactive let ^^Mpar
Therefore, when this • token is digested, TeX ends the paragraph and switches to vertical mode. The next token from the input stream is bfseries
. This is a macro, therefore it is expanded. I pass on the details of its expansion (protectbfseries
where the second bfseries
has a space at the end of its name, etc.). What is important is that this bfseries
doesn't start a new paragraph (its expansion doesn't contain any 〈horizontal command〉). This only happens when TeX digests the S
from See Note
, i.e., after bfseries
has been fully processed. At this point, TeX switches to horizontal mode because the S
is a 〈horizontal command〉; it inserts the indentation box (invisible here because parindent
is 0pt
), then the tokens stored in everypar
, in your case a single tabline
, and resumes normal processing of the input stream. The just-inserted tabline
token is expanded, this grabs See Note
as the first argument (you see, bfseries
isn't present in this argument, it is already behind us), consumes the active end-of-line character that follows (because it is part of the 〈parameter text〉 of the macro), then the replacement text is inserted with See Note
substituted for #1
:
xapptotabbodyunexpandedSee Note\hline•
(note that this xappto
call doesn't append the bfseries
to tabbody
, it has definitely been lost for tabbody
) and the process goes on, as we just explained.
Proposed solution
I propose not to rely on everypar
. Rather, we can make the end-of-line character active in the innermost group of your listit
environment definition and redefine the active end-of-line character to be let
-equal to tabline
(see my listit@obeylines
macro). This way, every end-of-line character in the special portion becomes equivalent to a tabline
token and is expanded right before the next line. This way, its #1
grabs everything until the following end-of-line, and thus no command is lost.
This method even allows you to have par
tokens among the text that is collected in tabbody
(see Paragraph break here:par But...
in the example below). Of course, it requires a means to stop the special collection process. Given your example, I decided that a line starting with explain
marks the end of this process (cf. listit@checknext
). Of course, one could use a different end marker if you wish.
documentclassarticle
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
makeatletter
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
longdeftabline#1~%
xapptotabbodyunexpanded#1\hline%
futureletnextlistit@checknext
newcommand*listit@obeylinescatcode`~=active let~=tabline
newcommand*listit@checknext%
ifxnextexplain
letnext=relax
else
letnext=tabline
fi
next
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
listit@obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hlinenoalignvskip 4pt%
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
textbfSee Note
magna aliqua.
Paragraph break here:par But we remain in the same ``line.''
explain
Note: verb+bfseries+ is not ignored anymore. You can easily see that
verb+textbfSee Note+ works fine too.
endlistit
enddocument
Footnote
- Such as a 〈letter〉, 〈otherchar〉 or
unhbox
coming from the expansion ofleavevmode
, among other possibilities (cf. TeXbook p. 283).
add a comment |
Diagnosis
The problem is that the lines of your tabbody
are collected by the tabline
macro, which is inserted by everypar
. However, the everypar
tokens are only inserted when a paragraph starts, and bfseries
used in vertical mode doesn't cause TeX to start a paragraph (i.e., to switch to horizontal mode). So, when one of the special lines designed to be read by tabline
starts with bfseries
, TeX is still in vertical mode when it finds the bfseries
(this is right after an end-of-line has been turned into par
). It expands it, and only later when a 〈horizontal command〉1 causes a switch to horizontal mode, it inserts tabline
which will collect the rest of the line. But when this happens, it is too late, the bfseries
has already been fully expanded and digested, it is not grabbed as part of the #1
by the inserted tabline
.
Example: suppose that TeX is collecting these lines:
tempor incididunt
bfseries See Note
tempor incididunt
is the first argument of the tabline
macro that was inserted by means of everypar
when the paragraph was started with the t
from tempor incididunt
(t
is a 〈letter〉 and therefore a 〈horizontal command〉; when TeX finds it in vertical mode, it switches to horizontal mode to start a new paragraph). So, the expansion of this tabline
consumed tempor incididunt•
from the input stream, where •
represents an active end-of-line character (it is active because obeylines
was used above). After these tokens have been removed from the input stream, the replacement text of tabline
is inserted, with tempor incididunt
substituted for #1
:
xapptotabbodyunexpandedtempor incididunt\hline•
Once xappto
has been fully processed, TeX finds the • that was just inserted, which has been made let
-equivalent to par
by obeylines
:
obeylines:
macro:->catcode `^^Mactive let ^^Mpar
Therefore, when this • token is digested, TeX ends the paragraph and switches to vertical mode. The next token from the input stream is bfseries
. This is a macro, therefore it is expanded. I pass on the details of its expansion (protectbfseries
where the second bfseries
has a space at the end of its name, etc.). What is important is that this bfseries
doesn't start a new paragraph (its expansion doesn't contain any 〈horizontal command〉). This only happens when TeX digests the S
from See Note
, i.e., after bfseries
has been fully processed. At this point, TeX switches to horizontal mode because the S
is a 〈horizontal command〉; it inserts the indentation box (invisible here because parindent
is 0pt
), then the tokens stored in everypar
, in your case a single tabline
, and resumes normal processing of the input stream. The just-inserted tabline
token is expanded, this grabs See Note
as the first argument (you see, bfseries
isn't present in this argument, it is already behind us), consumes the active end-of-line character that follows (because it is part of the 〈parameter text〉 of the macro), then the replacement text is inserted with See Note
substituted for #1
:
xapptotabbodyunexpandedSee Note\hline•
(note that this xappto
call doesn't append the bfseries
to tabbody
, it has definitely been lost for tabbody
) and the process goes on, as we just explained.
Proposed solution
I propose not to rely on everypar
. Rather, we can make the end-of-line character active in the innermost group of your listit
environment definition and redefine the active end-of-line character to be let
-equal to tabline
(see my listit@obeylines
macro). This way, every end-of-line character in the special portion becomes equivalent to a tabline
token and is expanded right before the next line. This way, its #1
grabs everything until the following end-of-line, and thus no command is lost.
This method even allows you to have par
tokens among the text that is collected in tabbody
(see Paragraph break here:par But...
in the example below). Of course, it requires a means to stop the special collection process. Given your example, I decided that a line starting with explain
marks the end of this process (cf. listit@checknext
). Of course, one could use a different end marker if you wish.
documentclassarticle
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
makeatletter
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
longdeftabline#1~%
xapptotabbodyunexpanded#1\hline%
futureletnextlistit@checknext
newcommand*listit@obeylinescatcode`~=active let~=tabline
newcommand*listit@checknext%
ifxnextexplain
letnext=relax
else
letnext=tabline
fi
next
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
listit@obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hlinenoalignvskip 4pt%
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
textbfSee Note
magna aliqua.
Paragraph break here:par But we remain in the same ``line.''
explain
Note: verb+bfseries+ is not ignored anymore. You can easily see that
verb+textbfSee Note+ works fine too.
endlistit
enddocument
Footnote
- Such as a 〈letter〉, 〈otherchar〉 or
unhbox
coming from the expansion ofleavevmode
, among other possibilities (cf. TeXbook p. 283).
Diagnosis
The problem is that the lines of your tabbody
are collected by the tabline
macro, which is inserted by everypar
. However, the everypar
tokens are only inserted when a paragraph starts, and bfseries
used in vertical mode doesn't cause TeX to start a paragraph (i.e., to switch to horizontal mode). So, when one of the special lines designed to be read by tabline
starts with bfseries
, TeX is still in vertical mode when it finds the bfseries
(this is right after an end-of-line has been turned into par
). It expands it, and only later when a 〈horizontal command〉1 causes a switch to horizontal mode, it inserts tabline
which will collect the rest of the line. But when this happens, it is too late, the bfseries
has already been fully expanded and digested, it is not grabbed as part of the #1
by the inserted tabline
.
Example: suppose that TeX is collecting these lines:
tempor incididunt
bfseries See Note
tempor incididunt
is the first argument of the tabline
macro that was inserted by means of everypar
when the paragraph was started with the t
from tempor incididunt
(t
is a 〈letter〉 and therefore a 〈horizontal command〉; when TeX finds it in vertical mode, it switches to horizontal mode to start a new paragraph). So, the expansion of this tabline
consumed tempor incididunt•
from the input stream, where •
represents an active end-of-line character (it is active because obeylines
was used above). After these tokens have been removed from the input stream, the replacement text of tabline
is inserted, with tempor incididunt
substituted for #1
:
xapptotabbodyunexpandedtempor incididunt\hline•
Once xappto
has been fully processed, TeX finds the • that was just inserted, which has been made let
-equivalent to par
by obeylines
:
obeylines:
macro:->catcode `^^Mactive let ^^Mpar
Therefore, when this • token is digested, TeX ends the paragraph and switches to vertical mode. The next token from the input stream is bfseries
. This is a macro, therefore it is expanded. I pass on the details of its expansion (protectbfseries
where the second bfseries
has a space at the end of its name, etc.). What is important is that this bfseries
doesn't start a new paragraph (its expansion doesn't contain any 〈horizontal command〉). This only happens when TeX digests the S
from See Note
, i.e., after bfseries
has been fully processed. At this point, TeX switches to horizontal mode because the S
is a 〈horizontal command〉; it inserts the indentation box (invisible here because parindent
is 0pt
), then the tokens stored in everypar
, in your case a single tabline
, and resumes normal processing of the input stream. The just-inserted tabline
token is expanded, this grabs See Note
as the first argument (you see, bfseries
isn't present in this argument, it is already behind us), consumes the active end-of-line character that follows (because it is part of the 〈parameter text〉 of the macro), then the replacement text is inserted with See Note
substituted for #1
:
xapptotabbodyunexpandedSee Note\hline•
(note that this xappto
call doesn't append the bfseries
to tabbody
, it has definitely been lost for tabbody
) and the process goes on, as we just explained.
Proposed solution
I propose not to rely on everypar
. Rather, we can make the end-of-line character active in the innermost group of your listit
environment definition and redefine the active end-of-line character to be let
-equal to tabline
(see my listit@obeylines
macro). This way, every end-of-line character in the special portion becomes equivalent to a tabline
token and is expanded right before the next line. This way, its #1
grabs everything until the following end-of-line, and thus no command is lost.
This method even allows you to have par
tokens among the text that is collected in tabbody
(see Paragraph break here:par But...
in the example below). Of course, it requires a means to stop the special collection process. Given your example, I decided that a line starting with explain
marks the end of this process (cf. listit@checknext
). Of course, one could use a different end marker if you wish.
documentclassarticle
usepackagemulticol
usepackagexparse
usepackagexltabular
usepackageetoolbox
makeatletter
%% https://tex.stackexchange.com/questions/487572/obeylines-and-gappto-from-etoolbox
%% Collect the body of the xltabular in tabbody:
begingroup
lccode`~=`^^M
lowercase%
endgroup
longdeftabline#1~%
xapptotabbodyunexpanded#1\hline%
futureletnextlistit@checknext
newcommand*listit@obeylinescatcode`~=active let~=tabline
newcommand*listit@checknext%
ifxnextexplain
letnext=relax
else
letnext=tabline
fi
next
NewDocumentEnvironmentlistit%
gdeftabbody
noindent
beginminipagetextwidth
raggedcolumns
beginmulticols2
col@number@ne
mathchardefLT@end@pen=0 %
begingroup
listit@obeylines
%
endmulticols
endminipage
makeatother
NewDocumentCommandexplain%
endgroup
vspace-baselineskip
beginxltabularlinewidthX
hlinehline
tabbody
hlinenoalignvskip 4pt%
endxltabular
begindocument
beginlistit
Lorem ipsum dolor
sit amet, consectetur
adipiscing elit
sed do eiusmod
tempor incididunt
bfseries See Note
ut labore
textbfSee Note
magna aliqua.
Paragraph break here:par But we remain in the same ``line.''
explain
Note: verb+bfseries+ is not ignored anymore. You can easily see that
verb+textbfSee Note+ works fine too.
endlistit
enddocument
Footnote
- Such as a 〈letter〉, 〈otherchar〉 or
unhbox
coming from the expansion ofleavevmode
, among other possibilities (cf. TeXbook p. 283).
edited 5 hours ago
answered 9 hours ago
frougonfrougon
8,3901 gold badge13 silver badges26 bronze badges
8,3901 gold badge13 silver badges26 bronze badges
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2ftex.stackexchange.com%2fquestions%2f505682%2fmacro-inserted-via-everypar-in-obeylines-context-doesnt-see-some-commands%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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