%% $Id: spark-otf.sty 463 2022-03-03 07:27:02Z herbert $
%%
%% This file is distributed under the terms of the LaTeX Project Public
%% License from CTAN archives in directory  macros/latex/base/lppl.txt.
%% Either version 1.3 or, at your option, any later version.
%%
% Copyright 2017,2022 Herbert Voss hvoss@tug.org
%%
\def\spark@version{0.05a}
\ProvidesPackage{spark-otf}[%
  2022/03/03 v. \spark@version~(Herbert Voss) Supports spark OpenType for lualatex/xelatex.] 
%
\RequirePackage{ifxetex,ifluatex,xkeyval}
%
\newif\ifspark@usefilenames \spark@usefilenamesfalse
\DeclareOptionX{usefilenames}[true]{\@nameuse{spark@usefilenames#1}}
%
\providecommand\spark@DefaultFeatures{}
\DeclareOptionX{DefaultFeatures}{\def\spark@DefaultFeatures{#1}}

\ProcessOptionsX\relax

\ifxetex\else\ifluatex\else
  \@latex@error{This package can only be used with "XeLaTeX" or "LuaLaTeX"!%
      \MessageBreak "pdfLaTeX" or any other "TeX" version are _not_ possible!}%
\fi\fi
\RequirePackage{%luaotfload,
xparse}

\ifluatex\RequirePackage{luacode}\fi

\newcommand\setSparkColor[2]{%
  \addfontfeatures{UprightFeatures={Color=#1}}#2%
  \addfontfeatures{UprightFeatures={Color=000000}}}

\ifspark@usefilenames
  \typeout {Using file names for the spark font}%
%-----------------------------------------  file names ----------------------------
  \font\sparkBarMedium     ="file:Sparks-Bar-Medium.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkBarNarrow     ="file:Sparks-Bar-Narrow.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkBarExtranarrow="file:Sparks-Bar-Extranarrow.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkBarWide       ="file:Sparks-Bar-Wide.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkBarExtrawide  ="file:Sparks-Bar-Extrawide.otfmode=node;+calt;\spark@DefaultFeatures" 
%
  \font\sparkDotlineMedium    ="file:Sparks-Dotline-Medium.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotlineThick     ="file:Sparks-Dotline-Thick.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotlineExtrathick="file:Sparks-Dotline-Extrathick.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotlineThin      ="file:Sparks-Dotline-Thin.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotlineExtrathin ="file:Sparks-Dotline-Extrathin.otf:mode=node;+calt;\spark@DefaultFeatures"  
%
  \font\sparkDotMedium    ="file:Sparks-Dot-Medium.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotSmall     ="file:Sparks-Dot-Small.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotExtralarge="file:Sparks-Dot-Extralarge.otf:mode=node;+calt;\spark@DefaultFeatures" 
  \font\sparkDotExtrasmall="file:Sparks-Dot-Extrasmall.otf:mode=node;+calt;\spark@DefaultFeatures" 
%
\else
  \typeout {Using symbolic names for the spark font}%
%-----------------------------------------  symbolic names ----------------------------
  \font\sparkBarMedium     = "name:Sparks Bar Medium:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkBarNarrow     = "name:Sparks Bar Narrow:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkBarExtranarrow= "name:Sparks Bar Extra-narrow:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkBarWide       = "name:Sparks Bar Wide:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkBarExtrawide  = "name:Sparks Bar Extra-wide:mode=node;+calt;\spark@DefaultFeatures"
%
  \font\sparkDotlineMedium    = "name:Sparks Dot-line Medium:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotlineThick     = "name:Sparks Dot-line Thick:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotlineExtrathick= "name:Sparks Dot-line Extra-thick:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotlineThin      = "name:Sparks Dot-line Thin:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotlineExtrathin = "name:Sparks Dot-line Extra-thin:mode=node;+calt;\spark@DefaultFeatures"
%
  \font\sparkDotMedium    = "name:Sparks Dot Medium:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotSmall     = "name:Sparks Dot Small:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotExtralarge= "name:Sparks Dot Extra-large:mode=node;+calt;\spark@DefaultFeatures"
  \font\sparkDotExtrasmall= "name:Sparks Dot Extra-small:mode=node;+calt;\spark@DefaultFeatures"
\fi
%
%
\def\Extend@List{\@ifnextchar!\Extend@List@i\Extend@List@ii}
\def\Extend@List@i!#1,#2\@nil{%
  \def\spark@mark@first{#1}%
  \def\spark@values@i{#1,}%
  \Extend@List@iii#2,!,!\@nil
}
\def\Extend@List@ii#1\@nil{\Extend@List@iii#1,!,!\@nil}
%
\def\Extend@List@iii#1,!#2,!#3\@nil{%
  \ifx\relax#2\relax % no value with !
    \edef\spark@values@i{\spark@values@i#1}%
    \def\spark@mark@last{}%
  \else
    \edef\spark@values@i{\spark@values@i#1,#2}%
    \def\spark@mark@last{#2}%
  \fi
}

\def\check@list@values#1{%
  \def\spark@values@i{}%
  \def\spark@mark@first{}%
  \def\spark@mark@last{}%
  \Extend@List#1\@nil
}

%
\ifluatex
\begin{luacode}
function RelativeValues(v,m)
  local Values = {}  
  for k,x in ipairs(v) do
    Values[k] = x
  end
  table.sort(Values)
  local MaxVal = (Values[#Values])
  for k,x in ipairs(v) do
    Values[k] = math.floor(x/MaxVal*m)
  end
  for i,k in ipairs(Values) do
    tex.sprint(k)
    if (i < #Values) then tex.sprint(",") end
  end
end
\end{luacode}
%                              12        3  45 
  \NewDocumentCommand\sparkBar{sO{Medium}O{}mO{}}{{%
    \check@list@values{#4}%
    \IfBooleanTF{#1}%
      {\edef\spark@values@ii{\directlua{RelativeValues({\spark@values@i},99)}}}%
      {\let\spark@values@ii\spark@values@i}%
    \@nameuse{sparkBar#2}#3\spark@mark@first\string{\spark@values@ii\string}\spark@mark@last#5%
  }}
%                              12        3  45
  \NewDocumentCommand\sparkDot{sO{Medium}O{}mO{}}{{%
    \check@list@values{#4}%
    \IfBooleanTF{#1}%
      {\edef\spark@values@ii{\directlua{RelativeValues({\spark@values@i},100)}}}%
      {\let\spark@values@ii\spark@values@i}%
    \@nameuse{sparkDot#2}#3\spark@mark@first\string{\spark@values@ii\string}\spark@mark@last#5%
  }}
%                                  12        3  45
  \NewDocumentCommand\sparkDotline{sO{Medium}O{}mO{}}{{%
    \check@list@values{#4}%
    \IfBooleanTF{#1}%
      {\edef\spark@values@ii{\directlua{RelativeValues({\spark@values@i},100)}}}%
      {\let\spark@values@ii\spark@values@i}%
    \@nameuse{sparkDotline#2}#3\spark@mark@first\string{\spark@values@ii\string}\spark@mark@last#5%
  }}
\else %% XeLaTeX%              1        2  34
  \NewDocumentCommand\sparkBar{O{Medium}O{}mO{}}{{%
    \check@list@values{#3}%
    \@nameuse{sparkBar#1}\spark@mark@first\string{\spark@values@i\string}\spark@mark@last%
  }}%                          1        2  34 
  \NewDocumentCommand\sparkDot{O{Medium}O{}mO{}}{{%
    \check@list@values{#3}%
    \@nameuse{sparkDot#1}\spark@mark@first\string{\spark@values@i\string}\spark@mark@last%
  }}%
  \NewDocumentCommand\sparkDotline{O{Medium}O{}mO{}}{{%
    \check@list@values{#3}%
    \@nameuse{sparkDotline#1}\spark@mark@first\string{\spark@values@i\string}\spark@mark@last%
  }}
\fi
%%
\endinput

