# Overlapping chords on lyrics with \makebox

I have the following code to add chords over the lyrics of a song:

\documentclass{article}

\usepackage[utf8]{inputenc}
\usepackage[english]{babel}
\usepackage{fontenc}
\usepackage{xcolor}
%Page Margins:

%Line Spacing, Paragraph indentation and Paragraph Spacing
\renewcommand{\baselinestretch}{1}
\setlength{\parindent}{0em}
\setlength{\parskip}{0.2em}

\newcommand\chord[2][l]{\makebox[0pt][#1]{\color{rgb,232:red,232;green,0;yellow,0}\begin{tabular}[b]{@{}l@{}}#2\\\mbox{}\end{tabular}}}

\begin{document}

This is a \chord{Am}li\chord{B}ne of text \chord{C}with chords\chord{Am}\chord{B}

\end{document}


which generates (I use pdflatex):

The problem is obvious: when chords are too close together they overlap. Is there a way to make the chords move to the right automatically just enough so that they do not overlap? I don't mind if the chord is not exactly over the spot where they are placed in the code, as long as they are clearly visible. Any suggestions are welcome!

Same output as my other answer, but this time the \chord macro takes only one argument. The second argument is implicit and consists of the following characters, up to four in total.

This is a \chord{Am}li\chord{B}ne of text \chord{C}with chords\chord{Am}\chord{B}%

Text\chord{B} with a chord at the end of a word\chord{A}%


yields

If you don't like the line filling the gap introduced by the chord above, remove \hrulefill in the definition of the command \chordEnd.

\documentclass{article}
\usepackage{xcolor}
\definecolor{chord}{RGB}{232,0,0}
% \chord{chord} + up to four characters as second arg
\newcommand\chord[1]{%
\def\thischord{#1}%
\def\lyrics{}%
\chorda
}
\newcommand\chorda{\chordDo\chordb}% 1st character
\newcommand\chordb{\chordDo\chordc}% 2nd character
\newcommand\chordc{\chordDo\chordd}% 3rd character
% Continue this chain to include more characters
% Make sure to rename \chordd below to whatever was the last command above.
\newcommand\chordd{\chordDo\chordEnd}% last character
\newcommand\chordDo[1]{%
\let\chordCont#1%
\futurelet\chordFl\chordDoX
}
\newcommand\chordDoX{%
\if\noexpand\chordFl\relax
\let\tmp\chordEnd
\else
\ifcat\chordFl\space
\let\tmp\chordSpace
\else
\let\tmp\chordChar
\fi
\fi
\tmp
}
\newcommand\chordChar[1]{%
\edef\lyrics{\lyrics#1}%
\chordCont
}
\newcommand\chordSpace{%
\edef\lyrics{\lyrics\ }%
\afterassignment\chordCont
\let\tmp=
}
\newcommand\chordEnd{%
\begin{tabular}[b]{@{}l@{}}
\textcolor{chord}{\thischord}\\
\lyrics\hrulefill
\end{tabular}%
}

\begin{document}
This is a \chord{Am}li\chord{B}ne of text \chord{C}with chords\chord{Am}\chord{B}%

Text\chord{B} with a chord at the end of a word\chord{A}%

\end{document}

• Thanks! This is perfect. Nov 26 '21 at 7:04
• One thing: does this also include spaces as the second argument? You mention letters or digits, but not spaces. How can I add more accepted characters? I mention this because the output for Text\chord{B} with a chord at the end of a word\chord{A} adds a line even when there is space enough for the chord. Image here. Nov 26 '21 at 12:09
• @Clerni I have updated my solution. Now any characters are accepted, including spaces. Nov 30 '21 at 20:21

You could do something like this.

\documentclass{article}
\usepackage{xcolor}
\definecolor{chord}{RGB}{232,0,0}
% \chord{chord}{lyrics}
\newcommand\chord[2]{%
\begin{tabular}[b]{@{}l@{}}
\textcolor{chord}{#1}\\
#2\hrulefill
\end{tabular}%
}
\begin{document}

This is a \chord{Am}{li}\chord{B}{ne} of text \chord{C}{with chords}\chord{Am}{}\chord{B}{}

\end{document}

• Is there any way of doing this without having to pass any parameter to the command? I'm generating (and compiling) this code automatically from a django web app (taking the lyrics from a database and using regex to translate the raw lyric/chord data to LaTeX code). Using this answer would require heavy use of regex to identify what to pass to the command. For manual editing of songs, though: great answer! Nov 25 '21 at 11:26
• Clarification: by "passing no parameter", I mean "passing no portion of lyrics". Of course, the chord name has to be passed. Nov 25 '21 at 11:33