minted icon indicating copy to clipboard operation
minted copied to clipboard

Text after \mint always begins with a new paragraph

Open muzimuzhi opened this issue 5 years ago • 9 comments

Text after \mint always begins with a new paragraph, and this is inconsistent with the minted env.

MWE:

\documentclass{article}
\usepackage{minted}
\begin{document}
text before minted env
\begin{minted}{html}
<h2>Something</h2>
\end{minted}
text after minted env

\bigskip

text before mint cmd
\mint{html}|<h2>Something</h2>|
text after mint cmd
\end{document}

image

muzimuzhi avatar Oct 14 '18 19:10 muzimuzhi

\mint is a shortcut for a one-line minted. I think you want \mintinline.

gpoore avatar Oct 14 '18 19:10 gpoore

I know \mintinline. But according to the document, \mint should acts the same as minted env, except that \mint is a one-line minted.

My MWE shows that, the text right behind\mint always begins with a new paragraph, while the text right following minted will not. I think this difference break the law that "\mint is only a shortcut of minted".

muzimuzhi avatar Oct 15 '18 12:10 muzimuzhi

Alright, I misunderstood what you were doing. That's a bug.

gpoore avatar Oct 15 '18 13:10 gpoore

It seems that Inserting a \leavevmode either before or after \minted@langlinenosoff in the definition of \mint@iii solves the problem.

\documentclass{article}
\usepackage{minted}  
\usepackage{etoolbox}

\makeatletter
% insert \leavevmode either before or after \minted@langlinenosoff
\patchcmd{\mint@iii}
  {\minted@langlinenosoff}
  {\minted@langlinenosoff\leavevmode}
  {}{\fail}
\makeatother

\begin{document}
text before minted env
\begin{minted}{html}
<h2>Something</h2>
\end{minted}
text after minted env

\bigskip

text before mint cmd
\mint{html}|<h2>Something</h2>|
text after mint cmd
\end{document}

image

Note: This has not been fully tested and I have not read through and understand the whole implementation of minted.


Update: \mint@iii uses \UseVerbatim (directly if draft mode of minted is on, otherwise indirectly) from fancyvrb package. This problem can be traced back to \UseVerbatim.

\documentclass{article}
\usepackage{fancyvrb}
\begin{document}
\begin{SaveVerbatim}{VerbEnv}
Verbatim line.
\end{SaveVerbatim}

1. Without extra group, ok
\UseVerbatim{VerbEnv}text

2. With extra group, wrong
{\UseVerbatim{VerbEnv}}text

3. With extra group and insert \verb|\leavevmode| before group ends, ok
{\UseVerbatim{VerbEnv}\leavevmode}text
\end{document}

image

Investigating implementation of \UseVerbatim may provide more info about "why this acts like that".

muzimuzhi avatar Oct 17 '19 03:10 muzimuzhi

Related lines of source code: https://github.com/gpoore/minted/blob/5d72859d714a6f2f6a42eec524476994d954b960/source/minted.dtx#L3249-L3276

muzimuzhi avatar Oct 17 '19 03:10 muzimuzhi

This comment

  1. shows my further investigation which starts from \UseVerbatim and
  2. provides reasons to support my previous suggestion (inserting \leavevmode).

Update 2: After some expansion, \UseVerbatim{VerbEnv} expands to

\FV@UseVerbatim{FV@SV@VerbText}

where

% result of executing `latexdef -p fancyvrb -s \FV@UseVerbatim` in command-line
% fancyvrb.sty, line 731:
\def\FV@UseVerbatim#1{%
  \FV@VerbatimBegin#1\FV@VerbatimEnd
  \@doendpe\global\@ignorefalse\ignorespaces}

% result of executing `latexdef -s \@doendpe` in command-line
% latex.ltx, line 4894:
\def\@doendpe{\@endpetrue
     \def\par{\@restorepar
              \clubpenalty\@clubpenalty
              \everypar{}\par\@endpefalse}\everypar
               {{\setbox\z@\lastbox}%
                \everypar{}\@endpefalse}}

