0

Is there an existing tool that will add/update a comment in my .tex files with the automatic paragraph number that was assigned to that paragraph?

I am using pdflatex on Cygwin (TeX Live 2016), with a custom class based on memoir, and parano.sty (tweaked) for paragraph numbering. The core of the numbering code is:

\renewcommand\theparano{\textbf{[\padzeroes[4]{\decimal{parano}}]}}

\everypar{\parindent0pt\refstepcounter{parano}%
\hbox to \paranoboxwidth{\theparano\hfill}}}

I get a generated PDF with paragraph numbers with no issues. For my use case, I sometimes need to refer to paragraphs by number. I would prefer to be able to look up the numbers in the source, but, of course, the numbers aren't there. Is there a tool that will insert them? E.g., so I could run

pdflatex foo
whatever-tool foo

and whatever-tool would edit foo.tex to add

% #42

(or whatever number) before each paragraph.

I know I can save the paragraph numbers to an aux file together with the input line numbers, and then roll my own perl or gawk whatever-tool. However, I am wondering if there is anything that already does this.

My apologies if this has already been answered and I missed it in my searching! The closest I could find were invertible documents and the TeX-PDF review workflow, neither of which is what I am looking for. Also, let me know if you need more of the source.

1 Answer 1

1

Well, for anyone who may be interested, I rolled my own using the perl script below, annotate-parano.pl.

In my particular case, I got the list of paragraph/line numbers from a modified parano.sty that uses newfile. The relevant portion is:

\everypar{\addtostream{@parano}{\arabic{parano} \parano@sourceline}}

where \parano@sourceline is modified from this answer:

\ifnum\inputlineno=\m@ne
\let\parano@sourceline\@empty
\else
\def\parano@sourceline{\the\inputlineno}
\fi

I have read that modifying \everypar can be dicey in LaTeX, but it's working OK in my use case.

In my document class, I use

\RequirePackage[map]{parano}

followed, later on, by \parano.

Source follows.

Source of annotate-parano.pl

#!/usr/bin/perl -s
# annotate-parano.pl: Copyright (c) 2017 cxw.  CC-BY 4.0.
# Usage: annotate-parano.pl -m=linemap.txt <file(s)>
# Produces output on stdin.  Line numbers are continuous over any files listed.
# linemap.txt should have one line per marker to be added, with two fields:
# paragraph number and line number.
use v5.10;

# Load the deltas from the given marker file
my @deltas;
my @markers;
my $prevline = 1;   # last line number at which a marker was added

open(my $marker_fd, $m) || die "Can't open marker file $m";
while(<$marker_fd>) {
    my ($parano, $lineno)=split;
    push @deltas, $lineno-$prevline;
    $prevline = $lineno;
    push @markers, "%\@$parano";     # or whatever marker format you want
} #foreach marker

# Mark the provided input
my $lastmarkedline = 1;     # anchor for the deltas.  1 is like $prevline.
my $marker_idx = 0;

