8

So I must admit I am way out of my depth and have no idea what I'm doing.

I apologize in advance for a long and complicated question.

I'm trying to build this output:

enter image description here

Which I have successfully (sort of) done.

However, what I really want to do is make a new environment called offset to do this automatically, taking the number of lines occupied by the text as an argument.

I've placed my code to make the environment inside

\newenvironment{offset}
{
Code before content
}
{
Code after content
}

but when I try to use begin{offset} . . . \end{offset} I get the basic framework of my offset environment and the tikz lines, but no text. What (well, how much) am I doing wrong?

Here's the code I've written, with commented blocks to make it easier to test the drawing and placement code inside and outside of the environment call.

\documentclass[final,oneside,11pt]{memoir}
\usepackage{tikz}
\usepackage{calc}
\usepackage{wrapfig}
\usepackage{lipsum}
% \usepackage{showframe}

\newenvironment{offset}
{
    \begin{wrapfigure}[19]{r}[1in]{2in}
        \noindent
        \newlength{\topverticalspacer}
        \setlength{\topverticalspacer}{-\baselineskip-\tabcolsep}
        \vspace*{\topverticalspacer}\\
        \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
            \node (0, 0) (n1) {};
            \draw[-,line width=1pt] (n1)--(2in, 0);
        \end{tikzpicture}\\
        \newlength{\verticalspacer}
        \setlength{\verticalspacer}{\tabcolsep-\baselineskip}
        \vspace*{\verticalspacer}\\
        \hspace*{\tabcolsep}
        \parbox{1.75in}{\textsf{
        \hspace{-5pt}
}
{
        }}
        \newlength{\bottomspacer}
        \setlength{\bottomspacer}{\baselineskip-\tabcolsep}
        \vspace*{\bottomspacer}\\
        \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
        \node (0, 0) (n2) {};
        \draw[-,line width=1pt] (n2)--(1in, 0);
    \end{tikzpicture}
    \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
        \draw[-,line width=1pt] (n1) -- (n2);
    \end{tikzpicture}
    \end{wrapfigure}
}

\begin{document}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \begin{offset}
    % \begin{wrapfigure}[19]{r}[1in]{2in}
    %   \noindent
    %   \newlength{\topverticalspacer}
    %   \setlength{\topverticalspacer}{-\baselineskip-\tabcolsep}
    %   \vspace*{\topverticalspacer}\\
    %   \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
    %       \node (0, 0) (n1) {};
    %       \draw[-,line width=1pt] (n1)--(2in, 0);
    %   \end{tikzpicture}\\
    %   \newlength{\verticalspacer}
    %   \setlength{\verticalspacer}{\tabcolsep-\baselineskip}
    %   \vspace*{\verticalspacer}\\
    %   \hspace*{\tabcolsep}
    %   \parbox{1.75in}{\textsf{
    %   \hspace{-5pt}
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
            tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
            quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
            consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
            cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
            proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    %   }}
    %   \newlength{\bottomspacer}
    %   \setlength{\bottomspacer}{\baselineskip-\tabcolsep}
    %   \vspace*{\bottomspacer}\\
    %   \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
    %   \node (0, 0) (n2) {};
    %   \draw[-,line width=1pt] (n2)--(1in, 0);
    % \end{tikzpicture}
    % \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
    %   \draw[-,line width=1pt] (n1) -- (n2);
    % \end{tikzpicture}
    % \end{wrapfigure}
    \end{offset}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \lipsum[2-4]
\end{document}

Sorry for the miles-long MWE and for using raw lorem ipsum, I didn't want the paragraph breaks that lipsum inserts.

Ryan
  • 2,914

3 Answers3

6

Several things are going on that are not working for you. First, the new lengths that you're defining should be defined outside of the environment. Secondly, you cannot call \parbox{1.75in}{ in one part of the definition for your new environment and close it in the second part. It's best to use an lrbox for that purpose. Thirdly, wrapfigure needs to be called directly from within the new environment you're defining, not with begin{wrapfigure}. Also, you only really need one tikzpicture to accomplish what you want.

\documentclass[final,oneside,11pt]{memoir}
\usepackage{tikz}
\usetikzlibrary{calc,tikzmark}
\usepackage{calc}
\usepackage{wrapfig}
\usepackage{lipsum}
% \usepackage{showframe}

%% this is where you should define your new lengths
% \newlength{\topverticalspacer}
% \newlength{\verticalspacer}
% \newlength{\bottomspacer}

\newsavebox\myoffsetbox

