Primeira aproximação

Primeira aproximação

Gostaria de encontrar uma maneira de alinhar horizontalmente dois ou mais locais aleatórios do meu documento (mas provavelmente na mesma página ou não muito distantes um do outro). É um pouco como a segunda coluna de uma tabela, mas:

  1. as "linhas" podem ser separadas por qualquer quantidade. (O tabular pode ser dividido entre as linhas.)
  2. nem sempre os pontos a serem alinhados podem ser vistos como pertencentes a uma linha ou célula de uma tabela, pois podem aparecer no meio de um parágrafo normal sem que o restante do parágrafo seja afetado por esse alinhamento.

Como conseguir que todos os marcadores estejam alinhados nos exemplos a seguir (substituindo os sinais de menos por espaço em branco)?

(1) Esta frase está faltando X. ---------∙ O que está faltando nesta frase?

Alguns comentários/parágrafos intermediários.

(2) X está faltando um assunto. -------------∙ O que/Quem está faltando em um assunto?

Alguns comentários/parágrafos intermediários.

(3) Meus amigos convidaram X para a festa. ---∙ Quem meus amigos convidaram para a festa?

Alguns comentários/parágrafos intermediários.

(4) -------------------------------∙ Quem meus amigos convidaram?

E mesmo nos parágrafos seguintes (substituindo os pontos negativos por espaço em branco)?

Este parágrafo salta horizontalmente -------∙ em algum ponto por algum motivo. O resto do texto pode abranger outras linhas seguintes.

Este parágrafo deseja que seus saltos caiam ---∙ exatamente na mesma posição horizontal absoluta do salto do parágrafo acima (não perfeitamente executado aqui).

Como se comportar quando a posição é alcançada antes de saltar ∙ é indefinido, mas pode ser definido saltando para a próxima linha e alinhando-a.

O salto também pode acontecer na segunda linha do parágrafo, para que fique mais parecido com ------------------------------- ∙ este salto.

O que (eu acho) eu preciso é de um mecanismo para lembrar alguma posição horizontal (por exemplo, 30 pontos da margem esquerda) (algo como um rótulo que não lembre o último número produzido, nem a página em que está, mas a posição horizontal absoluta que tem -talvez um tikz node?), recupere-o posteriormente no documento e use-o para posicionar algo horizontalmente nesta posição absoluta (30 pontos da margem esquerda).

Uma situação específica em que preciso disso é com exemplos linguísticos construídos paralelamente, mas que aparecem em diferentes partes do documento (veja acima). Espacialmente, se eles estiverem na mesma página, seria uma boa semântica visual mostrar sua pertença por meio desse alinhamento. Pronto, o ponto 2 acima não se sustenta, então usei a lembrança de um preâmbulo tabular tabuno MWE no final.

Um problema com esta solução é que qualquer parte esquerda de um exemplo que seja mais longa do que a parte esquerda do primeiro exemplo é quebrada. Preciso adicionar manualmente alguns \hspaceno final da primeira célula. Mas é algo que me agrada, porque raramente preciso alinhar mais do que alguns exemplos.

  This sentence misses X. \hspace*{4em} & What does this sentence miss?\\

E o segundo problema é que usar tabular nem sempre é uma opção como mostrado no meu segundo caso acima. Veja o final do MWE para esse segundo problema, resolvido ajustando manualmente todos \hspaceos comandos:

\documentclass{article}
\usepackage{expex}
\usepackage{tabu}

\begin{document}

\ex \begin{tabu}[t]{X[-1]@{\hspace{1em}}X}\savetabu{mypreamble}
  This sentence misses X. & What does this sentence miss?\\
\end{tabu}
\xe

Comments in between.

\ex \begin{tabu}{\usetabu{mypreamble}}
  X misses a subject. & Who/what misses a subject?\\
\end{tabu}
\xe

Another comment.

\ex \begin{tabu}{\usetabu{mypreamble}}
  My friends invited X to the party. & Who did my Friends invite to the party?\\
\end{tabu}
\xe

This paragraph horizontally jumps \hspace*{3em} \textbullet\ at some 
point for some reason. The rest of the text can span other the next lines.

This paragraph wants its jumps to land \hspace*{.5em} \textbullet\ 
exactly at the same absolute horizontal position as the jump from the 
above paragraph (not quite perfectly executed here).

How to behave when the position is reached before jumping \textbullet\ is undefined.

The jump can also happen in the second line of the paragraph, so that it 
looks like \hspace*{16em} \textbullet\ this jump. 

\end{document}

Como posso resolver o caso dos exemplos de uma forma ainda mais automatizada?

Como posso conseguir isso dentro de parágrafos?

marcadores a serem alinhados por meio de exemplos e parágrafos

Responder1

O exemplo a seguir coloca a questão a \hboxà direita. A largura da caixa é medida previamente usando a pergunta mais longa:

\documentclass{article}
\usepackage[
  hmargin=1.5in,
]{geometry}
\usepackage{enumerate}

\newdimen\QuestionLength
\newcommand*{\QuestionFormat}[1]{\textbullet~#1}%
\settowidth{\QuestionLength}{%
  \QuestionFormat{Who did my friends invite to the party?}%
}
\newcommand*{\question}[1]{%
  \leavevmode
  \unskip
  \hspace*{1em plus 1fill}\hbox to \QuestionLength{%
    \QuestionFormat{#1}\hfill
  }%
  \par
}

\begin{document}
\begin{enumerate}[(1)]
\item
  This sentence is missing X.
  \question{What is this sentence missing?}

  Some comment/paragraph(s) in between.

\item
  X is missing a subject.
  \question{What/Who is missing a subject?}

  Some comment/paragraph(s) in between.

\item
  My friends invited X to the party.
  \question{Who did my friends invite to the party?}

  Some comment/paragraph(s) in between.

\item
  \question{Who did my friends invite?}
\end{enumerate}
\end{document}

Resultado

Versão com correções de espaço à esquerda

A largura do maior texto à esquerda é colocada em \LeftPartLength. Em seguida, a largura da questão é calculada usando a largura da linha atual menos o comprimento da parte esquerda e algum espaço de separação. Um erro será gerado se não houver espaço suficiente para a pergunta.

\documentclass{article}
\usepackage[
  hmargin=1.5in,
]{geometry}
\usepackage{enumerate}

\newcommand*{\QuestionFormat}[1]{\textbullet~#1}%
\newdimen\QuestionLength
\newdimen\LeftPartLength
\newdimen\MiddleSep
\setlength{\MiddleSep}{1em}
\settowidth{\QuestionLength}{%
  \QuestionFormat{Who did my friends invite to the party?}%
}
\settowidth{\LeftPartLength}{%
   Some comment/paragraph(s) in between.%
}

\newcommand*{\question}[1]{%
  \leavevmode
  \unskip
  \begingroup
    \dimen0=\dimexpr\linewidth - \LeftPartLength - \MiddleSep\relax
    \ifdim\dimen0<\QuestionLength
      \errmessage{Question is large by %
        \the\dimexpr\QuestionLength-\dimen0\relax.}%
    \fi
    \hspace*{\MiddleSep plus 1fill}%
    \hbox to \dimen0{%
      \QuestionFormat{#1}\hfill
    }%
  \endgroup
  \par
}

\begin{document}
\begin{enumerate}[(1)]
\item
  This sentence is missing X.
  \question{What is this sentence missing?}

  Some comment/paragraph(s) in between.

\item
  X is missing a subject.
  \question{What/Who is missing a subject?}

  Some comment/paragraph(s) in between.

\item
  My friends invited X to the party.
  \question{Who did my friends invite to the party?}

  Some comment/paragraph(s) in between.

\item
  \question{Who did my friends invite?}
\end{enumerate}
\end{document}

Resultado

Responder2

Graças à sugestão de touhami, encontrei soluções mais gerais usando zref-savepos. Consulte a documentação do pacote para algumas explicações. Uma dificuldade parece ser que as posições absolutas são difíceis de lidar, enquanto as posições relativas são aceitáveis. Demora até5 compilaçõespara acertar as coisas!

Aqui o código comentado:

\documentclass[a4paper,10pt,DIV13]{scrartcl}
\usepackage{expex}
\usepackage{tabu}
\usepackage{ifthen}
\usepackage{calc}
\usepackage{zref-user}
\usepackage{zref-savepos}

\begin{document}

% because the bullets where here only to explicit what I wanted to align
% I didn't include them in the macros

% first the more general solution for paragraphs

\newlength{\tab}% the length of the jumps
\newcommand{\banchor}[1]{\zsaveposx{#1}}% choose the reference point

\newcommand{\balign}[2]{% the 1st argument is the anchorname of the current jump
                        % the 2nd argument is the name of the general anchor chosen
                        % through \banchor
\rule{0pt}{0pt}% to avoid trouble at the beginning of lines
\zsaveposx{#1}\zrefused{#1}% set the reference point from where you want to jump
\setlength{\tab}{\zposx{#2}sp-\zposx{#1}sp}% calculate the length of the jump
\ifthenelse{\lengthtest{\tab<0pt}}% if it's a negative jump,
  {\\\rule{0pt}{0pt}\zsaveposx{#1improbablename}%
    % then begin a new line and set the reference at its beginning
    % with a new anchor name
  \setlength{\tab}{\zposx{#2}sp-\zposx{#1improbablename}sp}% recalculate the jump
  } %
  {}%
\parbox[l]{\tab}{\rule{0pt}{0pt}}% use a \parbox to jump a exact unstrechtable length
% \hspace*{\tab} doesn't work here, because it's strechtable
}

This paragraph horizontally jumps\hspace*{4em}\banchor{B}\textbullet\ at  some point
for some reason. The rest of the text can span other the next lines. 
% this jump is arbitrary, the next ones (previous ones would also work)
% will adapt and align with it

This paragraph wants its jump to land\balign{Ba}{B}\textbullet\ exactly at the same
absolute horizontal position as the jump from the above paragraph (quite perfectly
executed here).

\balign{Bb}{B}\textbullet\ jumping directly to the point is also an option.

How to behave when the position is reached before jumping\balign{Bc}{B}\textbullet\ could
be defined by jumping to the next line.

The jump can also happen The jump can also happen The jump can also happen in the second
line of the paragraph, so that it looks like
\balign{Be}{B}\textbullet\ this jump. 

\bigskip
\hrule

% now to the linguistic examples, following the same principles, 
% but a bit adapted for the more specific needs of the linguistic  examples:
% compile and detect where to put the aligning anchor with \bmark
% use \btab to align the other right parts with it

\newlength{\tabmin}\setlength{\tabmin}{1em}

\newcommand{\bmark}[1]{%
\zsaveposx{#1}\zrefused{#1}\hspace*{\tabmin}}

\newcommand{\btab}[2]{%
\zsaveposx{#1}\zrefused{#1}%
\setlength{\tab}{\tabmin+\zposx{#2}sp-\zposx{#1}sp}%
\hspace*{\tab}}% \hspace* is ok, because wrapped lines are unexpected

\ex This sentence misses X.\btab{Aa}{A}\textbullet\ What does this sentence  miss?
\xe

Comments/explanations/paragraphs in between.

\ex X misses a subject.\btab{Ab}{A}\textbullet\ Who/what misses a subject?
\xe

Another comment.

\ex My friends invited X to the party.\bmark{A}\textbullet\ Who
did my friends invite to the party?
\xe

Another comment.

\ex \btab{Ac}{A}\textbullet\ Who did my friends invite?
\xe

\end{document}

texto alinhado de parágrafos diferentes

Editar

Agora substituí \parbox[l]{\tab}{\rule{0pt}{0pt}}e \hspace*{\tab}por uma regra simples, que pode ajudar a visualizar o salto exato se definido com altura diferente de zero \rule{\tab}{0pt}.

Melhoria ainda pendente: minha abordagem exige que o usuário encontre tantos nomes diferentes quantos saltos forem necessários no documento. Talvez um contador pudesse automatizar essa parte do trabalho, para que os comandos \balignrecebessem \btabapenas um argumento.

Testar essas macros em outros locais (em tabelas, ou ao lidar com gráficos, etc.) pode mostrar algumas limitações sérias.

Por enquanto, esta solução é a minha favorita.

Responder3

Primeira aproximação

A \parboxsolução funciona apenas para textos muito curtos. Aqui está um programa mais elaborado:

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{lipsum}

\makeatletter

\def\do#1{\@ifdefinable #1{\newdimen #1}}
% the above is because \newlength allocates a \skip
\do\JumpIndentation
\do\JPprevpardepth

% To allow customization:
\@ifdefinable\EveryJumpingPar{
    \newtoks\EveryJumpingPar \EveryJumpingPar={}
}

\newcommand*\StartJumpingPar{\par
    \JPprevpardepth \prevdepth
    \setbox\z@ \vbox\bgroup
        \color@begingroup % not sure it's really necessary
        \parfillskip \@flushglue
        \prevdepth \JPprevpardepth
        \indent \the\EveryJumpingPar
}
\newcommand*\Jump{%
        \par
        \color@endgroup
    \egroup
    \setbox\tw@ \vbox{%
        \unvcopy\z@
        \setbox\tw@ \lastbox % note that "\indent\par" yields at least one box
        \global \setbox\@ne \hbox{\unhbox\tw@}%
        \global \dimen@i \lastskip % should be -- finger crossed! -- the 
                                  % interline glue above the last box
        \unskip \unpenalty % remove interline glue and widow penalty
        \setbox\tw@ \lastbox % if non-void, assume it is penultimate line
        \global \dimen3 \ifvoid\tw@
            \JPprevpardepth
        \else
            \dp\tw@
        \fi
    }%
    \unvbox\z@
    \ifdim \wd\@ne<\JumpIndentation
        % backspace vertically by one line
        \skip@ \parskip
        \advance \skip@ \ht\@ne
        \advance \skip@ \dp\@ne
        \advance \skip@ \dimen@i
        \vskip -\skip@
        \prevdepth \dimen3
    \else
        \prevdepth \dp\@ne
    \fi
    {\parindent \JumpIndentation \indent}%
    \ignorespaces
}

\makeatother

\setlength{\JumpIndentation}{.57\textwidth} % set as desired



\begin{document}

Let's begin with an ordinart paragraph.

\lipsum[1]

\StartJumpingPar
Now a ``jumping paragraph''.
\lipsum*[1]\Jump\lipsum*[2]

Another ordinary (\emph{i.e.}, ``non-jumping'') paragraph in between, consisting
of at least two lines of text.

\StartJumpingPar
Note that all ``jump'' positions\Jump are vertically aligned, as required.

\StartJumpingPar
If the horizontal position to jump to has already been passed,\Jump the
\verb|\Jump| commands jumps to the next line, as required too.

\StartJumpingPar
Let's try, this time, to get aaaaalmost to\Jump the point!  Now we try again, 
with just one more~``a''.

\StartJumpingPar
Let's try, this time, to get aaaaaalmost to\Jump the point!  Are you satisfied?

\EveryJumpingPar{\textbullet\ }

\StartJumpingPar
Moreover, you can use the token register \verb|\EveryJumpingPar| to customize 
the appearance of\Jump your ``jumping paragraphs''.

That's all, folks!

\end{document}

A saída produzida por este código é:

Saída da 1ª aproximação

Isto deve ser considerado como uma primeira aproximação à resposta: aguardarei os comentários do OP antes de introduzir possíveis melhorias.


Segunda aproximação

Desta vez definimos um ambiente chamado JumpingParagraphs. Este ambiente deve conterapenasparágrafos comuns e nada mais. Dentro de cada parágrafo abrangido por este ambiente, o \Jumpcomando pode ser usado para tabular até a posição horizontal especificada pelo \JumpIndentationcomprimento rígido. O \Jumpcomando pode ser usado um número ilimitado de vezes dentro do mesmo parágrafo.

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{lipsum}

\makeatletter

\def\do#1{\@ifdefinable #1{\newdimen #1}}
% the above is because \newlength allocates a \skip
\do\JumpIndentation
\do\@JP@normal@indent
\do\@JP@prevpardepth

% To allow customization:
\@ifdefinable\EveryJumpingPar{
    \newtoks\EveryJumpingPar \EveryJumpingPar={}
}

\@ifdefinable\@JP@saved@par{} % just check that the name can be used
\newenvironment*{JumpingParagraphs}{%
    \@JP@normal@indent \parindent
    \let\@JP@saved@par\par
    \def\par{\@JP@par@close\@JP@start@paragraph}%
    \@JP@start@paragraph
}{%
    \@JP@par@close
}
\newcommand*\@JP@start@paragraph{%
    \@JP@par@open\@JP@normal@indent{\the\EveryJumpingPar}%
}
\newcommand*\@JP@par@open[2]{%
    \@JP@prevpardepth \prevdepth
    \setbox\z@ \vbox\bgroup
        \color@begingroup % not sure it's really necessary
        \parfillskip \@flushglue
        \prevdepth \@JP@prevpardepth
        {\parindent #1\indent #2}%
        \ignorespaces
}
\newcommand*\@JP@par@close{%
        \@JP@saved@par
        \global \dimen@i \prevdepth
        \color@endgroup
    \egroup
    \unvcopy\z@
    \prevdepth \dimen@i % for the moment
}
\newcommand*\Jump{%
    \@JP@par@close
    \setbox\z@ \vbox{%
        \unvbox\z@
        \setbox\z@ \lastbox % note that "\indent\par" yields at least one box
        \global \setbox\@ne \hbox{\unhbox\z@}%
        \global \dimen@i \lastskip % should be -- finger crossed! -- the 
                                   % interline glue above the last box
        \unskip \unpenalty % remove interline glue and widow penalty
        \setbox\z@ \lastbox % if non-void, assume it is penultimate line
        \global \dimen3 \ifvoid\z@
            \@JP@prevpardepth
        \else
            \dp\z@
        \fi
    }%
    \ifdim \wd\@ne<\JumpIndentation
        % backspace vertically by one line
        \skip@ \parskip
        \advance \skip@ \ht\@ne
        \advance \skip@ \dp\@ne
        \advance \skip@ \dimen@i
        \vskip -\skip@
        \prevdepth \dimen3
        \dimen@ \ht\@ne
    \else
        \prevdepth \dp\@ne
        \dimen@ \z@
    \fi
    \@JP@par@open\JumpIndentation{\vrule \@width\z@ \@height\dimen@}%
}

\makeatother

\setlength{\JumpIndentation}{.57\textwidth} % set as desired



\begin{document}

Let's begin with an ordinary paragraph.

\lipsum[1]

\begin{JumpingParagraphs}
% No empty lines here!
Now a ``jumping paragraph''.
\lipsum*[1]\Jump\lipsum*[2]
\Jump Regrettably, \verb|Overfull \hbox|'es might occur: this is almost
inevitable, given the fact that a line containing a ``jump'' places a double
constraint on the choice of the breakpoints.

Another ordinary (\emph{i.e.}, ``non-jumping'') paragraph in between, consisting
of at least two lines of text.  Note that it occurs \emph{within} a 
\texttt{JumpingParagraphs} environment.

Note that all ``jump'' positions\Jump are vertically aligned, as required.

If the horizontal position to jump to has already been passed,\Jump the
\verb|\Jump| commands jumps to the next line, as required too.

Let's try, this time, to get aaaaalmost to\Jump the point!  Now we try again, 
with just one more~``a''.

Let's try, this time, to get aaaaaalmost to\Jump the point!  Are you satisfied?

Moreover, you can use the token register \verb|\EveryJumpingPar| to customize 
the appearance of\Jump your ``jumping paragraphs''.  However, it must be set 
\emph{outside} of the \texttt{JumpingParagraphs} environment.

The \verb|\Jump| command can also be used\Jump several times\Jump within a
single paragraph.  And in-line mathematics (say, \( y=\sin(x) \)) may\Jump
occur, too.  As it is quite obvious, you can both jump \emph{to} math\Jump\(
y=\frac{1}{x} \), and \emph{from} math (the last equation is better
written as \( y=1/x \),\Jump isn't it?).  It is also possible to use unusually
high formulas, as in \( \displaystyle
\biggl(\frac{1}{x}+\frac{1}{y}\biggr)\biggl(\frac{1}{x}-\frac{1}{y}\biggr) \),
and, even in case of a\Jump jump, the spacing will be correct!

But alas, \( \displaystyle \frac{x}{y}+\frac{y}{x}=\frac{x^{2}+y^{2}}{xy} \)
\Jump fails miserably: the spacing is correct for the second half of the line,
but not for the first.  You should keep in mind this limitation.  On the other
hand,\Jump \( \displaystyle \frac{x}{y}+\frac{y}{x}=\frac{x^{2}+y^{2}}{xy} \)
works in a more or less acceptable way, as you can see.

\textbf{Main limitation:} a \texttt{JumpingParagraphs} environment cannot
contain \emph{anything} but ordinary paragraphs.
% No empty lines here!
\end{JumpingParagraphs}

This paragraph is outside the \texttt{JumpingParagraphs} environment.  Note 
that line spacing is correct

\bigbreak

\EveryJumpingPar = {\textbullet\ }

We have just set \verb|\EveryJumpingPar| to contain \verb*|\textbullet\ |.  Now 
we start another \texttt{JumpingParagraphs} environment.

\begin{JumpingParagraphs}
    $X$~misses something.
    \Jump What is $X$ missing?

    This sentence misses~$X$.
    \Jump What is missing?

    This sentence $X$ something.
    \Jump What is missing?
\end{JumpingParagraphs}

That's all, folks!

\end{document}

Terceira (e quarta) aproximação

A segunda aproximação não tratou corretamente o caso de múltiplos \partokens aparecerem na entrada, pois isso poderia resultar de linhas extras em branco. A terceira aproximação corrige esta falha, recorrendo a \everyparpara acionar a \@JP@start@paragraphmacro, e também adiciona o \EveryJumpregistrador de token:

\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\usepackage{lipsum}
\usepackage{color}

\definecolor{subdued}{gray}{.75}

\makeatletter

\def\do#1{\@ifdefinable #1{\newdimen #1}}
% the above is because \newlength allocates a \skip
\do\JumpIndentation
\do\@JP@normal@indent
\do\@JP@prevpardepth

% To allow customization:
\def\do#1{\@ifdefinable #1{\newtoks #1#1{}}}
\do\EveryJumpingPar
\do\EveryJump

\@ifdefinable\@JP@saved@par{} % just check that the name can be used
\@ifdefinable\@JP@next{}
\newenvironment*{JumpingParagraphs}{%
    \everypar{\@JP@start@paragraph}%
}{%
    \par
}
\newcommand*\@JP@start@paragraph{%
    \@JP@normal@indent \parindent
    \let\@JP@saved@par\par
    \setbox\z@ \lastbox % get indentation box
    \@@par % return to vertical mode with an empty paragraph
    \ifvoid\z@
        \let \@JP@next \noindent
    \else
        \let \@JP@next \indent
    \fi
    \@JP@par@open\@JP@next\@JP@normal@indent{\the\EveryJumpingPar}%
}
\newcommand*\@JP@par@open[3]{%
    % #1 <- either "\indent" or "\noindent"
    % #2 <- indentation amount
    % #3 <- tokens to insert at the beginning of the paragraph
    \@JP@prevpardepth \prevdepth
    \setbox\z@ \vbox\bgroup
        \color@begingroup % not sure it's really necessary
        \parfillskip \@flushglue
        \everypar{}%
        \let\par\@JP@par@close
        \prevdepth \@JP@prevpardepth
        {\parindent #2#1#3}%
        \ignorespaces
}
\newcommand*\@JP@par@close{%
        \@JP@saved@par
        \global \dimen@i \prevdepth
        \color@endgroup
    \egroup
    \unvcopy\z@
    \prevdepth \dimen@i % for the moment
}
\newcommand*\Jump{%
    \@JP@par@close
    \setbox\z@ \vbox{%
        \unvbox\z@
        \setbox\z@ \lastbox % note that "\indent\par" yields at least one box
        \global \setbox\@ne \hbox{\unhbox\z@}%
        \global \skip\@ne \lastskip % should be -- finger crossed! -- the 
                                    % interline glue above the last box
        \unskip \unpenalty % remove interline glue and widow penalty
        \setbox\z@ \lastbox % if non-void, assume it is penultimate line
        \global \dimen@i \ifvoid\z@
            \@JP@prevpardepth
        \else
            \dp\z@
        \fi
    }%
    \ifdim \wd\@ne<\JumpIndentation
        % backspace vertically by one line
        % Note: no "\parskip" glue is added in internal vertical mode when the
        %       current list is empty, so we don't need to compensate for it!
        \skip@ \skip\@ne
        \advance \skip@ \ht\@ne
        \advance \skip@ \dp\@ne
        \vskip -\skip@
        \prevdepth \dimen@i
        \dimen@   \ht\@ne
        \dimen@ii \dp\@ne
    \else
        \prevdepth \dp\@ne
        \dimen@   \z@
        \dimen@ii \z@
    \fi
    \@JP@par@open\indent\JumpIndentation{%
        % It was trivial to fix this one!
        \vrule \@width\z@ \@height\dimen@ \@depth\dimen@ii \relax
        % Now "\relax" is no longer necessary, actually.
        \the\EveryJump
    }%
}

\makeatother

\setlength{\JumpIndentation}{.57\textwidth} % set as desired



\begin{document}

Let's begin with an ordinary paragraph.

\lipsum[1]

\begin{JumpingParagraphs}

% Empty lines are now allowed here.

Now a ``jumping paragraph''.
\lipsum*[1]\Jump\lipsum*[2]
\Jump Regrettably,\hfil\verb|Overfull \hbox|'es might occur: this is almost
inevitable, given the fact that a line containing a ``jump'' places a double
constraint on the choice of the breakpoints.

% Multiple blank lines in the input are now handled correctly:


Another ordinary (\emph{i.e.}, ``non-jumping'') paragraph in between, consisting
of at least two lines of text.  Note that it occurs \emph{within} a 
\texttt{JumpingParagraphs} environment.

Note that all ``jump'' positions\Jump are vertically aligned, as required.

If the horizontal position to jump to has already been passed,\Jump the
\verb|\Jump| commands jumps to the next line, as required too.

Let's try, this time, to get aaaaalmost to\Jump the point!  Now we try again, 
with just one more~``a''.

Let's try, this time, to get aaaaaalmost to\Jump the point!  Are you satisfied?

\EveryJumpingPar = {\textbullet\ }

Moreover, you can use the token register \verb|\EveryJumpingPar| to customize 
the appearance of\Jump your ``jumping paragraphs''.

\EveryJump = {\textasteriskcentered\ }

In the same way, the \verb|\EveryJump| tokens\Jump are inserted each time a
\verb|\Jump| command\Jump is executed, as it is exemplified by this same\Jump
paragraph.

These token registers can now also be set inside the \texttt{JumpingParagraphs}
environment itself.

\EveryJumpingPar = {}
\EveryJump = {}

The \verb|\Jump| command can also be used\Jump several times\Jump within a
single paragraph.  And in-line mathematics (say, \( y=\sin(x) \)) may\Jump
occur, too.  As it is quite obvious, you can both jump \emph{to} math\Jump\(
y=\frac{1}{x} \), and \emph{from} math (the last equation is better
written as \( y=1/x \),\Jump isn't it?).  It is also possible to use unusually
high formulas, as in \( \displaystyle
\biggl(\frac{1}{x}+\frac{1}{y}\biggr)\biggl(\frac{1}{x}-\frac{1}{y}\biggr) \),
and, even in case of a\Jump jump, the spacing will be correct!

And now, also \( \displaystyle \frac{x}{y}+\frac{y}{x}=\frac{x^{2}+y^{2}}{xy} \)
\rlap{\color{subdued}sminnief}\Jump functions with absolute perfection: line
spacing is correct both for the first half of the line and for the second one.
On the other hand,\Jump \( \displaystyle
\frac{x}{y}+\frac{y}{x}=\frac{x^{2}+y^{2}}{xy} \) works in a less satisfactory
way, as you can see.  You should keep in mind this limitation.

\textbf{Main limitation:} a \texttt{JumpingParagraphs} environment cannot
contain \emph{anything} but ordinary paragraphs.

\noindent Note that \verb|\noindent| commands\Jump \emph{are} honored: indeed,
this has now been corrected (in an update).

\begingroup

\setlength{\parindent}{4em}

Also, \verb|\parindent| may now vary\Jump from one paragraph\Jump to another:
I~had completely overlooked this in the previous versions!

Another paragraph with the same\Jump different indentation.

\endgroup

Back to previous indentation,\Jump with a jump.

One last paragraph without jumps.

% Empty lines are now allowed here.

\end{JumpingParagraphs}

This paragraph is outside the \texttt{JumpingParagraphs} environment.  Note 
that line spacing is correct.

\bigbreak

\newcounter{sentence}
\renewcommand*{\thesentence}{{\normalfont (\textit{\alph{sentence}})}}
\EveryJumpingPar = {\refstepcounter{sentence}\llap{\thesentence\ }}
\EveryJump = {\textbullet\ }

We have just set \verb|\EveryJumpingPar| to contain a numbered label, which is
automatically stepped, and \verb|\EveryJump| to contain \verb*|\textbullet\ |.
Now we start another \texttt{JumpingParagraphs} environment.

\begin{JumpingParagraphs}
    \setlength{\parskip}{\medskipamount}

    $X$~misses something.
    \Jump What is $X$ missing?

    This sentence misses~$X$.
    \Jump What is missing?

    This sentence $X$ something.
    \Jump What is missing?

    Now, get close to the jump destination...
    \Jump to be sure that the baselines are lined up properly.
\end{JumpingParagraphs}

That's all, folks!

\end{document}

Desta vez também mostrarei a saída:

Saída da 3ª/4ª aproximação

A solução empregada zref-saveposé de fato mais flexível que esta; no entanto, acho que pode ser de algum interesse mostrar como o objetivo pode ser alcançado inteiramente com os bons e velhos métodos do “estilo Plain-TeX”: sem dependência de \pdfsaveposprimitivos relacionados operando em \shipout-time, sem necessidade de dois -passar a compilação, apenas brincando com caixas e cola.


Devo admitir claramente que esta questãotemme pegou! Estou refinando repetidamente minha resposta e provavelmente acabarei postando um pacote completo…

Responder4

Para o caso de parágrafos, encontrei uma solução usando a \parboxpara pular seu texto. Não sei dizer se \hboxseria uma ideia melhor. Isso resolve os casos em que o salto acontece na primeira linha de um parágrafo.

\newlength{\jumplength}
\setlength{\jumplength}{20em} % adjust manually
\newcommand{\jumping}[1]{\parbox[l]{\jumplength}{#1}}

\jumping{This paragraph horizontally jumps}\textbullet\ at some point
for some reason. The rest of the text can span other the next lines.

\jumping{This paragraph wants its jump to land}\textbullet\ exactly at  
the same absolute horizontal position as the jump from the above paragraph.

\jumping{~}\textbullet\ jumping directly to the point is also an option.

alinhamento de pontos em parágrafos diferentes

E por uma questão de exatidão, a segunda resposta de Heiko deveria ser

\settowidth{\LeftPartLength}{%
My friends invited X to the party.%
}

para corresponder exatamente às minhas necessidades, o que dá um resultado ligeiramente diferente:

insira a descrição da imagem aqui

informação relacionada