2

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:
\usepackage[headheight=130pt,tmargin=130pt,headsep=50pt, a4paper, total={6in, 9in}]{geometry}

%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): Generated line

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!

2

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

enter image description here

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}
3
  • Thanks! This is perfect.
    – Clerni
    Nov 26 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.
    – Clerni
    Nov 26 at 12:09
  • @Clerni I have updated my solution. Now any characters are accepted, including spaces.
    – gernot
    1 hour ago
2

You could do something like this.

enter image description here

\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}
2
  • 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!
    – Clerni
    Nov 25 at 11:26
  • Clarification: by "passing no parameter", I mean "passing no portion of lyrics". Of course, the chord name has to be passed.
    – Clerni
    Nov 25 at 11:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.