Modifying .sty files?

Yesterday I did some changes in the layout of my TeX document. I couldn't accomplish the changes until I opened the .sty files and modified some of their code. I am sure this is not the best idea. For one reason, after the packages got an update, I will have to modify the file again (and again and again).

Another way would be to create my own version of that .sty file and call that instead of the original one, but this might not be the best idea either. (again: at least the updates speak against it)

How can I accomplish the following changes by adding code to a local file (e.g. my .tex preamble) instead of changing global files (like the package .sty files)?

I wanted to change the following lines in ledmac.sty:

\def\printlines#1|#2|#3|#4|#5|#6|#7|{\begingroup
\setprintlines{#1}{#2}{#3}{#4}{#5}{#6}%
\ifl@d@pnum #1\fullstop\fi
\ifledplinenum \linenumrep{#2}\else \symplinenum\fi     %% #2 into: \arabtxt{\n{#2}}
\ifl@d@ssub \fullstop \sublinenumrep{#3}\fi
\ifl@d@dash \endashchar\fi
\ifl@d@pnum #4\fullstop\fi
\ifl@d@elin \linenumrep{#5}\fi
\ifl@d@esl \ifl@d@elin \fullstop\fi \sublinenumrep{#6}\fi
\endgroup}


The second thing is a line in ledpar.sty:

\newcommand*{\l@dlinenumR}{%
\numlabfont\linenumrepR{\line@numR}\Rlineflag%       %% numlabfont into: numlabfontR
\ifsublines@
\ifnum\subline@num>\z@
\unskip\fullstop\sublinenumrepR{\subline@numR}%
\fi
\fi}


(In the latter case, just adding \renewcommand with the modified code did not work.)

-
Sorry, missed the ampersands in the first case. You'll need to sandwich the first code block with \makeatletter and \makeatother too. –  qubyte Mar 9 '12 at 7:00

The ledmac package as well as many other packages in the LaTeX world isdistributed under the LaTeX Project Public License (LPPL). That means that you can use the code and you can modify it but for modification there are rules that you have to obey. The most important one is

If you are not the Current Maintainer of the Work, you may distribute a Derived Work provided the following conditions are met for every component of the Work unless that component clearly states in the copyright notice that it is exempt from that condition. Only the Current Maintainer is allowed to add such statements of exemption to a component of the Work.

(a) If a component of this Derived Work can be a direct replacement for a component of the Work when that component is used with the Base Interpreter, then, wherever this component of the Work identifies itself to the user when used interactively with that Base Interpreter, the replacement component of this Derived Work clearly and unambiguously identifies itself as a modified version of this component to the user when used interactively with that Base Interpreter.

In a nutshell this means that whenever you make changes you make them in a way that any other user that happens to use your modified file will be immediately aware of the fact that it was modified (and not only by searching in some comments inside the package). The typical way this is done in the TeX world is by simply renaming the file since the name is part of tthe interface, e.g., you say \usepackage{ledmac}.

The reason for this requirement by LPPL is that LaTeX is a laguage for communication not just a typesetting system and to be able to communicate both side have to have a common understanding about the language. For some further information see the article about the history of LPPL that appeared in TUGboat.

Thus the LPPL is there to protect you and the community and even if you never intend to distributed your modification it is best not to violate the LPPL. After all your changes may escape easily (just a fact of life). The LPPL makes the following recommendations here:

It is wise never to modify a component of the Work, even for your own personal use, without also meeting the above conditions for distributing the modified component. While you might intend that such modifications will never be distributed, often this will happen by accident — you may forget that you have modified that component; or it may not occur to you when allowing others to access the modified version that you are thus distributing it and violating the conditions of this license in ways that could have legal implications and, worse, cause problems for the community. It is therefore usually in your best interest to keep your copy of the Work identical with the public one. Many works provide ways to control the behavior of that work without altering any of its licensed components.

Modification approaches

Suitable methods of modifying a package have already been discussed but to put everything into one answer, here is a quick summary from my perspective:

One time changes

Modifications that are intended to be done only for a single document are best placed in the preamble of the document. In most cases you have to surround your redefinitions with \makeatletter and \makeatother in order to be able to access or modify commands that contain an @ sign in their names.

A possible alternative to redefinitions is to use the \patchcmd from the package etoolbox that allows you to replace some code of a command with some other code, e.g., from your question

 \usepackage{etoolbox}
\makeatletter
\patchcmd{\l@dlinenumR}{\numlabfont}{\numlabfontR}%
{\typeout{*** SUCCESS ***}}%
{\ERRORpatchfailed}  % stop with error (undefined csname) if patch fails
\makeatother


You still need \makeatletterbecause you modify a command with @ in its name but you restrict the modification to the necessary places which is usually helpful.

Modification intended for reuse on several documents

In that case using the document preamble is not necessarily a good idea because that means you repeat the same code over and over again. In that case the bes solution is to place your modifications into a small package and load this after the main package (unless of course the package itself doesn'T come with some configuration possibilities, as some do).

Note that if you use the package approach then do not use \makeatletter inside: in style files the @sign is automatically available for command names.

Bug fixes

Finally, if your change is more of a bug fix than a configuration, approach the author to provide an official update of the package. Of course as long as the bug persists you need to use one of the other approaches from above. In that case I would always propose to use the \patchcmd solution in the preamble because then you will be automatically alerted if the package finally changes (because your patch then fails).

-
@ Frank Mittelbach: wow. this is quite an answer. Thanks. Does the patchcmd-solution work with the first modification, i.e. the \def\printlines ... (because it is no \newcommand but a \def)? –  ClintEastwood Mar 9 '12 at 10:50
@Clint the patchcmd solution works on any command that was defined earlier. Thus it should be irrelevant whether that happened with \def, \let, \newcommand or what have you. But for details consult the package documentation. –  Frank Mittelbach Mar 9 '12 at 11:15
works like a charm! –  ClintEastwood Mar 9 '12 at 12:05

Whenever you which to perform a local redefinition, it is best to perform this modification in your .tex preamble if its minor, or in a local .sty file if its major or comprehensive. This compartmentalization makes it easier to decode and keeps the main .tex source clean.

Since both your example changes seem minor, I would suggest just adding the code to your .tex source preamble. Here are guidelines, specific to your case:

• First example: Include this code, as-is and wrapped with \makeatletter ... \makeatother, after loading \usepackage{ledmac}. Otherwise ledmac will overwrite your definitions;
-
I tried \makeatletter and \makeatother before but it did not work. Now it does. I am sure that I have done something wrong when I tried the first time. It's good to know now how to proceed and what is recommended. Thanks for you explanation. –  ClintEastwood Mar 9 '12 at 7:02

Just to complete everything (Frank's Modification intended for reuse on several documents). If you want to reuse the changes in new documents and comply with LPPL licensing requirements, you can make you own modified .sty files, say ledmac-mod.sty and ledpar-mod.sty save them to the right place in your local texmf tree and update your Tex file name database. After that you can use them as

\usepackage[<options]{ledmac-mod}
\usepackage[<options]{ledpar-mod}


ledmac-mod.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ledmac-mod}[2012/03/09 v1.0 Modified ledmac (Clint Eastwood)]
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{ledmac}}
\ProcessOptions\relax
\RequirePackage{ledmac}

\def\printlines#1|#2|#3|#4|#5|#6|#7|{%
\begingroup
\setprintlines{#1}{#2}{#3}{#4}{#5}{#6}%
\ifl@d@pnum #1\fullstop\fi
\ifledplinenum \linenumrep{#2}\else \symplinenum\fi     %% #2 into: \arabtxt{\n{#2}}
\ifl@d@ssub \fullstop \sublinenumrep{#3}\fi
\ifl@d@dash \endashchar\fi
\ifl@d@pnum #4\fullstop\fi
\ifl@d@elin \linenumrep{#5}\fi
\ifl@d@esl \ifl@d@elin \fullstop\fi \sublinenumrep{#6}\fi
\endgroup}

\endinput


ledpar-mod.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{ledpar-mod}[2012/03/09 v1.0 Modified ledpar (Clint Eastwood)]
\DeclareOption*{\PassOptionsToPackage{\CurrentOption}{ledpar}}
\ProcessOptions\relax
\RequirePackage{ledpar}

\renewcommand*{\l@dlinenumR}{%
\numlabfont\linenumrepR{\line@numR}\Rlineflag%       %% numlabfont into: numlabfontR
\ifsublines@
\ifnum\subline@num>\z@
\unskip\fullstop\sublinenumrepR{\subline@numR}%
\fi
\fi}
\endgroup}

\endinput

-
yet another nice solution. could I also combine Frank Mittelbach's and your solution by putting the patchcmd lines into my own modified .sty-file? –  ClintEastwood Mar 9 '12 at 12:19
@ClintEastwood: Yes, just add \RequirePackage{etoolbox} and then your patched commands –  Danie Els Mar 9 '12 at 12:24