while(<>) {
    if( ($marker_idx <= $#deltas) &&
        ( ($.-$lastmarkedline) == $deltas[$marker_idx] ) ) {    # time to mark
        say $markers[$marker_idx];
        $lastmarkedline=$.;
        ++$marker_idx;
    }
    print;
} #foreach input line

Source of parano.sty

% parano.sty, modified by cxw.
% Changes Copyright (c) 2013--2017 cxw.
%%
%% The original source files were:
%% parano.dtx  (with options: `package')
%%
%% File: parano.dtx Copyright (c) 2003, CV Radhakrishnan
%%       River Valley Technologies, Trivandrum, India
%%       <[email protected]>
%%
%% This package may be distributed under the terms of the LaTeX Project
%% Public License, as described in lppl.txt in the base LaTeX distribution.
%% either version 1.0 or, at your option, any later version.
%%
%% $Id: parano.sty,v 1.3 2003/06/14 19:20:42 cvr Exp cvr $
%%
%%
%% Usage of the commands provided:
%%
%% \parano           ==> starts para numbering
%% \parano[<number>] ==> starts the next para with number <number>
%% \endparano        ==> stops para numbering
%% \prepara          ==> redefine to add material that needs to appear
%%                       before the para number. default is null
%% \postpara         ==> redefine to append material to para number.
%%                       default is null
%% \paranoboxwidth   ==> width of paranumber box, default 2em
%%
%%
\NeedsTeXFormat{LaTeX2e}
\def\Fileversion$#1: #2 ${\gdef\fileversion{#2}}
\def\Filedate$#1: #2 #3 ${\gdef\filedate{#2}}
\Fileversion$Revision: 1.3-cw $
\Filedate$Date: 2015/06/08 00:00:00 $
\ProvidesPackage{parano}
   [\filedate\space\fileversion\space Paranumber support (CVR) (CW)]
\PackageWarningNoLine{parano}
   {****************************************\MessageBreak
    Package parano v,\fileversion\space loaded\MessageBreak
    ****************************************}

% Get the current source line number.  Modified from
% https://tex.stackexchange.com/a/81794/38377 by
% https://tex.stackexchange.com/users/3954/gonzalo-medina
\ifnum\inputlineno=\m@ne
\let\parano@sourceline\@empty
\else
\def\parano@sourceline{\the\inputlineno}
\fi

% Map file: if the "map" option is provided, print the line numbers and
% para numbers to a map file
\newif\if@parano@makemapfile\@parano@makemapfilefalse
\def\parano@saveline{}
\DeclareOption{map}{
  \@parano@makemapfiletrue
}
\ProcessOptions\relax

\if@parano@makemapfile
  \RequirePackage{newfile}
  % Make the map file.  Thanks to https://tex.stackexchange.com/a/10922/38377
  % by https://tex.stackexchange.com/users/2674/leo-liu
  \typeout{Logging paragraph numbers and line numbers to \jobname.paramap}
  \newoutputstream{@parano}
  \openoutputfile{\jobname.paramap}{@parano}
  \def\parano@saveline{%
    \addtostream{@parano}{\arabic{parano} \parano@sourceline}%
  }
\fi

\newcounter{parano}
%\@addtoreset{parano}{section}

\def\prepara{}
\def\postpara{}
\newdimen\paranoboxwidth
\paranoboxwidth=3em\relax
\newdimen\parwidth
\renewcommand\theparano{\thesection.\arabic{parano}}

\newif\ifparano\paranofalse

\def\parano{\global\paranotrue\@ifnextchar[{\@@parano}{\@parano}}
\AtBeginDocument{\parwidth\parindent}
\long\def\@parano{%%
%\typeout{PARINDENT = \the\parindent----PARWIDTH =  \the\parwidth}
  \everypar{\parindent0pt\refstepcounter{parano}%
  \parano@saveline
  \hbox to \paranoboxwidth{\prepara\theparano\hfill}\postpara}}

\long\def\@@parano[#1]{%
   \setcounter{parano}{#1}%
   \addtocounter{parano}{-1}%
   \everypar{\parindent0pt%
   \refstepcounter{parano}%
   \hbox to \paranoboxwidth{\prepara\theparano\hfill}\postpara}}

\def\endparano{\everypar{\parindent\parwidth}
         \global\paranofalse%
         \parindent\parwidth%
%\typeout{PARINDENT = \the\parindent::::PARWIDTH =  \the\parwidth}
}

\def\@xsect#1{%
  \@tempskipa #1\relax
  \ifdim \@tempskipa>\z@
    \par \nobreak
    \vskip \@tempskipa
    \@afterheading
  \else
    \@nobreakfalse
    \global\@noskipsectrue
    \everypar{%
      \if@noskipsec
        \global\@noskipsecfalse
       {\setbox\z@\lastbox}%
        \clubpenalty\@M
        \begingroup \@svsechd \endgroup
        \unskip
        \@tempskipa #1\relax
        \hskip -\@tempskipa
      \else
        \clubpenalty \@clubpenalty
        \everypar{}%
      \fi}%
  \fi
  \ifparano\@parano\fi\ignorespaces}

\def\@startsection#1#2#3#4#5#6{\everypar{}%
  \if@noskipsec \leavevmode \fi
  \par
  \@tempskipa #4\relax
  \@afterindenttrue
  \ifdim \@tempskipa <\z@
    \@tempskipa -\@tempskipa \@afterindentfalse
  \fi
    \everypar{}%
    \addpenalty\@secpenalty\addvspace{\@tempskipa}
  \@ifstar
    {\@ssect{#3}{#4}{#5}{#6}}%
    {\@dblarg{\@sect{#1}{#2}{#3}{#4}{#5}{#6}}}}

%%
%% End of file 'parano.sty'
%%
2
  • @cwx Could you add an example for usage?
    – cis
    Commented Jun 16, 2019 at 9:53
  • @cis Happy to! However, I'm not sure I can do so without more context. Would you please ask a question linking to this one and show what you're trying and what's happening? I'll take a look at it. Thanks!q
    – cxw
    Commented Jun 16, 2019 at 13:49

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .