11

Edit: I am not happy with the 3 answers my first, smaller bounty got me. So I rewrote the question to set clear rules and a proper bounty.


The solution should create two environments, originalemail and response with the following effects:

  • The originalemail-environment can be wrapped around normal LaTeX code, which might include lists, sections, etc, and that is then typeset normally, but in a way that slightly (4pt) indents all text and adds a vertical line on the left.
  • The response environment can be used inside the originalemail environment and results in the vertical line being broken and the contained text/code being aligned on the left without the originalemails indentation. The response has to be aligned to the left margin, irrespective of where in the originalemail it is placed (e.g., within a (nested) itemize or enumerate).

Summary

  • leave the layout of the original email in-tact (it should be possible to use sections, lists, paragraphs, floats, etc. as if it as was a plain TeX document and there were no responses and the numbering should be the same with and without respones)
  • using these environments should require no editing of the code after \begin{document}, outside the response environment. In particular any suspension or resume of enumerate or itemize environments---if required by the solution---should be automatic.
  • The only way in which the original layout should change is that it show vertical line (2pt) on the left margin and ideally a slight indentation (4pt).
  • responses and the fragments of the original email have to break pages as normal. (if you use parbox for the responses they wont)
  • allow to insert \replys anywhere in the the original text
  • bonus if the solution is nesteable (i.e. the outer originalemail contains an older originalemail and responses)

Rules: for the bounty, you're free to build on the existing answers, i.e. @marmot's/Gonzalo Medina's TikZ approach to draw the line in the left margin, @Vinccool96's tcolorbox or my own rudimentary approach to automatically suspending and resuming lists.

Screenshot from Gmail that roughly summarizes what I need: enter image description here

Input example This is a simple example of the document I am starting with. It is a standard LaTeX document, which I wrap into \begin{originalemail}...\end{originalemail}. Next I need to add my responses to it, but this should work context-independent (i.e. without manually tracking which other environments are currently open, which is why the answer by @Vinccool96 was not accepted)

Of course you may edit the preamble in order to define the new environments.

\documentclass{article}
%you may add code here
\begin{document}
%you may add code here
    \begin{originalemail}
     %inside this, the only change I can make to the code may be within
     % \begin{response}...\end{response}
        Text text text text text text
        \section{Text text text}
            Text text
            \begin{enumerate}
                \item text 
                \begin{itemize}
                    \item text 
                    \item text 
                \end{itemize}
                \item text 
                \item text 
            \end{enumerate}
    \end{originalemail}
\end{document}

The new enviroments should allow me to use \begin{response}my response\end{response} anywhere inside the orininalemail and achieve the desired layout break.

As pointed out by @Vinccool96, in order to break out out nested originalemails it might be neccessary to pass an argument \begin{response}[2] to indicate the number of levels it should break out of. But nesting is only a bonus.

  • 1
  • 2
    Not a solution, but if you are looking into this I would try to use tcolorbox instead of mdframed. tcolorbox is actively maintained and has an awesome manual while mdframed development seems to have stalled a while ago. – moewe Mar 20 at 16:31
  • 2
    @sheß Could you clarify? One can indeed put enumerations inside the \embed. So are you looking to suspend the embed to provide a response and then continue the enumeration where it left off? – Steven B. Segletes Mar 20 at 16:37
  • 3
    Isn't this an instance of a XY problem, where your actual ultimate objective is to nicely add your comment on a document submitted to you? If so, you might want to have a look at the todonotes package. (I.e. this package doesn't do the "bar in the left margin" thing, but might be of greater help for what you ultimately want to do. See notably inline notes.) See also changes package. – ebosi Mar 28 at 11:13
  • 2
    Actually, I think that what you are looking for is the changebar package. – ebosi Mar 28 at 11:19
5
+50
\documentclass{article}

\usepackage[most]{tcolorbox}
\tcbuselibrary{breakable}
\tcbuselibrary{skins}