\newenvironment{offset}
{%%
   \begin{lrbox}{\myoffsetbox}
     \begin{minipage}[t]{1.75in}
       \sffamily
       \noindent
       \hspace{-5pt}%%
}
{%%
     \end{minipage}
   \end{lrbox}%%
   \wrapfigure[19]{r}[1in]{2in}
      \raisebox{\dimexpr\ht\myoffsetbox+\tabcolsep}[0pt][0pt]{\tikzmark{aen1}}%%
      \hspace*{\tabcolsep}%%
      \usebox{\myoffsetbox}%%
      \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
        \draw[line width=1pt] 
            ($({pic cs:aen1})+(2in,0)$)    -- 
            (pic cs:aen1)                  -- 
            ++ (0,-\dimexpr\ht\myoffsetbox+\dp\myoffsetbox+2\tabcolsep) -- 
            ++ (1in,0);
      \end{tikzpicture}\\
    \endwrapfigure%%
}

\begin{document}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \begin{offset}
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
            tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
            quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
            consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
            cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
            proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \end{offset}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \lipsum[2-4]
\end{document}

enter image description here

By using an lrbox, you can measure the width, height, and depth of the offset paragraph to get a better fit for the framing.

UPDATE

Various environments don't play well inside a \newenvironment: this is usually because of how such environments scan ahead to look for their content by searching for their respective \end{<environment name>. That seems to be the case here with \begin{wrapfigure}.

By using the lrbox, I can measure the contents of the text to be offset. Initially, I use \tikzmark to create a mark on the page to reference the beginning of this offset material. I used \raisebox to raise this \tikzmark above the height of the top of the offset material according to its height (\ht\myoffsetbox) and the value of \tabcolsep. I don't want the \raisebox to add any visual white space to the page, so I pass it two optional arguments (I probably don't need both): the first optional argument says to assign the raised box a height of 0pt and the second optional argument says to assign the raised box a depth of 0pt.

The \tikzmark uses its own coordinate system. That means the names of the nodes created by writing \tikzmark{<node name>} are not directly accessible by their name. You need to reference them through the canvas name (coordinate system): pic cs:<node name>. I used the TikZ calc library (not necessary) to facilitate drawing the line across the top of the offset material. The parentheses in ({pic cs:aen1}) are not necessary and could be removed. They're residual from when I was more faithfully following your use of two nodes. I wanted to write (<node name 1>-|<node name 2>): to get the canvas parsed correctly, I needed to write ({pic cs:aen1}-|{pic cs:aen2}).

A.Ellett
  • 50,533
  • Thanks so much for the thorough answer, but could you explain a little more what you did with the tikzpicture? also, what is the difference with using \wrapfigure—should I be using it that way all the time? – Ryan Nov 17 '14 at 07:42
6

You are missing an awful lot of % at the ends of lines, and

        \parbox{1.75in}{\textsf{
        \hspace{-5pt}
}
{
        }}

Just always makes an empty parbox.

I don't think the tikz code is helping here really it is just complicating things if you just want to draw three lines.

enter image description here

\documentclass[final,oneside,11pt]{memoir}

\usepackage{wrapfig}
\usepackage{lipsum}
% \usepackage{showframe}

\newenvironment{offset}
{%
    \wrapfigure{r}[1in]{2in}%
    \kern-5pt
    \hrule
    \noindent\hbox\bgroup\vrule \kern9.6pt\minipage{\dimexpr2in-10pt\relax}%
    \kern5pt    
}
{%
\par
\kern5pt
\endminipage\egroup
\hrule width 1in
\endwrapfigure
}

\begin{document}
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \begin{offset}
            Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
            tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
            quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
            consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
            cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
            proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \end{offset}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \lipsum[2-4]
