-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e001e86
Showing
5 changed files
with
1,344 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.aux | ||
*.log | ||
*.out | ||
*.synctex.gz |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] |
Oops, something went wrong.