Hence the extra group around \UseVerbatim will restrict the redefinition of \par (done by \@doendpe) inside the group. Therefore when a new paragraph starts when tex engine encounters text after \UseVerbatim{...}, the auto-inserted \par is the original version. This causes the problem reported in this issue: paragraph indentation is inserted.

The insertion of \leavevmode makes the start of new paragraph (hence the auto-insertion of \par) ahead of the ending of extra group. This way, the inserted \par is the modified-by-\@doendpe version, hence new-paragraph-indentation is prohibited as expected.

muzimuzhi avatar Oct 17 '19 03:10 muzimuzhi

@muzimuzhi \leavevmode would be wrong here, it prematurely starts the paragraph so if the following thing is a new paragraph (or any kind of vertical display environment) then you will get a spurious paragraph with no text, no indent and just \parfillskip so it will look like extra vertical space (but not be dropped at a page break:

\documentclass{article}
\usepackage{minted}  
\usepackage{etoolbox}

\makeatletter
% insert \leavevmode either before or after \minted@langlinenosoff
\patchcmd{\mint@iii}
  {\minted@langlinenosoff}
  {\minted@langlinenosoff\leavevmode}
  {}{\fail}
\makeatother

\begin{document}
text before minted env
\begin{minted}{html}
<h2>Something</h2>
\end{minted}

text after minted env

\bigskip

text before mint cmd
\mint{html}|<h2>Something</h2>|

text after mint cmd
\end{document}

you want to lift \@doendpe out of the group

davidcarlisle avatar Oct 17 '19 06:10 davidcarlisle

Here is another attempt that adds an extra "@doendpe" into \mint@iii just after the ending of extra group. This seems to work either the following thing do starts a new paragraph or not.

\documentclass{article}
\usepackage{minted}  
\usepackage{etoolbox}

\makeatletter
% issue another \@doendpe and lift it out of the group
\patchcmd{\mint@iii}
  {\minted@langlinenosoff\endgroup}
  {\minted@langlinenosoff\endgroup\@doendpe}
  {}{\fail}
\makeatother

\begin{document}

\section*{Result of \texttt{minted} env}

\paragraph{1. }text before minted env
\begin{minted}{html}
<h2>Something</h2>
\end{minted}

new paragraph

\paragraph{2. }text before minted env
\begin{minted}{html}
<h2>Something</h2>
\end{minted}
not new paragraph

\section*{Result of \texttt{\textbackslash mint} cmd}

\paragraph{3. }text before mint cmd
\mint{html}|<h2>Something</h2>|

new paragraph

\paragraph{4. }text before mint cmd
\mint{html}|<h2>Something</h2>|
not new paragraph
\end{document}

image


I tried to substitute \aftergroup\@doendpe for \@doendpe in definition of \FV@UseVerbatim, but it works only if minted option "draft" is on. (Go back to reading source codes of minted.)

\def\renew@FV@UseVerbatim{% works only if minted option "draft" is on
  \def\FV@UseVerbatim##1{%
      \FV@VerbatimBegin##1\FV@VerbatimEnd
      \aftergroup\@doendpe\global\@ignorefalse\ignorespaces}%
}

\patchcmd{\mint@iii}
  {\minted@langlinenoson}
  {\minted@langlinenoson\renew@FV@UseVerbatim}
  {}{\fail}

muzimuzhi avatar Oct 18 '19 07:10 muzimuzhi

This is what I have known when "draft" is off,

  • \mint writes formatted text to .pygtex file.
  • The contents of this file is a Verbatim environment. (I haven't even reminded myself of this when posting last comment.)
  • By definition, \endVerbatim -> \FVE@Verbatim -> \FV@VerbatimEnd -> \FV@EndList
  • \FV@EndList is defined as
    \def\FV@EndList{%
      \FV@ListProcessLastLine
      \FV@EndListFrame
      \@endparenv
      \endgroup
      \@endpetrue}
    
  • It is \@endparenv and \@endpetrue from latex2e that change the indentation of following text.

It seems that the solve-by-redefine approach (like the \renew@FV@UseVerbatim in my last comment) would be more complex than I think and than inserting another \@doendpe.

muzimuzhi avatar Oct 18 '19 08:10 muzimuzhi