Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Sibirtsev committed Aug 4, 2020
0 parents commit e001e86
Show file tree
Hide file tree
Showing 5 changed files with 1,344 additions and 0 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
*.aux
*.log
*.out
*.synctex.gz
211 changes: 211 additions & 0 deletions chordbox.sty
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
%
% Copyright 2018 Steven Franzen
%
% This file is part of chordbox.
%
% Chordbox may be distributed and/or modified under the conditions of the
% LaTeX Project Public License, either version 1.3 of this license or (at your
% option) any later version. The latest version of this license is in
% http://www.latex-project.org/lppl.txt and version 1.3 or later is part of all
% distributions of LaTeX version 2005/12/01 or later.
%
% Chordbox has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of chordbox is Steven Franzen.
%
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{chordbox}[2019/04/14 v1.0 Minor improvement to documentation]

\RequirePackage{tikz, xifthen, xstring}
\usetikzlibrary{shapes.misc, scopes, backgrounds}

\newif\ifcb@startbarre

% Set up keys for the drawing code
\pgfqkeys{/chordbox}{
% This fills a bar of width 0.4 that scales properly, without requiring
% extra libraries
draw barre/.code 2 args={%
\fill (#1) -- +(0, -0.2) -| (#2) -- +(0, 0.2) -| cycle;
},
draw barre/.value required,
% Number of frets displayed
numfrets/.initial=4,
% Base fret number parser
base fret/.code={fr\raisebox{.5ex}{\scriptsize#1}},
% Chord name parser
name/.code=\ensuremath{\mathrm{#1}},
name/.value required,
% Configuration of text below the chord box and on the nodes
text below/.is choice,
text below/none/.code={\def\cb@textbelow{0}},
text below/fingering/.code={\def\cb@textbelow{1}},
text below/pitch/.code={\def\cb@textbelow{2}},
text below/fingering,
text on node/.is choice,
text on node/none/.code={\def\cb@textonnode{0}},
text on node/fingering/.code={\def\cb@textonnode{1}},
text on node/pitch/.code={\def\cb@textonnode{2}},
text on node/none,
% Symbols for pitch notation
flat symbol/.initial=\flat,
sharp symbol/.initial=\sharp,
% Pitch name settings; arrays only seem to work with TeX macros
pitch names/.store in=\cb@pitchnames,
pitch names={"A","A\#","B","C","C\#","D","D\#","E","F","F\#","G","G\#"},
tuning/.store in=\cb@tuning,
tuning={"E","A","D","G","B","E"},
% The base fret of a given chord box
@basefret/.initial=1,
% Calculate the given fret position #1, corrected for the base fret
@fretnum/.code=\pgfmathtruncatemacro{\fretnum}{%
1 + #1 - \pgfkeysvalueof{/chordbox/@basefret}
},
% Whether the barre has yet to be started
@start barre/.is if=cb@startbarre,
% Find and typeset pitch of string number #1 at fret number #2
@typeset pitch/.code 2 args={
\pgfmathparse{{\cb@tuning}[#1-1]}
\ifnum#2=0
\pgfkeys{@replace symbols=\pgfmathresult}
\else
\foreach \p in {0,...,11} {%
\pgfmathsetmacro{\stringpitch}{{\cb@pitchnames}[\p]}%
\if\stringpitch\pgfmathresult
\pgfmathparse{{\cb@pitchnames}[mod(\p + #2, 12)]}
\pgfkeys{@replace symbols=\pgfmathresult}%
\breakforeach
\fi
}
\fi
},
% Replace pitch text with math symbols
@replace symbols/.code={%
\def\#{\ensuremath{\pgfkeysvalueof{/chordbox/sharp symbol}}}%
\StrSubstitute{#1}{b}{%
\ensuremath{\pgfkeysvalueof{/chordbox/flat symbol}}%
}
}
}

% Define tikz drawing styles. The muted string symbol size is slightly smaller
% to make it visually similar to the open symbol. Both are also placed above
% their given coordinate for better separation from the box.
\tikzset{
chordbox/.style={baseline, scale=0.25},
chordbox/.value forbidden,
fret node text/.style={font=\Large\bfseries,text=white},
fret node text/.value forbidden,
pitch text below/.style={font=\tiny},
string/.is choice,
string/base/.style={%
circle, draw, inner sep=0, minimum size=20, transform shape%
},
string/fretted/.style={string/base, fill},
string/open/.style={string/base, above},
string/muted/.style={string/open, cross out, minimum size=19}
}

% Environment with parts common to both commands
\newenvironment{chordboxenv}[3]{%
\pgfqkeys{/chordbox}{@basefret={#1}, numfrets/.get=\numfrets}
\pgfqkeys{}{.search also=/chordbox}
% The code that draws the chord box. Argument #1 specifies the base fret
% (>1) of the chord box, #2 is the chord name and #3 the comma-separated
% list of finger positions, e.g. {x,0,2:2,2:3,1:1,0}.
\begin{tikzpicture}[chordbox]%
% Put coordinates at finger positions and above the frets (index 0),
% store string count, then draw the string grid and decorations
\foreach[count=\n] \fretposition in {#3} {
\global\let\chordbox@n\n
\foreach \fret in {0,...,\numfrets}
\coordinate (\n\fret) at (\n - 1, 0.5 - \fret);
% Extra coordinate for text below each string
\coordinate (\n) at (\n - 1, -\numfrets);
}
\draw grid (\chordbox@n - 1, -\numfrets);
\ifthenelse{\isempty{#1}\or#1<2}{% Draw the "nut"
\fill rectangle (\chordbox@n - 1, .2);
}{% Draw the position indicator
\node[left] at (11) {\pgfkeys{base fret={#1}}};
}
% Center chord name over strings
\pgfmathparse{0.5 * (\chordbox@n - 1)}
\node[above] at (\pgfmathresult, 1.25) {\pgfkeys{name={#2}}};
% Draw the string symbols according to argument #3
\foreach[count=\s] \fret in {#3} {
\ifnum\pdfmatch{^[0-9]+}{\fret}=1
\StrBehind{\pdflastmatch 0}{>}[\num]
\StrBehind{\fret}{:}[\frettext]
\def\pitch{\pgfkeys{@typeset pitch={\s}{\num}}}
\let\nodetext\empty
\ifcase\cb@textonnode
\or
\let\nodetext\frettext % 1
\or
\let\nodetext\pitch % 2
\fi
\ifnum\num=0
\node[string=open, fret node text, black] at (\s0)
{\nodetext};
\else
\pgfkeys{@fretnum=\num}
\node[string=fretted, fret node text] at (\s\fretnum)
{\nodetext};
\fi
% Display the "text below"
\ifnum\cb@textbelow>0
\if1\cb@textbelow
\if\frettext\empty
\else
\node[below] at (\s) {\frettext};
\fi
\else
% Insert vphantom here to align all pitch names
\node[below, pitch text below] at (\s)
{\vphantom{\pgfkeys{@replace symbols=\#b}}\pitch};
\fi
\fi
\else % Anything other than a number is taken to mean "muted"
\node[string=muted] at (\s0) {};
\fi
}
}{%
\end{tikzpicture}
}

% Draw a chord box without barres, for example:
% \chordbox{Am}{x,0,2,2,1,0}
% \chordbox[5]{A}{5,7,7,6,5,5}
\providecommand{\chordbox}[3][1]{%
\begin{chordboxenv}{#1}{#2}{#3}
\end{chordboxenv}
}

% Draw a chord box for a barre chord. Extra argument for the fret number(s)
% whose notes should be barred, for example:
% \bchordbox[3]{C}{x,3,5,5,5,3}{3,5}
\providecommand{\bchordbox}[4][1]{%
\begin{chordboxenv}{#1}{#2}{#3}
\foreach \b in {#4} {
\pgfkeys{@start barre=true, @fretnum=\b}
\foreach[count=\s] \f in {#3} {
\if\f\b
\ifcb@startbarre
\coordinate (start) at (\s\fretnum);
\global\cb@startbarrefalse
\else
\coordinate (end) at (\s\fretnum);
\fi
\fi
}
\scoped[on background layer]
\pgfkeys{draw barre={start}{end}};
}
\end{chordboxenv}
}

\endinput
[2018/12/07 v0.3 Support for pitch info]
[2018/12/04 v0.2 Support for fingering info, further customisation]
[2018/12/01 v0.1 Initial release]
Loading

0 comments on commit e001e86

Please sign in to comment.