6

Imagine the following document:

\documentclass{article}
\setlength{\parskip}{8pt}
\begin{document}
This is the first paragraph

This is the second paragraph

This is the third paragraph
\end{document}

I now want to modify the second (not the third!!) paragraph so that there is no spacing between the second and the third paragraph.

There are many ways to modify the third paragraph so that there is no parskip between the second and the third - but i must modify the second one.

Simplest example for a solution that does NOT fit for me:

{\setlength{\parskip}{0pt}This is the third paragraph}

Why?

The document seen here is a minimal example of LaTeX code generated by the WYSIWYM editor LyX.

In LyX, I need to create a paragraph layout style (for the second paragraph) that avoids spacing between a paragraph using that style and the following paragraph which is of any other style.

I can only modify the output of the second paragraph, because it is free to the user which style he uses for the following paragraph. All other paragraph styles are "normal" and generate a parskip, which is the normal desired behaviour. (except for the special paragraph style I want to generate)

Unfortunately, there seems to be no way to tell LyX not to generate \n\n after each style without modifying the source code.

Any ideas appreciated!

Update 1:

I found that a negative \vspace with the length of a single \parskip might do the trick, but am unsure about unforeseen consequences:

\documentclass{article}
\setlength{\parskip}{8pt}
\begin{document}
This is the first paragraph

This is the second paragraph\vspace{-\parskip}

This is the third paragraph
\end{document}

What could happen when i use the negative vspace in this context inside a large, auto-generated document?

  • 2
    Note that instead of \vspace{-8pt} you could equivalently say \vspace{-\parskip}. But I feel like I should ask: why do you want this behavior to begin with? – Sean Allred May 5 '15 at 17:21
  • Your "Why" section is still giving a solution to an unknown problem. – Sean Allred May 5 '15 at 17:31
  • @SeanAllred I updated the Why section to make it more clear. – Kaii May 6 '15 at 6:52
7

While I show \noparskip at the end of the 2nd paragraph, it can appear anywhere in the paragraph (INCLUDING the very beginning) and achieve the same effect.

EDIT: My concern with using a simple negative \vspace revolves around pagination that might be artificially brought on by the larger \parskip, prior to the invocation of the negative \vspace. Whether that is an issue in Lyx, I have no experience to know. I suppose though, that issuing the negative \vspace prior to the closing \par may be a safe option, but I'll let others comment.

\documentclass{article}
\setlength{\parskip}{8pt}
\let\svpar\par
\edef\svparskip{\the\parskip}
\def\revertpar{\svpar\setlength\parskip{\svparskip}\let\par\svpar}
\def\noparskip{\leavevmode\setlength\parskip{0pt}%
  \def\par{\svpar\let\par\revertpar}}
\begin{document}
This is the first paragraph

This is the second paragraph\noparskip  

This is the third paragraph

This is the fourth paragraph
\end{document}

enter image description here

  • Is there any disadvantage to simply introducing a -\parskip vspace? – Sean Allred May 5 '15 at 17:20
  • @SeanAllred I presume it could affect pagination. That would be my concern. – Steven B. Segletes May 5 '15 at 17:21
  • This breaks vertical spacing if \noparskip is followed by an enumerate or itemize environment. Is there an easy fix for that? – fefrei Sep 15 '15 at 14:43
  • 1
    @fefrei I have confirmed your observation. No immediate fix comes to mind, but I will think on it a bit. – Steven B. Segletes Sep 15 '15 at 14:50
  • 1
    I've developed a fix for this, see my separate answer. – fefrei Apr 20 '16 at 12:09
4

With the awesome help of @Inkane, I've tried to develop a version of Steven's code that interacts more nicely with enumerate and itemize environments. It's used like Steven's implementation, but has the following changes:

  • It does not prevent the parskip when the next paragraph is an enumerate or itemize.
  • It does not change the internal spacing in a list following \noparskip.

Here's the implementation:

\makeatletter
\newlength\noparskip@parskip % used to store a backup of the parskip value
\newboolean{noparskip@triggered} % flag to indicate that noparskip was run in the current paragraph
\setboolean{noparskip@triggered}{false}
\newboolean{noparskip@active} % flag to indicate that parskip should be restored after this paragraph
\setboolean{noparskip@active}{false}
\let\noparskip@par\par % store a backup of the \par command
\@setpar{% redefine \par with the means of ltpar.dtx to stay compatible to enumerate and itemize
    \ifhmode% since we're counting occurrences of \par, \par\par would be a problem, so check that we are actually ending a paragraph
        \ifthenelse{\boolean{noparskip@active}}{%
            \setlength\parskip\noparskip@parskip% restore parskip
            \setboolean{noparskip@active}{false}% remember not the restore parskip again
        }{}%
        \ifthenelse{\boolean{noparskip@triggered}}{%
            \ifthenelse{\boolean{noparskip@active}}{}{
                % we are triggering noparskip and not currently in a noparskip already
                \setlength\noparskip@parskip\parskip % copy the current parskip into the backup variable
            }%
            \setboolean{noparskip@triggered}{false}% paragraph is ending, so noparskip is no longer triggered
            \setlength\parskip{0pt}% no parskip when the next paragraph begins
            \setboolean{noparskip@active}{true}% parskip must be restored by the next par
        }{}%
    \fi%
    \noparskip@par% run the original par command
}
\def\noparskip@backout{%
    \ifthenelse{\boolean{noparskip@active}}{%
        % a list is beginning and parskip is currently set to zero, wich would mess up the list
        \setlength\parskip{\noparskip@parskip}% restore parskip before the list begins
        \setboolean{noparskip@active}{false}%
    }{}%
    \setboolean{noparskip@triggered}{false}% there's no sense in keeping noparskip triggered throughout a list
}
\xpretocmd\begin{%
    \ifstrequal{#1}{enumerate}{\noparskip@backout}{}%
    \ifstrequal{#1}{itemize}{\noparskip@backout}{}%
    \ifstrequal{#1}{list}{\noparskip@backout}{}%
}{}{}
\def\noparskip{%
    \leavevmode% ensure that we are within a paragraph
    \setboolean{noparskip@triggered}{true}% trigger noparskip
}
\makeatother

It needs \usepackage{xpatch} to run.

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.