Primera aproximación

Primera aproximación

Me gustaría encontrar una manera de alinear horizontalmente dos o más lugares aleatorios de mi documento (pero probablemente en la misma página o no muy lejos uno del otro). Es un poco como la segunda columna de una tabla, pero:

  1. las "filas" se pueden separar por cualquier cantidad de lo que sea. (La tabla se puede dividir entre filas).
  2. Los puntos a alinear no siempre pueden verse como pertenecientes a una fila o celda de un tabular, porque pueden aparecer en medio de un párrafo normal sin que el resto del párrafo se vea afectado por esta alineación.

¿Cómo lograr que todas las viñetas estén alineadas en los siguientes ejemplos (reemplazando los menos con espacios en blanco)?

(1) A esta oración le falta X. ---------∙ ¿Qué le falta a esta oración?

Algunos comentarios/párrafos intermedios.

(2) A X le falta un tema. -------------∙ ¿Qué/quién falta en una materia?

Algunos comentarios/párrafos intermedios.

(3) Mis amigos invitaron a X a la fiesta. ---∙ ¿A quién invitaron mis amigos a la fiesta?

Algunos comentarios/párrafos intermedios.

(4) -------------------------------∙ ¿A quién invitaron mis amigos?

¿Y lo mismo en los siguientes párrafos (reemplazando los menos con espacios en blanco)?

Este párrafo salta horizontalmente-------∙ en algún momento por alguna razón. El resto del texto puede abarcar las siguientes líneas.

Este párrafo quiere que sus saltos aterricen ---∙ exactamente en la misma posición horizontal absoluta que el salto del párrafo anterior (no ejecutado del todo perfectamente aquí).

Cómo comportarse cuando se alcanza la posición antes de saltar ∙ no está definido, pero podría definirse saltando a la siguiente línea y alineándose allí.

El salto también puede ocurrir en la segunda línea del párrafo, para que se parezca más a ------------------------------- ∙ este salto.

Lo que (creo) necesito es un mecanismo para recordar alguna posición horizontal (por ejemplo, 30 puntos desde el margen izquierdo) (algo así como una etiqueta que no recuerda ni el último número producido ni la página en la que se encuentra, sino la posición horizontal absoluta que tiene). -¿tal vez un tikz node?), luego recupérelo más adelante en el documento y úselo para colocar algo horizontalmente en esta posición absoluta (30 puntos desde el margen izquierdo).

Una situación específica en la que necesito esto es con ejemplos lingüísticos que se crean en paralelo pero que aparecen en diferentes partes del documento (ver arriba). Especialmente si están en la misma página, sería una buena semántica visual mostrar su pertenencia a través de esta alineación. Allí, el punto 2 anterior no se cumple, por lo que solía recordar un preámbulo tabular tabuen el MWE al final.

Un problema con esta solución es que cualquier parte izquierda de un ejemplo que sea más larga que la parte izquierda del primer ejemplo se rompe. Necesito agregar algunos manualmente \hspaceal final de la primera celda. Pero es algo con lo que estoy de acuerdo, porque rara vez tengo que alinear más que unos pocos ejemplos.

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

Y el segundo problema es que usar una tabla no siempre es una opción como se muestra en mi segundo caso anterior. Vea el final del MWE para ese segundo problema, resuelto ajustando manualmente todos \hspacelos 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}

¿Cómo puedo lograr el caso de los ejemplos de una manera aún más automatizada?

¿Cómo puedo lograr esto dentro de los párrafos?

viñetas para alinear a través de ejemplos y párrafos

Respuesta1

El siguiente ejemplo coloca la pregunta en a \hboxa la derecha. El ancho de la caja se mide previamente mediante la pregunta más larga:

\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

Versión con espacio fijo a la izquierda.

Se coloca el ancho del texto más grande a la izquierda \LeftPartLength. Luego, el ancho de la pregunta se calcula utilizando el ancho de línea actual menos la longitud de la parte izquierda y algo de espacio de separación. Se genera un error si no hay suficiente espacio para la pregunta.

\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

Respuesta2

Gracias a la sugerencia de Touhami, encontré soluciones más generales usando zref-savepos. Consulte la documentación del paquete para obtener algunas explicaciones. Una dificultad parece ser que las posiciones absolutas son difíciles de manejar, mientras que las posiciones relativas están bien. Se necesita hasta5 compilacionespara hacer las cosas bien!

Aquí el 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 alineado de diferentes párrafos

Editar

Ahora he reemplazado \parbox[l]{\tab}{\rule{0pt}{0pt}}y \hspace*{\tab}con una regla simple, que puede ayudar a visualizar el salto exacto si se configura con una altura distinta de cero \rule{\tab}{0pt}.

Mejora aún pendiente: mi enfoque necesita que el usuario encuentre tantos nombres diferentes como saltos sean necesarios en el documento. Tal vez un contador podría automatizar esta parte del trabajo, de modo que los comandos \balignsolo \btabtomen un argumento.

Probar estas macros en otros lugares (en tablas, o cuando se trata de gráficos, etc.) puede mostrar algunas limitaciones graves.

Por ahora, esta solución es mi favorita.

Respuesta3

Primera aproximación

La \parboxsolución sólo funciona para textos muy cortos. Aquí tenéis un programa más 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}

El resultado producido por este código es:

Salida de la primera aproximación

Esto debe considerarse como una primera aproximación a la respuesta: esperaré los comentarios del OP antes de introducir posibles mejoras.


Segunda aproximación

Esta vez definimos un entorno llamado JumpingParagraphs. Este entorno debe contenersolopárrafos ordinarios, y nada más. Dentro de cada párrafo abarcado por este entorno, el \Jumpcomando se puede utilizar para tabular en la posición horizontal especificada por la \JumpIndentationlongitud rígida. El \Jumpcomando se puede utilizar un número ilimitado de veces dentro del mismo párrafo.

\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}

Tercera (y cuarta) aproximación

La segunda aproximación no manejó correctamente el caso de que \paraparecieran múltiples tokens en la entrada, ya que podría resultar de líneas en blanco adicionales. La tercera aproximación corrige este defecto, recurriendo a \everyparpara activar la \@JP@start@paragraphmacro, y también añade el \EveryJumpregistro 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}

Esta vez también mostraré el resultado:

Salida de tercera/cuarta aproximación

La solución que emplea zref-saveposes efectivamente más flexible que ésta; sin embargo, creo que podría ser de algún interés mostrar cómo se puede lograr el objetivo completamente con buenos métodos de “estilo TeX simple”: sin dependencia de las \pdfsaveposprimitivas relacionadas que operan en \shipout-time, sin necesidad de dos -Pase la recopilación, simplemente jugando con cajas y pegamento.


Debo admitirlo claramente, esta preguntatiene¡me atrapó! Estoy refinando mi respuesta repetidamente y probablemente terminaré publicando un paquete completo...

Respuesta4

Para el caso de los párrafos, encontré una solución usando a \parboxpara saltar sobre su texto. No puedo decir si \hboxsería una mejor idea. Esto resuelve los casos en los que el salto ocurre en la primera línea de un párrafo.

\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.

alineación de puntos en diferentes párrafos

Y en aras de la exactitud, la segunda respuesta de Heiko debería decir

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

para corresponder exactamente a mis necesidades, lo que da un resultado ligeramente diferente:

ingrese la descripción de la imagen aquí

información relacionada