[Tex/LaTex] Modifying .sty files

best practicespackagespatching

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

Best Answer

License considerations

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

Related Question