General remarks
My focus here is on the process of refactoring in a Latex context.
Code refactoring is a broad topic with the objective to restructure existing code without changing its functionality (English Wikipedia). As a result code becomes easier to read, to understand and to maintain. The German version on refactoring (German Wikipedia) mentions possible objectives of refactoring activities:
- (R) making code easier to read
- (U) or easier to understand
- (X) or easier to extend
- (S) or avoiding code redundancy (simplification)
- (T) or improving code testability
In coding, e.g. in Latex, looking for opportunities to refactor should become second nature. I.e. do it often, perhaps even continuously.
Levels of refactoring
Most Latex users just create content, like text or graphics, using standard language features and packages, and do some tweaks on layout or visual appearance. For these I find generalization and clean-up the most effecitve refactoring strategy (see my example below).
Power users, e.g. when developing packages or document classes , may be also concerned, and perhaps even more, with data structures and data processing. For these I suggest to walk trough Martin Fowlers online catalogue of refactoring and translate the suggestions into their toolset wrt. Latex.
Note: Martin Fowler lives in the world of Objects, UML and Systems. So his catalogue may be hard to translate for those who just write content. But it's worth a try or two.
Whatever you do, apply knowledge you already have or gained e.g. via questions and answers on this site.
The process of refactoring ...
... is simple, while keeping aboves objectives in mind:
- write something
- spot refactoring opportunities (or necessities)
- refactor, decide and verify/test
- repeat
This is easy to do when working on your own code files, and a bit harder (i.e. lengthier) to do when documenting as an answer.
Refactoring the code example using generalization and clean-up
Using some code more than once, including errors or similarities or variations, is an opportunity to refactor by generalization.
The text
Obviously we have some redundancy or duplicates here wrt. the "ditch":
Some text with duplicates: The fox jumped over the ditch. The dietch was no dutch.
So, replacing a written "dietch" by a standard would be more useful ... especially when the whole document will talk about ditches in all shapes and forms. So, why not introducing a macro \dtch?
\newcommand\dtch[0]{ditch}
...
Some text with duplicates: The fox jumped over the \dtch{}. The \dtch{} was no dutch.
At least this improves reading (R), gives less redundancy (S) and can be extended easily later (X), once you discover, you want all ditches in bold: Change in one place only.
The Tikz code
What kind of things are repetitive or similar here?
\begin{tikzpicture}
\node[anchor=west,red] (A) at (0,0) {hello wrold};
\node[anchor=west,orange] (B) at (0,-1) {it's a beautiful world};
\node[anchor=west] at (A.east) {here we go};
\end{tikzpicture}
Same:
- the anchors
- "world", again with a typo
Similar:
- color
- nodes name
- y-coordinate
So an obvious refactoring step would be to replace all those anchors by one style:
% ~~~ style refactored ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\node[aw,red] (A) at (0, 0) {hello \wrld{}};
\node[aw,orange] (B) at (0,-1) {it's a beautiful \wrld{}};
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
Where to go from here?
Option 1: The first two node-lines look very similar and it's tempting to replace those more than one line by a loop, like so:
\newcommand\wrld[0]{world}
...
% ~~~ option 1: loop ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\foreach \col/\nm/\y/\t in {red/A/0/{hello \wrld{}},
orange/B/-1/{it's a beautiful \wrld{}}}
\node[aw,\col] (\nm) at (0,\y) {\t};
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
Now, changes just are confined to the list of data tupels. Depending on your preferences you may find this a good or bad result wrt. aboves objectives. This happens frequently, so you may want to investigate alternatives.
Option 2: Why not absorbing the two node statements by macro named \nd? This way you preserve the codes structure (2 lines of nodes) while absorbing all its changes as parameters to pass:
\newcommand\wrld[0]{world}
\newcommand\nd[4]{\node[aw,#1] (#2) at (0,#3) {#4};}% 1:col, 2:nm, 3:y, 4: txt
...
% ~~~ option 2: macro ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\nd{red} {A}{ 0}{hello \wrld{}}
\nd{orange}{B}{-1}{it's a beautiful \wrld{}}
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
Testing and deciding
Here we test just by compile and looking at the visual outcome. Now, all 3 options for Tikz refactoring give the same result:
\documentclass[10pt,a4paper]{article}
\usepackage{tikz}
% ~~~ macros ~~~~~~~~~~~~
\newcommand\dtch[0]{ditch}
\newcommand\wrld[0]{world}
\newcommand\nd[4]{\node[aw,#1] (#2) at (0,#3) {#4};}% 1:col, 2:nm, 3:y, 4: txt
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
Some text with duplicates: The fox jumped over the \dtch{}. The \dtch{} was no dutch.
% ~~~ style refactored ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\node[aw,red] (A) at (0, 0) {hello \wrld{}};
\node[aw,orange] (B) at (0,-1) {it's a beautiful \wrld{}};
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
% ~~~ option 1: loop ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\foreach \col/\nm/\y/\t in {red/A/0/{hello \wrld{}},
orange/B/-1/{it's a beautiful \wrld{}}}
\node[aw,\col] (\nm) at (0,\y) {\t};
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
% ~~~ option 2: macro ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\nd{red} {A}{ 0}{hello \wrld{}}
\nd{orange}{B}{-1}{it's a beautiful \wrld{}}
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
\end{document}

For my taste for the time being I'd stay with the style refactored.
Clean-up ... Result
Removing all obsolete code will give the (intermediate) result:
\documentclass[10pt,a4paper]{article}
\usepackage{tikz}
% ~~~ macros ~~~~~~~~~~~~
\newcommand\dtch[0]{ditch}
\newcommand\wrld[0]{world}
% ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
\begin{document}
Some text with duplicates: The fox jumped over the \dtch{}. The \dtch{} was no dutch.
% ~~~ style refactored ~~~~~~~~~~~~~~~~~~~~
\begin{tikzpicture}[
aw/.style={anchor=west},
]
\node[aw,red] (A) at (0, 0) {hello \wrld{}};
\node[aw,orange] (B) at (0,-1) {it's a beautiful \wrld{}};
\node[aw] at (A.east) {here we go};
\end{tikzpicture}
\end{document}
It's less visible here in this simple example: if you add more code (i.e. functionality) and refactor in parallel, code tends to become:
- more compact
- more versatile
- less prone to errors
- less noisy
- somehow more beautiful
Recap: your major tools
Unless you are a La/Tex guru with more ressources to unlock you may want to use at least these tools frequently when refactoring Latex code:
- telling comments
- indenting (see structured programming)
\newcommand (and also \newenvironment, \renew... etc.)
- file backups or versions (perhaps even git etc.)
- features from Latex and/or packages (like Tikz)
Some of my own examples
Over time I refacted code from questions. Often I documented the process, sometimes only the steps taken.
Process in detail on subject:
Documented refactoring steps taken on package: