%D \module
%D   [       file=symb-ini,
%D        version=1998.07.20,
%D          title=\CONTEXT\ Symbol Libraries,
%D       subtitle=Basic Symbols Commands,
%D         author=Hans Hagen,
%D           date=\currentdate,
%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
%C
%C This module is part of the \CONTEXT\ macro||package and is
%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
%C details.

%D The macros described here used to be part of the \type {core-con} module. I
%D decided to move them here when symbolsets saw the light. Let their light shine.

\writestatus{loading}{ConTeXt Symbol Libraries / Initialization}

\registerctxluafile{symb-ini}{}

\unprotect

%D \macros
%D   {definesymbol, symbol}
%D
%D Converting numbers or levels into a character, romannumeral, symbol or something
%D else, is supported by many \CONTEXT\ commands. Therefore we need a mechanism for
%D linking such numbers to their counterparts.
%D
%D First we take care of symbols. These are for instance used in enumerations and
%D itemizations. We have:
%D
%D \showsetup{definesymbol}
%D \showsetup{symbol}
%D
%D Symbols are simply linked to a tag. Such tags can be numbers or strings.
%D
%D \starttyping
%D \definesymbol [1]       [$\bullet$]
%D \definesymbol [level 5] [$\star$]
%D \stoptyping

\installcorenamespace{symbol}
\installcorenamespace{symbols}
\installcorenamespace{symbolset}
\installcorenamespace{symboldefault}

%D For now we only have one option.

\installparameterhandler\??symbols {symbols}
\installsetuphandler    \??symbols {symbols}

\appendtoks
   \doifelse{\symbolsparameter\c!stylealternative}\v!math
     \settrue\setfalse\prefermathovertextchar
\to \everysetupsymbols

\setupsymbols
  [\c!stylealternative=\v!text]

\let\currentsymbol   \empty
\let\currentsymbolset\empty

\newtoks\t_symb_setups

\let\m_symb_current_set\empty

\newconditional\c_symb_found

\newtoks\everysymbol

%D We don't use the commandhandler as symbols have their own subsystem for resolving
%D values.

\unexpanded\def\definesymbol
  {\dotripleempty\symb_define}

\def\symb_define[#1][#2][#3]% class name meaning
  {\ifthirdargument
     \setvalue{\??symbol#1:#2}{#3}%
     \doifsomething{#1}{\addvalue{\??symbolset#1}{#2}}%
   \else
     \setvalue{\??symbol\m_symb_current_set:#1}{#2}%
     \addvalue{\??symbolset\m_symb_current_set}{#1}%
   \fi}

\unexpanded\def\doifelseinsymbolset#1#2{\ifcsname\??symbol#1:#2\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi}
\unexpanded\def\doifinsymbolset    #1#2{\ifcsname\??symbol#1:#2\endcsname\expandafter\firstofoneargument \else\expandafter\gobbleoneargument   \fi}
\unexpanded\def\doifelsesymbolset    #1{\ifcsname\??symbolset#1\endcsname\expandafter\firstoftwoarguments\else\expandafter\secondoftwoarguments\fi}

\let\doifinsymbolsetelse\doifelseinsymbolset
\let\doifsymbolsetelse  \doifelsesymbolset

\letvalue{\??symbolset}\empty

%def\symbolset#1{\csname\??symbolset\ifcsname\??symbolset#1\endcsname#1\fi\endcsname} % no [#1], to be used in commalists etc

\def\symbolset#1{\begincsname\??symbolset#1\endcsname} % no [#1], to be used in commalists etc

%D Since symbols are used frequently in interactive documents, we speed up this one.
%D Well, that was history, since now we simplified things a bit, because the low
%D level macros have been sped up every now and then.

% We support both:
%
% Test test \symbol[whatever]\ test \symbol[whatever].
% Test test \symbol{whatever}  test \symbol{whatever}.

\unexpanded\def\symbol
  {\dontleavehmode % so we can start a paragraph with it
   \dodoubleempty\symb_place}

\def\symb_place   % so we also handle \symbol{name}
  {\iffirstargument  % which is nicer with following spaces
     \expandafter\symb_place_normal
   \else
     \expandafter\symb_place_special
   \fi}

\def\symb_place_normal
  {\ifsecondargument
     \expandafter\symb_place_normal_a
   \else
     \expandafter\symb_place_normal_b
   \fi}

% \def\symb_place_normal_a[#1][#2]%
%   {\edef\currentsymbol{#2}%
%    \ifcsname\??symbol#1:#2\endcsname
%       \symb_place_indeed{#1:#2}%
%    \else
%      \symb_place_normal_c
%    \fi}

\def\symb_place_normal_a[#1][#2]%
  {\edef\currentsymbol{#2}%
   \ifcsname\??symbol#1:#2\endcsname
      \symb_place_indeed{#1:#2}% maybe use \lastnamescs
   \else\ifcsname\??symboldefault#1\endcsname
      \symb_place_named{#1}% maybe use \lastnamescs
   \else
     \symb_place_normal_c
   \fi\fi}

\def\symb_place_normal_b[#1][#2]%
  {\edef\currentsymbol{#1}%
   \ifcsname\??symbol\currentsymbolset:#1\endcsname
     \symb_place_indeed{\currentsymbolset:#1}%
   \else
     \symb_place_normal_c
   \fi}

\def\symb_place_normal_c
  {\setfalse\c_symb_found
   \the\t_symb_setups
   \ifconditional\c_symb_found \else
     \symb_place_retry\currentsymbol % hm, isn't this redundant?
   \fi}

\def\symb_place_special[#1][#2]#3%
  {\firstargumenttrue
   \secondargumentfalse
   \symb_place_normal[#3][]}

\def\symb_place_indeed#1% \relax's prevent lookahead problems
  {\settrue\c_symb_found
   \begingroup
   \the\everysymbol
   \csname\??symbol#1\endcsname\relax
   \endgroup}

\letvalue{\??symbol}\firstofoneargument

\def\directsymbol#1#2% no \relax, there can be an argument, see lists
 %{\csname\??symbol\ifcsname\??symbol#1:#2\endcsname#1:#2\fi\endcsname}
  {\begincsname\??symbol#1:#2\endcsname}

\unexpanded\def\symb_fetch
  {\ifconditional\c_symb_found
     \expandafter\gobbleoneargument
   \else
     \expandafter\symb_fetch_indeed
   \fi}

% \def\symb_fetch_indeed#1%
%   {\ifcsname\??symbol#1:\currentsymbol\endcsname
%      \symb_place_indeed{#1:\currentsymbol}%
%    \fi}

\def\symb_fetch_indeed#1%
  {\ifcsname\??symbol#1:\currentsymbol\endcsname
     \symb_place_indeed{#1:\currentsymbol}%
   \else\ifcsname\??symboldefault#1\endcsname
     \symb_place_named{#1}%
   \fi\fi}

\def\symb_place_named#1% \relax's prevent lookahead problems
  {\begingroup
   \setbox\scratchbox\hbox\bgroup
     \the\everysymbol
     \getglyphstyled
       {\csname\??symboldefault#1\endcsname}%
       {\tochar{n:\currentsymbol}}%
     \relax
   \egroup
   \ifdim\wd\scratchbox>\zeropoint
     \unhbox\scratchbox
     \endgroup
     \setxvalue{\??symbol#1:\currentsymbol}%
       {\symb_place_named_indeed{#1}{\currentsymbol}}%
     \settrue\c_symb_found
   \else
     \endgroup
   \fi}

\unexpanded\def\symb_place_named_indeed#1#2% \relax's prevent lookahead problems
  {\settrue\c_symb_found
   \begingroup
   \the\everysymbol
   \getglyphstyled
     {\csname\??symboldefault#1\endcsname}%
     {\tochar{n:#2}}%
   \relax
   \endgroup}

\def\symb_place_retry#1%
  {\ifcsname\??symbol:#1\endcsname
     \symb_place_indeed{:#1}%
   \else
     #1%
   \fi}

%D \macros
%D   {definefiguresymbol}
%D
%D To simplify defining figure symbols, we offer:
%D
%D \showsetup{definefiguresymbol}
%D
%D By default, such symbols scale along the current bodyfont size or running font
%D size (which is better).

\def\defaultsymbolfactor{10}
\def\defaultsymbolheight{1.25ex}

\unexpanded\def\figuresymbol
  {\dodoubleempty\symb_figure}

\ifdefined\externalfigure       \else \def\externalfigure[#1][#2]{#1} \fi
\ifdefined\resetexternalfigures \else \let\resetexternalfigures\relax \fi

\def\symb_figure[#1][% #2]%
  {\externalfigure[#1][\c!reset=\v!yes,\c!symbol=\v!yes,\c!height=\defaultsymbolheight,}% #2]}

\appendtoks \resetexternalfigures \to \everysymbol

\unexpanded\def\definefiguresymbol
  {\dotripleempty\symb_figure_define}

\def\symb_figure_define[#1][#2][#3]%
  {\ifsecondargument
     \definesymbol[#1][{\symb_figure[#2][#3]}]%
   \fi}

%D \macros
%D   {doifsymboldefinedelse}
%D
%D A handy private one:

\def\symb_fetch_first
  {\ifconditional\c_symb_found
     \expandafter\gobbleoneargument
   \else
     \expandafter\symb_fetch_first_indeed
   \fi}

\def\symb_fetch_first_indeed#1%
  {\doifinsymbolset{#1}\currentsymbol{\settrue\c_symb_found}}

\def\symb_fetch_second#1%
  {\doifinsymbolset\empty\currentsymbol{\settrue\c_symb_found}}

\unexpanded\def\doifelsesymboldefined#1%
  {\begingroup
   \edef\currentsymbol{#1}%
   \let\symb_fetch\symb_fetch_first
   \setfalse\c_symb_found
   \the\t_symb_setups
   \ifconditional\c_symb_found
     \endgroup\expandafter\firstoftwoarguments
   \else
     \symb_fetch_second\currentsymbol
     \ifconditional\c_symb_found
       \endgroup\doubleexpandafter\firstoftwoarguments
     \else
       \endgroup\doubleexpandafter\secondoftwoarguments
     \fi
   \fi}

\let\doifsymboldefinedelse\doifelsesymboldefined

%D \macros
%D   {setupsymbolset,startsymbolset}
%D
%D From these macro definitions one can deduce that symbols can be grouped in
%D symbol sets:
%D
%D \starttyping
%D \startsymbolset [navigation 1]
%D   \definefiguresymbol [Next] [mp-symb.1]
%D   \definefiguresymbol [Prev] [mp-symb.2]
%D \stopsymbolset
%D \stoptyping
%D
%D Such a symbol can be typeset with:
%D
%D \starttyping
%D \setupsymbolset[navigation 1]\symbol[Next]
%D \stoptyping
%D
%D or simply:
%D
%D \starttyping
%D \symbol[navigation 1][Next]
%D \stoptyping
%D
%D Formally:
%D
%D \showsetup{setupsymbolset}
%D \showsetup{startsymbolset}

\installcorenamespace{symbolsets}

% \unexpanded\def\startsymbolset[#1]%
%   {\pushmacro\m_symb_current_set
%    \def\m_symb_current_set{#1}}

% maybe a parameterhandler:

\unexpanded\def\startsymbolset
  {\dodoubleargument\symb_start_set}

\def\symb_start_set[#1][#2]%
  {\pushmacro\m_symb_current_set
   \def\m_symb_current_set{#1}%
   \ifsecondargument
     \getdummyparameters[\s!font=,#2]%
     \edef\p_font{\dummyparameter\s!font}%
     \ifx\p_font\empty\else
       \letvalue{\??symboldefault#1}\p_font
     \fi
   \fi}

\unexpanded\def\stopsymbolset
  {\popmacro\m_symb_current_set}

\unexpanded\def\setupsymbolset[#1]%
  {\edef\currentsymbolset{#1}%
   \ifcsname\??symbolsets\currentsymbolset\endcsname \else
     \symb_setup_symbol_set
   \fi}

\def\symb_setup_symbol_set
  {\normalexpanded{\t_symb_setups{\symb_fetch{\currentsymbolset}\the\t_symb_setups}}%
   \letvalue{\??symbolsets\currentsymbolset}\empty} % speedup

\unexpanded\def\resetsymbolset
  {\t_symb_setups\emptytoks}

\unexpanded\def\forcesymbolset[#1]%
  {\t_symb_setups{\symb_fetch{#1}}}

%D \macros
%D   {showsymbolset}
%D
%D \showsetup{showsymbolset}

\fetchruntimecommand \showsymbolset \f!symb_run

%D \macros
%D   {usesymbols}
%D
%D \showsetup{usesymbols}

\unexpanded\def\usesymbols[#1]{\clf_usesymbols{#1}}

%D As longs as symbols are linked to levels or numbers, we can also use the
%D conversion mechanism, but in for instance the itemization macros, we prefer
%D symbols because they can more easier be (partially) redefined.

\protect \endinput

