% \iffalse ---!!! FIRST META-COMMENT !!!--- % % % This file is listparskip_code.dtx from version 1.0 % of the free and open-source LaTeX package "listparskip," % released December 2024. % % Running Plain TeX on listparskip_code.dtx will % produce the following files: % % (1) the package file listparskip.sty; % % (2) the derived files listparskip_heading.tex % and listparskip_user_guide.tex, and % listparskip_example.tex, which are % used for typesetting documentation; % % and % % (3) a number of other derived files. % % Running LaTeX on listparskip_code.dtx will produce the % files listed above as well as the following: % % (4) the pdf documentation file listparskip_code.pdf; % % and % % (5) a number of other derived files. % % To install listparskip on your computer, run this file % through Plain TeX or LaTeX and move listparskip.sty % to a directory searchable by TeX. See the associated % README.txt file for installation information. % % % \fi % \iffalse ---!!! SECOND META-COMMENT !!!--- % % % This file is from version 1.0 of the free and open-source % LaTeX package "listparskip," released December 2024. % % Copyright 2024 Conrad Kosowsky % % This file may be used, distributed, and modified under the % terms of the LaTeX Public Project License, version 1.3c or % any later version. The most recent version of this license % is available online at % % https://www.latex-project.org/lppl/ % % This Work has the LPPL status "maintained," and the current % maintainer is the package author, Conrad Kosowsky. He can % be reached at kosowsky.latex@gmail.com. The Work consists % of the following items: % % (1) the base file: % listparskip.dtx % % (2) the package file: % listparskip.sty % % (3) the pdf documentation files: % listparskip_code.pdf % listparskip_user_guide.pdf % listparskip_example.pdf % % (4) the derived files: % listparskip_user_guide.tex % listparskip_example.tex % listparskip_heading.tex % % (5) all other files created through the configuration % process % % and % % (6) this README.txt file % % PLEASE KNOW THAT THIS FREE SOFTWARE IS PROVIDED WITHOUT % ANY WARRANTY. SPECIFICALLY, THE "NO WARRANTY" SECTION OF % THE LATEX PROJECT PUBLIC LICENSE STATES THE FOLLOWING: % % THERE IS NO WARRANTY FOR THE WORK. EXCEPT WHEN OTHERWISE % STATED IN WRITING, THE COPYRIGHT HOLDER PROVIDES THE WORK % `AS IS’, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED % OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED % WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR % PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE % OF THE WORK IS WITH YOU. SHOULD THE WORK PROVE DEFECTIVE, % YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR % CORRECTION. % % IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED % TO IN WRITING WILL THE COPYRIGHT HOLDER, OR ANY AUTHOR % NAMED IN THE COMPONENTS OF THE WORK, OR ANY OTHER PARTY % WHO MAY DISTRIBUTE AND/OR MODIFY THE WORK AS PERMITTED % ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, % SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT % OF ANY USE OF THE WORK OR OUT OF INABILITY TO USE THE WORK % (INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA, DATA BEING % RENDERED INACCURATE, OR LOSSES SUSTAINED BY ANYONE AS A % RESULT OF ANY FAILURE OF THE WORK TO OPERATE WITH ANY % OTHER PROGRAMS), EVEN IF THE COPYRIGHT HOLDER OR SAID % AUTHOR OR SAID OTHER PARTY HAS BEEN ADVISED OF THE % POSSIBILITY OF SUCH DAMAGES. % % For more information, see the LaTeX Project Public License. % Derivative works based on this software may come with their % own license or terms of use, and the package author is not % responsible for any third-party software. % % Happy TeXing! % % % \fi % \iffalse % % The installation and driver files are incorporated into % listparskip_code.dtx, so we do not need to generate them % separately. The and tags are for % reference. % %<*batchfile> \begingroup \input docstrip.tex \keepsilent \askforoverwritefalse \preamble This file is from version 1.0 of the free and open-source LaTeX package "listparskip," released December 2024. Copyright 2024 Conrad Kosowsky This file may be used, distributed, and modified under the terms of the LaTeX Public Project License, version 1.3c or any later version. The most recent version of this license is available online at https://www.latex-project.org/lppl/ This work has the LPPL status "maintained," and the current maintainer is the package author, Conrad Kosowsky. He can be reached at kosowsky.latex@gmail.com. PLEASE KNOW THAT THIS FREE SOFTWARE IS PROVIDED WITHOUT ANY WARRANTY. SPECIFICALLY, THE "NO WARRANTY" SECTION OF THE LATEX PROJECT PUBLIC LICENSE STATES THE FOLLOWING: THERE IS NO WARRANTY FOR THE WORK. EXCEPT WHEN OTHERWISE STATED IN WRITING, THE COPYRIGHT HOLDER PROVIDES THE WORK `AS IS’, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE WORK IS WITH YOU. SHOULD THE WORK PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR, OR CORRECTION. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL THE COPYRIGHT HOLDER, OR ANY AUTHOR NAMED IN THE COMPONENTS OF THE WORK, OR ANY OTHER PARTY WHO MAY DISTRIBUTE AND/OR MODIFY THE WORK AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE WORK OR OUT OF INABILITY TO USE THE WORK (INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA, DATA BEING RENDERED INACCURATE, OR LOSSES SUSTAINED BY ANYONE AS A RESULT OF ANY FAILURE OF THE WORK TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF THE COPYRIGHT HOLDER OR SAID AUTHOR OR SAID OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. For more information, see the LaTeX Project Public License. Derivative works based on this software may come with their own license or terms of use, and the package author is not responsible for any third-party software. Happy TeXing! \endpreamble \generate{\file{listparskip.sty}{\from{listparskip_code.dtx}{package}} \file{listparskip_user_guide.tex}{\from{listparskip_code.dtx}{user}} \file{listparskip_example.tex}{\from{listparskip_code.dtx}{example}} \file{listparskip_heading.tex}{\from{listparskip_code.dtx}{heading}}} \catcode`\ =12\relax \immediate\write0{^^J% ****************************************************^^J% * Step 1 of the listparskip installation complete! *^^J% ****************************************************^^J^^J% ****************************************************^^J% * To finish installing the package, move *^^J% * listparskip.sty to a directory searchable by TeX *^^J% * after listparskip_code.tex is done typesetting *^^J% ****************************************************^^J} \endgroup \ifx\LaTeX\undefined \immediate\write0{Plain TeX format used; quitting now.} \immediate\write0{To create listparskip_code.pdf, run^^J% listparskip_code.dtx through LaTeX.^^J^^J} \expandafter\end \fi % %<*driver> \makeatletter \documentclass[12pt,doc2,letterpaper]{ltxdoc} \usepackage[margin=72.27pt]{geometry} \usepackage[factor=700,stretch=14,shrink=14,step=1]{microtype} \begin{document} \def\documentname{Implementation} \input listparskip_heading.tex \DocInput{listparskip_code.dtx} \end{document} % %<*package> % % \fi % % % \CheckSum{112} % \init@checksum % % \makeatother % \CharacterTable % {Upper-case \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z % Lower-case \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z % Digits \0\1\2\3\4\5\6\7\8\9 % Exclamation \! Double quote \" Hash (number) \# % Dollar \$ Percent \% Ampersand \& % Acute accent \' Left paren \( Right paren \) % Asterisk \* Plus \+ Comma \, % Minus \- Point \. Solidus \/ % Colon \: Semicolon \; Less than \< % Equals \= Greater than \> Question mark \? % Commercial at \@ Left bracket \[ Backslash \\ % Right bracket \] Circumflex \^ Underscore \_ % Grave accent \` Left brace \{ Vertical bar \| % Right brace \} Tilde \~} % \makeatletter % % % % % % % \noindent This file documents the code for the \textsf{listparskip} package. It is not a user guide! If you are looking for discussion of how \textsf{listparskip} will change the layout of your documents, see |listparskip_user_guide.pdf| and |listparskip_example.pdf|, which are included with the \textsf{listparskip} installation and are available on \textsc{ctan}. % % Spacing in list environments is subtle, and it will be helpful to summarize how \LaTeX\ implements vertical space in lists. Every list environment comes from either a |\list| or |\trivlist| macro, and |\list| is responsible for the standard list structure that shows up in enumerate, itemize, and description environments. A |\trivlist| is a list without any indentation or space for item markers, and this command comes up, for example, in quotations or some verbatim environments where fine control over vertical spacing is important. Both user-level commands serve as wrappers for the internal macro |\@trivlist|, which translates the definition of the current environment into internal list control sequences for processing later in the document. Default dimensions for different list levels come from the class file in the |\@listi| through |\@listiv| macros. % % When the user enters a list environment, for example with |\begin{enumerate}|, \TeX\ will at some point encounter |\@trivlist|. When that happens, \TeX\ prepares to add |\topsep| and |\parskip| to the main vertical list, and if \TeX\ is in \v mode, it prepares to add an extra |\partopsep|. The environment call itself doesn't add space or penalties, and instead, the first |\item| inside the list environment is responsible for these changes. Future uses of |\item| add an |\itempenalty| and |\itemsep| to the main vertical list, and any |\parsep| space additions happen automatically because \LaTeX\ sets |\parskip| to |\parsep| inside |\list| immediately after |\@trivlist|. At the end of the list environment, \TeX\ adds |\topsep| and, if it was present at the beginning of the environment, |\partopsep| to the main vertical list. \LaTeX\ does not instruct \TeX\ to manually add |\parskip|, so if the user includes, for example, an |\hbox| right after |\end{enumerate}|, \TeX\ will not add |\parskip| there. (\TeX\ is always in \v mode after it begins or ends a list environment.) % % Changing this behavior at the beginning of lists is straightforward---\textsf{listparskip} patches |\@trivlist| by treating the extra |\parskip| the same way \LaTeX\ normally treats |\partopsep|. Dealing with after-list space is more complicated. Normally |\@endparenv| adds |\topsep| and possibly |\partopsep| directly to the main vertical list, but we want a more tailored approach. Instead, \textsf{listparskip} redefines |\@endparenv| to add |\topsep| to the main vertical list and (globally) save |\topsep| plus |\partopsep| in |\@tempskipa|. Immediately outside the list environment, \textsf{listparskip} sets |\parskip| to 0pt and redefines |\par| to remove the previous |\topsep| and replace it with |\@tempskipa|. To ensure that (a) the extra |\partopsep| happens only if a blank line immediately follows the list and (b) \TeX\ avoids inserting |\parskip| only if \h mode material immediately follows the list, \textsf{listparskip} makes |\par|, |\everypar|, and |\item| restore |\par| and |\parskip| to their previous (local) definitions. Using creative groupings or manually redefining |\par| or |\everypar| right after a list may break things, so please be careful! % % Sometimes the user will want to include non-horizontal material, such as a box, immediately after a list environment without worrying about an extra or missing |\parskip| or |\partopsep|. In the implementation outlined above, \textsf{listparskip} adds or removes this space whenever \TeX\ first encounters a |\par| or \h mode material after a list. A box is neither of these things, so any after-list adjustments will show up after the box instead of before. The easiest way to avoid this problem is to transition to \h mode and then back to \v mode before adding the box, and the macro |\nullline| does this. % % \bigskip % \centerline{$***$} % \bigskip % % \noindent First, the package should declare itself. There are no package options. % \begin{macrocode} \NeedsTeXFormat{LaTeX2e} \ProvidesPackage{listparskip}[2024/12/17 v. 1.0 Package listparskip] \newdimen\@saveparskip % \end{macrocode} % We begin with spacing at the start of list environments. We patch |\@trivlist| such that |\@topsepadd| increases by |\parskip| only when \TeX\ is already in \v mode. % \begin{macrocode} \long\def\patch@trivlist#1\ifvmode#2\else#3% \advance\@topsep\parskip#4\@nil{% #1% \ifvmode \advance\@topsepadd\partopsep \advance\@topsepadd\parskip \else #3#4} \toks@\expandafter\expandafter\expandafter {\expandafter\patch@trivlist\@trivlist\@nil} \edef\@trivlist{\the\toks@} % \end{macrocode} % We change |\@endparenv| so that it adds only |\topsep|. We set |\@tempskipa| globally in order to access its value in |\@doendpe|, which is outside the current group. % \begin{macrocode} \def\@endparenv{% \addpenalty\@endparpenalty \addvspace\topsep \global\@tempskipa\glueexpr\topsep+\partopsep\relax \@endpetrue} % \end{macrocode} % Normally |\@restoreparskip| is |\relax|, but we change it in |\@doendpe| to return |\parskip| back to its previous value, which we have stored in |\@saveparskip|. This makes |\parskip\z@| a one-op. (Or a no-op if \TeX\ sees a |\par| or |\item| after the list and doesn't enter \h mode.)\vadjust{\penalty-100} % \begin{macrocode} \let\@restoreparskip\relax \def\@doendpe{% \@endpetrue \@saveparskip\parskip \parskip\z@ \def\@restoreparskip{% \parskip\@saveparskip \let\@restoreparskip\relax} % \end{macrocode} % We add |\@restoreparskip| to |\par|, and the |\addvspace| will replace the previous addition of |\topsep| from |\@endparenv| with |\topsep| plus |\partopsep|. We put everything inside an |\edef| so we can expand |\the\@tempskipa| now and not worry about a redefinition of |\@tempskipa| before the next |\par|. (Unlikely, but you never know.) % \begin{macrocode} \edef\par{% \unexpanded{\clubpenalty\@clubpenalty \everypar{}% \@restorepar\par \@restoreparskip \@endpefalse}% \noexpand\addvspace{\the\@tempskipa}}% % \end{macrocode} % The contents of |\everypar| here are the same as the \LaTeX\ default in this situation except that we add |\@restorepar| and |\@restoreparskip|. % \begin{macrocode} \everypar{\@restorepar \@restoreparskip {\setbox\z@\lastbox}% \everypar{}% \@endpefalse}} % \end{macrocode} % Next we add |\@restorepar| to the beginning of |\item|. Calling |\patch@item| on a control sequence |#1| will insert |\@restorepar| and |\@restoreparskip| into |#1|'s definition. % \begin{macrocode} \def\patch@item#1{% \edef#1{\noexpand\@restorepar \noexpand\@restoreparskip \expandafter\unexpanded\expandafter{#1}}} % \end{macrocode} % The \textsf{hyperref} package sometimes turns |\item| into a wrapper for itself. In that case, \textsf{hyperref} will have renamed |\item| to |\H@item|, so we patch that instead. % \begin{macrocode} \@ifpackageloaded{hyperref}{% \ifHy@implicit \patch@item\H@item \else \patch@item\item \fi}{\patch@item\item} % \end{macrocode} % Finally, create the command that forces a transition from \textsc v mode to \h mode and back without (directly) adding any space. % \begin{macrocode} \def\nullline{\ifvmode\nointerlineskip\leavevmode\par\fi} % \end{macrocode} % All done! % % % \iffalse % ^^A No version history unless we end up with multiple versions % % \vfill\eject % % \section*{Version History} % % \begin{multicols*}{2} % \raggedright % \parskip\z@ % \parindent\z@ % \leftskip1em % \obeylines % \setbox0\hbox{\hskip 1pt.\hskip 1pt} % \def\version#1#2{\bigskip\hbox to \hsize{\textbf{#1} % % \cleaders\copy0\hfill\ #2}\par} % \def\item{---\kern0.2ex\relax} % % \version{1.0}{May 2024} % \item initial release % % % \end{multicols*} % % \fi % % % \check@checksum % % % \iffalse % %<*user> % \documentclass[12pt]{article} \usepackage[margin=72.27pt]{geometry} \usepackage[factor=700,stretch=14,shrink=14,step=1]{microtype} \usepackage{booktabs} \usepackage{tabularx} \usepackage{enumitem} \setlist{topsep=\smallskipamount,itemsep=\smallskipamount, parsep=0pt,partopsep=0pt} \usepackage{shortvrb} \MakeShortVerb{|} \begin{document} \def\documentname{User Guide} \newdimen\MacroIndent \input listparskip_heading.tex \noindent Most \LaTeX\ users are familiar with the enumerate and itemize environments, and a number of other environments share the same underlying macros and structure. These list environments are useful and versatile, and they come up in many different situations where fine control over vertical spacing is important.\footnote{There is an overlap in terminology. The list environments described in this document are very different from horizontal and vertical lists in the \TeX\ language.} The dimensions |\topsep|, |\parsep|, |\partopsep|, and |\itemsep| control vertical spacing for list environments, and by default, \LaTeX\ determines the space immediately outside a list as follows: \begin{itemize} \item Always add |\topsep| before and after a list \item Add |\parskip| (not |\parsep|) always before a list and usually after it\footnote{\TeX\ treats any text after a list as the start of a new paragraph, so if the next material to be typeset is text, \TeX\ adds \vrb\parskip\ after the list. If the user includes a box or rule instead of text, it does not trigger the start of a paragraph, and \TeX\ does not add \vrb\parskip.} \item If a list begins outside of a paragraph, add |\partopsep| before and after the list \end{itemize} If |\parskip| is nonzero, for example in a formal letter, it is impossible to include a list inside a paragraph without the inter-paragraph space suggesting that the list forms its own paragraph. (Unless the user manually changes |\parskip| or adds negative vertical glue.) Similarly, \LaTeX\ chooses whether to add |\partopsep| after a list independently of what happens at that point in the source code. The \textsf{listparskip} package modifies this behavior by making the |\parskip| and |\partopsep| spacing depend more closely on paragraph structure from the source code. Under \textsf{listparskip} rules, the space around lists happens as follows: \begin{itemize} \item Always add |\topsep| before and after a list \item If a list begins outside of a paragraph, add |\parskip| and |\partopsep| before the list \item If a blank line comes immediately after the list in the source code, always add |\partopsep| and usually add |\parskip| \end{itemize} These changes happen automatically after loading the package, and they allow the user to control whether \TeX\ positions a list environment as its own paragraph or as part of the surrounding paragraph. When |\parskip| and |\partopsep| are both 0pt, this package does nothing, but for an example of what can happen when either dimension is positive, see |listparskip_example.pdf|, which is included with the \textsf{listparskip} installation and is available on \textsc{ctan}. Users can load \textsf{listparskip} with the standard |\usepackage{listparskip}| syntax, and the package has no options. \begin{figure}[t] \centerline{\bfseries Table 1: Recommended Source Code to Insert after a List\strut} \begin{tabularx}{\textwidth}{lXX}\toprule Next Material to Typeset & No New Paragraph Desired & New Paragraph Desired \\\midrule Text & Nothing & Blank line \\ |\item| & Nothing & Nothing or blank line \\ Box or Rule & |\nullline| & Blank line, then |\nullline| \\\bottomrule \end{tabularx} \end{figure} \begin{figure}[tb] \centerline{\bfseries Table 2: Space after a List When Using \textsf{listparskip}\strut} \begin{tabularx}{\textwidth}{XX}\toprule Material after a List & Vertical Space Used in Addition to |\topsep|\\\midrule Text* & None \\ Box & Don't do this\textsuperscript\ddag \\ |\item|*\textsuperscript\dag & $\vrb\parsep+\vrb\itemsep$ \\\midrule Blank line, then text* & $\vrb\partopsep+\vrb\parskip$ \\ Blank line, then box & Don't do this\textsuperscript\ddag \\ Blank line, then |\item|*\textsuperscript\dag & $\vrb\partopsep+\vrb\parsep+\vrb\itemsep$ \\\midrule |\nullline|, then text & |\parskip| \\ |\nullline|, then box* & None \\ |\nullline|, then |\item|\textsuperscript\dag & $\vrb\parsep+\vrb\itemsep$ \\\midrule Blank line, then |\nullline|, then text & $\vrb\partopsep+2\vrb\parskip$ \\ Blank line, then |\nullline|, then box* & $\vrb\partopsep+\vrb\parskip$ \\ Blank line, then |\nullline|, then |\item|\textsuperscript\dag & $\vrb\partopsep+2\vrb\parsep+\vrb\itemsep$ \\ \bottomrule \end{tabularx} \smallskip \vbox{\footnotesize\noindent\hskip 1.8em\llap{*}Recommended use. \noindent\hskip 1.8em\llap{\textsuperscript\dag}For \vrb\item\ in a nested list, the \vrb\parsep\ and \vrb\itemsep\ refer to the dimensions in the outer list, not the list that just ended. \noindent\hskip 1.8em\llap{\textsuperscript\ddag}With \textsf{listparskip}, putting a box after the end of a list environment without text or \vrb\nullline\ previously may mess up vertical spacing or paragraph indentation after the box depending on what comes next.} \end{figure} Immediately after the end of a list environment, \textsf{listparskip} expects to see a some text, a blank line followed by text, or an |\item|. As a general rule, text means an extra |\topsep|, and a blank line followed by text leads to an extra $\vrb\topsep+\vrb\partopsep+\vrb\parskip$. If you want to put something else, such as a box or rule, after the end of a list environment, you should type |\nullline| before the other material to prevent any spacing mishaps. This macro instructs \TeX\ to behave like it just encountered a line of text except without adding any vertical space. Table~1 shows my recommendations for code to include after a list in various cases depending on the desired result, and Table~2 shows the full rules for what happens after a list with \textsf{listparskip} in various situations. For more information, see |listparskip_code.pdf|, which is included with the \textsf{listparskip} installation and is available on \textsc{ctan}. \end{document} % % %<*example> % % \documentclass[12pt]{article} \usepackage[margin=72.27pt]{geometry} \usepackage[factor=700,stretch=14,shrink=14,step=1]{microtype} \usepackage{lipsum} \usepackage{multicol} \usepackage{enumitem} \setlist{parsep=0pt,partopsep=\medskipamount, topsep=\smallskipamount,itemsep=\smallskipamount} \usepackage{shortvrb} \MakeShortVerb{|} \parindent=0pt \makeatletter \begin{document} \def\documentname{Example} \newdimen\MacroIndent \input listparskip_heading.tex \baselineskip=14pt This document shows an example of \textsf{listparskip}. The left column uses standard \LaTeX\ spacing before and after the itemize and enumerate lists, and the right column shows the same text with \textsf{listparskip} spacing rules. Notice \textsf{listparskip} corrects the issues from the left column. \begin{multicols*}{2} \parskip\bigskipamount \lipsum[1][1] This paragraph has some bullet points in the middle of the paragraph. In this portion of the document, |\parskip| is set to |\bigskipamount|, and we see that \begin{itemize} \item \LaTeX\ inserts |\parskip| above the list \item Even though there is no |\par| between the paragraph and the itemize environment in the source code \item The same thing is true after the itemize \item It's especially salient when |\topsep| and |\itemsep| are |\smallskipamount| \end{itemize} Currently |\partopsep| is |\medskipamount|, but when there is no |\par| immediately before a list, \LaTeX\ does not insert |\partopsep| before or after the list environment. \hbox{This is true} \begin{enumerate} \item Despite the use of |\parskip|; and \item For the end of the list environment regardless of whether a |\par| follows the list, as is the case with this enumerate. \end{enumerate} \lipsum[1][2] \vfill\nointerlineskip\null \columnbreak \lipsum[1][1] This paragraph has some bullet points in the middle of the paragraph. In this portion of the document, |\parskip| is set to |\bigskipamount|, and we see that \begin{itemize} \vskip-\@outerparskip \vskip\z@ \item \LaTeX\ inserts |\parskip| above the list \item Even though there is no |\par| between the paragraph and the itemize environment in the source code \item The same thing is true after the itemize \item It's especially salient when |\topsep| and |\itemsep| are |\smallskipamount| \end{itemize} \vskip-\parskip Currently |\partopsep| is |\medskipamount|, but when there is no |\par| immediately before a list, \LaTeX\ does not insert |\partopsep| before or after the list environment. \hbox{This is true} \begin{enumerate} \vskip-\@outerparskip \vskip\z@ \item Despite the use of |\parskip|; and \item For the end of the list environment regardless of whether a |\par| follows the list, as is the case with this enumerate. \end{enumerate} \vskip\partopsep \lipsum[1][2] \end{multicols*} \end{document} % % % %<*heading> % % preliminaries \csname count@\endcsname\catcode`\@ \makeatletter % date \def\packageversion{1.0} \def\packagedate{December 2024} % spacing macros \MacroIndent=1.3em \baselineskip=\the\baselineskip plus 0.3pt minus 0.3pt\relax % section redefinition \let\@@section\section \def\section{\@ifstar\star@sect\no@star@sect} \def\star@sect#1{\sectionhook{#1}\@@section*{#1}} \def\no@star@sect#1{\sectionhook{#1}\@@section{#1}} % \def\sectionhook#1{% \ifdim\dimexpr\pagegoal-\pagetotal-3pt\relax<6\bigskipamount \vfill\eject \fi \def\sectionname{#1}} \let\sectionhook\@gobble % header and footer (centered page number in the foot % for first page only; otherwise at left or right of % the header) \def\@oddhead{% \ifnum\count0>1\relax \ifodd\c@page \hfil \llap{\the\count0}% \else \rlap{\the\count0}\hfil \fi \fi} \def\@oddfoot{\hfil\ifnum\count0=1\relax1\fi\hfil} % penalties \pretolerance=-1 \hyphenpenalty=20 \exhyphenpenalty=15 \brokenpenalty=0 \clubpenalty=0 \widowpenalty=0 \finalhyphendemerits=500 \doublehyphendemerits=2000 % floats \c@topnumber\@ne \def\topfraction{1} \def\bottomfraction{0.5} \def\textfraction{0} \def\floatpagefraction{0} % macros \def\h{\textsc h } \def\v{\textsc v } \def\smallskip{\vskip\smallskipamount} \def\medskip{\vskip\medskipamount} \def\bigskip{\vskip\bigskipamount} % environment for code (would probably better to use % trivlist) \let\code\@undefined \let\endcode\@undefined \newenvironment{code} {\strut\vadjust\bgroup\medskip\parindent\z@\leftskip=4em\relax \noindent\strut\ignorespaces} {\strut\par\medskip\egroup\hfill\break\strut\ignorespacesafterend} \def\argtext#1{\ensuremath{\langle$\textit{#1}$\rangle}} \def\vrb#1{\expandafter\texttt\expandafter{\string#1}} \def\clap@math#1{\hb@xt@\z@{\hss$\displaystyle#1$\hss}} % begin first-page heading {\large \parindent=0pt \leftskip=0pt plus 1 fil \rightskip=0pt plus 1fil \parfillskip=0pt {\strut\Large Package \textsf{listparskip} v.\ 1.0 \documentname}\par \strut Conrad Kosowsky\par \strut \packagedate\par \strut\texttt{kosowsky.latex@gmail.com}\par} % bigskip \bigskip % overview/abstract {\small \leftskip=0.5in \rightskip=0.5in \centerline{\bfseries Overview\strut} \noindent The \textsf{listparskip} package modifies list environments such that they add |\parskip| and |\partopsep| before or after a list if and only if the environment follows or precedes, respectively, a blank line (i.e.\ a |\par|). \par} % bar between overview/abstract and text \bigskip\bigskip\nointerlineskip \centerline{\vrule height 0.5pt width 2.5in}\bigskip\bigskip \nointerlineskip % restore catcode \catcode`\@\count@ % % % % \fi % % \endinput