The chords only have to be defined via \guitarchord
once, and can be reutilized as needed. Rather that using \raiseguitar
to set the vertical position, I use \setstackgap{L}{<baselinekip of stack>}
to do so.
EDITED to address deficiencies noted by OP. Macros to use include
\guitarchord\<chordname>{<chord-definition>}
and
\showchord [<short entry text>]{\<chordname>}
where the optional argument is used if the chord text is shorter than the chord width. Note two lengths specified in the MWE that allow adjustments in alignment and minimum chord spacing.
RE-EDITED to provide optional syntax that some may find preferable:
\chordline{\<chordname>}{<text>}
Here is the MWE:
\documentclass{article}
\usepackage{musixguit,stackengine}
\def\chordalign{\dimexpr2.2ex}% 2.2ex sets alignment of chord
\def\chordminwidth{\dimexpr6.5ex}% 6.5ex provides min. hskip for optional argument
\newcommand\guitarchord[2]{%
\savestack#1{\kern\chordalign\NOtes\guitar #2\en}
}
\newcommand\showchord[2][\relax]{%
\ifx\relax#1\relax\def\tmpuaw{T}\else\def\tmpuaw{F}\fi%
\stackengine{\Lstackgap}{#1}{%
\makebox[0ex][l]{#2}\kern\chordminwidth}{O}{l}{F}{\tmpuaw}{L}%
}
\newcommand\chordline[2]{\setbox0=\hbox{#2}%
\ifdim\wd0>\chordminwidth\showchord{#1}#2\else\showchord[#2]{#1}\fi%
}
\raiseguitar {0}
\setstackgap{L}{2.7\baselineskip}
\begin{document}
\guitarchord\Cm{{Cm $^7$}{2}x-----\gbarre1\gdot33\gdot52}
\guitarchord\GM{G{}o-----\gbarre3\gdot25\gdot35\gdot44}
\showchord[Ly-]{\Cm} \showchord{\GM}rics of the first
\showchord[of 2]{\Cm} \showchord{\GM}verses ...
Alternative syntax:
\chordline{\Cm}{Ly-}
\chordline{\GM}{rics of the first}
\chordline{\Cm}{of 2}
\chordline{\GM}{verses ...}
\end{document}
While I don't recommend it because of potential danger, the OP followed up asking if the #
character (and things like parentheses) could be incorporated into chord names. To do so, I make #
catcode 11, and employ a lot of \csname
nomenclature.
Here is such a version:
\documentclass{article}
\usepackage{musixguit,stackengine}
\def\chordalign{\dimexpr2.2ex}% 2.2ex sets alignment of chord
\def\chordminwidth{\dimexpr9ex}% 6.5ex provides min. hskip for optional argument
\newcommand\guitarchord[2]{%
\expandafter\savestack\expandafter{\csname #1\endcsname}{%
\kern\chordalign\NOtes\guitar #2\en}
}
\newcommand\showchord[2][\relax]{%
\ifx\relax#1\relax\def\tmpuaw{T}\else\def\tmpuaw{F}\fi%
\stackengine{\Lstackgap}{#1}{%
\makebox[0ex][l]{\csname #2\endcsname}\kern\chordminwidth}%
{O}{l}{F}{\tmpuaw}{L}%
}
\newcommand\chordline[2]{\setbox0=\hbox{#2}%
\ifdim\wd0>\chordminwidth\relax\showchord{#1}#2\else
\showchord[#2]{#1}\fi%
}
\raiseguitar {0}
\setstackgap{L}{2.7\baselineskip}
\begin{document}
\catcode`#=11
\guitarchord{F#m7(add4)}{{F$\sharp$m7(add4)$^7$}{2}x-----\gbarre1\gdot33\gdot52}
\guitarchord{GM}{G{}o-----\gbarre3\gdot25\gdot35\gdot44}
\showchord[Ly-]{F#m7(add4)} \showchord{GM}rics of the first
\showchord[of 2]{F#m7(add4)} \showchord{GM}verses ...
Alternative syntax:
\chordline{F#m7(add4)}{Ly-}
\chordline{GM}{rics of the first}
\chordline{F#m7(add4)}{of 2}
\chordline{GM}{verses ...}
\end{document}
First things first, you've done something wrong when defining the variable \d
and \s
. You should wrote \def\d{12}
! (More precisely, if you write \def\d = {A}
, you'll have to write \d =
each time you want the value 12
). That said, you have multiple ways to set variable and do calculus, among others:
\def\var{14}
you just set a variable, without any calculus.
- You can use counter (for integers) and length (for kind of real values) which allow some simple calculus:
\newlength{\var}
\setlength{\var}{\dimexpr(\varA+\varB)/2\relax}
.
- You can use pgf to do "advanced" math:
\pgfmathsetmacro{\var}{1-sin(180*\angle)^2}
(\pgfmathsetmacro\var{XXX}
works too). Note that there is a lot of pgf macro, but in my opinion this one is the most useful one! Beware that \pfgmathsetmacro
works weirdly with length, so maybe avoid giving \s
a unit... Also note that it will gives back a real value, if you want integer, you should use \pgfmathtruncatemacro
!
So in your case, in order to change the value of the text width, you could do
\def\s{20}
\pgfmathsetmacro{\distx}{\s-\s/(2^(\x/\d))}
\node[fret,minimum width=\distx em] at (XXXX) {$\x$};
But if you don't really use the node as an object, it might be easier to draw directly lines. It might produce a bigger code, but it's (in my opinion) easier to deal with.
Regarding the drawing, I've done something like that some times ago for ukulele!
I decided to use some recursive formula:
- The next fret is obtained by multiplying by 2^{-1/12} = 0.94387431268;
- The center of the space is obtained by multiplying by (1+2^{-1/12})/2 = 0.97193715634.
For the recursive part, you can keep values through iteration using \xdef\var{\var}
that will globally set \var
value. So
\def\var{0}
\foreach \x in {1,...,10}{
\pgfmathtruncatemacro\var{mod( \var+1, 5 )}
\xdef\var{\var}
\message{\var}
}
will print 1 2 3 4 0 1 2 3 4 0
!
First, we define every possible coordinate with the name (StringNumber-FretNumber) and some other useful positions, then we print what we want without thinking of the formula for the position!
So
\documentclass[margin=.2cm]{standalone}
\usepackage{tikz}
\usetikzlibrary{calc,arrows}
\begin{document}
\begin{tikzpicture}[
ynode/.style={draw=red!50,circle,fill=red!50,scale=.35,inner sep=1pt,minimum size=1.7em}]
%%%% Draw the base and set coordinates %%%%
\begin{scope}[xscale=-15,yscale=.3,line width=.5]
\xdef\x{1}
%% Left line
\draw[line width=1.5] (1,1) -- (1,6);
\foreach \fret in {1,...,24}{
%% Set coordinate for each string
\foreach \str in {1,...,6}{
\coordinate (\str-\fret) at (0.97193715634*\x,\str);
}
%% Set coordinate for the text above
\coordinate (Top-\fret) at (0.97193715634*\x,7);
%% Compute the position of the fret
\pgfmathsetmacro\x{\x * 0.94387431268}
\xdef\x{\x}
%% Draw the fret
\draw (\x,1) -- (\x,6);
}
%% Draw each string
\foreach \str in {1,...,6}{
\draw (1,\str) -- (0.97153194115*\x,\str);
\coordinate (start\str) at (1,\str);
}
\end{scope}
%% Draw the mark on the guitare
\foreach \f in {3,5,7,9,15,17}{
\draw[black!20,fill=black!10] ($(3-\f)!.5!(4-\f)$) circle (.08);
}
\draw[opacity=.20,fill,fill opacity=.10] (2-12) circle (.08) (5-12) circle (.08);
\end{tikzpicture}
\end{document}
which gives
It's quite easy to use it afterward. You could do for example
\node[znode] at (5-4) {\textbf{2}};
\node[znode] at (3-5) {\textbf{4}};
\draw[zbar] (2-3) -- (5-3);
with the style
zbar/.style={shorten >=-3,shorten <=-3,line width=6,round cap-round cap},
znode/.style={white,draw=black,circle,fill=black,scale=.5,inner sep=1pt,minimum size=1.7em},
which gives
If you want to display each note, you could add, in the tikzpicture,
%% We define the name of each number
\newcommand\savename[2]{\expandafter\xdef\csname name#1\endcsname{#2}}
\newcommand\getname[1]{\csname name#1\endcsname}
\foreach \n/\t in {1/A,2/A$\sharp$,3/B,4/C,5/C$\sharp$,6/D,7/D$\sharp$,8/E,9/F,10/F$\sharp$,11/G,0/G$\sharp$}{
\savename{\n}{\t}
}
%% Boucle on the string and the first note (given its number)
\foreach \str/\note in {1/8,2/1,3/6,4/11,5/3,6/8}{
\node[anchor=east] at (start\str) {\scriptsize\getname{\note}};
\foreach \fret in {1,...,24}{
\pgfmathtruncatemacro\note{mod( \note+1, 12 )}
\xdef\note{\note}
\node[ynode] at (\str-\fret) {\textbf{\getname{\note}}};
}
}
%% Number above each space
\foreach \fret in {1,...,24}{
\node[scale=.8] at (Top-\fret) {\tiny \fret};
}
which gives
Best Answer
Are you searching for something like this? http://www.texample.net/tikz/examples/guitar-chords/