14

I've been considering a more radical solution to the problem k.t.hagen posed a while back. Would it be possible (perhaps by catcode hijacking) to put hooks on individual lines of the source code? (more specifically, within the document environment)

Here is a MWE:

\documentclass{memoir}
\usepackage{libertine}      % want this font
\usepackage{xcolor}         % for color
\usepackage{xspace}

\newcounter{srcline}
\newcommand{\linemark}{%
    \stepcounter{srcline}%
    \textcolor{red}{\textsc{Line}~\arabic{srcline}}%
    \xspace}

\begin{document}
    Lorem ipsum dolor sit amet, consectetur adipiscing
    elit. Quisque porttitor ullamcorper velit, eu
    viverra augue varius in. Integer vehicula lacus
    vitae nunc blandit, sit amet auctor ex volutpat.
    Fusce ultrices elementum est, vel consectetur
    nulla elementum vel. Praesent in elit eu odio
    elementum luctus vel vitae leo. Sed vitae gravida
    nunc. Sed id posuere ligula. Donec a odio
    tincidunt, placerat nisl eget, egestas enim.
    Vivamus eget massa in quam fermentum cursus. In
    dictum, odio in laoreet fringilla, diam purus
    suscipit lorem, sit amet tempus ex lectus eget
    enim. Suspendisse potenti.
\end{document}

I hope to create something like this:

ideal

Where \linemark is called once per source line. Is there a way to accomplish this using LaTeX2e alone?


Edit 0

Try not to gobble paragraph breaks, MWE:

\documentclass{memoir}
\usepackage{libertine}      % want this font
\usepackage{xcolor}         % for color
\usepackage{xspace}

\newcounter{srcline}
\newcommand{\linemark}{%
    \stepcounter{srcline}%
    \textcolor{red}{\textsc{Line}~\arabic{srcline}}%
    \xspace}

