% --------------------------------------------------------------------------
% the LEADSHEETS package
% 
%   typesetting leadsheets and songbooks
%
% --------------------------------------------------------------------------
% Clemens Niederberger
% E-Mail: contact@mychemistry.eu
% --------------------------------------------------------------------------
% Copyright 2014-2017 Clemens Niederberger
%
% This work 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.
%
% This work has the LPPL maintenance status `maintained'.
%
% The Current Maintainer of this work is Clemens Niederberger.
% --------------------------------------------------------------------------
\LeadsheetsExplLibrary{chordnames}{2016/07/05 typesetting chord names with easy syntax}

\leadsheets_load_library:n {musicsymbols}

\tl_new:N \l__leadsheets_chord_tl
\tl_new:N \l__leadsheets_tension_tl
\tl_new:N \l__leadsheets_format_tl

\cs_new_protected:Npn \leadsheets_tension_sym:Nn #1#2
  { \tl_replace_all:Nnn #1 {#2} { \textsuperscript {#2} } }

\cs_new_protected:Npn \leadsheets_tension_sym:Nnn #1#2#3
  { \tl_replace_all:Nnn #1 {#2} { \textsuperscript {#3} } }
\cs_generate_variant:Nn \leadsheets_tension_sym:Nnn {NnV}

\cs_new_protected:Npn \leadsheets_chord_sym:Nnn #1#2#3
  { \tl_replace_all:Nnn #1 {#2} {#3} }
\cs_generate_variant:Nn \leadsheets_chord_sym:Nnn {NnV}

\tl_new:N \l__leadsheets_sharp_tl
\tl_new:N \l__leadsheets_flat_tl
\tl_new:N \l__leadsheets_doublesharp_tl
\tl_new:N \l__leadsheets_doubleflat_tl
\tl_new:N \l__leadsheets_full_dim_tl
\tl_new:N \l__leadsheets_half_dim_tl
\tl_new:N \l__leadsheets_aug_tl
\tl_new:N \l__leadsheets_major_tl
\tl_new:N \l__leadsheets_minor_tl
\tl_new:N \l__leadsheets_sus_tl
\tl_new:N \l__leadsheets_dim_tl
\tl_new:N \l__leadsheets_add_tl
\tl_new:N \l__leadsheets_major_seven_tl
\tl_new:N \l__leadsheets_german_B_tl
\tl_new:N \l__leadsheets_german_H_tl

\tl_set:Nn \l__leadsheets_sharp_tl       {\sharp}
\tl_set:Nn \l__leadsheets_flat_tl        {\flat}
\tl_set:Nn \l__leadsheets_doublesharp_tl {\doublesharp}
\tl_set:Nn \l__leadsheets_doubleflat_tl  {\doubleflat}
\tl_set:Nn \l__leadsheets_half_dim_tl    {\o{}}
\tl_set:Nn \l__leadsheets_full_dim_tl    {o}
\tl_set:Nn \l__leadsheets_aug_tl         {+}
\tl_set:Nn \l__leadsheets_major_tl       {}
\tl_set:Nn \l__leadsheets_minor_tl       {m}
\tl_set:Nn \l__leadsheets_sus_tl         {\textsuperscript{sus}}
\tl_set:Nn \l__leadsheets_dim_tl         {\textsuperscript{dim}}
\tl_set:Nn \l__leadsheets_add_tl         {\textsuperscript{add}}
\tl_set:Nn \l__leadsheets_major_seven_tl {\textsuperscript{maj7}}
\tl_set:Nn \l__leadsheets_major_nine_tl  {\textsuperscript{maj9}}
\tl_set:Nn \l__leadsheets_german_B_tl    {B}
\tl_set:Nn \l__leadsheets_german_H_tl    {H}

\group_begin:
% for convenient input of sharps:
\char_set_catcode_other:N \#
% because ^ is active in the song environment:
\char_set_catcode_active:N \^
% # is other so we need another parameter character:
\char_set_catcode_parameter:N \!

\cs_gset_protected:Npn \leadsheets_chord:
  {
    \group_begin:
      \tl_use:N \l__leadsheets_format_tl
      \char_set_catcode_other:N \#
      \char_set_catcode_active:N \^
      \leadsheets_chord_aux:n
  }

\cs_gset_protected:Npn \leadsheets_chord_aux:n !1
 {
    \tl_set:Nn \l__leadsheets_chord_tl {!1}
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {maj7} \l__leadsheets_major_seven_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {maj9} \l__leadsheets_major_nine_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {sus} \l__leadsheets_sus_tl
    \leadsheets_chord_sym:Nnn  \l__leadsheets_chord_tl {^} {\textsuperscript}
    \bool_if:NT \l__leadsheets_output_notation_german_bool
      {
        \leadsheets_chord_sym:NnV \l__leadsheets_chord_tl {B} \l__leadsheets_german_B_tl
        \leadsheets_chord_sym:NnV \l__leadsheets_chord_tl {H} \l__leadsheets_german_H_tl
      }
    \leadsheets_chord_sym:Nnn  \l__leadsheets_chord_tl {#b} {}
    \leadsheets_chord_sym:Nnn  \l__leadsheets_chord_tl {b#} {}
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {##} \l__leadsheets_doublesharp_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {bb} \l__leadsheets_doubleflat_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {#} \l__leadsheets_sharp_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {b} \l__leadsheets_flat_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {dim} \l__leadsheets_dim_tl
    \leadsheets_chord_sym:NnV  \l__leadsheets_chord_tl {add} \l__leadsheets_add_tl
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {0}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {1}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {2}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {3}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {4}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {5}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {6}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {7}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {8}
    \leadsheets_tension_sym:Nn \l__leadsheets_chord_tl {9}
    \leadsheets_tension_sym:NnV  \l__leadsheets_chord_tl {/o} \l__leadsheets_half_dim_tl
    \leadsheets_tension_sym:NnV  \l__leadsheets_chord_tl {o} \l__leadsheets_full_dim_tl
    \leadsheets_tension_sym:NnV  \l__leadsheets_chord_tl {+} \l__leadsheets_aug_tl
    \leadsheets_chord_sym:Nnn \l__leadsheets_chord_tl  {(}
      { \leadsheets_tension:w( }
    \leadsheets_chord_sym:Nnn \l__leadsheets_chord_tl  {mi}
      {\l__leadsheets_minor_tl}
    \leadsheets_chord_sym:Nnn \l__leadsheets_chord_tl  {ma}
      {\l__leadsheets_major_tl}
    \tl_replace_all:Nnn \l__leadsheets_chord_tl
      {\textsuperscript\textsuperscript}
      {\textsuperscript}
    \bool_if:NT \l__leadsheets_lowercase_minor_bool
      {
        \tl_put_left:Nn \l__leadsheets_chord_tl { \__leadsheets_start_minor:w }
        \tl_put_right:Nn \l__leadsheets_chord_tl { \q_stop }
      }
%    \show \l__leadsheets_chord_tl
    \tl_use:N \l__leadsheets_chord_tl
    \group_end:
  }

\group_end:

% lowercase letters for minor chords:
\bool_new:N \l__leadsheets_lowercase_minor_bool

\cs_new_protected:Npn \__leadsheets_start_minor:w #1 \q_stop
  {
    \tl_if_in:nnTF {#1} {\l__leadsheets_minor_tl}
      { \__leadsheets_revert_minor:w #1 \q_stop }
      {#1}
  }

\cs_new_protected:Npn \__leadsheets_revert_minor:w #1 \l__leadsheets_minor_tl #2 \q_stop
  { \tl_lower_case:n {#1} #2 }

\cs_new_protected:Npn \leadsheets_tension:w (#1)
  {
    \group_begin:
      \tl_set:Nn \l__leadsheets_tension_tl {#1}
      \leadsheets_chord_sym:Nnn \l__leadsheets_tension_tl
        {\textsuperscript}
        {\use:n}
      \textsuperscript { ( \tl_use:N \l__leadsheets_tension_tl ) }
    \group_end:
  }

\keys_define:nn {leadsheets/chords}
  {
    format       .tl_set:N = \l__leadsheets_format_tl ,
    sharp        .tl_set:N = \l__leadsheets_sharp_tl ,
    flat         .tl_set:N = \l__leadsheets_flat_tl ,
    double-sharp .tl_set:N = \l__leadsheets_doublesharp_tl ,
    double-flat  .tl_set:N = \l__leadsheets_doubleflat_tl ,
    half-dim     .tl_set:N = \l__leadsheets_half_dim_tl ,
    full-dim     .tl_set:N = \l__leadsheets_full_dim_tl ,
    aug          .tl_set:N = \l__leadsheets_aug_tl ,
    major        .tl_set:N = \l__leadsheets_major_tl ,
    minor        .code:n   =
      \str_if_eq:nnTF {#1} {lowercase}
        {
          \bool_set_true:N \l__leadsheets_lowercase_minor_bool
          \tl_clear:N \l__leadsheets_minor_tl
        }
        {
          \bool_set_false:N \l__leadsheets_lowercase_minor_bool
          \tl_set:Nn \l__leadsheets_minor_tl {#1}
        } ,
    sus          .tl_set:N = \l__leadsheets_sus_tl ,
    add          .tl_set:N = \l__leadsheets_add_tl ,
    dim          .tl_set:N = \l__leadsheets_dim_tl ,
    major-seven  .tl_set:N = \l__leadsheets_major_seven_tl ,
    major-nine   .tl_set:N = \l__leadsheets_major_nine_tl ,
    german-B     .tl_set:N = \l__leadsheets_german_B_tl ,
    german-H     .tl_set:N = \l__leadsheets_german_H_tl ,
    % since version 0.2 those are defined in the `chords` library:
    % output-notation .choice: ,
    % input-notation .choice: ,
  }

\NewDocumentCommand \setchords {m}
  { \keys_set:nn {leadsheets/chords} {#1} }

\NewDocumentCommand \chordname {} { \leadsheets_chord: }

\file_input_stop:

HISTORY:

2014/08/10 - first version
2015/05/08 - drop `literal' option for input and output notation
           - input/output notation is now handled by the `chords' library
           - German output of B and H can be customized
2015/05/22 - improvements to the chord macros
2015/07/02 - this is not a user library any more
2016/07/05 - with option `minor=lowercase' minor chords are now printed with
             lowercase letters; requires user input `Dmi' in order to get `d';
             lowercase letters can of course be input directly but then are
             immune to transposing
