2

This is the most strange and hard-to-debug situation I have encountered in latex. When \obeylines is in effect, it seems that macros with optional argument defined by xparse will have some trouble. This is demonstrated by the following MWE (I have tried hard to strip it down, but it is still quite lengthy, sorry... dispite this, it's structure is simple. Please see the Edit part for a full explanation):

\documentclass[fontsize=22pt]{scrreprt}

\usepackage{etoolbox}

\usepackage{geometry,calc}
\geometry{paperwidth=1280pt,paperheight=3840pt,margin=25pt}

\usepackage{tcolorbox}
\usepackage{xparse}

\usepackage[titles]{tocloft}
\addtocounter{tocdepth}{1}

\NewDocumentCommand\mypart{m D--{n}}{
  \printtocentry{#1}{#2}{part}
  \item[]
}

\newcommand*{\mychapname}{}
\NewDocumentCommand\mychap{m D--{n}}{
  \item[]
  \end{notes}
  \vspace{-8ex}
  \printtocentry{#1}{#2}{chapter}
  \begingroup\let\clearpage\relax
  \chapter*{\large\sffamily#1}
  \endgroup
  \renewcommand*{\mychapname}{#1}
  \vspace{-12ex}
  \begin{notes}
  \item[]
}

\NewDocumentCommand\printtocentry{m m m o}{
  \refstepcounter{#3}
  \def\mynumberline{\protect\numberline{\csname the#3\endcsname}}
  \IfNoValueF{#4}{\def\mynumberline{\relax}}
  \ifstrequal{#2}{t}{
    \addcontentsline{toc}{#3}{\mynumberline\colorbox{yellow}{#1}}
  }{}
  \ifstrequal{#2}{d}{
    \addcontentsline{toc}{#3}{\mynumberline\colorbox{green}{#1}}
  }{}
  \ifstrequal{#2}{n}{
    \addcontentsline{toc}{#3}{\mynumberline#1}
  }{}
}

\NewDocumentCommand\mysec{m D--{n}}{
  \printtocentry{#1}{#2}{section}
  \item[]\hfill
  {[~\mychapname~\textbf{--}~#1~]}
}

\NewDocumentCommand\mysubsec{m D--{n}}{
  \vspace{3ex}
  \printtocentry{#1}{#2}{subsection}
  \item[(#1)]\hfill
}

\def\removespecial{
  \catcode`\_=12
  \catcode`\^=12
  \catcode`\$=12
  %\catcode`\%=12
  \catcode`\#=12
  \catcode`\&=12
  \catcode`\~=12
}

% the second argument is used to highlight toc entries, I think this is where the bug is
\NewDocumentCommand\myitem{O{} D--{n}}{
  \vspace{1ex}
  \ifstrempty{#1}{}{
    \printtocentry{#1}{#2}{subsubsection}[NoNumberLine]
  }
  \item[#1]
  %%% this line is the source of problem, \obeylines changes the catcode of ^^M
  \obeylines
  \obeyspaces
  \removespecial
}

\renewcommand*{\\}{\textbackslash}

\usepackage[Sonny]{fncychap}
\renewcommand*{\DOCH}{}
\ChTitleVar{\large}

\usepackage[inline]{enumitem}
\newlist{notes}{description}{1}
\setlist[notes]{
  leftmargin=0.3\linewidth,labelsep=2em,
  itemsep=1.5ex,style=multiline,font=\normalfont
}

\begin{document}
\tableofcontents
\begin{notes}

\mypart{Part One}

% this chapter works, because \obeylines is not yet in effect
\mychap{Chap One}

\mysubsec{Subsec One}

\myitem[Item One]
...some content...

\myitem[Item Two]
...some content...

% this chapter does not work
% uncomment the next line would make it to work
%\catcode\endlinechar = 5
\mychap{Chap Two}

\mysubsec{Subsec Two}% disappear

\myitem[Item Three]% disappear
...some content...

\myitem[Item Four]% disappear
...some content...

% however, this chapter works:
\mychap{Chap Three}-d-

\mysubsec{Subsec Three}

\myitem[Item Five]
...some content...

\myitem[Item Six]
...some content...

\end{notes}
\end{document}

% vim: filetype=tex

Part of the result looks like this:

MWE

Chapter Two is where you can observe the problem, you can see that all items disappear and only the content of the items are left. However, it should have the exact same structure as Chapter One.

I have spent a lot of time trying to debug this issue, but in vein. And I don't know much plain tex. I think I have pinpointed the issue to be with \obeylines and the xparse-defined macros. I've also found that adding \catcode\endlinechar = 5 in front of \mychap{} could seemingly solve the problem. Can anyone 1) explain the problem and 2) tell me how to make it to work? Thanks.

Edit: I'm going to provide some background on the MWE and clarify what I'm trying to achieve here. The above MWE is adapted from a custom class called mynotes.sty, which just as its name implies, I normally use for taking notes. It provides a book-like structure for the notes with the main part being a list. Without this class, it could be done like this:

\usepackage[inline]{enumitem}
\newlist{notes}{description}{1}

\part{...}
\chapter{...}
\section{...}
\begin{notes}
\item[]...
\end{notes}
\section{...}
\begin{notes}
\item[]...
\end{notes}
...

Obviously there are too many \begin{notes}...\end{notes} there. So for good-looking and type-saving purposes, I define \mychap, \myitem etc. Additionally, one function is added: the ability to highlight entries in the toc. This is achieved by adding those D--{n} optional arguments to the \NewDocumentCommands. So now it works like:

\mychap{...}         % normal entry, no toc coloring
\mychap{...}-n-      % the same as above, because n is the default value
\mychap{...}-d-      % toc entry colored green
\mysec{...}-t-       % toc entry colored yellow

Enough history. Now the relevant part: in the original implementation of the class, these three lines was absent:

\obeylines
\obeyspaces
\removespecial

and it had worked great for its designed purpose. Until recently, I have to make notes of some topic which makes verbatim-like environment necessary. Again, this might work:

\myitem[...]
\begin{verbatim}...\end{verbatim}
\myitem[...]
\begin{alltt}...\end{alltt}

but it's too much typing. Also, breaking the functionality of alltt into three parts has the advantage of more flexibility. So I decided to add those three lines to try to simulate:

\myitem[...]
{\obeylines\obeyspaces\removespecial ...}
\myitem[...]
{\obeylines\obeyspaces\removespecial ...}
% could not figure out how to add the parentheses
% so in fact it is like:
\myitem[...]
\obeylines\obeyspaces\removespecial ...

However, these three lines BREAK the original format, and this is what the above MWE shows. In the output of the above MWE, the format of the three parts (Chap One, Chap Two and Chap Three) should look exactly the same except the color of the toc entries. Adding these three lines (more precisely, only the \obeylines line) make part of Chap Two off the left-hand edge (as Joseph kindly pointed out). From my point of view, the cause is like this:

% NOT working example
\myitem[...]
...
% \obeylines is in effect here! for some reason which I don't
% understand it breaks the following \mychap:
\mychap{Chap Two}

Trying to mitigate the effect of \obeylines would make it work as expected again:

% working example
\myitem[...]
...
\catcode\endlinechar = 5
\mychap{Chap Two}
% works again, those three lines not causing trouble any more

What's even more confusing is that this also works:

% working example
\myitem[...]
...
\mychap{Chap Two}-d-

This is what gives me the illusion that the handling of optional argument in xparse has some problem. And this is the full story. Many thanks for reading and helping me! :)

Oh yes, here is an explanation for those empty \item[]s in the code: that's because enumitem requires that \begin{notes}...\end{notes} have at least an \item[] inside.

  • 1
    It would be helpful if the example were more minimal (there is a lot of apparently unneeded code) and if we had some idea of what you are actually trying to achieve: \obeylines, etc. are normally for verbatim-like input, which is best handled in a dedicated environment. – Joseph Wright Aug 16 '14 at 12:03
  • You text is printing, it's just that with your extremely odd set up it's off the left-hand edge of the page. As I've no idea of what the aim actually is here, I'm struggling to write an answer! – Joseph Wright Aug 16 '14 at 12:11
  • @JosephWright Wait a minute, I will try to strip the code further and add some more commend to it. Thank you very much for the attention! – kawing-chiu Aug 16 '14 at 12:53
  • It really would be helpful to understand the underlying problem you're trying to solve. There is probably a better way to do this. (To see what Joseph is talking about, change your margin to 250pt.) – Sean Allred Aug 16 '14 at 13:02
  • 1
    Hi, I have updated the original post. Hope this time it would be clearer. – kawing-chiu Aug 16 '14 at 23:46
3

This is an explanation of the problem rather than a full solution.

As Joseph Wright suggested this problem would be much easier to understand with a proper minimal working example. In fact, if you cut down to a MWE then it becomes clear what the problem is: as one might suspect, the xparse package is completely innocent.

Here is (close to) a MWE. To save space I have compacted it a little, unfortunately readability suffers, but not by much...:

\documentclass{scrreprt} \usepackage{xparse}
\NewDocumentCommand\mychap{m D--{n}}{
  \item[]\end{notes} \textbf{#1} \begin{notes}\item[] }
\NewDocumentCommand\myitem{O{} D--{n}}{\item[#1]\obeylines}
\usepackage[inline]{enumitem}
\newlist{notes}{description}{1}
\setlist[notes]{nosep,leftmargin=0.3\linewidth}% Note the LEFTMARGIN !!!

\begin{document} \begin{notes}
  % this chapter works, because \obeylines is not yet in effect
  \mychap{Chap One} \myitem[Item Two] ...some content...

  % this chapter does not work: uncommenting the next line makes it work
  %\catcode\endlinechar = 5
  \mychap{Chap Two}
  \myitem[Item Four] ...some content...

  % however, this chapter works:
  \mychap{Chap Three}-d- \myitem[Item Six] ...some content...
\end{notes} \end{document}

This MWE is considerably shorter than that provided by the OP. This produces:

enter image description here

As in the question, with this cut-down version the second item is in the wrong place

As the OP says, setting \catcode\endlinechar = 5 the problem goes away, but this is not so surprising because this, in effect, undoes the previous \obeylines command.

The real cause of the problem, as indicated by my comment in the MWE, is the combination of the leftmargin=0.3\linewidth in the specifications of the notes environment and the \obeylines command: with obeylines in effect the enumitem package is struggling to put the appropriate left margin in place. If you set leftmargin=0 the problem goes away. Of course, this may not be what the OP wants.

Having taken the effort to understand the OP's code, I think that wrapping enumitem (i.e. notes), simply to indent a block seems is a little OTT. If I wanted to do something like this I think that I would go for a combination of editor shortcuts (aka snippets in vim) and some custom environments.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.