\newtcolorbox{emailstart}[3][]{%
    standard jigsaw,
    opacityframe=0,
    opacityback=0,
    colback=transparent,
    grow to left by=-1.5em,
    boxrule=0pt,
    boxsep=0pt,
    breakable,
    enhanced jigsaw,
    title={On #2, #3 wrote\par},
    coltitle={black},
    attach title to upper={},
    borderline west={4pt}{0pt}{black},
    overlay unbroken and first={\draw[shorten >=1.4pt, shorten <=1.4pt] ([yshift=-1.5em]frame.north west) -- ([yshift=-1.5em]frame.north east);},
    #1,
}

\newtcolorbox{emailresume}[1][]{%
    standard jigsaw,
    opacityframe=0,
    opacityback=0,
    colback=transparent,
    grow to left by=-1.5em,
    boxrule=0pt,
    boxsep=0pt,
    breakable,
    enhanced jigsaw,
    borderline west={4pt}{0pt}{black},
    #1,
}

\newcounter{enumicounter} %counter that will save the enumeration counter

\begin{document}
    \begin{emailstart}{2019}{Einstein}
        \begin{emailstart}{2018}{Sheß}
            Text Text Text Text

            Text Text Text Text Text Text Text
        \end{emailstart}
        Here I am putting my answer text 
    \end{emailstart}
    Oh, now I see your point


    \begin{emailresume}
        \begin{emailresume}
            \section{A section}
            Some content a list
            \begin{enumerate}
                \item One
                \setcounter{enumicounter}{\value{enumi}} % save the enumeration counter
            \end{enumerate}
        \end{emailresume}
        Here even more, there's no indentation, because you closed the enumaration and the email
    \end{emailresume}
    This is an answer to your answer
    \begin{emailresume}
        \begin{emailresume}
            \begin{enumerate}
                \setcounter{enumi}{\value{enumicounter}} % continue the enumeration
                \item Two
                \setcounter{enumicounter}{\value{enumi}} %save the enumeration counter
            \end{enumerate}
        \end{emailresume}
        Answer
        \begin{emailresume}
            \begin{enumerate}
                \setcounter{enumi}{\value{enumicounter}} % continue the enumeration
                \item Three
                \item Four
                \setcounter{enumicounter}{\value{enumi}} %save the enumeration counter
            \end{enumerate}
            \section{another section}
            More Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text
            \subsection{a subsection}
            More Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text
        \end{emailresume}
        More
        \begin{emailresume}
            \subsection{another subsection}
            More Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text Text
        \end{emailresume}
        More
        \begin{emailresume}
            Bye,

            Sheß
        \end{emailresume}
        Bye,

        Einstein
    \end{emailresume}
    Bye
\end{document}

  • So what you want is to get it with the indentation, except when you specifiy there's an answer? – Vinccool96 Mar 23 at 23:03
  • I modified my answer – Vinccool96 Mar 25 at 16:20
  • That's because it's in an enumerate environment. You'll need to add a \end{enumerate} before \response and a \begin{enumerate} after. – Vinccool96 Mar 26 at 16:07
  • Again edited. Is it good now? – Vinccool96 Mar 27 at 16:39
  • I proposed you something first where you only had to specify to resume the enumeration, but you rejected it. – Vinccool96 Mar 28 at 16:48
3

All I did here is to slightly modify Gonzalo Medina's nice answer. One can of course tune it a bit more. (I also understand that there is nothing squiggly here, I was too lazy to rename the macros.)

\documentclass{article}
\usepackage{refcount}
\usepackage{tikz}
\usetikzlibrary{calc,tikzmark}
\usepackage{lipsum}

\newcounter{tmp}
% \newcommand\tikzmark[1]{%
%   \tikz[overlay,remember picture] \node (#1) {};}

\newcommand\Startsquiggly{%
  \stepcounter{tmp}%
  \tikzmarknode{a}{\strut}\label{a\thetmp}%
  \ifnum\getpagerefnumber{a\thetmp}=\getpagerefnumber{b\thetmp} \else
  \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (a.south), \p2 = (b), \p3 = (current page.center) in
      ( $ (\x3,\y1) + (-.55\textwidth,0) $ ) --  ( $ (\x3,\y3) + (-0.55\textwidth,-0.5\textheight) $ );
  \end{tikzpicture}%
  \fi%
}

\newcommand\Endsquiggly{%
\tikzmarknode{b}{\strut}\label{b\thetmp}
  \ifnum\getpagerefnumber{a\thetmp}=\getpagerefnumber{b\thetmp}
  \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (a.south), \p2 = (b), \p3 = (current page.center) in
      ( $ (\x3,\y1) + (-.55\textwidth,1em) $ ) --  ( $ (\x3,\y2) + (-.55\textwidth,1em) $ );
  \end{tikzpicture}%
  \else
  \begin{tikzpicture}[overlay, remember picture]
    \draw [ultra thick,gray]
      let \p1 = (a.south), \p2 = (b), \p3 = (current page.center) in
      ( $ (\x3,\y3) + (-.55\textwidth,.5\textheight) $ ) -- ( $ (\x3,\y2) + (-.55\textwidth,1em) $ );
  \end{tikzpicture}%
  \fi
}

\newcommand\Squ[1]{\Startsquiggly#1\Endsquiggly}
\AtBeginDocument{\Startsquiggly}
\AtEndDocument{\par\Endsquiggly}
\newcommand{\response}[1]{\par\Endsquiggly#1\par\Startsquiggly}
\begin{document}
Some text, with pictures, lists, sections
\begin{enumerate}
\item Some text, with pictures, lists, sections
\response{answer1}
\item Some text, with pictures, lists, sections
\response{answer2}
\end{enumerate}
Some text, with pictures, lists, sections
\response{this is my answer}
Some text, with pictures, lists, sections
\section{section}
\subsection{subsection1}
Some text, with pictures, lists, sections
\subsection{subsection2}
Some text, with pictures, lists, sections
\subsection{subsection3}
Some text, with pictures, lists, sections
\response{I also have an answer here}
More text
\end{document}

enter image description here

  • 1
    @sheß Absolutely. Please note that there are also many posts linked to Gonzalo's nice answer, some of which may become relevant if you have something like \raggedbottom and so on. (I really just very quickly wrote that before I went cycling, there are many things one may want to add/consider/improve.) – marmot Mar 23 at 23:14
  • @sheß This point I do not understand. There are two things: (1) Draw the interrupted line on the margin and (2) add indentation. I didn't know you want to have (2) (which is clearer after the edit). So you wish to indent sections and so on? (In this case the question is very different from what I originally thought it is.) Or only texts as in the email conversation? – marmot Mar 28 at 17:30
  • 1
    Whoever downvoted this answer may want to take into account that this was an attempt to answer the question before the edit(s). – marmot Mar 30 at 18:29
  • Sorry, I missed the grace period and the bounty was out awarded – sheß Mar 31 at 10:03
2

A solution I came up with, but I'm still fairly unhappy with the amount of things that are hard-coded. E.g.

  • it requires that I change all \begin{enumerate}[some arguments] to \begin{enumerate}{some arguments}
  • works only for up to a fixed number of nested enumerates and
  • probably fails if the original document uses an itemize or something else.
  • it cannot be nested

So, eventhough I'm posting this as an aswer to my own post, I do not consider this complete and would be happy for anyone who adapts it to be more general

\documentclass{article}

\newcounter{breakdepth}
\usepackage{enumitem}
\usepackage{letltxmacro}

%redefine enumerates so that they are automatically resumable
\LetLtxMacro\ooenumerate\enumerate
\LetLtxMacro\endooenumerate\endenumerate
\makeatletter
    \renewenvironment{enumerate}[2][0]{%
        \ifx0#1%i.e. this is not a resume, but a new list, so start naming it.
            \ooenumerate[series=level\the\@enumdepth,#2]%
        \else
            \ooenumerate[#2]%
        \fi
    }{
         \endooenumerate%
    }
%define the command that breaks the \report environment, closes all enumerates, but resumes them afterwards
\newcommand{\response}[1]{%
\setcounter{breakdepth}{\the\@enumdepth}%
\ifnum\value{breakdepth}>3  \end{enumerate} \fi%
\ifnum\value{breakdepth}>2  \end{enumerate} \fi%
\ifnum\value{breakdepth}>1  \end{enumerate} \fi%
\ifnum\value{breakdepth}>0  \end{enumerate} \fi%
\end{report}%
#1%
\begin{report}%
\ifnum\value{breakdepth}>0  \begin{enumerate}[]{resume*=level\the\@enumdepth}\item[]\fi%
\ifnum\value{breakdepth}>1  \begin{enumerate}[]{resume*=level\the\@enumdepth}\item[]\fi%
\ifnum\value{breakdepth}>2  \begin{enumerate}[]{resume*=level\the\@enumdepth}\item[]\fi%
\ifnum\value{breakdepth}>3  \begin{enumerate}[]{resume*=level\the\@enumdepth}\item[]\fi%
}
\makeatother
%define the environment that has a slight indentation and a vertical line for the original text
\usepackage{mdframed}
\newenvironment{report}{\begin{mdframed}[linewidth=1pt,topline=false,rightline=false,bottomline=false,linecolor=black,innerleftmargin =0cm, leftmargin=2pt,innerrightmargin=1pt]}{\end{mdframed}}

\begin{document}
    \begin{report}
    \section{first section}
    \begin{enumerate}{label=\roman*.}
    \item ione 
    \begin{enumerate}{}
    \item aone
    %%%%%%%%%
    \response{test} 
    %%%%%%%%%
    \item atwo
    \end{enumerate}
    \item itwo
    \response{test} 
    \end{enumerate}
    \section{a section}
    Some text that is not inside a list
    \response{test} 
    more text
    \end{report}
\end{document}

enter image description here

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.