\begin{document}
    \catcode`\^^M\active%
    \let\oldLF\^^M%
    \def
    {\oldLF\linemark}
    Lorem ipsum dolor sit amet, consectetur adipiscing
    elit. Quisque porttitor ullamcorper velit, eu
    viverra augue varius in. Integer vehicula lacus
    vitae nunc blandit, sit amet auctor ex volutpat.
    Fusce ultrices elementum est, vel consectetur
    nulla elementum vel. Praesent in elit eu odio
    elementum luctus vel vitae leo. Sed vitae gravida
    nunc. Sed id posuere ligula. Donec a odio
    tincidunt, placerat nisl eget, egestas enim.
    Vivamus eget massa in quam fermentum cursus. In
    dictum, odio in laoreet fringilla, diam purus
    suscipit lorem, sit amet tempus ex lectus eget
    enim. Suspendisse potenti.

    % my solution does gobble the paragraph break above.
    % add \par after this comment to see how I want it
    Lorem ipsum dolor sit amet, consectetur adipiscing
    elit. Quisque porttitor ullamcorper velit, eu
    viverra augue varius in. Integer vehicula lacus
    vitae nunc blandit, sit amet auctor ex volutpat.
    Fusce ultrices elementum est, vel consectetur
    nulla elementum vel. Praesent in elit eu odio
    elementum luctus vel vitae leo. Sed vitae gravida
    nunc. Sed id posuere ligula. Donec a odio
    tincidunt, placerat nisl eget, egestas enim.
    Vivamus eget massa in quam fermentum cursus. In
    dictum, odio in laoreet fringilla, diam purus
    suscipit lorem, sit amet tempus ex lectus eget
    enim. Suspendisse potenti.
\end{document}
  • 1
    With other words: The original typed lines should be prepended with some hook and afterwards wrapped/broken etc. – user31729 Jun 22 '15 at 18:17
15

Now that you added a new answer with all your requirements, I created an expl3 solution. This comes with an extra feature, that counts all lines (so if you leave two blank lines, then Line 6 Line 7 Line 8 are added).

\documentclass{scrartcl}
\usepackage{xparse,xcolor}

\newcounter{srcline}

\ExplSyntaxOn
\NewDocumentEnvironment{scrlines} { }
 { \endgraf \char_set_active_eq:NN \^^M \kuang_active_lf: }
 { \endgraf }
\tl_clear_new:N \l_kuang_cumulativelines_tl
\tl_new:N \l_kuang_linemark_tl
\tl_set:Nn \l_kuang_linemark_tl
 {
  \stepcounter{srcline}
  \textcolor{red}{\textsc{Line\nobreakspace\thesrcline}}
 }
\cs_new_protected_nopar:Npn \kuang_active_lf:
 {
  \kuang_peek_active_lf:TF
   {
    \par
    \tl_put_right:Nn \l_kuang_cumulativelines_tl { ~ \l_kuang_linemark_tl }
    \kuang_active_lf:
   }
   {
    \tl_use:N \l_kuang_cumulativelines_tl
    \tl_clear:N \l_kuang_cumulativelines_tl
    \c_space_tl
    \tl_use:N \l_kuang_linemark_tl
    \c_space_tl
   }
 }
\group_begin:
 \char_set_catcode_active:N \^^M %
 \cs_new_protected_nopar:Npn \kuang_peek_active_lf:TF %
  { \peek_meaning_remove:NTF ^^M } %
\group_end:

\ExplSyntaxOff

\begin{document}
\begin{scrlines}
  Lorem ipsum dolor sit amet, consectetur adipiscing
  elit. Quisque porttitor ullamcorper velit, eu
  viverra augue varius in. Integer vehicula lacus
  vitae nunc blandit, sit amet auctor ex volutpat.
  Fusce ultrices elementum est, vel consectetur
  nulla elementum vel. Praesent in elit eu odio


  elementum luctus vel vitae leo. Sed vitae gravida
  nunc. Sed id posuere ligula. Donec a odio
  tincidunt, placerat nisl eget, egestas enim.
  Vivamus eget massa in quam fermentum cursus. In
  dictum, odio in laoreet fringilla, diam purus
  suscipit lorem, sit amet tempus ex lectus eget
  enim. Suspendisse potenti.%
\end{scrlines}
\end{document}

enter image description here


Original solution

Since you have \obeylines you can make use of it.

\documentclass{memoir}
\usepackage{xcolor}

\newcounter{srcline}
\newcommand{\linemark}{\stepcounter{srcline}%
    \textcolor{red}{\textsc{Line~\thesrcline}}}

% Playing with the gobbling of \par
\makeatletter
{\obeylines\gdef\scrlinepar{\@ifnextchar{^^M}{\endgraf\expandafter\scrlinepar\@gobble}{ \linemark\ }}}
\makeatother

\newenvironment{scrlines}
  {\endgraf\let\par\scrlinepar\obeylines}
  {\endgraf}

\begin{document}
  \begin{scrlines}
    Lorem ipsum dolor sit amet, consectetur adipiscing
    elit. Quisque porttitor ullamcorper velit, eu
    viverra augue varius in. Integer vehicula lacus
    vitae nunc blandit, sit amet auctor ex volutpat.
    Fusce ultrices elementum est, vel consectetur
    nulla elementum vel. Praesent in elit eu odio

    elementum luctus vel vitae leo. Sed vitae gravida
    nunc. Sed id posuere ligula. Donec a odio
    tincidunt, placerat nisl eget, egestas enim.
    Vivamus eget massa in quam fermentum cursus. In
    dictum, odio in laoreet fringilla, diam purus
    suscipit lorem, sit amet tempus ex lectus eget
    enim. Suspendisse potenti.%
  \end{scrlines}
\end{document}

enter image description here

|improve this answer|||||
9

I'm not sure how robust this solution is, but I simply redefine the catcode for the newline character to make it active, then append the new command to it.

\documentclass{memoir}
\usepackage{libertine}      % want this font
\usepackage{xcolor}         % for color
\usepackage{xspace}

\newcounter{srcline}
\newcommand{\linemark}{%
    \stepcounter{srcline}%
    \textcolor{red}{\textsc{Line}~\arabic{srcline}}%
    \xspace}

\begin{document}
    \catcode`\^^M\active%
    \let\oldLF\^^M%
    \def
    {\oldLF\linemark}
    Lorem ipsum dolor sit amet, consectetur adipiscing
    elit. Quisque porttitor ullamcorper velit, eu
    viverra augue varius in. Integer vehicula lacus
    vitae nunc blandit, sit amet auctor ex volutpat.
    Fusce ultrices elementum est, vel consectetur
    nulla elementum vel. Praesent in elit eu odio
    elementum luctus vel vitae leo. Sed vitae gravida
    nunc. Sed id posuere ligula. Donec a odio
    tincidunt, placerat nisl eget, egestas enim.
    Vivamus eget massa in quam fermentum cursus. In
    dictum, odio in laoreet fringilla, diam purus
    suscipit lorem, sit amet tempus ex lectus eget
    enim. Suspendisse potenti.
\end{document}

result

|improve this answer|||||
  • I feel like there's a way to use ^ notation to make this a bit more readable. Maybe ^^J or ^^M? – Sean Allred Jun 22 '15 at 19:15
  • @SeanAllred, I have made that correction. – Simon Kuang Jun 22 '15 at 19:24
6

A slight modification of Manuel's answer to track lines even across paragraph breaks.

\documentclass{memoir}
\usepackage{xcolor}

\newcounter{srcline}
\newcommand{\linemark}{\stepcounter{srcline}%
    \textcolor{red}{\textsc{Line~\thesrcline}}}

% Playing with the gobbling of \par
\makeatletter
{\obeylines\gdef\srclinepar{\@ifnextchar{^^M}{\endgraf\linemark\expandafter\srclinepar\@gobble}{ \linemark\ }}}
\makeatother

\newenvironment{srclines}
{\endgraf\let\par\srclinepar\obeylines}
{\endgraf}

\begin{document}
    \begin{srclines}
        Lorem ipsum dolor sit amet, consectetur adipiscing
        elit. Quisque porttitor ullamcorper velit, eu
        viverra augue varius in. Integer vehicula lacus
        vitae nunc blandit, sit amet auctor ex volutpat.
        Fusce ultrices elementum est, vel consectetur
        nulla elementum vel. Praesent in elit eu odio

        elementum luctus vel vitae leo. Sed vitae gravida
        nunc. Sed id posuere ligula. Donec a odio
        tincidunt, placerat nisl eget, egestas enim.
        Vivamus eget massa in quam fermentum cursus. In
        dictum, odio in laoreet fringilla, diam purus
        suscipit lorem, sit amet tempus ex lectus eget
        enim. Suspendisse potenti.%
    \end{srclines}
\end{document}
|improve this answer|||||

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.