\end{document}
David Carlisle
  • 757,742
  • What do the comments at ends of lines do? I've never heard of a % being required. – Ryan Nov 18 '14 at 22:36
  • 1
    end of line is a space. see http://tex.stackexchange.com/questions/7453/what-is-the-use-of-percent-signs-at-the-end-of-lines – David Carlisle Nov 18 '14 at 22:41
  • Thank you! Coming from Python I've always felt like LaTeX is a little weird about how it handles whitespace. – Ryan Nov 18 '14 at 22:46
  • I used Tikz in my mwe because I'm trying to learn how to make this type of environment, not just how to make this one exactly, because I'm having a lot of trouble researching best practices when things go beyond the basics. Do you know of a definitive resource (besides yourself) that I could read on this topic? I only have 3,723 pages of LaTeX related manuals on my computer and apparently that isn't enough. – Ryan Nov 18 '14 at 22:53
  • @Ryan I know nothing about tikz:-) but clearly you could use the same cutout technique as here but replace the basic \hrule and \vrule by some fancier tikz border with curved corners or whatever. I leave as an exercise for the reader. Honestly you wouldn't believe how little I know about tikz:-0 – David Carlisle Nov 18 '14 at 23:08
  • @Ryan it is not latex that is weird about white space but it is users who are weird (and inconsistent in their expectations;-) in your MWE you have a linebreak between eiusmod and tempor I'm assuming that you expect that to make a word-space? You similarly have a line break between \hspace*{\tabcolsep} and \parbox and it similarly adds a word space so indenting the parbox by a (stretchy, variable width) word-space in addition to the \tabcolsep. that is just one space amongst many added in the original. – David Carlisle Nov 18 '14 at 23:12
  • I didn't mean about Tikz, I meant about LaTeX; I want to understand and use it as a programming language instead of just for basic markup. Variables, math, new commands, new environments—it's easy to find documentation on the packages (tikz is a star example of that) but I don't feel like I understand how things are built in LaTeX. On some projects like one to calculate and draw a camera on a drone I combined LaTeX and Python, but it gets to be a massive pain to write. Shouldn't it be possible to do all that in LaTeX? – Ryan Nov 19 '14 at 00:13
  • @Ryan hard to say where really (ive been using it for nearly 30 years, so can't say what is the best source of info now): you can read the source of latex texdoc source2e the texbook of course or texbytopic is a good free alternative. and if I can read that python it only needs trig and and arithmetic? so yes you could do it all in tex (using expl3 or pgfmath for example) – David Carlisle Nov 19 '14 at 00:18
  • always the line-break-to-indicate-\par that's bothered me the most, but I suppose it seems more consistent now that I know that end-of-line is also interpreted as a command. Of course, it's not like I have any better ideas, I see why it's designed this way! – Ryan Nov 19 '14 at 00:21
  • eol is not really a command it's just a character (same as a space, it makes a space (ascii 32 token) except for some magic in the scanner such that two eol tokenize as \par not a single space as two space characters do. – David Carlisle Nov 19 '14 at 00:26
  • Thanks! yep, just trig and arithmetic, I'll look into pgfmath because three of the letters are familiar and seem to stand for "pretty good (f?) documentation" maybe if I learn enough someday I'll publish "LaTeX as a language" to see if anyone benefits from that perspective. – Ryan Nov 19 '14 at 00:29
3

Another alternative is the use of newcommand which is similar to newenvironment.

For references: Link1 Link2

enter image description here

Code

\documentclass[final,oneside,11pt]{memoir}
\usepackage{tikz}
\usepackage{calc}
\usepackage{wrapfig}
\usepackage{lipsum}
% \usepackage{showframe}

\newcommand*{\offset}[1]
{
    \begin{wrapfigure}[19]{r}[1in]{2in}
        \noindent
        \newlength{\topverticalspacer}
        \setlength{\topverticalspacer}{-\baselineskip-\tabcolsep}
        \vspace*{\topverticalspacer}\\
        \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
            \coordinate (n1) at (0, 0);
            \draw[-,line width=1pt,inner sep=0pt,outer sep=0pt] (n1)--(2in, 0);
        \end{tikzpicture}\\
        \newlength{\verticalspacer}
        \setlength{\verticalspacer}{\tabcolsep-\baselineskip}
        \vspace*{\verticalspacer}\\
        \hspace*{\tabcolsep}
%}
%{
        \parbox{1.75in}{\textsf{
        \hspace{-5pt}
#1}}
        \newlength{\bottomspacer}
        \setlength{\bottomspacer}{\baselineskip-\tabcolsep}
        \vspace*{\bottomspacer}\\
        \begin{tikzpicture}[remember picture, overlay, inner sep=0pt,outer sep=0pt]
        \coordinate  (n2) at (0, 0);
        \draw[-,line width=1pt] (n2)--(1in, 0);
    \end{tikzpicture}
   \begin{tikzpicture}[remember picture, overlay, inner sep=0pt]
        \draw[-,line width=1pt] (n1) -- (n2);
    \end{tikzpicture}
    \end{wrapfigure}
}

\begin{document}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
\offset{%
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
      tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
      quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
      consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
      cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
      proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
}
    Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
    tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
    quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
    consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse
    cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
    proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
    \lipsum[2-4]
\end{document}
Jesse
  • 29,686