Suppress parskip BEFORE (sic!) a specific paragraph?

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


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.